Added detection of Replay and SourceTV, and natives to query (bug 5124, r=fyren).
authorNicholas Hastings <skamonkey@gmail.com>
Thu Oct 20 21:39:57 2011 -0400 (2011-10-20)
changeset 3418b0e93f5101ef
parent 3417 dc2562dfd57b
child 3419 b1010658bf7f
Added detection of Replay and SourceTV, and natives to query (bug 5124, r=fyren).
core/PlayerManager.cpp
core/PlayerManager.h
core/smn_player.cpp
plugins/include/clients.inc
public/IPlayerHelpers.h
     1.1 --- a/core/PlayerManager.cpp	Thu Oct 20 21:35:50 2011 -0400
     1.2 +++ b/core/PlayerManager.cpp	Thu Oct 20 21:39:57 2011 -0400
     1.3 @@ -44,6 +44,7 @@
     1.4  #include "HalfLife2.h"
     1.5  #include <inetchannel.h>
     1.6  #include <iclient.h>
     1.7 +#include <tier0/icommandline.h>
     1.8  #include <IGameConfigs.h>
     1.9  #include "ExtensionSys.h"
    1.10  #include <sourcemod_version.h>
    1.11 @@ -113,6 +114,9 @@
    1.12  	m_FirstPass = false;
    1.13  	m_maxClients = 0;
    1.14  
    1.15 +	m_SourceTVUserId = -1;
    1.16 +	m_ReplayUserId = -1;
    1.17 +
    1.18  	m_UserIdLookUp = new int[USHRT_MAX+1];
    1.19  	memset(m_UserIdLookUp, 0, sizeof(int) * (USHRT_MAX+1));
    1.20  }
    1.21 @@ -232,8 +236,20 @@
    1.22  
    1.23  void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
    1.24  {
    1.25 +	static ConVar *tv_enable = icvar->FindVar("tv_enable");
    1.26 +#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
    1.27 +	static ConVar *replay_enable = icvar->FindVar("replay_enable");
    1.28 +#endif
    1.29 +
    1.30  	// clientMax will not necessarily be correct here (such as on late SourceTV enable)
    1.31  	m_maxClients = gpGlobals->maxClients;
    1.32 +
    1.33 +	m_bIsSourceTVActive = (tv_enable && tv_enable->GetBool() && CommandLine()->FindParm("-nohltv") == 0);
    1.34 +	m_bIsReplayActive = false;
    1.35 +#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
    1.36 +	m_bIsReplayActive = (replay_enable && replay_enable->GetBool());
    1.37 +#endif
    1.38 +	m_PlayersSinceActive = 0;
    1.39  	
    1.40  	if (!m_FirstPass)
    1.41  	{
    1.42 @@ -411,6 +427,7 @@
    1.43  {
    1.44  	int client = IndexOfEdict(pEntity);
    1.45  	CPlayer *pPlayer = &m_Players[client];
    1.46 +	++m_PlayersSinceActive;
    1.47  
    1.48  	pPlayer->Initialize(pszName, pszAddress, pEntity);
    1.49  	
    1.50 @@ -518,6 +535,40 @@
    1.51  		const char *authid = engine->GetPlayerNetworkIDString(pEntity);
    1.52  		pPlayer->Authorize(authid);
    1.53  		pPlayer->m_bFakeClient = true;
    1.54 +
    1.55 +		/*
    1.56 +		 * While we're already filtered to just bots, we'll do other checks to
    1.57 +		 * make sure that the requisite services are enabled and that the bots
    1.58 +		 * have joined at the expected time.
    1.59 +		 *
    1.60 +		 * Checking playerinfo's IsHLTV and IsReplay would be better and less
    1.61 +		 * error-prone but will always show false until later in the frame,
    1.62 +		 * after PutInServer and Activate, and we want it now!
    1.63 +		 */
    1.64 +		
    1.65 +		// This doesn't actually get incremented until OnClientConnect. Fake it to check.
    1.66 +		int newCount = m_PlayersSinceActive + 1;
    1.67 +		int userId = engine->GetPlayerUserId(pEntity);
    1.68 +
    1.69 +#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
    1.70 +		if (m_bIsReplayActive && newCount == 1
    1.71 +			&& (m_ReplayUserId == userId || strcmp(playername, "Replay") == 0))
    1.72 +		{
    1.73 +			pPlayer->m_bIsReplay = true;
    1.74 +			m_ReplayUserId = userId;
    1.75 +		}
    1.76 +#endif
    1.77 +
    1.78 +		if (m_bIsSourceTVActive
    1.79 +			&& ((!m_bIsReplayActive && newCount == 1)
    1.80 +				|| (m_bIsReplayActive && newCount == 2))
    1.81 +			&& (m_SourceTVUserId == userId || strcmp(playername, "SourceTV") == 0)
    1.82 +			)
    1.83 +		{
    1.84 +			pPlayer->m_bIsSourceTV = true;
    1.85 +			m_SourceTVUserId = userId;
    1.86 +		}
    1.87 +
    1.88  		if (!OnClientConnect(pEntity, playername, "127.0.0.1", error, sizeof(error)))
    1.89  		{
    1.90  			/* :TODO: kick the bot if it's rejected */
    1.91 @@ -1452,6 +1503,8 @@
    1.92  	m_LastPassword.clear();
    1.93  	m_LangId = SOURCEMOD_LANGUAGE_ENGLISH;
    1.94  	m_bFakeClient = false;
    1.95 +	m_bIsSourceTV = false;
    1.96 +	m_bIsReplay = false;
    1.97  	m_Serial.value = -1;
    1.98  }
    1.99  
   1.100 @@ -1524,6 +1577,8 @@
   1.101  	m_UserId = -1;
   1.102  	m_bIsInKickQueue = false;
   1.103  	m_bFakeClient = false;
   1.104 +	m_bIsSourceTV = false;
   1.105 +	m_bIsReplay = false;
   1.106  	m_Serial.value = -1;
   1.107  }
   1.108  
   1.109 @@ -1592,6 +1647,16 @@
   1.110  	return m_bFakeClient;
   1.111  }
   1.112  
   1.113 +bool CPlayer::IsSourceTV() const
   1.114 +{
   1.115 +	return m_bIsSourceTV;
   1.116 +}
   1.117 +
   1.118 +bool CPlayer::IsReplay() const
   1.119 +{
   1.120 +	return m_bIsReplay;
   1.121 +}
   1.122 +
   1.123  void CPlayer::SetAdminId(AdminId id, bool temporary)
   1.124  {
   1.125  	if (!m_IsConnected)
     2.1 --- a/core/PlayerManager.h	Thu Oct 20 21:35:50 2011 -0400
     2.2 +++ b/core/PlayerManager.h	Thu Oct 20 21:39:57 2011 -0400
     2.3 @@ -76,6 +76,8 @@
     2.4  	bool IsConnected();
     2.5  	bool IsAuthorized();
     2.6  	bool IsFakeClient();
     2.7 +	bool IsSourceTV() const;
     2.8 +	bool IsReplay() const;
     2.9  	void SetAdminId(AdminId id, bool temporary);
    2.10  	AdminId GetAdminId();
    2.11  	void Kick(const char *str);
    2.12 @@ -119,6 +121,8 @@
    2.13  	unsigned int m_LangId;
    2.14  	int m_UserId;
    2.15  	bool m_bFakeClient;
    2.16 +	bool m_bIsSourceTV;
    2.17 +	bool m_bIsReplay;
    2.18  	serial_t m_Serial;
    2.19  };
    2.20  
    2.21 @@ -208,12 +212,17 @@
    2.22  	int *m_UserIdLookUp;
    2.23  	int m_maxClients;
    2.24  	int m_PlayerCount;
    2.25 +	int m_PlayersSinceActive;
    2.26  	bool m_FirstPass;
    2.27  	unsigned int *m_AuthQueue;
    2.28  	String m_PassInfoVar;
    2.29  	bool m_QueryLang;
    2.30  	bool m_bIsListenServer;
    2.31  	int m_ListenClient;
    2.32 +	bool m_bIsSourceTVActive;
    2.33 +	bool m_bIsReplayActive;
    2.34 +	int m_SourceTVUserId;
    2.35 +	int m_ReplayUserId;
    2.36  };
    2.37  
    2.38  #if SOURCE_ENGINE >= SE_ORANGEBOX
     3.1 --- a/core/smn_player.cpp	Thu Oct 20 21:35:50 2011 -0400
     3.2 +++ b/core/smn_player.cpp	Thu Oct 20 21:39:57 2011 -0400
     3.3 @@ -200,6 +200,40 @@
     3.4  	return (pPlayer->IsFakeClient()) ? 1 : 0;
     3.5  }
     3.6  
     3.7 +static cell_t sm_IsClientSourceTV(IPluginContext *pCtx, const cell_t *params)
     3.8 +{
     3.9 +	int index = params[1];
    3.10 +	if ((index < 1) || (index > g_Players.GetMaxClients()))
    3.11 +	{
    3.12 +		return pCtx->ThrowNativeError("Client index %d is invalid", index);
    3.13 +	}
    3.14 +
    3.15 +	CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
    3.16 +	if (!pPlayer->IsConnected())
    3.17 +	{
    3.18 +		return pCtx->ThrowNativeError("Client %d is not connected", index);
    3.19 +	}
    3.20 +
    3.21 +	return (pPlayer->IsSourceTV()) ? 1 : 0;
    3.22 +}
    3.23 +
    3.24 +static cell_t sm_IsClientReplay(IPluginContext *pCtx, const cell_t *params)
    3.25 +{
    3.26 +	int index = params[1];
    3.27 +	if ((index < 1) || (index > g_Players.GetMaxClients()))
    3.28 +	{
    3.29 +		return pCtx->ThrowNativeError("Client index %d is invalid", index);
    3.30 +	}
    3.31 +
    3.32 +	CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
    3.33 +	if (!pPlayer->IsConnected())
    3.34 +	{
    3.35 +		return pCtx->ThrowNativeError("Client %d is not connected", index);
    3.36 +	}
    3.37 +
    3.38 +	return (pPlayer->IsReplay()) ? 1 : 0;
    3.39 +}
    3.40 +
    3.41  static cell_t IsClientObserver(IPluginContext *pContext, const cell_t *params)
    3.42  {
    3.43  	int client = params[1];
    3.44 @@ -1605,6 +1639,8 @@
    3.45  	{"IsClientAuthorized",		sm_IsClientAuthorized},
    3.46  	{"IsClientConnected",		sm_IsClientConnected},
    3.47  	{"IsFakeClient",			sm_IsClientFakeClient},
    3.48 +	{"IsClientSourceTV",		sm_IsClientSourceTV},
    3.49 +	{"IsClientReplay",			sm_IsClientReplay},
    3.50  	{"IsClientInGame",			sm_IsClientInGame},
    3.51  	{"IsClientObserver",		IsClientObserver},
    3.52  	{"RemoveUserFlags",			RemoveUserFlags},
     4.1 --- a/plugins/include/clients.inc	Thu Oct 20 21:35:50 2011 -0400
     4.2 +++ b/plugins/include/clients.inc	Thu Oct 20 21:39:57 2011 -0400
     4.3 @@ -315,6 +315,22 @@
     4.4  native bool:IsFakeClient(client);
     4.5  
     4.6  /**
     4.7 + * Returns if a certain player is the SourceTV bot.
     4.8 + *
     4.9 + * @param client		Player index.
    4.10 + * @return				True if player is the SourceTV bot, false otherwise.
    4.11 + */
    4.12 +native bool:IsClientSourceTV(client);
    4.13 +
    4.14 +/**
    4.15 + * Returns if a certain player is the Replay bot.
    4.16 + *
    4.17 + * @param client		Player index.
    4.18 + * @return				True if player is the Replay bot, false otherwise.
    4.19 + */
    4.20 +native bool:IsClientReplay(client);
    4.21 +
    4.22 +/**
    4.23   * Returns if a certain player is an observer/spectator.
    4.24   *
    4.25   * @param client		Player index.
     5.1 --- a/public/IPlayerHelpers.h	Thu Oct 20 21:35:50 2011 -0400
     5.2 +++ b/public/IPlayerHelpers.h	Thu Oct 20 21:39:57 2011 -0400
     5.3 @@ -41,7 +41,7 @@
     5.4  #include <IAdminSystem.h>
     5.5  
     5.6  #define SMINTERFACE_PLAYERMANAGER_NAME		"IPlayerManager"
     5.7 -#define SMINTERFACE_PLAYERMANAGER_VERSION	14
     5.8 +#define SMINTERFACE_PLAYERMANAGER_VERSION	15
     5.9  
    5.10  struct edict_t;
    5.11  class IPlayerInfo;
    5.12 @@ -222,6 +222,20 @@
    5.13  		virtual void MarkAsBeingKicked() =0;
    5.14  
    5.15  		virtual void SetLanguageId(unsigned int id) =0;
    5.16 +
    5.17 +		/**
    5.18 +		 * @brief Returns whether the player is the SourceTV bot.
    5.19 +		 *
    5.20 +		 * @return		True if the SourceTV bot, false otherwise.
    5.21 +		 */
    5.22 +		virtual bool IsSourceTV() const =0;
    5.23 +		
    5.24 +		/**
    5.25 +		 * @brief Returns whether the player is the Replay bot.
    5.26 +		 *
    5.27 +		 * @return		True if the Replay bot, false otherwise.
    5.28 +		 */
    5.29 +		virtual bool IsReplay() const =0;
    5.30  	};
    5.31  
    5.32  	/**