Add OnPlayerRunCmdPost forward ()

* Add OnPlayerRunCmdPost forward

Allow plugins to catch the values that are actually used by the game
after some eventual changes by other plugins.

* Add |const| qualifier to arrays in OnPlayerRunCmdPost forward
This commit is contained in:
peace-maker 2017-05-09 08:16:05 -06:00 committed by Asher Baker
parent ed42d2feea
commit 1351df4260
3 changed files with 126 additions and 17 deletions
extensions/sdktools
plugins/include

View File

@ -44,6 +44,7 @@
CHookManager g_Hooks;
static bool PRCH_enabled = false;
static bool PRCH_used = false;
static bool PRCHPost_used = false;
static bool FILE_used = false;
SH_DECL_MANUALHOOK2_void(PlayerRunCmdHook, 0, 0, 0, CUserCmd *, IMoveHelper *);
@ -60,6 +61,7 @@ SourceHook::CallClass<IBaseFileSystem> *basefilesystemPatch = NULL;
CHookManager::CHookManager()
{
m_usercmdsFwd = NULL;
m_usercmdsPostFwd = NULL;
m_netFileSendFwd = NULL;
m_netFileReceiveFwd = NULL;
m_pActiveNetChannel = NULL;
@ -99,11 +101,25 @@ void CHookManager::Initialize()
Param_CellByRef, // tickcount
Param_CellByRef, // seed
Param_Array); // mouse[2]
m_usercmdsPostFwd = forwards->CreateForward("OnPlayerRunCmdPost", ET_Ignore, 11, NULL,
Param_Cell, // client
Param_Cell, // buttons
Param_Cell, // impulse
Param_Array, // Float:vel[3]
Param_Array, // Float:angles[3]
Param_Cell, // weapon
Param_Cell, // subtype
Param_Cell, // cmdnum
Param_Cell, // tickcount
Param_Cell, // seed
Param_Array); // mouse[2]
}
void CHookManager::Shutdown()
{
forwards->ReleaseForward(m_usercmdsFwd);
forwards->ReleaseForward(m_usercmdsPostFwd);
forwards->ReleaseForward(m_netFileSendFwd);
forwards->ReleaseForward(m_netFileReceiveFwd);
@ -127,14 +143,14 @@ void CHookManager::OnClientConnect(int client)
void CHookManager::OnClientPutInServer(int client)
{
PlayerRunCmdHook(client);
if (PRCH_used)
PlayerRunCmdHook(client, false);
if (PRCHPost_used)
PlayerRunCmdHook(client, true);
}
void CHookManager::PlayerRunCmdHook(int client)
void CHookManager::PlayerRunCmdHook(int client, bool post)
{
if (!PRCH_used)
return;
edict_t *pEdict = PEntityOfEntIndex(client);
if (!pEdict)
{
@ -153,18 +169,24 @@ void CHookManager::PlayerRunCmdHook(int client)
return;
}
ke::Vector<CVTableHook *> &runUserCmdHookVec = post ? m_runUserCmdPostHooks : m_runUserCmdHooks;
CVTableHook hook(pEntity);
for (size_t i = 0; i < m_runUserCmdHooks.length(); ++i)
for (size_t i = 0; i < runUserCmdHookVec.length(); ++i)
{
if (hook == m_runUserCmdHooks[i])
if (hook == runUserCmdHookVec[i])
{
return;
}
}
int hookid = SH_ADD_MANUALVPHOOK(PlayerRunCmdHook, pEntity, SH_MEMBER(this, &CHookManager::PlayerRunCmd), false);
int hookid;
if (post)
hookid = SH_ADD_MANUALVPHOOK(PlayerRunCmdHook, pEntity, SH_MEMBER(this, &CHookManager::PlayerRunCmdPost), true);
else
hookid = SH_ADD_MANUALVPHOOK(PlayerRunCmdHook, pEntity, SH_MEMBER(this, &CHookManager::PlayerRunCmd), false);
hook.SetHookID(hookid);
m_runUserCmdHooks.append(new CVTableHook(hook));
runUserCmdHookVec.append(new CVTableHook(hook));
}
void CHookManager::PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper)
@ -230,6 +252,48 @@ void CHookManager::PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper)
RETURN_META(MRES_IGNORED);
}
void CHookManager::PlayerRunCmdPost(CUserCmd *ucmd, IMoveHelper *moveHelper)
{
if (m_usercmdsPostFwd->GetFunctionCount() == 0)
{
RETURN_META(MRES_IGNORED);
}
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
if (!pEntity)
{
RETURN_META(MRES_IGNORED);
}
edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
if (!pEdict)
{
RETURN_META(MRES_IGNORED);
}
int client = IndexOfEdict(pEdict);
cell_t vel[3] = { sp_ftoc(ucmd->forwardmove), sp_ftoc(ucmd->sidemove), sp_ftoc(ucmd->upmove) };
cell_t angles[3] = { sp_ftoc(ucmd->viewangles.x), sp_ftoc(ucmd->viewangles.y), sp_ftoc(ucmd->viewangles.z) };
cell_t mouse[2] = { ucmd->mousedx, ucmd->mousedy };
m_usercmdsPostFwd->PushCell(client);
m_usercmdsPostFwd->PushCell(ucmd->buttons);
m_usercmdsPostFwd->PushCell(ucmd->impulse);
m_usercmdsPostFwd->PushArray(vel, 3);
m_usercmdsPostFwd->PushArray(angles, 3);
m_usercmdsPostFwd->PushCell(ucmd->weaponselect);
m_usercmdsPostFwd->PushCell(ucmd->weaponsubtype);
m_usercmdsPostFwd->PushCell(ucmd->command_number);
m_usercmdsPostFwd->PushCell(ucmd->tick_count);
m_usercmdsPostFwd->PushCell(ucmd->random_seed);
m_usercmdsPostFwd->PushArray(mouse, 2);
m_usercmdsPostFwd->Execute();
RETURN_META(MRES_IGNORED);
}
void CHookManager::NetChannelHook(int client)
{
if (!FILE_used)
@ -387,16 +451,30 @@ bool CHookManager::SendFile(const char *filename, unsigned int transferID)
void CHookManager::OnPluginLoaded(IPlugin *plugin)
{
if (PRCH_enabled && !PRCH_used && m_usercmdsFwd->GetFunctionCount())
if (PRCH_enabled)
{
PRCH_used = true;
int MaxClients = playerhelpers->GetMaxClients();
for (int i = 1; i <= MaxClients; i++)
bool changed = false;
if (!PRCH_used && (m_usercmdsFwd->GetFunctionCount() > 0))
{
if (playerhelpers->GetGamePlayer(i)->IsInGame())
PRCH_used = true;
changed = true;
}
if (!PRCHPost_used && (m_usercmdsPostFwd->GetFunctionCount() > 0))
{
PRCHPost_used = true;
changed = true;
}
// Only check the hooks on the players if a new hook is used by this plugin.
if (changed)
{
int MaxClients = playerhelpers->GetMaxClients();
for (int i = 1; i <= MaxClients; i++)
{
OnClientPutInServer(i);
if (playerhelpers->GetGamePlayer(i)->IsInGame())
{
OnClientPutInServer(i);
}
}
}
}
@ -429,6 +507,17 @@ void CHookManager::OnPluginUnloaded(IPlugin *plugin)
PRCH_used = false;
}
if (PRCHPost_used && !m_usercmdsPostFwd->GetFunctionCount())
{
for (size_t i = 0; i < m_runUserCmdPostHooks.length(); ++i)
{
delete m_runUserCmdPostHooks[i];
}
m_runUserCmdPostHooks.clear();
PRCHPost_used = false;
}
if (FILE_used && !m_netFileSendFwd->GetFunctionCount() && !m_netFileReceiveFwd->GetFunctionCount())
{
for (size_t i = 0; i < m_netChannelHooks.length(); ++i)

View File

@ -49,6 +49,7 @@ public:
void OnClientConnect(int client);
void OnClientPutInServer(int client);
void PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper);
void PlayerRunCmdPost(CUserCmd *ucmd, IMoveHelper *moveHelper);
void OnMapStart();
public: /* NetChannel/Related Hooks */
bool FileExists(const char *filename, const char *pathID);
@ -66,14 +67,16 @@ public: //IFeatureProvider
virtual FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
private:
void PlayerRunCmdHook(int client);
void PlayerRunCmdHook(int client, bool post);
void NetChannelHook(int client);
private:
IForward *m_usercmdsFwd;
IForward *m_usercmdsPostFwd;
IForward *m_netFileSendFwd;
IForward *m_netFileReceiveFwd;
ke::Vector<CVTableHook *> m_runUserCmdHooks;
ke::Vector<CVTableHook *> m_runUserCmdPostHooks;
ke::Vector<CVTableHook *> m_netChannelHooks;
INetChannel *m_pActiveNetChannel;
bool m_bFSTranHookWarned = false;

View File

@ -58,6 +58,23 @@
*/
forward Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2]);
/**
* @brief Called after a clients movement buttons were processed.
*
* @param client Index of the client.
* @param buttons The current commands (as bitflags - see entity_prop_stocks.inc).
* @param impulse The current impulse command.
* @param vel Players desired velocity.
* @param angles Players desired view angles.
* @param weapon Entity index of the new weapon if player switches weapon, 0 otherwise.
* @param subtype Weapon subtype when selected from a menu.
* @param cmdnum Command number. Increments from the first command sent.
* @param tickcount Tick count. A client's prediction based on the server's GetGameTickCount value.
* @param seed Random seed. Used to determine weapon recoil, spread, and other predicted elements.
* @param mouse Mouse direction (x, y).
*/
forward void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2]);
/**
* @brief Called when a client requests a file from the server.
*