Add FileTransfer Hooks to SDKTools (r=Drifter).
This commit is contained in:
parent
8777d0d0da
commit
274e7bd329
@ -44,6 +44,7 @@
|
|||||||
#include <ISDKTools.h>
|
#include <ISDKTools.h>
|
||||||
#include "clientnatives.h"
|
#include "clientnatives.h"
|
||||||
#include "teamnatives.h"
|
#include "teamnatives.h"
|
||||||
|
#include "filesystem.h"
|
||||||
/**
|
/**
|
||||||
* @file extension.cpp
|
* @file extension.cpp
|
||||||
* @brief Implements SDK Tools extension code.
|
* @brief Implements SDK Tools extension code.
|
||||||
@ -68,6 +69,7 @@ IVoiceServer *voiceserver = NULL;
|
|||||||
IPlayerInfoManager *playerinfomngr = NULL;
|
IPlayerInfoManager *playerinfomngr = NULL;
|
||||||
ICvar *icvar = NULL;
|
ICvar *icvar = NULL;
|
||||||
IServer *iserver = NULL;
|
IServer *iserver = NULL;
|
||||||
|
IBaseFileSystem *basefilesystem = NULL;
|
||||||
CGlobalVars *gpGlobals;
|
CGlobalVars *gpGlobals;
|
||||||
ISoundEmitterSystemBase *soundemitterbase = NULL;
|
ISoundEmitterSystemBase *soundemitterbase = NULL;
|
||||||
|
|
||||||
@ -258,6 +260,7 @@ bool SDKTools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool
|
|||||||
GET_V_IFACE_ANY(GetEngineFactory, voiceserver, IVoiceServer, INTERFACEVERSION_VOICESERVER);
|
GET_V_IFACE_ANY(GetEngineFactory, voiceserver, IVoiceServer, INTERFACEVERSION_VOICESERVER);
|
||||||
GET_V_IFACE_ANY(GetServerFactory, playerinfomngr, IPlayerInfoManager, INTERFACEVERSION_PLAYERINFOMANAGER);
|
GET_V_IFACE_ANY(GetServerFactory, playerinfomngr, IPlayerInfoManager, INTERFACEVERSION_PLAYERINFOMANAGER);
|
||||||
GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION);
|
GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION);
|
||||||
|
GET_V_IFACE_CURRENT(GetFileSystemFactory, basefilesystem, IBaseFileSystem, BASEFILESYSTEM_INTERFACE_VERSION);
|
||||||
|
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
GET_V_IFACE_ANY(GetServerFactory, servertools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION);
|
GET_V_IFACE_ANY(GetServerFactory, servertools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION);
|
||||||
@ -466,9 +469,10 @@ const char *SDKTools::GetExtensionDateString()
|
|||||||
return SOURCEMOD_BUILD_TIME;
|
return SOURCEMOD_BUILD_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDKTools::OnClientPutInServer(int client)
|
bool SDKTools::InterceptClientConnect(int client, char *error, size_t maxlength)
|
||||||
{
|
{
|
||||||
g_Hooks.OnClientPutInServer(client);
|
g_Hooks.OnClientConnect(client);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_CSGO
|
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_CSGO
|
||||||
@ -487,6 +491,11 @@ void SDKTools::OnSendClientCommand(edict_t *pPlayer, const char *szFormat)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void SDKTools::OnClientPutInServer(int client)
|
||||||
|
{
|
||||||
|
g_Hooks.OnClientPutInServer(client);
|
||||||
|
}
|
||||||
|
|
||||||
class SDKTools_API : public ISDKTools
|
class SDKTools_API : public ISDKTools
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -89,6 +89,7 @@ public:
|
|||||||
public: //IConCommandBaseAccessor
|
public: //IConCommandBaseAccessor
|
||||||
bool RegisterConCommandBase(ConCommandBase *pVar);
|
bool RegisterConCommandBase(ConCommandBase *pVar);
|
||||||
public: //IClientListner
|
public: //IClientListner
|
||||||
|
bool InterceptClientConnect(int client, char *error, size_t maxlength);
|
||||||
void OnClientPutInServer(int client);
|
void OnClientPutInServer(int client);
|
||||||
void OnClientDisconnecting(int client);
|
void OnClientDisconnecting(int client);
|
||||||
public: // IVoiceServer
|
public: // IVoiceServer
|
||||||
@ -129,6 +130,7 @@ extern IVoiceServer *voiceserver;
|
|||||||
extern IPlayerInfoManager *playerinfomngr;
|
extern IPlayerInfoManager *playerinfomngr;
|
||||||
extern ICvar *icvar;
|
extern ICvar *icvar;
|
||||||
extern IServer *iserver;
|
extern IServer *iserver;
|
||||||
|
extern IBaseFileSystem *basefilesystem;
|
||||||
extern CGlobalVars *gpGlobals;
|
extern CGlobalVars *gpGlobals;
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
extern IServerTools *servertools;
|
extern IServerTools *servertools;
|
||||||
|
@ -37,18 +37,32 @@
|
|||||||
#include "utlvector.h"
|
#include "utlvector.h"
|
||||||
#include <shareddefs.h>
|
#include <shareddefs.h>
|
||||||
#include "usercmd.h"
|
#include "usercmd.h"
|
||||||
|
#include "filesystem.h"
|
||||||
|
|
||||||
#define FEATURECAP_PLAYERRUNCMD_11PARAMS "SDKTools PlayerRunCmd 11Params"
|
#define FEATURECAP_PLAYERRUNCMD_11PARAMS "SDKTools PlayerRunCmd 11Params"
|
||||||
|
|
||||||
CHookManager g_Hooks;
|
CHookManager g_Hooks;
|
||||||
static bool PRCH_enabled = false;
|
static bool PRCH_enabled = false;
|
||||||
static bool PRCH_used = false;
|
static bool PRCH_used = false;
|
||||||
|
static bool FILE_used = false;
|
||||||
|
|
||||||
SH_DECL_MANUALHOOK2_void(PlayerRunCmdHook, 0, 0, 0, CUserCmd *, IMoveHelper *);
|
SH_DECL_MANUALHOOK2_void(PlayerRunCmdHook, 0, 0, 0, CUserCmd *, IMoveHelper *);
|
||||||
|
SH_DECL_HOOK2(IBaseFileSystem, FileExists, SH_NOATTRIB, 0, bool, const char*, const char *);
|
||||||
|
#if SOURCE_ENGINE >= SE_ALIENSWARM || SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2
|
||||||
|
SH_DECL_HOOK3(INetChannel, SendFile, SH_NOATTRIB, 0, bool, const char *, unsigned int, bool);
|
||||||
|
#else
|
||||||
|
SH_DECL_HOOK2(INetChannel, SendFile, SH_NOATTRIB, 0, bool, const char *, unsigned int);
|
||||||
|
#endif
|
||||||
|
SH_DECL_HOOK2_void(INetChannel, ProcessPacket, SH_NOATTRIB, 0, struct netpacket_s *, bool);
|
||||||
|
|
||||||
|
SourceHook::CallClass<IBaseFileSystem> *basefilesystemPatch = NULL;
|
||||||
|
|
||||||
CHookManager::CHookManager()
|
CHookManager::CHookManager()
|
||||||
{
|
{
|
||||||
m_usercmdsFwd = NULL;
|
m_usercmdsFwd = NULL;
|
||||||
|
m_netFileSendFwd = NULL;
|
||||||
|
m_netFileReceiveFwd = NULL;
|
||||||
|
m_pActiveNetChannel = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHookManager::Initialize()
|
void CHookManager::Initialize()
|
||||||
@ -65,6 +79,13 @@ void CHookManager::Initialize()
|
|||||||
PRCH_enabled = false;
|
PRCH_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SH_ADD_HOOK(IBaseFileSystem, FileExists, basefilesystem, SH_MEMBER(this, &CHookManager::FileExists), false);
|
||||||
|
|
||||||
|
basefilesystemPatch = SH_GET_CALLCLASS(basefilesystem);
|
||||||
|
|
||||||
|
m_netFileSendFwd = forwards->CreateForward("OnFileSend", ET_Event, 2, NULL, Param_Cell, Param_String);
|
||||||
|
m_netFileReceiveFwd = forwards->CreateForward("OnFileReceive", ET_Event, 2, NULL, Param_Cell, Param_String);
|
||||||
|
|
||||||
plsys->AddPluginsListener(this);
|
plsys->AddPluginsListener(this);
|
||||||
sharesys->AddCapabilityProvider(myself, this, FEATURECAP_PLAYERRUNCMD_11PARAMS);
|
sharesys->AddCapabilityProvider(myself, this, FEATURECAP_PLAYERRUNCMD_11PARAMS);
|
||||||
|
|
||||||
@ -85,16 +106,25 @@ void CHookManager::Initialize()
|
|||||||
void CHookManager::Shutdown()
|
void CHookManager::Shutdown()
|
||||||
{
|
{
|
||||||
forwards->ReleaseForward(m_usercmdsFwd);
|
forwards->ReleaseForward(m_usercmdsFwd);
|
||||||
|
forwards->ReleaseForward(m_netFileSendFwd);
|
||||||
|
forwards->ReleaseForward(m_netFileReceiveFwd);
|
||||||
|
|
||||||
plsys->RemovePluginsListener(this);
|
plsys->RemovePluginsListener(this);
|
||||||
sharesys->DropCapabilityProvider(myself, this, FEATURECAP_PLAYERRUNCMD_11PARAMS);
|
sharesys->DropCapabilityProvider(myself, this, FEATURECAP_PLAYERRUNCMD_11PARAMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHookManager::OnClientConnect(int client)
|
||||||
|
{
|
||||||
|
NetChannelHook(client);
|
||||||
|
}
|
||||||
|
|
||||||
void CHookManager::OnClientPutInServer(int client)
|
void CHookManager::OnClientPutInServer(int client)
|
||||||
{
|
{
|
||||||
if (!PRCH_enabled)
|
PlayerRunCmdHook(client);
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
void CHookManager::PlayerRunCmdHook(int client)
|
||||||
|
{
|
||||||
if (!PRCH_used)
|
if (!PRCH_used)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -193,17 +223,144 @@ void CHookManager::PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper)
|
|||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHookManager::NetChannelHook(int client)
|
||||||
|
{
|
||||||
|
if (!FILE_used)
|
||||||
|
return;
|
||||||
|
|
||||||
|
INetChannel *pNetChannel = static_cast<INetChannel *>(engine->GetPlayerNetInfo(client));
|
||||||
|
if (pNetChannel == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Normal NetChannel Hooks. */
|
||||||
|
{
|
||||||
|
CVTableHook hook(pNetChannel);
|
||||||
|
size_t iter;
|
||||||
|
for (iter = 0; iter < m_netChannelHooks.length(); ++iter)
|
||||||
|
{
|
||||||
|
/* We can technically skip 2; even technical-ier, this could be a bool; but Valve. */
|
||||||
|
if (hook == m_netChannelHooks[iter])
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter == m_netChannelHooks.length())
|
||||||
|
{
|
||||||
|
int hookid = SH_ADD_VPHOOK(INetChannel, SendFile, pNetChannel, SH_MEMBER(this, &CHookManager::SendFile), false);
|
||||||
|
hook.SetHookID(hookid);
|
||||||
|
m_netChannelHooks.append(new CVTableHook(hook));
|
||||||
|
|
||||||
|
hookid = SH_ADD_VPHOOK(INetChannel, ProcessPacket, pNetChannel, SH_MEMBER(this, &CHookManager::ProcessPacket), false);
|
||||||
|
hook.SetHookID(hookid);
|
||||||
|
m_netChannelHooks.append(new CVTableHook(hook));
|
||||||
|
|
||||||
|
hookid = SH_ADD_VPHOOK(INetChannel, ProcessPacket, pNetChannel, SH_MEMBER(this, &CHookManager::ProcessPacket_Post), true);
|
||||||
|
hook.SetHookID(hookid);
|
||||||
|
m_netChannelHooks.append(new CVTableHook(hook));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHookManager::ProcessPacket(struct netpacket_s *packet, bool bHasHeader)
|
||||||
|
{
|
||||||
|
if (m_netFileReceiveFwd->GetFunctionCount() == 0)
|
||||||
|
{
|
||||||
|
RETURN_META(MRES_IGNORED);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pActiveNetChannel = META_IFACEPTR(INetChannel);
|
||||||
|
RETURN_META(MRES_IGNORED);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CHookManager::FileExists(const char *filename, const char *pathID)
|
||||||
|
{
|
||||||
|
if (m_pActiveNetChannel == NULL || m_netFileReceiveFwd->GetFunctionCount() == 0)
|
||||||
|
{
|
||||||
|
RETURN_META_VALUE(MRES_IGNORED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = SH_CALL(basefilesystemPatch, &IBaseFileSystem::FileExists)(filename, pathID);
|
||||||
|
if (ret == true) /* If the File Exists, the engine historically bails out. */
|
||||||
|
{
|
||||||
|
RETURN_META_VALUE(MRES_IGNORED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int userid = 0;
|
||||||
|
IClient *pClient = (IClient *)m_pActiveNetChannel->GetMsgHandler();
|
||||||
|
if (pClient != NULL)
|
||||||
|
{
|
||||||
|
userid = pClient->GetUserID();
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t res = Pl_Continue;
|
||||||
|
m_netFileReceiveFwd->PushCell(playerhelpers->GetClientOfUserId(userid));
|
||||||
|
m_netFileReceiveFwd->PushString(filename);
|
||||||
|
m_netFileReceiveFwd->Execute(&res);
|
||||||
|
|
||||||
|
if (res != Pl_Continue)
|
||||||
|
{
|
||||||
|
RETURN_META_VALUE(MRES_SUPERCEDE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_META_VALUE(MRES_IGNORED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHookManager::ProcessPacket_Post(struct netpacket_s* packet, bool bHasHeader)
|
||||||
|
{
|
||||||
|
m_pActiveNetChannel = NULL;
|
||||||
|
RETURN_META(MRES_IGNORED);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE >= SE_ALIENSWARM || SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2
|
||||||
|
bool CHookManager::SendFile(const char *filename, unsigned int transferID, bool isReplayDemo)
|
||||||
|
#else
|
||||||
|
bool CHookManager::SendFile(const char *filename, unsigned int transferID)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (m_netFileSendFwd->GetFunctionCount() == 0)
|
||||||
|
{
|
||||||
|
RETURN_META_VALUE(MRES_IGNORED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
INetChannel *pNetChannel = META_IFACEPTR(INetChannel);
|
||||||
|
if (pNetChannel == NULL)
|
||||||
|
{
|
||||||
|
RETURN_META_VALUE(MRES_IGNORED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int userid = 0;
|
||||||
|
IClient *pClient = (IClient *)m_pActiveNetChannel->GetMsgHandler();
|
||||||
|
if (pClient != NULL)
|
||||||
|
{
|
||||||
|
userid = pClient->GetUserID();
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t res = Pl_Continue;
|
||||||
|
m_netFileSendFwd->PushCell(playerhelpers->GetClientOfUserId(userid));
|
||||||
|
m_netFileSendFwd->PushString(filename);
|
||||||
|
m_netFileSendFwd->Execute(&res);
|
||||||
|
|
||||||
|
if (res != Pl_Continue)
|
||||||
|
{
|
||||||
|
/* Mimic the Engine. */
|
||||||
|
#if SOURCE_ENGINE >= SE_ALIENSWARM || SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2
|
||||||
|
pNetChannel->DenyFile(filename, transferID, isReplayDemo);
|
||||||
|
#else
|
||||||
|
pNetChannel->DenyFile(filename, transferID);
|
||||||
|
#endif
|
||||||
|
RETURN_META_VALUE(MRES_SUPERCEDE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_META_VALUE(MRES_IGNORED, false);
|
||||||
|
}
|
||||||
|
|
||||||
void CHookManager::OnPluginLoaded(IPlugin *plugin)
|
void CHookManager::OnPluginLoaded(IPlugin *plugin)
|
||||||
{
|
{
|
||||||
if (!PRCH_enabled)
|
if (PRCH_enabled && !PRCH_used && m_usercmdsFwd->GetFunctionCount())
|
||||||
return;
|
{
|
||||||
|
|
||||||
if (PRCH_used)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_usercmdsFwd->GetFunctionCount())
|
|
||||||
return;
|
|
||||||
|
|
||||||
PRCH_used = true;
|
PRCH_used = true;
|
||||||
|
|
||||||
int MaxClients = playerhelpers->GetMaxClients();
|
int MaxClients = playerhelpers->GetMaxClients();
|
||||||
@ -216,17 +373,25 @@ void CHookManager::OnPluginLoaded(IPlugin *plugin)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!FILE_used && (m_netFileSendFwd->GetFunctionCount() || m_netFileReceiveFwd->GetFunctionCount()))
|
||||||
|
{
|
||||||
|
FILE_used = true;
|
||||||
|
|
||||||
|
int MaxClients = playerhelpers->GetMaxClients();
|
||||||
|
for (int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if (playerhelpers->GetGamePlayer(i)->IsConnected())
|
||||||
|
{
|
||||||
|
OnClientConnect(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CHookManager::OnPluginUnloaded(IPlugin *plugin)
|
void CHookManager::OnPluginUnloaded(IPlugin *plugin)
|
||||||
{
|
{
|
||||||
if (!PRCH_enabled)
|
if (PRCH_used && !m_usercmdsFwd->GetFunctionCount())
|
||||||
return;
|
{
|
||||||
|
|
||||||
if (!PRCH_used)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_usercmdsFwd->GetFunctionCount())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < m_runUserCmdHooks.length(); ++i)
|
for (size_t i = 0; i < m_runUserCmdHooks.length(); ++i)
|
||||||
{
|
{
|
||||||
delete m_runUserCmdHooks[i];
|
delete m_runUserCmdHooks[i];
|
||||||
@ -236,6 +401,18 @@ void CHookManager::OnPluginUnloaded(IPlugin *plugin)
|
|||||||
PRCH_used = false;
|
PRCH_used = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FILE_used && !m_netFileSendFwd->GetFunctionCount() && !m_netFileReceiveFwd->GetFunctionCount())
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < m_netChannelHooks.length(); ++i)
|
||||||
|
{
|
||||||
|
delete m_netChannelHooks[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_netChannelHooks.clear();
|
||||||
|
FILE_used = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FeatureStatus CHookManager::GetFeatureStatus(FeatureType type, const char *name)
|
FeatureStatus CHookManager::GetFeatureStatus(FeatureType type, const char *name)
|
||||||
{
|
{
|
||||||
return FeatureStatus_Available;
|
return FeatureStatus_Available;
|
||||||
|
@ -36,6 +36,8 @@ class CUserCmd;
|
|||||||
|
|
||||||
#include "extension.h"
|
#include "extension.h"
|
||||||
#include <am-vector.h>
|
#include <am-vector.h>
|
||||||
|
#include "inetchannel.h"
|
||||||
|
#include "iclient.h"
|
||||||
#include "vtable_hook_helper.h"
|
#include "vtable_hook_helper.h"
|
||||||
|
|
||||||
class CHookManager : IPluginsListener, IFeatureProvider
|
class CHookManager : IPluginsListener, IFeatureProvider
|
||||||
@ -44,17 +46,35 @@ public:
|
|||||||
CHookManager();
|
CHookManager();
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
void OnClientConnect(int client);
|
||||||
void OnClientPutInServer(int client);
|
void OnClientPutInServer(int client);
|
||||||
void PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper);
|
void PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper);
|
||||||
|
public: /* NetChannel/Related Hooks */
|
||||||
|
bool FileExists(const char *filename, const char *pathID);
|
||||||
|
#if SOURCE_ENGINE >= SE_ALIENSWARM || SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2
|
||||||
|
bool SendFile(const char *filename, unsigned int transferID, bool isReplayDemo);
|
||||||
|
#else
|
||||||
|
bool SendFile(const char *filename, unsigned int transferID);
|
||||||
|
#endif
|
||||||
|
void ProcessPacket(struct netpacket_s *packet, bool bHasHeader);
|
||||||
|
void ProcessPacket_Post(struct netpacket_s *packet, bool bHasHeader);
|
||||||
public: //IPluginsListener
|
public: //IPluginsListener
|
||||||
void OnPluginLoaded(IPlugin *plugin);
|
void OnPluginLoaded(IPlugin *plugin);
|
||||||
void OnPluginUnloaded(IPlugin *plugin);
|
void OnPluginUnloaded(IPlugin *plugin);
|
||||||
public: //IFeatureProvider
|
public: //IFeatureProvider
|
||||||
virtual FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
|
virtual FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void PlayerRunCmdHook(int client);
|
||||||
|
void NetChannelHook(int client);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IForward *m_usercmdsFwd;
|
IForward *m_usercmdsFwd;
|
||||||
|
IForward *m_netFileSendFwd;
|
||||||
|
IForward *m_netFileReceiveFwd;
|
||||||
ke::Vector<CVTableHook *> m_runUserCmdHooks;
|
ke::Vector<CVTableHook *> m_runUserCmdHooks;
|
||||||
|
ke::Vector<CVTableHook *> m_netChannelHooks;
|
||||||
|
INetChannel *m_pActiveNetChannel;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CHookManager g_Hooks;
|
extern CHookManager g_Hooks;
|
||||||
|
@ -57,3 +57,23 @@
|
|||||||
* FEATURECAP_PLAYERRUNCMD_11PARAMS.
|
* FEATURECAP_PLAYERRUNCMD_11PARAMS.
|
||||||
*/
|
*/
|
||||||
forward Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon, &subtype, &cmdnum, &tickcount, &seed, mouse[2]);
|
forward Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon, &subtype, &cmdnum, &tickcount, &seed, mouse[2]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a client requests a file from the server.
|
||||||
|
*
|
||||||
|
* @param client Client index.
|
||||||
|
* @param sFile Requested file path.
|
||||||
|
*
|
||||||
|
* @return Plugin_Handled to block the transfer, Plugin_Continue to let it proceed.
|
||||||
|
*/
|
||||||
|
forward Action:OnFileSend(client, const String:sFile[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a client sends a file to the server.
|
||||||
|
*
|
||||||
|
* @param client Client index.
|
||||||
|
* @param sFile Requested file path.
|
||||||
|
*
|
||||||
|
* @return Plugin_Handled to block the transfer, Plugin_Continue to let it proceed.
|
||||||
|
*/
|
||||||
|
forward Action:OnFileReceive(client, const String:sFile[]);
|
||||||
|
Loading…
Reference in New Issue
Block a user