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;
};