Move PlayerRunCmd to a global VTable Hook (bug 6051, r=psychonic).
authorKyle Sanderson <kyle.leet@gmail.com>
Sat Mar 01 14:25:35 2014 -0700 (2014-03-01)
changeset 42683c383c5b1aaa
parent 4267 a0821295a515
child 4269 c7562e57750b
Move PlayerRunCmd to a global VTable Hook (bug 6051, r=psychonic).
extensions/sdktools/hooks.cpp
extensions/sdktools/hooks.h
extensions/sdktools/voice.cpp
public/vtable_hook_helper.h
     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_