Added detection of Replay and SourceTV, and natives to query (bug 5124, r=fyren).
This commit is contained in:
parent
5732e34f50
commit
f3d19a860a
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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},
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user