diff --git a/include/TServer.h b/include/TServer.h index f057012..b8c308b 100644 --- a/include/TServer.h +++ b/include/TServer.h @@ -18,6 +18,7 @@ public: TServer(int argc, char** argv); + void InsertClient(std::shared_ptr Ptr); std::weak_ptr InsertNewClient(); void RemoveClient(std::weak_ptr); // in Fn, return true to continue, return false to break diff --git a/include/TTCPServer.h b/include/TTCPServer.h index 4c0a960..3a6322b 100644 --- a/include/TTCPServer.h +++ b/include/TTCPServer.h @@ -17,7 +17,7 @@ public: bool TCPSend(TClient& c, const std::string& Data); void SendLarge(TClient& c, std::string Data); void Respond(TClient& c, const std::string& MSG, bool Rel); - std::weak_ptr CreateClient(SOCKET TCPSock); + std::shared_ptr CreateClient(SOCKET TCPSock); std::string TCPRcv(TClient& c); void ClientKick(TClient& c, const std::string& R); @@ -32,6 +32,7 @@ public: void SyncResources(TClient& c); void UpdatePlayers(); + private: std::optional> mUDPServer { std::nullopt }; TServer& mServer; diff --git a/src/TServer.cpp b/src/TServer.cpp index b1dec53..b6398a2 100644 --- a/src/TServer.cpp +++ b/src/TServer.cpp @@ -269,3 +269,9 @@ void TServer::Apply(TClient& c, int VID, const std::string& pckt) { Veh.Accept(writer); c.SetCarData(VID, Header + Buffer.GetString()); } + +void TServer::InsertClient(std::shared_ptr NewClient) { + debug("inserting client (" + std::to_string(ClientCount()) + ")"); + WriteLock Lock(mClientsMutex); + (void)mClients.insert(NewClient); +} diff --git a/src/TTCPServer.cpp b/src/TTCPServer.cpp index fb8cf17..c6020bb 100644 --- a/src/TTCPServer.cpp +++ b/src/TTCPServer.cpp @@ -57,32 +57,29 @@ void TTCPServer::HandleDownload(SOCKET TCPSock) { } void TTCPServer::Authentication(SOCKET TCPSock) { - auto c = CreateClient(TCPSock); + auto Client = CreateClient(TCPSock); std::string Rc; info("Identifying new client..."); - Assert(!c.expired()); - - auto LockedClient = c.lock(); - Rc = TCPRcv(*LockedClient); + Rc = TCPRcv(*Client); if (Rc.size() > 3 && Rc.substr(0, 2) == "VC") { Rc = Rc.substr(2); if (Rc.length() > 4 || Rc != Application::ClientVersion()) { - ClientKick(*LockedClient, "Outdated Version!"); + ClientKick(*Client, "Outdated Version!"); return; } } else { - ClientKick(*LockedClient, "Invalid version header!"); + ClientKick(*Client, "Invalid version header!"); return; } - TCPSend(*LockedClient, "S"); + TCPSend(*Client, "S"); - Rc = TCPRcv(*LockedClient); + Rc = TCPRcv(*Client); if (Rc.size() > 50) { - ClientKick(*LockedClient, "Invalid Key!"); + ClientKick(*Client, "Invalid Key!"); return; } @@ -95,26 +92,26 @@ void TTCPServer::Authentication(SOCKET TCPSock) { json::Document AuthResponse; AuthResponse.Parse(Rc.c_str()); if (Rc == "-1" || AuthResponse.HasParseError()) { - ClientKick(*LockedClient, "Invalid key! Please restart your game."); + ClientKick(*Client, "Invalid key! Please restart your game."); return; } if (AuthResponse["username"].IsString() && AuthResponse["roles"].IsString() && AuthResponse["guest"].IsBool()) { - LockedClient->SetName(AuthResponse["username"].GetString()); - LockedClient->SetRoles(AuthResponse["roles"].GetString()); - LockedClient->SetIsGuest(AuthResponse["guest"].GetBool()); + Client->SetName(AuthResponse["username"].GetString()); + Client->SetRoles(AuthResponse["roles"].GetString()); + Client->SetIsGuest(AuthResponse["guest"].GetBool()); } else { - ClientKick(*LockedClient, "Invalid authentication data!"); + ClientKick(*Client, "Invalid authentication data!"); return; } - debug("Name -> " + LockedClient->GetName() + ", Guest -> " + std::to_string(LockedClient->IsGuest()) + ", Roles -> " + LockedClient->GetRoles()); + debug("Name -> " + Client->GetName() + ", Guest -> " + std::to_string(Client->IsGuest()) + ", Roles -> " + Client->GetRoles()); debug("There are " + std::to_string(mServer.ClientCount()) + " known clients"); mServer.ForEachClient([&](std::weak_ptr ClientPtr) -> bool { if (!ClientPtr.expired()) { auto Cl = ClientPtr.lock(); - info("Client Iteration: Name -> " + LockedClient->GetName() + ", Guest -> " + std::to_string(LockedClient->IsGuest()) + ", Roles -> " + LockedClient->GetRoles()); - if (Cl->GetName() == LockedClient->GetName() && Cl->IsGuest() == LockedClient->IsGuest()) { + info("Client Iteration: Name -> " + Client->GetName() + ", Guest -> " + std::to_string(Client->IsGuest()) + ", Roles -> " + Client->GetRoles()); + if (Cl->GetName() == Client->GetName() && Cl->IsGuest() == Client->IsGuest()) { info("New client matched with current iteration"); info("Old client (" + Cl->GetName() + ") kicked: Reconnecting"); CloseSocketProper(Cl->GetTCPSock()); @@ -125,27 +122,28 @@ void TTCPServer::Authentication(SOCKET TCPSock) { return true; }); - auto arg = std::make_unique(TLuaArg { { LockedClient->GetName(), LockedClient->GetRoles(), LockedClient->IsGuest() } }); + auto arg = std::make_unique(TLuaArg { { Client->GetName(), Client->GetRoles(), Client->IsGuest() } }); std::any Res = TriggerLuaEvent("onPlayerAuth", false, nullptr, std::move(arg), true); std::string Type = Res.type().name(); if (Type.find("int") != std::string::npos && std::any_cast(Res)) { - ClientKick(*LockedClient, "you are not allowed on the server!"); + ClientKick(*Client, "you are not allowed on the server!"); return; } else if (Type.find("string") != std::string::npos) { - ClientKick(*LockedClient, std::any_cast(Res)); + ClientKick(*Client, std::any_cast(Res)); return; } if (mServer.ClientCount() < size_t(Application::Settings.MaxPlayers)) { info("Identification success"); - TCPClient(c); + mServer.InsertClient(Client); + TCPClient(Client); } else - ClientKick(*LockedClient, "Server full!"); + ClientKick(*Client, "Server full!"); } -std::weak_ptr TTCPServer::CreateClient(SOCKET TCPSock) { - auto c = mServer.InsertNewClient(); - c.lock()->SetTCPSock(TCPSock); +std::shared_ptr TTCPServer::CreateClient(SOCKET TCPSock) { + auto c = std::make_shared(mServer); + c->SetTCPSock(TCPSock); return c; }