Added detection of Replay and SourceTV, and natives to query (bug 5124, r=fyren).

This commit is contained in:
Nicholas Hastings 2011-10-20 21:39:57 -04:00
parent 5732e34f50
commit f3d19a860a
5 changed files with 141 additions and 1 deletions

View File

@ -44,6 +44,7 @@
#include "HalfLife2.h"
#include <inetchannel.h>
#include <iclient.h>
#include <tier0/icommandline.h>
#include <IGameConfigs.h>
#include "ExtensionSys.h"
#include <sourcemod_version.h>
@ -113,6 +114,9 @@ PlayerManager::PlayerManager()
m_FirstPass = false;
m_maxClients = 0;
m_SourceTVUserId = -1;
m_ReplayUserId = -1;
m_UserIdLookUp = new int[USHRT_MAX+1];
memset(m_UserIdLookUp, 0, sizeof(int) * (USHRT_MAX+1));
}
@ -232,8 +236,20 @@ ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
{
static ConVar *tv_enable = icvar->FindVar("tv_enable");
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
static ConVar *replay_enable = icvar->FindVar("replay_enable");
#endif
// clientMax will not necessarily be correct here (such as on late SourceTV enable)
m_maxClients = gpGlobals->maxClients;
m_bIsSourceTVActive = (tv_enable && tv_enable->GetBool() && CommandLine()->FindParm("-nohltv") == 0);
m_bIsReplayActive = false;
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
m_bIsReplayActive = (replay_enable && replay_enable->GetBool());
#endif
m_PlayersSinceActive = 0;
if (!m_FirstPass)
{
@ -411,6 +427,7 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
{
int client = IndexOfEdict(pEntity);
CPlayer *pPlayer = &m_Players[client];
++m_PlayersSinceActive;
pPlayer->Initialize(pszName, pszAddress, pEntity);
@ -518,6 +535,40 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
const char *authid = engine->GetPlayerNetworkIDString(pEntity);
pPlayer->Authorize(authid);
pPlayer->m_bFakeClient = true;
/*
* While we're already filtered to just bots, we'll do other checks to
* make sure that the requisite services are enabled and that the bots
* have joined at the expected time.
*
* Checking playerinfo's IsHLTV and IsReplay would be better and less
* error-prone but will always show false until later in the frame,
* after PutInServer and Activate, and we want it now!
*/
// This doesn't actually get incremented until OnClientConnect. Fake it to check.
int newCount = m_PlayersSinceActive + 1;
int userId = engine->GetPlayerUserId(pEntity);
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
if (m_bIsReplayActive && newCount == 1
&& (m_ReplayUserId == userId || strcmp(playername, "Replay") == 0))
{
pPlayer->m_bIsReplay = true;
m_ReplayUserId = userId;
}
#endif
if (m_bIsSourceTVActive
&& ((!m_bIsReplayActive && newCount == 1)
|| (m_bIsReplayActive && newCount == 2))
&& (m_SourceTVUserId == userId || strcmp(playername, "SourceTV") == 0)
)
{
pPlayer->m_bIsSourceTV = true;
m_SourceTVUserId = userId;
}
if (!OnClientConnect(pEntity, playername, "127.0.0.1", error, sizeof(error)))
{
/* :TODO: kick the bot if it's rejected */
@ -1452,6 +1503,8 @@ CPlayer::CPlayer()
m_LastPassword.clear();
m_LangId = SOURCEMOD_LANGUAGE_ENGLISH;
m_bFakeClient = false;
m_bIsSourceTV = false;
m_bIsReplay = false;
m_Serial.value = -1;
}
@ -1524,6 +1577,8 @@ void CPlayer::Disconnect()
m_UserId = -1;
m_bIsInKickQueue = false;
m_bFakeClient = false;
m_bIsSourceTV = false;
m_bIsReplay = false;
m_Serial.value = -1;
}
@ -1592,6 +1647,16 @@ bool CPlayer::IsFakeClient()
return m_bFakeClient;
}
bool CPlayer::IsSourceTV() const
{
return m_bIsSourceTV;
}
bool CPlayer::IsReplay() const
{
return m_bIsReplay;
}
void CPlayer::SetAdminId(AdminId id, bool temporary)
{
if (!m_IsConnected)

View File

@ -76,6 +76,8 @@ public:
bool IsConnected();
bool IsAuthorized();
bool IsFakeClient();
bool IsSourceTV() const;
bool IsReplay() const;
void SetAdminId(AdminId id, bool temporary);
AdminId GetAdminId();
void Kick(const char *str);
@ -119,6 +121,8 @@ private:
unsigned int m_LangId;
int m_UserId;
bool m_bFakeClient;
bool m_bIsSourceTV;
bool m_bIsReplay;
serial_t m_Serial;
};
@ -208,12 +212,17 @@ private:
int *m_UserIdLookUp;
int m_maxClients;
int m_PlayerCount;
int m_PlayersSinceActive;
bool m_FirstPass;
unsigned int *m_AuthQueue;
String m_PassInfoVar;
bool m_QueryLang;
bool m_bIsListenServer;
int m_ListenClient;
bool m_bIsSourceTVActive;
bool m_bIsReplayActive;
int m_SourceTVUserId;
int m_ReplayUserId;
};
#if SOURCE_ENGINE >= SE_ORANGEBOX

View File

@ -200,6 +200,40 @@ static cell_t sm_IsClientFakeClient(IPluginContext *pCtx, const cell_t *params)
return (pPlayer->IsFakeClient()) ? 1 : 0;
}
static cell_t sm_IsClientSourceTV(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->IsSourceTV()) ? 1 : 0;
}
static cell_t sm_IsClientReplay(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->IsReplay()) ? 1 : 0;
}
static cell_t IsClientObserver(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
@ -1605,6 +1639,8 @@ REGISTER_NATIVES(playernatives)
{"IsClientAuthorized", sm_IsClientAuthorized},
{"IsClientConnected", sm_IsClientConnected},
{"IsFakeClient", sm_IsClientFakeClient},
{"IsClientSourceTV", sm_IsClientSourceTV},
{"IsClientReplay", sm_IsClientReplay},
{"IsClientInGame", sm_IsClientInGame},
{"IsClientObserver", IsClientObserver},
{"RemoveUserFlags", RemoveUserFlags},

View File

@ -314,6 +314,22 @@ native bool:IsClientAuthorized(client);
*/
native bool:IsFakeClient(client);
/**
* Returns if a certain player is the SourceTV bot.
*
* @param client Player index.
* @return True if player is the SourceTV bot, false otherwise.
*/
native bool:IsClientSourceTV(client);
/**
* Returns if a certain player is the Replay bot.
*
* @param client Player index.
* @return True if player is the Replay bot, false otherwise.
*/
native bool:IsClientReplay(client);
/**
* Returns if a certain player is an observer/spectator.
*

View File

@ -41,7 +41,7 @@
#include <IAdminSystem.h>
#define SMINTERFACE_PLAYERMANAGER_NAME "IPlayerManager"
#define SMINTERFACE_PLAYERMANAGER_VERSION 14
#define SMINTERFACE_PLAYERMANAGER_VERSION 15
struct edict_t;
class IPlayerInfo;
@ -222,6 +222,20 @@ namespace SourceMod
virtual void MarkAsBeingKicked() =0;
virtual void SetLanguageId(unsigned int id) =0;
/**
* @brief Returns whether the player is the SourceTV bot.
*
* @return True if the SourceTV bot, false otherwise.
*/
virtual bool IsSourceTV() const =0;
/**
* @brief Returns whether the player is the Replay bot.
*
* @return True if the Replay bot, false otherwise.
*/
virtual bool IsReplay() const =0;
};
/**