From ca3df3bd5014251c52b5559ea035a16d9467489b Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Thu, 19 Feb 2009 19:19:44 +1300 Subject: [PATCH] Added a client verification serial API (bug 3616, r=dvander) --- core/PlayerManager.cpp | 32 ++++++++++++++++++++++++++++++++ core/PlayerManager.h | 13 +++++++++++++ core/smn_player.cpp | 20 ++++++++++++++++++++ plugins/include/clients.inc | 14 ++++++++++++++ public/IPlayerHelpers.h | 16 +++++++++++++++- 5 files changed, 94 insertions(+), 1 deletion(-) diff --git a/core/PlayerManager.cpp b/core/PlayerManager.cpp index db584c0e8..9cd3084ea 100644 --- a/core/PlayerManager.cpp +++ b/core/PlayerManager.cpp @@ -81,6 +81,8 @@ extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelega ConCommand *maxplayersCmd = NULL; +unsigned int g_PlayerSerialCount = 0; + class KickPlayerTimer : public ITimedEvent { public: @@ -1356,6 +1358,28 @@ void PlayerManager::MaxPlayersChanged( int newvalue /*= -1*/ ) } } +int PlayerManager::GetClientFromSerial(unsigned int serial) +{ + serial_t s; + s.value = serial; + + int client = s.bits.index; + + IGamePlayer *pPlayer = GetGamePlayer(client); + + if (!pPlayer) + { + return 0; + } + + if (serial == pPlayer->GetSerial()) + { + return client; + } + + return 0; +} + #if SOURCE_ENGINE >= SE_ORANGEBOX void CmdMaxplayersCallback(const CCommand &command) { @@ -1397,6 +1421,9 @@ void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity) m_iIndex = IndexOfEdict(pEntity); m_LangId = g_Translator.GetServerLanguage(); + m_Serial.bits.index = m_iIndex; + m_Serial.bits.serial = g_PlayerSerialCount++; + char ip2[24], *ptr; strncopy(ip2, ip, sizeof(ip2)); if ((ptr = strchr(ip2, ':')) != NULL) @@ -1760,3 +1787,8 @@ int CPlayer::GetLifeState() return PLAYER_LIFE_DEAD; } } + +unsigned int CPlayer::GetSerial() +{ + return m_Serial.value; +} \ No newline at end of file diff --git a/core/PlayerManager.h b/core/PlayerManager.h index 5d568a701..3b7a9662a 100644 --- a/core/PlayerManager.h +++ b/core/PlayerManager.h @@ -51,6 +51,16 @@ using namespace SourceHook; #define MIN_API_FOR_ADMINCALLS 7 +union serial_t +{ + uint32_t value; + struct + { + uint8_t index; + uint32_t serial : 24; + } bits; +}; + class CPlayer : public IGamePlayer { friend class PlayerManager; @@ -74,6 +84,7 @@ public: int GetUserId(); bool RunAdminCacheChecks(); void NotifyPostAdminChecks(); + unsigned int GetSerial(); public: void DoBasicAdminChecks(); bool IsInKickQueue(); @@ -107,6 +118,7 @@ private: unsigned int m_LangId; int m_UserId; bool m_bFakeClient; + serial_t m_Serial; }; class PlayerManager : @@ -156,6 +168,7 @@ public: //IPlayerManager void RegisterCommandTargetProcessor(ICommandTargetProcessor *pHandler); void UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler); void ProcessCommandTarget(cmd_target_info_t *info); + int GetClientFromSerial(unsigned int serial); public: // IConVarChangeListener void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue); public: diff --git a/core/smn_player.cpp b/core/smn_player.cpp index 03f5f95dc..3303ab82d 100644 --- a/core/smn_player.cpp +++ b/core/smn_player.cpp @@ -1551,6 +1551,24 @@ static cell_t FormatActivitySource(IPluginContext *pContext, const cell_t *param return bShowActivity ? 1 : 0; } +static cell_t sm_GetClientSerial(IPluginContext *pContext, const cell_t *params) +{ + int client = params[1]; + + CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); + if (!pPlayer) + { + return pContext->ThrowNativeError("Client index %d is invalid", client); + } + + return pPlayer->GetSerial(); +} + +static cell_t sm_GetClientFromSerial(IPluginContext *pContext, const cell_t *params) +{ + return g_Players.GetClientFromSerial(params[1]); +} + REGISTER_NATIVES(playernatives) { {"AddUserFlags", AddUserFlags}, @@ -1604,6 +1622,8 @@ REGISTER_NATIVES(playernatives) {"IsClientInKickQueue", IsClientInKickQueue}, {"ProcessTargetString", ProcessTargetString}, {"FormatActivitySource", FormatActivitySource}, + {"GetClientSerial", sm_GetClientSerial}, + {"GetClientFromSerial", sm_GetClientFromSerial}, {NULL, NULL} }; diff --git a/plugins/include/clients.inc b/plugins/include/clients.inc index e319af18c..e252407c2 100644 --- a/plugins/include/clients.inc +++ b/plugins/include/clients.inc @@ -708,3 +708,17 @@ native KickClientEx(client, const String:format[]="", any:...); */ native ChangeClientTeam(client, team); +/** + * Returns the clients unique serial identifier. + * + * @return Serial number. + */ +native GetClientSerial(client); + +/** + * Returns the client index by its serial number. + * + * @return Client index, or 0 for invalid serial. + */ +native GetClientFromSerial(serial); + diff --git a/public/IPlayerHelpers.h b/public/IPlayerHelpers.h index 911bffdd9..5195c60cf 100644 --- a/public/IPlayerHelpers.h +++ b/public/IPlayerHelpers.h @@ -41,7 +41,7 @@ #include #define SMINTERFACE_PLAYERMANAGER_NAME "IPlayerManager" -#define SMINTERFACE_PLAYERMANAGER_VERSION 8 +#define SMINTERFACE_PLAYERMANAGER_VERSION 9 struct edict_t; class IPlayerInfo; @@ -183,6 +183,13 @@ namespace SourceMod * call it at various times). */ virtual void NotifyPostAdminChecks() =0; + + /** + * @brief Returns the clients unique serial identifier. + * + * @return Serial number. + */ + virtual unsigned int GetSerial() =0; }; /** @@ -481,6 +488,13 @@ namespace SourceMod * @param pHandler Pointer to an ICommandTargetProcessor instance. */ virtual void UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler) =0; + + /** + * @brief Returns the client index by its serial number. + * + * @return Client index, or 0 for invalid serial. + */ + virtual int GetClientFromSerial(unsigned int serial) =0; }; }