From 3864cee2f0ff8105ce198e390680724e6558ab8f Mon Sep 17 00:00:00 2001 From: Nico <122193236+Nico8340@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:54:35 +0100 Subject: [PATCH 1/8] New util New util function that allows to search for players by serial --- Server/mods/deathmatch/logic/CPlayerManager.cpp | 13 +++++++++++++ Server/mods/deathmatch/logic/CPlayerManager.h | 1 + 2 files changed, 14 insertions(+) diff --git a/Server/mods/deathmatch/logic/CPlayerManager.cpp b/Server/mods/deathmatch/logic/CPlayerManager.cpp index abdf923df7..bca9896fec 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/CPlayerManager.cpp @@ -138,6 +138,19 @@ CPlayer* CPlayerManager::Get(const char* szNick, bool bCaseSensitive) return NULL; } +CPlayer* CPlayerManager::GetBySerial(const SString& serial) noexcept +{ + for (auto& player : m_Players) + { + if (player->GetSerial() == serial) + { + return player; + } + } + + return nullptr; +} + void CPlayerManager::DeleteAll() { // Delete all the items in the list diff --git a/Server/mods/deathmatch/logic/CPlayerManager.h b/Server/mods/deathmatch/logic/CPlayerManager.h index bd503380f4..052eee9b03 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.h +++ b/Server/mods/deathmatch/logic/CPlayerManager.h @@ -40,6 +40,7 @@ class CPlayerManager CPlayer* Get(const NetServerPlayerID& PlayerSocket); CPlayer* Get(const char* szNick, bool bCaseSensitive = false); + CPlayer* GetBySerial(const SString& serial) noexcept; std::list::const_iterator IterBegin() { return m_Players.begin(); }; std::list::const_iterator IterEnd() { return m_Players.end(); }; From 1a9d402421100f5fb32e69a7b54cd30c00b9a916 Mon Sep 17 00:00:00 2001 From: Nico <122193236+Nico8340@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:54:56 +0100 Subject: [PATCH 2/8] New enum & logic New enum called SERIAL_DUPLICATE and logic that checks if there are no other players on the server having the same serial --- Client/mods/deathmatch/logic/CPacketHandler.cpp | 4 ++++ Client/mods/deathmatch/logic/CPacketHandler.h | 1 + Server/mods/deathmatch/logic/CGame.cpp | 13 +++++++++++++ .../logic/packets/CPlayerDisconnectedPacket.h | 1 + 4 files changed, 19 insertions(+) diff --git a/Client/mods/deathmatch/logic/CPacketHandler.cpp b/Client/mods/deathmatch/logic/CPacketHandler.cpp index ebf2ba5140..3142a6e4d2 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -572,6 +572,10 @@ void CPacketHandler::Packet_ServerDisconnected(NetBitStreamInterface& bitStream) strReason = _("Disconnected: Serial verification failed"); strErrorCode = _E("CD44"); break; + case ePlayerDisconnectType::SERIAL_DUPLICATE: + strReason = _("Disconnected: Serial already in use"); + strErrorCode = _E("CD50"); + break; case ePlayerDisconnectType::CONNECTION_DESYNC: strReason = _("Disconnected: Connection desync %s"); strErrorCode = _E("CD45"); diff --git a/Client/mods/deathmatch/logic/CPacketHandler.h b/Client/mods/deathmatch/logic/CPacketHandler.h index ca0f6f3d69..d2ed5c3bbd 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.h +++ b/Client/mods/deathmatch/logic/CPacketHandler.h @@ -38,6 +38,7 @@ class CPacketHandler ELEMENT_FAILURE, GENERAL_REFUSED, SERIAL_VERIFICATION, + SERIAL_DUPLICATE, CONNECTION_DESYNC, BAN, KICK, diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 9543e1e447..7c486d74ad 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -1798,6 +1798,19 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) return; } + // Check if another player is using the same serial + CPlayer* playerExisting = m_pPlayerManager->GetBySerial(strSerial); + + if (playerExisting) + { + // Tell the console + CLogger::LogPrintf("CONNECT: %s failed to connect (Serial already in use) (%s)\n", szNick, strIPAndSerial.c_str()); + + // Tell the player the problem + DisconnectPlayer(this, *pPlayer, CPlayerDisconnectedPacket::SERIAL_DUPLICATE); + return; + } + // Check the nick is valid if (!CheckNickProvided(szNick)) { diff --git a/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h index 82fdfbd1b0..22e884e721 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h @@ -35,6 +35,7 @@ class CPlayerDisconnectedPacket final : public CPacket ELEMENT_FAILURE, GENERAL_REFUSED, SERIAL_VERIFICATION, + SERIAL_DUPLICATE, CONNECTION_DESYNC, BAN, KICK, From 1ad0e7503c4e47d1ad7ae53bf96b7a9353c02e6f Mon Sep 17 00:00:00 2001 From: Nico <122193236+Nico8340@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:19:35 +0100 Subject: [PATCH 3/8] Make GetBySerial a constant --- Server/mods/deathmatch/logic/CPlayerManager.cpp | 2 +- Server/mods/deathmatch/logic/CPlayerManager.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Server/mods/deathmatch/logic/CPlayerManager.cpp b/Server/mods/deathmatch/logic/CPlayerManager.cpp index bca9896fec..21575a7cf9 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/CPlayerManager.cpp @@ -138,7 +138,7 @@ CPlayer* CPlayerManager::Get(const char* szNick, bool bCaseSensitive) return NULL; } -CPlayer* CPlayerManager::GetBySerial(const SString& serial) noexcept +CPlayer* CPlayerManager::GetBySerial(const SString& serial) const noexcept { for (auto& player : m_Players) { diff --git a/Server/mods/deathmatch/logic/CPlayerManager.h b/Server/mods/deathmatch/logic/CPlayerManager.h index 052eee9b03..13fde4b628 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.h +++ b/Server/mods/deathmatch/logic/CPlayerManager.h @@ -40,7 +40,7 @@ class CPlayerManager CPlayer* Get(const NetServerPlayerID& PlayerSocket); CPlayer* Get(const char* szNick, bool bCaseSensitive = false); - CPlayer* GetBySerial(const SString& serial) noexcept; + CPlayer* GetBySerial(const SString& serial) const noexcept; std::list::const_iterator IterBegin() { return m_Players.begin(); }; std::list::const_iterator IterEnd() { return m_Players.end(); }; From aa33493df71b4e6303fddb9125729884f62088b5 Mon Sep 17 00:00:00 2001 From: Nico <122193236+Nico8340@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:44:29 +0100 Subject: [PATCH 4/8] Make suggested changes --- Server/mods/deathmatch/logic/CGame.cpp | 4 +--- Server/mods/deathmatch/logic/CPlayerManager.cpp | 4 ++-- Server/mods/deathmatch/logic/CPlayerManager.h | 3 ++- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 7c486d74ad..1dd074adcf 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -1799,9 +1799,7 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) } // Check if another player is using the same serial - CPlayer* playerExisting = m_pPlayerManager->GetBySerial(strSerial); - - if (playerExisting) + if (m_pPlayerManager->GetBySerial(strSerial)) { // Tell the console CLogger::LogPrintf("CONNECT: %s failed to connect (Serial already in use) (%s)\n", szNick, strIPAndSerial.c_str()); diff --git a/Server/mods/deathmatch/logic/CPlayerManager.cpp b/Server/mods/deathmatch/logic/CPlayerManager.cpp index 21575a7cf9..eec3b87990 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/CPlayerManager.cpp @@ -138,9 +138,9 @@ CPlayer* CPlayerManager::Get(const char* szNick, bool bCaseSensitive) return NULL; } -CPlayer* CPlayerManager::GetBySerial(const SString& serial) const noexcept +const CPlayer* CPlayerManager::GetBySerial(const std::string serial) const noexcept { - for (auto& player : m_Players) + for (const auto& player : m_Players) { if (player->GetSerial() == serial) { diff --git a/Server/mods/deathmatch/logic/CPlayerManager.h b/Server/mods/deathmatch/logic/CPlayerManager.h index 13fde4b628..7e48b2319b 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.h +++ b/Server/mods/deathmatch/logic/CPlayerManager.h @@ -17,6 +17,7 @@ class CPlayerManager; #include "packets/CPacket.h" #include "CPlayer.h" #include "../Config.h" +#include class CPlayerManager { @@ -40,7 +41,7 @@ class CPlayerManager CPlayer* Get(const NetServerPlayerID& PlayerSocket); CPlayer* Get(const char* szNick, bool bCaseSensitive = false); - CPlayer* GetBySerial(const SString& serial) const noexcept; + const CPlayer* GetBySerial(const std::string serial) const noexcept; std::list::const_iterator IterBegin() { return m_Players.begin(); }; std::list::const_iterator IterEnd() { return m_Players.end(); }; From c8bfe8e99c1defa073b143c7c978e1c960654835 Mon Sep 17 00:00:00 2001 From: Nico <122193236+Nico8340@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:10:32 +0100 Subject: [PATCH 5/8] Make a new parameter Make a new parameter called check_duplicate_serials which is enabled by default --- Server/mods/deathmatch/local.conf | 6 ++++++ Server/mods/deathmatch/logic/CGame.cpp | 2 +- Server/mods/deathmatch/logic/CMainConfig.cpp | 2 ++ Server/mods/deathmatch/logic/CMainConfig.h | 2 ++ Server/mods/deathmatch/mtaserver.conf | 6 ++++++ Server/mods/deathmatch/mtaserver.conf.template | 6 ++++++ 6 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Server/mods/deathmatch/local.conf b/Server/mods/deathmatch/local.conf index 039e155d81..d30a608781 100644 --- a/Server/mods/deathmatch/local.conf +++ b/Server/mods/deathmatch/local.conf @@ -274,6 +274,12 @@ Values: 0 - Off, 1 - Enabled. Default - 0 --> 0 + + 1 + diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 1dd074adcf..7c3748fabc 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -1799,7 +1799,7 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) } // Check if another player is using the same serial - if (m_pPlayerManager->GetBySerial(strSerial)) + if (m_pMainConfig->IsCheckDuplicateSerialsEnabled() && m_pPlayerManager->GetBySerial(strSerial)) { // Tell the console CLogger::LogPrintf("CONNECT: %s failed to connect (Serial already in use) (%s)\n", szNick, strIPAndSerial.c_str()); diff --git a/Server/mods/deathmatch/logic/CMainConfig.cpp b/Server/mods/deathmatch/logic/CMainConfig.cpp index bece65e885..49c73419ca 100644 --- a/Server/mods/deathmatch/logic/CMainConfig.cpp +++ b/Server/mods/deathmatch/logic/CMainConfig.cpp @@ -80,6 +80,7 @@ CMainConfig::CMainConfig(CConsole* pConsole) : CXMLConfig(NULL) m_iBackupAmount = 5; m_bSyncMapElementData = true; m_elementDataWhitelisted = false; + m_checkDuplicateSerials = true; } bool CMainConfig::Load() @@ -528,6 +529,7 @@ bool CMainConfig::Load() } GetBoolean(m_pRootNode, "elementdata_whitelisted", m_elementDataWhitelisted); + GetBoolean(m_pRootNode, "check_duplicate_serials", m_checkDuplicateSerials); ApplyNetOptions(); diff --git a/Server/mods/deathmatch/logic/CMainConfig.h b/Server/mods/deathmatch/logic/CMainConfig.h index 9758ae2dbf..05df0e2f32 100644 --- a/Server/mods/deathmatch/logic/CMainConfig.h +++ b/Server/mods/deathmatch/logic/CMainConfig.h @@ -127,6 +127,7 @@ class CMainConfig : public CXMLConfig bool IsDatabaseCredentialsProtectionEnabled() const { return m_bDatabaseCredentialsProtectionEnabled != 0; } bool IsFakeLagCommandEnabled() const { return m_bFakeLagCommandEnabled != 0; } bool IsElementDataWhitelisted() const { return m_elementDataWhitelisted; } + bool IsCheckDuplicateSerialsEnabled() const noexcept { return m_checkDuplicateSerials; } bool IsCheckResourceClientFilesEnabled() const noexcept { return m_checkResourceClientFiles != 0; } SString GetSetting(const SString& configSetting); @@ -230,5 +231,6 @@ class CMainConfig : public CXMLConfig int m_iPlayerTriggeredEventIntervalMs; int m_iMaxPlayerTriggeredEventsPerInterval; bool m_elementDataWhitelisted; + bool m_checkDuplicateSerials; int m_checkResourceClientFiles; }; diff --git a/Server/mods/deathmatch/mtaserver.conf b/Server/mods/deathmatch/mtaserver.conf index 11ef497fa7..726199d548 100644 --- a/Server/mods/deathmatch/mtaserver.conf +++ b/Server/mods/deathmatch/mtaserver.conf @@ -274,6 +274,12 @@ Values: 0 - Off, 1 - Enabled. Default - 0 --> 0 + + 1 + 0 + + 1 + 1 + + 1 + From aa0a0f1fbee40dabc5259cb742db3a0094801ca2 Mon Sep 17 00:00:00 2001 From: Nico <122193236+Nico8340@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:30:44 +0100 Subject: [PATCH 7/8] Make suggested changes --- Client/mods/deathmatch/logic/CPacketHandler.h | 4 ++-- Server/mods/deathmatch/logic/CGame.cpp | 6 +++++- Server/mods/deathmatch/logic/CPlayerManager.cpp | 2 +- Server/mods/deathmatch/logic/CPlayerManager.h | 3 +-- .../deathmatch/logic/packets/CPlayerDisconnectedPacket.h | 4 ++-- Shared/sdk/net/bitstream.h | 4 ++++ 6 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Client/mods/deathmatch/logic/CPacketHandler.h b/Client/mods/deathmatch/logic/CPacketHandler.h index d2ed5c3bbd..9a50b24615 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.h +++ b/Client/mods/deathmatch/logic/CPacketHandler.h @@ -38,12 +38,12 @@ class CPacketHandler ELEMENT_FAILURE, GENERAL_REFUSED, SERIAL_VERIFICATION, - SERIAL_DUPLICATE, CONNECTION_DESYNC, BAN, KICK, CUSTOM, - SHUTDOWN + SHUTDOWN, + SERIAL_DUPLICATE }; struct SEntityDependantStuff diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 7c3748fabc..a72885c929 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -1805,7 +1805,11 @@ void CGame::Packet_PlayerJoinData(CPlayerJoinDataPacket& Packet) CLogger::LogPrintf("CONNECT: %s failed to connect (Serial already in use) (%s)\n", szNick, strIPAndSerial.c_str()); // Tell the player the problem - DisconnectPlayer(this, *pPlayer, CPlayerDisconnectedPacket::SERIAL_DUPLICATE); + if (pPlayer->CanBitStream(eBitStreamVersion::CheckDuplicateSerials)) + DisconnectPlayer(this, *pPlayer, CPlayerDisconnectedPacket::SERIAL_DUPLICATE); + else + DisconnectPlayer(this, *pPlayer, CPlayerDisconnectedPacket::KICK); + return; } diff --git a/Server/mods/deathmatch/logic/CPlayerManager.cpp b/Server/mods/deathmatch/logic/CPlayerManager.cpp index eec3b87990..3b34d447e6 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/CPlayerManager.cpp @@ -138,7 +138,7 @@ CPlayer* CPlayerManager::Get(const char* szNick, bool bCaseSensitive) return NULL; } -const CPlayer* CPlayerManager::GetBySerial(const std::string serial) const noexcept +CPlayer* CPlayerManager::GetBySerial(const std::string_view serial) const noexcept { for (const auto& player : m_Players) { diff --git a/Server/mods/deathmatch/logic/CPlayerManager.h b/Server/mods/deathmatch/logic/CPlayerManager.h index 7e48b2319b..0380c4bce4 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.h +++ b/Server/mods/deathmatch/logic/CPlayerManager.h @@ -17,7 +17,6 @@ class CPlayerManager; #include "packets/CPacket.h" #include "CPlayer.h" #include "../Config.h" -#include class CPlayerManager { @@ -41,7 +40,7 @@ class CPlayerManager CPlayer* Get(const NetServerPlayerID& PlayerSocket); CPlayer* Get(const char* szNick, bool bCaseSensitive = false); - const CPlayer* GetBySerial(const std::string serial) const noexcept; + CPlayer* GetBySerial(const std::string_view serial) const noexcept; std::list::const_iterator IterBegin() { return m_Players.begin(); }; std::list::const_iterator IterEnd() { return m_Players.end(); }; diff --git a/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h b/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h index 22e884e721..541f9b191c 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h +++ b/Server/mods/deathmatch/logic/packets/CPlayerDisconnectedPacket.h @@ -35,12 +35,12 @@ class CPlayerDisconnectedPacket final : public CPacket ELEMENT_FAILURE, GENERAL_REFUSED, SERIAL_VERIFICATION, - SERIAL_DUPLICATE, CONNECTION_DESYNC, BAN, KICK, CUSTOM, - SHUTDOWN + SHUTDOWN, + SERIAL_DUPLICATE }; CPlayerDisconnectedPacket(const char* szReason); diff --git a/Shared/sdk/net/bitstream.h b/Shared/sdk/net/bitstream.h index c29f739ff1..4dde7f3782 100644 --- a/Shared/sdk/net/bitstream.h +++ b/Shared/sdk/net/bitstream.h @@ -572,6 +572,10 @@ enum class eBitStreamVersion : unsigned short // 2024-09-04 RespawnObject_Serverside, + // Add check_duplicate_serials + // 2024-09-04 + CheckDuplicateSerials, + // This allows us to automatically increment the BitStreamVersion when things are added to this enum. // Make sure you only add things above this comment. Next, From da0c71d46f5c7da40332a98a28d02387150b5db6 Mon Sep 17 00:00:00 2001 From: Nico <122193236+Nico8340@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:37:26 +0100 Subject: [PATCH 8/8] Make suggested changes Co-authored-by: Fernando Rocha <34967844+Fernando-A-Rocha@users.noreply.github.com> --- Server/mods/deathmatch/logic/CPlayerManager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Server/mods/deathmatch/logic/CPlayerManager.cpp b/Server/mods/deathmatch/logic/CPlayerManager.cpp index 3b34d447e6..227d3677f2 100644 --- a/Server/mods/deathmatch/logic/CPlayerManager.cpp +++ b/Server/mods/deathmatch/logic/CPlayerManager.cpp @@ -143,9 +143,7 @@ CPlayer* CPlayerManager::GetBySerial(const std::string_view serial) const noexce for (const auto& player : m_Players) { if (player->GetSerial() == serial) - { return player; - } } return nullptr;