feat(Core/Config): added info about bad lines in config file (#5813)

This commit is contained in:
Kargatum
2021-05-13 04:03:53 +07:00
committed by GitHub
parent 0bc23075bf
commit 681c3237df

View File

@@ -20,6 +20,39 @@ namespace
std::unordered_map<std::string /*name*/, std::string /*value*/> _configOptions;
std::mutex _configLock;
// Check system configs like *server.conf*
bool IsAppConfig(std::string_view fileName)
{
size_t found = fileName.find_first_of("authserver.conf");
if (found != std::string::npos)
{
return true;
}
found = fileName.find_first_of("worldserver.conf");
if (found != std::string::npos)
{
return true;
}
return false;
}
template<typename Format, typename... Args>
inline void PrintError(std::string_view filename, Format&& fmt, Args&& ... args)
{
std::string message = acore::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...);
if (IsAppConfig(filename))
{
printf("%s\n", message.c_str());
}
else
{
LOG_ERROR("server.loading", "%s", message.c_str());
}
}
void AddKey(std::string const& optionName, std::string const& optionKey, bool replace = true)
{
auto const& itr = _configOptions.find(optionName);
@@ -42,45 +75,91 @@ namespace
std::ifstream in(file);
if (in.fail())
{
throw ConfigException(acore::StringFormat("Config::LoadFile: Failed open file '%s'", file.c_str()));
}
uint32 count = 0;
uint32 lineNumber = 0;
std::unordered_map<std::string /*name*/, std::string /*value*/> fileConfigs;
auto IsDuplicateOption = [&](std::string const& confOption)
{
auto const& itr = fileConfigs.find(confOption);
if (itr != fileConfigs.end())
{
PrintError(file, "> Config::LoadFile: Dublicate key name '%s' in config file '%s'", std::string(confOption).c_str(), file.c_str());
return true;
}
return false;
};
while (in.good())
{
lineNumber++;
std::string line;
std::getline(in, line);
if (line.empty())
continue;
// read line error
if (!in.good() && !in.eof())
{
throw ConfigException(acore::StringFormat("> Config::LoadFile: Failure to read line number %u in file '%s'", lineNumber, file.c_str()));
}
// remove whitespace in line
line = acore::String::Trim(line, in.getloc());
if (line.empty())
{
continue;
}
// comments
if (line[0] == '#' || line[0] == '[')
{
continue;
}
size_t found = line.find_first_of('#');
if (found != std::string::npos)
{
line = line.substr(0, found);
}
auto const equal_pos = line.find('=');
if (equal_pos == std::string::npos || equal_pos == line.length())
return;
{
PrintError(file, "> Config::LoadFile: Failure to read line number %u in file '%s'. Skip this line", lineNumber, file.c_str());
continue;
}
auto entry = acore::String::Trim(line.substr(0, equal_pos), in.getloc());
auto value = acore::String::Trim(line.substr(equal_pos + 1), in.getloc());
auto value = acore::String::Trim(line.substr(equal_pos + 1, std::string::npos), in.getloc());
value.erase(std::remove(value.begin(), value.end(), '"'), value.end());
AddKey(entry, value);
// Skip if 2+ same options in one config file
if (IsDuplicateOption(entry))
{
continue;
}
// Add to temp container
fileConfigs.emplace(entry, value);
count++;
}
// No lines read
if (!count)
throw ConfigException(acore::StringFormat("Config::LoadFile: Empty file '%s'", file.c_str()));
// Add correct keys if file load without errors
for (auto const& [entry, key] : fileConfigs)
{
AddKey(entry, key);
}
}
bool LoadFile(std::string const& file)
@@ -92,7 +171,7 @@ namespace
}
catch (const std::exception& e)
{
LOG_ERROR("server", "> Config: %s", e.what());
PrintError(file, "> %s", e.what());
}
return false;