diff --git a/include/TSettings.h b/include/TSettings.h index 81857fe..11433df 100644 --- a/include/TSettings.h +++ b/include/TSettings.h @@ -17,11 +17,44 @@ // along with this program. If not, see . #pragma once +#include +#include +#include #include #include #include #include +struct ComposedKey { + std::string Category; + std::string Key; + + bool operator==(const ComposedKey& rhs) const { + return (this->Category == rhs.Category && this->Key == rhs.Key); + } +}; + +template <> +struct fmt::formatter : formatter { + auto format(ComposedKey key, format_context& ctx) const; +}; + +inline auto fmt::formatter::format(ComposedKey key, fmt::format_context& ctx) const { + std::string key_metadata = fmt::format("{}::{}", key.Category, key.Key); + return formatter::format(key_metadata, ctx); +} + +namespace std { +template <> +class hash { +public: + std::uint64_t operator()(const ComposedKey& key) const { + std::hash hash_fn; + return hash_fn(key.Category + key.Key); + } +}; +} + struct Settings { using SettingsTypeVariant = std::variant; @@ -78,23 +111,24 @@ struct Settings { SettingsAccessMask // Console read/write permissions >; - std::unordered_map InputAccessMapping { - { "Description", { General_Description, write } }, - { "Tags", { General_Tags, write } }, - { "MaxPlayers", { General_MaxPlayers, write } }, - { "Name", { General_Name, write } }, - { "Map", { General_Map, read } }, - { "AuthKey", { General_AuthKey, noaccess } }, - { "Private", { General_Private, read } }, - { "Port", { General_Port, read } }, - { "MaxCars", { General_MaxCars, write } }, - { "LogChat", { General_LogChat, read } }, - { "Resourcefolder", { General_ResourceFolder, read } }, - { "Debug", { General_Debug, noaccess } }, - { "SendErrorsShowMessage", { Misc_SendErrorsShowMessage, noaccess } }, - { "SendErrors", { Misc_SendErrors, noaccess } }, - { "ImScaredOfUpdates", { Misc_ImScaredOfUpdates, noaccess } } + std::unordered_map InputAccessMapping { + { { "General", "Description" }, { General_Description, write } }, + { { "General", "Tags" }, { General_Tags, write } }, + { { "General", "MaxPlayers" }, { General_MaxPlayers, write } }, + { { "General", "Name" }, { General_Name, write } }, + { { "General", "Map" }, { General_Map, read } }, + { { "General", "AuthKey" }, { General_AuthKey, noaccess } }, + { { "General", "Private" }, { General_Private, read } }, + { { "General", "Port" }, { General_Port, read } }, + { { "General", "MaxCars" }, { General_MaxCars, write } }, + { { "General", "LogChat" }, { General_LogChat, read } }, + { { "General", "ResourceFolder" }, { General_ResourceFolder, read } }, + { { "General", "Debug" }, { General_Debug, noaccess } }, + { { "Misc", "SendErrorsShowMessage" }, { Misc_SendErrorsShowMessage, noaccess } }, + { { "Misc", "SendErrors" }, { Misc_SendErrors, noaccess } }, + { { "Misc", "ImScaredOfUpdates" }, { Misc_ImScaredOfUpdates, noaccess } } }; + /* std::unordered_map InputKeyMapping{ {"Description", General_Description}, @@ -172,25 +206,25 @@ struct Settings { SettingsMap.at(key) = value; } - const std::unordered_map& getACLMap() const { + const std::unordered_map& getACLMap() const { return InputAccessMapping; } - SettingsAccessControl getConsoleInputAccessMapping(const std::string& keyName) { + SettingsAccessControl getConsoleInputAccessMapping(const ComposedKey& keyName) { if (!InputAccessMapping.contains(keyName)) { throw std::logic_error { "Unknown key name accessed in Settings::getConsoleInputAccessMapping" }; } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) { - throw std::logic_error { "Key " + keyName + " is not accessible from within the runtime!" }; + throw std::logic_error { "Setting '" + keyName.Category + " > " + keyName.Key + "' is not accessible from within the runtime!" }; } return InputAccessMapping.at(keyName); } - void setConsoleInputAccessMapping(const std::string& keyName, std::string value) { + void setConsoleInputAccessMapping(const ComposedKey& keyName, std::string value) { if (!InputAccessMapping.contains(keyName)) { throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" }; } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) { - throw std::logic_error { "Key " + keyName + " is not accessible from within the runtime!" }; + throw std::logic_error { "Setting '" + keyName.Category + " > " + keyName.Key + "' is not accessible from within the runtime!" }; } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::read) { - throw std::logic_error { "Key " + keyName + " is not writeable from within the runtime!" }; + throw std::logic_error { "Setting '" + keyName.Category + " > " + keyName.Key + "' is not writeable from within the runtime!" }; } Key key = InputAccessMapping.at(keyName).first; @@ -201,13 +235,13 @@ struct Settings { SettingsMap.at(key) = value; } - void setConsoleInputAccessMapping(const std::string& keyName, int value) { + void setConsoleInputAccessMapping(const ComposedKey& keyName, int value) { if (!InputAccessMapping.contains(keyName)) { throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" }; } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) { - throw std::logic_error { "Key " + keyName + " is not accessible from within the runtime!" }; + throw std::logic_error { "Key '" + keyName.Category + " > " + keyName.Key + "' is not accessible from within the runtime!" }; } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::read) { - throw std::logic_error { "Key " + keyName + " is not writeable from within the runtime!" }; + throw std::logic_error { "Key '" + keyName.Category + " > " + keyName.Key + "' is not writeable from within the runtime!" }; } Key key = InputAccessMapping.at(keyName).first; @@ -218,13 +252,13 @@ struct Settings { SettingsMap.at(key) = value; } - void setConsoleInputAccessMapping(const std::string& keyName, bool value) { + void setConsoleInputAccessMapping(const ComposedKey& keyName, bool value) { if (!InputAccessMapping.contains(keyName)) { throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" }; } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) { - throw std::logic_error { "Key " + keyName + " is not accessible from within the runtime!" }; + throw std::logic_error { "Key '" + keyName.Category + " > " + keyName.Key + "' is not accessible from within the runtime!" }; } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::read) { - throw std::logic_error { "Key " + keyName + " is not writeable from within the runtime!" }; + throw std::logic_error { "Key '" + keyName.Category + " > " + keyName.Key + "' is not writeable from within the runtime!" }; } Key key = InputAccessMapping.at(keyName).first; diff --git a/src/TConsole.cpp b/src/TConsole.cpp index d0ca3af..64eb176 100644 --- a/src/TConsole.cpp +++ b/src/TConsole.cpp @@ -382,10 +382,10 @@ void TConsole::Command_Settings(const std::string&, const std::vector prints current value of specified setting - settings set sets specified setting to value + settings help displays this help + settings list lists all settings + settings get prints current value of specified setting + settings set sets specified setting to value )"; if (args.size() == 0) { @@ -399,27 +399,28 @@ void TConsole::Command_Settings(const std::string&, const std::vector {}' = {}", args.at(1), args.at(2), keyValue)); }, [&args](int keyValue) { - Application::Console().WriteRaw(fmt::format("{} = {}", args.at(1), keyValue)); + Application::Console().WriteRaw(fmt::format("'{} > {}' = {}", args.at(1), args.at(2), keyValue)); }, [&args](bool keyValue) { - Application::Console().WriteRaw(fmt::format("{} = {}", args.at(1), keyValue)); + Application::Console().WriteRaw(fmt::format("'{} > {}' = {}", args.at(1), args.at(2), keyValue)); } }, @@ -439,23 +440,23 @@ void TConsole::Command_Settings(const std::string&, const std::vector {} := {}", args.at(1), args.at(2), std::string(args.at(2)))); }, [&args](int keyValue) { - Application::SettingsSingleton.setConsoleInputAccessMapping(args.at(1), std::stoi(args.at(2))); - Application::Console().WriteRaw(fmt::format("{} := {}", args.at(1), std::stoi(args.at(2)))); + Application::SettingsSingleton.setConsoleInputAccessMapping(ComposedKey(args.at(1), args.at(2)), std::stoi(args.at(2))); + Application::Console().WriteRaw(fmt::format("{} > {} := {}", args.at(1),args.at(2), std::stoi(args.at(2)))); }, [&args](bool keyValue) { // todo: implement other way to convert from string to bool - Application::SettingsSingleton.setConsoleInputAccessMapping(args.at(1), std::stoi(args.at(2))); - Application::Console().WriteRaw(fmt::format("{} := {}", args.at(1), std::stoi(args.at(2)))); + Application::SettingsSingleton.setConsoleInputAccessMapping(ComposedKey(args.at(1), args.at(2)), std::stoi(args.at(2))); + Application::Console().WriteRaw(fmt::format("{} > {} := {}", args.at(1), args.at(2), std::stoi(args.at(2)))); } }, @@ -468,25 +469,25 @@ void TConsole::Command_Settings(const std::string&, const std::vector - for(const auto& [keyName, keyACL] : Application::SettingsSingleton.getACLMap()){ + for(const auto& [composedKey, keyACL] : Application::SettingsSingleton.getACLMap()){ // even though we have the value, we want to ignore it in order to make use of access // control checks try{ - Settings::SettingsAccessControl acl = Application::SettingsSingleton.getConsoleInputAccessMapping(keyName); + Settings::SettingsAccessControl acl = Application::SettingsSingleton.getConsoleInputAccessMapping(composedKey); Settings::SettingsTypeVariant keyType = Application::SettingsSingleton.get(acl.first); std::visit( overloaded { - [&keyName](std::string keyValue) { - Application::Console().WriteRaw(fmt::format("{} = {}", keyName, keyValue)); + [&composedKey](std::string keyValue) { + Application::Console().WriteRaw(fmt::format("{} = {}", composedKey, keyValue)); }, - [&keyName](int keyValue) { - Application::Console().WriteRaw(fmt::format("{} = {}", keyName, keyValue)); + [&composedKey](int keyValue) { + Application::Console().WriteRaw(fmt::format("{} = {}", composedKey, keyValue)); }, - [&keyName](bool keyValue) { - Application::Console().WriteRaw(fmt::format("{} = {}", keyName, keyValue)); + [&composedKey](bool keyValue) { + Application::Console().WriteRaw(fmt::format("{} = {}", composedKey, keyValue)); } },