diff --git a/include/Client.h b/include/Client.h index 7defcbd..1cad3ca 100644 --- a/include/Client.h +++ b/include/Client.h @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -46,9 +47,13 @@ public: int GetID() const { return mID; } bool IsConnected() const { return mIsConnected; } bool IsSynced() const { return mIsSynced; } + bool IsSyncing() const { return mIsSyncing; } bool IsGuest() const { return mIsGuest; } void SetIsGuest(bool NewIsGuest) { mIsGuest = NewIsGuest; } void SetIsSynced(bool NewIsSynced) { mIsSynced = NewIsSynced; } + void SetIsSyncing(bool NewIsSyncing) { mIsSyncing = NewIsSyncing; } + void EnqueueMissedPacketDuringSyncing(const std::string& Packet) { mMissedPacketsDuringSyncing.push(Packet); } + size_t MissedPacketQueueSize() const { return mMissedPacketsDuringSyncing.size(); } void SetIsConnected(bool NewIsConnected) { mIsConnected = NewIsConnected; } TServer& Server() const; void UpdatePingTime(); @@ -58,6 +63,8 @@ private: TServer& mServer; bool mIsConnected = false; bool mIsSynced = false; + bool mIsSyncing = false; + std::queue mMissedPacketsDuringSyncing; bool mIsGuest = false; std::mutex mVehicleDataMutex; TSetOfVehicleData mVehicleData; diff --git a/include/TTCPServer.h b/include/TTCPServer.h index 3fd1a09..2178808 100644 --- a/include/TTCPServer.h +++ b/include/TTCPServer.h @@ -16,7 +16,7 @@ public: void operator()() override; - bool TCPSend(TClient& c, const std::string& Data); + bool TCPSend(TClient& c, const std::string& Data, bool IsSync = false); void SendLarge(TClient& c, std::string Data); void Respond(TClient& c, const std::string& MSG, bool Rel); std::shared_ptr CreateClient(SOCKET TCPSock); diff --git a/src/TTCPServer.cpp b/src/TTCPServer.cpp index c8c38ff..0fcdbfe 100644 --- a/src/TTCPServer.cpp +++ b/src/TTCPServer.cpp @@ -80,7 +80,7 @@ void TTCPServer::Authentication(SOCKET TCPSock) { ClientKick(*Client, "Invalid version header!"); return; } - TCPSend(*Client, "S"); + TCPSend(*Client, "S", false); Rc = TCPRcv(*Client); @@ -153,7 +153,12 @@ std::shared_ptr TTCPServer::CreateClient(SOCKET TCPSock) { return c; } -bool TTCPServer::TCPSend(TClient& c, const std::string& Data) { +bool TTCPServer::TCPSend(TClient& c, const std::string& Data, bool IsSync) { + if (c.IsSyncing() && !IsSync) { + c.EnqueueMissedPacketDuringSyncing(Data); + return true; + } else if (!c.IsSyncing() && c.IsSynced() && c.MissedPacketQueueSize() != 0) { + } int32_t Size, Sent; std::string Send(4, 0); Size = int32_t(Data.size()); @@ -265,7 +270,7 @@ std::string TTCPServer::TCPRcv(TClient& c) { void TTCPServer::ClientKick(TClient& c, const std::string& R) { info("Client kicked: " + R); - TCPSend(c, "E" + R); + TCPSend(c, "E" + R, false); c.SetStatus(-2); CloseSocketProper(c.GetTCPSock()); } @@ -374,7 +379,7 @@ void TTCPServer::SyncResources(TClient& c) { #ifndef DEBUG try { #endif - TCPSend(c, "P" + std::to_string(c.GetID())); + TCPSend(c, "P" + std::to_string(c.GetID()), false); std::string Data; while (c.GetStatus() > -1) { Data = TCPRcv(c); @@ -406,7 +411,7 @@ void TTCPServer::Parse(TClient& c, const std::string& Packet) { std::string ToSend = mResourceManager.FileList() + mResourceManager.FileSizes(); if (ToSend.empty()) ToSend = "-"; - TCPSend(c, ToSend); + TCPSend(c, ToSend, false); } return; default: @@ -418,11 +423,11 @@ void TTCPServer::SendFile(TClient& c, const std::string& Name) { info(c.GetName() + " requesting : " + Name.substr(Name.find_last_of('/'))); if (!std::filesystem::exists(Name)) { - TCPSend(c, "CO"); + TCPSend(c, "CO", false); warn("File " + Name + " could not be accessed!"); return; } else - TCPSend(c, "AG"); + TCPSend(c, "AG", false); ///Wait for connections int T = 0; @@ -515,7 +520,7 @@ void TTCPServer::SendLarge(TClient& c, std::string Data) { std::string CMP(Comp(Data)); Data = "ABG:" + CMP; } - TCPSend(c, Data); + TCPSend(c, Data, false); } void TTCPServer::Respond(TClient& c, const std::string& MSG, bool Rel) { @@ -524,7 +529,7 @@ void TTCPServer::Respond(TClient& c, const std::string& MSG, bool Rel) { if (C == 'O' || C == 'T' || MSG.length() > 1000) { SendLarge(c, MSG); } else { - TCPSend(c, MSG); + TCPSend(c, MSG, false); } } else { UDPServer().UDPSend(c, MSG); @@ -538,12 +543,14 @@ void TTCPServer::SyncClient(const std::weak_ptr& c) { auto LockedClient = c.lock(); if (LockedClient->IsSynced()) return; - LockedClient->SetIsSynced(true); + // Syncing, later set isSynced + // after syncing is done, we apply all packets they missed std::this_thread::sleep_for(std::chrono::seconds(1)); Respond(*LockedClient, ("Sn") + LockedClient->GetName(), true); UDPServer().SendToAll(LockedClient.get(), ("JWelcome ") + LockedClient->GetName() + "!", false, true); TriggerLuaEvent(("onPlayerJoin"), false, nullptr, std::make_unique(TLuaArg { { LockedClient->GetID() } }), false); bool Return = false; + LockedClient->SetIsSyncing(true); mServer.ForEachClient([&](const std::weak_ptr& ClientPtr) -> bool { if (!ClientPtr.expired()) { auto client = ClientPtr.lock(); @@ -565,9 +572,11 @@ void TTCPServer::SyncClient(const std::weak_ptr& c) { } return true; }); + LockedClient->SetIsSyncing(false); if (Return) { return; } + LockedClient->SetIsSynced(true); info(LockedClient->GetName() + (" is now synced!")); } diff --git a/src/TUDPServer.cpp b/src/TUDPServer.cpp index 2326496..3dbc202 100644 --- a/src/TUDPServer.cpp +++ b/src/TUDPServer.cpp @@ -102,7 +102,7 @@ void TUDPServer::SendToAll(TClient* c, const std::string& Data, bool Self, bool if (C == 'O' || C == 'T' || Data.length() > 1000) mTCPServer.SendLarge(*Client, Data); else - mTCPServer.TCPSend(*Client, Data); + mTCPServer.TCPSend(*Client, Data, false); } else UDPSend(*Client, Data); }