From 9c9843a0fc96ba52c72cb56e3dbc253ad9b30b21 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Thu, 15 Sep 2022 23:13:37 +0200 Subject: [PATCH] Centralize kick/ban wrappers to CBanSystem and add new server functions for kicking/banning players --- r5dev/networksystem/bansystem.cpp | 200 ++++++++++++++++++++++++++++-- r5dev/networksystem/bansystem.h | 6 + r5dev/public/iconvar.h | 2 +- r5dev/squirrel/sqinit.cpp | 47 +++++++ r5dev/squirrel/sqinit.h | 4 + r5dev/squirrel/sqscript.cpp | 8 +- r5dev/tier1/cmd.cpp | 10 +- r5dev/vstdlib/callback.cpp | 156 +---------------------- 8 files changed, 264 insertions(+), 169 deletions(-) diff --git a/r5dev/networksystem/bansystem.cpp b/r5dev/networksystem/bansystem.cpp index 02a5dc95..6fe9a36b 100644 --- a/r5dev/networksystem/bansystem.cpp +++ b/r5dev/networksystem/bansystem.cpp @@ -12,20 +12,16 @@ #include "networksystem/bansystem.h" //----------------------------------------------------------------------------- -// Purpose: loads and parses the banlist +// Purpose: loads and parses the banned list //----------------------------------------------------------------------------- void CBanSystem::Load(void) { if (IsBanListValid()) - { m_vBanList.clear(); - } FileHandle_t pFile = FileSystem()->Open("banlist.json", "rt"); if (!pFile) - { return; - } uint32_t nLen = FileSystem()->Size(pFile); char* pBuf = MemAllocSingleton()->Alloc(nLen); @@ -43,9 +39,7 @@ void CBanSystem::Load(void) if (!jsIn.is_null()) { if (!jsIn["totalBans"].is_null()) - { nTotalBans = jsIn["totalBans"].get(); - } } for (size_t i = 0; i < nTotalBans; i++) @@ -243,7 +237,7 @@ void CBanSystem::BanListCheck(void) } //----------------------------------------------------------------------------- -// Purpose: checks if specified ip address or necleus id is banned +// Purpose: checks if specified ip address or nucleus id is banned // Input : &svIpAddress - // nNucleusID - // Output : true if banned, false if not banned @@ -272,7 +266,7 @@ bool CBanSystem::IsBanned(const string& svIpAddress, const uint64_t nNucleusID) } //----------------------------------------------------------------------------- -// Purpose: checks if refuselist is valid +// Purpose: checks if refused list is valid //----------------------------------------------------------------------------- bool CBanSystem::IsRefuseListValid(void) const { @@ -280,11 +274,197 @@ bool CBanSystem::IsRefuseListValid(void) const } //----------------------------------------------------------------------------- -// Purpose: checks if banlist is valid +// Purpose: checks if banned list is valid //----------------------------------------------------------------------------- bool CBanSystem::IsBanListValid(void) const { return !m_vBanList.empty(); } + +//----------------------------------------------------------------------------- +// Purpose: kicks a player by given name +// Input : &svPlayerName - +//----------------------------------------------------------------------------- +void CBanSystem::KickPlayerByName(const string& svPlayerName) +{ + if (svPlayerName.empty()) + return; + + for (int i = 0; i < MAX_PLAYERS; i++) + { + if (CClient* pClient = g_pClient->GetClient(i)) + { + if (CNetChan* pNetChan = pClient->GetNetChan()) + { + if (strlen(pNetChan->GetName()) > 0) + { + if (svPlayerName.compare(pNetChan->GetName()) == NULL) // Our wanted name? + NET_DisconnectClient(pClient, i, "Kicked from server", 0, true); + } + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: kicks a player by given handle or id +// Input : svHandle - +//----------------------------------------------------------------------------- +void CBanSystem::KickPlayerById(const string& svHandle) +{ + if (svHandle.empty()) + return; + + try + { + bool bOnlyDigits = StringIsDigit(svHandle); + for (int i = 0; i < MAX_PLAYERS; i++) + { + CClient* pClient = g_pClient->GetClient(i); + if (!pClient) + continue; + + CNetChan* pNetChan = pClient->GetNetChan(); + if (!pNetChan) + continue; + + if (bOnlyDigits) + { + uint64_t nTargetID = static_cast(std::stoll(svHandle)); + if (nTargetID > MAX_PLAYERS) // Is it a possible nucleusID? + { + uint64_t nNucleusID = pClient->GetNucleusID(); + if (nNucleusID != nTargetID) + continue; + } + else // If its not try by handle. + { + uint64_t nClientID = static_cast(pClient->GetHandle()); + if (nClientID != nTargetID) + continue; + } + + NET_DisconnectClient(pClient, i, "Kicked from server", 0, true); + } + else + { + if (svHandle.compare(pNetChan->GetAddress()) != NULL) + continue; + + NET_DisconnectClient(pClient, i, "Kicked from server", 0, true); + } + } + } + catch (const std::exception& e) + { + Error(eDLL_T::SERVER, NO_ERROR, "%s - %s", __FUNCTION__, e.what()); + return; + } +} + +//----------------------------------------------------------------------------- +// Purpose: bans a player by given name +// Input : &svPlayerName - +//----------------------------------------------------------------------------- +void CBanSystem::BanPlayerByName(const string& svPlayerName) +{ + if (svPlayerName.empty()) + return; + + bool bSave = false; + + for (int i = 0; i < MAX_PLAYERS; i++) + { + if (CClient* pClient = g_pClient->GetClient(i)) + { + if (CNetChan* pNetChan = pClient->GetNetChan()) + { + if (strlen(pNetChan->GetName()) > 0) + { + if (svPlayerName.compare(pNetChan->GetName()) == NULL) // Our wanted name? + { + if (AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave) + bSave = true; + + NET_DisconnectClient(pClient, i, "Banned from server", 0, true); + } + } + } + } + } + + if (bSave) + Save(); +} + +//----------------------------------------------------------------------------- +// Purpose: bans a player by given handle or id +// Input : svHandle - +//----------------------------------------------------------------------------- +void CBanSystem::BanPlayerById(const string& svHandle) +{ + if (svHandle.empty()) + return; + + try + { + bool bOnlyDigits = StringIsDigit(svHandle); + bool bSave = false; + + for (int i = 0; i < MAX_PLAYERS; i++) + { + CClient* pClient = g_pClient->GetClient(i); + if (!pClient) + continue; + + CNetChan* pNetChan = pClient->GetNetChan(); + if (!pNetChan) + continue; + + if (bOnlyDigits) + { + uint64_t nTargetID = static_cast(std::stoll(svHandle)); + if (nTargetID > static_cast(MAX_PLAYERS)) // Is it a possible nucleusID? + { + uint64_t nNucleusID = pClient->GetNucleusID(); + if (nNucleusID != nTargetID) + continue; + } + else // If its not try by handle. + { + uint64_t nClientID = static_cast(pClient->GetHandle()); + if (nClientID != nTargetID) + continue; + } + + if (AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave) + bSave = true; + + Save(); + NET_DisconnectClient(pClient, i, "Banned from server", 0, true); + } + else + { + if (svHandle.compare(pNetChan->GetAddress()) != NULL) + continue; + + if (AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave) + bSave = true; + + Save(); + NET_DisconnectClient(pClient, i, "Banned from server", 0, true); + } + } + + if (bSave) + Save(); + } + catch (const std::exception& e) + { + Error(eDLL_T::SERVER, NO_ERROR, "%s - %s", __FUNCTION__, e.what()); + return; + } +} + /////////////////////////////////////////////////////////////////////////////// CBanSystem* g_pBanSystem = new CBanSystem(); diff --git a/r5dev/networksystem/bansystem.h b/r5dev/networksystem/bansystem.h index 2c8aafc1..823344eb 100644 --- a/r5dev/networksystem/bansystem.h +++ b/r5dev/networksystem/bansystem.h @@ -18,6 +18,12 @@ public: bool IsRefuseListValid(void) const; bool IsBanListValid(void) const; + void KickPlayerByName(const string& svPlayerName); + void KickPlayerById(const string& svHandle); + + void BanPlayerByName(const string& svPlayerName); + void BanPlayerById(const string& svHandle); + private: vector> m_vRefuseList = {}; vector> m_vBanList = {}; diff --git a/r5dev/public/iconvar.h b/r5dev/public/iconvar.h index e1b90f74..5d00d029 100644 --- a/r5dev/public/iconvar.h +++ b/r5dev/public/iconvar.h @@ -39,7 +39,7 @@ class CCommand; // If a change is requested it must come from the console (i.e., no remote client changes) // If a value is changed while a server is active, it's replicated to all connected clients #define FCVAR_REPLICATED (1<<13) // server setting enforced on clients, TODO rename to FCAR_SERVER at some time -#define FCVAR_CHEAT (1<<14) // Only useable in singleplayer / debug / multiplayer & sv_cheats +#define FCVAR_CHEAT (1<<14) // Only usable in singleplayer / debug / multiplayer & sv_cheats #define FCVAR_SS (1<<15) // causes varnameN where N == 2 through max splitscreen slots for mod to be autogenerated #define FCVAR_DEMO (1<<16) // record this cvar when starting a demo file #define FCVAR_DONTRECORD (1<<17) // don't record these command in demofiles diff --git a/r5dev/squirrel/sqinit.cpp b/r5dev/squirrel/sqinit.cpp index 505d6818..c93151da 100644 --- a/r5dev/squirrel/sqinit.cpp +++ b/r5dev/squirrel/sqinit.cpp @@ -22,6 +22,9 @@ #include "squirrel/sqapi.h" #include "squirrel/sqinit.h" #include "networksystem/pylon.h" +#ifndef CLIENT_DLL +#include "networksystem/bansystem.h" +#endif // !CLIENT_DLL #ifndef DEDICATED #include "networksystem/listmanager.h" #endif // !DEDICATED @@ -119,6 +122,50 @@ namespace VSquirrel sq_pushinteger(v, g_pServer->GetNumFakeClients()); return SQ_OK; } + + //----------------------------------------------------------------------------- + // Purpose: kicks a player by given name + //----------------------------------------------------------------------------- + SQRESULT KickPlayerByName(HSQUIRRELVM v) + { + SQChar* szPlayer = sq_getstring(v, 1); + g_pBanSystem->KickPlayerByName(szPlayer); + + return SQ_OK; + } + + //----------------------------------------------------------------------------- + // Purpose: kicks a player by given handle or id + //----------------------------------------------------------------------------- + SQRESULT KickPlayerById(HSQUIRRELVM v) + { + SQChar* szPlayer = sq_getstring(v, 1); + g_pBanSystem->KickPlayerById(szPlayer); + + return SQ_OK; + } + + //----------------------------------------------------------------------------- + // Purpose: bans a player by given name + //----------------------------------------------------------------------------- + SQRESULT BanPlayerByName(HSQUIRRELVM v) + { + SQChar* szPlayer = sq_getstring(v, 1); + g_pBanSystem->BanPlayerByName(szPlayer); + + return SQ_OK; + } + + //----------------------------------------------------------------------------- + // Purpose: bans a player by given handle or id + //----------------------------------------------------------------------------- + SQRESULT BanPlayerById(HSQUIRRELVM v) + { + SQChar* szPlayer = sq_getstring(v, 1); + g_pBanSystem->BanPlayerById(szPlayer); + + return SQ_OK; + } } #endif // !CLIENT_DLL #ifndef DEDICATED diff --git a/r5dev/squirrel/sqinit.h b/r5dev/squirrel/sqinit.h index 7b5cc778..ab29d7ae 100644 --- a/r5dev/squirrel/sqinit.h +++ b/r5dev/squirrel/sqinit.h @@ -29,6 +29,10 @@ namespace VSquirrel { SQRESULT GetNumHumanPlayers(HSQUIRRELVM v); SQRESULT GetNumFakeClients(HSQUIRRELVM v); + SQRESULT KickPlayerByName(HSQUIRRELVM v); + SQRESULT KickPlayerById(HSQUIRRELVM v); + SQRESULT BanPlayerByName(HSQUIRRELVM v); + SQRESULT BanPlayerById(HSQUIRRELVM v); } #endif // !CLIENT_DLL #ifndef DEDICATED diff --git a/r5dev/squirrel/sqscript.cpp b/r5dev/squirrel/sqscript.cpp index 6ba41a46..7b210744 100644 --- a/r5dev/squirrel/sqscript.cpp +++ b/r5dev/squirrel/sqscript.cpp @@ -53,7 +53,13 @@ void Script_RegisterServerFunctions(CSquirrelVM* pSquirrelVM) Script_RegisterFunction(pSquirrelVM, "GetAvailableMaps", "Script_GetAvailableMaps", "Gets an array of all available maps", "array< string >", "", &VSquirrel::SHARED::GetAvailableMaps); Script_RegisterFunction(pSquirrelVM, "GetAvailablePlaylists", "Script_GetAvailablePlaylists", "Gets an array of all available playlists", "array< string >", "", &VSquirrel::SHARED::GetAvailablePlaylists); - Script_RegisterFunction(pSquirrelVM, "ShutdownHostGame", "Script_ShutdownHostGame", "Shuts down the local host game", "void", "", &VSquirrel::SHARED::ShutdownHostGame); + Script_RegisterFunction(pSquirrelVM, "ShutdownHostGame", "Script_ShutdownHostGame", "Shuts the local host game down", "void", "", &VSquirrel::SHARED::ShutdownHostGame); + + Script_RegisterFunction(pSquirrelVM, "KickPlayerByName", "Script_KickPlayerByName", "Kicks a player from the server by name", "void", "string", &VSquirrel::SERVER::KickPlayerByName); + Script_RegisterFunction(pSquirrelVM, "KickPlayerById", "Script_KickPlayerById", "Kicks a player from the server by handle or nucleus id", "void", "string", &VSquirrel::SERVER::KickPlayerById); + + Script_RegisterFunction(pSquirrelVM, "BanPlayerByName", "Script_BanPlayerByName", "Bans a player from the server by name", "void", "string", &VSquirrel::SERVER::BanPlayerByName); + Script_RegisterFunction(pSquirrelVM, "BanPlayerById", "Script_BanPlayerById", "Bans a player from the server by handle or nucleus id", "void", "string", &VSquirrel::SERVER::BanPlayerById); } #endif // !CLIENT_DLL diff --git a/r5dev/tier1/cmd.cpp b/r5dev/tier1/cmd.cpp index ecb3ab90..16a79ea9 100644 --- a/r5dev/tier1/cmd.cpp +++ b/r5dev/tier1/cmd.cpp @@ -247,7 +247,7 @@ int CCommand::MaxCommandLength(void) const //----------------------------------------------------------------------------- bool CCommand::HasOnlyDigits(int nIndex) const { - string svString = Arg(nIndex); + const string svString = Arg(nIndex); for (const char& character : svString) { if (std::isdigit(character) == 0) @@ -336,10 +336,10 @@ void ConCommand::Init(void) // SERVER DLL | #ifndef CLIENT_DLL ConCommand::Create("script", "Run input code as SERVER script on the VM.", FCVAR_GAMEDLL | FCVAR_CHEAT, SQVM_ServerScript_f, nullptr); - ConCommand::Create("sv_kick", "Kick a client from the server by user name. | Usage: sv_kick \"\".", FCVAR_GAMEDLL | FCVAR_RELEASE, Host_Kick_f, nullptr); - ConCommand::Create("sv_kickid", "Kick a client from the server by handle or nucleus id | Usage: sv_kickid \"\"/\"\".", FCVAR_GAMEDLL | FCVAR_RELEASE, Host_KickID_f, nullptr); - ConCommand::Create("sv_ban", "Bans a client from the server by user name. | Usage: sv_ban .", FCVAR_GAMEDLL | FCVAR_RELEASE, Host_Ban_f, nullptr); - ConCommand::Create("sv_banid", "Bans a client from the server by handle, nucleus id or ip address | Usage: sv_banid \"\"/\"/\".", FCVAR_GAMEDLL | FCVAR_RELEASE, Host_BanID_f, nullptr); + ConCommand::Create("sv_kick", "Kick a client from the server by user name. | Usage: sv_kick \"\".", FCVAR_RELEASE, Host_Kick_f, nullptr); + ConCommand::Create("sv_kickid", "Kick a client from the server by handle or nucleus id | Usage: sv_kickid \"\"/\"\".", FCVAR_RELEASE, Host_KickID_f, nullptr); + ConCommand::Create("sv_ban", "Bans a client from the server by user name. | Usage: sv_ban .", FCVAR_RELEASE, Host_Ban_f, nullptr); + ConCommand::Create("sv_banid", "Bans a client from the server by handle, nucleus id or ip address | Usage: sv_banid \"\"/\"/\".", FCVAR_RELEASE, Host_BanID_f, nullptr); ConCommand::Create("sv_unban", "Unbans a client from the server by nucleus id or ip address | Usage: sv_unban \"\"/\"\".", FCVAR_RELEASE, Host_Unban_f, nullptr); ConCommand::Create("sv_reloadbanlist", "Reloads the banned list.", FCVAR_RELEASE, Host_ReloadBanList_f, nullptr); #endif // !CLIENT_DLL diff --git a/r5dev/vstdlib/callback.cpp b/r5dev/vstdlib/callback.cpp index 4aecba86..68433bb3 100644 --- a/r5dev/vstdlib/callback.cpp +++ b/r5dev/vstdlib/callback.cpp @@ -109,22 +109,7 @@ void Host_Kick_f(const CCommand& args) return; } - for (int i = 0; i < MAX_PLAYERS; i++) - { - if (CClient* pClient = g_pClient->GetClient(i)) - { - if (CNetChan* pNetChan = pClient->GetNetChan()) - { - if (strlen(pNetChan->GetName()) > 0) - { - if (strcmp(args.Arg(1), pNetChan->GetName()) == NULL) // Our wanted name? - { - NET_DisconnectClient(pClient, i, "Kicked from server", 0, true); - } - } - } - } - } + g_pBanSystem->KickPlayerByName(args.Arg(1)); } #ifndef CLIENT_DLL /* @@ -139,57 +124,7 @@ void Host_KickID_f(const CCommand& args) return; } - try - { - bool bOnlyDigits = args.HasOnlyDigits(1); - for (int i = 0; i < MAX_PLAYERS; i++) - { - CClient* pClient = g_pClient->GetClient(i); - if (!pClient) - continue; - - CNetChan* pNetChan = pClient->GetNetChan(); - if (!pNetChan) - continue; - - if (bOnlyDigits) - { - uint64_t nTargetID = static_cast(std::stoll(args.Arg(1))); - if (nTargetID > MAX_PLAYERS) // Is it a possible nucleusID? - { - uint64_t nNucleusID = pClient->GetNucleusID(); - if (nNucleusID != nTargetID) - { - continue; - } - } - else // If its not try by handle. - { - uint64_t nClientID = static_cast(pClient->GetHandle()); - if (nClientID != nTargetID) - { - continue; - } - } - - NET_DisconnectClient(pClient, i, "Kicked from server", 0, true); - } - else - { - if (strcmp(args.Arg(1), pNetChan->GetAddress()) != NULL) - { - continue; - } - - NET_DisconnectClient(pClient, i, "Kicked from server", 0, true); - } - } - } - catch (const std::exception& e) - { - Error(eDLL_T::SERVER, NO_ERROR, "%s - %s", __FUNCTION__, e.what()); - return; - } + g_pBanSystem->KickPlayerById(args.Arg(1)); } /* @@ -204,33 +139,7 @@ void Host_Ban_f(const CCommand& args) return; } - bool bSave = false; - - for (int i = 0; i < MAX_PLAYERS; i++) - { - if (CClient* pClient = g_pClient->GetClient(i)) - { - if (CNetChan* pNetChan = pClient->GetNetChan()) - { - if (strlen(pNetChan->GetName()) > 0) - { - if (strcmp(args.Arg(1), pNetChan->GetName()) == NULL) // Our wanted name? - { - if (g_pBanSystem->AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave) - { - bSave = true; - } - NET_DisconnectClient(pClient, i, "Banned from server", 0, true); - } - } - } - } - } - - if (bSave) - { - g_pBanSystem->Save(); - } + g_pBanSystem->BanPlayerByName(args.Arg(1)); } /* @@ -243,64 +152,7 @@ void Host_BanID_f(const CCommand& args) if (args.ArgC() < 2) return; - try - { - bool bOnlyDigits = args.HasOnlyDigits(1); - bool bSave = false; - - for (int i = 0; i < MAX_PLAYERS; i++) - { - CClient* pClient = g_pClient->GetClient(i); - if (!pClient) - continue; - - CNetChan* pNetChan = pClient->GetNetChan(); - if (!pNetChan) - continue; - - if (bOnlyDigits) - { - uint64_t nTargetID = static_cast(std::stoll(args.Arg(1))); - if (nTargetID > static_cast(MAX_PLAYERS)) // Is it a possible nucleusID? - { - uint64_t nNucleusID = pClient->GetNucleusID(); - if (nNucleusID != nTargetID) - continue; - } - else // If its not try by handle. - { - uint64_t nClientID = static_cast(pClient->GetHandle()); - if (nClientID != nTargetID) - continue; - } - - if (g_pBanSystem->AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave) - bSave = true; - - g_pBanSystem->Save(); - NET_DisconnectClient(pClient, i, "Banned from server", 0, true); - } - else - { - if (strcmp(args.Arg(1), pNetChan->GetAddress()) != NULL) - continue; - - if (g_pBanSystem->AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave) - bSave = true; - - g_pBanSystem->Save(); - NET_DisconnectClient(pClient, i, "Banned from server", 0, true); - } - } - - if (bSave) - g_pBanSystem->Save(); - } - catch (const std::exception& e) - { - Error(eDLL_T::SERVER, NO_ERROR, "%s - %s", __FUNCTION__, e.what()); - return; - } + g_pBanSystem->BanPlayerById(args.Arg(1)); } /*