diff --git a/Server/mods/deathmatch/acl.xml b/Server/mods/deathmatch/acl.xml index 5e4d1292c3..c6c0f4e8c9 100644 --- a/Server/mods/deathmatch/acl.xml +++ b/Server/mods/deathmatch/acl.xml @@ -103,6 +103,7 @@ + @@ -188,6 +189,7 @@ + diff --git a/Server/mods/deathmatch/logic/CAccount.cpp b/Server/mods/deathmatch/logic/CAccount.cpp index 73934a9f8b..87584b8e0d 100644 --- a/Server/mods/deathmatch/logic/CAccount.cpp +++ b/Server/mods/deathmatch/logic/CAccount.cpp @@ -14,6 +14,7 @@ #include "CAccountManager.h" #include "CIdArray.h" #include "CClient.h" +#include CAccount::CAccount(CAccountManager* pManager, EAccountType accountType, const std::string& strName, const std::string& strPassword, int iUserID, const std::string& strIP, const std::string& strSerial, const SString& strHttpPassAppend) @@ -255,6 +256,20 @@ bool CAccount::IsIpAuthorized(const SString& strIp) return false; } +// +// Check if the serial has 32 hexadecimal characters +// +bool CAccount::IsValidSerial(const std::string& serial) const noexcept +{ + const std::regex serialPattern("^[A-Fa-f0-9]{32}$"); + + try{ + return std::regex_match(serial, serialPattern); + } catch (...) { + return false; + } +} + // // Mark pending serial as authorized for this account // @@ -289,6 +304,19 @@ bool CAccount::RemoveSerial(const SString& strSerial) return false; } +// +// Replace the serial number for a specific account +// +bool CAccount::SetAccountSerial(const std::string& serial) noexcept +{ + if (!IsValidSerial(serial)) + return false; + + m_strSerial = serial; + m_pManager->MarkAsChanged(this); + return true; +} + // // Cleanup unauthorized serials // diff --git a/Server/mods/deathmatch/logic/CAccount.h b/Server/mods/deathmatch/logic/CAccount.h index 363dd57d98..843adf191d 100644 --- a/Server/mods/deathmatch/logic/CAccount.h +++ b/Server/mods/deathmatch/logic/CAccount.h @@ -97,10 +97,12 @@ class CAccount SSerialUsage* GetSerialUsage(const SString& strSerial); bool IsIpAuthorized(const SString& strIp); bool IsSerialAuthorized(const SString& strSerial); + bool IsValidSerial(const std::string& serial) const noexcept; bool AddSerialForAuthorization(const SString& strSerial, const SString& strIp); bool AuthorizeSerial(const SString& strSerial, const SString& strWho); bool RemoveSerial(const SString& strSerial); void RemoveUnauthorizedSerials(); + bool SetAccountSerial(const std::string& serial) noexcept; CClient* GetClient() const { return m_pClient; } void SetClient(CClient* pClient); diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 67764f8057..a2808ec3ce 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -11425,6 +11425,15 @@ bool CStaticFunctionDefinitions::GetAccountSerial(CAccount* pAccount, SString& s return bRegistered; } + +bool CStaticFunctionDefinitions::SetAccountSerial(CAccount* account, const std::string& serial) noexcept +{ + if (account && account->IsRegistered()) + return account->SetAccountSerial(serial); + + return false; +} + bool CStaticFunctionDefinitions::GetAccountsBySerial(const SString& strSerial, std::vector& outAccounts) { m_pAccountManager->GetAccountsBySerial(strSerial, outAccounts); diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h index dd6202208f..02541aa73f 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -703,6 +703,7 @@ class CStaticFunctionDefinitions // Account set funcs static CAccount* AddAccount(const SString& strName, const SString& strPassword, bool bAllowCaseVariations, SString& strOutError); static bool RemoveAccount(CAccount* pAccount); + static bool SetAccountSerial(CAccount* account, const std::string& serial) noexcept; static bool SetAccountName(CAccount* pAccount, SString strNewName, bool bAllowCaseVariations, SString& strOutError); static bool SetAccountPassword(CAccount* pAccount, SString szPassword, CAccountPassword::EAccountPasswordType ePasswordType); static bool SetAccountData(CAccount* pAccount, const char* szKey, CLuaArgument* pArgument); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.cpp index 7af41f0e99..ffc9c2c06d 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.cpp @@ -42,6 +42,7 @@ void CLuaAccountDefs::LoadFunctions() {"addAccount", AddAccount}, {"removeAccount", RemoveAccount}, {"setAccountPassword", SetAccountPassword}, + {"setAccountSerial", ArgumentParser}, {"setAccountData", SetAccountData}, {"setAccountName", SetAccountName}, {"copyAccountData", CopyAccountData}, @@ -71,6 +72,7 @@ void CLuaAccountDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setData", "setAccountData"); lua_classfunction(luaVM, "setPassword", "setAccountPassword"); lua_classfunction(luaVM, "setName", "setAccountName"); + lua_classfunction(luaVM, "setSerial", "setAccountSerial"); lua_classfunction(luaVM, "getSerial", "getAccountSerial"); lua_classfunction(luaVM, "getIP", "getAccountIP"); @@ -513,6 +515,12 @@ int CLuaAccountDefs::RemoveAccount(lua_State* luaVM) return 1; } +bool CLuaAccountDefs::SetAccountSerial(CAccount* account, std::string serial) noexcept +{ + return CStaticFunctionDefinitions::SetAccountSerial(account, serial); +} + + int CLuaAccountDefs::SetAccountName(lua_State* luaVM) { // bool setAccountPassword ( account theAccount, string name[, bool allowCaseVariations = false ] ) diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.h index 1a9fdc45cf..263d12f9da 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaAccountDefs.h @@ -48,4 +48,5 @@ class CLuaAccountDefs : public CLuaDefs LUA_DECLARE(SetAccountPassword); LUA_DECLARE(SetAccountData); LUA_DECLARE(CopyAccountData); + static bool SetAccountSerial(CAccount* account, std::string serial) noexcept; };