From 30e476c35e89502d8cb34c0ec720e5279862218c Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sat, 16 Mar 2013 23:12:40 -0400 Subject: [PATCH] Added GetSteamAccountID function to IPlayerHelpers and native for sp (bug 5548, r=asherkin). --- core/PlayerManager.cpp | 34 ++++++++++++++++++++++++++++++++-- core/PlayerManager.h | 2 ++ core/smn_player.cpp | 18 ++++++++++++++++++ plugins/include/clients.inc | 12 ++++++++++++ public/IPlayerHelpers.h | 11 ++++++++++- 5 files changed, 74 insertions(+), 3 deletions(-) diff --git a/core/PlayerManager.cpp b/core/PlayerManager.cpp index d479da98..a5a10aa9 100644 --- a/core/PlayerManager.cpp +++ b/core/PlayerManager.cpp @@ -923,8 +923,7 @@ void PlayerManager::OnClientSettingsChanged(edict_t *pEntity) const char *networkid_force; if ((networkid_force = engine->GetClientConVarValue(client, "networkid_force")) && networkid_force[0] != '\0') { - unsigned long long *steamId = (unsigned long long *)engine->GetClientSteamID(pEntity); - unsigned int accountId = steamId ? (*steamId & 0xFFFFFFFF) : 0; + unsigned int accountId = pPlayer->GetSteamAccountID(); g_Logger.LogMessage("\"%s<%d><>\" has bad networkid (id \"%s\") (ip \"%s\")", new_name, pPlayer->GetUserId(), accountId & 1, accountId >> 1, networkid_force, pPlayer->GetIPAddress()); @@ -1586,6 +1585,7 @@ CPlayer::CPlayer() m_bIsSourceTV = false; m_bIsReplay = false; m_Serial.value = -1; + m_SteamAccountID = 0; } void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity) @@ -1665,6 +1665,7 @@ void CPlayer::Disconnect() m_bIsSourceTV = false; m_bIsReplay = false; m_Serial.value = -1; + m_SteamAccountID = 0; } void CPlayer::SetName(const char *name) @@ -1697,6 +1698,35 @@ const char *CPlayer::GetAuthString(bool validated) return m_AuthID.c_str(); } +unsigned int CPlayer::GetSteamAccountID(bool validated) +{ + if (IsFakeClient() || (validated && !IsAuthStringValidated())) + { + return 0; + } + + if (m_SteamAccountID != 0) + { + return m_SteamAccountID; + } + +#if SOURCE_ENGINE < SE_ORANGEBOX + const char * pAuth = GetAuthString(); + /* STEAM_0:1:123123 | STEAM_ID_LAN | STEAM_ID_PENDING */ + if (pAuth && (strlen(pAuth) > 10) && pAuth[8] != '_') + { + m_SteamAccountID = (atoi(&pAuth[8]) | (atoi(&pAuth[10]) << 1)); + } +#else + unsigned long long *steamId = (unsigned long long *)engine->GetClientSteamID(m_pEdict); + if (steamId) + { + m_SteamAccountID = (*steamId & 0xFFFFFFFF); + } +#endif + return m_SteamAccountID; +} + edict_t *CPlayer::GetEdict() { return m_pEdict; diff --git a/core/PlayerManager.h b/core/PlayerManager.h index f5f83362..b1869313 100644 --- a/core/PlayerManager.h +++ b/core/PlayerManager.h @@ -70,6 +70,7 @@ public: const char *GetName(); const char *GetIPAddress(); const char *GetAuthString(bool validated = true); + unsigned int GetSteamAccountID(bool validated = true); edict_t *GetEdict(); bool IsInGame(); bool WasCountedAsInGame(); @@ -126,6 +127,7 @@ private: bool m_bIsSourceTV; bool m_bIsReplay; serial_t m_Serial; + unsigned int m_SteamAccountID; }; class PlayerManager : diff --git a/core/smn_player.cpp b/core/smn_player.cpp index 257dee7e..ca3f8416 100644 --- a/core/smn_player.cpp +++ b/core/smn_player.cpp @@ -174,6 +174,23 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) return 1; } +static cell_t sm_GetSteamAccountID(IPluginContext *pCtx, const cell_t *params) +{ + int index = params[1]; + if ((index < 1) || (index > g_Players.GetMaxClients())) + { + return pCtx->ThrowNativeError("Client index %d is invalid", index); + } + + CPlayer *pPlayer = g_Players.GetPlayerByIndex(index); + if (!pPlayer->IsConnected()) + { + return pCtx->ThrowNativeError("Client %d is not connected", index); + } + + return pPlayer->GetSteamAccountID(!!params[2]); +} + static cell_t sm_IsClientConnected(IPluginContext *pCtx, const cell_t *params) { int index = params[1]; @@ -1651,6 +1668,7 @@ REGISTER_NATIVES(playernatives) {"CanUserTarget", CanUserTarget}, {"ChangeClientTeam", ChangeClientTeam}, {"GetClientAuthString", sm_GetClientAuthStr}, + {"GetSteamAccountID", sm_GetSteamAccountID}, {"GetClientCount", sm_GetClientCount}, {"GetClientInfo", sm_GetClientInfo}, {"GetClientIP", sm_GetClientIP}, diff --git a/plugins/include/clients.inc b/plugins/include/clients.inc index 02ad529f..74d6aa7f 100644 --- a/plugins/include/clients.inc +++ b/plugins/include/clients.inc @@ -269,6 +269,18 @@ native bool:GetClientIP(client, String:ip[], maxlen, bool:remport=true); */ native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=true); +/** + * Returns the client's Steam account ID. + * + * @param client Client Index. + * @param validate Check backend validation status. + * DO NOT PASS FALSE UNLESS YOU UNDERSTAND THE CONSEQUENCES, + * You WILL KNOW if you need to use this, MOST WILL NOT. + * @return Steam account ID or 0 if not available. + * @error If the client is not connected or the index is invalid. + */ +native GetSteamAccountID(client, bool:validate=true); + /** * Retrieves a client's user id, which is an index incremented for every client * that joins the server. diff --git a/public/IPlayerHelpers.h b/public/IPlayerHelpers.h index deaa6299..c11fff8a 100644 --- a/public/IPlayerHelpers.h +++ b/public/IPlayerHelpers.h @@ -41,7 +41,7 @@ #include #define SMINTERFACE_PLAYERMANAGER_NAME "IPlayerManager" -#define SMINTERFACE_PLAYERMANAGER_VERSION 16 +#define SMINTERFACE_PLAYERMANAGER_VERSION 17 struct edict_t; class IPlayerInfo; @@ -237,6 +237,15 @@ namespace SourceMod * @return True if the Replay bot, false otherwise. */ virtual bool IsReplay() const =0; + + /** + * @brief Returns the client's Steam account ID. + * + * @param validated Check backend validation status. + * + * @return Steam account ID or 0 if not available. + */ + virtual unsigned int GetSteamAccountID(bool validated = true) =0; }; /**