Add lots of memory safety to client interface

This commit is contained in:
Lion Kortlepel 2020-11-08 02:50:17 +01:00
parent 96668add6e
commit 26383d5346
8 changed files with 38 additions and 29 deletions

View File

@ -14,6 +14,7 @@
#include <vector>
#include <chrono>
#include <set>
#include <algorithm>
struct VData{
int ID = -1;
@ -57,17 +58,23 @@ public:
int GetID();
};
struct ClientInterface{
std::set<Client*> Clients;
void RemoveClient(Client *c){
std::set<std::unique_ptr<Client>> Clients;
void RemoveClient(Client*& c){
Assert(c);
c->ClearCars();
Clients.erase(c);
delete c;
auto Iter = std::find_if(Clients.begin(), Clients.end(), [&](auto& ptr) {
return c == ptr.get();
});
Assert(Iter != Clients.end());
if (Iter == Clients.end()) {
return;
}
Clients.erase(Iter);
c = nullptr;
}
void AddClient(Client *c){
void AddClient(Client*&& c){
Assert(c);
Clients.insert(c);
Clients.insert(std::move(std::unique_ptr<Client>(c)));
}
int Size(){
return int(Clients.size());

View File

@ -14,7 +14,7 @@
void WebsocketInit();
std::string GetPlayers(){
std::string Return;
for(Client* c : CI->Clients){
for(auto& c : CI->Clients){
if(c != nullptr){
Return += c->GetName() + ";";
}

View File

@ -240,9 +240,10 @@ int lua_Sleep(lua_State* L) {
return 1;
}
Client* GetClient(int ID) {
for (Client* c : CI->Clients) {
if (c != nullptr && c->GetID() == ID)
return c;
for (auto& c : CI->Clients) {
if (c != nullptr && c->GetID() == ID) {
return c.get();
}
}
return nullptr;
}
@ -295,7 +296,7 @@ int lua_GetDID(lua_State* L) {
int lua_GetAllPlayers(lua_State* L) {
lua_newtable(L);
int i = 1;
for (Client* c : CI->Clients) {
for (auto& c : CI->Clients) {
if (c == nullptr)
continue;
lua_pushinteger(L, c->GetID());

View File

@ -81,7 +81,7 @@ void Check(Hold* S){
}
int Max(){
int M = MaxPlayers;
for(Client*c : CI->Clients){
for(auto& c : CI->Clients){
if(c != nullptr){
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->SetRole(Role);
c->SetDID(DID);
CI->AddClient(c);
InitClient(c);
Client& Client = *c;
CI->AddClient(std::move(c));
InitClient(&Client);
}
std::pair<int,int> Parse(const std::string& msg){
std::stringstream ss(msg);
@ -175,7 +176,7 @@ void Identification(SOCKET TCPSock,Hold*S,RSA*Skey){
}
DebugPrintTIDInternal(std::string("Client(") + Name + ")");
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->GetDID() == DID){
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));

View File

@ -125,9 +125,9 @@ void SyncClient(Client*c){
Respond(c,Sec("Sn")+c->GetName(),true);
SendToAll(c,Sec("JWelcome ")+c->GetName()+"!",false,true);
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 != c) {
if (client.get() != c) {
for (VData *v : client->GetAllCars()) {
if(v != nullptr){
Respond(c, v->Data, true);

View File

@ -12,7 +12,7 @@ int OpenID(){
bool found;
do {
found = true;
for (Client *c : CI->Clients){
for (auto& c : CI->Clients){
if(c != nullptr){
if(c->GetID() == ID){
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){
if (!Self)Assert(c);
char C = Data.at(0);
for(Client*client : CI->Clients){
for(auto& client : CI->Clients){
if(client != nullptr) {
if (Self || client != c) {
if (Self || client.get() != c) {
if (client->isSynced) {
if (Rel || C == 'W' || C == 'Y' || C == 'V' || C == 'E') {
if (C == 'O' || C == 'T' ||
Data.length() > 1000)SendLarge(client, Data);
else TCPSend(client, Data);
} else UDPSend(client, Data);
Data.length() > 1000)SendLarge(client.get(), Data);
else TCPSend(client.get(), Data);
} else UDPSend(client.get(), Data);
}
}
}
@ -51,7 +51,7 @@ void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){
}
void UpdatePlayers(){
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() + ",";
}
Packet = Packet.substr(0,Packet.length()-1);

View File

@ -14,7 +14,7 @@ void Monitor() {
StatReport = "-";
return;
}
for (Client *c : CI->Clients) {
for (auto& c : CI->Clients) {
if (c != nullptr && c->GetCarCount() > 0) {
C++;
V += c->GetCarCount();

View File

@ -311,11 +311,11 @@ void LOOP() {
ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/
uint8_t ID = Data.at(0) - 1;
for (Client* c : CI->Clients) {
for (auto& c : CI->Clients) {
if (c != nullptr && c->GetID() == ID) {
c->SetUDPAddr(client);
c->isConnected = true;
UDPParser(c, Data.substr(2));
UDPParser(c.get(), Data.substr(2));
}
}
} catch (const std::exception& e) {
@ -357,11 +357,11 @@ void LOOP() {
ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/
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) {
c->SetUDPAddr(client);
c->isConnected = true;
UDPParser(c, Data.substr(2));
UDPParser(c.get(), Data.substr(2));
}
}
} catch (const std::exception& e) {