From 5e75d0928c07f67ef04c9106b0082ab15f48495f Mon Sep 17 00:00:00 2001 From: Borja Ferrer Date: Thu, 28 Dec 2006 00:48:09 +0000 Subject: [PATCH] Added PlayerManager basic hookings Moved ftoc and ctof to an utility file Added some more string natives --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40231 --- core/CPlayerManager.cpp | 101 ++++++++++++++++++++++++++++ core/CPlayerManager.h | 29 ++++++++ core/msvc8/sourcemod_mm.vcproj | 12 ++++ core/smn_float.cpp | 10 +-- core/smn_string.cpp | 46 +++++++++++++ core/sourcemm_api.cpp | 4 +- core/sourcemm_api.h | 1 + core/systems/ForwardSys.cpp | 3 + sourcepawn/include/sp_vm_typeutil.h | 15 +++++ 9 files changed, 211 insertions(+), 10 deletions(-) create mode 100644 core/CPlayerManager.cpp create mode 100644 core/CPlayerManager.h create mode 100644 sourcepawn/include/sp_vm_typeutil.h diff --git a/core/CPlayerManager.cpp b/core/CPlayerManager.cpp new file mode 100644 index 00000000..968e18af --- /dev/null +++ b/core/CPlayerManager.cpp @@ -0,0 +1,101 @@ +#include "CPlayerManager.h" +#include "ForwardSys.h" + +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_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *); +SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *); + +void CPlayerManager::OnSourceModAllInitialized() +{ + SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &CPlayerManager::OnClientConnect, false); + SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, serverClients, this, &CPlayerManager::OnClientPutInServer, true); + SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &CPlayerManager::OnClientDisconnect, false); + SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &CPlayerManager::OnClientDisconnect_Post, true); + SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientCommand, serverClients, this, &CPlayerManager::OnClientCommand, false); + + /* Register OnClientConnect */ + ParamType p1[] = {Param_Cell, Param_String, Param_Cell}; + m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_Event, 3, p1); + + /* Register OnClientPutInServer */ + ParamType p2[] = {Param_Cell}; + m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", ET_Ignore, 1, p2); + + /* Register OnClientDisconnect */ + 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); + + /* Register OnClientCommand */ + m_clcommand = g_Forwards.CreateForward("OnClientCommand", ET_Hook, 1, p2); + + /* Register OnClientAuthorized */ + //:TODO: +} + +void CPlayerManager::OnSourceModShutdown() +{ + SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &CPlayerManager::OnClientConnect, false); + SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, serverClients, this, &CPlayerManager::OnClientPutInServer, true); + SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &CPlayerManager::OnClientDisconnect, false); + SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &CPlayerManager::OnClientDisconnect_Post, true); + SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientCommand, serverClients, this, &CPlayerManager::OnClientCommand, false); + + /* Release forwards */ + g_Forwards.ReleaseForward(m_clconnect); + g_Forwards.ReleaseForward(m_clputinserver); + g_Forwards.ReleaseForward(m_cldisconnect); + g_Forwards.ReleaseForward(m_cldisconnect_post); + g_Forwards.ReleaseForward(m_clcommand); +} + +bool CPlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen) +{ + cell_t res = 1; + + m_clconnect->PushCell(engine->IndexOfEdict(pEntity)); + m_clconnect->PushStringEx(reject, maxrejectlen, SM_PARAM_STRING_UTF8, SM_PARAM_COPYBACK); + m_clconnect->PushCell(maxrejectlen); + m_clconnect->Execute(&res, NULL); + + return (res) ? true : false; +} + +void CPlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername) +{ + cell_t res; + + m_clputinserver->PushCell(engine->IndexOfEdict(pEntity)); + m_clputinserver->Execute(&res, NULL); +} + +void CPlayerManager::OnClientAuthorized() +{ + //:TODO: +} + +void CPlayerManager::OnClientDisconnect(edict_t *pEntity) +{ + cell_t res; + + m_cldisconnect->PushCell(engine->IndexOfEdict(pEntity)); + m_cldisconnect->Execute(&res, NULL); +} + +void CPlayerManager::OnClientDisconnect_Post(edict_t *pEntity) +{ + cell_t res; + + m_cldisconnect_post->PushCell(engine->IndexOfEdict(pEntity)); + m_cldisconnect_post->Execute(&res, NULL); +} + +void CPlayerManager::OnClientCommand(edict_t *pEntity) +{ + cell_t res; + + m_clcommand->PushCell(engine->IndexOfEdict(pEntity)); + m_clcommand->Execute(&res, NULL); +} \ No newline at end of file diff --git a/core/CPlayerManager.h b/core/CPlayerManager.h new file mode 100644 index 00000000..b11b233c --- /dev/null +++ b/core/CPlayerManager.h @@ -0,0 +1,29 @@ +#ifndef _INCLUDE_SOURCEMOD_CPLAYERMANAGER_H_ +#define _INCLUDE_SOURCEMOD_CPLAYERMANAGER_H_ + +#include "sourcemod.h" +#include +#include "sourcemm_api.h" +#include + +class CPlayerManager : public SMGlobalClass +{ +public: //SMGlobalClass + virtual void OnSourceModAllInitialized(); + virtual void OnSourceModShutdown(); +public: + bool OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen); + void OnClientPutInServer(edict_t *pEntity, char const *playername); + void OnClientDisconnect(edict_t *pEntity); + void OnClientDisconnect_Post(edict_t *pEntity); + void OnClientAuthorized(); //:TODO: any args needed? + void OnClientCommand(edict_t *pEntity); +private: + IForward *m_clconnect; + IForward *m_cldisconnect; + IForward *m_cldisconnect_post; + IForward *m_clputinserver; + IForward *m_clcommand; +}; + +#endif //_INCLUDE_SOURCEMOD_CPLAYERMANAGER_H_ \ No newline at end of file diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj index f729f595..79ece72c 100644 --- a/core/msvc8/sourcemod_mm.vcproj +++ b/core/msvc8/sourcemod_mm.vcproj @@ -178,6 +178,10 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + @@ -216,6 +220,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + @@ -499,6 +507,10 @@ RelativePath="..\..\sourcepawn\include\sp_vm_types.h" > + + diff --git a/core/smn_float.cpp b/core/smn_float.cpp index cba159f9..96a4d129 100644 --- a/core/smn_float.cpp +++ b/core/smn_float.cpp @@ -1,20 +1,12 @@ #include #include #include "sp_vm_api.h" +#include "sp_vm_typeutil.h" using namespace SourcePawn; #define PI 3.14159265358979323846 -inline cell_t ftoc(float val) -{ - return *(cell_t *)&val; -} -inline float ctof(cell_t val) -{ - return *(float *)&val; -} - inline float AngleToRadians(float val, int mode) { switch (mode) diff --git a/core/smn_string.cpp b/core/smn_string.cpp index 627d1a90..b76c485f 100644 --- a/core/smn_string.cpp +++ b/core/smn_string.cpp @@ -1,7 +1,9 @@ #include "sm_platform.h" #include #include +#include #include "sp_vm_api.h" +#include "sp_vm_typeutil.h" using namespace SourcePawn; @@ -43,6 +45,18 @@ inline const char *_strstr(const char *str, const char *substr) #endif } +inline int StrConvInt(const char *str) +{ + char *dummy; + return strtol(str, &dummy, 10); +} + +inline float StrConvFloat(const char *str) +{ + char *dummy; + return (float)strtod(str, &dummy); +} + /********************************************* * * * STRING MANIPULATION NATIVE IMPLEMENTATIONS * @@ -109,3 +123,35 @@ static cell_t sm_strcopy(IPluginContext *pCtx, const cell_t *params) return (dest - start); } + +static cell_t sm_strtonum(IPluginContext *pCtx, const cell_t *params) +{ + char *str; + pCtx->LocalToString(params[1], &str); + + return StrConvInt(str); +} + +static cell_t sm_numtostr(IPluginContext *pCtx, const cell_t *params) +{ + char *str; + pCtx->LocalToString(params[2], &str); + + return snprintf(str, params[3], "%d", params[1]); +} + +static cell_t sm_strtofloat(IPluginContext *pCtx, const cell_t *params) +{ + char *str; + pCtx->LocalToString(params[1], &str); + + return ftoc(StrConvFloat(str)); +} + +static cell_t sm_floattostr(IPluginContext *pCtx, const cell_t *params) +{ + char *str; + pCtx->LocalToString(params[2], &str); + + return snprintf(str, params[3], "%f", ctof(params[1])); +} diff --git a/core/sourcemm_api.cpp b/core/sourcemm_api.cpp index 7c701977..1b593456 100644 --- a/core/sourcemm_api.cpp +++ b/core/sourcemm_api.cpp @@ -6,6 +6,7 @@ SourceMod_Core g_SourceMod_Core; IVEngineServer *engine = NULL; IServerGameDLL *gamedll = NULL; +IServerGameClients *serverClients = NULL; PLUGIN_EXPOSE(SourceMod, g_SourceMod_Core); @@ -15,11 +16,12 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen GET_V_IFACE_ANY(serverFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); + GET_V_IFACE_CURRENT(serverFactory, serverClients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS); return g_SourceMod.InitializeSourceMod(error, maxlen, late); } -bool SourceMod_Core::Unload(char *error, size_t maxlen) +bool SourceMod_Core::Unload(char *error, size_t maxlen) { return true; } diff --git a/core/sourcemm_api.h b/core/sourcemm_api.h index dff0a5a8..8dea8b0b 100644 --- a/core/sourcemm_api.h +++ b/core/sourcemm_api.h @@ -30,6 +30,7 @@ public: extern SourceMod_Core g_SourceMod_Core; extern IVEngineServer *engine; extern IServerGameDLL *gamedll; +extern IServerGameClients *serverClients; PLUGIN_GLOBALVARS(); diff --git a/core/systems/ForwardSys.cpp b/core/systems/ForwardSys.cpp index d0dd7b26..0a3bb6b1 100644 --- a/core/systems/ForwardSys.cpp +++ b/core/systems/ForwardSys.cpp @@ -28,6 +28,9 @@ CForwardManager g_Forwards; * X Push vararg strings (copyback tested = :TODO:) */ +// :TODO: IMPORTANT!!! The result pointer arg in the execute function maybe invalid if the forward fails +// so later evaluation of this result may cause problems on higher levels of abstraction. DOCUMENT OR FIX ALL FORWARDS! + void CForwardManager::OnSourceModAllInitialized() { g_PluginSys.AddPluginsListener(this); diff --git a/sourcepawn/include/sp_vm_typeutil.h b/sourcepawn/include/sp_vm_typeutil.h new file mode 100644 index 00000000..40987e4d --- /dev/null +++ b/sourcepawn/include/sp_vm_typeutil.h @@ -0,0 +1,15 @@ +#ifndef _INCLUDE_SOURCEPAWN_VM_TYPEUTIL_H_ +#define _INCLUDE_SOURCEPAWN_VM_TYPEUTIL_H_ + +#include "sp_vm_types.h" + +inline cell_t ftoc(float val) +{ + return *(cell_t *)&val; +} +inline float ctof(cell_t val) +{ + return *(float *)&val; +} + +#endif //_INCLUDE_SOURCEPAWN_VM_TYPEUTIL_H_ \ No newline at end of file