mirror of
https://github.com/SantaSpeen/BeamMP-Server.git
synced 2025-07-03 13:15:24 +00:00
Lua: Almost Working events, all triggers working
This commit is contained in:
parent
cb1eb40def
commit
a44050f0f1
@ -133,6 +133,9 @@ void RegisterThread(const std::string str);
|
||||
Application::Console().Write(_this_location + std::string("[DEBUG] ") + (x)); \
|
||||
} \
|
||||
} while (false)
|
||||
// for those times when you just need to ignore something :^)
|
||||
// explicity disables a [[nodiscard]] warning
|
||||
#define beammp_ignore(x) (void)x
|
||||
|
||||
#define Biggest 30000
|
||||
std::string Comp(std::string Data);
|
||||
|
@ -6,12 +6,12 @@
|
||||
namespace LuaAPI {
|
||||
void Print(sol::variadic_args);
|
||||
namespace MP {
|
||||
static inline TLuaEngine* Engine { nullptr };
|
||||
extern TLuaEngine* Engine;
|
||||
|
||||
std::string GetOSName();
|
||||
std::tuple<int, int, int> GetServerVersion();
|
||||
bool TriggerClientEvent(int PlayerID, const std::string& EventName, const std::string& Data);
|
||||
size_t GetPlayerCount() { return Engine->Server().ClientCount(); }
|
||||
inline size_t GetPlayerCount() { return Engine->Server().ClientCount(); }
|
||||
void DropPlayer(int ID, std::optional<std::string> MaybeReason);
|
||||
void SendChatMessage(int ID, const std::string& Message);
|
||||
void RemoveVehicle(int PlayerID, int VehicleID);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "TServer.h"
|
||||
#include <any>
|
||||
#include <filesystem>
|
||||
#include <initializer_list>
|
||||
#include <lua.hpp>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
@ -40,21 +41,39 @@ struct TLuaPluginConfig {
|
||||
|
||||
class TLuaEngine : IThreaded {
|
||||
public:
|
||||
TLuaEngine(TServer& Server, TNetwork& Network);
|
||||
TLuaEngine();
|
||||
~TLuaEngine() noexcept {
|
||||
beammp_debug("Lua Engine terminated");
|
||||
}
|
||||
|
||||
void operator()() override;
|
||||
|
||||
TNetwork& Network() { return mNetwork; }
|
||||
TServer& Server() { return mServer; }
|
||||
TNetwork& Network() { return *mNetwork; }
|
||||
TServer& Server() { return *mServer; }
|
||||
|
||||
void SetNetwork(TNetwork* Network) { mNetwork = Network; }
|
||||
void SetServer(TServer* Server) { mServer = Server; }
|
||||
|
||||
static void WaitForAll(std::vector<std::shared_ptr<TLuaResult>>& Results);
|
||||
[[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, const std::initializer_list<std::any>& Args);
|
||||
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);
|
||||
template <typename... ArgsT>
|
||||
[[nodiscard]] std::vector<std::shared_ptr<TLuaResult>> TriggerEvent(const std::string& EventName, ArgsT&&... Args) {
|
||||
std::unique_lock Lock(mEventsMutex);
|
||||
if (mEvents.find(EventName) == mEvents.end()) {
|
||||
return {};
|
||||
}
|
||||
std::vector<std::shared_ptr<TLuaResult>> Results;
|
||||
for (const auto& Event : mEvents.at(EventName)) {
|
||||
for (const auto& Function : Event.second) {
|
||||
beammp_debug("TriggerEvent: triggering \"" + Function + "\" on \"" + Event.first + "\"");
|
||||
Results.push_back(EnqueueFunctionCall(Event.first, Function, { std::forward<ArgsT>(Args)... }));
|
||||
}
|
||||
}
|
||||
return Results;
|
||||
}
|
||||
std::set<std::string> GetEventHandlersForState(const std::string& EventName, TLuaStateId StateId);
|
||||
|
||||
static constexpr const char* BeamMPFnNotFoundError = "BEAMMP_FN_NOT_FOUND";
|
||||
@ -70,7 +89,7 @@ private:
|
||||
StateThreadData(const StateThreadData&) = delete;
|
||||
~StateThreadData() noexcept { beammp_debug("\"" + mStateId + "\" destroyed"); }
|
||||
[[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, const std::initializer_list<std::any>& Args);
|
||||
void RegisterEvent(const std::string& EventName, const std::string& FunctionName);
|
||||
void operator()() override;
|
||||
|
||||
@ -87,14 +106,14 @@ private:
|
||||
std::thread mThread;
|
||||
std::queue<std::pair<std::shared_ptr<std::string>, std::shared_ptr<TLuaResult>>> mStateExecuteQueue;
|
||||
std::recursive_mutex mStateExecuteQueueMutex;
|
||||
std::queue<std::pair<std::string, std::shared_ptr<TLuaResult>>> mStateFunctionQueue;
|
||||
std::queue<std::tuple<std::string, std::shared_ptr<TLuaResult>, std::initializer_list<std::any>>> mStateFunctionQueue;
|
||||
std::recursive_mutex mStateFunctionQueueMutex;
|
||||
TLuaEngine* mEngine;
|
||||
sol::state_view mStateView { mState };
|
||||
};
|
||||
|
||||
TNetwork& mNetwork;
|
||||
TServer& mServer;
|
||||
TNetwork* mNetwork;
|
||||
TServer* mServer;
|
||||
std::atomic_bool mShutdown { false };
|
||||
fs::path mResourceServerPath;
|
||||
std::vector<TLuaPlugin*> mLuaPlugins;
|
||||
@ -104,10 +123,4 @@ private:
|
||||
std::recursive_mutex mEventsMutex;
|
||||
};
|
||||
|
||||
#include <any>
|
||||
// DEAD CODE
|
||||
struct TLuaArg {
|
||||
std::vector<std::any> args;
|
||||
void PushArgs(lua_State* State);
|
||||
};
|
||||
std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr<TLuaArg> arg, bool Wait);
|
||||
//std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr<TLuaArg> arg, bool Wait);
|
||||
|
@ -4,11 +4,32 @@
|
||||
|
||||
static std::string LuaToString(const sol::object& Value, size_t Indent = 1) {
|
||||
switch (Value.get_type()) {
|
||||
case sol::type::userdata: {
|
||||
std::stringstream ss;
|
||||
ss << "[[userdata: " << Value.as<sol::userdata>().pointer() << "]]";
|
||||
return ss.str();
|
||||
}
|
||||
case sol::type::thread: {
|
||||
std::stringstream ss;
|
||||
ss << "[[thread: " << Value.as<sol::thread>().pointer() << "]] {"
|
||||
<< "\n";
|
||||
for (size_t i = 0; i < Indent; ++i) {
|
||||
ss << "\t";
|
||||
}
|
||||
ss << "status: " << std::to_string(int(Value.as<sol::thread>().status())) << "\n}";
|
||||
return ss.str();
|
||||
}
|
||||
case sol::type::lightuserdata: {
|
||||
std::stringstream ss;
|
||||
ss << "[[lightuserdata: " << Value.as<sol::lightuserdata>().pointer() << "]]";
|
||||
return ss.str();
|
||||
}
|
||||
case sol::type::string:
|
||||
return Value.as<std::string>();
|
||||
case sol::type::number:
|
||||
return std::to_string(Value.as<float>());
|
||||
case sol::type::nil:
|
||||
case sol::type::none:
|
||||
return "<nil>";
|
||||
case sol::type::boolean:
|
||||
return Value.as<bool>() ? "true" : "false";
|
||||
@ -130,13 +151,13 @@ void LuaAPI::MP::RemoveVehicle(int PID, int VID) {
|
||||
c->DeleteCar(VID);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void LuaAPI::MP::Set(int ConfigID, sol::object NewValue) {
|
||||
switch (ConfigID) {
|
||||
case 0: //debug
|
||||
if (lua_isboolean(L, 2)) {
|
||||
Application::Settings.DebugModeEnabled = NewValue.as<bool>();
|
||||
beammp_info("Set `Debug` to ") + (Application::Settings.DebugModeEnabled ? "true" : "false"));
|
||||
beammp_info("Set `Debug` to " + (Application::Settings.DebugModeEnabled ? "true" : "false"));
|
||||
} else
|
||||
SendError(Engine(), L, ("set invalid argument [2] expected boolean for ID : 0"));
|
||||
break;
|
||||
@ -187,6 +208,7 @@ void LuaAPI::MP::Set(int ConfigID, sol::object NewValue) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void LuaAPI::MP::Sleep(size_t Ms) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(Ms));
|
||||
|
@ -84,6 +84,6 @@ void TConsole::WriteRaw(const std::string& str) {
|
||||
}
|
||||
|
||||
void TConsole::InitializeLuaConsole(TLuaEngine& Engine) {
|
||||
Engine.EnsureStateExists(mStateId, "Console");
|
||||
mLuaEngine = &Engine;
|
||||
Engine.EnsureStateExists(mStateId, "Console");
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ static TLuaStateId GenerateUniqueStateId() {
|
||||
return std::to_string(MTGen64()) + std::to_string(std::chrono::duration_cast<std::chrono::nanoseconds>(Time).count());
|
||||
}
|
||||
|
||||
TLuaEngine::TLuaEngine(TServer& Server, TNetwork& Network)
|
||||
: mNetwork(Network)
|
||||
, mServer(Server) {
|
||||
TLuaEngine* LuaAPI::MP::Engine;
|
||||
|
||||
TLuaEngine::TLuaEngine() {
|
||||
LuaAPI::MP::Engine = this;
|
||||
if (!fs::exists(Application::Settings.Resource)) {
|
||||
fs::create_directory(Application::Settings.Resource);
|
||||
@ -41,7 +41,7 @@ void TLuaEngine::operator()() {
|
||||
CollectAndInitPlugins();
|
||||
// now call all onInit's
|
||||
for (const auto& Pair : mLuaStates) {
|
||||
auto Res = EnqueueFunctionCall(Pair.first, "onInit");
|
||||
auto Res = EnqueueFunctionCall(Pair.first, "onInit", {});
|
||||
Res->WaitUntilReady();
|
||||
if (Res->Error && Res->ErrorMessage != TLuaEngine::BeamMPFnNotFoundError) {
|
||||
beammp_lua_error("Calling \"onInit\" on \"" + Pair.first + "\" failed: " + Res->ErrorMessage);
|
||||
@ -53,16 +53,24 @@ void TLuaEngine::operator()() {
|
||||
}
|
||||
}
|
||||
|
||||
void TLuaEngine::WaitForAll(std::vector<std::shared_ptr<TLuaResult>>& Results) {
|
||||
for (const auto& Result : Results) {
|
||||
while (!Result->Ready) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<TLuaResult> TLuaEngine::EnqueueScript(TLuaStateId StateID, const std::shared_ptr<std::string>& Script) {
|
||||
std::unique_lock Lock(mLuaStatesMutex);
|
||||
beammp_debug("enqueuing script into \"" + StateID + "\"");
|
||||
return mLuaStates.at(StateID)->EnqueueScript(Script);
|
||||
}
|
||||
|
||||
std::shared_ptr<TLuaResult> TLuaEngine::EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName) {
|
||||
std::shared_ptr<TLuaResult> TLuaEngine::EnqueueFunctionCall(TLuaStateId StateID, const std::string& FunctionName, const std::initializer_list<std::any>& Args) {
|
||||
std::unique_lock Lock(mLuaStatesMutex);
|
||||
beammp_debug("calling \"" + FunctionName + "\" in \"" + StateID + "\"");
|
||||
return mLuaStates.at(StateID)->EnqueueFunctionCall(FunctionName);
|
||||
return mLuaStates.at(StateID)->EnqueueFunctionCall(FunctionName, Args);
|
||||
}
|
||||
|
||||
void TLuaEngine::CollectAndInitPlugins() {
|
||||
@ -119,7 +127,7 @@ void TLuaEngine::EnsureStateExists(TLuaStateId StateId, const std::string& Name,
|
||||
mLuaStates[StateId] = std::move(DataPtr);
|
||||
RegisterEvent("onInit", StateId, "onInit");
|
||||
if (!DontCallOnInit) {
|
||||
auto Res = EnqueueFunctionCall(StateId, "onInit");
|
||||
auto Res = EnqueueFunctionCall(StateId, "onInit", {});
|
||||
Res->WaitUntilReady();
|
||||
if (Res->Error && Res->ErrorMessage != TLuaEngine::BeamMPFnNotFoundError) {
|
||||
beammp_lua_error("Calling \"onInit\" on \"" + StateId + "\" failed: " + Res->ErrorMessage);
|
||||
@ -133,21 +141,6 @@ void TLuaEngine::RegisterEvent(const std::string& EventName, TLuaStateId StateId
|
||||
mEvents[EventName][StateId].insert(FunctionName);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<TLuaResult>> TLuaEngine::TriggerEvent(const std::string& EventName) {
|
||||
std::unique_lock Lock(mEventsMutex);
|
||||
if (mEvents.find(EventName) == mEvents.end()) {
|
||||
return {};
|
||||
}
|
||||
std::vector<std::shared_ptr<TLuaResult>> Results;
|
||||
for (const auto& Event : mEvents.at(EventName)) {
|
||||
for (const auto& Function : Event.second) {
|
||||
beammp_debug("TriggerEvent: triggering \"" + Function + "\" on \"" + Event.first + "\"");
|
||||
Results.push_back(EnqueueFunctionCall(Event.first, Function));
|
||||
}
|
||||
}
|
||||
return Results;
|
||||
}
|
||||
|
||||
std::set<std::string> TLuaEngine::GetEventHandlersForState(const std::string& EventName, TLuaStateId StateId) {
|
||||
return mEvents[EventName][StateId];
|
||||
}
|
||||
@ -227,8 +220,8 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi
|
||||
: mName(Name)
|
||||
, mShutdown(Shutdown)
|
||||
, mStateId(StateId)
|
||||
, mState(luaL_newstate())
|
||||
, mEngine(&Engine) {
|
||||
mState = luaL_newstate();
|
||||
luaL_openlibs(mState);
|
||||
sol::state_view StateView(mState);
|
||||
// StateView.globals()["package"].get()
|
||||
@ -262,7 +255,7 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi
|
||||
return Lua_GetPlayerIdentifiers(ID);
|
||||
});
|
||||
Table.set_function("Sleep", &LuaAPI::MP::Sleep);
|
||||
Table.set_function("Set", &LuaAPI::MP::Set);
|
||||
//Table.set_function("Set", &LuaAPI::MP::Set);
|
||||
//Table.set_function("HttpsGET", &LuaAPI::MP::HttpsGET);
|
||||
//Table.set_function("HttpsPOST", &LuaAPI::MP::HttpsPOST);
|
||||
Table.create_named("Settings",
|
||||
@ -284,13 +277,13 @@ std::shared_ptr<TLuaResult> TLuaEngine::StateThreadData::EnqueueScript(const std
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::shared_ptr<TLuaResult> TLuaEngine::StateThreadData::EnqueueFunctionCall(const std::string& FunctionName) {
|
||||
std::shared_ptr<TLuaResult> TLuaEngine::StateThreadData::EnqueueFunctionCall(const std::string& FunctionName, const std::initializer_list<std::any>& Args) {
|
||||
beammp_debug("calling \"" + FunctionName + "\" in \"" + mName + "\"");
|
||||
auto Result = std::make_shared<TLuaResult>();
|
||||
Result->StateId = mStateId;
|
||||
Result->Function = FunctionName;
|
||||
std::unique_lock Lock(mStateFunctionQueueMutex);
|
||||
mStateFunctionQueue.push({ FunctionName, Result });
|
||||
mStateFunctionQueue.push({ FunctionName, Result, Args });
|
||||
return Result;
|
||||
}
|
||||
|
||||
@ -327,26 +320,29 @@ void TLuaEngine::StateThreadData::operator()() {
|
||||
auto FnNameResultPair = mStateFunctionQueue.front();
|
||||
mStateFunctionQueue.pop();
|
||||
Lock.unlock();
|
||||
FnNameResultPair.second->StateId = mStateId;
|
||||
beammp_debug("Running function \"" + FnNameResultPair.first + "\"");
|
||||
auto& StateId = std::get<0>(FnNameResultPair);
|
||||
auto& Result = std::get<1>(FnNameResultPair);
|
||||
auto& Args = std::get<1>(FnNameResultPair);
|
||||
Result->StateId = mStateId;
|
||||
beammp_debug("Running function \"" + std::get<0>(FnNameResultPair) + "\"");
|
||||
sol::state_view StateView(mState);
|
||||
auto Fn = StateView[FnNameResultPair.first];
|
||||
beammp_debug("Done running function \"" + FnNameResultPair.first + "\"");
|
||||
auto Fn = StateView[StateId];
|
||||
beammp_debug("Done running function \"" + StateId + "\"");
|
||||
if (Fn.valid() && Fn.get_type() == sol::type::function) {
|
||||
auto Res = Fn();
|
||||
auto Res = Fn(Args);
|
||||
if (Res.valid()) {
|
||||
FnNameResultPair.second->Error = false;
|
||||
FnNameResultPair.second->Result = std::move(Res);
|
||||
Result->Error = false;
|
||||
Result->Result = std::move(Res);
|
||||
} else {
|
||||
FnNameResultPair.second->Error = true;
|
||||
Result->Error = true;
|
||||
sol::error Err = Res;
|
||||
FnNameResultPair.second->ErrorMessage = Err.what();
|
||||
Result->ErrorMessage = Err.what();
|
||||
}
|
||||
FnNameResultPair.second->Ready = true;
|
||||
Result->Ready = true;
|
||||
} else {
|
||||
FnNameResultPair.second->Error = true;
|
||||
FnNameResultPair.second->ErrorMessage = BeamMPFnNotFoundError; // special error kind that we can ignore later
|
||||
FnNameResultPair.second->Ready = true;
|
||||
Result->Error = true;
|
||||
Result->ErrorMessage = BeamMPFnNotFoundError; // special error kind that we can ignore later
|
||||
Result->Ready = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -359,10 +355,3 @@ void TLuaResult::WaitUntilReady() {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
}
|
||||
|
||||
// AHHH
|
||||
std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr<TLuaArg> arg, bool Wait) {
|
||||
}
|
||||
|
||||
void TLuaArg::PushArgs(lua_State* State) {
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
|
||||
#include "LuaAPI.h"
|
||||
|
||||
TNetwork::TNetwork(TServer& Server, TPPSMonitor& PPSMonitor, TResourceManager& ResourceManager)
|
||||
: mServer(Server)
|
||||
, mPPSMonitor(PPSMonitor)
|
||||
@ -289,14 +291,27 @@ void TNetwork::Authentication(const TConnection& ClientConnection) {
|
||||
|
||||
return true;
|
||||
});
|
||||
auto Futures = LuaAPI::MP::Engine->TriggerEvent("onPlayerAuth", Client->GetName(), Client->GetRoles(), Client->IsGuest());
|
||||
TLuaEngine::WaitForAll(Futures);
|
||||
bool NotAllowed = std::any_of(Futures.begin(), Futures.end(),
|
||||
[](const std::shared_ptr<TLuaResult>& Result) {
|
||||
return !Result->Error && Result->Result.is<int>() && bool(Result->Result.as<int>());
|
||||
});
|
||||
std::string Reason;
|
||||
bool NotAllowedWithReason = std::any_of(Futures.begin(), Futures.end(),
|
||||
[&Reason](const std::shared_ptr<TLuaResult>& Result) -> bool {
|
||||
if (!Result->Error && Result->Result.is<std::string>()) {
|
||||
Reason = Result->Result.as<std::string>();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
auto arg = std::make_unique<TLuaArg>(TLuaArg { { Client->GetName(), Client->GetRoles(), Client->IsGuest() } });
|
||||
std::any Res = TriggerLuaEvent("onPlayerAuth", false, nullptr, std::move(arg), true);
|
||||
if (Res.type() == typeid(int) && std::any_cast<int>(Res)) {
|
||||
if (NotAllowed) {
|
||||
ClientKick(*Client, "you are not allowed on the server!");
|
||||
return;
|
||||
} else if (Res.type() == typeid(std::string)) {
|
||||
ClientKick(*Client, std::any_cast<std::string>(Res));
|
||||
} else if (NotAllowedWithReason) {
|
||||
ClientKick(*Client, Reason);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -563,7 +578,8 @@ void TNetwork::OnDisconnect(const std::weak_ptr<TClient>& ClientPtr, bool kicked
|
||||
Packet = ("L") + c.GetName() + (" left the server!");
|
||||
SendToAll(&c, Packet, false, true);
|
||||
Packet.clear();
|
||||
TriggerLuaEvent(("onPlayerDisconnect"), false, nullptr, std::make_unique<TLuaArg>(TLuaArg { { c.GetID() } }), false);
|
||||
auto Futures = LuaAPI::MP::Engine->TriggerEvent("onPlayerDisconnect", c.GetID());
|
||||
beammp_ignore(Futures);
|
||||
if (c.GetTCPSock())
|
||||
CloseSocketProper(c.GetTCPSock());
|
||||
if (c.GetDownSock())
|
||||
@ -597,13 +613,13 @@ void TNetwork::OnConnect(const std::weak_ptr<TClient>& c) {
|
||||
auto LockedClient = c.lock();
|
||||
LockedClient->SetID(OpenID());
|
||||
beammp_info("Assigned ID " + std::to_string(LockedClient->GetID()) + " to " + LockedClient->GetName());
|
||||
TriggerLuaEvent("onPlayerConnecting", false, nullptr, std::make_unique<TLuaArg>(TLuaArg { { LockedClient->GetID() } }), false);
|
||||
beammp_ignore(LuaAPI::MP::Engine->TriggerEvent("onPlayerConnecting", LockedClient->GetID()));
|
||||
SyncResources(*LockedClient);
|
||||
if (LockedClient->GetStatus() < 0)
|
||||
return;
|
||||
(void)Respond(*LockedClient, "M" + Application::Settings.MapName, true); //Send the Map on connect
|
||||
beammp_info(LockedClient->GetName() + " : Connected");
|
||||
TriggerLuaEvent("onPlayerJoining", false, nullptr, std::make_unique<TLuaArg>(TLuaArg { { LockedClient->GetID() } }), false);
|
||||
beammp_ignore(LuaAPI::MP::Engine->TriggerEvent("onPlayerJoining", LockedClient->GetID()));
|
||||
}
|
||||
|
||||
void TNetwork::SyncResources(TClient& c) {
|
||||
@ -802,7 +818,7 @@ bool TNetwork::SyncClient(const std::weak_ptr<TClient>& c) {
|
||||
// ignore error
|
||||
(void)SendToAll(LockedClient.get(), ("JWelcome ") + LockedClient->GetName() + "!", false, true);
|
||||
|
||||
TriggerLuaEvent(("onPlayerJoin"), false, nullptr, std::make_unique<TLuaArg>(TLuaArg { { LockedClient->GetID() } }), false);
|
||||
beammp_ignore(LuaAPI::MP::Engine->TriggerEvent("onPlayerJoin", LockedClient->GetID()));
|
||||
LockedClient->SetIsSyncing(true);
|
||||
bool Return = false;
|
||||
bool res = true;
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <any>
|
||||
#include <sstream>
|
||||
|
||||
#include "LuaAPI.h"
|
||||
|
||||
#undef GetObject //Fixes Windows
|
||||
|
||||
#include "Json.h"
|
||||
@ -119,17 +121,25 @@ void TServer::GlobalParser(const std::weak_ptr<TClient>& Client, std::string Pac
|
||||
#endif
|
||||
Network.SendToAll(LockedClient.get(), Packet, false, true);
|
||||
return;
|
||||
case 'C':
|
||||
case 'C': {
|
||||
#ifdef DEBUG
|
||||
beammp_debug(std::string(("got 'C' packet: '")) + Packet + ("' (") + std::to_string(Packet.size()) + (")"));
|
||||
#endif
|
||||
if (Packet.length() < 4 || Packet.find(':', 3) == std::string::npos)
|
||||
break;
|
||||
Res = TriggerLuaEvent("onChatMessage", false, nullptr, std::make_unique<TLuaArg>(TLuaArg { { LockedClient->GetID(), LockedClient->GetName(), Packet.substr(Packet.find(':', 3) + 1) } }), true);
|
||||
if (std::any_cast<int>(Res))
|
||||
auto Futures = LuaAPI::MP::Engine->TriggerEvent("onChatMessage", LockedClient->GetID(), LockedClient->GetName(), Packet.substr(Packet.find(':', 3) + 1));
|
||||
TLuaEngine::WaitForAll(Futures);
|
||||
if (std::any_of(Futures.begin(), Futures.end(),
|
||||
[](const std::shared_ptr<TLuaResult>& Elem) {
|
||||
return !Elem->Error
|
||||
&& Elem->Result.is<int>()
|
||||
&& bool(Elem->Result.as<int>());
|
||||
})) {
|
||||
break;
|
||||
}
|
||||
Network.SendToAll(nullptr, Packet, true, true);
|
||||
return;
|
||||
}
|
||||
case 'E':
|
||||
#ifdef DEBUG
|
||||
beammp_debug(std::string(("got 'E' packet: '")) + Packet + ("' (") + std::to_string(Packet.size()) + (")"));
|
||||
@ -154,7 +164,7 @@ void TServer::HandleEvent(TClient& c, const std::string& Data) {
|
||||
Name = t;
|
||||
break;
|
||||
case 2:
|
||||
TriggerLuaEvent(Name, false, nullptr, std::make_unique<TLuaArg>(TLuaArg { { c.GetID(), t } }), false);
|
||||
beammp_ignore(LuaAPI::MP::Engine->TriggerEvent(Name, c.GetID(), t));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -207,9 +217,14 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ
|
||||
|
||||
std::string CarJson = Packet.substr(5);
|
||||
Packet = "Os:" + c.GetRoles() + ":" + c.GetName() + ":" + std::to_string(c.GetID()) + "-" + std::to_string(CarID) + ":" + CarJson;
|
||||
auto Res = TriggerLuaEvent(("onVehicleSpawn"), false, nullptr, std::make_unique<TLuaArg>(TLuaArg { { c.GetID(), CarID, Packet.substr(3) } }), true);
|
||||
auto Futures = LuaAPI::MP::Engine->TriggerEvent("onVehicleSpawn", c.GetID(), CarID, Packet.substr(3));
|
||||
TLuaEngine::WaitForAll(Futures);
|
||||
bool ShouldntSpawn = std::any_of(Futures.begin(), Futures.end(),
|
||||
[](const std::shared_ptr<TLuaResult>& Result) {
|
||||
return !Result->Error && Result->Result.is<int>() && Result->Result.as<int>() != 0;
|
||||
});
|
||||
|
||||
if (ShouldSpawn(c, CarJson, CarID) && std::any_cast<int>(Res) == 0) {
|
||||
if (ShouldSpawn(c, CarJson, CarID) && !ShouldntSpawn) {
|
||||
c.AddNewCar(CarID, Packet);
|
||||
Network.SendToAll(nullptr, Packet, true, true);
|
||||
} else {
|
||||
@ -235,14 +250,17 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ
|
||||
VID = stoi(vid);
|
||||
}
|
||||
if (PID != -1 && VID != -1 && PID == c.GetID()) {
|
||||
auto Res = TriggerLuaEvent(("onVehicleEdited"), false, nullptr,
|
||||
std::make_unique<TLuaArg>(TLuaArg { { c.GetID(), VID, Packet.substr(3) } }),
|
||||
true);
|
||||
auto Futures = LuaAPI::MP::Engine->TriggerEvent("onVehicleEdited", c.GetID(), VID, Packet.substr(3));
|
||||
TLuaEngine::WaitForAll(Futures);
|
||||
bool ShouldntAllow = std::any_of(Futures.begin(), Futures.end(),
|
||||
[](const std::shared_ptr<TLuaResult>& Result) {
|
||||
return !Result->Error && Result->Result.is<int>() && Result->Result.as<int>() != 0;
|
||||
});
|
||||
|
||||
auto FoundPos = Packet.find('{');
|
||||
FoundPos = FoundPos == std::string::npos ? 0 : FoundPos; // attempt at sanitizing this
|
||||
if ((c.GetUnicycleID() != VID || IsUnicycle(c, Packet.substr(FoundPos)))
|
||||
&& std::any_cast<int>(Res) == 0) {
|
||||
&& !ShouldntAllow) {
|
||||
Network.SendToAll(&c, Packet, false, true);
|
||||
Apply(c, VID, Packet);
|
||||
} else {
|
||||
@ -272,8 +290,7 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ
|
||||
c.SetUnicycleID(-1);
|
||||
}
|
||||
Network.SendToAll(nullptr, Packet, true, true);
|
||||
TriggerLuaEvent(("onVehicleDeleted"), false, nullptr,
|
||||
std::make_unique<TLuaArg>(TLuaArg { { c.GetID(), VID } }), false);
|
||||
beammp_ignore(LuaAPI::MP::Engine->TriggerEvent("onVehicleDeleted", c.GetID(), VID));
|
||||
c.DeleteCar(VID);
|
||||
beammp_debug(c.GetName() + (" deleted car with ID ") + std::to_string(VID));
|
||||
}
|
||||
@ -293,9 +310,7 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ
|
||||
|
||||
if (PID != -1 && VID != -1 && PID == c.GetID()) {
|
||||
Data = Data.substr(Data.find('{'));
|
||||
TriggerLuaEvent("onVehicleReset", false, nullptr,
|
||||
std::make_unique<TLuaArg>(TLuaArg { { c.GetID(), VID, Data } }),
|
||||
false);
|
||||
beammp_ignore(LuaAPI::MP::Engine->TriggerEvent("onVehicleReset", c.GetID(), VID, Data));
|
||||
Network.SendToAll(&c, Packet, false, true);
|
||||
}
|
||||
return;
|
||||
|
10
src/main.cpp
10
src/main.cpp
@ -1,5 +1,6 @@
|
||||
#include "Common.h"
|
||||
#include "Http.h"
|
||||
#include "LuaAPI.h"
|
||||
#include "TConfig.h"
|
||||
#include "THeartbeatThread.h"
|
||||
#include "TLuaEngine.h"
|
||||
@ -48,10 +49,15 @@ int main(int argc, char** argv) {
|
||||
|
||||
bool Shutdown = false;
|
||||
Application::RegisterShutdownHandler([&Shutdown] { Shutdown = true; });
|
||||
Application::RegisterShutdownHandler([] { TriggerLuaEvent("onShutdown", false, nullptr, {}, true); });
|
||||
Application::RegisterShutdownHandler([] {
|
||||
auto Futures = LuaAPI::MP::Engine->TriggerEvent("onShutdown");
|
||||
TLuaEngine::WaitForAll(Futures);
|
||||
});
|
||||
|
||||
TServer Server(argc, argv);
|
||||
TConfig Config;
|
||||
TLuaEngine LuaEngine;
|
||||
LuaEngine.SetServer(&Server);
|
||||
|
||||
if (Config.Failed()) {
|
||||
beammp_info("Closing in 10 seconds");
|
||||
@ -64,7 +70,7 @@ int main(int argc, char** argv) {
|
||||
TPPSMonitor PPSMonitor(Server);
|
||||
THeartbeatThread Heartbeat(ResourceManager, Server);
|
||||
TNetwork Network(Server, PPSMonitor, ResourceManager);
|
||||
TLuaEngine LuaEngine(Server, Network);
|
||||
LuaEngine.SetNetwork(&Network);
|
||||
PPSMonitor.SetNetwork(Network);
|
||||
Application::Console().InitializeLuaConsole(LuaEngine);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user