diff --git a/include/Client.h b/include/Client.h index d4bf8cb..dc96bab 100644 --- a/include/Client.h +++ b/include/Client.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -45,6 +46,8 @@ public: void SetIsSynced(bool NewIsSynced) { mIsSynced = NewIsSynced; } void SetIsConnected(bool NewIsConnected) { mIsConnected = NewIsConnected; } TServer& Server() const; + void UpdatePingTime(); + int SecondsSinceLastPing(); private: TServer& mServer; @@ -59,4 +62,5 @@ private: std::string mDID; int mStatus = 0; int mID = -1; + std::chrono::time_point mLastPingTime; }; diff --git a/include/TPPSMonitor.h b/include/TPPSMonitor.h index e2539b2..44a0ff4 100644 --- a/include/TPPSMonitor.h +++ b/include/TPPSMonitor.h @@ -12,9 +12,13 @@ public: void SetInternalPPS(int NewPPS) { mInternalPPS = NewPPS; } void IncrementInternalPPS() { ++mInternalPPS; } [[nodiscard]] int InternalPPS() const { return mInternalPPS; } + void SetTCPServer(TTCPServer& Server) { mTCPServer = std::ref(Server); } private: + TTCPServer& TCPServer() { return mTCPServer->get(); } + TServer& mServer; + std::optional> mTCPServer { std::nullopt }; bool mShutdown { false }; int mInternalPPS { 0 }; }; \ No newline at end of file diff --git a/include/TTCPServer.h b/include/TTCPServer.h index a6e8b49..f898e1b 100644 --- a/include/TTCPServer.h +++ b/include/TTCPServer.h @@ -32,7 +32,7 @@ public: bool CheckBytes(TClient& c, int32_t BytesRcv); void SyncResources(TClient& c); - void UpdatePlayers(); + void UpdatePlayer(TClient& Client); private: std::optional> mUDPServer { std::nullopt }; diff --git a/src/Client.cpp b/src/Client.cpp index b730131..8918fca 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -70,3 +70,12 @@ TServer& TClient::Server() const { TClient::TClient(TServer& Server) : mServer(Server) { } + +void TClient::UpdatePingTime() { + mLastPingTime = std::chrono::high_resolution_clock::now(); +} +int TClient::SecondsSinceLastPing() { + return std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - mLastPingTime) + .count(); +} diff --git a/src/TPPSMonitor.cpp b/src/TPPSMonitor.cpp index 9e2711b..eb42927 100644 --- a/src/TPPSMonitor.cpp +++ b/src/TPPSMonitor.cpp @@ -1,5 +1,6 @@ #include "TPPSMonitor.h" #include "Client.h" +#include "TTCPServer.h" TPPSMonitor::TPPSMonitor(TServer& Server) : mServer(Server) { @@ -15,6 +16,11 @@ TPPSMonitor::TPPSMonitor(TServer& Server) Start(); } void TPPSMonitor::operator()() { + while (!mTCPServer) { + // hard spi + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + std::vector> TimedOutClients; while (!mShutdown) { int C = 0, V = 0; if (mServer.ClientCount() == 0) { @@ -28,9 +34,16 @@ void TPPSMonitor::operator()() { C++; V += c->GetCarCount(); } + // kick on "no ping" + if (c->SecondsSinceLastPing() > 10) { + TimedOutClients.push_back(c); + } } return true; }); + for (auto& ClientToKick : TimedOutClients) { + TCPServer().ClientKick(*ClientToKick, "Timeout (no ping for >10 seconds)"); + } if (C == 0 || mInternalPPS == 0) { Application::SetPPS("-"); } else { diff --git a/src/TServer.cpp b/src/TServer.cpp index b6398a2..47a839c 100644 --- a/src/TServer.cpp +++ b/src/TServer.cpp @@ -93,7 +93,8 @@ void TServer::GlobalParser(std::weak_ptr Client, std::string Packet, TP return; case 'p': TCPServer.Respond(*LockedClient, ("p"), false); - TCPServer.UpdatePlayers(); + TCPServer.UpdatePlayer(*LockedClient); + LockedClient->UpdatePingTime(); return; case 'O': if (Packet.length() > 1000) { diff --git a/src/TTCPServer.cpp b/src/TTCPServer.cpp index 53da9ce..f82b130 100644 --- a/src/TTCPServer.cpp +++ b/src/TTCPServer.cpp @@ -260,6 +260,7 @@ std::string TTCPServer::TCPRcv(TClient& c) { void TTCPServer::ClientKick(TClient& c, const std::string& R) { info("Client kicked: " + R); TCPSend(c, "E" + R); + c.SetStatus(-2); CloseSocketProper(c.GetTCPSock()); } @@ -287,8 +288,7 @@ void TTCPServer::TCPClient(std::weak_ptr c) { } } -void TTCPServer::UpdatePlayers() { - debug("Update Players!"); +void TTCPServer::UpdatePlayer(TClient& Client) { std::string Packet = ("Ss") + std::to_string(mServer.ClientCount()) + "/" + std::to_string(Application::Settings.MaxPlayers) + ":"; mServer.ForEachClient([&](std::weak_ptr ClientPtr) -> bool { if (!ClientPtr.expired()) { @@ -298,7 +298,7 @@ void TTCPServer::UpdatePlayers() { return true; }); Packet = Packet.substr(0, Packet.length() - 1); - UDPServer().SendToAll(nullptr, Packet, true, true); + Respond(Client, Packet, true); } void TTCPServer::OnDisconnect(std::weak_ptr ClientPtr, bool kicked) { diff --git a/src/main.cpp b/src/main.cpp index 01d8dd4..9048c12 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,6 +55,7 @@ int main(int argc, char** argv) { TUDPServer UDPServer(Server, PPSMonitor, TCPServer); TLuaEngine LuaEngine(Server, TCPServer, UDPServer); TCPServer.SetUDPServer(UDPServer); + PPSMonitor.SetTCPServer(TCPServer); Application::Console().InitializeLuaConsole(LuaEngine); // TODO: replace