Merge pull request #73 from A-lex-Ra/main

smart language detection
This commit is contained in:
MihailRis 2023-12-26 19:18:47 +03:00 committed by GitHub
commit 128bc277b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 41 deletions

View File

@ -68,7 +68,7 @@ Engine::Engine(EngineSettings& settings, EnginePaths* paths)
Audio::initialize(); Audio::initialize();
gui = new gui::GUI(); gui = new gui::GUI();
if (settings.ui.language == "auto") { if (settings.ui.language == "auto") {
settings.ui.language = platform::detect_locale(); settings.ui.language = langs::locale_by_envlocale(platform::detect_locale(), paths->getResources());
} }
setLanguage(settings.ui.language); setLanguage(settings.ui.language);
std::cout << "-- initializing finished" << std::endl; std::cout << "-- initializing finished" << std::endl;

View File

@ -166,18 +166,18 @@ fs::path WorldFiles::getLightsFolder() const {
return directory/fs::path("lights"); return directory/fs::path("lights");
} }
fs::path WorldFiles::getRegionFilename(int x, int y) const { fs::path WorldFiles::getRegionFilename(int x, int z) const {
std::string filename = std::to_string(x) + "_" + std::to_string(y) + ".bin"; std::string filename = std::to_string(x) + "_" + std::to_string(z) + ".bin";
return fs::path(filename); return fs::path(filename);
} }
bool WorldFiles::parseRegionFilename(const std::string& name, int& x, int& y) { bool WorldFiles::parseRegionFilename(const std::string& name, int& x, int& z) {
size_t sep = name.find('_'); size_t sep = name.find('_');
if (sep == std::string::npos || sep == 0 || sep == name.length()-1) if (sep == std::string::npos || sep == 0 || sep == name.length()-1)
return false; return false;
try { try {
x = std::stoi(name.substr(0, sep)); x = std::stoi(name.substr(0, sep));
y = std::stoi(name.substr(sep+1)); z = std::stoi(name.substr(sep+1));
} catch (std::invalid_argument& err) { } catch (std::invalid_argument& err) {
return false; return false;
} catch (std::out_of_range& err) { } catch (std::out_of_range& err) {
@ -248,7 +248,7 @@ files::rafile* WorldFiles::getRegFile(glm::ivec3 coord, const fs::path& folder)
auto iter = std::next(openRegFiles.begin(), rand() % openRegFiles.size()); auto iter = std::next(openRegFiles.begin(), rand() % openRegFiles.size());
openRegFiles.erase(iter); openRegFiles.erase(iter);
} }
fs::path filename = folder/getRegionFilename(coord.x, coord.y); fs::path filename = folder / getRegionFilename(coord[0], coord[1]);
if (!fs::is_regular_file(filename)) { if (!fs::is_regular_file(filename)) {
return nullptr; return nullptr;
} }
@ -297,25 +297,25 @@ ubyte* WorldFiles::readChunkData(int x,
return data; return data;
} }
void WorldFiles::fetchChunks(WorldRegion* region, int x, int y, fs::path folder, int layer) { void WorldFiles::fetchChunks(WorldRegion* region, int x, int z, fs::path folder, int layer) {
ubyte** chunks = region->getChunks(); ubyte** chunks = region->getChunks();
uint32_t* sizes = region->getSizes(); uint32_t* sizes = region->getSizes();
for (size_t i = 0; i < REGION_CHUNKS_COUNT; i++) { for (size_t i = 0; i < REGION_CHUNKS_COUNT; i++) {
int chunk_x = (i % REGION_SIZE) + x * REGION_SIZE; int chunk_x = (i % REGION_SIZE) + x * REGION_SIZE;
int chunk_z = (i / REGION_SIZE) + y * REGION_SIZE; int chunk_z = (i / REGION_SIZE) + z * REGION_SIZE;
if (chunks[i] == nullptr) { if (chunks[i] == nullptr) {
chunks[i] = readChunkData(chunk_x, chunk_z, sizes[i], folder, layer); chunks[i] = readChunkData(chunk_x, chunk_z, sizes[i], folder, layer);
} }
} }
} }
void WorldFiles::writeRegion(int x, int y, WorldRegion* entry, fs::path folder, int layer){ void WorldFiles::writeRegion(int x, int z, WorldRegion* entry, fs::path folder, int layer){
fs::path filename = folder/getRegionFilename(x, y); fs::path filename = folder/getRegionFilename(x, z);
glm::ivec3 regcoord(x, y, layer); glm::ivec3 regcoord(x, z, layer);
if (getRegFile(regcoord, folder)) { if (getRegFile(regcoord, folder)) {
fetchChunks(entry, x, y, folder, layer); fetchChunks(entry, x, z, folder, layer);
openRegFiles.erase(regcoord); openRegFiles.erase(regcoord);
} }
@ -359,7 +359,7 @@ void WorldFiles::writeRegions(regionsmap& regions, const fs::path& folder, int l
if (region->getChunks() == nullptr || !region->isUnsaved()) if (region->getChunks() == nullptr || !region->isUnsaved())
continue; continue;
glm::ivec2 key = it.first; glm::ivec2 key = it.first;
writeRegion(key.x, key.y, region, folder, layer); writeRegion(key[0], key[1], region, folder, layer);
} }
} }

View File

@ -77,6 +77,7 @@ void langs::loadLocalesInfo(const path& resdir, string& fallback) {
auto langs = root->obj("langs"); auto langs = root->obj("langs");
if (langs) { if (langs) {
std::cout << "locales ";
for (auto& entry : langs->map) { for (auto& entry : langs->map) {
auto langInfo = entry.second; auto langInfo = entry.second;
@ -87,9 +88,31 @@ void langs::loadLocalesInfo(const path& resdir, string& fallback) {
continue; continue;
} }
std::cout << "locale " << entry.first << " (" << name << ") added" << std::endl; std::cout << "[" << entry.first << " (" << name << ")] ";
langs::locales_info[entry.first] = LocaleInfo {entry.first, name}; langs::locales_info[entry.first] = LocaleInfo {entry.first, name};
} }
std::cout << "added" << std::endl;
}
}
std::string langs::locale_by_envlocale(const std::string& envlocale, const path& resdir){
string fallback = FALLBACK_DEFAULT;
if (locales_info.size() == 0) {
loadLocalesInfo(resdir, fallback);
}
if (locales_info.find(envlocale) != locales_info.end()) {
std::cout << "locale " << envlocale << " is automatically selected" << std::endl;
return envlocale;
}
else {
for (const auto& loc : locales_info) {
if (loc.first.find(envlocale.substr(0, 2)) != std::string::npos) {
std::cout << "locale " << loc.first << " is automatically selected" << std::endl;
return loc.first;
}
}
std::cout << "locale " << fallback << " is automatically selected" << std::endl;
return fallback;
} }
} }

View File

@ -48,6 +48,9 @@ namespace langs {
const std::filesystem::path& resdir, const std::filesystem::path& resdir,
std::string& fallback); std::string& fallback);
extern std::string locale_by_envlocale(const std::string& envlocale,
const std::filesystem::path& resdir);
extern void load(const std::filesystem::path& resdir, extern void load(const std::filesystem::path& resdir,
const std::string& locale, const std::string& locale,
const std::vector<ContentPack>& packs, const std::vector<ContentPack>& packs,

View File

@ -7,18 +7,6 @@
#include "../typedefs.h" #include "../typedefs.h"
namespace platform {
const std::string DEFAULT_LOCALE = "en_EN";
}
/*System locale to engine locale mapping*/
std::string platform::get_locale_by_lang(std::string lang) {
if (lang == "ru") {
return "ru_RU";
}
return DEFAULT_LOCALE;
}
#ifdef WIN32 #ifdef WIN32
#include <Windows.h> #include <Windows.h>
@ -32,18 +20,12 @@ void platform::configure_encoding() {
std::string platform::detect_locale() { std::string platform::detect_locale() {
LCID lcid = GetThreadLocale(); LCID lcid = GetThreadLocale();
wchar_t preferredLocaleName[LOCALE_NAME_MAX_LENGTH]; wchar_t preferredLocaleName[LOCALE_NAME_MAX_LENGTH];//locale name format: ll-CC
if (LCIDToLocaleName(lcid, preferredLocaleName, LOCALE_NAME_MAX_LENGTH, 0) == 0) { if (LCIDToLocaleName(lcid, preferredLocaleName, LOCALE_NAME_MAX_LENGTH, 0) == 0) {
std::cout << "error in platform::detect_locale! LCIDToLocaleName failed." << std::endl; std::cerr << "error in platform::detect_locale! LCIDToLocaleName failed." << std::endl;
} }
wchar_t parentLocaleName[LOCALE_NAME_MAX_LENGTH]; //ll_CC format
if (GetLocaleInfoEx(preferredLocaleName, LOCALE_SPARENT, parentLocaleName, LOCALE_NAME_MAX_LENGTH) == 0){ return util::wstr2str_utf8(preferredLocaleName).replace(2, 1, "_").substr(0, 5);
std::cout << "error in platform::detect_locale! GetLocaleInfoEx failed." << std::endl;
}
std::wcout << "detected environment language locale: " << parentLocaleName << std::endl;
std::string preferredLang = util::wstr2str_utf8(parentLocaleName);
return get_locale_by_lang(preferredLang);
} }
#else #else
@ -53,12 +35,10 @@ void platform::configure_encoding(){
std::string platform::detect_locale() { std::string platform::detect_locale() {
std::string programLocaleName = setlocale(LC_ALL, nullptr); std::string programLocaleName = setlocale(LC_ALL, nullptr);
std::string preferredLocaleName = setlocale(LC_ALL, ""); std::string preferredLocaleName = setlocale(LC_ALL, ""); //locale name format: ll_CC.encoding
std::cout << "detected environment locale: " << preferredLocaleName << std::endl;
setlocale(LC_ALL, programLocaleName.c_str()); setlocale(LC_ALL, programLocaleName.c_str());
std::string preferredLang = preferredLocaleName.substr(0, 2); return preferredLocaleName.substr(0, 5);
return get_locale_by_lang(preferredLang);
} }
#endif #endif

View File

@ -5,8 +5,8 @@
namespace platform { namespace platform {
extern void configure_encoding(); extern void configure_encoding();
// @return environment locale in ISO format ll_CC
extern std::string detect_locale(); extern std::string detect_locale();
extern std::string get_locale_by_lang(std::string lang);
} }
#endif // UTIL_PLATFORM_H_ #endif // UTIL_PLATFORM_H_