fix(FontMgr): also keep in mind game language when generating font texture (#2892)

This commit is contained in:
Andreas Maerten 2024-07-23 08:47:38 +02:00 committed by GitHub
parent 2ff3105684
commit f62c8c875e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 333 additions and 274 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Ignore all differences in line endings
* -crlf

View File

@ -1,26 +1,21 @@
#pragma once #pragma once
#include "gta/enums.hpp"
namespace big namespace big
{ {
struct LanguageType const std::map<eGameLanguage, const std::string_view> languages = {
{ {eGameLanguage::ENGLISH, "English"},
uint32_t id; {eGameLanguage::FRENCH, "French"},
const char name[32]; {eGameLanguage::GERMAN, "German"},
}; {eGameLanguage::ITALIAN, "Italian"},
{eGameLanguage::SPANISH, "Spanish (Spain)"},
const LanguageType languages[] = { {eGameLanguage::BRAZILIAN_PORTUGUESE, "Portuguese (Brazil)"},
{0, "English"}, {eGameLanguage::POLISH, "Polish"},
{1, "French"}, {eGameLanguage::RUSSIAN, "Russian"},
{2, "German"}, {eGameLanguage::KOREAN, "Korean"},
{3, "Italian"}, {eGameLanguage::TRADITIONAL_CHINESE, "Chinese (Traditional)"},
{4, "Spanish (Spain)"}, {eGameLanguage::JAPANESE, "Japanese"},
{5, "Portuguese (Brazil)"}, {eGameLanguage::MEXICAN_SPANISH, "Spanish (Mexico)"},
{6, "Polish"}, {eGameLanguage::SIMPLIFIED_CHINESE, "Chinese (Simpified)"},
{7, "Russian"},
{8, "Korean"},
{9, "Chinese (Traditional)"},
{10, "Japanese"},
{11, "Spanish (Mexico)"},
{12, "Chinese (Simpified)"},
}; };
} }

View File

@ -2,6 +2,7 @@
#include "backend/reactions/interloper_reaction.hpp" #include "backend/reactions/interloper_reaction.hpp"
#include "backend/reactions/reaction.hpp" #include "backend/reactions/reaction.hpp"
#include "core/data/hud_colors.hpp" #include "core/data/hud_colors.hpp"
#include "core/data/language_codes.hpp"
#include "core/data/ptfx_effects.hpp" #include "core/data/ptfx_effects.hpp"
#include "enums.hpp" #include "enums.hpp"
#include "file_manager.hpp" #include "file_manager.hpp"
@ -723,7 +724,7 @@ namespace big
bool spoof_session_region_type = false; bool spoof_session_region_type = false;
int session_region_type = 0; int session_region_type = 0;
bool spoof_session_language = false; bool spoof_session_language = false;
int session_language = 0; eGameLanguage session_language = eGameLanguage::ENGLISH;
bool spoof_session_player_count = false; bool spoof_session_player_count = false;
int session_player_count = 25; int session_player_count = 25;
int spoof_session_bad_sport_status = 0; int spoof_session_bad_sport_status = 0;
@ -1053,7 +1054,7 @@ namespace big
int region_filter = 0; int region_filter = 0;
bool language_filter_enabled = false; bool language_filter_enabled = false;
int language_filter = 0; eGameLanguage language_filter = eGameLanguage::ENGLISH;
bool pool_filter_enabled = false; bool pool_filter_enabled = false;
int pool_filter = 0; int pool_filter = 0;

View File

@ -3,6 +3,24 @@
constexpr auto MAX_PLAYERS = 32; constexpr auto MAX_PLAYERS = 32;
enum class eGameLanguage : int
{
ENGLISH,
FRENCH,
GERMAN,
ITALIAN,
SPANISH,
BRAZILIAN_PORTUGUESE,
POLISH,
RUSSIAN,
KOREAN,
TRADITIONAL_CHINESE,
JAPANESE,
MEXICAN_SPANISH,
SIMPLIFIED_CHINESE
};
NLOHMANN_JSON_SERIALIZE_ENUM(eGameLanguage, {{eGameLanguage::ENGLISH, "english"}, {eGameLanguage::FRENCH, "french"}, {eGameLanguage::GERMAN, "german"}, {eGameLanguage::ITALIAN, "italian"}, {eGameLanguage::SPANISH, "spanish"}, {eGameLanguage::BRAZILIAN_PORTUGUESE, "brazilian_portuguese"}, {eGameLanguage::POLISH, "polish"}, {eGameLanguage::RUSSIAN, "russian"}, {eGameLanguage::KOREAN, "korean"}, {eGameLanguage::TRADITIONAL_CHINESE, "traditional_chinese"}, {eGameLanguage::JAPANESE, "japanese"}, {eGameLanguage::MEXICAN_SPANISH, "mexican_spanish"}, {eGameLanguage::SIMPLIFIED_CHINESE, "simplified_chinese"}})
enum class ControllerInputs : uint32_t enum class ControllerInputs : uint32_t
{ {
INPUT_NEXT_CAMERA, INPUT_NEXT_CAMERA,

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "function_types.hpp" #include "function_types.hpp"
#include "gta/enums.hpp"
#include <memory/handle.hpp> #include <memory/handle.hpp>
@ -284,7 +285,7 @@ namespace big
functions::handle_chat_message m_handle_chat_message; functions::handle_chat_message m_handle_chat_message;
int* m_language; eGameLanguage* m_language;
functions::update_language m_update_language; functions::update_language m_update_language;
PVOID m_model_spawn_bypass; PVOID m_model_spawn_bypass;

View File

@ -12,6 +12,7 @@
#include "util/session.hpp" #include "util/session.hpp"
#include "util/system.hpp" #include "util/system.hpp"
#include "util/teleport.hpp" #include "util/teleport.hpp"
#include <script/globals/GPBD_FM.hpp> #include <script/globals/GPBD_FM.hpp>
#include <script/globals/GPBD_FM_3.hpp> #include <script/globals/GPBD_FM_3.hpp>
@ -202,7 +203,6 @@ namespace lua::network
if (auto player = big::g_player_service->get_by_id(player_idx)) if (auto player = big::g_player_service->get_by_id(player_idx))
{ {
big::chat::send_message(msg, player); big::chat::send_message(msg, player);
} }
} }
@ -306,7 +306,7 @@ namespace lua::network
if (big::g_player_service->get_by_id(pid)) if (big::g_player_service->get_by_id(pid))
{ {
auto& boss_goon = big::scr_globals::gpbd_fm_3.as<GPBD_FM_3*>()->Entries[pid].BossGoon; auto& boss_goon = big::scr_globals::gpbd_fm_3.as<GPBD_FM_3*>()->Entries[pid].BossGoon;
return big::languages[boss_goon.Language].name; return big::languages.at((eGameLanguage)boss_goon.Language).data();
} }
return "Unknown"; return "Unknown";
} }

View File

@ -1210,7 +1210,7 @@ namespace big
"83 3D ? ? ? ? ? 44 8B C3", "83 3D ? ? ? ? ? 44 8B C3",
[](memory::handle ptr) [](memory::handle ptr)
{ {
g_pointers->m_gta.m_language = ptr.add(2).rip().add(1).as<int*>(); g_pointers->m_gta.m_language = ptr.add(2).rip().add(1).as<eGameLanguage*>();
g_pointers->m_gta.m_update_language = ptr.add(0x38).rip().as<functions::update_language>(); g_pointers->m_gta.m_update_language = ptr.add(0x38).rip().as<functions::update_language>();
} }
}, },

View File

@ -1,6 +1,7 @@
#include "font_mgr.hpp" #include "font_mgr.hpp"
#include "fonts/fonts.hpp" #include "fonts/fonts.hpp"
#include "pointers.hpp"
#include "renderer.hpp" #include "renderer.hpp"
#include "thread_pool.hpp" #include "thread_pool.hpp"
@ -29,57 +30,51 @@ namespace big
m_update_lock.unlock(); m_update_lock.unlock();
} }
void font_mgr::update_required_alphabet_type(eAlphabetType type)
{
m_require_extra = type;
g_thread_pool->push([this] {
rebuild();
});
}
void font_mgr::rebuild() void font_mgr::rebuild()
{ {
m_update_lock.lock(); m_update_lock.lock();
g_renderer.pre_reset(); g_renderer.pre_reset();
const auto extra_font_file = get_available_font_file_for_alphabet_type();
if (m_require_extra != eAlphabetType::LATIN && !extra_font_file.exists())
{
LOG(WARNING) << "Could not find an appropriate font for the current language!";
}
const auto extra_glyph_range = get_imgui_alphabet_type();
auto& io = ImGui::GetIO(); auto& io = ImGui::GetIO();
io.Fonts->Clear(); io.Fonts->Clear();
// default font size const auto required_alphabet_types = get_required_alphabet_types();
{
ImFontConfig fnt_cfg{};
fnt_cfg.FontDataOwnedByAtlas = false;
strcpy(fnt_cfg.Name, "Fnt20px");
io.Fonts->AddFontFromMemoryTTF(const_cast<uint8_t*>(font_storopia),
sizeof(font_storopia),
20.f,
&fnt_cfg,
io.Fonts->GetGlyphRangesDefault());
if (m_require_extra != eAlphabetType::LATIN && extra_font_file.exists())
{
fnt_cfg.MergeMode = true;
io.Fonts->AddFontFromFileTTF(extra_font_file.get_path().string().c_str(), 20.f, &fnt_cfg, extra_glyph_range);
}
io.Fonts->Build();
}
// any other font sizes we need to support
for (auto [size, font_ptr] : m_extra_font_sizes) for (auto [size, font_ptr] : m_extra_font_sizes)
{ {
ImFontConfig fnt_cfg{}; ImFontConfig fnt_cfg{};
fnt_cfg.FontDataOwnedByAtlas = false; fnt_cfg.FontDataOwnedByAtlas = false;
strcpy(fnt_cfg.Name, std::format("Fnt{}px", (int)size).c_str()); strcpy(fnt_cfg.Name, std::format("Fnt{}px", (int)size).c_str());
*font_ptr = io.Fonts->AddFontFromMemoryTTF(const_cast<uint8_t*>(font_storopia), const auto tmp_ptr = io.Fonts->AddFontFromMemoryTTF(const_cast<uint8_t*>(font_storopia),
sizeof(font_storopia), sizeof(font_storopia),
size, size,
&fnt_cfg, &fnt_cfg,
io.Fonts->GetGlyphRangesDefault()); io.Fonts->GetGlyphRangesDefault());
if (m_require_extra != eAlphabetType::LATIN && extra_font_file.exists()) if (font_ptr)
{
*font_ptr = tmp_ptr;
}
for (const auto required_type : required_alphabet_types)
{
const auto font_file = get_available_font_file_for_alphabet_type(required_type);
const auto glyph_range = get_imgui_alphabet_type(required_type);
if (required_type != eAlphabetType::LATIN && font_file.exists())
{ {
fnt_cfg.MergeMode = true; fnt_cfg.MergeMode = true;
io.Fonts->AddFontFromFileTTF(extra_font_file.get_path().string().c_str(), size, &fnt_cfg, extra_glyph_range); io.Fonts->AddFontFromFileTTF(font_file.get_path().string().c_str(), size, &fnt_cfg, glyph_range);
}
} }
io.Fonts->Build(); io.Fonts->Build();
} }
@ -97,20 +92,11 @@ namespace big
m_update_lock.unlock(); m_update_lock.unlock();
} }
void font_mgr::update_required_alphabet_type(eAlphabetType type) file font_mgr::get_available_font_file_for_alphabet_type(const eAlphabetType type) const
{
m_require_extra = type;
g_thread_pool->push([this] {
rebuild();
});
}
file font_mgr::get_available_font_file_for_alphabet_type()
{ {
static const auto fonts_folder = std::filesystem::path(std::getenv("SYSTEMROOT")) / "Fonts"; static const auto fonts_folder = std::filesystem::path(std::getenv("SYSTEMROOT")) / "Fonts";
const auto& fonts = m_fonts.find(m_require_extra); const auto& fonts = m_fonts.find(type);
if (fonts == m_fonts.end()) if (fonts == m_fonts.end())
return {}; return {};
for (const auto& font : fonts->second) for (const auto& font : fonts->second)
@ -124,6 +110,45 @@ namespace big
return {}; return {};
} }
const std::unordered_set<eAlphabetType> font_mgr::get_required_alphabet_types() const
{
auto required_alphabet_types = std::unordered_set<eAlphabetType>({eAlphabetType::LATIN});
required_alphabet_types.insert(get_game_language_alphabet_type());
required_alphabet_types.insert(m_require_extra);
return required_alphabet_types;
}
eAlphabetType font_mgr::get_game_language_alphabet_type()
{
switch (*g_pointers->m_gta.m_language)
{
case eGameLanguage::RUSSIAN: return eAlphabetType::CYRILLIC;
case eGameLanguage::JAPANESE: return eAlphabetType::JAPANESE;
case eGameLanguage::KOREAN: return eAlphabetType::KOREAN;
case eGameLanguage::SIMPLIFIED_CHINESE:
case eGameLanguage::TRADITIONAL_CHINESE: return eAlphabetType::CHINESE;
}
return eAlphabetType::LATIN;
}
const ImWchar* font_mgr::get_imgui_alphabet_type(const eAlphabetType type)
{
auto& io = ImGui::GetIO();
switch (type)
{
case eAlphabetType::CHINESE: return GetGlyphRangesChineseSimplifiedOfficial();
case eAlphabetType::CYRILLIC: return io.Fonts->GetGlyphRangesCyrillic();
case eAlphabetType::JAPANESE: return io.Fonts->GetGlyphRangesJapanese();
case eAlphabetType::KOREAN: return io.Fonts->GetGlyphRangesKorean();
case eAlphabetType::TURKISH: return GetGlyphRangesTurkish();
default:
case eAlphabetType::LATIN: return io.Fonts->GetGlyphRangesDefault();
}
}
const ImWchar* font_mgr::GetGlyphRangesChineseSimplifiedOfficial() const ImWchar* font_mgr::GetGlyphRangesChineseSimplifiedOfficial()
{ {
// Store all official characters for Simplified Chinese. // Store all official characters for Simplified Chinese.
@ -190,20 +215,4 @@ namespace big
}; };
return &icons_ranges_Turkish[0]; return &icons_ranges_Turkish[0];
} }
const ImWchar* font_mgr::get_imgui_alphabet_type()
{
auto& io = ImGui::GetIO();
switch (m_require_extra)
{
case eAlphabetType::CHINESE: return GetGlyphRangesChineseSimplifiedOfficial();
case eAlphabetType::CYRILLIC: return io.Fonts->GetGlyphRangesCyrillic();
case eAlphabetType::JAPANESE: return io.Fonts->GetGlyphRangesJapanese();
case eAlphabetType::KOREAN: return io.Fonts->GetGlyphRangesKorean();
case eAlphabetType::TURKISH: return GetGlyphRangesTurkish();
default:
case eAlphabetType::LATIN: return io.Fonts->GetGlyphRangesDefault();
}
}
} }

View File

@ -15,7 +15,8 @@ namespace big
std::mutex m_update_lock; std::mutex m_update_lock;
public: public:
font_mgr(std::vector<std::pair<float, ImFont**>> extra_font_sizes = {{28.f, &g.window.font_title}, font_mgr(std::vector<std::pair<float, ImFont**>> extra_font_sizes = {{20.f, nullptr},
{28.f, &g.window.font_title},
{24.f, &g.window.font_sub_title}, {24.f, &g.window.font_sub_title},
{18.f, &g.window.font_small}}); {18.f, &g.window.font_small}});
virtual ~font_mgr() = default; virtual ~font_mgr() = default;
@ -33,9 +34,14 @@ namespace big
private: private:
void rebuild(); void rebuild();
file get_available_font_file_for_alphabet_type(); file get_available_font_file_for_alphabet_type(const eAlphabetType type) const;
const ImWchar* GetGlyphRangesChineseSimplifiedOfficial(); const std::unordered_set<eAlphabetType> get_required_alphabet_types() const;
const ImWchar* GetGlyphRangesTurkish();
const ImWchar* get_imgui_alphabet_type(); static eAlphabetType get_game_language_alphabet_type();
static const ImWchar* get_imgui_alphabet_type(const eAlphabetType type);
static const ImWchar* GetGlyphRangesChineseSimplifiedOfficial();
static const ImWchar* GetGlyphRangesTurkish();
}; };
} }

View File

@ -1,9 +1,9 @@
#include "matchmaking_service.hpp" #include "matchmaking_service.hpp"
#include "fiber_pool.hpp"
#include "hooking/hooking.hpp" #include "hooking/hooking.hpp"
#include "pointers.hpp" #include "pointers.hpp"
#include "script.hpp" #include "script.hpp"
#include "fiber_pool.hpp"
#include <network/Network.hpp> #include <network/Network.hpp>
@ -25,7 +25,7 @@ namespace big
attributes->m_param_values[4] = g.spoofing.session_region_type; attributes->m_param_values[4] = g.spoofing.session_region_type;
if (g.spoofing.spoof_session_language) if (g.spoofing.spoof_session_language)
attributes->m_param_values[3] = g.spoofing.session_language; attributes->m_param_values[3] = (uint32_t)g.spoofing.session_language;
if (g.spoofing.spoof_session_player_count && g.spoofing.increase_player_limit) if (g.spoofing.spoof_session_player_count && g.spoofing.increase_player_limit)
attributes->m_param_values[2] = std::min(29, g.spoofing.session_player_count); attributes->m_param_values[2] = std::min(29, g.spoofing.session_player_count);
@ -101,7 +101,7 @@ namespace big
m_found_sessions[i].is_valid = false; m_found_sessions[i].is_valid = false;
if (g.session_browser.language_filter_enabled if (g.session_browser.language_filter_enabled
&& m_found_sessions[i].attributes.language != g.session_browser.language_filter) && (eGameLanguage)m_found_sessions[i].attributes.language != g.session_browser.language_filter)
m_found_sessions[i].is_valid = false; m_found_sessions[i].is_valid = false;
if (g.session_browser.player_count_filter_enabled if (g.session_browser.player_count_filter_enabled
@ -264,7 +264,6 @@ namespace big
LOG(WARNING) << __FUNCTION__ ": update_session_advertisement failed for multiplex task " << i; LOG(WARNING) << __FUNCTION__ ": update_session_advertisement failed for multiplex task " << i;
return; return;
} }
}); });
i++; i++;
} }

View File

@ -295,21 +295,21 @@ namespace big
switch (game_lang) switch (game_lang)
{ {
case 1: preferred_lang = "fr_FR"; break; case eGameLanguage::FRENCH: preferred_lang = "fr_FR"; break;
case 2: preferred_lang = "de_DE"; break; case eGameLanguage::GERMAN: preferred_lang = "de_DE"; break;
case 3: preferred_lang = "it_IT"; break; case eGameLanguage::ITALIAN: preferred_lang = "it_IT"; break;
case 4: case eGameLanguage::SPANISH:
case 11: preferred_lang = "es_ES"; break; case eGameLanguage::MEXICAN_SPANISH: preferred_lang = "es_ES"; break;
case 5: preferred_lang = "pt_BR"; break; case eGameLanguage::BRAZILIAN_PORTUGUESE: preferred_lang = "pt_BR"; break;
case 6: preferred_lang = "pl_PL"; break; case eGameLanguage::POLISH: preferred_lang = "pl_PL"; break;
case 7: preferred_lang = "ru_RU"; break; case eGameLanguage::RUSSIAN: preferred_lang = "ru_RU"; break;
case 8: preferred_lang = "ko_KR"; break; case eGameLanguage::KOREAN: preferred_lang = "ko_KR"; break;
case 9: preferred_lang = "zh_TW"; break; case eGameLanguage::TRADITIONAL_CHINESE: preferred_lang = "zh_TW"; break;
case 10: preferred_lang = "ja_JP"; break; case eGameLanguage::JAPANESE: preferred_lang = "ja_JP"; break;
case 12: preferred_lang = "zh_CN"; break; case eGameLanguage::SIMPLIFIED_CHINESE: preferred_lang = "zh_CN"; break;
} }
if (game_lang == 12 || game_lang == 9) if (game_lang == eGameLanguage::SIMPLIFIED_CHINESE || game_lang == eGameLanguage::TRADITIONAL_CHINESE)
{ {
// Tweaks to make it easier for people playing in the China region // Tweaks to make it easier for people playing in the China region
g.session_browser.filter_multiplexed_sessions = true; g.session_browser.filter_multiplexed_sessions = true;

View File

@ -19,7 +19,8 @@ namespace big
static char name_buf[32]; static char name_buf[32];
static char search[64]; static char search[64];
static char session_info[0x100]{}; static char session_info[0x100]{};
ImGui::Text(std::format("{}: {}", "VIEW_SESSION_TOTAL_SESSIONS_FOUND"_T.data(), g_matchmaking_service->get_num_found_sessions()).c_str()); ImGui::Text(std::format("{}: {}", "VIEW_SESSION_TOTAL_SESSIONS_FOUND"_T.data(), g_matchmaking_service->get_num_found_sessions())
.c_str());
ImGui::SetNextItemWidth(300.f); ImGui::SetNextItemWidth(300.f);
@ -43,8 +44,8 @@ namespace big
auto host_rid = session.info.m_net_player_data.m_gamer_handle.m_rockstar_id; auto host_rid = session.info.m_net_player_data.m_gamer_handle.m_rockstar_id;
auto player = g_player_database_service->get_player_by_rockstar_id(host_rid); auto player = g_player_database_service->get_player_by_rockstar_id(host_rid);
if ((g.session_browser.exclude_modder_sessions && player && player->block_join) || if ((g.session_browser.exclude_modder_sessions && player && player->block_join)
(g.session_browser.filter_multiplexed_sessions && session.attributes.multiplex_count > 1)) || (g.session_browser.filter_multiplexed_sessions && session.attributes.multiplex_count > 1))
continue; continue;
if (components::selectable(session_str, i == selected_session_idx)) if (components::selectable(session_str, i == selected_session_idx))
@ -55,11 +56,17 @@ namespace big
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
{ {
auto tool_tip = std::format("{}: {}\n{}: {}\n{}: {}\n{}: {}\n{}: {:X}", "SESSION_BROWSER_NUM_PLAYERS"_T, session.attributes.player_count, auto tool_tip = std::format("{}: {}\n{}: {}\n{}: {}\n{}: {}\n{}: {:X}",
"REGION"_T, regions[session.attributes.region].name, "SESSION_BROWSER_NUM_PLAYERS"_T,
"LANGUAGE"_T, languages[session.attributes.language].name, session.attributes.player_count,
"SESSION_BROWSER_HOST_RID"_T, session.info.m_net_player_data.m_gamer_handle.m_rockstar_id, // TODO: this is not accurate "REGION"_T,
"SESSION_BROWSER_DISCRIMINATOR"_T, session.attributes.discriminator); regions[session.attributes.region].name,
"LANGUAGE"_T,
languages.at((eGameLanguage)session.attributes.language),
"SESSION_BROWSER_HOST_RID"_T,
session.info.m_net_player_data.m_gamer_handle.m_rockstar_id, // TODO: this is not accurate
"SESSION_BROWSER_DISCRIMINATOR"_T,
session.attributes.discriminator);
ImGui::SetTooltip(tool_tip.c_str()); ImGui::SetTooltip(tool_tip.c_str());
} }
} }
@ -80,9 +87,11 @@ namespace big
auto& session = g_matchmaking_service->get_found_sessions()[selected_session_idx]; auto& session = g_matchmaking_service->get_found_sessions()[selected_session_idx];
ImGui::Text(std::format("{}: {}", "SESSION_BROWSER_NUM_PLAYERS"_T, session.attributes.player_count).c_str()); ImGui::Text(std::format("{}: {}", "SESSION_BROWSER_NUM_PLAYERS"_T, session.attributes.player_count).c_str());
ImGui::Text(std::format("{}: 0x{:X}", "SESSION_BROWSER_DISCRIMINATOR"_T, session.attributes.discriminator).c_str()); ImGui::Text(
std::format("{}: 0x{:X}", "SESSION_BROWSER_DISCRIMINATOR"_T, session.attributes.discriminator).c_str());
ImGui::Text(std::format("{}: {}", "REGION"_T, regions[session.attributes.region].name).c_str()); ImGui::Text(std::format("{}: {}", "REGION"_T, regions[session.attributes.region].name).c_str());
ImGui::Text(std::format("{}: {}", "LANGUAGE"_T, languages[session.attributes.language].name).c_str()); ImGui::Text(
std::format("{}: {}", "LANGUAGE"_T, languages.at((eGameLanguage)session.attributes.language)).c_str());
auto& data = session.info.m_net_player_data; auto& data = session.info.m_net_player_data;
ImGui::Text(std::format("{}: {}", "SESSION_BROWSER_HOST_RID"_T, data.m_gamer_handle.m_rockstar_id).c_str()); ImGui::Text(std::format("{}: {}", "SESSION_BROWSER_HOST_RID"_T, data.m_gamer_handle.m_rockstar_id).c_str());
@ -143,13 +152,13 @@ namespace big
{ {
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::BeginCombo("###language_select", languages[g.session_browser.language_filter].name)) if (ImGui::BeginCombo("###language_select", languages.at(g.session_browser.language_filter).data()))
{ {
for (const auto& language : languages) for (const auto& [id, language] : languages)
{ {
if (ImGui::Selectable(language.name, g.session_browser.language_filter == language.id)) if (ImGui::Selectable(language.data(), g.session_browser.language_filter == id))
{ {
g.session_browser.language_filter = language.id; g.session_browser.language_filter = id;
}; };
} }
ImGui::EndCombo(); ImGui::EndCombo();
@ -168,7 +177,8 @@ namespace big
if (g.session_browser.pool_filter_enabled) if (g.session_browser.pool_filter_enabled)
{ {
ImGui::SameLine(); ImGui::SameLine();
static const std::string pool_filter_options = std::string("NORMAL"_T.data()) + '\0' + std::string("BAD_SPORT"_T.data()); static const std::string pool_filter_options =
std::string("NORMAL"_T.data()) + '\0' + std::string("BAD_SPORT"_T.data());
ImGui::Combo("###pooltype", &g.session_browser.pool_filter, pool_filter_options.c_str()); ImGui::Combo("###pooltype", &g.session_browser.pool_filter, pool_filter_options.c_str());
} }
@ -186,7 +196,8 @@ namespace big
if (ImGui::TreeNode("SORTING"_T.data())) if (ImGui::TreeNode("SORTING"_T.data()))
{ {
static const std::string sort_by_options = std::string("OFF"_T.data()) + '\0' + std::string("PLAYER_COUNT"_T.data()); static const std::string sort_by_options = std::string("OFF"_T.data()) + '\0' + std::string("PLAYER_COUNT"_T.data());
static const std::string sort_direction_options = std::string("ASCENDING"_T.data()) + '\0' + std::string("DESCENDING"_T.data()); static const std::string sort_direction_options =
std::string("ASCENDING"_T.data()) + '\0' + std::string("DESCENDING"_T.data());
ImGui::Combo("SORT_BY"_T.data(), &g.session_browser.sort_method, sort_by_options.c_str()); ImGui::Combo("SORT_BY"_T.data(), &g.session_browser.sort_method, sort_by_options.c_str());
if (g.session_browser.sort_method != 0) if (g.session_browser.sort_method != 0)
ImGui::Combo("DIRECTION"_T.data(), &g.session_browser.sort_direction, sort_direction_options.c_str()); ImGui::Combo("DIRECTION"_T.data(), &g.session_browser.sort_direction, sort_direction_options.c_str());

View File

@ -130,13 +130,13 @@ namespace big
{ {
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::BeginCombo("###language_select", languages[g.spoofing.session_language].name)) if (ImGui::BeginCombo("###language_select", languages.at(g.spoofing.session_language).data()))
{ {
for (const auto& language : languages) for (const auto& [id, language] : languages)
{ {
if (ImGui::Selectable(language.name, g.spoofing.session_language == language.id)) if (ImGui::Selectable(language.data(), g.spoofing.session_language == id))
{ {
g.spoofing.session_language = language.id; g.spoofing.session_language = id;
}; };
} }
ImGui::EndCombo(); ImGui::EndCombo();

View File

@ -2,10 +2,10 @@
#include "core/data/language_codes.hpp" #include "core/data/language_codes.hpp"
#include "core/scr_globals.hpp" #include "core/scr_globals.hpp"
#include "natives.hpp" #include "natives.hpp"
#include "services/player_database/player_database_service.hpp"
#include "views/view.hpp"
#include "services/gta_data/gta_data_service.hpp" #include "services/gta_data/gta_data_service.hpp"
#include "services/player_database/player_database_service.hpp"
#include "util/session.hpp" #include "util/session.hpp"
#include "views/view.hpp"
#include <network/netConnection.hpp> #include <network/netConnection.hpp>
#include <script/globals/GPBD_FM.hpp> #include <script/globals/GPBD_FM.hpp>
@ -75,15 +75,18 @@ namespace big
const auto wallet = reinterpret_cast<uint64_t&>(stats.WalletBalance); const auto wallet = reinterpret_cast<uint64_t&>(stats.WalletBalance);
if (boss_goon.Language >= 0 && boss_goon.Language < 13) if (boss_goon.Language >= 0 && boss_goon.Language < 13)
ImGui::Text("PLAYER_INFO_LANGUAGE"_T.data(), languages[boss_goon.Language].name); ImGui::Text("PLAYER_INFO_LANGUAGE"_T.data(), languages.at((eGameLanguage)boss_goon.Language).data());
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_CEO_NAME"_T, boss_goon.GangName.Data).c_str()); ImGui::Text(std::format("{}: {}", "PLAYER_INFO_CEO_NAME"_T, boss_goon.GangName.Data).c_str());
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_MC_NAME"_T, boss_goon.ClubhouseName.Data).c_str()); ImGui::Text(std::format("{}: {}", "PLAYER_INFO_MC_NAME"_T, boss_goon.ClubhouseName.Data).c_str());
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_WALLET"_T, wallet).c_str()); ImGui::Text(std::format("{}: {}", "PLAYER_INFO_WALLET"_T, wallet).c_str());
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_BANK"_T, money - wallet).c_str()); ImGui::Text(std::format("{}: {}", "PLAYER_INFO_BANK"_T, money - wallet).c_str());
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_TOTAL_MONEY"_T, money).c_str()); ImGui::Text(std::format("{}: {}", "PLAYER_INFO_TOTAL_MONEY"_T, money).c_str());
ImGui::Text(std::format("{}: {} ({} {})", "PLAYER_INFO_RANK"_T, stats.Rank, "PLAYER_INFO_RANK_RP"_T, stats.RP).c_str()); ImGui::Text(
ImGui::Text(std::format("{}: {} ({} {})", "VIEW_PLAYER_INFO_HEALTH"_T, ped_health, "VIEW_PLAYER_INFO_MAXHEALTH"_T, ped_maxhealth).c_str()); std::format("{}: {} ({} {})", "PLAYER_INFO_RANK"_T, stats.Rank, "PLAYER_INFO_RANK_RP"_T, stats.RP)
.c_str());
ImGui::Text(std::format("{}: {} ({} {})", "VIEW_PLAYER_INFO_HEALTH"_T, ped_health, "VIEW_PLAYER_INFO_MAXHEALTH"_T, ped_maxhealth)
.c_str());
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_KD"_T, stats.KdRatio).c_str()); ImGui::Text(std::format("{}: {}", "PLAYER_INFO_KD"_T, stats.KdRatio).c_str());
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_KILLS"_T, stats.KillsOnPlayers).c_str()); ImGui::Text(std::format("{}: {}", "PLAYER_INFO_KILLS"_T, stats.KillsOnPlayers).c_str());
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_DEATHS"_T, stats.DeathsByPlayers).c_str()); ImGui::Text(std::format("{}: {}", "PLAYER_INFO_DEATHS"_T, stats.DeathsByPlayers).c_str());
@ -100,33 +103,48 @@ namespace big
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::Text(std::format("{}: {}", "VIEW_PLAYER_INFO_NAT_TYPE"_T, get_nat_type_str(g_player_service->get_selected()->get_net_data()->m_nat_type)).c_str()); ImGui::Text(std::format("{}: {}",
"VIEW_PLAYER_INFO_NAT_TYPE"_T,
get_nat_type_str(g_player_service->get_selected()->get_net_data()->m_nat_type))
.c_str());
if (auto peer = g_player_service->get_selected()->get_connection_peer()) if (auto peer = g_player_service->get_selected()->get_connection_peer())
{ {
ImGui::Text(std::format("{}: {}", "VIEW_PLAYER_INFO_CONNECTION_TYPE"_T, get_connection_type_str(peer->m_peer_address.m_connection_type)).c_str()); ImGui::Text(std::format("{}: {}",
"VIEW_PLAYER_INFO_CONNECTION_TYPE"_T,
get_connection_type_str(peer->m_peer_address.m_connection_type))
.c_str());
if (peer->m_peer_address.m_connection_type == 2) if (peer->m_peer_address.m_connection_type == 2)
{ {
auto ip = peer->m_relay_address.m_relay_address; auto ip = peer->m_relay_address.m_relay_address;
ImGui::Text(std::format("{}: {}.{}.{}.{}", "VIEW_PLAYER_INFO_RELAY_IP"_T, ip.m_field1, ip.m_field2, ip.m_field3, ip.m_field4).c_str()); ImGui::Text(std::format("{}: {}.{}.{}.{}", "VIEW_PLAYER_INFO_RELAY_IP"_T, ip.m_field1, ip.m_field2, ip.m_field3, ip.m_field4)
.c_str());
} }
else if (peer->m_peer_address.m_connection_type == 3) else if (peer->m_peer_address.m_connection_type == 3)
{ {
auto ip = peer->m_peer_address.m_relay_address; auto ip = peer->m_peer_address.m_relay_address;
ImGui::Text(std::format("{}: {}.{}.{}.{}", "VIEW_PLAYER_INFO_PEER_RELAY_IP"_T, ip.m_field1, ip.m_field2, ip.m_field3, ip.m_field4).c_str()); ImGui::Text(std::format("{}: {}.{}.{}.{}", "VIEW_PLAYER_INFO_PEER_RELAY_IP"_T, ip.m_field1, ip.m_field2, ip.m_field3, ip.m_field4)
.c_str());
} }
ImGui::Text(std::format("{}: {}", "VIEW_PLAYER_INFO_NUM_MESSAGES_SENT"_T, peer->m_num_messages_batched).c_str()); ImGui::Text(
ImGui::Text(std::format("{}: {}", "VIEW_PLAYER_INFO_NUM_RELIABLES_SENT"_T, peer->m_num_reliable_messages_batched).c_str()); std::format("{}: {}", "VIEW_PLAYER_INFO_NUM_MESSAGES_SENT"_T, peer->m_num_messages_batched).c_str());
ImGui::Text(std::format("{}: {}", "VIEW_PLAYER_INFO_NUM_RELIABLES_RESENT"_T, peer->m_num_resent_reliable_messages_batched).c_str()); ImGui::Text(std::format("{}: {}", "VIEW_PLAYER_INFO_NUM_RELIABLES_SENT"_T, peer->m_num_reliable_messages_batched)
.c_str());
ImGui::Text(std::format("{}: {}", "VIEW_PLAYER_INFO_NUM_RELIABLES_RESENT"_T, peer->m_num_resent_reliable_messages_batched)
.c_str());
} }
ImGui::Text(std::format("{}: {:X}", "VIEW_PLAYER_INFO_HOST_TOKEN"_T, g_player_service->get_selected()->get_net_data()->m_host_token).c_str()); ImGui::Text(std::format("{}: {:X}",
"VIEW_PLAYER_INFO_HOST_TOKEN"_T,
g_player_service->get_selected()->get_net_data()->m_host_token)
.c_str());
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Copy")) if (ImGui::Button("Copy"))
{ {
ImGui::SetClipboardText(std::format("{:X}", g_player_service->get_selected()->get_net_data()->m_host_token).data()); ImGui::SetClipboardText(
std::format("{:X}", g_player_service->get_selected()->get_net_data()->m_host_token).data());
} }
ImGui::EndGroup(); ImGui::EndGroup();
@ -148,8 +166,7 @@ namespace big
ImGui::Separator(); ImGui::Separator();
if (ImGui::BeginCombo("CHAT_COMMAND_PERMISSIONS"_T.data(), if (ImGui::BeginCombo("CHAT_COMMAND_PERMISSIONS"_T.data(),
COMMAND_ACCESS_LEVELS[g_player_service->get_selected()->command_access_level.value_or( COMMAND_ACCESS_LEVELS[g_player_service->get_selected()->command_access_level.value_or(g.session.chat_command_default_access_level)]))
g.session.chat_command_default_access_level)]))
{ {
for (const auto& [type, name] : COMMAND_ACCESS_LEVELS) for (const auto& [type, name] : COMMAND_ACCESS_LEVELS)
{ {

View File

@ -27,20 +27,20 @@ namespace big
ImGui::EndCombo(); ImGui::EndCombo();
} }
if (ImGui::BeginCombo("VIEW_SETTINGS_GAME_LANGUAGE"_T.data(), languages[*g_pointers->m_gta.m_language].name)) if (ImGui::BeginCombo("VIEW_SETTINGS_GAME_LANGUAGE"_T.data(), languages.at(*g_pointers->m_gta.m_language).data()))
{ {
for (auto& language : languages) for (auto& [id, language] : languages)
{ {
if (ImGui::Selectable(language.name, language.id == *g_pointers->m_gta.m_language)) if (ImGui::Selectable(language.data(), id == *g_pointers->m_gta.m_language))
{ {
*g_pointers->m_gta.m_language = language.id; *g_pointers->m_gta.m_language = id;
g_fiber_pool->queue_job([] { g_fiber_pool->queue_job([] {
g_pointers->m_gta.m_update_language(true); g_pointers->m_gta.m_update_language(true);
}); });
} }
if (language.id == *g_pointers->m_gta.m_language) if (id == *g_pointers->m_gta.m_language)
{ {
ImGui::SetItemDefaultFocus(); ImGui::SetItemDefaultFocus();
} }