Lua: Almost Working events, all triggers working

This commit is contained in:
Lion Kortlepel 2021-09-17 00:21:43 +02:00
parent cb1eb40def
commit a44050f0f1
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
9 changed files with 157 additions and 93 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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));

View File

@ -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");
}

View File

@ -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) {
}

View File

@ -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;

View File

@ -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;

View File

@ -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);