Move PlayerRunCmd to a global VTable Hook (bug 6051, r=psychonic).
This commit is contained in:
parent
8a7af5ba0d
commit
38bbb8580f
@ -116,36 +116,18 @@ void CHookManager::OnClientPutInServer(int client)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SH_ADD_MANUALHOOK(PlayerRunCmdHook, pEntity, SH_MEMBER(this, &CHookManager::PlayerRunCmd), false);
|
CVTableHook hook(pEntity);
|
||||||
}
|
for (size_t i = 0; i < m_runUserCmdHooks.length(); ++i)
|
||||||
|
|
||||||
void CHookManager::OnClientDisconnecting(int client)
|
|
||||||
{
|
|
||||||
if (!PRCH_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!PRCH_used)
|
|
||||||
return;
|
|
||||||
|
|
||||||
edict_t *pEdict = PEntityOfEntIndex(client);
|
|
||||||
if (!pEdict)
|
|
||||||
{
|
{
|
||||||
return;
|
if (hook == m_runUserCmdHooks[i])
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IServerUnknown *pUnknown = pEdict->GetUnknown();
|
int hookid = SH_ADD_MANUALVPHOOK(PlayerRunCmdHook, pEntity, SH_MEMBER(this, &CHookManager::PlayerRunCmd), false);
|
||||||
if (!pUnknown)
|
hook.SetHookID(hookid);
|
||||||
{
|
m_runUserCmdHooks.append(new CVTableHook(hook));
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CBaseEntity *pEntity = pUnknown->GetBaseEntity();
|
|
||||||
if (!pEntity)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SH_REMOVE_MANUALHOOK(PlayerRunCmdHook, pEntity, SH_MEMBER(this, &CHookManager::PlayerRunCmd), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHookManager::PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper)
|
void CHookManager::PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper)
|
||||||
@ -245,15 +227,12 @@ void CHookManager::OnPluginUnloaded(IPlugin *plugin)
|
|||||||
if (m_usercmdsFwd->GetFunctionCount())
|
if (m_usercmdsFwd->GetFunctionCount())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int MaxClients = playerhelpers->GetMaxClients();
|
for (size_t i = 0; i < m_runUserCmdHooks.length(); ++i)
|
||||||
for (int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
{
|
||||||
if (playerhelpers->GetGamePlayer(i)->IsInGame())
|
delete m_runUserCmdHooks[i];
|
||||||
{
|
|
||||||
OnClientDisconnecting(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_runUserCmdHooks.clear();
|
||||||
PRCH_used = false;
|
PRCH_used = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
class CUserCmd;
|
class CUserCmd;
|
||||||
|
|
||||||
#include "extension.h"
|
#include "extension.h"
|
||||||
|
#include "amtl/am-vector.h"
|
||||||
|
#include "vtable_hook_helper.h"
|
||||||
|
|
||||||
class CHookManager : IPluginsListener, IFeatureProvider
|
class CHookManager : IPluginsListener, IFeatureProvider
|
||||||
{
|
{
|
||||||
@ -43,7 +45,6 @@ public:
|
|||||||
void Initialize();
|
void Initialize();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void OnClientPutInServer(int client);
|
void OnClientPutInServer(int client);
|
||||||
void OnClientDisconnecting(int client);
|
|
||||||
void PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper);
|
void PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper);
|
||||||
public: //IPluginsListener
|
public: //IPluginsListener
|
||||||
void OnPluginLoaded(IPlugin *plugin);
|
void OnPluginLoaded(IPlugin *plugin);
|
||||||
@ -53,6 +54,7 @@ public: //IFeatureProvider
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
IForward *m_usercmdsFwd;
|
IForward *m_usercmdsFwd;
|
||||||
|
ke::Vector<CVTableHook *> m_runUserCmdHooks;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CHookManager g_Hooks;
|
extern CHookManager g_Hooks;
|
||||||
|
@ -173,8 +173,6 @@ bool SDKTools::OnSetClientListening(int iReceiver, int iSender, bool bListen)
|
|||||||
|
|
||||||
void SDKTools::OnClientDisconnecting(int client)
|
void SDKTools::OnClientDisconnecting(int client)
|
||||||
{
|
{
|
||||||
g_Hooks.OnClientDisconnecting(client);
|
|
||||||
|
|
||||||
int max_clients = playerhelpers->GetMaxClients();
|
int max_clients = playerhelpers->GetMaxClients();
|
||||||
|
|
||||||
if (g_VoiceHookCount == 0)
|
if (g_VoiceHookCount == 0)
|
||||||
|
104
public/vtable_hook_helper.h
Normal file
104
public/vtable_hook_helper.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* =============================================================================
|
||||||
|
* SourceMod
|
||||||
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||||
|
* Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||||
|
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||||
|
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||||
|
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||||
|
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||||
|
* this exception to all derivative works. AlliedModders LLC defines further
|
||||||
|
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||||
|
* or <http://www.sourcemod.net/license.php>.
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_VTABLE_HOOK_HELPER_H_
|
||||||
|
#define _INCLUDE_VTABLE_HOOK_HELPER_H_
|
||||||
|
|
||||||
|
class CVTableHook
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CVTableHook(void *takenclass)
|
||||||
|
{
|
||||||
|
this->vtableptr = *reinterpret_cast<void ***>(takenclass);
|
||||||
|
this->hookid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CVTableHook(void *vtable, int hook)
|
||||||
|
{
|
||||||
|
this->vtableptr = vtable;
|
||||||
|
this->hookid = hook;
|
||||||
|
}
|
||||||
|
|
||||||
|
CVTableHook(CVTableHook &other)
|
||||||
|
{
|
||||||
|
this->vtableptr = other.vtableptr;
|
||||||
|
this->hookid = other.hookid;
|
||||||
|
|
||||||
|
other.hookid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CVTableHook(CVTableHook *other)
|
||||||
|
{
|
||||||
|
this->vtableptr = other->vtableptr;
|
||||||
|
this->hookid = other->hookid;
|
||||||
|
|
||||||
|
other->hookid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~CVTableHook()
|
||||||
|
{
|
||||||
|
if (this->hookid)
|
||||||
|
{
|
||||||
|
SH_REMOVE_HOOK_ID(this->hookid);
|
||||||
|
this->hookid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
void *GetVTablePtr(void)
|
||||||
|
{
|
||||||
|
return this->vtableptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetHookID(int hook)
|
||||||
|
{
|
||||||
|
this->hookid = hook;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsHooked(void)
|
||||||
|
{
|
||||||
|
return (this->hookid != 0);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
bool operator == (CVTableHook &other)
|
||||||
|
{
|
||||||
|
return (this->GetVTablePtr() == other.GetVTablePtr());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator == (CVTableHook *other)
|
||||||
|
{
|
||||||
|
return (this->GetVTablePtr() == other->GetVTablePtr());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void *vtableptr;
|
||||||
|
int hookid;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_INCLUDE_VTABLE_HOOK_HELPER_H_
|
Loading…
Reference in New Issue
Block a user