From 454943b55950f301503f517fad072ad9ef8b628f Mon Sep 17 00:00:00 2001 From: TotallyNotElite Date: Thu, 26 Nov 2020 12:41:10 +0100 Subject: [PATCH] Fix: Fix default variable values being set incorrectly when preloading This only affects the "Key" type because of SDL Incorrect default variables means that all keys will be unbound as soon as a config file is loaded. This commit essentially replaces e9b9cf16b17f0f42d14e80c97a6bf2577a730228 --- include/settings/Bool.hpp | 2 +- include/settings/Float.hpp | 2 +- include/settings/Int.hpp | 2 +- include/settings/Key.hpp | 5 ++++- include/settings/Manager.hpp | 6 +++--- include/settings/Registered.hpp | 6 ++---- include/settings/Rgba.hpp | 2 +- include/settings/Settings.hpp | 5 ++--- include/settings/String.hpp | 2 +- src/hack.cpp | 4 ++++ src/settings/Manager.cpp | 26 +++++++++++++++----------- src/settings/Registered.cpp | 5 ----- 12 files changed, 35 insertions(+), 32 deletions(-) diff --git a/include/settings/Bool.hpp b/include/settings/Bool.hpp index f6c8e73a..220b843c 100644 --- a/include/settings/Bool.hpp +++ b/include/settings/Bool.hpp @@ -27,7 +27,7 @@ public: return VariableType::BOOL; } - void fromString(const std::string &string) override + void fromString(const std::string &string, bool = false) override { if (string == "0" || string == "false") setInternal(false); diff --git a/include/settings/Float.hpp b/include/settings/Float.hpp index e48ddfb2..dabcb298 100644 --- a/include/settings/Float.hpp +++ b/include/settings/Float.hpp @@ -19,7 +19,7 @@ public: return VariableType::FLOAT; } - void fromString(const std::string &string) override + void fromString(const std::string &string, bool = false) override { errno = 0; auto next = std::strtof(string.c_str(), nullptr); diff --git a/include/settings/Int.hpp b/include/settings/Int.hpp index 0a520c63..058a7e2b 100644 --- a/include/settings/Int.hpp +++ b/include/settings/Int.hpp @@ -19,7 +19,7 @@ public: return VariableType::INT; } - void fromString(const std::string &string) override + void fromString(const std::string &string, bool = false) override { errno = 0; auto result = std::strtol(string.c_str(), nullptr, 10); diff --git a/include/settings/Key.hpp b/include/settings/Key.hpp index b9fb43b5..47eb241f 100644 --- a/include/settings/Key.hpp +++ b/include/settings/Key.hpp @@ -32,7 +32,7 @@ public: } // Valid inputs: "Mouse1", "Mouse5", "Key 6", "Key 10", "Key 2", "Space". - void fromString(const std::string &string) override + void fromString(const std::string &string, bool init = false) override { if (string == "") { @@ -57,6 +57,9 @@ public: } setInternal(key); + // This is broken otherwise + if (init) + this->string = string; } // Variable & causes segfault with gcc optimizations + these dont even diff --git a/include/settings/Manager.hpp b/include/settings/Manager.hpp index 5c5029d3..4a8f76dc 100644 --- a/include/settings/Manager.hpp +++ b/include/settings/Manager.hpp @@ -29,10 +29,10 @@ class Manager public: struct VariableDescriptor { - explicit VariableDescriptor(IVariable &variable); - VariableDescriptor(IVariable &variable, std::string value); + VariableDescriptor(IVariable &variable); bool isChanged(); + void applyDefaults(); IVariable &variable; std::string defaults{}; @@ -43,7 +43,7 @@ public: public: void add(IVariable &me, std::string name); - void add(IVariable &me, std::string name, std::string value); + void applyDefaults(); IVariable *lookup(const std::string &string); std::unordered_map registered{}; diff --git a/include/settings/Registered.hpp b/include/settings/Registered.hpp index 0ff00d75..79d04690 100644 --- a/include/settings/Registered.hpp +++ b/include/settings/Registered.hpp @@ -10,7 +10,6 @@ namespace settings { void registerVariable(IVariable &variable, std::string name); -void registerVariable(IVariable &variable, std::string name, std::string value); template class RegisteredVariableProxy : public Variable { @@ -21,11 +20,10 @@ public: { registerVariable(*this, name); } - RegisteredVariableProxy(std::string name, std::string value) { - this->fromString(value); - registerVariable(*this, name, value); + this->fromString(value, true); + registerVariable(*this, name); } }; diff --git a/include/settings/Rgba.hpp b/include/settings/Rgba.hpp index 552963b3..46853f4f 100644 --- a/include/settings/Rgba.hpp +++ b/include/settings/Rgba.hpp @@ -30,7 +30,7 @@ public: return VariableType::COLOR; } - void fromString(const std::string &string) override + void fromString(const std::string &string, bool = false) override { uint8_t rgba[4] = { 0, 0, 0, 255 }; diff --git a/include/settings/Settings.hpp b/include/settings/Settings.hpp index 99152246..dd8438cb 100644 --- a/include/settings/Settings.hpp +++ b/include/settings/Settings.hpp @@ -55,8 +55,8 @@ public: virtual ~IVariable() = default; // Faster than checking with dynamic_cast - virtual VariableType getType() = 0; - virtual void fromString(const std::string &string) = 0; + virtual VariableType getType() = 0; + virtual void fromString(const std::string &string, bool init = false) = 0; // Const reference because every variable will cache the string value // instead of generating it every call virtual const std::string &toString() = 0; @@ -84,7 +84,6 @@ protected: } std::vector &, T)>> callbacks{}; - T default_value{}; }; template class Variable diff --git a/include/settings/String.hpp b/include/settings/String.hpp index 89fc0614..1edb4fcc 100644 --- a/include/settings/String.hpp +++ b/include/settings/String.hpp @@ -19,7 +19,7 @@ public: return VariableType::STRING; } - void fromString(const std::string &string) override + void fromString(const std::string &string, bool = false) override { fireCallbacks(string); value = string; diff --git a/src/hack.cpp b/src/hack.cpp index 18d5f654..f0f11b15 100644 --- a/src/hack.cpp +++ b/src/hack.cpp @@ -313,6 +313,10 @@ free(logname);*/ #endif CreateEarlyInterfaces(); + + // Applying the defaults needs to be delayed, because preloaded Cathook can not properly convert SDL codes to names before TF2 init + settings::Manager::instance().applyDefaults(); + logging::Info("Clearing Early initializer stack"); while (!init_stack_early().empty()) { diff --git a/src/settings/Manager.cpp b/src/settings/Manager.cpp index f23f43f8..3e788b6a 100644 --- a/src/settings/Manager.cpp +++ b/src/settings/Manager.cpp @@ -24,14 +24,13 @@ void Manager::add(IVariable &me, std::string name) registered.emplace(name, me); } -void Manager::add(IVariable &me, std::string name, std::string value) +// Applying the defaults needs to be delayed, because preloaded Cathook can not properly convert SDL codes to names before TF2 init +void Manager::applyDefaults() { - if (registered.find(name) != registered.end()) + for (auto &variables : registered) { - logging::Info(("Double registering variable: " + name).c_str()); - throw std::runtime_error("Double registering variable: " + name); + variables.second.applyDefaults(); } - registered.emplace(name, Manager::VariableDescriptor{ me, value }); } IVariable *Manager::lookup(const std::string &string) @@ -48,14 +47,19 @@ Manager::VariableDescriptor::VariableDescriptor(IVariable &variable) : variable( defaults = variable.toString(); } -Manager::VariableDescriptor::VariableDescriptor(IVariable &variable, std::string value) : variable(variable) -{ - type = variable.getType(); - defaults = value; -} - bool Manager::VariableDescriptor::isChanged() { return variable.toString() != defaults; } + +// Applying the defaults needs to be delayed, because preloaded Cathook can not properly convert SDL codes to names before TF2 init +void Manager::VariableDescriptor::applyDefaults() +{ + if (type == VariableType::KEY) + { + // Shitcode, this is a pain in the you know what to fix + variable.fromString(variable.toString()); + defaults = variable.toString(); + } +} } // namespace settings diff --git a/src/settings/Registered.cpp b/src/settings/Registered.cpp index f2ebbd93..cc320909 100755 --- a/src/settings/Registered.cpp +++ b/src/settings/Registered.cpp @@ -8,8 +8,3 @@ void settings::registerVariable(IVariable &variable, std::string name) { Manager::instance().add(variable, name); } - -void settings::registerVariable(IVariable &variable, std::string name, std::string value) -{ - Manager::instance().add(variable, name, value); -}