summaryrefslogtreecommitdiffstats
path: root/src/game/client/language.cc
diff options
context:
space:
mode:
authoruntodesu <kirill@untode.su>2025-07-01 03:08:39 +0500
committeruntodesu <kirill@untode.su>2025-07-01 03:08:39 +0500
commit458e0005690ea9d579588a0a12368fc2c2c9a93a (patch)
tree588a9ca6cb3c76d9193b5bd4601d64f0e50e8c8c /src/game/client/language.cc
parentc7b0c8e0286a1b2bb7ec55e579137dfc3b22eeb9 (diff)
downloadvoxelius-458e0005690ea9d579588a0a12368fc2c2c9a93a.tar.bz2
voxelius-458e0005690ea9d579588a0a12368fc2c2c9a93a.zip
I hyper-focued on refactoring again
- I put a cool-sounding "we are number one" remix on repeat and straight up grinded the entire repository to a better state until 03:09 AM. I guess I have something wrong in my brain that makes me do this shit
Diffstat (limited to 'src/game/client/language.cc')
-rw-r--r--src/game/client/language.cc196
1 files changed, 0 insertions, 196 deletions
diff --git a/src/game/client/language.cc b/src/game/client/language.cc
deleted file mode 100644
index 2ae0bc6..0000000
--- a/src/game/client/language.cc
+++ /dev/null
@@ -1,196 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/language.hh"
-
-#include "core/config.hh"
-
-#include "client/globals.hh"
-#include "client/settings.hh"
-
-constexpr static const char* DEFAULT_LANGUAGE = "en_US";
-
-// Available languages are kept in a special manifest file which
-// is essentially a key-value map of semi-IETF-compliant language tags
-// and the language's endonym; after reading the manifest, the translation
-// system knows what language it can load and will act accordingly
-constexpr static const char* MANIFEST_PATH = "lang/manifest.json";
-
-static LanguageManifest manifest;
-static LanguageIterator current_language;
-static std::unordered_map<std::string, std::string> language_map;
-static std::unordered_map<std::string, LanguageIterator> ietf_map;
-static ConfigString config_language(DEFAULT_LANGUAGE);
-
-static void send_language_event(LanguageIterator new_language)
-{
- LanguageSetEvent event;
- event.new_language = new_language;
- globals::dispatcher.trigger(event);
-}
-
-void language::init(void)
-{
- globals::client_config.add_value("language", config_language);
-
- settings::add_language_select(0, settings_location::GENERAL, "language");
-
- auto file = PHYSFS_openRead(MANIFEST_PATH);
-
- if(file == nullptr) {
- spdlog::critical("language: {}: {}", MANIFEST_PATH, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
- std::terminate();
- }
-
- auto source = std::string(PHYSFS_fileLength(file), char(0x00));
- PHYSFS_readBytes(file, source.data(), source.size());
- PHYSFS_close(file);
-
- auto jsonv = json_parse_string(source.c_str());
- const auto json = json_value_get_object(jsonv);
- const auto count = json_object_get_count(json);
-
- if((jsonv == nullptr) || (json == nullptr) || (count == 0)) {
- spdlog::critical("language: {}: parse error", MANIFEST_PATH);
- json_value_free(jsonv);
- std::terminate();
- }
-
- for(std::size_t i = 0; i < count; ++i) {
- const auto ietf = json_object_get_name(json, i);
- const auto value = json_object_get_value_at(json, i);
- const auto endonym = json_value_get_string(value);
-
- if(ietf && endonym) {
- LanguageInfo info;
- info.ietf = std::string(ietf);
- info.endonym = std::string(endonym);
- info.display = std::format("{} ({})", endonym, ietf);
- manifest.push_back(info);
- }
- }
-
- for(auto it = manifest.cbegin(); it != manifest.cend(); ++it) {
- ietf_map.emplace(it->ietf, it);
- }
-
- json_value_free(jsonv);
-
- // This is temporary! This value will
- // be overriden in init_late after the
- // config system updates config_language
- current_language = manifest.cend();
-}
-
-void language::init_late(void)
-{
- auto user_language = ietf_map.find(config_language.get());
-
- if(user_language != ietf_map.cend()) {
- language::set(user_language->second);
- return;
- }
-
- auto fallback = ietf_map.find(DEFAULT_LANGUAGE);
-
- if(fallback != ietf_map.cend()) {
- language::set(fallback->second);
- return;
- }
-
- spdlog::critical("language: we're doomed!");
- spdlog::critical("language: {} doesn't exist!", DEFAULT_LANGUAGE);
- std::terminate();
-}
-
-void language::set(LanguageIterator new_language)
-{
- if(new_language != manifest.cend()) {
- auto path = std::format("lang/lang.{}.json", new_language->ietf);
-
- auto file = PHYSFS_openRead(path.c_str());
-
- if(file == nullptr) {
- spdlog::warn("language: {}: {}", path, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
- send_language_event(new_language);
- return;
- }
-
- auto source = std::string(PHYSFS_fileLength(file), char(0x00));
- PHYSFS_readBytes(file, source.data(), source.size());
- PHYSFS_close(file);
-
- auto jsonv = json_parse_string(source.c_str());
- const auto json = json_value_get_object(jsonv);
- const auto count = json_object_get_count(json);
-
- if((jsonv == nullptr) || (json == nullptr) || (count == 0)) {
- spdlog::warn("language: {}: parse error", path);
- send_language_event(new_language);
- json_value_free(jsonv);
- return;
- }
-
- language_map.clear();
-
- for(size_t i = 0; i < count; ++i) {
- const auto key = json_object_get_name(json, i);
- const auto value = json_object_get_value_at(json, i);
- const auto value_str = json_value_get_string(value);
-
- if(key && value_str) {
- language_map.emplace(key, value_str);
- continue;
- }
- }
-
- json_value_free(jsonv);
-
- current_language = new_language;
- config_language.set(new_language->ietf.c_str());
- }
-
- send_language_event(new_language);
-}
-
-LanguageIterator language::get_current(void)
-{
- return current_language;
-}
-
-LanguageIterator language::find(const char* ietf)
-{
- const auto it = ietf_map.find(ietf);
- if(it != ietf_map.cend()) {
- return it->second;
- } else {
- return manifest.cend();
- }
-}
-
-LanguageIterator language::cbegin(void)
-{
- return manifest.cbegin();
-}
-
-LanguageIterator language::cend(void)
-{
- return manifest.cend();
-}
-
-const char* language::resolve(const char* key)
-{
- const auto it = language_map.find(key);
- if(it != language_map.cend()) {
- return it->second.c_str();
- } else {
- return key;
- }
-}
-
-std::string language::resolve_gui(const char* key)
-{
- // We need window tags to retain their hierarchy when a language
- // dynamically changes; ImGui allows to provide hidden unique identifiers
- // to GUI primitives that have their name change dynamically, so we're using this
- return std::format("{}###{}", language::resolve(key), key);
-}