added steamid auth functions

added better bot detection
added gameframe hook for timer
renamed more playermanager stuff

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40454
This commit is contained in:
David Anderson 2007-02-07 08:44:48 +00:00
parent 085264e837
commit 03fd3139c5
9 changed files with 225 additions and 54 deletions

View File

@ -15,7 +15,7 @@
#include "ForwardSys.h" #include "ForwardSys.h"
#include "ShareSys.h" #include "ShareSys.h"
CPlayerManager g_PlayerManager; CPlayerManager g_Players;
SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char *, const char *, char *, int); SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char *, const char *, char *, int);
SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, const char *); SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, const char *);
@ -24,6 +24,17 @@ SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *)
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *); SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *);
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int); SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
CPlayerManager::CPlayerManager()
{
m_AuthQueue = NULL;
m_FirstPass = true;
}
CPlayerManager::~CPlayerManager()
{
delete [] m_AuthQueue;
}
void CPlayerManager::OnSourceModAllInitialized() void CPlayerManager::OnSourceModAllInitialized()
{ {
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &CPlayerManager::OnClientConnect, false); SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &CPlayerManager::OnClientConnect, false);
@ -37,28 +48,17 @@ void CPlayerManager::OnSourceModAllInitialized()
g_ShareSys.AddInterface(NULL, this); g_ShareSys.AddInterface(NULL, this);
/* Register OnClientConnect */
ParamType p1[] = {Param_Cell, Param_String, Param_Cell}; ParamType p1[] = {Param_Cell, Param_String, Param_Cell};
m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_Event, 3, p1);
/* Register OnClientPutInServer */
ParamType p2[] = {Param_Cell}; ParamType p2[] = {Param_Cell};
ParamType p3[] = {Param_Cell, Param_String};
m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_Event, 3, p1);
m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", ET_Ignore, 1, p2); m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", ET_Ignore, 1, p2);
/* Register OnClientDisconnect */
m_cldisconnect = g_Forwards.CreateForward("OnClientDisconnect", ET_Ignore, 1, p2); m_cldisconnect = g_Forwards.CreateForward("OnClientDisconnect", ET_Ignore, 1, p2);
/* Register OnClientDisconnect_Post */
m_cldisconnect_post = g_Forwards.CreateForward("OnClientDisconnect_Post", ET_Ignore, 1, p2); m_cldisconnect_post = g_Forwards.CreateForward("OnClientDisconnect_Post", ET_Ignore, 1, p2);
/* Register OnClientCommand */
m_clcommand = g_Forwards.CreateForward("OnClientCommand", ET_Hook, 1, p2); m_clcommand = g_Forwards.CreateForward("OnClientCommand", ET_Hook, 1, p2);
/* Register OnClientSettingsChanged */
m_clinfochanged = g_Forwards.CreateForward("OnClientSettingsChanged", ET_Ignore, 1, p2); m_clinfochanged = g_Forwards.CreateForward("OnClientSettingsChanged", ET_Ignore, 1, p2);
m_clauth = g_Forwards.CreateForward("OnClientAuthorized", ET_Ignore, 2, p2);
/* Register OnClientAuthorized */
//:TODO:
} }
void CPlayerManager::OnSourceModShutdown() void CPlayerManager::OnSourceModShutdown()
@ -78,6 +78,7 @@ void CPlayerManager::OnSourceModShutdown()
g_Forwards.ReleaseForward(m_cldisconnect_post); g_Forwards.ReleaseForward(m_cldisconnect_post);
g_Forwards.ReleaseForward(m_clcommand); g_Forwards.ReleaseForward(m_clcommand);
g_Forwards.ReleaseForward(m_clinfochanged); g_Forwards.ReleaseForward(m_clinfochanged);
g_Forwards.ReleaseForward(m_clauth);
delete [] m_Players; delete [] m_Players;
} }
@ -90,7 +91,79 @@ void CPlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int c
m_maxClients = clientMax; m_maxClients = clientMax;
m_PlayerCount = 0; m_PlayerCount = 0;
m_Players = new CPlayer[m_maxClients + 1]; m_Players = new CPlayer[m_maxClients + 1];
m_AuthQueue = new unsigned int[m_maxClients + 1];
m_FirstPass = false; m_FirstPass = false;
memset(m_AuthQueue, 0, sizeof(unsigned int) * (m_maxClients + 1));
}
}
void CPlayerManager::RunAuthChecks()
{
CPlayer *pPlayer;
const char *authstr;
unsigned int removed = 0;
for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
{
pPlayer = GetPlayerByIndex(m_AuthQueue[i]);
authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict);
if (authstr && authstr[0] != '\0'
&& (strcmp(authstr, "STEAM_ID_PENDING") != 0))
{
/* Set authorization */
pPlayer->m_AuthID.assign(authstr);
pPlayer->m_IsAuthorized = true;
/* Send to extensions */
List<IClientListener *>::iterator iter;
IClientListener *pListener;
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
{
pListener = (*iter);
pListener->OnClientAuthorized(m_AuthQueue[i], authstr);
}
/* Send to plugins */
if (m_clauth->GetFunctionCount())
{
m_clauth->PushCell(m_AuthQueue[i]);
m_clauth->PushString(authstr);
m_clauth->Execute(NULL);
}
/* Mark as removed from queue */
m_AuthQueue[i] = 0;
removed++;
}
}
/* Clean up the queue */
if (removed)
{
/* We don't have to compcat the list if it's empty */
if (removed != m_AuthQueue[0])
{
unsigned int diff = 0;
for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
{
/* If this member is removed... */
if (m_AuthQueue[i] == 0)
{
/* Increase the differential */
diff++;
} else {
/* diff cannot increase faster than i+1 */
assert(i > diff);
assert(i - diff >= 1);
/* move this index down */
m_AuthQueue[i - diff] = m_AuthQueue[i];
}
}
m_AuthQueue[0] -= removed;
} else {
m_AuthQueue[0] = 0;
g_SourceMod.SetAuthChecking(false);
}
} }
} }
@ -117,6 +190,12 @@ bool CPlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, cons
m_clconnect->PushCell(maxrejectlen); m_clconnect->PushCell(maxrejectlen);
m_clconnect->Execute(&res, NULL); m_clconnect->Execute(&res, NULL);
if (res)
{
m_AuthQueue[++m_AuthQueue[0]] = client;
g_SourceMod.SetAuthChecking(true);
}
return (res) ? true : false; return (res) ? true : false;
} }
@ -143,6 +222,25 @@ void CPlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playernam
cell_t res; cell_t res;
int client = engine->IndexOfEdict(pEntity); int client = engine->IndexOfEdict(pEntity);
CPlayer *pPlayer = GetPlayerByIndex(client);
if (!pPlayer->IsConnected())
{
/* Run manual connection routines */
char error[255];
if (!OnClientConnect(pEntity, playername, "127.0.0.1", error, sizeof(error)))
{
/* :TODO: kick the bot if it's rejected */
return;
}
List<IClientListener *>::iterator iter;
IClientListener *pListener = NULL;
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
{
pListener = (*iter);
pListener->OnClientConnected(client);
}
}
List<IClientListener *>::iterator iter; List<IClientListener *>::iterator iter;
IClientListener *pListener = NULL; IClientListener *pListener = NULL;
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++) for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
@ -186,6 +284,27 @@ void CPlayerManager::OnClientDisconnect(edict_t *pEntity)
pListener->OnClientDisconnecting(client); pListener->OnClientDisconnecting(client);
} }
/**
* Remove client from auth queue if necessary
*/
if (!m_Players[client].IsAuthorized())
{
for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
{
if (m_AuthQueue[i] == client)
{
/* Move everything ahead of us back by one */
for (unsigned int j=i+1; j<=m_AuthQueue[0]; j++)
{
m_AuthQueue[j-1] = m_AuthQueue[j];
}
/* Remove us and break */
m_AuthQueue[0]--;
break;
}
}
}
m_Players[client].Disconnect(); m_Players[client].Disconnect();
} }
@ -275,7 +394,7 @@ CPlayer::CPlayer()
m_IsConnected = false; m_IsConnected = false;
m_IsInGame = false; m_IsInGame = false;
m_IsAuthorized = false; m_IsAuthorized = false;
m_PlayerEdict = NULL; m_pEdict = NULL;
} }
void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity) void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
@ -283,7 +402,7 @@ void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
m_IsConnected = true; m_IsConnected = true;
m_Name.assign(name); m_Name.assign(name);
m_Ip.assign(ip); m_Ip.assign(ip);
m_PlayerEdict = pEntity; m_pEdict = pEntity;
} }
void CPlayer::Connect() void CPlayer::Connect()
@ -305,7 +424,7 @@ void CPlayer::Disconnect()
m_Name.clear(); m_Name.clear();
m_Ip.clear(); m_Ip.clear();
m_AuthID.clear(); m_AuthID.clear();
m_PlayerEdict = NULL; m_pEdict = NULL;
} }
void CPlayer::SetName(const char *name) void CPlayer::SetName(const char *name)
@ -330,7 +449,7 @@ const char *CPlayer::GetAuthString() const
edict_t *CPlayer::GetEdict() const edict_t *CPlayer::GetEdict() const
{ {
return m_PlayerEdict; return m_pEdict;
} }
bool CPlayer::IsInGame() const bool CPlayer::IsInGame() const

View File

@ -21,6 +21,7 @@
#include <IPlayerHelpers.h> #include <IPlayerHelpers.h>
#include <sh_string.h> #include <sh_string.h>
#include <sh_list.h> #include <sh_list.h>
#include <sh_vector.h>
using namespace SourceHook; using namespace SourceHook;
@ -51,7 +52,7 @@ private:
String m_Name; String m_Name;
String m_Ip; String m_Ip;
String m_AuthID; String m_AuthID;
edict_t *m_PlayerEdict; edict_t *m_pEdict;
}; };
class CPlayerManager : class CPlayerManager :
@ -59,12 +60,14 @@ class CPlayerManager :
public IPlayerManager public IPlayerManager
{ {
public: public:
CPlayerManager() : m_FirstPass(true) {} CPlayerManager();
~CPlayerManager();
public: //SMGlobalClass public: //SMGlobalClass
void OnSourceModAllInitialized(); void OnSourceModAllInitialized();
void OnSourceModShutdown(); void OnSourceModShutdown();
public: public:
CPlayer *GetPlayerByIndex(int client) const; CPlayer *GetPlayerByIndex(int client) const;
void RunAuthChecks();
public: public:
bool OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen); bool OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen);
bool OnClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen); bool OnClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen);
@ -100,12 +103,14 @@ private:
IForward *m_clputinserver; IForward *m_clputinserver;
IForward *m_clcommand; IForward *m_clcommand;
IForward *m_clinfochanged; IForward *m_clinfochanged;
IForward *m_clauth;
CPlayer *m_Players; CPlayer *m_Players;
int m_maxClients; int m_maxClients;
int m_PlayerCount; int m_PlayerCount;
bool m_FirstPass; bool m_FirstPass;
unsigned int *m_AuthQueue;
}; };
extern CPlayerManager g_PlayerManager; extern CPlayerManager g_Players;
#endif //_INCLUDE_SOURCEMOD_CPLAYERMANAGER_H_ #endif //_INCLUDE_SOURCEMOD_CPLAYERMANAGER_H_

View File

@ -72,7 +72,7 @@ try_serverlang:
pCtx->ThrowNativeError("Translation failure: English language not found."); pCtx->ThrowNativeError("Translation failure: English language not found.");
goto error_out; goto error_out;
} }
} else if ((target >= 1) && (target <= g_PlayerManager.GetMaxClients())) { } else if ((target >= 1) && (target <= g_Players.GetMaxClients())) {
langname = "en"; //:TODO: read player's lang langname = "en"; //:TODO: read player's lang
if (!langname || !g_Translator.GetLanguageByCode(langname, &langid)) if (!langname || !g_Translator.GetLanguageByCode(langname, &langid))
{ {

View File

@ -18,37 +18,37 @@ static cell_t sm_GetClientCount(IPluginContext *pCtx, const cell_t *params)
{ {
if (params[1]) if (params[1])
{ {
return g_PlayerManager.NumPlayers(); return g_Players.NumPlayers();
} }
int maxplayers = g_PlayerManager.MaxClients(); int maxplayers = g_Players.MaxClients();
int count = 0; int count = 0;
for (int i=1; i<=maxplayers; ++i) for (int i=1; i<=maxplayers; ++i)
{ {
CPlayer *pPlayer = g_PlayerManager.GetPlayerByIndex(i); CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
if ((pPlayer->IsConnected()) && !(pPlayer->IsInGame())) if ((pPlayer->IsConnected()) && !(pPlayer->IsInGame()))
{ {
count++; count++;
} }
} }
return (g_PlayerManager.NumPlayers() + count); return (g_Players.NumPlayers() + count);
} }
static cell_t sm_GetMaxClients(IPluginContext *pCtx, const cell_t *params) static cell_t sm_GetMaxClients(IPluginContext *pCtx, const cell_t *params)
{ {
return g_PlayerManager.MaxClients(); return g_Players.MaxClients();
} }
static cell_t sm_GetClientName(IPluginContext *pCtx, const cell_t *params) static cell_t sm_GetClientName(IPluginContext *pCtx, const cell_t *params)
{ {
int index = params[1]; int index = params[1];
if ((index < 1) || (index > g_PlayerManager.GetMaxClients())) if ((index < 1) || (index > g_Players.GetMaxClients()))
{ {
return pCtx->ThrowNativeError("Invalid client index %d.", index); return pCtx->ThrowNativeError("Invalid client index %d.", index);
} }
CPlayer *pPlayer = g_PlayerManager.GetPlayerByIndex(index); CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
if (!pPlayer->IsConnected()) if (!pPlayer->IsConnected())
{ {
return pCtx->ThrowNativeError("Client %d is not connected.", index); return pCtx->ThrowNativeError("Client %d is not connected.", index);
@ -61,12 +61,12 @@ static cell_t sm_GetClientName(IPluginContext *pCtx, const cell_t *params)
static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params) static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params)
{ {
int index = params[1]; int index = params[1];
if ((index < 1) || (index > g_PlayerManager.GetMaxClients())) if ((index < 1) || (index > g_Players.GetMaxClients()))
{ {
return pCtx->ThrowNativeError("Invalid client index %d.", index); return pCtx->ThrowNativeError("Invalid client index %d.", index);
} }
CPlayer *pPlayer = g_PlayerManager.GetPlayerByIndex(index); CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
if (!pPlayer->IsConnected()) if (!pPlayer->IsConnected())
{ {
return pCtx->ThrowNativeError("Client %d is not connected.", index); return pCtx->ThrowNativeError("Client %d is not connected.", index);
@ -87,12 +87,12 @@ static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params)
static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params) static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
{ {
int index = params[1]; int index = params[1];
if ((index < 1) || (index > g_PlayerManager.GetMaxClients())) if ((index < 1) || (index > g_Players.GetMaxClients()))
{ {
return pCtx->ThrowNativeError("Invalid client index %d.", index); return pCtx->ThrowNativeError("Invalid client index %d.", index);
} }
CPlayer *pPlayer = g_PlayerManager.GetPlayerByIndex(index); CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
if (!pPlayer->IsConnected()) if (!pPlayer->IsConnected())
{ {
return pCtx->ThrowNativeError("Client %d is not connected.", index); return pCtx->ThrowNativeError("Client %d is not connected.", index);
@ -105,45 +105,45 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
static cell_t sm_IsPlayerConnected(IPluginContext *pCtx, const cell_t *params) static cell_t sm_IsPlayerConnected(IPluginContext *pCtx, const cell_t *params)
{ {
int index = params[1]; int index = params[1];
if ((index < 1) || (index > g_PlayerManager.GetMaxClients())) if ((index < 1) || (index > g_Players.GetMaxClients()))
{ {
return pCtx->ThrowNativeError("Invalid client index %d.", index); return pCtx->ThrowNativeError("Invalid client index %d.", index);
} }
return (g_PlayerManager.GetPlayerByIndex(index)->IsConnected()) ? 1 : 0; return (g_Players.GetPlayerByIndex(index)->IsConnected()) ? 1 : 0;
} }
static cell_t sm_IsPlayerIngame(IPluginContext *pCtx, const cell_t *params) static cell_t sm_IsPlayerIngame(IPluginContext *pCtx, const cell_t *params)
{ {
int index = params[1]; int index = params[1];
if ((index < 1) || (index > g_PlayerManager.GetMaxClients())) if ((index < 1) || (index > g_Players.GetMaxClients()))
{ {
return pCtx->ThrowNativeError("Invalid client index %d.", index); return pCtx->ThrowNativeError("Invalid client index %d.", index);
} }
return (g_PlayerManager.GetPlayerByIndex(index)->IsInGame()) ? 1 : 0; return (g_Players.GetPlayerByIndex(index)->IsInGame()) ? 1 : 0;
} }
static cell_t sm_IsPlayerAuthorized(IPluginContext *pCtx, const cell_t *params) static cell_t sm_IsPlayerAuthorized(IPluginContext *pCtx, const cell_t *params)
{ {
int index = params[1]; int index = params[1];
if ((index < 1) || (index > g_PlayerManager.GetMaxClients())) if ((index < 1) || (index > g_Players.GetMaxClients()))
{ {
return pCtx->ThrowNativeError("Invalid client index %d.", index); return pCtx->ThrowNativeError("Invalid client index %d.", index);
} }
return (g_PlayerManager.GetPlayerByIndex(index)->IsAuthorized()) ? 1 : 0; return (g_Players.GetPlayerByIndex(index)->IsAuthorized()) ? 1 : 0;
} }
static cell_t sm_IsPlayerFakeClient(IPluginContext *pCtx, const cell_t *params) static cell_t sm_IsPlayerFakeClient(IPluginContext *pCtx, const cell_t *params)
{ {
int index = params[1]; int index = params[1];
if ((index < 1) || (index > g_PlayerManager.GetMaxClients())) if ((index < 1) || (index > g_Players.GetMaxClients()))
{ {
return pCtx->ThrowNativeError("Invalid client index %d.", index); return pCtx->ThrowNativeError("Invalid client index %d.", index);
} }
CPlayer *pPlayer = g_PlayerManager.GetPlayerByIndex(index); CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
if (!pPlayer->IsConnected()) if (!pPlayer->IsConnected())
{ {
return pCtx->ThrowNativeError("Client %d is not connected.", index); return pCtx->ThrowNativeError("Client %d is not connected.", index);
@ -172,12 +172,12 @@ static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params)
static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params) static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
{ {
int index = params[1]; int index = params[1];
if ((index < 1) || (index > g_PlayerManager.GetMaxClients())) if ((index < 1) || (index > g_Players.GetMaxClients()))
{ {
return pCtx->ThrowNativeError("Invalid client index %d.", index); return pCtx->ThrowNativeError("Invalid client index %d.", index);
} }
CPlayer *pPlayer = g_PlayerManager.GetPlayerByIndex(index); CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
if (!pPlayer->IsInGame()) if (!pPlayer->IsInGame())
{ {
return pCtx->ThrowNativeError("Client %d is not in game.", index); return pCtx->ThrowNativeError("Client %d is not in game.", index);

View File

@ -21,6 +21,7 @@ IVEngineServer *engine = NULL;
IServerGameDLL *gamedll = NULL; IServerGameDLL *gamedll = NULL;
IServerGameClients *serverClients = NULL; IServerGameClients *serverClients = NULL;
ISmmPluginManager *g_pMMPlugins = NULL; ISmmPluginManager *g_pMMPlugins = NULL;
CGlobalVars *gpGlobals = NULL;
PLUGIN_EXPOSE(SourceMod, g_SourceMod_Core); PLUGIN_EXPOSE(SourceMod, g_SourceMod_Core);
@ -41,6 +42,8 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
return false; return false;
} }
gpGlobals = ismm->pGlobals();
return g_SourceMod.InitializeSourceMod(error, maxlen, late); return g_SourceMod.InitializeSourceMod(error, maxlen, late);
} }

View File

@ -45,6 +45,7 @@ extern IVEngineServer *engine;
extern IServerGameDLL *gamedll; extern IServerGameDLL *gamedll;
extern IServerGameClients *serverClients; extern IServerGameClients *serverClients;
extern ISmmPluginManager *g_pMMPlugins; extern ISmmPluginManager *g_pMMPlugins;
extern CGlobalVars *gpGlobals;
PLUGIN_GLOBALVARS(); PLUGIN_GLOBALVARS();

View File

@ -23,9 +23,11 @@
#include "ExtensionSys.h" #include "ExtensionSys.h"
#include "AdminCache.h" #include "AdminCache.h"
#include "sm_stringutil.h" #include "sm_stringutil.h"
#include "CPlayerManager.h"
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool); SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false); SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false);
SH_DECL_HOOK1_void(IServerGameDLL, GameFrame, SH_NOATTRIB, false, bool);
SourcePawnEngine g_SourcePawn; SourcePawnEngine g_SourcePawn;
SourceModBase g_SourceMod; SourceModBase g_SourceMod;
@ -35,6 +37,8 @@ SourceHook::String g_BaseDir;
ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn; ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn;
IVirtualMachine *g_pVM; IVirtualMachine *g_pVM;
IdentityToken_t *g_pCoreIdent = NULL; IdentityToken_t *g_pCoreIdent = NULL;
float g_LastTime = 0.0f;
float g_LastAuthCheck = 0.0f;
typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *); typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *);
typedef unsigned int (*GETEXPORTCOUNT)(); typedef unsigned int (*GETEXPORTCOUNT)();
@ -150,6 +154,7 @@ void SourceModBase::StartSourceMod(bool late)
/* First initialize the global hooks we need */ /* First initialize the global hooks we need */
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false); SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false);
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, this, &SourceModBase::LevelShutdown, false); SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, this, &SourceModBase::LevelShutdown, false);
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, GameFrame, gamedll, this, &SourceModBase::GameFrame, false);
/* Notify! */ /* Notify! */
SMGlobalClass *pBase = SMGlobalClass::head; SMGlobalClass *pBase = SMGlobalClass::head;
@ -178,6 +183,8 @@ bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, ch
{ {
m_IsMapLoading = true; m_IsMapLoading = true;
m_ExecPluginReload = true; m_ExecPluginReload = true;
g_LastTime = 0.0f;
g_LastAuthCheck = 0.0f;
g_Logger.MapChange(pMapName); g_Logger.MapChange(pMapName);
@ -191,6 +198,25 @@ bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, ch
RETURN_META_VALUE(MRES_IGNORED, true); RETURN_META_VALUE(MRES_IGNORED, true);
} }
void SourceModBase::GameFrame(bool simulating)
{
/**
* Note: This is all hardcoded rather than delegated to save
* precious CPU cycles.
*/
float curtime = gpGlobals->curtime;
if (curtime - g_LastTime > 0.1f)
{
if (m_CheckingAuth
&& (gpGlobals->curtime - g_LastAuthCheck > 0.7f))
{
g_LastAuthCheck = gpGlobals->curtime;
g_Players.RunAuthChecks();
}
g_LastTime = curtime;
}
}
void SourceModBase::LevelShutdown() void SourceModBase::LevelShutdown()
{ {
if (m_ExecPluginReload) if (m_ExecPluginReload)
@ -280,6 +306,7 @@ void SourceModBase::CloseSourceMod()
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false); SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SourceModBase::LevelInit, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, this, &SourceModBase::LevelShutdown, false); SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, LevelShutdown, gamedll, this, &SourceModBase::LevelShutdown, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, GameFrame, gamedll, this, &SourceModBase::GameFrame, false);
/* Rest In Peace */ /* Rest In Peace */
ShutdownJIT(); ShutdownJIT();
@ -349,6 +376,11 @@ void SourceModBase::SetGlobalTarget(unsigned int index)
m_target = index; m_target = index;
} }
void SourceModBase::SetAuthChecking(bool set)
{
m_CheckingAuth = set;
}
unsigned int SourceModBase::GetGlobalTarget() const unsigned int SourceModBase::GetGlobalTarget() const
{ {
return m_target; return m_target;

View File

@ -37,8 +37,8 @@ public:
void StartSourceMod(bool late); void StartSourceMod(bool late);
/** /**
* @brief Shuts down all SourceMod components * @brief Shuts down all SourceMod components
*/ */
void CloseSourceMod(); void CloseSourceMod();
/** /**
@ -47,8 +47,8 @@ public:
bool LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background); bool LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
/** /**
* @brief Level shutdown hook * @brief Level shutdown hook
*/ */
void LevelShutdown(); void LevelShutdown();
/** /**
@ -57,15 +57,14 @@ public:
bool IsMapLoading(); bool IsMapLoading();
/** /**
* @brief Stores the global target index. * @brief Stores the global target index.
*/ */
void SetGlobalTarget(unsigned int index); void SetGlobalTarget(unsigned int index);
/** /**
* @brief Returns the global target index. * @brief Returns the global target index.
*/ */
unsigned int GetGlobalTarget() const; unsigned int GetGlobalTarget() const;
public: //ISourceMod public: //ISourceMod
const char *GetModPath(); const char *GetModPath();
const char *GetSourceModPath(); const char *GetSourceModPath();
@ -73,17 +72,20 @@ public: //ISourceMod
void LogMessage(IExtension *pExt, const char *format, ...); void LogMessage(IExtension *pExt, const char *format, ...);
void LogError(IExtension *pExt, const char *format, ...); void LogError(IExtension *pExt, const char *format, ...);
size_t FormatString(char *buffer, size_t maxlength, IPluginContext *pContext, const cell_t *params, unsigned int param); size_t FormatString(char *buffer, size_t maxlength, IPluginContext *pContext, const cell_t *params, unsigned int param);
void SetAuthChecking(bool set);
private: private:
/** /**
* @brief Loading plugins * @brief Loading plugins
*/ */
void DoGlobalPluginLoads(); void DoGlobalPluginLoads();
void GameFrame(bool simulating);
private: private:
char m_SMBaseDir[PLATFORM_MAX_PATH+1]; char m_SMBaseDir[PLATFORM_MAX_PATH+1];
char m_SMRelDir[PLATFORM_MAX_PATH+1]; char m_SMRelDir[PLATFORM_MAX_PATH+1];
bool m_IsMapLoading; bool m_IsMapLoading;
bool m_ExecPluginReload; bool m_ExecPluginReload;
unsigned int m_target; unsigned int m_target;
bool m_CheckingAuth;
}; };
extern SourceModBase g_SourceMod; extern SourceModBase g_SourceMod;

View File

@ -136,6 +136,15 @@ forward OnClientCommand(client);
*/ */
forward OnClientSettingsChanged(client); forward OnClientSettingsChanged(client);
/**
* Called when a client receives a Steam ID.
* @note This is called by bots, but the ID will be "BOT"
*
* @param client Player index.
* @param auth Player auth string.
*/
forward OnClientAuthorized(client, const String:auth[]);
/** /**
* Returns the maximum number of clients allowed on the server. * Returns the maximum number of clients allowed on the server.
* *