Move PlayerRunCmd to a global VTable Hook (bug 6051, r=psychonic).
Move PlayerRunCmd to a global VTable Hook (
bug 6051, r=psychonic).
1.1 --- a/extensions/sdktools/hooks.cpp Sat Mar 01 11:00:52 2014 -0500
1.2 +++ b/extensions/sdktools/hooks.cpp Sat Mar 01 14:25:35 2014 -0700
1.3 @@ -116,36 +116,18 @@
1.4 return;
1.5 }
1.6
1.7 - SH_ADD_MANUALHOOK(PlayerRunCmdHook, pEntity, SH_MEMBER(this, &CHookManager::PlayerRunCmd), false);
1.8 -}
1.9 -
1.10 -void CHookManager::OnClientDisconnecting(int client)
1.11 -{
1.12 - if (!PRCH_enabled)
1.13 - return;
1.14 -
1.15 - if (!PRCH_used)
1.16 - return;
1.17 -
1.18 - edict_t *pEdict = PEntityOfEntIndex(client);
1.19 - if (!pEdict)
1.20 + CVTableHook hook(pEntity);
1.21 + for (size_t i = 0; i < m_runUserCmdHooks.length(); ++i)
1.22 {
1.23 - return;
1.24 + if (hook == m_runUserCmdHooks[i])
1.25 + {
1.26 + return;
1.27 + }
1.28 }
1.29
1.30 - IServerUnknown *pUnknown = pEdict->GetUnknown();
1.31 - if (!pUnknown)
1.32 - {
1.33 - return;
1.34 - }
1.35 -
1.36 - CBaseEntity *pEntity = pUnknown->GetBaseEntity();
1.37 - if (!pEntity)
1.38 - {
1.39 - return;
1.40 - }
1.41 -
1.42 - SH_REMOVE_MANUALHOOK(PlayerRunCmdHook, pEntity, SH_MEMBER(this, &CHookManager::PlayerRunCmd), false);
1.43 + int hookid = SH_ADD_MANUALVPHOOK(PlayerRunCmdHook, pEntity, SH_MEMBER(this, &CHookManager::PlayerRunCmd), false);
1.44 + hook.SetHookID(hookid);
1.45 + m_runUserCmdHooks.append(new CVTableHook(hook));
1.46 }
1.47
1.48 void CHookManager::PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper)
1.49 @@ -245,15 +227,12 @@
1.50 if (m_usercmdsFwd->GetFunctionCount())
1.51 return;
1.52
1.53 - int MaxClients = playerhelpers->GetMaxClients();
1.54 - for (int i = 1; i <= MaxClients; i++)
1.55 + for (size_t i = 0; i < m_runUserCmdHooks.length(); ++i)
1.56 {
1.57 - if (playerhelpers->GetGamePlayer(i)->IsInGame())
1.58 - {
1.59 - OnClientDisconnecting(i);
1.60 - }
1.61 + delete m_runUserCmdHooks[i];
1.62 }
1.63
1.64 + m_runUserCmdHooks.clear();
1.65 PRCH_used = false;
1.66 }
1.67
2.1 --- a/extensions/sdktools/hooks.h Sat Mar 01 11:00:52 2014 -0500
2.2 +++ b/extensions/sdktools/hooks.h Sat Mar 01 14:25:35 2014 -0700
2.3 @@ -35,6 +35,8 @@
2.4 class CUserCmd;
2.5
2.6 #include "extension.h"
2.7 +#include "amtl/am-vector.h"
2.8 +#include "vtable_hook_helper.h"
2.9
2.10 class CHookManager : IPluginsListener, IFeatureProvider
2.11 {
2.12 @@ -43,7 +45,6 @@
2.13 void Initialize();
2.14 void Shutdown();
2.15 void OnClientPutInServer(int client);
2.16 - void OnClientDisconnecting(int client);
2.17 void PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper);
2.18 public: //IPluginsListener
2.19 void OnPluginLoaded(IPlugin *plugin);
2.20 @@ -53,6 +54,7 @@
2.21
2.22 private:
2.23 IForward *m_usercmdsFwd;
2.24 + ke::Vector<CVTableHook *> m_runUserCmdHooks;
2.25 };
2.26
2.27 extern CHookManager g_Hooks;
3.1 --- a/extensions/sdktools/voice.cpp Sat Mar 01 11:00:52 2014 -0500
3.2 +++ b/extensions/sdktools/voice.cpp Sat Mar 01 14:25:35 2014 -0700
3.3 @@ -173,8 +173,6 @@
3.4
3.5 void SDKTools::OnClientDisconnecting(int client)
3.6 {
3.7 - g_Hooks.OnClientDisconnecting(client);
3.8 -
3.9 int max_clients = playerhelpers->GetMaxClients();
3.10
3.11 if (g_VoiceHookCount == 0)
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/public/vtable_hook_helper.h Sat Mar 01 14:25:35 2014 -0700
4.3 @@ -0,0 +1,104 @@
4.4 +/**
4.5 + * vim: set ts=4 :
4.6 + * =============================================================================
4.7 + * SourceMod
4.8 + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
4.9 + * =============================================================================
4.10 + *
4.11 + * This program is free software; you can redistribute it and/or modify it under
4.12 + * the terms of the GNU General Public License, version 3.0, as published by the
4.13 + * Free Software Foundation.
4.14 + *
4.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
4.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
4.18 + * details.
4.19 + *
4.20 + * You should have received a copy of the GNU General Public License along with
4.21 + * this program. If not, see <http://www.gnu.org/licenses/>.
4.22 + *
4.23 + * As a special exception, AlliedModders LLC gives you permission to link the
4.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
4.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
4.26 + * by the Valve Corporation. You must obey the GNU General Public License in
4.27 + * all respects for all other code used. Additionally, AlliedModders LLC grants
4.28 + * this exception to all derivative works. AlliedModders LLC defines further
4.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
4.30 + * or <http://www.sourcemod.net/license.php>.
4.31 + *
4.32 + * Version: $Id$
4.33 + */
4.34 +
4.35 +#ifndef _INCLUDE_VTABLE_HOOK_HELPER_H_
4.36 +#define _INCLUDE_VTABLE_HOOK_HELPER_H_
4.37 +
4.38 +class CVTableHook
4.39 +{
4.40 +public:
4.41 + CVTableHook(void *takenclass)
4.42 + {
4.43 + this->vtableptr = *reinterpret_cast<void ***>(takenclass);
4.44 + this->hookid = 0;
4.45 + }
4.46 +
4.47 + CVTableHook(void *vtable, int hook)
4.48 + {
4.49 + this->vtableptr = vtable;
4.50 + this->hookid = hook;
4.51 + }
4.52 +
4.53 + CVTableHook(CVTableHook &other)
4.54 + {
4.55 + this->vtableptr = other.vtableptr;
4.56 + this->hookid = other.hookid;
4.57 +
4.58 + other.hookid = 0;
4.59 + }
4.60 +
4.61 + CVTableHook(CVTableHook *other)
4.62 + {
4.63 + this->vtableptr = other->vtableptr;
4.64 + this->hookid = other->hookid;
4.65 +
4.66 + other->hookid = 0;
4.67 + }
4.68 +
4.69 + ~CVTableHook()
4.70 + {
4.71 + if (this->hookid)
4.72 + {
4.73 + SH_REMOVE_HOOK_ID(this->hookid);
4.74 + this->hookid = 0;
4.75 + }
4.76 + }
4.77 +public:
4.78 + void *GetVTablePtr(void)
4.79 + {
4.80 + return this->vtableptr;
4.81 + }
4.82 +
4.83 + void SetHookID(int hook)
4.84 + {
4.85 + this->hookid = hook;
4.86 + }
4.87 +
4.88 + bool IsHooked(void)
4.89 + {
4.90 + return (this->hookid != 0);
4.91 + }
4.92 +public:
4.93 + bool operator == (CVTableHook &other)
4.94 + {
4.95 + return (this->GetVTablePtr() == other.GetVTablePtr());
4.96 + }
4.97 +
4.98 + bool operator == (CVTableHook *other)
4.99 + {
4.100 + return (this->GetVTablePtr() == other->GetVTablePtr());
4.101 + }
4.102 +private:
4.103 + void *vtableptr;
4.104 + int hookid;
4.105 +};
4.106 +
4.107 +#endif //_INCLUDE_VTABLE_HOOK_HELPER_H_