From ebca331ae4a1e1d1505d4243750ca4a4704bf713 Mon Sep 17 00:00:00 2001 From: Scott Ehlert Date: Fri, 21 Apr 2006 06:35:47 +0000 Subject: [PATCH] Added client version of "meta" command in order to allow clients to view version information and a list of loaded plugins. Added ClientConPrintf to API for printing text in a client's console. Same as IVEngineServer::ClientPrintf except that it allows string formatting. Updated changelog for possible future version. Version bumpage. Feel free to kill me for doing a change of this almost massive scale :-\ At least none of this breaks plugins though. --HG-- extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40193 --- sourcemm/CPlugin.h | 2 +- sourcemm/CSmmAPI.cpp | 9 +++++ sourcemm/CSmmAPI.h | 4 ++- sourcemm/ISmmAPI.h | 7 ++++ sourcemm/changelog.txt | 8 +++++ sourcemm/concommands.cpp | 76 +++++++++++++++++++++++++++++++++++++++- sourcemm/concommands.h | 2 ++ sourcemm/sourcemm.cpp | 13 ++++++- sourcemm/sourcemm.h | 5 +-- sourcemm/version.rc | 9 +++-- 10 files changed, 124 insertions(+), 11 deletions(-) diff --git a/sourcemm/CPlugin.h b/sourcemm/CPlugin.h index f5bd61f..1fe9701 100644 --- a/sourcemm/CPlugin.h +++ b/sourcemm/CPlugin.h @@ -32,7 +32,7 @@ * 4: Added AllPluginsLoaded() callback (2005-04-18) * 5: Bumped version for SourceHook V4 (2005-05-01) * 6: Added functions for console printing (2005-05-26) - * M 7: Changed template libraries (2005-08-11) + * M 7: Changed template libraries (2005-08-11) * New loading structure mechanism * New SourceHook version * C 8: New SourceHook version (2005-12-23) diff --git a/sourcemm/CSmmAPI.cpp b/sourcemm/CSmmAPI.cpp index 7c5b9b3..979bd34 100644 --- a/sourcemm/CSmmAPI.cpp +++ b/sourcemm/CSmmAPI.cpp @@ -360,3 +360,12 @@ void CSmmAPI::PathFormat(char *buffer, size_t len, const char *fmt, ...) } } +void CSmmAPI::ClientConPrintf(edict_t *client, const char *fmt, ...) +{ + va_list ap; + static char buf[4096]; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf) - 1, fmt, ap); + g_Engine.engine->ClientPrintf(client, buf); + va_end(ap); +} diff --git a/sourcemm/CSmmAPI.h b/sourcemm/CSmmAPI.h index 9902aed..eed291f 100644 --- a/sourcemm/CSmmAPI.h +++ b/sourcemm/CSmmAPI.h @@ -54,6 +54,7 @@ namespace SourceMM virtual void *InterfaceSearch(CreateInterfaceFn fn, const char *iface, int max, int *ret); virtual const char *GetBaseDir(); virtual void PathFormat(char *buffer, size_t len, const char *fmt, ...); + void ClientConPrintf(edict_t *client, const char *fmt, ...); public: bool CacheCmds(); private: @@ -65,6 +66,7 @@ namespace SourceMM extern SourceMM::CSmmAPI g_SmmAPI; -#define CONMSG g_SmmAPI.ConPrintf +#define CONMSG g_SmmAPI.ConPrintf +#define CLIENT_CONMSG g_SmmAPI.ClientConPrintf #endif //_INCLUDE_CSMM_API_H diff --git a/sourcemm/ISmmAPI.h b/sourcemm/ISmmAPI.h index b6b30c1..cdd22c8 100644 --- a/sourcemm/ISmmAPI.h +++ b/sourcemm/ISmmAPI.h @@ -98,6 +98,12 @@ public: //Added in 1.2 (1:2) * @brief Formats a file path to the local OS. Does not include any base directories. */ virtual void PathFormat(char *buffer, size_t len, const char *fmt, ...) =0; +public: // Added in 1.2.2 (1:3) + /** + * @brief Prints text in the specified client's console. Same as IVEngineServer::ClientPrintf + * except that it allows for string formatting. + */ + virtual void ClientConPrintf(edict_t *client, const char *fmt, ...) =0; }; @@ -105,6 +111,7 @@ public: //Added in 1.2 (1:2) * 1.1.0 bumped API to 1:0. The breaking changes occured in sourcehook and the plugin API. * 1.1.2 added API call for generating iface names. * 1.2 added API more helper functions and new SourceHook version. + * 1.2.2 added API for printing to client console (with string formatting) */ #endif //_INCLUDE_ISMM_API_H diff --git a/sourcemm/changelog.txt b/sourcemm/changelog.txt index 9d05ece..43ef150 100644 --- a/sourcemm/changelog.txt +++ b/sourcemm/changelog.txt @@ -1,3 +1,11 @@ +2006/XX/XX 1.2.2: + - Added ClientConPrintf to API for printing text in a client's console. This does the + same thing as IVEngineServer::ClientPrintf except that it allows string formatting. + - Added client version of "meta" command in order to allow clients to view version + information and a list of loaded plugins. + - Fixed a bug where the mm_pluginsfile cvar was being ignored. + - Fixed a memory leak when using ISmmAPI::InterfaceSearch. + 2006/02/15 1.2.1: - Fixed bug where returning newparams in a post hook would cause infinite recursion. - Fixed bug where "meta load" could load the same plugin multiple times. diff --git a/sourcemm/concommands.cpp b/sourcemm/concommands.cpp index 9234488..ed72277 100644 --- a/sourcemm/concommands.cpp +++ b/sourcemm/concommands.cpp @@ -549,8 +549,82 @@ void CAlwaysRegisterableCommand::BringToFront() } } +void ClientCommand_handler(edict_t *client) +{ + IVEngineServer *e = g_Engine.engine; + const char *cmd = e->Cmd_Argv(0); + + if (strcmp(cmd, "meta") == 0) + { + int args = e->Cmd_Argc(); + if (args == 2) + { + const char *subcmd = e->Cmd_Argv(1); + + if (strcmp(subcmd, "credits") == 0) + { + CLIENT_CONMSG(client, "Metamod:Source was developed by:\n"); + CLIENT_CONMSG(client, " SourceHook: Pavol \"PM OnoTo\" Marko\n"); + CLIENT_CONMSG(client, " GameDLL/Plugins: David \"BAILOPAN\" Anderson\n"); + CLIENT_CONMSG(client, " GameDLL: Scott \"Damaged Soul\" Ehlert\n"); + CLIENT_CONMSG(client, "For more information, see the official website\n"); + CLIENT_CONMSG(client, "http://www.sourcemm.net/\n"); + } + else if(strcmp(subcmd, "version") == 0) + { + CLIENT_CONMSG(client, "Metamod:Source version %s\n", SOURCEMM_VERSION); + CLIENT_CONMSG(client, "Compiled on: %s\n", SOURCEMM_DATE); + CLIENT_CONMSG(client, "Plugin interface version: %d:%d\n", PLAPI_VERSION, PLAPI_MIN_VERSION); + CLIENT_CONMSG(client, "SourceHook version: %d:%d\n", g_SourceHook.GetIfaceVersion(), g_SourceHook.GetImplVersion()); + CLIENT_CONMSG(client, "http://www.sourcemm.net/\n"); + } + else if(strcmp(subcmd, "list") == 0) + { + SourceMM::CPluginManager::CPlugin *pl; + PluginIter i; + const char *version=NULL; + const char *name=NULL; + const char *author=NULL; + + CLIENT_CONMSG(client, "-Id- %-20.19s %-10.9s %-12.11s\n", "Name", "Version", "Author"); + + for (i=g_PluginMngr._begin(); i!=g_PluginMngr._end(); i++) + { + pl = (*i); + if (!pl) + break; + + // Should paused plugins really show up in the list too? + if (pl->m_API && (pl->m_Status == Pl_Running || pl->m_Status == Pl_Paused)) + { + version = pl->m_API->GetVersion(); + author = pl->m_API->GetAuthor(); + name = pl->m_API->GetName(); + + if (!version || !author || !name) + break; + + CLIENT_CONMSG(client, "[%02d] %-20.19s %-10.9s %-12.11s\n", pl->m_Id, name, version, author); + } + } + } + } + else + { + CLIENT_CONMSG(client, "Metamod:Source Menu\n"); + CLIENT_CONMSG(client, "usage: meta \n"); + CLIENT_CONMSG(client, " credits - About Metamod:Source\n"); + CLIENT_CONMSG(client, " list - List plugins\n"); + CLIENT_CONMSG(client, " version - Version information\n"); + } + + RETURN_META(MRES_SUPERCEDE); + } + + RETURN_META(MRES_IGNORED); +} + const char *GetPluginsFile() { return mm_pluginsfile.GetString(); } - diff --git a/sourcemm/concommands.h b/sourcemm/concommands.h index 091b733..40f5859 100644 --- a/sourcemm/concommands.h +++ b/sourcemm/concommands.h @@ -44,6 +44,8 @@ public: void BringToFront(); }; +void ClientCommand_handler(edict_t *client); + const char *GetPluginsFile(); extern SMConVarAccessor g_SMConVarAccessor; diff --git a/sourcemm/sourcemm.cpp b/sourcemm/sourcemm.cpp index cba884d..dcbdfbe 100644 --- a/sourcemm/sourcemm.cpp +++ b/sourcemm/sourcemm.cpp @@ -29,13 +29,14 @@ SH_DECL_HOOK4(IServerGameDLL, DLLInit, SH_NOATTRIB, false, bool, CreateInterface SH_DECL_HOOK0_void(IServerGameDLL, DLLShutdown, SH_NOATTRIB, false); SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false); SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool); +SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *); bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn filesystemFactory, CGlobalVars *pGlobals); bool DLLInit_Post(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn filesystemFactory, CGlobalVars *pGlobals); void DLLShutdown_handler(); void LevelShutdown_handler(); bool LevelInit_handler(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background); -GameDllInfo g_GameDll = {false, NULL, NULL, NULL}; +GameDllInfo g_GameDll = {false, NULL, NULL, NULL, NULL}; EngineInfo g_Engine; SourceHook::CSourceHookImpl g_SourceHook; SourceHook::ISourceHook *g_SHPtr = &g_SourceHook; @@ -102,6 +103,15 @@ void InitMainStates() SH_ADD_HOOK_STATICFUNC(IServerGameDLL, DLLShutdown, g_GameDll.pGameDLL, DLLShutdown_handler, false); SH_ADD_HOOK_STATICFUNC(IServerGameDLL, LevelShutdown, g_GameDll.pGameDLL, LevelShutdown_handler, true); SH_ADD_HOOK_STATICFUNC(IServerGameDLL, LevelInit, g_GameDll.pGameDLL, LevelInit_handler, true); + + if (g_GameDll.pGameClients) + SH_ADD_HOOK_STATICFUNC(IServerGameClients, ClientCommand, g_GameDll.pGameClients, ClientCommand_handler, false); + else + { + // If IServerGameClients isn't found, this really isn't a fatal error so... + LogMessage("[META] Warning: Could not find IServerGameClients!"); + LogMessage("[META] Warning: The 'meta' command will not be available to clients."); + } } bool DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn filesystemFactory, CGlobalVars *pGlobals) @@ -349,6 +359,7 @@ SMM_API void *CreateInterface(const char *iface, int *ret) pInfo->lib = gamedll; pInfo->loaded = true; pInfo->pGameDLL = NULL; + pInfo->pGameClients = (IServerGameClients *)((fn)(INTERFACEVERSION_SERVERGAMECLIENTS, NULL)); gamedll_list.push_back(pInfo); } } diff --git a/sourcemm/sourcemm.h b/sourcemm/sourcemm.h index dd43003..af20dff 100644 --- a/sourcemm/sourcemm.h +++ b/sourcemm/sourcemm.h @@ -34,11 +34,11 @@ * increase vers_release when bug fix releases are made * never increase major */ -#define SOURCEMM_VERSION "1.2.1" +#define SOURCEMM_VERSION "1.2.2" #define SOURCEMM_DATE __DATE__ #define SM_MAJOR_VERSION 1 //never need to increase this #define SM_VERS_API_MAJOR 1 //increase this on a breaking change -#define SM_VERS_API_MINOR 2 //increase this on a non-breaking API change +#define SM_VERS_API_MINOR 3 //increase this on a non-breaking API change #define SM_VERS_RELEASE 1 //increase this on a bug-fix release. //We need a good CServerGameDLL version to work properly. We support these inclusively. @@ -72,6 +72,7 @@ struct GameDllInfo HINSTANCE lib; CreateInterfaceFn factory; IServerGameDLL *pGameDLL; + IServerGameClients *pGameClients; }; /** @brief Stores information about the HL2 Engine pointers */ diff --git a/sourcemm/version.rc b/sourcemm/version.rc index 7fe2d35..945b6ea 100755 --- a/sourcemm/version.rc +++ b/sourcemm/version.rc @@ -1,6 +1,5 @@ // Microsoft Visual C++ generated resource script. // - #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // @@ -26,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,1,0 - PRODUCTVERSION 1,2,1,0 + FILEVERSION 1,2,2,0 + PRODUCTVERSION 1,2,2,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -44,12 +43,12 @@ BEGIN BEGIN VALUE "Comments", "Metamod: Source" VALUE "FileDescription", "Metamod: Source" - VALUE "FileVersion", "1.2.1" + VALUE "FileVersion", "1.2.2" VALUE "InternalName", "sourcemm" VALUE "LegalCopyright", "Copyright (c) 2004-2006, Metamod: Source Development Team" VALUE "OriginalFilename", "server.dll" VALUE "ProductName", "Metamod: Source" - VALUE "ProductVersion", "1.2.1" + VALUE "ProductVersion", "1.2.2" END END BLOCK "VarFileInfo"