fix(FontMgr): also keep in mind game language when generating font texture (#2892)
This commit is contained in:
parent
2ff3105684
commit
f62c8c875e
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Ignore all differences in line endings
|
||||||
|
* -crlf
|
@ -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)"},
|
||||||
|
{eGameLanguage::BRAZILIAN_PORTUGUESE, "Portuguese (Brazil)"},
|
||||||
|
{eGameLanguage::POLISH, "Polish"},
|
||||||
|
{eGameLanguage::RUSSIAN, "Russian"},
|
||||||
|
{eGameLanguage::KOREAN, "Korean"},
|
||||||
|
{eGameLanguage::TRADITIONAL_CHINESE, "Chinese (Traditional)"},
|
||||||
|
{eGameLanguage::JAPANESE, "Japanese"},
|
||||||
|
{eGameLanguage::MEXICAN_SPANISH, "Spanish (Mexico)"},
|
||||||
|
{eGameLanguage::SIMPLIFIED_CHINESE, "Chinese (Simpified)"},
|
||||||
};
|
};
|
||||||
|
}
|
||||||
const LanguageType languages[] = {
|
|
||||||
{0, "English"},
|
|
||||||
{1, "French"},
|
|
||||||
{2, "German"},
|
|
||||||
{3, "Italian"},
|
|
||||||
{4, "Spanish (Spain)"},
|
|
||||||
{5, "Portuguese (Brazil)"},
|
|
||||||
{6, "Polish"},
|
|
||||||
{7, "Russian"},
|
|
||||||
{8, "Korean"},
|
|
||||||
{9, "Chinese (Traditional)"},
|
|
||||||
{10, "Japanese"},
|
|
||||||
{11, "Spanish (Mexico)"},
|
|
||||||
{12, "Chinese (Simpified)"},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
@ -1976,18 +1994,18 @@ enum class eTaskTypeIndex
|
|||||||
enum class eTaskFlags
|
enum class eTaskFlags
|
||||||
{
|
{
|
||||||
ParachuteWhenCoordThresholdIsReached = 1 << 3,
|
ParachuteWhenCoordThresholdIsReached = 1 << 3,
|
||||||
CamShakeOnFall = 1 << 4,
|
CamShakeOnFall = 1 << 4,
|
||||||
PlayRagdollAnim = 1 << 5,
|
PlayRagdollAnim = 1 << 5,
|
||||||
PlayDiveAnim = 1 << 7,
|
PlayDiveAnim = 1 << 7,
|
||||||
NoFallAnimation = 1 << 10,
|
NoFallAnimation = 1 << 10,
|
||||||
NoSlowFall = 1 << 11,
|
NoSlowFall = 1 << 11,
|
||||||
Unk12 = 1 << 12,
|
Unk12 = 1 << 12,
|
||||||
SuperJump = 1 << 15,
|
SuperJump = 1 << 15,
|
||||||
LandOnJump = 1 << 16,
|
LandOnJump = 1 << 16,
|
||||||
BeastJump = 1 << 17,
|
BeastJump = 1 << 17,
|
||||||
BeastJumpWithSuper = SuperJump | BeastJump,
|
BeastJumpWithSuper = SuperJump | BeastJump,
|
||||||
GracefulLanding = NoFallAnimation | NoSlowFall | Unk12 | LandOnJump,
|
GracefulLanding = NoFallAnimation | NoSlowFall | Unk12 | LandOnJump,
|
||||||
RagdollOnFall = BeastJump | PlayRagdollAnim
|
RagdollOnFall = BeastJump | PlayRagdollAnim
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class eDoorId
|
enum class eDoorId
|
||||||
@ -2121,4 +2139,4 @@ enum PedRelationships : int
|
|||||||
Wanted,
|
Wanted,
|
||||||
Hate,
|
Hate,
|
||||||
Indifferent = 255
|
Indifferent = 255
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -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";
|
||||||
}
|
}
|
||||||
@ -343,19 +343,19 @@ namespace lua::network
|
|||||||
ns["set_all_player_coords"] = set_all_player_coords;
|
ns["set_all_player_coords"] = set_all_player_coords;
|
||||||
ns["get_selected_player"] = get_selected_player;
|
ns["get_selected_player"] = get_selected_player;
|
||||||
ns["get_selected_database_player_rockstar_id"] = get_selected_database_player_rockstar_id;
|
ns["get_selected_database_player_rockstar_id"] = get_selected_database_player_rockstar_id;
|
||||||
ns["flag_player_as_modder"] = sol::overload(flag_player_as_modder, flag_player_as_modder_custom_reason);
|
ns["flag_player_as_modder"] = sol::overload(flag_player_as_modder, flag_player_as_modder_custom_reason);
|
||||||
ns["is_player_flagged_as_modder"] = is_player_flagged_as_modder;
|
ns["is_player_flagged_as_modder"] = is_player_flagged_as_modder;
|
||||||
ns["is_player_friend"] = is_player_friend;
|
ns["is_player_friend"] = is_player_friend;
|
||||||
ns["get_flagged_modder_reason"] = get_flagged_modder_reason;
|
ns["get_flagged_modder_reason"] = get_flagged_modder_reason;
|
||||||
ns["force_script_host"] = force_script_host;
|
ns["force_script_host"] = force_script_host;
|
||||||
ns["send_chat_message"] = send_chat_message;
|
ns["send_chat_message"] = send_chat_message;
|
||||||
ns["send_chat_message_to_player"] = send_chat_message_to_player;
|
ns["send_chat_message_to_player"] = send_chat_message_to_player;
|
||||||
ns["get_player_rank"] = get_player_rank;
|
ns["get_player_rank"] = get_player_rank;
|
||||||
ns["get_player_rp"] = get_player_rp;
|
ns["get_player_rp"] = get_player_rp;
|
||||||
ns["get_player_money"] = get_player_money;
|
ns["get_player_money"] = get_player_money;
|
||||||
ns["get_player_wallet"] = get_player_wallet;
|
ns["get_player_wallet"] = get_player_wallet;
|
||||||
ns["get_player_bank"] = get_player_bank;
|
ns["get_player_bank"] = get_player_bank;
|
||||||
ns["get_player_language_id"] = get_player_language_id;
|
ns["get_player_language_id"] = get_player_language_id;
|
||||||
ns["get_player_language_name"] = get_player_language_name;
|
ns["get_player_language_name"] = get_player_language_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
fnt_cfg.MergeMode = true;
|
*font_ptr = tmp_ptr;
|
||||||
io.Fonts->AddFontFromFileTTF(extra_font_file.get_path().string().c_str(), size, &fnt_cfg, extra_glyph_range);
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
@ -68,7 +68,7 @@ namespace big
|
|||||||
rage::rlTaskStatus state{};
|
rage::rlTaskStatus state{};
|
||||||
static rage::rlSessionInfo result_sessions[MAX_SESSIONS_TO_FIND];
|
static rage::rlSessionInfo result_sessions[MAX_SESSIONS_TO_FIND];
|
||||||
|
|
||||||
m_active = true;
|
m_active = true;
|
||||||
m_num_valid_sessions = 0;
|
m_num_valid_sessions = 0;
|
||||||
|
|
||||||
if (g_hooking->get_original<hooks::start_matchmaking_find_sessions>()(0, 1, &component, MAX_SESSIONS_TO_FIND, result_sessions, &m_num_sessions_found, &state))
|
if (g_hooking->get_original<hooks::start_matchmaking_find_sessions>()(0, 1, &component, MAX_SESSIONS_TO_FIND, result_sessions, &m_num_sessions_found, &state))
|
||||||
@ -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
|
||||||
@ -163,7 +163,7 @@ namespace big
|
|||||||
|
|
||||||
if (!g.spoofing.multiplex_session)
|
if (!g.spoofing.multiplex_session)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (status->status)
|
if (status->status)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -190,10 +190,10 @@ namespace big
|
|||||||
}
|
}
|
||||||
|
|
||||||
MatchmakingId primary_id = *out_id; // create a copy if the original memory gets deallocated
|
MatchmakingId primary_id = *out_id; // create a copy if the original memory gets deallocated
|
||||||
std::uint32_t id_hash = rage::joaat(primary_id.m_data1);
|
std::uint32_t id_hash = rage::joaat(primary_id.m_data1);
|
||||||
|
|
||||||
// m_data1 is generated from m_data2 and m_data3
|
// m_data1 is generated from m_data2 and m_data3
|
||||||
m_multiplexed_sessions.emplace(id_hash, std::vector<MatchmakingId>{ });
|
m_multiplexed_sessions.emplace(id_hash, std::vector<MatchmakingId>{});
|
||||||
|
|
||||||
// create multiplex advertisements
|
// create multiplex advertisements
|
||||||
for (int i = 0; i < (g.spoofing.multiplex_count - 1); i++)
|
for (int i = 0; i < (g.spoofing.multiplex_count - 1); i++)
|
||||||
@ -206,7 +206,7 @@ namespace big
|
|||||||
LOG(WARNING) << __FUNCTION__ ": advertise_session returned false for multiplex task " << i;
|
LOG(WARNING) << __FUNCTION__ ": advertise_session returned false for multiplex task " << i;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (status.status == 1)
|
while (status.status == 1)
|
||||||
script::get_current()->yield();
|
script::get_current()->yield();
|
||||||
|
|
||||||
@ -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++;
|
||||||
}
|
}
|
||||||
@ -322,4 +321,4 @@ namespace big
|
|||||||
LOG(WARNING) << __FUNCTION__ ": sending fail code " << msg->m_status;
|
LOG(WARNING) << __FUNCTION__ ": sending fail code " << msg->m_status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
@ -41,11 +42,11 @@ namespace big
|
|||||||
session_str = std::format("{:X}", session.info.m_session_token);
|
session_str = std::format("{:X}", session.info.m_session_token);
|
||||||
|
|
||||||
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,14 +177,15 @@ 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Checkbox("FILTER_MULTIPLEXED_SESSIONS"_T.data(), &g.session_browser.filter_multiplexed_sessions);
|
ImGui::Checkbox("FILTER_MULTIPLEXED_SESSIONS"_T.data(), &g.session_browser.filter_multiplexed_sessions);
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
ImGui::SetTooltip("FILTER_MULTIPLEXED_SESSIONS_DESC"_T.data());
|
ImGui::SetTooltip("FILTER_MULTIPLEXED_SESSIONS_DESC"_T.data());
|
||||||
|
|
||||||
ImGui::Checkbox("EXCLUDE_MODDER_SESSIONS"_T.data(), &g.session_browser.exclude_modder_sessions);
|
ImGui::Checkbox("EXCLUDE_MODDER_SESSIONS"_T.data(), &g.session_browser.exclude_modder_sessions);
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
ImGui::SetTooltip("EXCLUDE_MODDER_SESSIONS_DESC"_T.data());
|
ImGui::SetTooltip("EXCLUDE_MODDER_SESSIONS_DESC"_T.data());
|
||||||
@ -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());
|
||||||
|
@ -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();
|
||||||
|
@ -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>
|
||||||
@ -19,9 +19,9 @@ namespace big
|
|||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 1: return "VIEW_PLAYER_INFO_NAT_TYPE_OPEN"_T.data();
|
case 1: return "VIEW_PLAYER_INFO_NAT_TYPE_OPEN"_T.data();
|
||||||
case 2: return "VIEW_PLAYER_INFO_NAT_TYPE_MODERATE"_T.data();
|
case 2: return "VIEW_PLAYER_INFO_NAT_TYPE_MODERATE"_T.data();
|
||||||
case 3: return "VIEW_PLAYER_INFO_NAT_TYPE_STRICT"_T.data();
|
case 3: return "VIEW_PLAYER_INFO_NAT_TYPE_STRICT"_T.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
return "VIEW_NET_PLAYER_DB_GAME_MODE_UNKNOWN"_T.data();
|
return "VIEW_NET_PLAYER_DB_GAME_MODE_UNKNOWN"_T.data();
|
||||||
@ -31,9 +31,9 @@ namespace big
|
|||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 1: return "VIEW_PLAYER_INFO_CONNECTION_TYPE_DIRECT"_T.data();
|
case 1: return "VIEW_PLAYER_INFO_CONNECTION_TYPE_DIRECT"_T.data();
|
||||||
case 2: return "VIEW_PLAYER_INFO_CONNECTION_TYPE_RELAY"_T.data();
|
case 2: return "VIEW_PLAYER_INFO_CONNECTION_TYPE_RELAY"_T.data();
|
||||||
case 3: return "VIEW_PLAYER_INFO_CONNECTION_TYPE_PEER_RELAY"_T.data();
|
case 3: return "VIEW_PLAYER_INFO_CONNECTION_TYPE_PEER_RELAY"_T.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
return "VIEW_NET_PLAYER_DB_GAME_MODE_UNKNOWN"_T.data();
|
return "VIEW_NET_PLAYER_DB_GAME_MODE_UNKNOWN"_T.data();
|
||||||
@ -60,118 +60,135 @@ namespace big
|
|||||||
}
|
}
|
||||||
|
|
||||||
components::options_modal(
|
components::options_modal(
|
||||||
"VIEW_PLAYER_INFO_EXTRA_INFO"_T.data(),
|
"VIEW_PLAYER_INFO_EXTRA_INFO"_T.data(),
|
||||||
[ped_health, ped_maxhealth] {
|
[ped_health, ped_maxhealth] {
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
auto id = g_player_service->get_selected()->id();
|
auto id = g_player_service->get_selected()->id();
|
||||||
|
|
||||||
if (id != -1)
|
if (id != -1)
|
||||||
{
|
{
|
||||||
auto& stats = scr_globals::gpbd_fm_1.as<GPBD_FM*>()->Entries[id].PlayerStats;
|
auto& stats = scr_globals::gpbd_fm_1.as<GPBD_FM*>()->Entries[id].PlayerStats;
|
||||||
auto& boss_goon = scr_globals::gpbd_fm_3.as<GPBD_FM_3*>()->Entries[id].BossGoon;
|
auto& boss_goon = scr_globals::gpbd_fm_3.as<GPBD_FM_3*>()->Entries[id].BossGoon;
|
||||||
|
|
||||||
const auto money = reinterpret_cast<uint64_t&>(stats.Money);
|
const auto money = reinterpret_cast<uint64_t&>(stats.Money);
|
||||||
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)
|
||||||
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_KD"_T, stats.KdRatio).c_str());
|
.c_str());
|
||||||
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_KILLS"_T, stats.KillsOnPlayers).c_str());
|
ImGui::Text(std::format("{}: {} ({} {})", "VIEW_PLAYER_INFO_HEALTH"_T, ped_health, "VIEW_PLAYER_INFO_MAXHEALTH"_T, ped_maxhealth)
|
||||||
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_DEATHS"_T, stats.DeathsByPlayers).c_str());
|
.c_str());
|
||||||
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_PROSTITUTES"_T, stats.ProstitutesFrequented).c_str());
|
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_KD"_T, stats.KdRatio).c_str());
|
||||||
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_LAP_DANCES"_T, stats.LapDancesBought).c_str());
|
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_KILLS"_T, stats.KillsOnPlayers).c_str());
|
||||||
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_MISSIONS_CREATED"_T, stats.MissionsCreated).c_str());
|
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_DEATHS"_T, stats.DeathsByPlayers).c_str());
|
||||||
auto meltdown_completed = scr_globals::gpbd_fm_1.as<GPBD_FM*>()->Entries[id].MeltdownComplete ? "YES"_T : "NO"_T;
|
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_PROSTITUTES"_T, stats.ProstitutesFrequented).c_str());
|
||||||
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_METLDOWN_COMPLETE"_T, meltdown_completed).c_str());
|
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_LAP_DANCES"_T, stats.LapDancesBought).c_str());
|
||||||
}
|
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_MISSIONS_CREATED"_T, stats.MissionsCreated).c_str());
|
||||||
|
auto meltdown_completed = scr_globals::gpbd_fm_1.as<GPBD_FM*>()->Entries[id].MeltdownComplete ? "YES"_T : "NO"_T;
|
||||||
|
ImGui::Text(std::format("{}: {}", "PLAYER_INFO_METLDOWN_COMPLETE"_T, meltdown_completed).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
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;
|
{
|
||||||
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());
|
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_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}",
|
||||||
ImGui::SameLine();
|
"VIEW_PLAYER_INFO_HOST_TOKEN"_T,
|
||||||
if (ImGui::Button("Copy"))
|
g_player_service->get_selected()->get_net_data()->m_host_token)
|
||||||
{
|
.c_str());
|
||||||
ImGui::SetClipboardText(std::format("{:X}", g_player_service->get_selected()->get_net_data()->m_host_token).data());
|
ImGui::SameLine();
|
||||||
}
|
if (ImGui::Button("Copy"))
|
||||||
|
{
|
||||||
|
ImGui::SetClipboardText(
|
||||||
|
std::format("{:X}", g_player_service->get_selected()->get_net_data()->m_host_token).data());
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (ImGui::Checkbox("TRUST"_T.data(), &g_player_service->get_selected()->is_trusted))
|
if (ImGui::Checkbox("TRUST"_T.data(), &g_player_service->get_selected()->is_trusted))
|
||||||
{
|
{
|
||||||
auto entry = g_player_database_service->get_or_create_player(g_player_service->get_selected());
|
auto entry = g_player_database_service->get_or_create_player(g_player_service->get_selected());
|
||||||
entry->is_trusted = g_player_service->get_selected()->is_trusted;
|
entry->is_trusted = g_player_service->get_selected()->is_trusted;
|
||||||
g_player_database_service->save();
|
g_player_database_service->save();
|
||||||
}
|
}
|
||||||
ImGui::Checkbox("VIEW_PLAYER_INFO_BLOCK_EXPLOSIONS"_T.data(), &g_player_service->get_selected()->block_explosions);
|
ImGui::Checkbox("VIEW_PLAYER_INFO_BLOCK_EXPLOSIONS"_T.data(), &g_player_service->get_selected()->block_explosions);
|
||||||
ImGui::Checkbox("VIEW_PLAYER_INFO_BLOCK_CLONE_CREATE"_T.data(), &g_player_service->get_selected()->block_clone_create);
|
ImGui::Checkbox("VIEW_PLAYER_INFO_BLOCK_CLONE_CREATE"_T.data(), &g_player_service->get_selected()->block_clone_create);
|
||||||
ImGui::Checkbox("VIEW_PLAYER_INFO_BLOCK_CLONE_SYNC"_T.data(), &g_player_service->get_selected()->block_clone_sync);
|
ImGui::Checkbox("VIEW_PLAYER_INFO_BLOCK_CLONE_SYNC"_T.data(), &g_player_service->get_selected()->block_clone_sync);
|
||||||
ImGui::Checkbox("VIEW_PLAYER_INFO_BLOCK_NETWORK_EVENTS"_T.data(), &g_player_service->get_selected()->block_net_events);
|
ImGui::Checkbox("VIEW_PLAYER_INFO_BLOCK_NETWORK_EVENTS"_T.data(), &g_player_service->get_selected()->block_net_events);
|
||||||
ImGui::Checkbox("VIEW_PLAYER_INFO_LOG_CLONES"_T.data(), &g_player_service->get_selected()->log_clones);
|
ImGui::Checkbox("VIEW_PLAYER_INFO_LOG_CLONES"_T.data(), &g_player_service->get_selected()->log_clones);
|
||||||
|
|
||||||
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)
|
{
|
||||||
{
|
if (ImGui::Selectable(name,
|
||||||
if (ImGui::Selectable(name,
|
type == g_player_service->get_selected()->command_access_level.value_or(g.session.chat_command_default_access_level)))
|
||||||
type == g_player_service->get_selected()->command_access_level.value_or(g.session.chat_command_default_access_level)))
|
{
|
||||||
{
|
g.session.chat_command_default_access_level = type;
|
||||||
g.session.chat_command_default_access_level = type;
|
g_player_database_service->get_or_create_player(g_player_service->get_selected())->command_access_level = type;
|
||||||
g_player_database_service->get_or_create_player(g_player_service->get_selected())->command_access_level = type;
|
g_player_database_service->save();
|
||||||
g_player_database_service->save();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (type == g_player_service->get_selected()->command_access_level.value_or(g.session.chat_command_default_access_level))
|
if (type == g_player_service->get_selected()->command_access_level.value_or(g.session.chat_command_default_access_level))
|
||||||
{
|
{
|
||||||
ImGui::SetItemDefaultFocus();
|
ImGui::SetItemDefaultFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndCombo();
|
ImGui::EndCombo();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
"VIEW_PLAYER_INFO_EXTRA_INFO"_T.data());
|
"VIEW_PLAYER_INFO_EXTRA_INFO"_T.data());
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
@ -280,11 +297,11 @@ namespace big
|
|||||||
if (ip)
|
if (ip)
|
||||||
{
|
{
|
||||||
ImGui::Text("PLAYER_INFO_IP"_T.data(),
|
ImGui::Text("PLAYER_INFO_IP"_T.data(),
|
||||||
ip.value().m_field1,
|
ip.value().m_field1,
|
||||||
ip.value().m_field2,
|
ip.value().m_field2,
|
||||||
ip.value().m_field3,
|
ip.value().m_field3,
|
||||||
ip.value().m_field4,
|
ip.value().m_field4,
|
||||||
port);
|
port);
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
@ -308,8 +325,8 @@ namespace big
|
|||||||
ImGui::Text("VIEW_PLAYER_INFO_IP_UNKNOWN"_T.data());
|
ImGui::Text("VIEW_PLAYER_INFO_IP_UNKNOWN"_T.data());
|
||||||
|
|
||||||
auto cxn_type = g_player_service->get_selected()->get_connection_peer() ?
|
auto cxn_type = g_player_service->get_selected()->get_connection_peer() ?
|
||||||
g_player_service->get_selected()->get_connection_peer()->m_peer_address.m_connection_type :
|
g_player_service->get_selected()->get_connection_peer()->m_peer_address.m_connection_type :
|
||||||
0;
|
0;
|
||||||
|
|
||||||
if (g.protections.force_relay_connections && ImGui::IsItemHovered())
|
if (g.protections.force_relay_connections && ImGui::IsItemHovered())
|
||||||
ImGui::SetTooltip("VIEW_PLAYER_INFO_IP_FORCE_RELAY_TOOLTIP"_T.data());
|
ImGui::SetTooltip("VIEW_PLAYER_INFO_IP_FORCE_RELAY_TOOLTIP"_T.data());
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user