From a3811b32cf20ddff48051767cc7670c3f3a1144a Mon Sep 17 00:00:00 2001 From: Asher Baker Date: Thu, 22 Oct 2015 17:33:34 +0100 Subject: [PATCH] Added ConVar API for extensions. --- core/HalfLife2.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++ core/HalfLife2.h | 33 +++++++++++++++++++- public/IGameHelpers.h | 71 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 174 insertions(+), 2 deletions(-) diff --git a/core/HalfLife2.cpp b/core/HalfLife2.cpp index 179e3fdc0..f9b9a5052 100644 --- a/core/HalfLife2.cpp +++ b/core/HalfLife2.cpp @@ -1291,6 +1291,78 @@ bool CHalfLife2::IsMapValid(const char *map) return FindMap(map) != SMFindMapResult::NotFound; } +const ISMConVar *CHalfLife2::FindConVar(const char *name) +{ + const ConVar *cvar = icvar->FindVar(name); + + if (cvar == NULL || cvar->IsCommand()) + { + return NULL; + } + + return new SMConVar(cvar); +} + +bool SMConVar::IsFlagSet(int flag) const +{ + return m_wrapped->IsFlagSet(flag); +} + +const char *SMConVar::GetName() const +{ + return m_wrapped->GetName(); +} + +const char *SMConVar::GetHelpText() const +{ + return m_wrapped->GetHelpText(); +} + +const char *SMConVar::GetString() const +{ + return m_wrapped->GetString(); +} + +float SMConVar::GetFloat() const +{ + return m_wrapped->GetFloat(); +} + +int SMConVar::GetInt() const +{ + return m_wrapped->GetInt(); +} + +bool SMConVar::GetBool() const +{ + return m_wrapped->GetBool(); +} + +bool SMConVar::GetMin(float &minVal) const +{ + return m_wrapped->GetMin(minVal); +} + +bool SMConVar::GetMax(float &maxVal) const +{ + return m_wrapped->GetMax(maxVal); +} + +const char *SMConVar::GetDefault() const +{ + return m_wrapped->GetDefault(); +} + +void SMConVar::Release() const +{ + delete this; +} + +SMConVar::SMConVar(const ConVar *wrap) +{ + m_wrapped = wrap; +} + // TODO: Add ep1 support for this. (No IServerTools available there) #if SOURCE_ENGINE >= SE_ORANGEBOX string_t CHalfLife2::AllocPooledString(const char *pszValue) diff --git a/core/HalfLife2.h b/core/HalfLife2.h index 811bdcbba..5cb3a0555 100644 --- a/core/HalfLife2.h +++ b/core/HalfLife2.h @@ -49,6 +49,8 @@ #include #include +class ConVar; + namespace SourceMod { class ICommandArgs; } // namespace SourceMod @@ -139,7 +141,35 @@ enum class SMFindMapResult : cell_t { PossiblyAvailable }; -class CHalfLife2 : +class SMConVar : public ISMConVar +{ + friend class CHalfLife2; + +public: + bool IsFlagSet(int flag) const; + + const char *GetName() const; + const char *GetHelpText() const; + + const char *GetString() const; + float GetFloat() const; + int GetInt() const; + bool GetBool() const; + + bool GetMin(float &minVal) const; + bool GetMax(float &maxVal) const; + + const char *GetDefault() const; + + void Release() const; + +protected: + SMConVar(const ConVar *wrap); + + const ConVar *m_wrapped; +}; + +class CHalfLife2 : public SMGlobalClass, public IGameHelpers { @@ -188,6 +218,7 @@ public: //IGameHelpers SMFindMapResult FindMap(char *pMapName, size_t nMapNameMax); SMFindMapResult FindMap(const char *pMapName, char *pFoundMap = NULL, size_t nMapNameMax = 0); bool GetMapDisplayName(const char *pMapName, char *pDisplayname, size_t nMapNameMax); + const ISMConVar *FindConVar(const char *name); #if SOURCE_ENGINE >= SE_ORANGEBOX string_t AllocPooledString(const char *pszValue); #endif diff --git a/public/IGameHelpers.h b/public/IGameHelpers.h index 443a08665..36b399daf 100644 --- a/public/IGameHelpers.h +++ b/public/IGameHelpers.h @@ -40,7 +40,7 @@ */ #define SMINTERFACE_GAMEHELPERS_NAME "IGameHelpers" -#define SMINTERFACE_GAMEHELPERS_VERSION 10 +#define SMINTERFACE_GAMEHELPERS_VERSION 11 class CBaseEntity; class CBaseHandle; @@ -73,6 +73,67 @@ namespace SourceMod unsigned int actual_offset; /**< Actual computed offset. */ }; + /** + * @brief Wrapper class for console variables. + * It is currently only possible to get read-only access to existing ones. + * File a bug if you want setters as well (or to create your own convars). + * + * If you're including the HL2SDK, you should use it's ConVar headers over this class. + */ + class ISMConVar + { + protected: + ISMConVar() {}; + virtual ~ISMConVar() {}; + + public: + /** + * @brief Check if a flag is set on a console variable. + * These values are engine specific, but are generally the same across engines. + * Look in the SDK for the FCVAR_* defines for possible values. + */ + virtual bool IsFlagSet(int flag) const =0; + + virtual const char *GetName() const =0; + virtual const char *GetHelpText() const =0; + + /** + * @brief Various accessors for console variable values. + * GetString is the definitive source. + */ + virtual const char *GetString() const =0; + virtual float GetFloat() const =0; + virtual int GetInt() const =0; + virtual bool GetBool() const =0; + + /** + * @brief Get the minimum value allowed to be set via the console. + * Note that this is only a suggestion and the value can be outside this bound. + * + * @return true if a minimum is configured. + */ + virtual bool GetMin(float &minVal) const =0; + + /** + * @brief Get the maximum value allowed to be set via the console. + * Note that this is only a suggestion and the value can be outside this bound. + * + * @return true if a maximum is configured. + */ + virtual bool GetMax(float &maxVal) const =0; + + /** + * @brief Get the default value the console variable was created with. + */ + virtual const char *GetDefault() const =0; + + /** + * @brief Release the console variable wrapper. + * This MUST be called when you're done. + */ + virtual void Release() const =0; + }; + class IGameHelpers : public SMInterface { public: @@ -335,6 +396,14 @@ namespace SourceMod * on failure. */ virtual bool FindDataMapInfo(datamap_t *pMap, const char *offset, sm_datatable_info_t *pDataTable) =0; + + /** + * @brief Find a console variable by name. You MUST call ISMConVar::Release when you're done. + * + * @param convar Name of console varaible. + * @return Pointer to console varaible wrapper, NULL if it doesn't exist. + */ + virtual const ISMConVar *FindConVar(const char *name) =0; }; }