mirror of
https://github.com/SantaSpeen/BeamMP-Server.git
synced 2025-08-18 12:45:36 +00:00
Add lots of memory safety to client interface
This commit is contained in:
parent
96668add6e
commit
26383d5346
@ -14,6 +14,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
struct VData{
|
struct VData{
|
||||||
int ID = -1;
|
int ID = -1;
|
||||||
@ -57,17 +58,23 @@ public:
|
|||||||
int GetID();
|
int GetID();
|
||||||
};
|
};
|
||||||
struct ClientInterface{
|
struct ClientInterface{
|
||||||
std::set<Client*> Clients;
|
std::set<std::unique_ptr<Client>> Clients;
|
||||||
void RemoveClient(Client *c){
|
void RemoveClient(Client*& c){
|
||||||
Assert(c);
|
Assert(c);
|
||||||
c->ClearCars();
|
c->ClearCars();
|
||||||
Clients.erase(c);
|
auto Iter = std::find_if(Clients.begin(), Clients.end(), [&](auto& ptr) {
|
||||||
delete c;
|
return c == ptr.get();
|
||||||
|
});
|
||||||
|
Assert(Iter != Clients.end());
|
||||||
|
if (Iter == Clients.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Clients.erase(Iter);
|
||||||
c = nullptr;
|
c = nullptr;
|
||||||
}
|
}
|
||||||
void AddClient(Client *c){
|
void AddClient(Client*&& c){
|
||||||
Assert(c);
|
Assert(c);
|
||||||
Clients.insert(c);
|
Clients.insert(std::move(std::unique_ptr<Client>(c)));
|
||||||
}
|
}
|
||||||
int Size(){
|
int Size(){
|
||||||
return int(Clients.size());
|
return int(Clients.size());
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
void WebsocketInit();
|
void WebsocketInit();
|
||||||
std::string GetPlayers(){
|
std::string GetPlayers(){
|
||||||
std::string Return;
|
std::string Return;
|
||||||
for(Client* c : CI->Clients){
|
for(auto& c : CI->Clients){
|
||||||
if(c != nullptr){
|
if(c != nullptr){
|
||||||
Return += c->GetName() + ";";
|
Return += c->GetName() + ";";
|
||||||
}
|
}
|
||||||
|
@ -240,9 +240,10 @@ int lua_Sleep(lua_State* L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
Client* GetClient(int ID) {
|
Client* GetClient(int ID) {
|
||||||
for (Client* c : CI->Clients) {
|
for (auto& c : CI->Clients) {
|
||||||
if (c != nullptr && c->GetID() == ID)
|
if (c != nullptr && c->GetID() == ID) {
|
||||||
return c;
|
return c.get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -295,7 +296,7 @@ int lua_GetDID(lua_State* L) {
|
|||||||
int lua_GetAllPlayers(lua_State* L) {
|
int lua_GetAllPlayers(lua_State* L) {
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (Client* c : CI->Clients) {
|
for (auto& c : CI->Clients) {
|
||||||
if (c == nullptr)
|
if (c == nullptr)
|
||||||
continue;
|
continue;
|
||||||
lua_pushinteger(L, c->GetID());
|
lua_pushinteger(L, c->GetID());
|
||||||
|
@ -81,7 +81,7 @@ void Check(Hold* S){
|
|||||||
}
|
}
|
||||||
int Max(){
|
int Max(){
|
||||||
int M = MaxPlayers;
|
int M = MaxPlayers;
|
||||||
for(Client*c : CI->Clients){
|
for(auto& c : CI->Clients){
|
||||||
if(c != nullptr){
|
if(c != nullptr){
|
||||||
if(c->GetRole() == Sec("MDEV"))M++;
|
if(c->GetRole() == Sec("MDEV"))M++;
|
||||||
}
|
}
|
||||||
@ -94,8 +94,9 @@ void CreateClient(SOCKET TCPSock,const std::string &Name, const std::string &DID
|
|||||||
c->SetName(Name);
|
c->SetName(Name);
|
||||||
c->SetRole(Role);
|
c->SetRole(Role);
|
||||||
c->SetDID(DID);
|
c->SetDID(DID);
|
||||||
CI->AddClient(c);
|
Client& Client = *c;
|
||||||
InitClient(c);
|
CI->AddClient(std::move(c));
|
||||||
|
InitClient(&Client);
|
||||||
}
|
}
|
||||||
std::pair<int,int> Parse(const std::string& msg){
|
std::pair<int,int> Parse(const std::string& msg){
|
||||||
std::stringstream ss(msg);
|
std::stringstream ss(msg);
|
||||||
@ -175,7 +176,7 @@ void Identification(SOCKET TCPSock,Hold*S,RSA*Skey){
|
|||||||
}
|
}
|
||||||
DebugPrintTIDInternal(std::string("Client(") + Name + ")");
|
DebugPrintTIDInternal(std::string("Client(") + Name + ")");
|
||||||
debug(Sec("Name -> ") + Name + Sec(", Role -> ") + Role + Sec(", ID -> ") + DID);
|
debug(Sec("Name -> ") + Name + Sec(", Role -> ") + Role + Sec(", ID -> ") + DID);
|
||||||
for(Client*c: CI->Clients){
|
for(auto& c : CI->Clients){
|
||||||
if(c != nullptr){
|
if(c != nullptr){
|
||||||
if(c->GetDID() == DID){
|
if(c->GetDID() == DID){
|
||||||
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
|
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
|
||||||
|
@ -125,9 +125,9 @@ void SyncClient(Client*c){
|
|||||||
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,std::unique_ptr<LuaArg>(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 (auto& client : CI->Clients) {
|
||||||
if(client != nullptr){
|
if(client != nullptr){
|
||||||
if (client != c) {
|
if (client.get() != c) {
|
||||||
for (VData *v : client->GetAllCars()) {
|
for (VData *v : client->GetAllCars()) {
|
||||||
if(v != nullptr){
|
if(v != nullptr){
|
||||||
Respond(c, v->Data, true);
|
Respond(c, v->Data, true);
|
||||||
|
@ -12,7 +12,7 @@ int OpenID(){
|
|||||||
bool found;
|
bool found;
|
||||||
do {
|
do {
|
||||||
found = true;
|
found = true;
|
||||||
for (Client *c : CI->Clients){
|
for (auto& c : CI->Clients){
|
||||||
if(c != nullptr){
|
if(c != nullptr){
|
||||||
if(c->GetID() == ID){
|
if(c->GetID() == ID){
|
||||||
found = false;
|
found = false;
|
||||||
@ -35,15 +35,15 @@ void Respond(Client*c, const std::string& MSG, bool Rel){
|
|||||||
void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){
|
void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){
|
||||||
if (!Self)Assert(c);
|
if (!Self)Assert(c);
|
||||||
char C = Data.at(0);
|
char C = Data.at(0);
|
||||||
for(Client*client : CI->Clients){
|
for(auto& client : CI->Clients){
|
||||||
if(client != nullptr) {
|
if(client != nullptr) {
|
||||||
if (Self || client != c) {
|
if (Self || client.get() != c) {
|
||||||
if (client->isSynced) {
|
if (client->isSynced) {
|
||||||
if (Rel || C == 'W' || C == 'Y' || C == 'V' || C == 'E') {
|
if (Rel || C == 'W' || C == 'Y' || C == 'V' || C == 'E') {
|
||||||
if (C == 'O' || C == 'T' ||
|
if (C == 'O' || C == 'T' ||
|
||||||
Data.length() > 1000)SendLarge(client, Data);
|
Data.length() > 1000)SendLarge(client.get(), Data);
|
||||||
else TCPSend(client, Data);
|
else TCPSend(client.get(), Data);
|
||||||
} else UDPSend(client, Data);
|
} else UDPSend(client.get(), Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){
|
|||||||
}
|
}
|
||||||
void UpdatePlayers(){
|
void UpdatePlayers(){
|
||||||
std::string Packet = Sec("Ss") + std::to_string(CI->Size())+"/"+std::to_string(MaxPlayers) + ":";
|
std::string Packet = Sec("Ss") + std::to_string(CI->Size())+"/"+std::to_string(MaxPlayers) + ":";
|
||||||
for (Client*c : CI->Clients) {
|
for (auto& c : CI->Clients) {
|
||||||
if(c != nullptr)Packet += c->GetName() + ",";
|
if(c != nullptr)Packet += c->GetName() + ",";
|
||||||
}
|
}
|
||||||
Packet = Packet.substr(0,Packet.length()-1);
|
Packet = Packet.substr(0,Packet.length()-1);
|
||||||
|
@ -14,7 +14,7 @@ void Monitor() {
|
|||||||
StatReport = "-";
|
StatReport = "-";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (Client *c : CI->Clients) {
|
for (auto& c : CI->Clients) {
|
||||||
if (c != nullptr && c->GetCarCount() > 0) {
|
if (c != nullptr && c->GetCarCount() > 0) {
|
||||||
C++;
|
C++;
|
||||||
V += c->GetCarCount();
|
V += c->GetCarCount();
|
||||||
|
@ -311,11 +311,11 @@ void LOOP() {
|
|||||||
ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet
|
ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet
|
||||||
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/
|
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/
|
||||||
uint8_t ID = Data.at(0) - 1;
|
uint8_t ID = Data.at(0) - 1;
|
||||||
for (Client* c : CI->Clients) {
|
for (auto& c : CI->Clients) {
|
||||||
if (c != nullptr && c->GetID() == ID) {
|
if (c != nullptr && c->GetID() == ID) {
|
||||||
c->SetUDPAddr(client);
|
c->SetUDPAddr(client);
|
||||||
c->isConnected = true;
|
c->isConnected = true;
|
||||||
UDPParser(c, Data.substr(2));
|
UDPParser(c.get(), Data.substr(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
@ -357,11 +357,11 @@ void LOOP() {
|
|||||||
ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet
|
ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet
|
||||||
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/
|
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/
|
||||||
uint8_t ID = uint8_t(Data.at(0)) - 1;
|
uint8_t ID = uint8_t(Data.at(0)) - 1;
|
||||||
for (Client* c : CI->Clients) {
|
for (auto& c : CI->Clients) {
|
||||||
if (c != nullptr && c->GetID() == ID) {
|
if (c != nullptr && c->GetID() == ID) {
|
||||||
c->SetUDPAddr(client);
|
c->SetUDPAddr(client);
|
||||||
c->isConnected = true;
|
c->isConnected = true;
|
||||||
UDPParser(c, Data.substr(2));
|
UDPParser(c.get(), Data.substr(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user