From 34af81a7d85e986f8acd7f4f10f098738a5a7c0c 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(-) diff --git a/NorthstarDLL/core/convar/convar.cpp b/NorthstarDLL/core/convar/convar.cpp index 6646729a..d4efc1a0 100644 --- a/NorthstarDLL/core/convar/convar.cpp +++ b/NorthstarDLL/core/convar/convar.cpp @@ -497,40 +497,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