aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/config.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-10-06 10:45:48 +0200
committerGitHub <[email protected]>2023-10-06 10:45:48 +0200
commitfb70324d37282910d7fa3047f4ec290d0c5a94b1 (patch)
treea1bc82fcfdb96eb5b461742b613fcbb63f816a54 /src/zenserver/config.cpp
parentreject known bad bucket names in structured cache (#452) (diff)
downloadzen-fb70324d37282910d7fa3047f4ec290d0c5a94b1.tar.xz
zen-fb70324d37282910d7fa3047f4ec290d0c5a94b1.zip
zenserver project restructuring (#442)
Diffstat (limited to 'src/zenserver/config.cpp')
-rw-r--r--src/zenserver/config.cpp894
1 files changed, 441 insertions, 453 deletions
diff --git a/src/zenserver/config.cpp b/src/zenserver/config.cpp
index b7699900f..435b66a83 100644
--- a/src/zenserver/config.cpp
+++ b/src/zenserver/config.cpp
@@ -32,6 +32,8 @@ ZEN_THIRD_PARTY_INCLUDES_END
# pragma comment(lib, "shell32.lib")
# pragma comment(lib, "ole32.lib")
+namespace zen {
+
std::filesystem::path
PickDefaultStateDirectory()
{
@@ -51,8 +53,12 @@ PickDefaultStateDirectory()
return L"";
}
+} // namespace zen
+
#else
+namespace zen {
+
std::filesystem::path
PickDefaultStateDirectory()
{
@@ -61,8 +67,12 @@ PickDefaultStateDirectory()
return std::filesystem::path(Passwd->pw_dir) / ".zen";
}
+} // namespace zen
+
#endif
+namespace zen {
+
void
ValidateOptions(ZenServerOptions& ServerOptions)
{
@@ -159,409 +169,385 @@ MakeSafePath(const std::string_view Path)
namespace LuaConfig {
-void
-EscapeBackslash(std::string& InOutString)
-{
- std::size_t BackslashPos = InOutString.find('\\');
- if (BackslashPos != std::string::npos)
+ void EscapeBackslash(std::string& InOutString)
{
- std::size_t Offset = 0;
- zen::ExtendableStringBuilder<512> PathBuilder;
- while (BackslashPos != std::string::npos)
+ std::size_t BackslashPos = InOutString.find('\\');
+ if (BackslashPos != std::string::npos)
{
- PathBuilder.Append(InOutString.substr(Offset, BackslashPos + 1 - Offset));
- PathBuilder.Append('\\');
- Offset = BackslashPos + 1;
- BackslashPos = InOutString.find('\\', Offset);
+ std::size_t Offset = 0;
+ zen::ExtendableStringBuilder<512> PathBuilder;
+ while (BackslashPos != std::string::npos)
+ {
+ PathBuilder.Append(InOutString.substr(Offset, BackslashPos + 1 - Offset));
+ PathBuilder.Append('\\');
+ Offset = BackslashPos + 1;
+ BackslashPos = InOutString.find('\\', Offset);
+ }
+ PathBuilder.Append(InOutString.substr(Offset, BackslashPos));
+ InOutString = PathBuilder.ToString();
}
- PathBuilder.Append(InOutString.substr(Offset, BackslashPos));
- InOutString = PathBuilder.ToString();
}
-}
-class OptionValue
-{
-public:
- virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) = 0;
- virtual void Parse(sol::object Object) = 0;
+ class OptionValue
+ {
+ public:
+ virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) = 0;
+ virtual void Parse(sol::object Object) = 0;
- virtual ~OptionValue() {}
-};
+ virtual ~OptionValue() {}
+ };
-typedef std::shared_ptr<OptionValue> TOptionValue;
+ typedef std::shared_ptr<OptionValue> TOptionValue;
-class StringOption : public OptionValue
-{
-public:
- StringOption(std::string& Value) : Value(Value) {}
- virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override
+ class StringOption : public OptionValue
{
- StringBuilder.Append(fmt::format("\"{}\"", Value));
- }
- virtual void Parse(sol::object Object) override { Value = Object.as<std::string>(); }
- std::string& Value;
-};
-
-class FilePathOption : public OptionValue
-{
-public:
- FilePathOption(std::filesystem::path& Value) : Value(Value) {}
- virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override
- {
- std::string Path = Value.string();
- EscapeBackslash(Path);
- StringBuilder.Append(fmt::format("\"{}\"", Path));
- }
- virtual void Parse(sol::object Object) override
- {
- std::string Str = Object.as<std::string>();
- if (!Str.empty())
+ public:
+ StringOption(std::string& Value) : Value(Value) {}
+ virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override
{
- Value = MakeSafePath(Str);
+ StringBuilder.Append(fmt::format("\"{}\"", Value));
}
- }
- std::filesystem::path& Value;
-};
-
-class BoolOption : public OptionValue
-{
-public:
- BoolOption(bool& Value) : Value(Value) {}
- virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override { StringBuilder.Append(Value ? "true" : "false"); }
- virtual void Parse(sol::object Object) override { Value = Object.as<bool>(); }
- bool& Value;
-};
+ virtual void Parse(sol::object Object) override { Value = Object.as<std::string>(); }
+ std::string& Value;
+ };
-class CachePolicyOption : public OptionValue
-{
-public:
- CachePolicyOption(UpstreamCachePolicy& Value) : Value(Value) {}
- virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override
+ class FilePathOption : public OptionValue
{
- switch (Value)
+ public:
+ FilePathOption(std::filesystem::path& Value) : Value(Value) {}
+ virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override
{
- case UpstreamCachePolicy::Read:
- StringBuilder.Append("readonly");
- break;
- case UpstreamCachePolicy::Write:
- StringBuilder.Append("writeonly");
- break;
- case UpstreamCachePolicy::Disabled:
- StringBuilder.Append("disabled");
- break;
- case UpstreamCachePolicy::ReadWrite:
- StringBuilder.Append("readwrite");
- break;
- default:
- ZEN_ASSERT(false);
+ std::string Path = Value.string();
+ EscapeBackslash(Path);
+ StringBuilder.Append(fmt::format("\"{}\"", Path));
}
- }
- virtual void Parse(sol::object Object) override
- {
- std::string PolicyString = Object.as<std::string>();
- if (PolicyString == "readonly")
+ virtual void Parse(sol::object Object) override
{
- Value = UpstreamCachePolicy::Read;
+ std::string Str = Object.as<std::string>();
+ if (!Str.empty())
+ {
+ Value = MakeSafePath(Str);
+ }
}
- else if (PolicyString == "writeonly")
+ std::filesystem::path& Value;
+ };
+
+ class BoolOption : public OptionValue
+ {
+ public:
+ BoolOption(bool& Value) : Value(Value) {}
+ virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override
{
- Value = UpstreamCachePolicy::Write;
+ StringBuilder.Append(Value ? "true" : "false");
}
- else if (PolicyString == "disabled")
+ virtual void Parse(sol::object Object) override { Value = Object.as<bool>(); }
+ bool& Value;
+ };
+
+ class CachePolicyOption : public OptionValue
+ {
+ public:
+ CachePolicyOption(UpstreamCachePolicy& Value) : Value(Value) {}
+ virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override
{
- Value = UpstreamCachePolicy::Disabled;
+ switch (Value)
+ {
+ case UpstreamCachePolicy::Read:
+ StringBuilder.Append("readonly");
+ break;
+ case UpstreamCachePolicy::Write:
+ StringBuilder.Append("writeonly");
+ break;
+ case UpstreamCachePolicy::Disabled:
+ StringBuilder.Append("disabled");
+ break;
+ case UpstreamCachePolicy::ReadWrite:
+ StringBuilder.Append("readwrite");
+ break;
+ default:
+ ZEN_ASSERT(false);
+ }
}
- else if (PolicyString == "readwrite")
+ virtual void Parse(sol::object Object) override
{
- Value = UpstreamCachePolicy::ReadWrite;
+ std::string PolicyString = Object.as<std::string>();
+ if (PolicyString == "readonly")
+ {
+ Value = UpstreamCachePolicy::Read;
+ }
+ else if (PolicyString == "writeonly")
+ {
+ Value = UpstreamCachePolicy::Write;
+ }
+ else if (PolicyString == "disabled")
+ {
+ Value = UpstreamCachePolicy::Disabled;
+ }
+ else if (PolicyString == "readwrite")
+ {
+ Value = UpstreamCachePolicy::ReadWrite;
+ }
}
- }
- UpstreamCachePolicy& Value;
-};
-
-template<Integral T>
-class NumberOption : public OptionValue
-{
-public:
- NumberOption(T& Value) : Value(Value) {}
- virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override { StringBuilder.Append(fmt::format("{}", Value)); }
- virtual void Parse(sol::object Object) override { Value = Object.as<T>(); }
- T& Value;
-};
-
-class LuaContainerWriter
-{
-public:
- LuaContainerWriter(zen::StringBuilderBase& StringBuilder, std::string_view Indent)
- : StringBuilder(StringBuilder)
- , InitialIndent(Indent.length())
- , LocalIndent(Indent)
- {
- StringBuilder.Append("{\n");
- LocalIndent.push_back('\t');
- }
- ~LuaContainerWriter()
- {
- LocalIndent.pop_back();
- StringBuilder.Append(LocalIndent);
- StringBuilder.Append("}");
- }
+ UpstreamCachePolicy& Value;
+ };
- void BeginContainer(std::string_view Name)
+ template<Integral T>
+ class NumberOption : public OptionValue
{
- StringBuilder.Append(LocalIndent);
- if (!Name.empty())
- {
- StringBuilder.Append(Name);
- StringBuilder.Append(" = {\n");
- }
- else
+ public:
+ NumberOption(T& Value) : Value(Value) {}
+ virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override
{
- StringBuilder.Append("{\n");
+ StringBuilder.Append(fmt::format("{}", Value));
}
- LocalIndent.push_back('\t');
- }
- void WriteValue(std::string_view Name, std::string_view Value)
+ virtual void Parse(sol::object Object) override { Value = Object.as<T>(); }
+ T& Value;
+ };
+
+ class LuaContainerWriter
{
- if (Name.empty())
+ public:
+ LuaContainerWriter(zen::StringBuilderBase& StringBuilder, std::string_view Indent)
+ : StringBuilder(StringBuilder)
+ , InitialIndent(Indent.length())
+ , LocalIndent(Indent)
{
- StringBuilder.Append(fmt::format("{}\"{}\",\n", LocalIndent, Value));
+ StringBuilder.Append("{\n");
+ LocalIndent.push_back('\t');
}
- else
+ ~LuaContainerWriter()
{
- StringBuilder.Append(fmt::format("{}{} = \"{}\",\n", LocalIndent, Name, Value));
+ LocalIndent.pop_back();
+ StringBuilder.Append(LocalIndent);
+ StringBuilder.Append("}");
}
- }
- void EndContainer()
- {
- LocalIndent.pop_back();
- StringBuilder.Append(LocalIndent);
- StringBuilder.Append("}");
- StringBuilder.Append(",\n");
- }
-private:
- zen::StringBuilderBase& StringBuilder;
- const std::size_t InitialIndent;
- std::string LocalIndent;
-};
-
-class StringArrayOption : public OptionValue
-{
-public:
- StringArrayOption(std::vector<std::string>& Value) : Value(Value) {}
- virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override
- {
- if (Value.empty())
+ void BeginContainer(std::string_view Name)
{
- StringBuilder.Append("{}");
- }
- if (Value.size() == 1)
- {
- StringBuilder.Append(fmt::format("\"{}\"", Value[0]));
+ StringBuilder.Append(LocalIndent);
+ if (!Name.empty())
+ {
+ StringBuilder.Append(Name);
+ StringBuilder.Append(" = {\n");
+ }
+ else
+ {
+ StringBuilder.Append("{\n");
+ }
+ LocalIndent.push_back('\t');
}
- else
+ void WriteValue(std::string_view Name, std::string_view Value)
{
- LuaContainerWriter Writer(StringBuilder, Indent);
- for (std::string String : Value)
+ if (Name.empty())
+ {
+ StringBuilder.Append(fmt::format("{}\"{}\",\n", LocalIndent, Value));
+ }
+ else
{
- Writer.WriteValue("", String);
+ StringBuilder.Append(fmt::format("{}{} = \"{}\",\n", LocalIndent, Name, Value));
}
}
- }
- virtual void Parse(sol::object Object) override
+ void EndContainer()
+ {
+ LocalIndent.pop_back();
+ StringBuilder.Append(LocalIndent);
+ StringBuilder.Append("}");
+ StringBuilder.Append(",\n");
+ }
+
+ private:
+ zen::StringBuilderBase& StringBuilder;
+ const std::size_t InitialIndent;
+ std::string LocalIndent;
+ };
+
+ class StringArrayOption : public OptionValue
{
- if (Object.get_type() == sol::type::string)
+ public:
+ StringArrayOption(std::vector<std::string>& Value) : Value(Value) {}
+ virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override
{
- Value.push_back(Object.as<std::string>());
+ if (Value.empty())
+ {
+ StringBuilder.Append("{}");
+ }
+ if (Value.size() == 1)
+ {
+ StringBuilder.Append(fmt::format("\"{}\"", Value[0]));
+ }
+ else
+ {
+ LuaContainerWriter Writer(StringBuilder, Indent);
+ for (std::string String : Value)
+ {
+ Writer.WriteValue("", String);
+ }
+ }
}
- else if (Object.get_type() == sol::type::table)
+ virtual void Parse(sol::object Object) override
{
- for (const auto& Kv : Object.as<sol::table>())
+ if (Object.get_type() == sol::type::string)
{
- Value.push_back(Kv.second.as<std::string>());
+ Value.push_back(Object.as<std::string>());
+ }
+ else if (Object.get_type() == sol::type::table)
+ {
+ for (const auto& Kv : Object.as<sol::table>())
+ {
+ Value.push_back(Kv.second.as<std::string>());
+ }
}
}
- }
-private:
- std::vector<std::string>& Value;
-};
+ private:
+ std::vector<std::string>& Value;
+ };
-class ZenAuthConfigOption : public OptionValue
-{
-public:
- ZenAuthConfigOption(ZenAuthConfig& Value) : Value(Value) {}
- virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override
+ class ZenAuthConfigOption : public OptionValue
{
- if (Value.OpenIdProviders.empty())
+ public:
+ ZenAuthConfigOption(ZenAuthConfig& Value) : Value(Value) {}
+ virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override
{
- StringBuilder.Append("{}");
- return;
- }
- LuaContainerWriter Writer(StringBuilder, Indent);
- for (const ZenOpenIdProviderConfig& Config : Value.OpenIdProviders)
- {
- Writer.BeginContainer("");
+ if (Value.OpenIdProviders.empty())
{
- Writer.WriteValue("name", Config.Name);
- Writer.WriteValue("url", Config.Url);
- Writer.WriteValue("clientid", Config.ClientId);
+ StringBuilder.Append("{}");
+ return;
+ }
+ LuaContainerWriter Writer(StringBuilder, Indent);
+ for (const ZenOpenIdProviderConfig& Config : Value.OpenIdProviders)
+ {
+ Writer.BeginContainer("");
+ {
+ Writer.WriteValue("name", Config.Name);
+ Writer.WriteValue("url", Config.Url);
+ Writer.WriteValue("clientid", Config.ClientId);
+ }
+ Writer.EndContainer();
}
- Writer.EndContainer();
}
- }
- virtual void Parse(sol::object Object) override
- {
- if (sol::optional<sol::table> OpenIdProviders = Object.as<sol::table>())
+ virtual void Parse(sol::object Object) override
{
- for (const auto& Kv : OpenIdProviders.value())
+ if (sol::optional<sol::table> OpenIdProviders = Object.as<sol::table>())
{
- if (sol::optional<sol::table> OpenIdProvider = Kv.second.as<sol::table>())
+ for (const auto& Kv : OpenIdProviders.value())
{
- std::string Name = OpenIdProvider.value().get_or("name", std::string("Default"));
- std::string Url = OpenIdProvider.value().get_or("url", std::string());
- std::string ClientId = OpenIdProvider.value().get_or("clientid", std::string());
+ if (sol::optional<sol::table> OpenIdProvider = Kv.second.as<sol::table>())
+ {
+ std::string Name = OpenIdProvider.value().get_or("name", std::string("Default"));
+ std::string Url = OpenIdProvider.value().get_or("url", std::string());
+ std::string ClientId = OpenIdProvider.value().get_or("clientid", std::string());
- Value.OpenIdProviders.push_back({.Name = std::move(Name), .Url = std::move(Url), .ClientId = std::move(ClientId)});
+ Value.OpenIdProviders.push_back({.Name = std::move(Name), .Url = std::move(Url), .ClientId = std::move(ClientId)});
+ }
}
}
}
- }
- ZenAuthConfig& Value;
-};
+ ZenAuthConfig& Value;
+ };
-class ZenObjectStoreConfigOption : public OptionValue
-{
-public:
- ZenObjectStoreConfigOption(ZenObjectStoreConfig& Value) : Value(Value) {}
- virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override
+ class ZenObjectStoreConfigOption : public OptionValue
{
- if (Value.Buckets.empty())
+ public:
+ ZenObjectStoreConfigOption(ZenObjectStoreConfig& Value) : Value(Value) {}
+ virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override
{
- StringBuilder.Append("{}");
- return;
- }
- LuaContainerWriter Writer(StringBuilder, Indent);
- for (const ZenObjectStoreConfig::BucketConfig& Config : Value.Buckets)
- {
- Writer.BeginContainer("");
+ if (Value.Buckets.empty())
{
- Writer.WriteValue("name", Config.Name);
- std::string Directory = Config.Directory.string();
- EscapeBackslash(Directory);
- Writer.WriteValue("directory", Directory);
+ StringBuilder.Append("{}");
+ return;
+ }
+ LuaContainerWriter Writer(StringBuilder, Indent);
+ for (const ZenObjectStoreConfig::BucketConfig& Config : Value.Buckets)
+ {
+ Writer.BeginContainer("");
+ {
+ Writer.WriteValue("name", Config.Name);
+ std::string Directory = Config.Directory.string();
+ EscapeBackslash(Directory);
+ Writer.WriteValue("directory", Directory);
+ }
+ Writer.EndContainer();
}
- Writer.EndContainer();
}
- }
- virtual void Parse(sol::object Object) override
- {
- if (sol::optional<sol::table> Buckets = Object.as<sol::table>())
+ virtual void Parse(sol::object Object) override
{
- for (const auto& Kv : Buckets.value())
+ if (sol::optional<sol::table> Buckets = Object.as<sol::table>())
{
- if (sol::optional<sol::table> Bucket = Kv.second.as<sol::table>())
+ for (const auto& Kv : Buckets.value())
{
- std::string Name = Bucket.value().get_or("name", std::string("Default"));
- std::string Directory = Bucket.value().get_or("directory", std::string());
+ if (sol::optional<sol::table> Bucket = Kv.second.as<sol::table>())
+ {
+ std::string Name = Bucket.value().get_or("name", std::string("Default"));
+ std::string Directory = Bucket.value().get_or("directory", std::string());
- Value.Buckets.push_back({.Name = std::move(Name), .Directory = MakeSafePath(Directory)});
+ Value.Buckets.push_back({.Name = std::move(Name), .Directory = MakeSafePath(Directory)});
+ }
}
}
}
- }
- ZenObjectStoreConfig& Value;
-};
-
-std::shared_ptr<OptionValue>
-MakeOption(std::string& Value)
-{
- return std::make_shared<StringOption>(Value);
-};
+ ZenObjectStoreConfig& Value;
+ };
-std::shared_ptr<OptionValue>
-MakeOption(std::filesystem::path& Value)
-{
- return std::make_shared<FilePathOption>(Value);
-};
+ std::shared_ptr<OptionValue> MakeOption(std::string& Value) { return std::make_shared<StringOption>(Value); };
-template<Integral T>
-std::shared_ptr<OptionValue>
-MakeOption(T& Value)
-{
- return std::make_shared<NumberOption<T>>(Value);
-};
+ std::shared_ptr<OptionValue> MakeOption(std::filesystem::path& Value) { return std::make_shared<FilePathOption>(Value); };
-std::shared_ptr<OptionValue>
-MakeOption(bool& Value)
-{
- return std::make_shared<BoolOption>(Value);
-};
+ template<Integral T>
+ std::shared_ptr<OptionValue> MakeOption(T& Value)
+ {
+ return std::make_shared<NumberOption<T>>(Value);
+ };
-std::shared_ptr<OptionValue>
-MakeOption(UpstreamCachePolicy& Value)
-{
- return std::make_shared<CachePolicyOption>(Value);
-};
+ std::shared_ptr<OptionValue> MakeOption(bool& Value) { return std::make_shared<BoolOption>(Value); };
-std::shared_ptr<OptionValue>
-MakeOption(std::vector<std::string>& Value)
-{
- return std::make_shared<StringArrayOption>(Value);
-};
+ std::shared_ptr<OptionValue> MakeOption(UpstreamCachePolicy& Value) { return std::make_shared<CachePolicyOption>(Value); };
-std::shared_ptr<OptionValue>
-MakeOption(ZenAuthConfig& Value)
-{
- return std::make_shared<ZenAuthConfigOption>(Value);
-};
+ std::shared_ptr<OptionValue> MakeOption(std::vector<std::string>& Value) { return std::make_shared<StringArrayOption>(Value); };
-std::shared_ptr<OptionValue>
-MakeOption(ZenObjectStoreConfig& Value)
-{
- return std::make_shared<ZenObjectStoreConfigOption>(Value);
-};
+ std::shared_ptr<OptionValue> MakeOption(ZenAuthConfig& Value) { return std::make_shared<ZenAuthConfigOption>(Value); };
-struct Option
-{
- std::string CommandLineOptionName;
- TOptionValue Value;
-};
+ std::shared_ptr<OptionValue> MakeOption(ZenObjectStoreConfig& Value) { return std::make_shared<ZenObjectStoreConfigOption>(Value); };
-struct Options
-{
-public:
- template<typename T>
- void AddOption(std::string_view Key, T& Value, std::string_view CommandLineOptionName = "")
+ struct Option
{
- OptionMap.insert_or_assign(std::string(Key),
- Option{.CommandLineOptionName = std::string(CommandLineOptionName), .Value = MakeOption(Value)});
+ std::string CommandLineOptionName;
+ TOptionValue Value;
};
- void Parse(const std::filesystem::path& Path, const cxxopts::ParseResult& CmdLineResult)
+ struct Options
{
- zen::IoBuffer LuaScript = zen::IoBufferBuilder::MakeFromFile(Path);
+ public:
+ template<typename T>
+ void AddOption(std::string_view Key, T& Value, std::string_view CommandLineOptionName = "")
+ {
+ OptionMap.insert_or_assign(std::string(Key),
+ Option{.CommandLineOptionName = std::string(CommandLineOptionName), .Value = MakeOption(Value)});
+ };
- if (LuaScript)
+ void Parse(const std::filesystem::path& Path, const cxxopts::ParseResult& CmdLineResult)
{
- sol::state lua;
+ zen::IoBuffer LuaScript = zen::IoBufferBuilder::MakeFromFile(Path);
+
+ if (LuaScript)
+ {
+ sol::state lua;
- lua.open_libraries(sol::lib::base);
+ lua.open_libraries(sol::lib::base);
- lua.set_function("getenv", [&](const std::string env) -> sol::object {
+ lua.set_function("getenv", [&](const std::string env) -> sol::object {
#if ZEN_PLATFORM_WINDOWS
- std::wstring EnvVarValue;
- size_t RequiredSize = 0;
- std::wstring EnvWide = zen::Utf8ToWide(env);
- _wgetenv_s(&RequiredSize, nullptr, 0, EnvWide.c_str());
+ std::wstring EnvVarValue;
+ size_t RequiredSize = 0;
+ std::wstring EnvWide = zen::Utf8ToWide(env);
+ _wgetenv_s(&RequiredSize, nullptr, 0, EnvWide.c_str());
- if (RequiredSize == 0)
- return sol::make_object(lua, sol::lua_nil);
+ if (RequiredSize == 0)
+ return sol::make_object(lua, sol::lua_nil);
- EnvVarValue.resize(RequiredSize);
- _wgetenv_s(&RequiredSize, EnvVarValue.data(), RequiredSize, EnvWide.c_str());
- return sol::make_object(lua, zen::WideToUtf8(EnvVarValue.c_str()));
+ EnvVarValue.resize(RequiredSize);
+ _wgetenv_s(&RequiredSize, EnvVarValue.data(), RequiredSize, EnvWide.c_str());
+ return sol::make_object(lua, zen::WideToUtf8(EnvVarValue.c_str()));
#elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
char* EnvVariable = getenv(env.c_str());
if (EnvVariable == nullptr)
@@ -573,198 +559,198 @@ public:
ZEN_UNUSED(env);
return sol::make_object(lua, sol::lua_nil);
#endif
- });
+ });
- try
- {
- sol::load_result config = lua.load(std::string_view((const char*)LuaScript.Data(), LuaScript.Size()), "zen_cfg");
-
- if (!config.valid())
+ try
{
- sol::error err = config;
+ sol::load_result config = lua.load(std::string_view((const char*)LuaScript.Data(), LuaScript.Size()), "zen_cfg");
+
+ if (!config.valid())
+ {
+ sol::error err = config;
+
+ std::string ErrorString = sol::to_string(config.status());
- std::string ErrorString = sol::to_string(config.status());
+ throw std::runtime_error(fmt::format("{} error: {}", ErrorString, err.what()));
+ }
- throw std::runtime_error(fmt::format("{} error: {}", ErrorString, err.what()));
+ config();
+ }
+ catch (std::exception& e)
+ {
+ throw std::runtime_error(fmt::format("failed to load config script ('{}'): {}", Path, e.what()).c_str());
}
- config();
- }
- catch (std::exception& e)
- {
- throw std::runtime_error(fmt::format("failed to load config script ('{}'): {}", Path, e.what()).c_str());
+ Parse(lua, CmdLineResult);
}
-
- Parse(lua, CmdLineResult);
}
- }
- void Parse(const sol::state& LuaState, const cxxopts::ParseResult& CmdLineResult)
- {
- for (auto It : LuaState)
+ void Parse(const sol::state& LuaState, const cxxopts::ParseResult& CmdLineResult)
{
- sol::object Key = It.first;
- sol::type KeyType = Key.get_type();
- if (KeyType == sol::type::string)
+ for (auto It : LuaState)
{
- sol::type ValueType = It.second.get_type();
- switch (ValueType)
+ sol::object Key = It.first;
+ sol::type KeyType = Key.get_type();
+ if (KeyType == sol::type::string)
{
- case sol::type::table:
- {
- std::string Name = Key.as<std::string>();
- if (Name.starts_with("_"))
- {
- continue;
- }
- if (Name == "base")
+ sol::type ValueType = It.second.get_type();
+ switch (ValueType)
+ {
+ case sol::type::table:
{
- continue;
+ std::string Name = Key.as<std::string>();
+ if (Name.starts_with("_"))
+ {
+ continue;
+ }
+ if (Name == "base")
+ {
+ continue;
+ }
+ Traverse(It.second.as<sol::table>(), Name, CmdLineResult);
}
- Traverse(It.second.as<sol::table>(), Name, CmdLineResult);
- }
- break;
- default:
- break;
+ break;
+ default:
+ break;
+ }
}
}
}
- }
- void Touch(std::string_view Key) { UsedKeys.insert(std::string(Key)); }
+ void Touch(std::string_view Key) { UsedKeys.insert(std::string(Key)); }
- void Print(zen::StringBuilderBase& SB, const cxxopts::ParseResult& CmdLineResult)
- {
- for (auto It : OptionMap)
+ void Print(zen::StringBuilderBase& SB, const cxxopts::ParseResult& CmdLineResult)
{
- if (CmdLineResult.count(It.second.CommandLineOptionName) != 0)
+ for (auto It : OptionMap)
{
- UsedKeys.insert(It.first);
+ if (CmdLineResult.count(It.second.CommandLineOptionName) != 0)
+ {
+ UsedKeys.insert(It.first);
+ }
}
- }
- std::vector<std::string> SortedKeys(UsedKeys.begin(), UsedKeys.end());
- std::sort(SortedKeys.begin(), SortedKeys.end());
- auto GetTablePath = [](const std::string& Key) -> std::vector<std::string> {
- std::vector<std::string> Path;
- zen::ForEachStrTok(Key, '.', [&Path](std::string_view Part) {
- Path.push_back(std::string(Part));
- return true;
- });
- return Path;
- };
- std::vector<std::string> CurrentTablePath;
- std::string Indent;
- auto It = SortedKeys.begin();
- for (const std::string& Key : SortedKeys)
- {
- std::vector<std::string> KeyPath = GetTablePath(Key);
- std::string Name = KeyPath.back();
- KeyPath.pop_back();
- if (CurrentTablePath != KeyPath)
+ std::vector<std::string> SortedKeys(UsedKeys.begin(), UsedKeys.end());
+ std::sort(SortedKeys.begin(), SortedKeys.end());
+ auto GetTablePath = [](const std::string& Key) -> std::vector<std::string> {
+ std::vector<std::string> Path;
+ zen::ForEachStrTok(Key, '.', [&Path](std::string_view Part) {
+ Path.push_back(std::string(Part));
+ return true;
+ });
+ return Path;
+ };
+ std::vector<std::string> CurrentTablePath;
+ std::string Indent;
+ auto It = SortedKeys.begin();
+ for (const std::string& Key : SortedKeys)
{
- size_t EqualCount = 0;
- while (EqualCount < CurrentTablePath.size() && EqualCount < KeyPath.size() &&
- CurrentTablePath[EqualCount] == KeyPath[EqualCount])
- {
- EqualCount++;
- }
- while (CurrentTablePath.size() > EqualCount)
+ std::vector<std::string> KeyPath = GetTablePath(Key);
+ std::string Name = KeyPath.back();
+ KeyPath.pop_back();
+ if (CurrentTablePath != KeyPath)
{
- CurrentTablePath.pop_back();
- Indent.pop_back();
- SB.Append(Indent);
- SB.Append("}");
- if (CurrentTablePath.size() == EqualCount && !Indent.empty() && KeyPath.size() >= EqualCount)
+ size_t EqualCount = 0;
+ while (EqualCount < CurrentTablePath.size() && EqualCount < KeyPath.size() &&
+ CurrentTablePath[EqualCount] == KeyPath[EqualCount])
{
- SB.Append(",");
+ EqualCount++;
}
- SB.Append("\n");
- if (Indent.empty())
+ while (CurrentTablePath.size() > EqualCount)
{
+ CurrentTablePath.pop_back();
+ Indent.pop_back();
+ SB.Append(Indent);
+ SB.Append("}");
+ if (CurrentTablePath.size() == EqualCount && !Indent.empty() && KeyPath.size() >= EqualCount)
+ {
+ SB.Append(",");
+ }
SB.Append("\n");
+ if (Indent.empty())
+ {
+ SB.Append("\n");
+ }
+ }
+ while (EqualCount < KeyPath.size())
+ {
+ SB.Append(Indent);
+ SB.Append(KeyPath[EqualCount]);
+ SB.Append(" = {\n");
+ Indent.push_back('\t');
+ CurrentTablePath.push_back(KeyPath[EqualCount]);
+ EqualCount++;
}
}
- while (EqualCount < KeyPath.size())
- {
- SB.Append(Indent);
- SB.Append(KeyPath[EqualCount]);
- SB.Append(" = {\n");
- Indent.push_back('\t');
- CurrentTablePath.push_back(KeyPath[EqualCount]);
- EqualCount++;
- }
- }
- SB.Append(Indent);
- SB.Append(Name);
- SB.Append(" = ");
- OptionMap[Key].Value->Print(Indent, SB);
- SB.Append(",\n");
- }
- while (!CurrentTablePath.empty())
- {
- Indent.pop_back();
- SB.Append(Indent);
- SB.Append("}\n");
- CurrentTablePath.pop_back();
+ SB.Append(Indent);
+ SB.Append(Name);
+ SB.Append(" = ");
+ OptionMap[Key].Value->Print(Indent, SB);
+ SB.Append(",\n");
+ }
+ while (!CurrentTablePath.empty())
+ {
+ Indent.pop_back();
+ SB.Append(Indent);
+ SB.Append("}\n");
+ CurrentTablePath.pop_back();
+ }
}
- }
-private:
- void Traverse(sol::table Table, std::string_view PathPrefix, const cxxopts::ParseResult& CmdLineResult)
- {
- for (auto It : Table)
+ private:
+ void Traverse(sol::table Table, std::string_view PathPrefix, const cxxopts::ParseResult& CmdLineResult)
{
- sol::object Key = It.first;
- sol::type KeyType = Key.get_type();
- if (KeyType == sol::type::string || KeyType == sol::type::number)
+ for (auto It : Table)
{
- sol::type ValueType = It.second.get_type();
- switch (ValueType)
+ sol::object Key = It.first;
+ sol::type KeyType = Key.get_type();
+ if (KeyType == sol::type::string || KeyType == sol::type::number)
{
- case sol::type::table:
- case sol::type::string:
- case sol::type::number:
- case sol::type::boolean:
- {
- std::string Name = Key.as<std::string>();
- if (Name.starts_with("_"))
- {
- continue;
- }
- Name = std::string(PathPrefix) + "." + Key.as<std::string>();
- auto OptionIt = OptionMap.find(Name);
- if (OptionIt != OptionMap.end())
+ sol::type ValueType = It.second.get_type();
+ switch (ValueType)
+ {
+ case sol::type::table:
+ case sol::type::string:
+ case sol::type::number:
+ case sol::type::boolean:
{
- UsedKeys.insert(Name);
- if (CmdLineResult.count(OptionIt->second.CommandLineOptionName) != 0)
+ std::string Name = Key.as<std::string>();
+ if (Name.starts_with("_"))
{
continue;
}
- OptionIt->second.Value->Parse(It.second);
- continue;
- }
- if (ValueType == sol::type::table)
- {
- if (Name == "base")
+ Name = std::string(PathPrefix) + "." + Key.as<std::string>();
+ auto OptionIt = OptionMap.find(Name);
+ if (OptionIt != OptionMap.end())
{
+ UsedKeys.insert(Name);
+ if (CmdLineResult.count(OptionIt->second.CommandLineOptionName) != 0)
+ {
+ continue;
+ }
+ OptionIt->second.Value->Parse(It.second);
continue;
}
- Traverse(It.second.as<sol::table>(), Name, CmdLineResult);
+ if (ValueType == sol::type::table)
+ {
+ if (Name == "base")
+ {
+ continue;
+ }
+ Traverse(It.second.as<sol::table>(), Name, CmdLineResult);
+ }
}
- }
- break;
- default:
- break;
+ break;
+ default:
+ break;
+ }
}
}
}
- }
- std::unordered_map<std::string, Option> OptionMap;
- std::unordered_set<std::string> UsedKeys;
-};
+ std::unordered_map<std::string, Option> OptionMap;
+ std::unordered_set<std::string> UsedKeys;
+ };
} // namespace LuaConfig
@@ -1508,3 +1494,5 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
ServerOptions.AbsLogFile = ServerOptions.DataDir / "logs" / "zenserver.log";
}
}
+
+} // namespace zen