diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 4901a46ebb..b8468395c0 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -71,12 +71,12 @@ #include "net/SimHeaders.h" #include -#define MAX_BULLETSYNC_DISTANCE 400.0f -#define MAX_EXPLOSION_SYNC_DISTANCE 400.0f +#define MAX_BULLETSYNC_DISTANCE 400.0f +#define MAX_EXPLOSION_SYNC_DISTANCE 400.0f #define MAX_PROJECTILE_SYNC_DISTANCE 400.0f -#define RELEASE_MIN_CLIENT_VERSION "1.6.0-0.00000" -#define FIREBALLDESTRUCT_MIN_CLIENT_VERSION "1.6.0-9.22199" +#define RELEASE_MIN_CLIENT_VERSION "1.6.0-0.00000" +#define FIREBALLDESTRUCT_MIN_CLIENT_VERSION "1.6.0-9.22199" #ifndef WIN32 #include @@ -403,14 +403,14 @@ CGame::~CGame() // Clear our global pointer g_pGame = NULL; - // Remove our console control handler - #ifdef WIN32 +// Remove our console control handler +#ifdef WIN32 SetConsoleCtrlHandler(ConsoleEventHandler, FALSE); - #else +#else signal(SIGTERM, SIG_DFL); signal(SIGINT, SIG_DFL); signal(SIGPIPE, SIG_DFL); - #endif +#endif } void CGame::GetTag(char* szInfoTag, int iInfoTag) @@ -528,8 +528,7 @@ void CGame::DoPulse() // Process our resource stop/restart queue CLOCK_CALL1(m_pResourceManager->ProcessQueue();); - if (GetTickCount64_() + m_iClientTriggeredEventsIntervalMs > m_lClientTriggeredEventsLastCheck) - ProcessClientTriggeredEventSpam(); + ProcessClientTriggeredEventSpam(); // Delete all items requested CLOCK_CALL1(m_ElementDeleter.DoDeleteAll();); @@ -657,9 +656,9 @@ bool CGame::Start(int iArgumentCount, char* szArguments[]) // Encrypt crash dumps for uploading HandleCrashDumpEncryption(); - // Check Windows server is using correctly compiled Lua dll - #ifndef MTA_DEBUG - #ifdef WIN32 +// Check Windows server is using correctly compiled Lua dll +#ifndef MTA_DEBUG + #ifdef WIN32 HMODULE hModule = LoadLibrary("lua5.1.dll"); // Release server should not have this function PVOID pFunc = static_cast(GetProcAddress(hModule, "luaX_is_apicheck_enabled")); @@ -669,8 +668,8 @@ bool CGame::Start(int iArgumentCount, char* szArguments[]) CLogger::ErrorPrintf("Problem with Lua dll\n"); return false; } - #endif #endif +#endif // Read some settings m_pACLManager->SetFileName(m_pMainConfig->GetAccessControlListFile().c_str()); @@ -880,16 +879,16 @@ bool CGame::Start(int iArgumentCount, char* szArguments[]) m_pPlayerManager->SetScriptDebugging(m_pScriptDebugging); - // Set our console control handler - #ifdef WIN32 +// Set our console control handler +#ifdef WIN32 SetConsoleCtrlHandler(ConsoleEventHandler, TRUE); - // Hide the close box - // DeleteMenu ( GetSystemMenu ( GetConsoleWindow(), FALSE ), SC_CLOSE, MF_BYCOMMAND ); - #else +// Hide the close box +// DeleteMenu ( GetSystemMenu ( GetConsoleWindow(), FALSE ), SC_CLOSE, MF_BYCOMMAND ); +#else signal(SIGTERM, &sighandler); signal(SIGINT, &sighandler); signal(SIGPIPE, SIG_IGN); - #endif +#endif // Add our builtin events AddBuiltInEvents(); @@ -1309,10 +1308,11 @@ void CGame::JoinPlayer(CPlayer& Player) marker.Set("Start"); // Let him join - Player.Send(CPlayerJoinCompletePacket( - Player.GetID(), m_pMapManager->GetRootElement()->GetID(), m_pMainConfig->GetHTTPDownloadType(), m_pMainConfig->GetHTTPPort(), - m_pMainConfig->GetHTTPDownloadURL().c_str(), m_pMainConfig->GetHTTPMaxConnectionsPerClient(), m_pMainConfig->GetEnableClientChecks(), - m_pMainConfig->IsVoiceEnabled(), m_pMainConfig->GetVoiceSampleRate(), m_pMainConfig->GetVoiceQuality(), m_pMainConfig->GetVoiceBitrate(), m_pMainConfig->GetServerName().c_str())); + Player.Send(CPlayerJoinCompletePacket(Player.GetID(), m_pMapManager->GetRootElement()->GetID(), m_pMainConfig->GetHTTPDownloadType(), + m_pMainConfig->GetHTTPPort(), m_pMainConfig->GetHTTPDownloadURL().c_str(), + m_pMainConfig->GetHTTPMaxConnectionsPerClient(), m_pMainConfig->GetEnableClientChecks(), + m_pMainConfig->IsVoiceEnabled(), m_pMainConfig->GetVoiceSampleRate(), m_pMainConfig->GetVoiceQuality(), + m_pMainConfig->GetVoiceBitrate(), m_pMainConfig->GetServerName().c_str())); marker.Set("CPlayerJoinCompletePacket"); @@ -1753,13 +1753,13 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) strExtra = SStringX(strExtraTemp); strPlayerVersion = SStringX(strPlayerVersionTemp); } - #if MTASA_VERSION_TYPE < VERSION_TYPE_UNSTABLE +#if MTASA_VERSION_TYPE < VERSION_TYPE_UNSTABLE if (atoi(ExtractVersionStringBuildNumber(Packet.GetPlayerVersion())) != 0) { // Use player version from packet if it contains a valid build number strPlayerVersion = Packet.GetPlayerVersion(); } - #endif +#endif SString strIP = pPlayer->GetSourceIP(); SString strIPAndSerial("IP: %s Serial: %s Version: %s", strIP.c_str(), strSerial.c_str(), strPlayerVersion.c_str()); @@ -1897,7 +1897,7 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) return; } - #if MTASA_VERSION_TYPE > VERSION_TYPE_UNSTABLE +#if MTASA_VERSION_TYPE > VERSION_TYPE_UNSTABLE if (Packet.GetPlayerVersion().length() > 0 && Packet.GetPlayerVersion() != pPlayer->GetPlayerVersion()) { // Tell the console @@ -1907,7 +1907,7 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) DisconnectPlayer(this, *pPlayer, CPlayerDisconnectedPacket::VERSION_MISMATCH); return; } - #endif +#endif PlayerCompleteConnect(pPlayer); } @@ -2791,23 +2791,23 @@ void CGame::Packet_ProjectileSync(CProjectileSyncPacket& Packet) } CLuaArguments arguments; - arguments.PushNumber(Packet.m_ucWeaponType); // "weaponType" - arguments.PushNumber(vecPosition.fX); // "posX" - arguments.PushNumber(vecPosition.fY); // "posY" - arguments.PushNumber(vecPosition.fZ); // "posZ" - arguments.PushNumber(Packet.m_fForce); // "force" + arguments.PushNumber(Packet.m_ucWeaponType); // "weaponType" + arguments.PushNumber(vecPosition.fX); // "posX" + arguments.PushNumber(vecPosition.fY); // "posY" + arguments.PushNumber(vecPosition.fZ); // "posZ" + arguments.PushNumber(Packet.m_fForce); // "force" CElement* pTarget = nullptr; if (Packet.m_bHasTarget && Packet.m_TargetID != INVALID_ELEMENT_ID) pTarget = CElementIDs::GetElement(Packet.m_TargetID); - arguments.PushElement(pTarget); // "target" - arguments.PushNumber(Packet.m_vecRotation.fX); // "rotX" - arguments.PushNumber(Packet.m_vecRotation.fY); // "rotY" - arguments.PushNumber(Packet.m_vecRotation.fZ); // "rotZ" - arguments.PushNumber(Packet.m_vecMoveSpeed.fX); // "velX" - arguments.PushNumber(Packet.m_vecMoveSpeed.fY); // "velY" - arguments.PushNumber(Packet.m_vecMoveSpeed.fZ); // "velZ" + arguments.PushElement(pTarget); // "target" + arguments.PushNumber(Packet.m_vecRotation.fX); // "rotX" + arguments.PushNumber(Packet.m_vecRotation.fY); // "rotY" + arguments.PushNumber(Packet.m_vecRotation.fZ); // "rotZ" + arguments.PushNumber(Packet.m_vecMoveSpeed.fX); // "velX" + arguments.PushNumber(Packet.m_vecMoveSpeed.fY); // "velY" + arguments.PushNumber(Packet.m_vecMoveSpeed.fZ); // "velZ" // Trigger Lua event and see if we are allowed to continue if (!pPlayer->CallEvent("onPlayerProjectileCreation", arguments)) @@ -4511,7 +4511,7 @@ void CGame::SendPacketBatchEnd() bool CGame::IsBulletSyncActive() { bool bConfigSaysEnable = m_pMainConfig->GetBulletSyncEnabled(); -#if 0 // No auto bullet sync as there are some problems with it +#if 0 // No auto bullet sync as there are some problems with it bool bGlitchesSayEnable = ( m_Glitches [ GLITCH_FASTFIRE ] || m_Glitches [ GLITCH_CROUCHBUG ] ); #else bool bGlitchesSayEnable = false; @@ -4711,17 +4711,42 @@ void CGame::RegisterClientTriggeredEventUsage(CPlayer* pPlayer) if (!pPlayer || !pPlayer->IsPlayer() || pPlayer->IsBeingDeleted()) return; - m_mapClientTriggeredEvents[pPlayer]++; + auto now = GetTickCount64_(); + + // If key/player doesn't exist in map, store time of entry + if (m_mapClientTriggeredEvents.find(pPlayer) == m_mapClientTriggeredEvents.end()) + m_mapClientTriggeredEvents[pPlayer].m_llTicks = now; + + // Only increment if we haven't reached the interval time already + if (now - m_mapClientTriggeredEvents[pPlayer].m_llTicks <= m_iClientTriggeredEventsIntervalMs) + m_mapClientTriggeredEvents[pPlayer].m_uiCounter++; } void CGame::ProcessClientTriggeredEventSpam() { - for (const auto& [player, count]: m_mapClientTriggeredEvents) + for (auto it = m_mapClientTriggeredEvents.begin(); it != m_mapClientTriggeredEvents.end();) { - if (player && player->IsPlayer() && !player->IsBeingDeleted() && count > m_iMaxClientTriggeredEventsPerInterval) - player->CallEvent("onPlayerTriggerEventThreshold", {}); - } + const auto& [player, data] = *it; + bool remove = false; - m_mapClientTriggeredEvents.clear(); - m_lClientTriggeredEventsLastCheck = GetTickCount64_(); + if (player && player->IsPlayer() && !player->IsBeingDeleted()) + { + if (GetTickCount64_() - data.m_llTicks >= m_iClientTriggeredEventsIntervalMs) + { + if (data.m_uiCounter > m_iMaxClientTriggeredEventsPerInterval) + player->CallEvent("onPlayerTriggerEventThreshold", {}); + + remove = true; + } + } + else + { + remove = true; + } + + if (remove) + it = m_mapClientTriggeredEvents.erase(it); + else + it++; + } } diff --git a/Server/mods/deathmatch/logic/CGame.h b/Server/mods/deathmatch/logic/CGame.h index cce2d6fe8a..22e38aadf4 100644 --- a/Server/mods/deathmatch/logic/CGame.h +++ b/Server/mods/deathmatch/logic/CGame.h @@ -665,7 +665,12 @@ class CGame int m_iMaxClientTriggeredEventsPerInterval = 100; int m_iClientTriggeredEventsIntervalMs = 1000; - long long m_lClientTriggeredEventsLastCheck = 0; - std::map m_mapClientTriggeredEvents; + struct ClientTriggeredEventsInfo + { + long long m_llTicks = 0; + uint32_t m_uiCounter = 0; + }; + + std::map m_mapClientTriggeredEvents; };