From 6509983350223d7529d978293a341ffb53ecec96 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:08:38 +0200 Subject: [PATCH] ModSystem: implement ParseConVars properly The implementation was commented as it was unfinished. The code now properly checks if the convar was already registered. The code now also deallocates the convar memory on shutdown. --- src/pluginsystem/modsystem.cpp | 126 +++++++++++++++++++-------------- src/pluginsystem/modsystem.h | 3 +- 2 files changed, 76 insertions(+), 53 deletions(-) diff --git a/src/pluginsystem/modsystem.cpp b/src/pluginsystem/modsystem.cpp index 3ab6e7b1..38c7aa87 100644 --- a/src/pluginsystem/modsystem.cpp +++ b/src/pluginsystem/modsystem.cpp @@ -156,7 +156,7 @@ void CModSystem::WriteModStatusList() kv.RecursiveSaveToFile(buf, 0); if (!FileSystem()->WriteFile(MOD_STATUS_LIST_FILE, "PLATFORM", buf)) - Error(eDLL_T::ENGINE, NO_ERROR, "Failed to write mod status list '%s'\n", MOD_STATUS_LIST_FILE); + Error(eDLL_T::ENGINE, NO_ERROR, "Failed to write mod status list '%s'.\n", MOD_STATUS_LIST_FILE); } //----------------------------------------------------------------------------- @@ -180,7 +180,7 @@ CModSystem::ModInstance_t::ModInstance_t(const CUtlString& basePath) } // parse any additional info from mod.vdf - //ParseConVars(); + ParseConVars(); ParseLocalizationFiles(); // add mod folder to search paths so files can be easily loaded from here @@ -209,6 +209,8 @@ CModSystem::ModInstance_t::~ModInstance_t() { if (m_SettingsKV) delete m_SettingsKV; + + m_ConVars.PurgeAndDeleteElements(); } //----------------------------------------------------------------------------- @@ -279,56 +281,76 @@ bool CModSystem::ModInstance_t::ParseSettings() //----------------------------------------------------------------------------- // Purpose: parses and registers convars listed in settings KV //----------------------------------------------------------------------------- -//void CModSystem::ModInstance_t::ParseConVars() -//{ -// Assert(m_SettingsKV); -// KeyValues* pConVars = m_SettingsKV->FindKey("ConVars"); -// -// if (pConVars) -// { -// for (KeyValues* pSubKey = pConVars->GetFirstSubKey(); -// pSubKey != nullptr; pSubKey = pSubKey->GetNextKey()) -// { -// const char* pszName = pSubKey->GetName(); -// const char* pszFlagsString = pSubKey->GetString("flags", "NONE"); -// const char* pszHelpString = pSubKey->GetString("helpText"); -// const char* pszUsageString = pSubKey->GetString("usageText"); -// -// KeyValues* pValues = pSubKey->FindKey("Values"); -// -// const char* pszDefaultValue = "0"; -// bool bMin = false; -// bool bMax = false; -// float fMin = 0.f; -// float fMax = 0.f; -// -// if (pValues) -// { -// pszDefaultValue = pValues->GetString("default", "0"); -// -// // minimum cvar value -// if (pValues->FindKey("min")) -// { -// bMin = true; // has min value -// fMin = pValues->GetFloat("min", 0.f); -// } -// -// // maximum cvar value -// if (pValues->FindKey("max")) -// { -// bMax = true; // has max value -// fMax = pValues->GetFloat("max", 1.f); -// } -// } -// -// int flags = FCVAR_NONE; -// -// if (ConVar_ParseFlagString(pszFlagsString, flags, pszName)) -// ConVar::StaticCreate(pszName, pszDefaultValue, flags, -// pszHelpString, bMin, fMin, bMax, fMax, nullptr, pszUsageString); -// } -// } -//} +void CModSystem::ModInstance_t::ParseConVars() +{ + Assert(m_SettingsKV); + KeyValues* pConVars = m_SettingsKV->FindKey("ConVars"); + + if (pConVars) + { + for (KeyValues* pSubKey = pConVars->GetFirstSubKey(); + pSubKey != nullptr; pSubKey = pSubKey->GetNextKey()) + { + const char* pszName = pSubKey->GetName(); + const char* pszFlagsString = pSubKey->GetString("flags", "NONE"); + const char* pszHelpString = pSubKey->GetString("helpText"); + const char* pszUsageString = pSubKey->GetString("usageText"); + + KeyValues* pValues = pSubKey->FindKey("Values"); + + const char* pszDefaultValue = "0"; + bool bMin = false; + bool bMax = false; + float fMin = 0.f; + float fMax = 0.f; + + if (pValues) + { + pszDefaultValue = pValues->GetString("default", "0"); + + // minimum cvar value + if (pValues->FindKey("min")) + { + bMin = true; // has min value + fMin = pValues->GetFloat("min", 0.f); + } + + // maximum cvar value + if (pValues->FindKey("max")) + { + bMax = true; // has max value + fMax = pValues->GetFloat("max", 1.f); + } + } + + int flags = FCVAR_NONE; + + if (ConVar_ParseFlagString(pszFlagsString, flags, pszName)) + { + if (g_pCVar->FindCommandBase(pszName) != nullptr) + { + Warning(eDLL_T::ENGINE, NO_ERROR, "Failed to register ConVar '%s' for mod '%s' ('%s'); already registered.\n", + pszName, m_Name.String(), m_ModID.String()); + + continue; + } + + ConVar* cvar = new ConVar(pszName, pszDefaultValue, flags, pszHelpString, bMin, fMin, bMax, fMax, nullptr, pszUsageString); + + if (!cvar) + { + // Quit as we ran out of memory. + Error(eDLL_T::ENGINE, EXIT_FAILURE, "Failed to register ConVar '%s' for mod '%s' ('%s'); allocation failure.\n", + pszName, m_Name.String(), m_ModID.String()); + + return; + } + + m_ConVars.AddToTail(cvar); + } + } + } +} //----------------------------------------------------------------------------- // Purpose: parses and stores localization file paths in a vector diff --git a/src/pluginsystem/modsystem.h b/src/pluginsystem/modsystem.h index 2a336dc1..bfbd3be6 100644 --- a/src/pluginsystem/modsystem.h +++ b/src/pluginsystem/modsystem.h @@ -29,7 +29,7 @@ public: ~ModInstance_t(); bool ParseSettings(); - //void ParseConVars(); + void ParseConVars(); void ParseLocalizationFiles(); inline void SetState(eModState state) { m_iState = state; }; @@ -52,6 +52,7 @@ public: bool m_bHasScriptCompileList; // if this mod has a scripts.rson file that exists CUtlVector m_LocalizationFiles; + CUtlVector m_ConVars; CUtlString m_Name; CUtlString m_ModID;