From 817b5f940eef4b76b865bd740af5276a8d1ff2f7 Mon Sep 17 00:00:00 2001 From: Nick Hastings Date: Sun, 21 May 2023 12:13:17 -0400 Subject: [PATCH] Iterate on ConCommands, ClientCommands, and the split S1/S2 compat --- core/ISmmAPI.h | 10 +++- core/metamod.cpp | 4 +- core/metamod.h | 62 +++++++++++----------- core/metamod_console.cpp | 10 ++-- core/metamod_console.h | 2 +- core/metamod_provider.h | 6 +-- core/provider/provider_base.h | 2 +- core/provider/source/provider_source.cpp | 2 +- core/provider/source/provider_source.h | 2 +- core/provider/source2/provider_source2.cpp | 25 ++++----- core/provider/source2/provider_source2.h | 6 +-- 11 files changed, 66 insertions(+), 65 deletions(-) diff --git a/core/ISmmAPI.h b/core/ISmmAPI.h index 6676e34..50dc701 100644 --- a/core/ISmmAPI.h +++ b/core/ISmmAPI.h @@ -53,6 +53,14 @@ class ConCommandBase; #define MMIFACE_SH_HOOKMANAUTOGEN "IHookManagerAutoGen" /**< SourceHook::IHookManagerAutoGen Pointer */ #define IFACE_MAXNUM 999 /**< Maximum interface version */ +#if defined META_IS_SOURCE2 +typedef CPlayerSlot MMSPlayer_t; +static const MMSPlayer_t MMSPlayer_INVALID = CPlayerSlot(-1); +#else +typedef edict_t* MMSPlayer_t; +static const MMSPlayer_t MMSPlayer_INVALID = nullptr; +#endif + typedef void* (*CreateInterfaceFn)(const char *pName, int *pReturnCode); class IServerPluginCallbacks; @@ -255,7 +263,7 @@ namespace SourceMM * @param client Client edict pointer. * @param fmt Formatted string to print to the client. */ - virtual void ClientConPrintf(edict_t *client, const char *fmt, ...) =0; + virtual void ClientConPrintf(MMSPlayer_t client, const char *fmt, ...) =0; /** * @brief Wrapper around InterfaceSearch(). Assumes no maximum. diff --git a/core/metamod.cpp b/core/metamod.cpp index a1a2dc3..d57bab3 100644 --- a/core/metamod.cpp +++ b/core/metamod.cpp @@ -200,7 +200,7 @@ static class ProviderCallbacks : public IMetamodSourceProviderCallbacks return Command_Meta(info); } - virtual bool OnCommand_ClientMeta(edict_t* client, IMetamodSourceCommandInfo* info) override + virtual bool OnCommand_ClientMeta(MMSPlayer_t client, IMetamodSourceCommandInfo* info) override { return Command_ClientMeta(client, info); } @@ -750,7 +750,7 @@ size_t MetamodSource::PathFormat(char *buffer, size_t len, const char *fmt, ...) return mylen; } -void MetamodSource::ClientConPrintf(edict_t *client, const char *fmt, ...) +void MetamodSource::ClientConPrintf(MMSPlayer_t client, const char *fmt, ...) { va_list ap; char buffer[2048]; diff --git a/core/metamod.h b/core/metamod.h index 82b6bf8..468c61f 100644 --- a/core/metamod.h +++ b/core/metamod.h @@ -53,40 +53,40 @@ using namespace SourceMM; class MetamodSource : public ISmmAPI { +public: // ISmmAPI + void LogMsg(ISmmPlugin *pl, const char *msg, ...) override; + CreateInterfaceFn GetEngineFactory(bool syn=true) override; + CreateInterfaceFn GetPhysicsFactory(bool syn=true) override; + CreateInterfaceFn GetFileSystemFactory(bool syn=true) override; + CreateInterfaceFn GetServerFactory(bool syn=true) override; + CGlobalVars *GetCGlobals() override; + bool RegisterConCommandBase(ISmmPlugin *plugin, ConCommandBase *pCommand) override; + void UnregisterConCommandBase(ISmmPlugin *plugin, ConCommandBase *pCommand) override; + void ConPrint(const char *str) override; + void ConPrintf(const char *fmt, ...) override; + void GetApiVersions(int &major, int &minor, int &plvers, int &plmin) override; + void GetShVersions(int &shvers, int &shimpl) override; + void AddListener(ISmmPlugin *plugin, IMetamodListener *pListener) override; + void *MetaFactory(const char *iface, int *ret, PluginId *id) override; + int FormatIface(char iface[], size_t maxlength) override; + void *InterfaceSearch(CreateInterfaceFn fn, const char *iface, int max, int *ret) override; + const char *GetBaseDir() override; + size_t PathFormat(char *buffer, size_t len, const char *fmt, ...) override; + void ClientConPrintf(MMSPlayer_t client, const char *fmt, ...) override; + void *VInterfaceMatch(CreateInterfaceFn fn, const char *iface, int min=-1) override; + void EnableVSPListener() override; + int GetGameDLLVersion() override; + int GetUserMessageCount() override; + int FindUserMessage(const char *name, int *size=NULL) override; + const char *GetUserMessage(int index, int *size=NULL) override; + int GetVSPVersion() override; + int GetSourceEngineBuild() override; + IServerPluginCallbacks *GetVSPInfo(int *pVersion) override; + size_t Format(char *buffer, size_t maxlength, const char *format, ...) override; + size_t FormatArgs(char *buffer, size_t maxlength, const char *format, va_list ap) override; public: - void LogMsg(ISmmPlugin *pl, const char *msg, ...); - CreateInterfaceFn GetEngineFactory(bool syn=true); - CreateInterfaceFn GetPhysicsFactory(bool syn=true); - CreateInterfaceFn GetFileSystemFactory(bool syn=true); - CreateInterfaceFn GetServerFactory(bool syn=true); - CGlobalVars *GetCGlobals(); void SetLastMetaReturn(META_RES res); META_RES GetLastMetaReturn(); - bool RegisterConCommandBase(ISmmPlugin *plugin, ConCommandBase *pCommand); - void UnregisterConCommandBase(ISmmPlugin *plugin, ConCommandBase *pCommand); - void ConPrint(const char *str); - void ConPrintf(const char *fmt, ...); - void GetApiVersions(int &major, int &minor, int &plvers, int &plmin); - void GetShVersions(int &shvers, int &shimpl); - void AddListener(ISmmPlugin *plugin, IMetamodListener *pListener); - void *MetaFactory(const char *iface, int *ret, PluginId *id); - int FormatIface(char iface[], size_t maxlength); - void *InterfaceSearch(CreateInterfaceFn fn, const char *iface, int max, int *ret); - const char *GetBaseDir(); - size_t PathFormat(char *buffer, size_t len, const char *fmt, ...); - void ClientConPrintf(edict_t *client, const char *fmt, ...); - void *VInterfaceMatch(CreateInterfaceFn fn, const char *iface, int min=-1); - void EnableVSPListener(); - int GetGameDLLVersion(); - int GetUserMessageCount(); - int FindUserMessage(const char *name, int *size=NULL); - const char *GetUserMessage(int index, int *size=NULL); - int GetVSPVersion(); - int GetSourceEngineBuild(); - IServerPluginCallbacks *GetVSPInfo(int *pVersion); - size_t Format(char *buffer, size_t maxlength, const char *format, ...); - size_t FormatArgs(char *buffer, size_t maxlength, const char *format, va_list ap); -public: bool IsLoadedAsGameDLL(); const char *GetGameBinaryPath(); const char *GetPluginsFile(); diff --git a/core/metamod_console.cpp b/core/metamod_console.cpp index 28effa8..8cadd8a 100644 --- a/core/metamod_console.cpp +++ b/core/metamod_console.cpp @@ -44,9 +44,9 @@ using namespace SourceHook; #define CLIENT_CONMSG g_Metamod.ClientConPrintf template -void CMDMSG(edict_t *client, const char *pMsg, Ts ... ts) +void CMDMSG(MMSPlayer_t client, const char *pMsg, Ts ... ts) { - if (client) + if (client != MMSPlayer_INVALID) { CLIENT_CONMSG(client, pMsg, ts...); } @@ -56,7 +56,7 @@ void CMDMSG(edict_t *client, const char *pMsg, Ts ... ts) } } -static void ReplyCredits(edict_t *client = nullptr) +static void ReplyCredits(MMSPlayer_t client = MMSPlayer_INVALID) { CMDMSG(client, "Metamod:Source was developed by:\n"); CMDMSG(client, " SourceHook: Pavol \"PM OnoTo\" Marko\n"); @@ -66,7 +66,7 @@ static void ReplyCredits(edict_t *client = nullptr) CMDMSG(client, "http://www.metamodsource.net/\n"); } -static void ReplyVersion(edict_t *client = nullptr) +static void ReplyVersion(MMSPlayer_t client = MMSPlayer_INVALID) { CMDMSG(client, " Metamod:Source Version Information\n"); CMDMSG(client, " Metamod:Source version %s\n", METAMOD_VERSION); @@ -642,7 +642,7 @@ bool Command_Meta(IMetamodSourceCommandInfo *info) return true; } -bool Command_ClientMeta(edict_t *client, IMetamodSourceCommandInfo *info) +bool Command_ClientMeta(MMSPlayer_t client, IMetamodSourceCommandInfo *info) { const char *cmd = info->GetArg(0); diff --git a/core/metamod_console.h b/core/metamod_console.h index 6b3e278..68c026a 100644 --- a/core/metamod_console.h +++ b/core/metamod_console.h @@ -31,6 +31,6 @@ #include "metamod_provider.h" bool Command_Meta(IMetamodSourceCommandInfo *info); -bool Command_ClientMeta(edict_t *client, IMetamodSourceCommandInfo *info); +bool Command_ClientMeta(MMSPlayer_t client, IMetamodSourceCommandInfo *info); #endif //_INCLUDE_CONCOMMANDS_H diff --git a/core/metamod_provider.h b/core/metamod_provider.h index e1065d6..2c12a2e 100644 --- a/core/metamod_provider.h +++ b/core/metamod_provider.h @@ -98,7 +98,7 @@ namespace SourceMM /** * @brief Called when a client executes "meta" as a ClientCommand */ - virtual bool OnCommand_ClientMeta(edict_t* client, IMetamodSourceCommandInfo* info) = 0; + virtual bool OnCommand_ClientMeta(MMSPlayer_t player, IMetamodSourceCommandInfo* info) = 0; }; class IMetamodSourceProvider @@ -150,10 +150,10 @@ namespace SourceMM /** * @brief Prints text in the specified client's console. * - * @param client Client edict pointer. + * @param player Player identifier * @param msg Message string. */ - virtual void ClientConsolePrint(edict_t *client, const char *msg) =0; + virtual void ClientConsolePrint(MMSPlayer_t player, const char *msg) =0; /** * @brief Halts the server with a fatal error message. diff --git a/core/provider/provider_base.h b/core/provider/provider_base.h index 3092eba..413a5cf 100644 --- a/core/provider/provider_base.h +++ b/core/provider/provider_base.h @@ -60,7 +60,7 @@ public: // Must implement virtual bool ProcessVDF(const char* file, char path[], size_t path_len, char alias[], size_t alias_len) override = 0; virtual const char* GetCommandLineValue(const char* key, const char* defval) override = 0; virtual void ConsolePrint(const char* msg) override = 0; - virtual void ClientConsolePrint(edict_t* client, const char* msg) override = 0; + virtual void ClientConsolePrint(MMSPlayer_t player, const char* msg) override = 0; virtual void ServerCommand(const char* cmd) override = 0; virtual MetamodSourceConVar *CreateConVar(const char* name, const char* defval, diff --git a/core/provider/source/provider_source.cpp b/core/provider/source/provider_source.cpp index d5eb3ed..a6b330f 100644 --- a/core/provider/source/provider_source.cpp +++ b/core/provider/source/provider_source.cpp @@ -347,7 +347,7 @@ const char* SourceProvider::GetCommandLineValue(const char* key, const char* def return NULL; } -void SourceProvider::ClientConsolePrint(edict_t* pEdict, const char* message) +void SourceProvider::ClientConsolePrint(MMSPlayer_t pEdict, const char* message) { engine->ClientPrintf(pEdict, message); } diff --git a/core/provider/source/provider_source.h b/core/provider/source/provider_source.h index 3d80bae..6f55ade 100644 --- a/core/provider/source/provider_source.h +++ b/core/provider/source/provider_source.h @@ -45,7 +45,7 @@ public: // BaseProvider virtual const char* GetGameDescription() override; virtual const char* GetCommandLineValue(const char* key, const char* defval) override; virtual void ConsolePrint(const char* msg) override; - virtual void ClientConsolePrint(edict_t* client, const char* msg) override; + virtual void ClientConsolePrint(MMSPlayer_t client, const char* msg) override; virtual void ServerCommand(const char* cmd) override; virtual MetamodSourceConVar *CreateConVar(const char* name, const char* defval, diff --git a/core/provider/source2/provider_source2.cpp b/core/provider/source2/provider_source2.cpp index 13502fd..89cbb02 100644 --- a/core/provider/source2/provider_source2.cpp +++ b/core/provider/source2/provider_source2.cpp @@ -38,8 +38,8 @@ static Source2Provider g_Source2Provider; IMetamodSourceProvider* provider = &g_Source2Provider; +CON_COMMAND_EXTERN(meta, LocalCommand_Meta, "Metamod:Source control options"); -ConCommand meta_local_cmd("meta", LocalCommand_Meta, "Metamod:Source control options"); static ISource2ServerConfig* serverconfig = NULL; INetworkServerService* netservice = NULL; @@ -53,7 +53,7 @@ SH_DECL_HOOK3_void(INetworkServerService, StartupServer, SH_NOATTRIB, 0, const G SH_DECL_HOOK5_void(IEngineServiceMgr, SwitchToLoop, SH_NOATTRIB, 0, const char *, KeyValues *, uint32, const char *, bool); SH_DECL_HOOK2_void(INetworkGameServer, Init, SH_NOATTRIB, 0, const GameSessionConfiguration_t &, const char *); SH_DECL_HOOK3(INetworkGameServer, StartChangeLevel, SH_NOATTRIB, 0, CUtlVector *, const char *, const char *, void *); -SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, CEntityIndex, const CCommand&); +SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, CPlayerSlot, const CCommand&); #ifdef SHOULD_OVERRIDE_ALLOWDEDICATED_SERVER SH_DECL_HOOK1(ISource2ServerConfig, AllowDedicatedServers, const, 0, bool, EUniverse); @@ -125,9 +125,7 @@ void Source2Provider::Notify_DLLInit_Pre(CreateInterfaceFn engineFactory, g_pCVar = icvar; -#ifdef S2_CONVAR_UNFINISHED - g_SMConVarAccessor.RegisterConCommandBase(&meta_local_cmd); -#endif + ConVar_Register(FCVAR_RELEASE); if (gameclients) { @@ -144,9 +142,7 @@ void Source2Provider::Notify_DLLInit_Pre(CreateInterfaceFn engineFactory, void Source2Provider::Notify_DLLShutdown_Pre() { -#ifdef S2_CONVAR_UNFINISHED - g_SMConVarAccessor.RemoveMetamodCommands(); -#endif + ConVar_Unregister(); } bool Source2Provider::ProcessVDF(const char* file, char path[], size_t path_len, char alias[], size_t alias_len) @@ -242,9 +238,8 @@ void Source2Provider::ConsolePrint(const char* str) ConMsg("%s", str); } -void Source2Provider::ClientConsolePrint(edict_t* pEdict, const char* message) +void Source2Provider::ClientConsolePrint(MMSPlayer_t client, const char* message) { - int client = (int)(pEdict - gpGlobals->pEdicts); engine->ClientPrintf(client, message); } @@ -263,7 +258,7 @@ const char* Source2Provider::GetConVarString(MetamodSourceConVar *convar) return convar->GetString(); #else - return ""; + return nullptr; #endif } @@ -350,7 +345,7 @@ private: const CCommand* m_cmd; }; -void LocalCommand_Meta(const CCommand& args) +void LocalCommand_Meta(const CCommandContext &, const CCommand& args) { if (nullptr != g_Source2Provider.m_pCallbacks) { @@ -438,17 +433,15 @@ void Source2Provider::Hook_SwitchToLoop(const char *pszLoopName, KeyValues *pKV, RETURN_META(MRES_IGNORED); } -void Source2Provider::Hook_ClientCommand(CEntityIndex index, const CCommand& _cmd) +void Source2Provider::Hook_ClientCommand(CPlayerSlot nSlot, const CCommand& _cmd) { - int client = index.Get(); GlobCommand cmd(&_cmd); if (strcmp(cmd.GetArg(0), "meta") == 0) { if (nullptr != m_pCallbacks) { - auto pEdict = reinterpret_cast(gpGlobals->pEdicts + (intp)client); - m_pCallbacks->OnCommand_ClientMeta(pEdict, &cmd); + m_pCallbacks->OnCommand_ClientMeta(nSlot, &cmd); } RETURN_META(MRES_SUPERCEDE); diff --git a/core/provider/source2/provider_source2.h b/core/provider/source2/provider_source2.h index ff90d6e..d9f0378 100644 --- a/core/provider/source2/provider_source2.h +++ b/core/provider/source2/provider_source2.h @@ -52,7 +52,7 @@ public: virtual const char* GetGameDescription() override; virtual const char* GetCommandLineValue(const char* key, const char* defval) override; virtual void ConsolePrint(const char* msg) override; - virtual void ClientConsolePrint(edict_t* client, const char* msg) override; + virtual void ClientConsolePrint(MMSPlayer_t player, const char* msg) override; virtual void ServerCommand(const char* cmd) override; virtual MetamodSourceConVar *CreateConVar(const char* name, const char* defval, @@ -71,14 +71,14 @@ public: void Hook_Init(const GameSessionConfiguration_t &config, const char* pszMapName); CUtlVector *Hook_StartChangeLevel(const char*, const char*, void*); void Hook_SwitchToLoop(const char *pszLoopName, KeyValues *pKV, uint32 nId, const char *pszUnk, bool bUnk); - void Hook_ClientCommand(CEntityIndex index, const CCommand& args); + void Hook_ClientCommand(CPlayerSlot nSlot, const CCommand& args); private: bool KVLoadFromFile(KeyValues *kv, IFileSystem *filesystem, const char *resourceName, const char *pathID); private: IFileSystem* baseFs = nullptr; std::string sLastMap; - friend void LocalCommand_Meta(const CCommand& args); + friend void LocalCommand_Meta(const CCommandContext& context, const CCommand& args); }; #endif