mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2026-02-16 02:30:54 +00:00
Add more safety on some memory handling
This commit is contained in:
@@ -7,8 +7,8 @@
|
|||||||
#include <any>
|
#include <any>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <mutex>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
std::string GetFileName() const;
|
std::string GetFileName() const;
|
||||||
lua_State* GetState();
|
lua_State* GetState();
|
||||||
const lua_State* GetState() const;
|
const lua_State* GetState() const;
|
||||||
char* GetOrigin();
|
std::string GetOrigin();
|
||||||
std::mutex Lock;
|
std::mutex Lock;
|
||||||
void Reload();
|
void Reload();
|
||||||
Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console = false);
|
Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console = false);
|
||||||
@@ -73,6 +73,6 @@ public:
|
|||||||
void SetStopThread(bool StopThread) { _StopThread = StopThread; }
|
void SetStopThread(bool StopThread) { _StopThread = StopThread; }
|
||||||
bool GetStopThread() const { return _StopThread; }
|
bool GetStopThread() const { return _StopThread; }
|
||||||
};
|
};
|
||||||
int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* args);
|
int CallFunction(Lua* lua, const std::string& FuncName, std::unique_ptr<LuaArg> args);
|
||||||
int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, LuaArg* arg, bool Wait);
|
int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::unique_ptr<LuaArg> arg, bool Wait);
|
||||||
extern std::set<std::unique_ptr<Lua>> PluginEngine;
|
extern std::set<std::unique_ptr<Lua>> PluginEngine;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ typedef unsigned long DWORD, *PDWORD, *LPDWORD;
|
|||||||
std::vector<std::string> QConsoleOut;
|
std::vector<std::string> QConsoleOut;
|
||||||
std::string CInputBuff;
|
std::string CInputBuff;
|
||||||
std::mutex MLock;
|
std::mutex MLock;
|
||||||
Lua* LuaConsole;
|
std::unique_ptr<Lua> LuaConsole;
|
||||||
void HandleInput(const std::string& cmd) {
|
void HandleInput(const std::string& cmd) {
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
if (cmd == "exit") {
|
if (cmd == "exit") {
|
||||||
@@ -130,7 +130,7 @@ void SetupConsole() {
|
|||||||
}
|
}
|
||||||
void ConsoleInit() {
|
void ConsoleInit() {
|
||||||
SetupConsole();
|
SetupConsole();
|
||||||
LuaConsole = new Lua(true);
|
LuaConsole = std::make_unique<Lua>(true);
|
||||||
printf("> ");
|
printf("> ");
|
||||||
std::thread In(ReadCin);
|
std::thread In(ReadCin);
|
||||||
In.detach();
|
In.detach();
|
||||||
|
|||||||
@@ -13,10 +13,10 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
LuaArg* CreateArg(lua_State* L, int T, int S) {
|
std::unique_ptr<LuaArg> CreateArg(lua_State* L, int T, int S) {
|
||||||
if (S > T)
|
if (S > T)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
auto* temp = new LuaArg;
|
std::unique_ptr<LuaArg> temp(new LuaArg);
|
||||||
for (int C = S; C <= T; C++) {
|
for (int C = S; C <= T; C++) {
|
||||||
if (lua_isstring(L, C)) {
|
if (lua_isstring(L, C)) {
|
||||||
temp->args.emplace_back(std::string(lua_tostring(L, C)));
|
temp->args.emplace_back(std::string(lua_tostring(L, C)));
|
||||||
@@ -52,11 +52,11 @@ void SendError(lua_State* L, const std::string& msg) {
|
|||||||
}
|
}
|
||||||
warn(a + Sec(" | Incorrect Call of ") + msg);
|
warn(a + Sec(" | Incorrect Call of ") + msg);
|
||||||
}
|
}
|
||||||
int Trigger(Lua* lua, const std::string& R, LuaArg* arg) {
|
int Trigger(Lua* lua, const std::string& R, std::unique_ptr<LuaArg> arg) {
|
||||||
std::lock_guard<std::mutex> lockGuard(lua->Lock);
|
std::lock_guard<std::mutex> lockGuard(lua->Lock);
|
||||||
std::packaged_task<int()> task([lua, R, arg] { return CallFunction(lua, R, arg); });
|
std::packaged_task<int(std::unique_ptr<LuaArg>)> task([lua, R](std::unique_ptr<LuaArg> arg) { return CallFunction(lua, R, std::move(arg)); });
|
||||||
std::future<int> f1 = task.get_future();
|
std::future<int> f1 = task.get_future();
|
||||||
std::thread t(std::move(task));
|
std::thread t(std::move(task), std::move(arg));
|
||||||
t.detach();
|
t.detach();
|
||||||
auto status = f1.wait_for(std::chrono::seconds(5));
|
auto status = f1.wait_for(std::chrono::seconds(5));
|
||||||
if (status != std::future_status::timeout)
|
if (status != std::future_status::timeout)
|
||||||
@@ -64,11 +64,11 @@ int Trigger(Lua* lua, const std::string& R, LuaArg* arg) {
|
|||||||
SendError(lua->GetState(), R + " took too long to respond");
|
SendError(lua->GetState(), R + " took too long to respond");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int FutureWait(Lua* lua, const std::string& R, LuaArg* arg, bool Wait) {
|
int FutureWait(Lua* lua, const std::string& R, std::unique_ptr<LuaArg> arg, bool Wait) {
|
||||||
Assert(lua);
|
Assert(lua);
|
||||||
std::packaged_task<int()> task([lua, R, arg] { return Trigger(lua, R, arg); });
|
std::packaged_task<int(std::unique_ptr<LuaArg>)> task([lua, R](std::unique_ptr<LuaArg> arg) { return Trigger(lua, R, std::move(arg)); });
|
||||||
std::future<int> f1 = task.get_future();
|
std::future<int> f1 = task.get_future();
|
||||||
std::thread t(std::move(task));
|
std::thread t(std::move(task), std::move(arg));
|
||||||
t.detach();
|
t.detach();
|
||||||
int T = 0;
|
int T = 0;
|
||||||
if (Wait)
|
if (Wait)
|
||||||
@@ -78,16 +78,16 @@ int FutureWait(Lua* lua, const std::string& R, LuaArg* arg, bool Wait) {
|
|||||||
return f1.get();
|
return f1.get();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, LuaArg* arg, bool Wait) {
|
int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::unique_ptr<LuaArg> arg, bool Wait) {
|
||||||
int R = 0;
|
int R = 0;
|
||||||
for (auto& Script : PluginEngine) {
|
for (auto& Script : PluginEngine) {
|
||||||
if (Script->IsRegistered(Event)) {
|
if (Script->IsRegistered(Event)) {
|
||||||
if (local) {
|
if (local) {
|
||||||
if (Script->GetPluginName() == Caller->GetPluginName()) {
|
if (Script->GetPluginName() == Caller->GetPluginName()) {
|
||||||
R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait);
|
R += FutureWait(Script.get(), Script->GetRegistered(Event), std::move(arg), Wait);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait);
|
R += FutureWait(Script.get(), Script->GetRegistered(Event), std::move(arg), Wait);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return R;
|
return R;
|
||||||
@@ -553,15 +553,11 @@ void Lua::Reload() {
|
|||||||
CallFunction(this, Sec("onInit"), nullptr);
|
CallFunction(this, Sec("onInit"), nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char* Lua::GetOrigin() {
|
std::string Lua::GetOrigin() {
|
||||||
std::string T = GetFileName().substr(GetFileName().find('\\'));
|
return GetFileName().substr(GetFileName().find('\\'));
|
||||||
char* Data = new char[T.size()];
|
|
||||||
ZeroMemory(Data, T.size());
|
|
||||||
memcpy(Data, T.c_str(), T.size());
|
|
||||||
return Data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* Arg) {
|
int CallFunction(Lua* lua, const std::string& FuncName, std::unique_ptr<LuaArg> Arg) {
|
||||||
lua_State* luaState = lua->GetState();
|
lua_State* luaState = lua->GetState();
|
||||||
lua_getglobal(luaState, FuncName.c_str());
|
lua_getglobal(luaState, FuncName.c_str());
|
||||||
if (lua_isfunction(luaState, -1)) {
|
if (lua_isfunction(luaState, -1)) {
|
||||||
@@ -569,11 +565,9 @@ int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* Arg) {
|
|||||||
if (Arg != nullptr) {
|
if (Arg != nullptr) {
|
||||||
Size = int(Arg->args.size());
|
Size = int(Arg->args.size());
|
||||||
Arg->PushArgs(luaState);
|
Arg->PushArgs(luaState);
|
||||||
delete Arg;
|
|
||||||
Arg = nullptr;
|
|
||||||
}
|
}
|
||||||
int R = 0;
|
int R = 0;
|
||||||
char* Origin = lua->GetOrigin();
|
std::string Origin = lua->GetOrigin();
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
__try {
|
__try {
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
@@ -584,10 +578,9 @@ int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* Arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
} __except (Handle(GetExceptionInformation(), Origin)) {
|
} __except (Handle(GetExceptionInformation(), Origin.data())) {
|
||||||
}
|
}
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
delete[] Origin;
|
|
||||||
}
|
}
|
||||||
ClearStack(luaState);
|
ClearStack(luaState);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -672,5 +665,6 @@ fs::file_time_type Lua::GetLastWrite() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Lua::~Lua() {
|
Lua::~Lua() {
|
||||||
|
info("closing lua state");
|
||||||
lua_close(luaState);
|
lua_close(luaState);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ void VehicleParser(Client*c,const std::string& Pckt){
|
|||||||
Packet = "Os:"+c->GetRole()+":"+c->GetName()+":"+std::to_string(c->GetID())+"-"+std::to_string(CarID)+Packet.substr(4);
|
Packet = "Os:"+c->GetRole()+":"+c->GetName()+":"+std::to_string(c->GetID())+"-"+std::to_string(CarID)+Packet.substr(4);
|
||||||
if(c->GetCarCount() >= MaxCars ||
|
if(c->GetCarCount() >= MaxCars ||
|
||||||
TriggerLuaEvent(Sec("onVehicleSpawn"),false,nullptr,
|
TriggerLuaEvent(Sec("onVehicleSpawn"),false,nullptr,
|
||||||
new LuaArg{{c->GetID(),CarID,Packet.substr(3)}},true)){
|
std::unique_ptr<LuaArg>(new LuaArg{{c->GetID(),CarID,Packet.substr(3)}}),
|
||||||
|
true)){
|
||||||
Respond(c,Packet,true);
|
Respond(c,Packet,true);
|
||||||
std::string Destroy = "Od:" + std::to_string(c->GetID())+"-"+std::to_string(CarID);
|
std::string Destroy = "Od:" + std::to_string(c->GetID())+"-"+std::to_string(CarID);
|
||||||
Respond(c,Destroy,true);
|
Respond(c,Destroy,true);
|
||||||
@@ -67,7 +68,8 @@ void VehicleParser(Client*c,const std::string& Pckt){
|
|||||||
}
|
}
|
||||||
if(PID != -1 && VID != -1 && PID == c->GetID()){
|
if(PID != -1 && VID != -1 && PID == c->GetID()){
|
||||||
if(!TriggerLuaEvent(Sec("onVehicleEdited"),false,nullptr,
|
if(!TriggerLuaEvent(Sec("onVehicleEdited"),false,nullptr,
|
||||||
new LuaArg{{c->GetID(),VID,Packet.substr(3)}},true)) {
|
std::unique_ptr<LuaArg>(new LuaArg{{c->GetID(),VID,Packet.substr(3)}}),
|
||||||
|
true)) {
|
||||||
SendToAll(c, Packet, false, true);
|
SendToAll(c, Packet, false, true);
|
||||||
Apply(c,VID,Packet);
|
Apply(c,VID,Packet);
|
||||||
}else{
|
}else{
|
||||||
@@ -87,7 +89,7 @@ void VehicleParser(Client*c,const std::string& Pckt){
|
|||||||
if(PID != -1 && VID != -1 && PID == c->GetID()){
|
if(PID != -1 && VID != -1 && PID == c->GetID()){
|
||||||
SendToAll(nullptr,Packet,true,true);
|
SendToAll(nullptr,Packet,true,true);
|
||||||
TriggerLuaEvent(Sec("onVehicleDeleted"),false,nullptr,
|
TriggerLuaEvent(Sec("onVehicleDeleted"),false,nullptr,
|
||||||
new LuaArg{{c->GetID(),VID}},false);
|
std::unique_ptr<LuaArg>(new LuaArg{{c->GetID(),VID}}),false);
|
||||||
c->DeleteCar(VID);
|
c->DeleteCar(VID);
|
||||||
debug(c->GetName() + Sec(" deleted car with ID ") + std::to_string(VID));
|
debug(c->GetName() + Sec(" deleted car with ID ") + std::to_string(VID));
|
||||||
}
|
}
|
||||||
@@ -107,7 +109,7 @@ void SyncClient(Client*c){
|
|||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
Respond(c,Sec("Sn")+c->GetName(),true);
|
Respond(c,Sec("Sn")+c->GetName(),true);
|
||||||
SendToAll(c,Sec("JWelcome ")+c->GetName()+"!",false,true);
|
SendToAll(c,Sec("JWelcome ")+c->GetName()+"!",false,true);
|
||||||
TriggerLuaEvent(Sec("onPlayerJoin"),false,nullptr,new LuaArg{{c->GetID()}},false);
|
TriggerLuaEvent(Sec("onPlayerJoin"),false,nullptr,std::unique_ptr<LuaArg>(new LuaArg{{c->GetID()}}),false);
|
||||||
for (Client*client : CI->Clients) {
|
for (Client*client : CI->Clients) {
|
||||||
if(client != nullptr){
|
if(client != nullptr){
|
||||||
if (client != c) {
|
if (client != c) {
|
||||||
@@ -144,7 +146,7 @@ void HandleEvent(Client*c ,const std::string&Data){
|
|||||||
Name = t;
|
Name = t;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
TriggerLuaEvent(Name, false, nullptr,new LuaArg{{c->GetID(),t}},false);
|
TriggerLuaEvent(Name, false, nullptr,std::unique_ptr<LuaArg>(new LuaArg{{c->GetID(),t}}),false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -189,9 +191,10 @@ void GlobalParser(Client*c, const std::string& Pack){
|
|||||||
return;
|
return;
|
||||||
case 'C':
|
case 'C':
|
||||||
if(Packet.length() < 4 || Packet.find(':', 3) == std::string::npos)break;
|
if(Packet.length() < 4 || Packet.find(':', 3) == std::string::npos)break;
|
||||||
if (TriggerLuaEvent(Sec("onChatMessage"), false, nullptr,new LuaArg{
|
if (TriggerLuaEvent(Sec("onChatMessage"), false, nullptr,
|
||||||
|
std::unique_ptr<LuaArg>(new LuaArg{
|
||||||
{c->GetID(), c->GetName(), Packet.substr(Packet.find(':', 3) + 1)}
|
{c->GetID(), c->GetName(), Packet.substr(Packet.find(':', 3) + 1)}
|
||||||
},true))break;
|
}),true))break;
|
||||||
SendToAll(nullptr, Packet, true, true);
|
SendToAll(nullptr, Packet, true, true);
|
||||||
return;
|
return;
|
||||||
case 'E':
|
case 'E':
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ void OnDisconnect(Client*c,bool kicked){
|
|||||||
Packet = Sec("L")+c->GetName()+Sec(" Left the server!");
|
Packet = Sec("L")+c->GetName()+Sec(" Left the server!");
|
||||||
SendToAll(c, Packet,false,true);
|
SendToAll(c, Packet,false,true);
|
||||||
Packet.clear();
|
Packet.clear();
|
||||||
TriggerLuaEvent(Sec("onPlayerDisconnect"),false,nullptr,new LuaArg{{c->GetID()}},false);
|
TriggerLuaEvent(Sec("onPlayerDisconnect"),false,nullptr,std::unique_ptr<LuaArg>(new LuaArg{{c->GetID()}}),false);
|
||||||
c->ClearCars();
|
c->ClearCars();
|
||||||
CI->RemoveClient(c); ///Removes the Client from existence
|
CI->RemoveClient(c); ///Removes the Client from existence
|
||||||
}
|
}
|
||||||
@@ -80,10 +80,10 @@ void OnConnect(Client*c){
|
|||||||
info(Sec("Client connected"));
|
info(Sec("Client connected"));
|
||||||
c->SetID(OpenID());
|
c->SetID(OpenID());
|
||||||
info(Sec("Assigned ID ") + std::to_string(c->GetID()) + Sec(" to ") + c->GetName());
|
info(Sec("Assigned ID ") + std::to_string(c->GetID()) + Sec(" to ") + c->GetName());
|
||||||
TriggerLuaEvent(Sec("onPlayerConnecting"),false,nullptr,new LuaArg{{c->GetID()}},false);
|
TriggerLuaEvent(Sec("onPlayerConnecting"),false,nullptr,std::unique_ptr<LuaArg>(new LuaArg{{c->GetID()}}),false);
|
||||||
SyncResources(c);
|
SyncResources(c);
|
||||||
if(c->GetStatus() < 0)return;
|
if(c->GetStatus() < 0)return;
|
||||||
Respond(c,"M"+MapName,true); //Send the Map on connect
|
Respond(c,"M"+MapName,true); //Send the Map on connect
|
||||||
info(c->GetName() + Sec(" : Connected"));
|
info(c->GetName() + Sec(" : Connected"));
|
||||||
TriggerLuaEvent(Sec("onPlayerJoining"),false,nullptr,new LuaArg{{c->GetID()}},false);
|
TriggerLuaEvent(Sec("onPlayerJoining"),false,nullptr,std::unique_ptr<LuaArg>(new LuaArg{{c->GetID()}}),false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "Startup.h"
|
#include "Startup.h"
|
||||||
#include "CustomAssert.h"
|
#include "CustomAssert.h"
|
||||||
|
#include "Curl/curl.h"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
[[noreturn]] void loop(){
|
[[noreturn]] void loop(){
|
||||||
@@ -11,6 +12,8 @@
|
|||||||
}
|
}
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
DebugPrintTID();
|
DebugPrintTID();
|
||||||
|
// curl needs to be initialized to properly deallocate its resources later
|
||||||
|
Assert(curl_global_init(CURL_GLOBAL_DEFAULT) == CURLE_OK);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::thread t1(loop);
|
std::thread t1(loop);
|
||||||
t1.detach();
|
t1.detach();
|
||||||
@@ -23,5 +26,7 @@ int main(int argc, char* argv[]) {
|
|||||||
HBInit();
|
HBInit();
|
||||||
StatInit();
|
StatInit();
|
||||||
NetMain();
|
NetMain();
|
||||||
|
// clean up curl at the end to be sure
|
||||||
|
curl_global_cleanup();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user