Update s2 sample extension to khook

This commit is contained in:
Kenzzer 2025-08-15 01:05:19 +00:00
parent b1bc1b560f
commit 35642572a3
No known key found for this signature in database
GPG Key ID: 64C3FD4332686DC1
5 changed files with 83 additions and 64 deletions

View File

@ -106,7 +106,7 @@ class MMSPluginConfig(object):
self.sdk_manifests = [] self.sdk_manifests = []
self.sdks = {} self.sdks = {}
self.sdk_targets = [] self.sdk_targets = []
self.binaries = [] self.tasks = []
self.mms_root = mms_root self.mms_root = mms_root
self.version_header_deps = [] self.version_header_deps = []
self.versionlib_deps = dict() self.versionlib_deps = dict()
@ -166,10 +166,6 @@ class MMSPluginConfig(object):
self.sdk_manifests = SdkHelpers.sdk_manifests self.sdk_manifests = SdkHelpers.sdk_manifests
self.sdk_targets = SdkHelpers.sdk_targets self.sdk_targets = SdkHelpers.sdk_targets
for sdk_target in self.sdk_targets:
if not sdk_target.sdk['source2']:
raise Exception('Only Source2 games are supported by this script.')
def addVersioning(self, cxx): def addVersioning(self, cxx):
cxx.includes += [ cxx.includes += [
os.path.join(builder.buildPath, 'versioning') os.path.join(builder.buildPath, 'versioning')
@ -325,6 +321,9 @@ const char *PLUGIN_REVISION_COUNT = \"{revision_count}\";
'-Wno-uninitialized', '-Wno-uninitialized',
'-Wno-unused', '-Wno-unused',
'-Wno-switch', '-Wno-switch',
'-Wno-unknown-pragmas',
'-Wno-dangling-else',
'-Wno-non-pod-varargs',
'-msse', '-msse',
'-fPIC', '-fPIC',
] ]
@ -431,21 +430,16 @@ const char *PLUGIN_REVISION_COUNT = \"{revision_count}\";
elif cxx.target.platform == 'windows': elif cxx.target.platform == 'windows':
cxx.defines += ['WIN32', '_WINDOWS'] cxx.defines += ['WIN32', '_WINDOWS']
def Library(self, cxx, name): def HL2Library(self, context, compiler, project, sdk):
binary = cxx.Library(name) binary = project.Configure(compiler, '{0}.{1}'.format(project.name, sdk['extension']), '{0} {1}'.format(sdk['name'], compiler.target.arch))
return binary
def HL2Library(self, context, compiler, name, sdk):
binary = self.Library(compiler, name)
mms_core_path = os.path.join(self.mms_root, 'core')
cxx = binary.compiler cxx = binary.compiler
self.addVersioning(cxx) self.addVersioning(cxx)
cxx.cxxincludes += [ cxx.cxxincludes += [
os.path.join(context.currentSourcePath), os.path.join(context.currentSourcePath),
os.path.join(mms_core_path), os.path.join(self.mms_root, 'core'),
os.path.join(mms_core_path, 'sourcehook'), os.path.join(self.mms_root, 'third_party', 'khook', 'include')
] ]
for other_sdk in self.sdk_manifests: for other_sdk in self.sdk_manifests:

View File

@ -1,11 +1,13 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os import os
project = builder.LibraryProject(MMSPlugin.metadata["name"])
for sdk_target in MMSPlugin.sdk_targets: for sdk_target in MMSPlugin.sdk_targets:
sdk = sdk_target.sdk sdk = sdk_target.sdk
cxx = sdk_target.cxx cxx = sdk_target.cxx
binary = MMSPlugin.HL2Library(builder, cxx, f'{MMSPlugin.metadata["name"]}.{sdk["name"]}', sdk) binary = MMSPlugin.HL2Library(builder, cxx, project, sdk)
binary.sources += [ binary.sources += [
'src/plugin.cpp', 'src/plugin.cpp',
@ -15,5 +17,4 @@ for sdk_target in MMSPlugin.sdk_targets:
os.path.join(sdk['path'], 'common', 'network_connection.proto'), os.path.join(sdk['path'], 'common', 'network_connection.proto'),
])] ])]
nodes = builder.Add(binary) MMSPlugin.tasks += builder.Add(project)
MMSPlugin.binaries += [nodes]

View File

@ -94,7 +94,7 @@ for sdk_target in MMSPlugin.sdk_targets:
packages[sdk['name']] = SDKPackage(cxx, sdk['name']) packages[sdk['name']] = SDKPackage(cxx, sdk['name'])
pdb_list = [] pdb_list = []
for task in MMSPlugin.binaries: for task in MMSPlugin.tasks:
# Determine which sdk this binary belongs to since we encode it in its name # Determine which sdk this binary belongs to since we encode it in its name
binary_filename = os.path.splitext(os.path.basename(task.binary.path))[0] binary_filename = os.path.splitext(os.path.basename(task.binary.path))[0]
sdk_name = binary_filename.split('.')[-1] sdk_name = binary_filename.split('.')[-1]

View File

@ -16,17 +16,6 @@
#include "plugin.h" #include "plugin.h"
#include "iserver.h" #include "iserver.h"
SH_DECL_HOOK3_void(IServerGameDLL, GameFrame, SH_NOATTRIB, 0, bool, bool, bool);
SH_DECL_HOOK4_void(IServerGameClients, ClientActive, SH_NOATTRIB, 0, CPlayerSlot, bool, const char *, uint64);
SH_DECL_HOOK5_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, CPlayerSlot, ENetworkDisconnectionReason, const char *, uint64, const char *);
SH_DECL_HOOK4_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, CPlayerSlot, char const *, int, uint64);
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, CPlayerSlot );
SH_DECL_HOOK6_void(IServerGameClients, OnClientConnected, SH_NOATTRIB, 0, CPlayerSlot, const char*, uint64, const char *, const char *, bool);
SH_DECL_HOOK6(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, CPlayerSlot, const char*, uint64, const char *, bool, CBufferString *);
SH_DECL_HOOK2(IGameEventManager2, FireEvent, SH_NOATTRIB, 0, bool, IGameEvent *, bool);
SH_DECL_HOOK2_void( IServerGameClients, ClientCommand, SH_NOATTRIB, 0, CPlayerSlot, const CCommand & );
MMSPlugin g_ThisPlugin; MMSPlugin g_ThisPlugin;
IServerGameDLL *server = NULL; IServerGameDLL *server = NULL;
IServerGameClients *gameclients = NULL; IServerGameClients *gameclients = NULL;
@ -63,6 +52,18 @@ CON_COMMAND_F(sample_command, "Sample command", FCVAR_NONE)
META_CONPRINTF( "Sample command called by %d. Command: %s\n", context.GetPlayerSlot(), args.GetCommandString() ); META_CONPRINTF( "Sample command called by %d. Command: %s\n", context.GetPlayerSlot(), args.GetCommandString() );
} }
MMSPlugin::MMSPlugin() :
m_GameFrame(&IServerGameDLL::GameFrame, this, nullptr, &MMSPlugin::Hook_GameFrame),
m_ClientActive(&IServerGameClients::ClientActive, this, nullptr, &MMSPlugin::Hook_ClientActive),
m_ClientDisconnect(&IServerGameClients::ClientDisconnect, this, nullptr, &MMSPlugin::Hook_ClientDisconnect),
m_ClientPutInServer(&IServerGameClients::ClientPutInServer, this, nullptr, &MMSPlugin::Hook_ClientPutInServer),
m_ClientSettingsChanged(&IServerGameClients::ClientSettingsChanged, this, &MMSPlugin::Hook_ClientSettingsChanged, nullptr),
m_OnClientConnected(&IServerGameClients::OnClientConnected, this, &MMSPlugin::Hook_OnClientConnected, nullptr),
m_ClientConnect(&IServerGameClients::ClientConnect, this, &MMSPlugin::Hook_ClientConnect, nullptr),
m_ClientCommand(&IServerGameClients::ClientCommand, this, &MMSPlugin::Hook_ClientCommand, nullptr)
{
}
PLUGIN_EXPOSE(MMSPlugin, g_ThisPlugin); PLUGIN_EXPOSE(MMSPlugin, g_ThisPlugin);
bool MMSPlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) bool MMSPlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
{ {
@ -82,14 +83,14 @@ bool MMSPlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, boo
META_CONPRINTF( "Starting plugin.\n" ); META_CONPRINTF( "Starting plugin.\n" );
SH_ADD_HOOK(IServerGameDLL, GameFrame, server, SH_MEMBER(this, &MMSPlugin::Hook_GameFrame), true); m_GameFrame.Add(server);
SH_ADD_HOOK(IServerGameClients, ClientActive, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientActive), true); m_ClientActive.Add(gameclients);
SH_ADD_HOOK(IServerGameClients, ClientDisconnect, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientDisconnect), true); m_ClientDisconnect.Add(gameclients);
SH_ADD_HOOK(IServerGameClients, ClientPutInServer, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientPutInServer), true); m_ClientPutInServer.Add(gameclients);
SH_ADD_HOOK(IServerGameClients, ClientSettingsChanged, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientSettingsChanged), false); m_ClientSettingsChanged.Add(gameclients);
SH_ADD_HOOK(IServerGameClients, OnClientConnected, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_OnClientConnected), false); m_OnClientConnected.Add(gameclients);
SH_ADD_HOOK(IServerGameClients, ClientConnect, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientConnect), false); m_ClientConnect.Add(gameclients);
SH_ADD_HOOK(IServerGameClients, ClientCommand, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientCommand), false); m_ClientCommand.Add(gameclients);
META_CONPRINTF( "All hooks started!\n" ); META_CONPRINTF( "All hooks started!\n" );
@ -175,14 +176,14 @@ bool MMSPlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, boo
bool MMSPlugin::Unload(char *error, size_t maxlen) bool MMSPlugin::Unload(char *error, size_t maxlen)
{ {
SH_REMOVE_HOOK(IServerGameDLL, GameFrame, server, SH_MEMBER(this, &MMSPlugin::Hook_GameFrame), true); m_GameFrame.Remove(server);
SH_REMOVE_HOOK(IServerGameClients, ClientActive, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientActive), true); m_ClientActive.Remove(gameclients);
SH_REMOVE_HOOK(IServerGameClients, ClientDisconnect, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientDisconnect), true); m_ClientDisconnect.Remove(gameclients);
SH_REMOVE_HOOK(IServerGameClients, ClientPutInServer, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientPutInServer), true); m_ClientPutInServer.Remove(gameclients);
SH_REMOVE_HOOK(IServerGameClients, ClientSettingsChanged, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientSettingsChanged), false); m_ClientSettingsChanged.Remove(gameclients);
SH_REMOVE_HOOK(IServerGameClients, OnClientConnected, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_OnClientConnected), false); m_OnClientConnected.Remove(gameclients);
SH_REMOVE_HOOK(IServerGameClients, ClientConnect, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientConnect), false); m_ClientConnect.Remove(gameclients);
SH_REMOVE_HOOK(IServerGameClients, ClientCommand, gameclients, SH_MEMBER(this, &MMSPlugin::Hook_ClientCommand), false); m_ClientCommand.Remove(gameclients);
return true; return true;
} }
@ -194,44 +195,56 @@ void MMSPlugin::AllPluginsLoaded()
*/ */
} }
void MMSPlugin::Hook_ClientActive( CPlayerSlot slot, bool bLoadGame, const char *pszName, uint64 xuid ) KHook::Return<void> MMSPlugin::Hook_ClientActive( IServerGameClients*, CPlayerSlot slot, bool bLoadGame, const char *pszName, uint64 xuid )
{ {
META_CONPRINTF( "Hook_ClientActive(%d, %d, \"%s\", %d)\n", slot, bLoadGame, pszName, xuid ); META_CONPRINTF( "Hook_ClientActive(%d, %d, \"%s\", %d)\n", slot, bLoadGame, pszName, xuid );
return { KHook::Action::Ignore };
} }
void MMSPlugin::Hook_ClientCommand( CPlayerSlot slot, const CCommand &args ) KHook::Return<void> MMSPlugin::Hook_ClientCommand( IServerGameClients*, CPlayerSlot slot, const CCommand &args )
{ {
META_CONPRINTF( "Hook_ClientCommand(%d, \"%s\")\n", slot, args.GetCommandString() ); META_CONPRINTF( "Hook_ClientCommand(%d, \"%s\")\n", slot, args.GetCommandString() );
return { KHook::Action::Ignore };
} }
void MMSPlugin::Hook_ClientSettingsChanged( CPlayerSlot slot ) KHook::Return<void> MMSPlugin::Hook_ClientSettingsChanged( IServerGameClients*, CPlayerSlot slot )
{ {
META_CONPRINTF( "Hook_ClientSettingsChanged(%d)\n", slot ); META_CONPRINTF( "Hook_ClientSettingsChanged(%d)\n", slot );
return { KHook::Action::Ignore };
} }
void MMSPlugin::Hook_OnClientConnected( CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, const char *pszAddress, bool bFakePlayer ) KHook::Return<void> MMSPlugin::Hook_OnClientConnected( IServerGameClients*, CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, const char *pszAddress, bool bFakePlayer )
{ {
META_CONPRINTF( "Hook_OnClientConnected(%d, \"%s\", %d, \"%s\", \"%s\", %d)\n", slot, pszName, xuid, pszNetworkID, pszAddress, bFakePlayer ); META_CONPRINTF( "Hook_OnClientConnected(%d, \"%s\", %d, \"%s\", \"%s\", %d)\n", slot, pszName, xuid, pszNetworkID, pszAddress, bFakePlayer );
return { KHook::Action::Ignore };
} }
bool MMSPlugin::Hook_ClientConnect( CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, bool unk1, CBufferString *pRejectReason ) KHook::Return<bool> MMSPlugin::Hook_ClientConnect( IServerGameClients*, CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, bool unk1, CBufferString *pRejectReason )
{ {
META_CONPRINTF( "Hook_ClientConnect(%d, \"%s\", %d, \"%s\", %d, \"%s\")\n", slot, pszName, xuid, pszNetworkID, unk1, pRejectReason->Get() ); META_CONPRINTF( "Hook_ClientConnect(%d, \"%s\", %d, \"%s\", %d, \"%s\")\n", slot, pszName, xuid, pszNetworkID, unk1, pRejectReason->Get() );
RETURN_META_VALUE(MRES_IGNORED, true); return { KHook::Action::Ignore };
} }
void MMSPlugin::Hook_ClientPutInServer( CPlayerSlot slot, char const *pszName, int type, uint64 xuid ) KHook::Return<void> MMSPlugin::Hook_ClientPutInServer( IServerGameClients*, CPlayerSlot slot, char const *pszName, int type, uint64 xuid )
{ {
META_CONPRINTF( "Hook_ClientPutInServer(%d, \"%s\", %d, %d)\n", slot, pszName, type, xuid ); META_CONPRINTF( "Hook_ClientPutInServer(%d, \"%s\", %d, %d)\n", slot, pszName, type, xuid );
return { KHook::Action::Ignore };
} }
void MMSPlugin::Hook_ClientDisconnect( CPlayerSlot slot, ENetworkDisconnectionReason reason, const char *pszName, uint64 xuid, const char *pszNetworkID ) KHook::Return<void> MMSPlugin::Hook_ClientDisconnect( IServerGameClients*, CPlayerSlot slot, ENetworkDisconnectionReason reason, const char *pszName, uint64 xuid, const char *pszNetworkID )
{ {
META_CONPRINTF( "Hook_ClientDisconnect(%d, %d, \"%s\", %d, \"%s\")\n", slot, reason, pszName, xuid, pszNetworkID ); META_CONPRINTF( "Hook_ClientDisconnect(%d, %d, \"%s\", %d, \"%s\")\n", slot, reason, pszName, xuid, pszNetworkID );
return { KHook::Action::Ignore };
} }
void MMSPlugin::Hook_GameFrame( bool simulating, bool bFirstTick, bool bLastTick ) KHook::Return<void> MMSPlugin::Hook_GameFrame( IServerGameDLL*, bool simulating, bool bFirstTick, bool bLastTick )
{ {
/** /**
* simulating: * simulating:
@ -239,6 +252,7 @@ void MMSPlugin::Hook_GameFrame( bool simulating, bool bFirstTick, bool bLastTick
* true | game is ticking * true | game is ticking
* false | game is not ticking * false | game is not ticking
*/ */
return { KHook::Action::Ignore };
} }
void MMSPlugin::OnLevelInit( char const *pMapName, void MMSPlugin::OnLevelInit( char const *pMapName,

View File

@ -17,13 +17,14 @@
#include <ISmmPlugin.h> #include <ISmmPlugin.h>
#include <igameevents.h> #include <igameevents.h>
#include <sh_vector.h>
#include "version_gen.h" #include "version_gen.h"
class MMSPlugin : public ISmmPlugin, public IMetamodListener class MMSPlugin : public ISmmPlugin, public IMetamodListener
{ {
public: public:
MMSPlugin();
bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late); bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late);
bool Unload(char *error, size_t maxlen); bool Unload(char *error, size_t maxlen);
void AllPluginsLoaded(); void AllPluginsLoaded();
@ -35,14 +36,14 @@ public: //hooks
bool loadGame, bool loadGame,
bool background ); bool background );
void OnLevelShutdown(); void OnLevelShutdown();
void Hook_GameFrame( bool simulating, bool bFirstTick, bool bLastTick ); KHook::Return<void> Hook_GameFrame(IServerGameDLL*, bool simulating, bool bFirstTick, bool bLastTick );
void Hook_ClientActive( CPlayerSlot slot, bool bLoadGame, const char *pszName, uint64 xuid ); KHook::Return<void> Hook_ClientActive(IServerGameClients*, CPlayerSlot slot, bool bLoadGame, const char *pszName, uint64 xuid );
void Hook_ClientDisconnect( CPlayerSlot slot, ENetworkDisconnectionReason reason, const char *pszName, uint64 xuid, const char *pszNetworkID ); KHook::Return<void> Hook_ClientDisconnect(IServerGameClients*, CPlayerSlot slot, ENetworkDisconnectionReason reason, const char *pszName, uint64 xuid, const char *pszNetworkID );
void Hook_ClientPutInServer( CPlayerSlot slot, char const *pszName, int type, uint64 xuid ); KHook::Return<void> Hook_ClientPutInServer(IServerGameClients*, CPlayerSlot slot, char const *pszName, int type, uint64 xuid );
void Hook_ClientSettingsChanged( CPlayerSlot slot ); KHook::Return<void> Hook_ClientSettingsChanged(IServerGameClients*, CPlayerSlot slot );
void Hook_OnClientConnected( CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, const char *pszAddress, bool bFakePlayer ); KHook::Return<void> Hook_OnClientConnected(IServerGameClients*, CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, const char *pszAddress, bool bFakePlayer );
bool Hook_ClientConnect( CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, bool unk1, CBufferString *pRejectReason ); KHook::Return<bool> Hook_ClientConnect(IServerGameClients*, CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, bool unk1, CBufferString *pRejectReason );
void Hook_ClientCommand( CPlayerSlot nSlot, const CCommand &_cmd ); KHook::Return<void> Hook_ClientCommand(IServerGameClients*, CPlayerSlot nSlot, const CCommand &_cmd );
public: public:
const char *GetAuthor() { return PLUGIN_AUTHOR; } const char *GetAuthor() { return PLUGIN_AUTHOR; }
const char *GetName() { return PLUGIN_DISPLAY_NAME; } const char *GetName() { return PLUGIN_DISPLAY_NAME; }
@ -52,6 +53,15 @@ public:
const char *GetVersion() { return PLUGIN_FULL_VERSION; } const char *GetVersion() { return PLUGIN_FULL_VERSION; }
const char *GetDate() { return __DATE__; } const char *GetDate() { return __DATE__; }
const char *GetLogTag() { return PLUGIN_LOGTAG; } const char *GetLogTag() { return PLUGIN_LOGTAG; }
protected:
KHook::Virtual<IServerGameDLL, void, bool, bool, bool> m_GameFrame;
KHook::Virtual<IServerGameClients, void, CPlayerSlot, bool, const char *, uint64> m_ClientActive;
KHook::Virtual<IServerGameClients, void, CPlayerSlot, ENetworkDisconnectionReason, const char *, uint64, const char *> m_ClientDisconnect;
KHook::Virtual<IServerGameClients, void, CPlayerSlot, char const *, int, uint64> m_ClientPutInServer;
KHook::Virtual<IServerGameClients, void, CPlayerSlot> m_ClientSettingsChanged;
KHook::Virtual<IServerGameClients, void, CPlayerSlot, const char*, uint64, const char *, const char *, bool> m_OnClientConnected;
KHook::Virtual<IServerGameClients, bool, CPlayerSlot, const char*, uint64, const char *, bool, CBufferString *> m_ClientConnect;
KHook::Virtual<IServerGameClients, void, CPlayerSlot, const CCommand &> m_ClientCommand;
}; };
extern MMSPlugin g_ThisPlugin; extern MMSPlugin g_ThisPlugin;