mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-07-04 00:36:14 +00:00
Fix compile issue with asio, implement Lua events
This commit is contained in:
parent
ebe3630ec8
commit
26231c6272
@ -1,6 +1,13 @@
|
|||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
project(Server)
|
project(Server)
|
||||||
|
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps/asio/asio/include")
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps/rapidjson/include")
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps/websocketpp")
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps/commandline")
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps/sol2/include")
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps")
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
message(STATUS "MSVC -> forcing use of statically-linked runtime.")
|
message(STATUS "MSVC -> forcing use of statically-linked runtime.")
|
||||||
STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
|
STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
|
||||||
@ -46,14 +53,6 @@ add_executable(BeamMP-Server
|
|||||||
include/TNetwork.h src/TNetwork.cpp
|
include/TNetwork.h src/TNetwork.cpp
|
||||||
include/LuaAPI.h src/LuaAPI.cpp)
|
include/LuaAPI.h src/LuaAPI.cpp)
|
||||||
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/asio/asio/include")
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/asio/asio/include")
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/rapidjson/include")
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/websocketpp")
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/commandline")
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps/sol2/include")
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/deps")
|
|
||||||
|
|
||||||
include_directories(BeamMP-Server PUBLIC ${Boost_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
include_directories(BeamMP-Server PUBLIC ${Boost_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
find_package(Lua REQUIRED)
|
find_package(Lua REQUIRED)
|
||||||
|
7
deps/CMakeLists.txt
vendored
7
deps/CMakeLists.txt
vendored
@ -1,3 +1,10 @@
|
|||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps/asio/asio/include")
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps/rapidjson/include")
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps/websocketpp")
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps/commandline")
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps/sol2/include")
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}/deps")
|
||||||
|
|
||||||
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/socket.io-client-cpp")
|
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/socket.io-client-cpp")
|
||||||
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/commandline")
|
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/commandline")
|
||||||
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/sol2")
|
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/sol2")
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <toml11/toml.hpp>
|
#include <toml11/toml.hpp>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#define SOL_ALL_SAFETIES_ON 1
|
#define SOL_ALL_SAFETIES_ON 1
|
||||||
#include <sol/sol.hpp>
|
#include <sol/sol.hpp>
|
||||||
@ -44,6 +45,8 @@ public:
|
|||||||
[[nodiscard]] std::shared_ptr<TLuaResult> EnqueueScript(TLuaStateId StateID, const std::shared_ptr<std::string>& Script);
|
[[nodiscard]] std::shared_ptr<TLuaResult> EnqueueScript(TLuaStateId StateID, const std::shared_ptr<std::string>& Script);
|
||||||
[[nodiscard]] std::shared_ptr<TLuaResult> EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName);
|
[[nodiscard]] std::shared_ptr<TLuaResult> EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName);
|
||||||
void EnsureStateExists(TLuaStateId StateId, const std::string& Name, bool DontCallOnInit = false);
|
void EnsureStateExists(TLuaStateId StateId, const std::string& Name, bool DontCallOnInit = false);
|
||||||
|
void RegisterEvent(const std::string& EventName, TLuaStateId StateId, const std::string& FunctionName);
|
||||||
|
[[nodiscard]] std::vector<std::shared_ptr<TLuaResult>> TriggerEvent(const std::string& EventName);
|
||||||
|
|
||||||
static constexpr const char* BeamMPFnNotFoundError = "BEAMMP_FN_NOT_FOUND";
|
static constexpr const char* BeamMPFnNotFoundError = "BEAMMP_FN_NOT_FOUND";
|
||||||
|
|
||||||
@ -54,10 +57,11 @@ private:
|
|||||||
|
|
||||||
class StateThreadData : IThreaded {
|
class StateThreadData : IThreaded {
|
||||||
public:
|
public:
|
||||||
StateThreadData(const std::string& Name, std::atomic_bool& Shutdown, TLuaStateId StateId);
|
StateThreadData(const std::string& Name, std::atomic_bool& Shutdown, TLuaStateId StateId, TLuaEngine& Engine);
|
||||||
StateThreadData(const StateThreadData&) = delete;
|
StateThreadData(const StateThreadData&) = delete;
|
||||||
[[nodiscard]] std::shared_ptr<TLuaResult> EnqueueScript(const std::shared_ptr<std::string>& Script);
|
[[nodiscard]] std::shared_ptr<TLuaResult> EnqueueScript(const std::shared_ptr<std::string>& Script);
|
||||||
[[nodiscard]] std::shared_ptr<TLuaResult> EnqueueFunctionCall(const std::string& FunctionName);
|
[[nodiscard]] std::shared_ptr<TLuaResult> EnqueueFunctionCall(const std::string& FunctionName);
|
||||||
|
void RegisterEvent(const std::string& EventName, const std::string& FunctionName);
|
||||||
void operator()() override;
|
void operator()() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -67,9 +71,10 @@ private:
|
|||||||
lua_State* mState;
|
lua_State* mState;
|
||||||
std::thread mThread;
|
std::thread mThread;
|
||||||
std::queue<std::pair<std::shared_ptr<std::string>, std::shared_ptr<TLuaResult>>> mStateExecuteQueue;
|
std::queue<std::pair<std::shared_ptr<std::string>, std::shared_ptr<TLuaResult>>> mStateExecuteQueue;
|
||||||
std::mutex mStateExecuteQueueMutex;
|
std::recursive_mutex mStateExecuteQueueMutex;
|
||||||
std::queue<std::pair<std::string, std::shared_ptr<TLuaResult>>> mStateFunctionQueue;
|
std::queue<std::pair<std::string, std::shared_ptr<TLuaResult>>> mStateFunctionQueue;
|
||||||
std::mutex mStateFunctionQueueMutex;
|
std::recursive_mutex mStateFunctionQueueMutex;
|
||||||
|
TLuaEngine* mEngine;
|
||||||
};
|
};
|
||||||
|
|
||||||
TNetwork& mNetwork;
|
TNetwork& mNetwork;
|
||||||
@ -78,7 +83,9 @@ private:
|
|||||||
fs::path mResourceServerPath;
|
fs::path mResourceServerPath;
|
||||||
std::vector<TLuaPlugin*> mLuaPlugins;
|
std::vector<TLuaPlugin*> mLuaPlugins;
|
||||||
std::unordered_map<TLuaStateId, std::unique_ptr<StateThreadData>> mLuaStates;
|
std::unordered_map<TLuaStateId, std::unique_ptr<StateThreadData>> mLuaStates;
|
||||||
std::mutex mLuaStatesMutex;
|
std::recursive_mutex mLuaStatesMutex;
|
||||||
|
std::unordered_map<std::string /* event name */, std::unordered_map<TLuaStateId, std::set<std::string>>> mEvents;
|
||||||
|
std::recursive_mutex mEventsMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include <any>
|
#include <any>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "LuaAPI.h"
|
#include "LuaAPI.h"
|
||||||
#include "TLuaEngine.h"
|
#include "TLuaEngine.h"
|
||||||
|
|
||||||
static std::string LuaToString(const sol::object& Value) {
|
static std::string LuaToString(const sol::object& Value, size_t Indent = 1) {
|
||||||
switch (Value.get_type()) {
|
switch (Value.get_type()) {
|
||||||
case sol::type::string:
|
case sol::type::string:
|
||||||
return Value.as<std::string>();
|
return Value.as<std::string>();
|
||||||
@ -15,10 +15,17 @@ static std::string LuaToString(const sol::object& Value) {
|
|||||||
Result << "[[table: " << Table.pointer() << "]]: {";
|
Result << "[[table: " << Table.pointer() << "]]: {";
|
||||||
if (!Table.empty()) {
|
if (!Table.empty()) {
|
||||||
for (const auto& Entry : Table) {
|
for (const auto& Entry : Table) {
|
||||||
Result << "\n\t" << LuaToString(Entry.first) << ": " << LuaToString(Entry.second) << ",";
|
Result << "\n";
|
||||||
|
for (size_t i = 0; i < Indent; ++i) {
|
||||||
|
Result << "\t";
|
||||||
|
}
|
||||||
|
Result << LuaToString(Entry.first, Indent + 1) << ": " << LuaToString(Entry.second, Indent + 1) << ",";
|
||||||
}
|
}
|
||||||
Result << "\n";
|
Result << "\n";
|
||||||
}
|
}
|
||||||
|
for (size_t i = 0; i < Indent - 1; ++i) {
|
||||||
|
Result << "\t";
|
||||||
|
}
|
||||||
Result << "}";
|
Result << "}";
|
||||||
return Result.str();
|
return Result.str();
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,6 @@ void TLuaEngine::FindAndParseConfig(const fs::path& Folder, TLuaPluginConfig& Co
|
|||||||
auto ConfigFile = Folder / TLuaPluginConfig::FileName;
|
auto ConfigFile = Folder / TLuaPluginConfig::FileName;
|
||||||
if (fs::exists(ConfigFile) && fs::is_regular_file(ConfigFile)) {
|
if (fs::exists(ConfigFile) && fs::is_regular_file(ConfigFile)) {
|
||||||
beammp_debug("\"" + ConfigFile.string() + "\" found");
|
beammp_debug("\"" + ConfigFile.string() + "\" found");
|
||||||
// TODO use toml11 here to parse it
|
|
||||||
try {
|
try {
|
||||||
auto Data = toml::parse(ConfigFile);
|
auto Data = toml::parse(ConfigFile);
|
||||||
if (Data.contains("LuaStateID")) {
|
if (Data.contains("LuaStateID")) {
|
||||||
@ -112,10 +111,12 @@ void TLuaEngine::FindAndParseConfig(const fs::path& Folder, TLuaPluginConfig& Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TLuaEngine::EnsureStateExists(TLuaStateId StateId, const std::string& Name, bool DontCallOnInit) {
|
void TLuaEngine::EnsureStateExists(TLuaStateId StateId, const std::string& Name, bool DontCallOnInit) {
|
||||||
|
std::unique_lock Lock(mLuaStatesMutex);
|
||||||
if (mLuaStates.find(StateId) == mLuaStates.end()) {
|
if (mLuaStates.find(StateId) == mLuaStates.end()) {
|
||||||
beammp_debug("Creating lua state for state id \"" + StateId + "\"");
|
beammp_debug("Creating lua state for state id \"" + StateId + "\"");
|
||||||
auto DataPtr = std::make_unique<StateThreadData>(Name, mShutdown, StateId);
|
auto DataPtr = std::make_unique<StateThreadData>(Name, mShutdown, StateId, *this);
|
||||||
mLuaStates[StateId] = std::move(DataPtr);
|
mLuaStates[StateId] = std::move(DataPtr);
|
||||||
|
RegisterEvent("onInit", StateId, "onInit");
|
||||||
if (!DontCallOnInit) {
|
if (!DontCallOnInit) {
|
||||||
auto Res = EnqueueFunctionCall(StateId, "onInit");
|
auto Res = EnqueueFunctionCall(StateId, "onInit");
|
||||||
Res->WaitUntilReady();
|
Res->WaitUntilReady();
|
||||||
@ -126,10 +127,27 @@ void TLuaEngine::EnsureStateExists(TLuaStateId StateId, const std::string& Name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomic_bool& Shutdown, TLuaStateId StateId)
|
void TLuaEngine::RegisterEvent(const std::string& EventName, TLuaStateId StateId, const std::string& FunctionName) {
|
||||||
|
std::unique_lock Lock(mEventsMutex);
|
||||||
|
mEvents[EventName][StateId].insert(FunctionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<TLuaResult>> TLuaEngine::TriggerEvent(const std::string& EventName) {
|
||||||
|
std::unique_lock Lock(mEventsMutex);
|
||||||
|
std::vector<std::shared_ptr<TLuaResult>> Results;
|
||||||
|
for (const auto& Entry : mEvents[EventName]) {
|
||||||
|
for (const auto& Function : Entry.second) {
|
||||||
|
Results.emplace_back(EnqueueFunctionCall(Entry.first, Function));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Results;
|
||||||
|
}
|
||||||
|
|
||||||
|
TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomic_bool& Shutdown, TLuaStateId StateId, TLuaEngine& Engine)
|
||||||
: mName(Name)
|
: mName(Name)
|
||||||
, mShutdown(Shutdown)
|
, mShutdown(Shutdown)
|
||||||
, mStateId(StateId) {
|
, mStateId(StateId)
|
||||||
|
, mEngine(&Engine) {
|
||||||
mState = luaL_newstate();
|
mState = luaL_newstate();
|
||||||
luaL_openlibs(mState);
|
luaL_openlibs(mState);
|
||||||
sol::state_view StateView(mState);
|
sol::state_view StateView(mState);
|
||||||
@ -137,6 +155,19 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi
|
|||||||
auto Table = StateView.create_named_table("MP");
|
auto Table = StateView.create_named_table("MP");
|
||||||
Table.set_function("GetOSName", &LuaAPI::MP::GetOSName);
|
Table.set_function("GetOSName", &LuaAPI::MP::GetOSName);
|
||||||
Table.set_function("GetServerVersion", &LuaAPI::MP::GetServerVersion);
|
Table.set_function("GetServerVersion", &LuaAPI::MP::GetServerVersion);
|
||||||
|
Table.set_function("RegisterEvent",
|
||||||
|
[this](const std::string& EventName, const std::string& FunctionName) {
|
||||||
|
RegisterEvent(EventName, FunctionName);
|
||||||
|
});
|
||||||
|
Table.set_function("");
|
||||||
|
Table.create_named("Settings",
|
||||||
|
"Debug", 0,
|
||||||
|
"Private", 1,
|
||||||
|
"MaxCars", 2,
|
||||||
|
"MaxPlayers", 3,
|
||||||
|
"Map", 4,
|
||||||
|
"Name", 5,
|
||||||
|
"Description", 6);
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +187,10 @@ std::shared_ptr<TLuaResult> TLuaEngine::StateThreadData::EnqueueFunctionCall(con
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TLuaEngine::StateThreadData::RegisterEvent(const std::string& EventName, const std::string& FunctionName) {
|
||||||
|
mEngine->RegisterEvent(EventName, mStateId, FunctionName);
|
||||||
|
}
|
||||||
|
|
||||||
void TLuaEngine::StateThreadData::operator()() {
|
void TLuaEngine::StateThreadData::operator()() {
|
||||||
RegisterThread("Lua:" + mStateId);
|
RegisterThread("Lua:" + mStateId);
|
||||||
while (!mShutdown) {
|
while (!mShutdown) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user