From b019e0b5f760959363afce134cf1e15efa658ed1 Mon Sep 17 00:00:00 2001 From: pg9182 <96569817+pg9182@users.noreply.github.com> Date: Wed, 19 Apr 2023 18:05:59 -0400 Subject: Fix parsing string ConVar/ConCommand.Flags from `mod.json` (#450) Fix parsing string ConVar/ConCommand.Flags from mod.json The ParseConVarFlagsString function introduced in 64100065b55f79e76542ba689545c60e6fb0dcef (#373) is utterly broken. It only parses the first flag, logs misleading warnings, has an undefined return value in some codepaths, and is somewhat convoluted. Luckily, this doesn't appear to affect most (if not all) existing mods, as they all seem to be using integer values for Flags, which is taken as-is. https://github.com/search?q=path%3A**%2Fmod.json+ConVars+Flags&type=code --- NorthstarDLL/core/convar/convar.cpp | 46 +++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 25 deletions(-) (limited to 'NorthstarDLL/core') diff --git a/NorthstarDLL/core/convar/convar.cpp b/NorthstarDLL/core/convar/convar.cpp index 21fca8c0..1ea27fc0 100644 --- a/NorthstarDLL/core/convar/convar.cpp +++ b/NorthstarDLL/core/convar/convar.cpp @@ -490,40 +490,36 @@ bool ConVar::ClampValue(float& flValue) int ParseConVarFlagsString(std::string modName, std::string sFlags) { - sFlags += '|'; // add additional | so we register the last flag - std::string sCurrentFlag; + int iFlags = 0; + std::stringstream stFlags(sFlags); + std::string sFlag; - for (int i = 0; i < sFlags.length(); i++) + while (std::getline(stFlags, sFlag, '|')) { - if (isspace(sFlags[i])) + // trim the flag + sFlag.erase(sFlag.find_last_not_of(" \t\n\f\v\r") + 1); + sFlag.erase(0, sFlag.find_first_not_of(" \t\n\f\v\r")); + + // skip if empty + if (sFlag.empty()) continue; - // if we encounter a |, add current string as a flag - if (sFlags[i] == '|') + // find the matching flag value + bool ok = false; + for (auto const& flagPair : g_PrintCommandFlags) { - bool bHasFlags = false; - int iCurrentFlags; - - for (auto& flagPair : g_PrintCommandFlags) + if (sFlag == flagPair.second) { - if (!sCurrentFlag.compare(flagPair.second)) - { - iCurrentFlags = flagPair.first; - bHasFlags = true; - break; - } + iFlags |= flagPair.first; + ok = true; + break; } - - if (bHasFlags) - return iCurrentFlags; - else - spdlog::warn("Mod ConCommand {} has unknown flag {}", modName, sCurrentFlag); - - sCurrentFlag = ""; } - else + if (!ok) { - sCurrentFlag += sFlags[i]; + spdlog::warn("Mod ConCommand {} has unknown flag {}", modName, sFlag); } } + + return iFlags; } -- cgit v1.2.3