mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-07-01 23:35:41 +00:00
Fix ComposedKey
metadata not printing to console
Make ComposedKey formattable by overloading fmt::format Signed-off-by: Lucca Jiménez Könings <development@jimkoen.com>
This commit is contained in:
parent
8693b8a2b0
commit
f5e2f7425f
@ -17,11 +17,44 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
#include <fmt/core.h>
|
||||||
|
#include <fmt/format.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
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<ComposedKey> : formatter<std::string> {
|
||||||
|
auto format(ComposedKey key, format_context& ctx) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline auto fmt::formatter<ComposedKey>::format(ComposedKey key, fmt::format_context& ctx) const {
|
||||||
|
std::string key_metadata = fmt::format("{}::{}", key.Category, key.Key);
|
||||||
|
return formatter<std::string>::format(key_metadata, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <>
|
||||||
|
class hash<ComposedKey> {
|
||||||
|
public:
|
||||||
|
std::uint64_t operator()(const ComposedKey& key) const {
|
||||||
|
std::hash<std::string> hash_fn;
|
||||||
|
return hash_fn(key.Category + key.Key);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
struct Settings {
|
struct Settings {
|
||||||
using SettingsTypeVariant = std::variant<std::string, bool, int>;
|
using SettingsTypeVariant = std::variant<std::string, bool, int>;
|
||||||
|
|
||||||
@ -78,23 +111,24 @@ struct Settings {
|
|||||||
SettingsAccessMask // Console read/write permissions
|
SettingsAccessMask // Console read/write permissions
|
||||||
>;
|
>;
|
||||||
|
|
||||||
std::unordered_map<std::string, SettingsAccessControl> InputAccessMapping {
|
std::unordered_map<ComposedKey, SettingsAccessControl> InputAccessMapping {
|
||||||
{ "Description", { General_Description, write } },
|
{ { "General", "Description" }, { General_Description, write } },
|
||||||
{ "Tags", { General_Tags, write } },
|
{ { "General", "Tags" }, { General_Tags, write } },
|
||||||
{ "MaxPlayers", { General_MaxPlayers, write } },
|
{ { "General", "MaxPlayers" }, { General_MaxPlayers, write } },
|
||||||
{ "Name", { General_Name, write } },
|
{ { "General", "Name" }, { General_Name, write } },
|
||||||
{ "Map", { General_Map, read } },
|
{ { "General", "Map" }, { General_Map, read } },
|
||||||
{ "AuthKey", { General_AuthKey, noaccess } },
|
{ { "General", "AuthKey" }, { General_AuthKey, noaccess } },
|
||||||
{ "Private", { General_Private, read } },
|
{ { "General", "Private" }, { General_Private, read } },
|
||||||
{ "Port", { General_Port, read } },
|
{ { "General", "Port" }, { General_Port, read } },
|
||||||
{ "MaxCars", { General_MaxCars, write } },
|
{ { "General", "MaxCars" }, { General_MaxCars, write } },
|
||||||
{ "LogChat", { General_LogChat, read } },
|
{ { "General", "LogChat" }, { General_LogChat, read } },
|
||||||
{ "Resourcefolder", { General_ResourceFolder, read } },
|
{ { "General", "ResourceFolder" }, { General_ResourceFolder, read } },
|
||||||
{ "Debug", { General_Debug, noaccess } },
|
{ { "General", "Debug" }, { General_Debug, noaccess } },
|
||||||
{ "SendErrorsShowMessage", { Misc_SendErrorsShowMessage, noaccess } },
|
{ { "Misc", "SendErrorsShowMessage" }, { Misc_SendErrorsShowMessage, noaccess } },
|
||||||
{ "SendErrors", { Misc_SendErrors, noaccess } },
|
{ { "Misc", "SendErrors" }, { Misc_SendErrors, noaccess } },
|
||||||
{ "ImScaredOfUpdates", { Misc_ImScaredOfUpdates, noaccess } }
|
{ { "Misc", "ImScaredOfUpdates" }, { Misc_ImScaredOfUpdates, noaccess } }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
std::unordered_map<std::string, Key> InputKeyMapping{
|
std::unordered_map<std::string, Key> InputKeyMapping{
|
||||||
{"Description", General_Description},
|
{"Description", General_Description},
|
||||||
@ -172,25 +206,25 @@ struct Settings {
|
|||||||
SettingsMap.at(key) = value;
|
SettingsMap.at(key) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::unordered_map<std::string, SettingsAccessControl>& getACLMap() const {
|
const std::unordered_map<ComposedKey, SettingsAccessControl>& getACLMap() const {
|
||||||
return InputAccessMapping;
|
return InputAccessMapping;
|
||||||
}
|
}
|
||||||
SettingsAccessControl getConsoleInputAccessMapping(const std::string& keyName) {
|
SettingsAccessControl getConsoleInputAccessMapping(const ComposedKey& keyName) {
|
||||||
if (!InputAccessMapping.contains(keyName)) {
|
if (!InputAccessMapping.contains(keyName)) {
|
||||||
throw std::logic_error { "Unknown key name accessed in Settings::getConsoleInputAccessMapping" };
|
throw std::logic_error { "Unknown key name accessed in Settings::getConsoleInputAccessMapping" };
|
||||||
} else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) {
|
} 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);
|
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)) {
|
if (!InputAccessMapping.contains(keyName)) {
|
||||||
throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" };
|
throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" };
|
||||||
} else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) {
|
} 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) {
|
} 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;
|
Key key = InputAccessMapping.at(keyName).first;
|
||||||
@ -201,13 +235,13 @@ struct Settings {
|
|||||||
|
|
||||||
SettingsMap.at(key) = value;
|
SettingsMap.at(key) = value;
|
||||||
}
|
}
|
||||||
void setConsoleInputAccessMapping(const std::string& keyName, int value) {
|
void setConsoleInputAccessMapping(const ComposedKey& keyName, int value) {
|
||||||
if (!InputAccessMapping.contains(keyName)) {
|
if (!InputAccessMapping.contains(keyName)) {
|
||||||
throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" };
|
throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" };
|
||||||
} else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) {
|
} 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) {
|
} 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;
|
Key key = InputAccessMapping.at(keyName).first;
|
||||||
@ -218,13 +252,13 @@ struct Settings {
|
|||||||
|
|
||||||
SettingsMap.at(key) = value;
|
SettingsMap.at(key) = value;
|
||||||
}
|
}
|
||||||
void setConsoleInputAccessMapping(const std::string& keyName, bool value) {
|
void setConsoleInputAccessMapping(const ComposedKey& keyName, bool value) {
|
||||||
if (!InputAccessMapping.contains(keyName)) {
|
if (!InputAccessMapping.contains(keyName)) {
|
||||||
throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" };
|
throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" };
|
||||||
} else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) {
|
} 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) {
|
} 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;
|
Key key = InputAccessMapping.at(keyName).first;
|
||||||
|
@ -382,10 +382,10 @@ void TConsole::Command_Settings(const std::string&, const std::vector<std::strin
|
|||||||
|
|
||||||
static constexpr const char* sHelpString = R"(
|
static constexpr const char* sHelpString = R"(
|
||||||
Settings:
|
Settings:
|
||||||
settings help displays this help
|
settings help displays this help
|
||||||
settings list lists all settings
|
settings list lists all settings
|
||||||
settings get <setting> prints current value of specified setting
|
settings get <category> <setting> prints current value of specified setting
|
||||||
settings set <setting> <value> sets specified setting to value
|
settings set <categoty> <setting> <value> sets specified setting to value
|
||||||
)";
|
)";
|
||||||
|
|
||||||
if (args.size() == 0) {
|
if (args.size() == 0) {
|
||||||
@ -399,27 +399,28 @@ void TConsole::Command_Settings(const std::string&, const std::vector<std::strin
|
|||||||
Application::Console().WriteRaw("BeamMP-Server Console: " + std::string(sHelpString));
|
Application::Console().WriteRaw("BeamMP-Server Console: " + std::string(sHelpString));
|
||||||
return;
|
return;
|
||||||
} else if (args.front() == "get") {
|
} else if (args.front() == "get") {
|
||||||
if (args.size() == 1) {
|
if (args.size() < 3) {
|
||||||
beammp_errorf("'settings get' needs at least one argument!");
|
beammp_errorf("'settings get' needs at least two arguments!");
|
||||||
|
|
||||||
Application::Console().WriteRaw("BeamMP-Server Console: " + std::string(sHelpString));
|
Application::Console().WriteRaw("BeamMP-Server Console: " + std::string(sHelpString));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Settings::SettingsAccessControl acl = Application::SettingsSingleton.getConsoleInputAccessMapping(args.at(1));
|
Settings::SettingsAccessControl acl = Application::SettingsSingleton.getConsoleInputAccessMapping(ComposedKey(args.at(1), args.at(2)));
|
||||||
Settings::SettingsTypeVariant keyType = Application::SettingsSingleton.get(acl.first);
|
Settings::SettingsTypeVariant keyType = Application::SettingsSingleton.get(acl.first);
|
||||||
|
|
||||||
std::visit(
|
std::visit(
|
||||||
overloaded {
|
overloaded {
|
||||||
[&args](std::string keyValue) {
|
[&args](std::string keyValue) {
|
||||||
Application::Console().WriteRaw(fmt::format("{} = {}", args.at(1), keyValue));
|
Application::Console().WriteRaw(fmt::format("'{} > {}' = {}", args.at(1), args.at(2), keyValue));
|
||||||
},
|
},
|
||||||
[&args](int 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) {
|
[&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<std::strin
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
Settings::SettingsAccessControl acl = Application::SettingsSingleton.getConsoleInputAccessMapping(args.at(1));
|
Settings::SettingsAccessControl acl = Application::SettingsSingleton.getConsoleInputAccessMapping(ComposedKey(args.at(1), args.at(2)));
|
||||||
Settings::SettingsTypeVariant keyType = Application::SettingsSingleton.get(acl.first);
|
Settings::SettingsTypeVariant keyType = Application::SettingsSingleton.get(acl.first);
|
||||||
|
|
||||||
std::visit(
|
std::visit(
|
||||||
overloaded {
|
overloaded {
|
||||||
[&args](std::string keyValue) {
|
[&args](std::string keyValue) {
|
||||||
Application::SettingsSingleton.setConsoleInputAccessMapping(args.at(1), std::string(args.at(2)));
|
Application::SettingsSingleton.setConsoleInputAccessMapping(ComposedKey(args.at(1), args.at(2)), std::string(args.at(2)));
|
||||||
Application::Console().WriteRaw(fmt::format("{} := {}", args.at(1), std::string(args.at(2))));
|
Application::Console().WriteRaw(fmt::format("{} > {} := {}", args.at(1), args.at(2), std::string(args.at(2))));
|
||||||
},
|
},
|
||||||
[&args](int keyValue) {
|
[&args](int keyValue) {
|
||||||
Application::SettingsSingleton.setConsoleInputAccessMapping(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), std::stoi(args.at(2))));
|
Application::Console().WriteRaw(fmt::format("{} > {} := {}", args.at(1),args.at(2), std::stoi(args.at(2))));
|
||||||
},
|
},
|
||||||
[&args](bool keyValue) {
|
[&args](bool keyValue) {
|
||||||
// todo: implement other way to convert from string to bool
|
// todo: implement other way to convert from string to bool
|
||||||
Application::SettingsSingleton.setConsoleInputAccessMapping(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), 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<std::strin
|
|||||||
|
|
||||||
}else if(args.front() == "list"){
|
}else if(args.front() == "list"){
|
||||||
//std::unordered_map<std::string, Settings::SettingsAccessControl>
|
//std::unordered_map<std::string, Settings::SettingsAccessControl>
|
||||||
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
|
// even though we have the value, we want to ignore it in order to make use of access
|
||||||
// control checks
|
// control checks
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
|
||||||
Settings::SettingsAccessControl acl = Application::SettingsSingleton.getConsoleInputAccessMapping(keyName);
|
Settings::SettingsAccessControl acl = Application::SettingsSingleton.getConsoleInputAccessMapping(composedKey);
|
||||||
Settings::SettingsTypeVariant keyType = Application::SettingsSingleton.get(acl.first);
|
Settings::SettingsTypeVariant keyType = Application::SettingsSingleton.get(acl.first);
|
||||||
|
|
||||||
std::visit(
|
std::visit(
|
||||||
overloaded {
|
overloaded {
|
||||||
[&keyName](std::string keyValue) {
|
[&composedKey](std::string keyValue) {
|
||||||
Application::Console().WriteRaw(fmt::format("{} = {}", keyName, keyValue));
|
Application::Console().WriteRaw(fmt::format("{} = {}", composedKey, keyValue));
|
||||||
},
|
},
|
||||||
[&keyName](int keyValue) {
|
[&composedKey](int keyValue) {
|
||||||
Application::Console().WriteRaw(fmt::format("{} = {}", keyName, keyValue));
|
Application::Console().WriteRaw(fmt::format("{} = {}", composedKey, keyValue));
|
||||||
},
|
},
|
||||||
[&keyName](bool keyValue) {
|
[&composedKey](bool keyValue) {
|
||||||
Application::Console().WriteRaw(fmt::format("{} = {}", keyName, keyValue));
|
Application::Console().WriteRaw(fmt::format("{} = {}", composedKey, keyValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user