From cf6dbdb1fe64283c639872f9899167231242906d Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 21 Sep 2007 18:03:57 +0000 Subject: [PATCH] - added an api call for finding source engine build - random markup/doc changes --HG-- branch : sourcemm-1.6.0 extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/sourcemm-1.6.0%40426 --- sourcemm/CSmmAPI.cpp | 5 ++ sourcemm/CSmmAPI.h | 116 +++++++++++++++++++++--------------------- sourcemm/ISmmAPI.h | 73 ++++++++++++++++++-------- sourcemm/ISmmPlugin.h | 64 ++++++++++++++--------- sourcemm/sourcemm.cpp | 28 ++++------ sourcemm/sourcemm.h | 18 +++---- 6 files changed, 175 insertions(+), 129 deletions(-) diff --git a/sourcemm/CSmmAPI.cpp b/sourcemm/CSmmAPI.cpp index 0bd8dd4..459e585 100644 --- a/sourcemm/CSmmAPI.cpp +++ b/sourcemm/CSmmAPI.cpp @@ -673,3 +673,8 @@ int CSmmAPI::GetVSPVersion() { return g_VspVersion; } + +int CSmmAPI::GetSourceEngineBuild() +{ + return g_SourceEngineVersion; +} diff --git a/sourcemm/CSmmAPI.h b/sourcemm/CSmmAPI.h index 546b77b..98f9563 100644 --- a/sourcemm/CSmmAPI.h +++ b/sourcemm/CSmmAPI.h @@ -29,69 +29,67 @@ typedef CUtlDict UserMsgDict; typedef void (*CONPRINTF_FUNC)(const char *, ...); -namespace SourceMM +class CSmmAPI : public ISmmAPI { - class CSmmAPI : public ISmmAPI +public: + CSmmAPI(); + ~CSmmAPI(); +public: + void LogMsg(ISmmPlugin *pl, const char *msg, ...); +public: + CreateInterfaceFn engineFactory(bool syn=true); + CreateInterfaceFn physicsFactory(bool syn=true); + CreateInterfaceFn fileSystemFactory(bool syn=true); + CreateInterfaceFn serverFactory(bool syn=true); + CGlobalVars *pGlobals(); + void SetLastMetaReturn(META_RES res); + META_RES GetLastMetaReturn(); + IConCommandBaseAccessor *GetCvarBaseAccessor(); + bool RegisterConCmdBase(ISmmPlugin *plugin, ConCommandBase *pCommand); + void UnregisterConCmdBase(ISmmPlugin *plugin, ConCommandBase *pCommand); + void ConPrint(const char *fmt); + void ConPrintf(const char *fmt, ...); + bool RemotePrintingAvailable() { - public: - CSmmAPI(); - ~CSmmAPI(); - public: - void LogMsg(ISmmPlugin *pl, const char *msg, ...); - public: - CreateInterfaceFn engineFactory(bool syn=true); - CreateInterfaceFn physicsFactory(bool syn=true); - CreateInterfaceFn fileSystemFactory(bool syn=true); - CreateInterfaceFn serverFactory(bool syn=true); - CGlobalVars *pGlobals(); - void SetLastMetaReturn(META_RES res); - META_RES GetLastMetaReturn(); - IConCommandBaseAccessor *GetCvarBaseAccessor(); - bool RegisterConCmdBase(ISmmPlugin *plugin, ConCommandBase *pCommand); - void UnregisterConCmdBase(ISmmPlugin *plugin, ConCommandBase *pCommand); - void ConPrint(const char *fmt); - void ConPrintf(const char *fmt, ...); - bool RemotePrintingAvailable() - { - return CmdCacheSuccessful(); - } - virtual void GetApiVersions(int &major, int &minor, int &plvers, int &plmin); - virtual void GetShVersions(int &shvers, int &shimpl); - virtual void AddListener(ISmmPlugin *plugin, IMetamodListener *pListener); - virtual void *MetaFactory(const char *iface, int *ret, PluginId *id); - virtual int FormatIface(char buffer[], unsigned int maxlength); - 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, ...); - 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(); - public: - bool CacheCmds(); - bool CmdCacheSuccessful(); - void LoadAsVSP(); - bool VSPEnabled() - { - return m_VSP; - } - bool CacheUserMessages(); - bool MsgCacheSuccessful(); - private: - META_RES m_Res; - CONPRINTF_FUNC m_ConPrintf; - bool m_CmdCache; - bool m_VSP; - int m_MsgCount; - UserMsgDict m_UserMessages; - }; + return CmdCacheSuccessful(); + } + virtual void GetApiVersions(int &major, int &minor, int &plvers, int &plmin); + virtual void GetShVersions(int &shvers, int &shimpl); + virtual void AddListener(ISmmPlugin *plugin, IMetamodListener *pListener); + virtual void *MetaFactory(const char *iface, int *ret, PluginId *id); + virtual int FormatIface(char buffer[], unsigned int maxlength); + 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, ...); + 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(); +public: + bool CacheCmds(); + bool CmdCacheSuccessful(); + void LoadAsVSP(); + bool VSPEnabled() + { + return m_VSP; + } + bool CacheUserMessages(); + bool MsgCacheSuccessful(); +private: + META_RES m_Res; + CONPRINTF_FUNC m_ConPrintf; + bool m_CmdCache; + bool m_VSP; + int m_MsgCount; + UserMsgDict m_UserMessages; }; -extern SourceMM::CSmmAPI g_SmmAPI; +extern CSmmAPI g_SmmAPI; #define CONMSG g_SmmAPI.ConPrintf #define CLIENT_CONMSG g_SmmAPI.ClientConPrintf diff --git a/sourcemm/ISmmAPI.h b/sourcemm/ISmmAPI.h index d37e543..e6f7c70 100644 --- a/sourcemm/ISmmAPI.h +++ b/sourcemm/ISmmAPI.h @@ -33,7 +33,11 @@ class ISmmPlugin; #define MMIFACE_SOURCEHOOK "ISourceHook" /**< ISourceHook Pointer */ #define MMIFACE_PLMANAGER "IPluginManager" /**< SourceMM Plugin Functions */ -#define IFACE_MAXNUM 999 +#define IFACE_MAXNUM 999 /**< Maximum interface version */ + +#define SOURCE_ENGINE_ORIGINAL 0 /**< Original Source Engine (used by The Ship) */ +#define SOURCE_ENGINE_EPISODEONE 1 /**< Episode 1 Source Engine (second major SDK) */ +#define SOURCE_ENGINE_ORANGEBOX 2 /**< Orange Box Source Engine (third major SDK) */ class ISmmAPI { @@ -119,7 +123,7 @@ public: // Added in 1.00-RC2 (0:0) * * @param plugin Parent plugin API pointer. * @param pCommand ConCommandBase to register. - * @return True if successful, false otherwise. Does not return false yet. + * @return True if successful, false otherwise. */ virtual bool RegisterConCmdBase(ISmmPlugin *plugin, ConCommandBase *pCommand) =0; @@ -133,6 +137,7 @@ public: // Added in 1.00-RC2 (0:0) /** * @brief Prints an unformatted string to the remote server console. + * * Note: Newlines are not added automatically. * * @param str Message string. @@ -141,6 +146,7 @@ public: // Added in 1.00-RC2 (0:0) /** * @brief Prints a formatted message to the remote server console. + * * Note: Newlines are not added automatically. * * @param fmt Formatted message. @@ -207,7 +213,7 @@ public: // Added in 1.1.2 (1:1) public: // Added in 1.2 (1:2) /** - * @brief Searches for an interface for you. + * @brief Searches for an interface, eliminating the need to loop through FormatIface(). * * @param fn InterfaceFactory function. * @param iface Interface string name. @@ -219,15 +225,17 @@ public: // Added in 1.2 (1:2) /** * @brief Returns the base directory of the game/server, equivalent to - * IVEngineServer::GetGameDir(), except the path is absolute. + * IVEngineServer::GetGameDir(), except the path is absolute. * * @return Static pointer to game's absolute basedir. */ virtual const char *GetBaseDir() =0; /** - * @brief Formats a file path to the local OS. Does not include any base directories. - * Note that all slashes and black slashes are reverted to the local OS's expectancy. + * @brief Formats a file path to the local OS. + * + * Does not include any base directories. Note that all slashes and black + * slashes are reverted to the local OS's expectancy. * * @param buffer Destination buffer to store path. * @param len Maximum length of buffer, including null terminator. @@ -237,8 +245,8 @@ public: // Added in 1.2 (1:2) 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. + * @brief Prints text in the specified client's console. Same as + * IVEngineServer::ClientPrintf except that it allows for string formatting. * * @param client Client edict pointer. * @param fmt Formatted string to print to the client. @@ -253,11 +261,13 @@ public: // Added in 1.3 (1:4) * * @param fn Interface factory function. * @param iface Interface string. - * @param min Minimum value to search from. If zero, searching begins from the - * first available version regardless of the interface. - * Note that this can return interfaces EARLIER than the version specified. - * A value of -1 (default) specifies the string version as the minimum. - * Any other value specifices the minimum value to search from. + * @param min Minimum value to search from. If zero, searching + * begins from the first available version regardless + * of the interface. Note that this can return + * interfaces EARLIER than the version specified. A + * value of -1 (default) specifies the string version + * as the minimum. Any other value specifices the + * minimum value to search from. * @return Interface pointer, or NULL if not found. */ virtual void *VInterfaceMatch(CreateInterfaceFn fn, const char *iface, int min=-1) =0; @@ -266,14 +276,19 @@ public: // Added in 1.4 (1:5) /** * @brief Tells SourceMM to add VSP hooking capability to plugins. * - * Since this potentially uses more resources than it would otherwise, plugins have to - * explicitly enable the feature. Whether requested or not, if it is enabled, all plugins - * will get a pointer to the VSP listener through IMetamodListener. + * Since this potentially uses more resources than it would otherwise, + * plugins have to explicitly enable the feature. Whether requested or + * not, if it is enabled, all plugins will get a pointer to the VSP + * listener through IMetamodListener. This will not be called more than + * once for a given plugin; if it is requested more than once, each + * successive call will only give the pointer to plugins which have not + * yet received it. */ virtual void EnableVSPListener() =0; /** - * @brief Returns the interface version of the GameDLL's IServerGameDLL implementation. + * @brief Returns the interface version of the GameDLL's IServerGameDLL + * implementation. * * @return Interface version of the loaded IServerGameDLL. */ @@ -282,7 +297,8 @@ public: // Added in 1.4 (1:5) /** * @brief Returns the number of user messages in the GameDLL. * - * @return Number of user messages, or -1 if SourceMM has failed to get user message list. + * @return Number of user messages, or -1 if SourceMM has + * failed to get user message list. */ virtual int GetUserMessageCount() =0; @@ -303,15 +319,29 @@ public: // Added in 1.4 (1:5) * @return Message name, or NULL on failure. */ virtual const char *GetUserMessage(int index, int *size=NULL) =0; + public: // Added in 1.5.0 (1:6) /** - * @brief Returns the highest interface version of IServerPluginCallbacks that the engine supports. - * This is useful for games that run on older versions of the Source engine, such as The Ship. + * @brief Returns the highest interface version of IServerPluginCallbacks + * that the engine supports. This is useful for games that run on older + * versions of the Source engine, such as The Ship. * * @return Highest interface version of IServerPluginCallbacks. - * Returns 0 if SourceMM's VSP listener isn't currently enabled. + * Returns 0 if SourceMM's VSP listener isn't currently + * enabled. */ virtual int GetVSPVersion() =0; + +public: // Added in 1.6.0 (1:7) + /** + * @brief Returns the engine interface that MM:S is using as a backend. + * + * The values will be one of the SOURCE_ENGINE_* constants from the top + * of this file. + * + * @return A SOURCE_ENGINE_* constant value. + */ + virtual int GetSourceEngineBuild() =0; }; @@ -325,6 +355,7 @@ public: // Added in 1.5.0 (1:6) * 1.3 Added new interface search API. * 1.4 Added VSP listener and user message API. * 1.5.0 Added API for getting highest supported version of IServerPluginCallbacks. + * 1.6.0 Added API for Orange Box. */ #endif //_INCLUDE_ISMM_API_H diff --git a/sourcemm/ISmmPlugin.h b/sourcemm/ISmmPlugin.h index 7b2ea3a..f795e0b 100644 --- a/sourcemm/ISmmPlugin.h +++ b/sourcemm/ISmmPlugin.h @@ -33,6 +33,7 @@ public: public: /** * @brief Called on plugin load. + * * NOTE - As of API 7, this is called as DLLInit() executes - after the parameters are known, but before * the original GameDLL function is called. Therefore, you cannot hook it, but you don't need to - * Load() is basically your hook. @@ -40,22 +41,24 @@ public: * However, take care to note that if your plugin is unloaded, and the gamedll/engine have cached * an interface you've passed, something will definitely crash. Be careful. * - * @param id Internal id of plugin. Saved globally by PLUGIN_SAVEVARS() - * @param ismm External API for SourceMM. Saved globally by PLUGIN_SAVEVARS() - * @param list Contains a list of factories. Hook a factory call by setting one equal to your own function. - * @param late Set to true if your plugin was loaded late (not at server load). - * @param error Error message buffer - * @param maxlen Size of error message buffer - * @return True if successful, return false to reject the load. + * @param id Internal id of plugin. Saved globally by PLUGIN_SAVEVARS() + * @param ismm External API for SourceMM. Saved globally by PLUGIN_SAVEVARS() + * @param list Contains a list of factories. Hook a factory call by setting one equal to your own function. + * @param late Set to true if your plugin was loaded late (not at server load). + * @param error Error message buffer + * @param maxlen Size of error message buffer + * @return True if successful, return false to reject the load. */ virtual bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlength, bool late) =0; /** - * @brief Called when your plugin is "queried". This is useful for rejecting a loaded - * state. For example, if your plugin wants to stop operating, it can simply return - * false and copy an error message. This will notify other plugins or MM:S of something - * bad that happened. NOTE - MM:S will not cache the return state, so if you return false, - * your plugin will not actually be paused or unloaded. This callback will be called when: + * @brief Called when your plugin is "queried". + * + * This is useful for rejecting a loaded state. For example, if your plugin wants + * to stop operating, it can simply return false and copy an error message. This + * will notify other plugins or MM:S of something bad that happened. NOTE - MM:S + * will not cache the return state, so if you return false, your plugin will not + * actually be paused or unloaded. This callback will be called when: * - Another plugin requests it * - Someone types "meta list", it will show up as "REFUSED" * - When Metamod need to re-check the plugin's status @@ -132,10 +135,11 @@ public: virtual const char *GetLogTag() =0; public: /** - * @brief Called when all plugins have been loaded - API version 4 + * @brief Called when all plugins have been loaded. * - * This is useful for knowing when it's safe to request things another plugin might have. - * NOTE for API 7 - This is called after DLLInit(). + * This is called after DLLInit(), and thus the mod has been mostly initialized. + * It is also safe to assume that all other (automatically loaded) plugins are now + * ready to start interacting, because they are all loaded. */ virtual void AllPluginsLoaded() { @@ -148,35 +152,45 @@ public: class IMetamodListener { public: - virtual ~IMetamodListener() { } + virtual ~IMetamodListener() + { + } public: /** * @brief Called when a plugin is loaded. * * @param id Id of the plugin. */ - virtual void OnPluginLoad(PluginId id) { } + virtual void OnPluginLoad(PluginId id) + { + } /** * @brief Called when a plugin is unloaded. * * @param id Id of the plugin. */ - virtual void OnPluginUnload(PluginId id) { } + virtual void OnPluginUnload(PluginId id) + { + } /** * @brief Called when a plugin is paused. * * @param id Id of the plugin. */ - virtual void OnPluginPause(PluginId id) { } + virtual void OnPluginPause(PluginId id) + { + } /** * @brief Called when a plugin is unpaused. * * @param id Id of the plugin. */ - virtual void OnPluginUnpause(PluginId id) { } + virtual void OnPluginUnpause(PluginId id) + { + } /** * @brief Called when the level is loaded (after GameInit, before ServerActivate). @@ -195,7 +209,9 @@ public: /** * @brief Called when the level is shut down. May be called more than once. */ - virtual void OnLevelShutdown() { } + virtual void OnLevelShutdown() + { + } /** * @brief Called when engineFactory() is used through Metamod:Source's wrapper. @@ -308,7 +324,8 @@ public: * This callback is provided to all plugins regardless of which (or how many) * called EnableVSPListener(), but only if at least one did in fact enable it. * - * This callback is only available for plugins using API v1:5 (SourceMM 1.4+). + * This callback is only available for plugins using API v1:5 (Metamod:Source 1.4+). + * If a plugin loads lately, it may still call EnableVSPListener(). * * @param iface Interface pointer. If NULL, then the VSP listening construct * failed to initialize and is not available. @@ -317,7 +334,8 @@ public: { } - /* @brief Called when Metamod:Source is about to remove a concommand or convar. + /** + * @brief Called when Metamod:Source is about to remove a concommand or convar. * This can also be called if ISmmAPI::UnregisterConCmdBase is used by a plugin. * * @param id Id of the plugin that created the concommand or convar. diff --git a/sourcemm/sourcemm.cpp b/sourcemm/sourcemm.cpp index 8e08cd5..477ef17 100644 --- a/sourcemm/sourcemm.cpp +++ b/sourcemm/sourcemm.cpp @@ -60,6 +60,7 @@ SourceHook::CallClass *g_GameDllPatch; int g_GameDllVersion = 0; int g_GameClientsVersion = 0; int g_VspVersion = 0; +int g_SourceEngineVersion = SOURCE_ENGINE_ORIGINAL; const char VSPIFACE[] = "ISERVERPLUGINCALLBACKS"; const char GAMEINFO_PATH[] = "|gameinfo_path|"; @@ -218,7 +219,7 @@ SMM_API void *CreateInterface(const char *iface, int *ret) /* Prevent loading of self as a SourceMM plugin or Valve server plugin :x */ if (strcmp(iface, PLAPI_NAME) == 0) { - Warning("Do not try loading Metamod:Source as a SourceMM or Valve server plugin.\n"); + Warning("Do not try loading Metamod:Source as a plugin.\n"); if (ret) { @@ -388,16 +389,18 @@ SMM_API void *CreateInterface(const char *iface, int *ret) { /* This is the interface we want! Right now we support versions 3 through 8 */ g_GameDllVersion = atoi(&(iface[len])); - int sizeTooBig = 0; //rename this to sizeWrong in the future! - if (g_GameDllVersion < MIN_GAMEDLL_VERSION || g_GameDllVersion > MAX_GAMEDLL_VERSION) + if (g_GameDllVersion < MIN_GAMEDLL_VERSION) { - /* Maybe this will get used in the future */ - sizeTooBig = g_GameDllVersion; if (ret) { *ret = IFACE_FAILED; } } + else if (g_GameDllVersion > 3) + { + /* The engine is at least episode 1 */ + g_SourceEngineVersion = SOURCE_ENGINE_EPISODEONE; + } SourceHook::List::iterator iter; GameDllInfo *pInfo = NULL; void *ptr; @@ -418,21 +421,12 @@ SMM_API void *CreateInterface(const char *iface, int *ret) } if (g_GameDll.loaded) { - if (sizeTooBig) - { - Error("This mod version requires a SourceMM update (ServerGameDLL%03d)!\n", sizeTooBig); - if (ret) - { - *ret = IFACE_FAILED; - } - return NULL; - } else { - InitMainStates(); - } + InitMainStates(); } else { - sizeTooBig = 0; if (ret) + { *ret = IFACE_FAILED; + } return NULL; } } else { diff --git a/sourcemm/sourcemm.h b/sourcemm/sourcemm.h index 33b0c40..24bf5fd 100644 --- a/sourcemm/sourcemm.h +++ b/sourcemm/sourcemm.h @@ -32,21 +32,18 @@ * increase api_major when API breaks * increase api_minor when new functions are added (non-breaking) */ -#define SOURCEMM_VERSION SVN_FILE_VERSION_STRING -#define SOURCEMM_DATE __DATE__ -#define SM_VERS_API_MAJOR 1 //increase this on a breaking change -#define SM_VERS_API_MINOR 6 //increase this on a non-breaking API change +#define SOURCEMM_VERSION SVN_FILE_VERSION_STRING +#define SOURCEMM_DATE __DATE__ +#define SM_VERS_API_MAJOR 1 //increase this on a breaking change +#define SM_VERS_API_MINOR 7 //increase this on a non-breaking API change -//We need a good CServerGameDLL version to work properly. We support these inclusively. +/* We need a good CServerGameDLL version to work properly. We support these inclusively. */ #define MIN_GAMEDLL_VERSION 3 -#define MAX_GAMEDLL_VERSION 8 /* Maximum version of IServerPluginCallbacks that SourceMM supports */ #define MAX_VSP_VERSION 2 -/** - * @brief Entry point for HL2 Engine - */ +/** @brief Entry point for HL2 Engine */ SMM_API void *CreateInterface(const char *name, int *code); /** @brief Wrapper to catch GameDLL calls */ @@ -123,6 +120,9 @@ extern int g_VspVersion; /** @brief IServerGameClients version the mod uses */ extern int g_GameClientsVersion; +/** @brief Source Engine version */ +extern int g_SourceEngineVersion; + extern bool bGameInit; /** @brief Global CallClass for IServerGameDLL */