Fixes + validate h2 mod config

This commit is contained in:
fed 2023-02-22 04:36:28 +01:00
parent 806c206fe8
commit 818f35cfeb
5 changed files with 127 additions and 36 deletions

View File

@ -3,6 +3,7 @@
#include "config.hpp"
#include "console.hpp"
#include "language.hpp"
#include <utils/hook.hpp>
#include <utils/io.hpp>
@ -11,6 +12,55 @@
namespace config
{
namespace
{
using validate_type_callback_t = std::function<bool(const field_value&)>;
using validate_callback_t = std::function<bool(const field_value&)>;
struct field_definition_t
{
field_type type;
field_value default_value;
std::optional<validate_callback_t> validate_value = {};
};
template <typename... Args>
std::pair<std::string, field_definition_t> define_field(const std::string& name, Args&&... args)
{
return std::make_pair(name, field_definition_t{std::forward<Args>(args)...});
}
std::unordered_map<std::string, field_definition_t> field_definitions =
{
{define_field("language", config::field_type::string, language::get_default_language(), language::is_valid_language)},
};
}
nlohmann::json validate_config_field(const std::string& key, const nlohmann::json& value)
{
const auto iter = field_definitions.find(key);
if (iter == field_definitions.end())
{
return value;
}
if (value.type() != iter->second.type)
{
return iter->second.default_value;
}
if (iter->second.validate_value.has_value())
{
const auto& validate_value = iter->second.validate_value.value();
if (!validate_value(value))
{
iter->second.default_value;
}
}
return value;
}
void write_config(const nlohmann::json& json)
{
try

View File

@ -2,9 +2,14 @@
namespace config
{
typedef nlohmann::json::value_t field_type;
typedef nlohmann::json field_value;
nlohmann::json read_config();
void write_config(const nlohmann::json& json);
nlohmann::json validate_config_field(const std::string& key, const field_value& value);
template <typename T>
std::optional<T> get(const std::string& key)
{
@ -14,14 +19,15 @@ namespace config
return {};
}
return {cfg[key].get<T>()};
const auto value = validate_config_field(key, cfg[key]);
return {value.get<T>()};
}
template <typename T>
void set(const std::string& key, const T& value)
{
auto cfg = read_config();
cfg[key] = value;
cfg[key] = validate_config_field(key, value);
write_config(cfg);
}
}

View File

@ -7,6 +7,7 @@
#include "filesystem.hpp"
#include "console.hpp"
#include "command.hpp"
#include "language.hpp"
#include <utils/io.hpp>
#include <utils/hook.hpp>
@ -116,25 +117,6 @@ namespace database
return file.ends_with(".ff") || file.ends_with(".pak");
}
std::unordered_set<game::language_t> unsuppored_languages =
{
{game::LANGUAGE_CZECH}
};
bool is_unsupported_language(const std::string& name)
{
for (auto i = 0; i < 17; i++)
{
if ((game::languages[i].name == name || game::languages[i].shortname == name) &&
unsuppored_languages.contains(static_cast<game::language_t>(i)))
{
return true;
}
}
return false;
}
bool is_loc_folder(game::Sys_Folder folder)
{
return folder == game::SF_PAKFILE_LOC || folder == game::SF_ZONE_LOC || folder == game::SF_VIDEO_LOC;
@ -160,7 +142,7 @@ namespace database
{
const auto loc = name.substr(0, 3);
const auto found = find_fastfile(name);
if (is_unsupported_language(loc) && !found.has_value())
if (language::is_custom_language(loc) && !found.has_value())
{
name = "eng" + name.substr(3);
file_ = name;
@ -421,7 +403,7 @@ namespace database
utils::hook::detour sys_set_folder_hook;
void sys_set_folder_stub(game::Sys_Folder folder, const char* path)
{
if (is_loc_folder(folder) && is_unsupported_language(path))
if (is_loc_folder(folder) && language::is_custom_language(path))
{
path = "english";
}

View File

@ -8,6 +8,9 @@
#include <utils/hook.hpp>
#include <utils/io.hpp>
#include <utils/string.hpp>
#define OLD_LANGUAGE_FILE "players2/default/language"
namespace language
{
@ -27,20 +30,25 @@ namespace language
{game::LANGUAGE_RUSSIAN_PARTIAL},
};
std::unordered_set<game::language_t> cyrillic_languages =
std::unordered_set<game::language_t> polish_russian_languages =
{
game::LANGUAGE_RUSSIAN,
game::LANGUAGE_POLISH,
game::LANGUAGE_CZECH,
game::LANGUAGE_RUSSIAN_PARTIAL,
{game::LANGUAGE_RUSSIAN},
{game::LANGUAGE_POLISH},
{game::LANGUAGE_CZECH},
{game::LANGUAGE_RUSSIAN_PARTIAL},
};
std::unordered_set<game::language_t> asian_languages =
{
game::LANGUAGE_JAPANESE_FULL,
game::LANGUAGE_JAPANESE_PARTIAL,
game::LANGUAGE_TRADITIONAL_CHINESE,
game::LANGUAGE_SIMPLIFIED_CHINESE,
{game::LANGUAGE_JAPANESE_FULL},
{game::LANGUAGE_JAPANESE_PARTIAL},
{game::LANGUAGE_TRADITIONAL_CHINESE},
{game::LANGUAGE_SIMPLIFIED_CHINESE},
};
std::unordered_set<game::language_t> custom_languages =
{
{game::LANGUAGE_CZECH},
};
const char* get_loc_language_string()
@ -58,6 +66,40 @@ namespace language
}
}
std::string get_default_language()
{
return "english";
}
bool is_valid_language(const std::string& name)
{
const auto lower = utils::string::to_lower(name);
for (auto i = 0; i < game::LANGUAGE_COUNT; i++)
{
const auto a = game::languages[i].name;
const auto b = game::languages[i].is_supported;
if (game::languages[i].name == lower)
{
return true;
}
}
return false;
}
bool is_custom_language(const std::string& name)
{
for (const auto& language : custom_languages)
{
if (game::languages[language].name == name || game::languages[language].shortname == name)
{
return true;
}
}
return false;
}
game::language_t current()
{
static auto* loc_language = game::Dvar_FindVar("loc_language");
@ -71,7 +113,7 @@ namespace language
bool is_polrus()
{
return cyrillic_languages.contains(current());
return polish_russian_languages.contains(current());
}
bool is_arabic()
@ -91,7 +133,7 @@ namespace language
void set_from_index(const int index)
{
if (index < 0 || index > 17)
if (index < 0 || index >= game::LANGUAGE_COUNT)
{
return;
}
@ -107,9 +149,16 @@ namespace language
{
utils::hook::call(0x14060AFFB, get_loc_language_string);
for (auto i = 0; i < 17; i++)
if (utils::io::file_exists(OLD_LANGUAGE_FILE))
{
game::languages[i].is_supported = 1;
const auto lang = utils::io::read_file(OLD_LANGUAGE_FILE);
config::set("language", lang);
utils::io::remove_file(OLD_LANGUAGE_FILE);
}
for (const auto& language : custom_languages)
{
game::languages[language].is_supported = 1;
}
}
};

View File

@ -4,6 +4,10 @@
namespace language
{
std::string get_default_language();
bool is_valid_language(const std::string& name);
bool is_custom_language(const std::string& name);
void set(const std::string& language);
void set_from_index(const int index);