diff --git a/core/IPluginManager.h b/core/IPluginManager.h index ac0b7c03..10bb0928 100644 --- a/core/IPluginManager.h +++ b/core/IPluginManager.h @@ -34,6 +34,72 @@ */ #include +#include + +#if defined META_IS_SOURCE2 +#include +#include +class ConCommandBase +{ +public: + ConCommandBase(const ConVarCreation_t& creation, int64_t nAdditionalFlags, const ConVarHandle& handle) : + m_bIsCvar(true), + m_Name(creation.m_pszName), + m_nAdditionalFlags(nAdditionalFlags), + m_Handle(handle), + m_Creation(creation) + {} + + ConCommandBase(const ConCommandCreation_t& creation, int64_t nAdditionalFlags, const ConCommandHandle& handle) : + m_bIsCvar(false), + m_Name(creation.m_pszName), + m_nAdditionalFlags(nAdditionalFlags), + m_Handle(handle), + m_Creation(creation) + {} + + const char* GetName() const { return m_Name.c_str(); } + bool IsConVar() const { return m_bIsCvar; } + + ConVarHandle GetConVar() { return m_Handle.cvar; } + ConCommandHandle GetConCommand() { return m_Handle.cmd; } + + ConVarCreation_t& GetConVarCreation() { return m_Creation.cvar; } + ConCommandCreation_t& GetConCommandCreation() { return m_Creation.cmd; } + + int64_t GetAdditionalFlags() const { return m_nAdditionalFlags; } +protected: + bool m_bIsCvar; + std::string m_Name; + int64_t m_nAdditionalFlags; + + union ConCommandBaseHandle { + ConCommandBaseHandle(ConVarHandle handle) : + cvar(handle) + {} + + ConCommandBaseHandle(ConCommandHandle handle) : + cmd(handle) + {} + + ConVarHandle cvar; + ConCommandHandle cmd; + } m_Handle; + + union ConCommandBaseCreation { + ConCommandBaseCreation(const ConVarCreation_t& handle) : + cvar(handle) + {} + + ConCommandBaseCreation(const ConCommandCreation_t& handle) : + cmd(handle) + {} + + ConVarCreation_t cvar; + ConCommandCreation_t cmd; + } m_Creation; +}; +#endif namespace SourceMM { diff --git a/core/metamod.cpp b/core/metamod.cpp index bfe44d09..f30042e5 100644 --- a/core/metamod.cpp +++ b/core/metamod.cpp @@ -78,9 +78,33 @@ static bool is_game_init = false; static bool vsp_load_requested = false; static bool vsp_loaded = false; static game_dll_t gamedll_info; -static MetamodSourceConVar *metamod_version = NULL; -static MetamodSourceConVar *mm_pluginsfile = NULL; -static MetamodSourceConVar *mm_basedir = NULL; + +static MetamodSourceConVar metamod_version("metamod_version", + ConVarFlag_Notify|ConVarFlag_SpOnly, + "Metamod:Source Version", + METAMOD_VERSION +); + +static MetamodSourceConVar mm_pluginsfile("mm_pluginsfile", + ConVarFlag_SpOnly, + "Metamod:Source Plugins File", +#if defined WIN32 || defined _WIN32 + "addons\\metamod\\metaplugins.ini" +#else + "addons/metamod/metaplugins.ini" +#endif +); + +static MetamodSourceConVar mm_basedir("mm_basedir", + ConVarFlag_SpOnly, + "Metamod:Source Base Folder", +#if defined __linux__ || defined __APPLE__ + "addons/metamod" +#else + "addons\\metamod" +#endif +); + static CreateInterfaceFn engine_factory = NULL; static CreateInterfaceFn physics_factory = NULL; static CreateInterfaceFn filesystem_factory = NULL; @@ -180,12 +204,12 @@ static class ProviderCallbacks : public IMetamodSourceProviderCallbacks sizeof(filepath), "%s/%s", mod_path.c_str(), - provider->GetConVarString(mm_pluginsfile)); + mm_pluginsfile.GetValue()); g_Metamod.PathFormat(vdfpath, sizeof(vdfpath), "%s/%s", mod_path.c_str(), - provider->GetConVarString(mm_basedir)); + mm_basedir.GetValue()); mm_LoadPlugins(filepath, vdfpath); } else @@ -438,7 +462,7 @@ DoInitialPluginLoads() const char *mmBaseDir = provider->GetCommandLineValue("mm_basedir", NULL); if (!pluginFile) { - pluginFile = provider->GetConVarString(mm_pluginsfile); + pluginFile = mm_pluginsfile.GetValue(); if (pluginFile == NULL) { pluginFile = "addons/metamod/metaplugins.ini"; @@ -446,7 +470,7 @@ DoInitialPluginLoads() } if (!mmBaseDir) { - mmBaseDir = provider->GetConVarString(mm_basedir); + mmBaseDir = mm_basedir.GetValue(); if (mmBaseDir == NULL) { mmBaseDir = "addons/metamod"; @@ -471,30 +495,8 @@ mm_StartupMetamod(bool is_vsp_load) METAMOD_VERSION, is_vsp_load ? "V" : ""); - metamod_version = provider->CreateConVar("metamod_version", - METAMOD_VERSION, - "Metamod:Source Version", - ConVarFlag_Notify|ConVarFlag_SpOnly); - - provider->SetConVarString(metamod_version, buffer); - - mm_pluginsfile = provider->CreateConVar("mm_pluginsfile", -#if defined WIN32 || defined _WIN32 - "addons\\metamod\\metaplugins.ini", -#else - "addons/metamod/metaplugins.ini", -#endif - "Metamod:Source Plugins File", - ConVarFlag_SpOnly); - - mm_basedir = provider->CreateConVar("mm_basedir", -#if defined __linux__ || defined __APPLE__ - "addons/metamod", -#else - "addons\\metamod", -#endif - "Metamod:Source Base Folder", - ConVarFlag_SpOnly); + // TO-DO + // ConVar register here.... g_bIsVspBridged = is_vsp_load; @@ -881,12 +883,12 @@ const char *MetamodSource::GetGameBinaryPath() const char *MetamodSource::GetPluginsFile() { - return provider->GetConVarString(mm_pluginsfile); + return mm_pluginsfile.GetValue(); } const char *MetamodSource::GetVDFDir() { - return provider->GetConVarString(mm_basedir); + return mm_basedir.GetValue(); } bool MetamodSource::RegisterConCommandBase(ISmmPlugin *plugin, ConCommandBase *pCommand) diff --git a/core/metamod_convar.h b/core/metamod_convar.h new file mode 100644 index 00000000..f6e7bdd0 --- /dev/null +++ b/core/metamod_convar.h @@ -0,0 +1,129 @@ +#pragma once + +#include +#include + +#include + +template +class MetamodSourceConVar; + +enum EMetaConVarType : int16_t +{ + EMetaConVarType_Invalid = -1, + EMetaConVarType_Bool, + EMetaConVarType_Int16, + EMetaConVarType_UInt16, + EMetaConVarType_Int32, + EMetaConVarType_UInt32, + EMetaConVarType_Int64, + EMetaConVarType_UInt64, + EMetaConVarType_Float32, + EMetaConVarType_Float64, + EMetaConVarType_String, + EMetaConVarType_Color, + EMetaConVarType_Vector2, + EMetaConVarType_Vector3, + EMetaConVarType_Vector4, + EMetaConVarType_Qangle, + EMetaConVarType_MAX +}; + +template +constexpr EMetaConVarType TranslateMetaConVarType(); + +struct MetamodConVarCreation_t +{ + std::string m_name; + std::string m_help; + int32_t m_flags; + + EMetaConVarType m_type; + + template + T& DefaultValue() { return *reinterpret_cast(m_defaultValue); } + template + T& MinValue() { return *reinterpret_cast(m_minValue); } + template + T& MaxValue() { return *reinterpret_cast(m_maxValue); } + + uint8_t m_defaultValue[sizeof(CVValue_t)]; + uint8_t m_minValue[sizeof(CVValue_t)]; + uint8_t m_maxValue[sizeof(CVValue_t)]; + + bool m_hasDefault; + bool m_hasMin; + bool m_hasMax; + + void* m_changeCallback; + void** m_conVar; + + template + MetamodConVarCreation_t(const char* name, int32_t flags, const char* help, const T& value, void* cb = nullptr) : + m_name(name), + m_help(help), + m_flags(flags), + m_type(TranslateMetaConVarType()), + m_hasDefault(true), + m_changeCallback(cb) + { + DefaultValue() = value; + } + + template + MetamodConVarCreation_t(const char* name, int32_t flags, const char* help, const T& value, bool min, const T& minValue, bool max, const T& maxValue, void* cb = nullptr) : + m_name(name), + m_help(help), + m_flags(flags), + m_type(TranslateMetaConVarType()), + m_hasDefault(true), + m_hasMin(min), + m_hasMax(max), + m_changeCallback(cb) + { + DefaultValue() = value; + MinValue() = minValue; + MaxValue() = maxValue; + } +}; + +// For backwards compatibility +template +class MetamodSourceConVar +{ +private: +#if defined META_IS_SOURCE2 + using FnConVarChangeCallback_t = void(*)(ConVar* ref, const CSplitScreenSlot nSlot, const T* pNewValue, const T* pOldValue); + ConVar* m_ConVar; +#else + using FnConVarChangeCallback_t = void(*)(IConVar* var, const char* pOldValue, float flOldValue); + ConVar* m_ConVar; +#endif + +public: + + MetamodSourceConVar(const char* name, int32_t flags, const char* help, const T& value, FnConVarChangeCallback_t cb = nullptr); + MetamodSourceConVar(const char* name, int32_t flags, const char* help, const T& value, bool min, const T& minValue, bool max, const T& maxValue, FnConVarChangeCallback_t cb = nullptr); + + inline const T GetValue( ) const; + inline const T GetDefaultValue( ) const; + inline const T GetMinValue( ) const; + inline const T GetMaxValue( ) const; + + inline void SetDefaultValue( const T& value ); + inline void SetMinValue( const T& value ); + inline void SetMaxValue( const T& value ); + + inline void RemoveDefaultValue( ); + inline void RemoveMinValue( ); + inline void RemoveMaxValue( ); + + inline void GetStringValue( char* dst, size_t len, int index = 0 ) const; + inline void GetStringDefaultValue( char* dst, size_t len ) const; + inline void GetStringMinValue( char* dst, size_t len ) const; + inline void GetStringMaxValue( char* dst, size_t len ) const; + + int yes[offset_of, &MetamodSourceConVar::yes>()]; +}; + +#include "metamod_convar.hxx" \ No newline at end of file diff --git a/core/metamod_convar.hxx b/core/metamod_convar.hxx new file mode 100644 index 00000000..b17e2325 --- /dev/null +++ b/core/metamod_convar.hxx @@ -0,0 +1,121 @@ +#pragma once + +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_Bool; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_Int16; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_UInt16; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_Int32; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_UInt32; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_Int64; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_UInt64; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_Float32; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_Float64; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ){ return EMetaConVarType_String; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_Color; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_Vector2; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_Vector3; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_Vector4; } +template<> constexpr EMetaConVarType TranslateMetaConVarType( void ) { return EMetaConVarType_Qangle; } + +template +MetamodSourceConVar::MetamodSourceConVar(const char* name, int32_t flags, const char* help, const T& value, FnConVarChangeCallback_t cb) : +m_ConVar(nullptr) +{ + MetamodConVarCreation_t create(name, flags, help, value, reinterpret_cast(cb)); +} + +template +MetamodSourceConVar::MetamodSourceConVar(const char* name, int32_t flags, const char* help, const T& value, bool min, const T& minValue, bool max, const T& maxValue, FnConVarChangeCallback_t cb) : +m_ConVar(nullptr) +{ + MetamodConVarCreation_t create(name, flags, help, value, cb, min, minValue, max, maxValue, reinterpret_cast(cb)); +} + +#if defined META_IS_SOURCE2 +template +inline const T MetamodSourceConVar::GetValue() const +{ + return m_ConVar->GetValue(); +} + +template +inline const T MetamodSourceConVar::GetDefaultValue( ) const +{ + return m_ConVar->GetDefaultValue( ); +} + +template +inline const T MetamodSourceConVar::GetMinValue( ) const +{ + return m_ConVar->GetMinValue( ); +} + +template +inline const T MetamodSourceConVar::GetMaxValue( ) const +{ + return m_ConVar->GetMaxValue( ); +} + +template +inline void MetamodSourceConVar::SetDefaultValue( const T& value ) +{ + m_ConVar->SetDefaultValue( value ); +} + +template +inline void MetamodSourceConVar::SetMinValue( const T& value ) +{ + m_ConVar->SetMinValue( value ); +} + +template +inline void MetamodSourceConVar::SetMaxValue( const T& value ) +{ + m_ConVar->SetMaxValue( value ); +} + +template +inline void MetamodSourceConVar::RemoveDefaultValue( ) +{ + m_ConVar->RemoveDefaultValue( ); +} + +template +inline void MetamodSourceConVar::RemoveMinValue( ) +{ + m_ConVar->RemoveMinValue( ); +} + +template +inline void MetamodSourceConVar::RemoveMaxValue( ) +{ + m_ConVar->RemoveMaxValue( ); +} + +template +inline void MetamodSourceConVar::GetStringValue( char* dst, size_t len, int index ) const +{ + m_ConVar->GetStringValue( dst, len, index ); +} + +template +inline void MetamodSourceConVar::GetStringDefaultValue( char* dst, size_t len ) const +{ + m_ConVar->GetStringDefaultValue( dst, len ); +} + +template +inline void MetamodSourceConVar::GetStringMinValue( char* dst, size_t len ) const +{ + m_ConVar->GetStringMinValue( dst, len ); +} + +template +inline void MetamodSourceConVar::GetStringMaxValue( char* dst, size_t len ) const +{ + m_ConVar->GetStringMaxValue( dst, len ); +} +#else + + + +#endif \ No newline at end of file diff --git a/core/metamod_provider.h b/core/metamod_provider.h index 2c12a2e4..e4cda146 100644 --- a/core/metamod_provider.h +++ b/core/metamod_provider.h @@ -26,10 +26,10 @@ #ifndef _INCLUDE_METAMOD_SOURCE_SUPPORT_H_ #define _INCLUDE_METAMOD_SOURCE_SUPPORT_H_ +#include "metamod_convar.h" + namespace SourceMM { - class MetamodSourceConVar; - enum { ConVarFlag_None = 0, @@ -208,36 +208,6 @@ namespace SourceMM */ virtual void ServerCommand(const char *cmd) =0; - /** - * @brief Creates a ConVar pointer. - * - * @param name ConVar name. - * @param defval Default value string. - * @param flags ConVar flags. - * @param help Help text. - * @return ConVar pointer. - */ - virtual MetamodSourceConVar *CreateConVar(const char *name, - const char *defval, - const char *help, - int flags) =0; - - /** - * @brief Returns the string value of a ConVar. - * - * @param convar ConVar pointer. - * @return String value. - */ - virtual const char *GetConVarString(MetamodSourceConVar *convar) =0; - - /** - * @brief Sets a ConVar string. - * - * @param convar ConVar pointer. - * @param str String pointer. - */ - virtual void SetConVarString(MetamodSourceConVar *convar, const char *str) =0; - /** * @brief Retrieves the absolute path to the game directory. * diff --git a/core/provider/provider_base.h b/core/provider/provider_base.h index 413a5cf1..ac00c79f 100644 --- a/core/provider/provider_base.h +++ b/core/provider/provider_base.h @@ -62,12 +62,6 @@ class BaseProvider : public IMetamodSourceProvider virtual void ConsolePrint(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, - const char* help, - int flags) override = 0; - virtual const char* GetConVarString(MetamodSourceConVar *convar) override = 0; - virtual void SetConVarString(MetamodSourceConVar *convar, const char* str) override = 0; virtual bool RegisterConCommandBase(ConCommandBase* pCommand) override = 0; virtual void UnregisterConCommandBase(ConCommandBase* pCommand) override = 0; virtual bool IsConCommandBaseACommand(ConCommandBase* pCommand) override = 0; diff --git a/core/provider/source2/provider_source2.cpp b/core/provider/source2/provider_source2.cpp index ef05448f..0a7305e2 100644 --- a/core/provider/source2/provider_source2.cpp +++ b/core/provider/source2/provider_source2.cpp @@ -265,76 +265,36 @@ void Source2Provider::ServerCommand(const char* cmd) engine->ServerCommand(cmd); } -const char* Source2Provider::GetConVarString(MetamodSourceConVar *convar) -{ -#ifdef S2_CONVAR_UNFINISHED - if (convar == NULL) - { - return NULL; - } - - return convar->GetString(); -#else - return nullptr; -#endif -} - -void Source2Provider::SetConVarString(MetamodSourceConVar *convar, const char* str) -{ -#ifdef S2_CONVAR_UNFINISHED - convar->SetValue(str); -#endif -} - bool Source2Provider::IsConCommandBaseACommand(ConCommandBase* pCommand) { -#ifdef S2_CONVAR_UNFINISHED - return pCommand->IsCommand(); -#else - return false; -#endif + return !pCommand->IsConVar(); } bool Source2Provider::RegisterConCommandBase(ConCommandBase* pCommand) { -#ifdef S2_CONVAR_UNFINISHED - return g_SMConVarAccessor.Register(pCommand); -#else + if (pCommand->IsConVar()) + { + auto& creation = pCommand->GetConVarCreation(); + icvar->RegisterConVar(creation, pCommand->GetAdditionalFlags(), creation.m_pHandle, creation.m_pConVarData); + } + else + { + auto& creation = pCommand->GetConCommandCreation(); + *creation.m_pHandle = icvar->RegisterConCommand(creation, pCommand->GetAdditionalFlags()); + } return true; -#endif } void Source2Provider::UnregisterConCommandBase(ConCommandBase* pCommand) { -#ifdef S2_CONVAR_UNFINISHED - return g_SMConVarAccessor.Unregister(pCommand); -#endif -} - -MetamodSourceConVar* Source2Provider::CreateConVar(const char* name, - const char* defval, - const char* help, - int flags) -{ -#ifdef S2_CONVAR_UNFINISHED - int newflags = 0; - if (flags & ConVarFlag_Notify) + if (pCommand->IsConVar()) { - newflags |= FCVAR_NOTIFY; + icvar->UnregisterConVar(pCommand->GetConVar()); } - if (flags & ConVarFlag_SpOnly) + else { - newflags |= FCVAR_SPONLY; + icvar->UnregisterConCommand(pCommand->GetConCommand()); } - - ConVar* pVar = new ConVar(name, defval, newflags, help); - - g_SMConVarAccessor.RegisterConCommandBase(pVar); - - return pVar; -#else - return nullptr; -#endif } class GlobCommand : public IMetamodSourceCommandInfo @@ -453,4 +413,4 @@ void Source2Provider::Hook_ClientCommand(CPlayerSlot nSlot, const CCommand& _cmd } RETURN_META(MRES_IGNORED); -} +} \ No newline at end of file diff --git a/core/provider/source2/provider_source2.h b/core/provider/source2/provider_source2.h index 6f833112..0567a69f 100644 --- a/core/provider/source2/provider_source2.h +++ b/core/provider/source2/provider_source2.h @@ -55,12 +55,6 @@ class Source2Provider : public BaseProvider virtual void ConsolePrint(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, - const char* help, - int flags) override; - virtual const char* GetConVarString(MetamodSourceConVar *convar) override; - virtual void SetConVarString(MetamodSourceConVar *convar, const char* str) override; virtual bool RegisterConCommandBase(ConCommandBase* pCommand) override; virtual void UnregisterConCommandBase(ConCommandBase* pCommand) override; virtual bool IsConCommandBaseACommand(ConCommandBase* pCommand) override;