iw4x-client/src/Components/Modules/Localization.cpp

219 lines
6.9 KiB
C++
Raw Normal View History

2016-07-11 11:14:58 -04:00
#include "STDInclude.hpp"
namespace Components
{
2016-09-08 15:41:01 -04:00
std::mutex Localization::LocalizeMutex;
2016-07-11 11:14:58 -04:00
Dvar::Var Localization::UseLocalization;
2016-07-22 06:52:12 -04:00
Utils::Memory::Allocator Localization::MemAllocator;
2016-07-11 11:14:58 -04:00
std::map<std::string, Game::LocalizedEntry*> Localization::LocalizeMap;
std::map<std::string, Game::LocalizedEntry*> Localization::TempLocalizeMap;
void Localization::Set(std::string key, std::string value)
{
2016-09-08 15:41:01 -04:00
std::lock_guard<std::mutex> _(Localization::LocalizeMutex);
2016-07-11 11:14:58 -04:00
if (Localization::LocalizeMap.find(key) != Localization::LocalizeMap.end())
{
Game::LocalizedEntry* entry = Localization::LocalizeMap[key];
2016-07-22 06:52:12 -04:00
char* newStaticValue = Localization::MemAllocator.DuplicateString(value);
2016-07-11 11:14:58 -04:00
if (!newStaticValue) return;
2016-07-22 06:52:12 -04:00
if (entry->value) Localization::MemAllocator.Free(entry->value);
2016-07-11 11:14:58 -04:00
entry->value = newStaticValue;
return;
}
2016-07-22 06:52:12 -04:00
Game::LocalizedEntry* entry = Localization::MemAllocator.Allocate<Game::LocalizedEntry>();
2016-07-11 11:14:58 -04:00
if (!entry) return;
2016-07-22 06:52:12 -04:00
entry->name = Localization::MemAllocator.DuplicateString(key);
2016-07-11 11:14:58 -04:00
if (!entry->name)
{
2016-07-22 06:52:12 -04:00
Localization::MemAllocator.Free(entry);
2016-07-11 11:14:58 -04:00
return;
}
2016-07-22 06:52:12 -04:00
entry->value = Localization::MemAllocator.DuplicateString(value);
2016-07-11 11:14:58 -04:00
if (!entry->value)
{
2016-07-22 06:52:12 -04:00
Localization::MemAllocator.Free(entry->name);
Localization::MemAllocator.Free(entry);
2016-07-11 11:14:58 -04:00
return;
}
Localization::LocalizeMap[key] = entry;
}
const char* Localization::Get(const char* key)
{
if (!Localization::UseLocalization.Get<bool>()) return key;
Game::LocalizedEntry* entry = nullptr;
2016-09-08 15:41:01 -04:00
std::lock_guard<std::mutex> _(Localization::LocalizeMutex);
2016-07-11 11:14:58 -04:00
if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end())
{
entry = Localization::TempLocalizeMap[key];
}
else if (Localization::LocalizeMap.find(key) != Localization::LocalizeMap.end())
{
entry = Localization::LocalizeMap[key];
}
2016-09-08 15:41:01 -04:00
if (!entry || !entry->value)
{
Localization::LocalizeMutex.unlock();
entry = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_LOCALIZE, key).localize;
Localization::LocalizeMutex.lock();
}
2016-07-11 11:14:58 -04:00
if (entry && entry->value)
{
return entry->value;
}
return key;
}
void Localization::SetTemp(std::string key, std::string value)
{
2016-09-08 15:41:01 -04:00
std::lock_guard<std::mutex> _(Localization::LocalizeMutex);
2016-07-11 11:14:58 -04:00
if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end())
{
Game::LocalizedEntry* entry = Localization::TempLocalizeMap[key];
2016-07-22 06:52:12 -04:00
if(entry->value) Localization::MemAllocator.Free(entry->value);
entry->value = Localization::MemAllocator.DuplicateString(value);
2016-07-11 11:14:58 -04:00
}
else
{
2016-07-22 06:52:12 -04:00
Game::LocalizedEntry* entry = Localization::MemAllocator.Allocate<Game::LocalizedEntry>();
2016-07-11 11:14:58 -04:00
if (!entry) return;
2016-07-22 06:52:12 -04:00
entry->name = Localization::MemAllocator.DuplicateString(key);
2016-07-11 11:14:58 -04:00
if (!entry->name)
{
2016-07-22 06:52:12 -04:00
Localization::MemAllocator.Free(entry);
2016-07-11 11:14:58 -04:00
return;
}
2016-07-22 06:52:12 -04:00
entry->value = Localization::MemAllocator.DuplicateString(value);
2016-07-11 11:14:58 -04:00
if (!entry->value)
{
2016-07-22 06:52:12 -04:00
Localization::MemAllocator.Free(entry->name);
Localization::MemAllocator.Free(entry);
2016-07-11 11:14:58 -04:00
return;
}
Localization::TempLocalizeMap[key] = entry;
}
}
void Localization::ClearTemp()
{
2016-09-08 15:41:01 -04:00
std::lock_guard<std::mutex> _(Localization::LocalizeMutex);
2016-07-11 11:14:58 -04:00
for (auto i = Localization::TempLocalizeMap.begin(); i != Localization::TempLocalizeMap.end(); ++i)
{
if (i->second)
{
2016-07-22 06:52:12 -04:00
if (i->second->name) Localization::MemAllocator.Free(i->second->name);
if (i->second->value) Localization::MemAllocator.Free(i->second->value);
Localization::MemAllocator.Free(i->second);
2016-07-11 11:14:58 -04:00
}
}
Localization::TempLocalizeMap.clear();
}
2016-08-17 20:18:45 -04:00
void __stdcall Localization::SetStringStub(const char* key, const char* value, bool /*isEnglish*/)
2016-07-11 11:14:58 -04:00
{
Localization::Set(key, value);
}
DWORD Localization::SELoadLanguageStub()
{
if (ZoneBuilder::IsEnabled())
{
if (FileSystem::File(fmt::sprintf("localizedstrings/iw4x_%s.str", Game::Win_GetLanguage())).Exists())
{
Game::SE_Load(Utils::String::VA("localizedstrings/iw4x_%s.str", Game::Win_GetLanguage()), 0);
}
else
{
Game::SE_Load("localizedstrings/iw4x_english.str", 0);
}
}
2016-07-11 11:14:58 -04:00
return Utils::Hook::Call<DWORD()>(0x629E20)();
}
Localization::Localization()
{
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_LOCALIZE, [] (Game::XAssetType, std::string filename)
{
Game::XAssetHeader header = { 0 };
2016-09-08 15:41:01 -04:00
std::lock_guard<std::mutex> _(Localization::LocalizeMutex);
2016-07-11 11:14:58 -04:00
if (Localization::TempLocalizeMap.find(filename) != Localization::TempLocalizeMap.end())
{
header.localize = Localization::TempLocalizeMap[filename];
}
else if (Localization::LocalizeMap.find(filename) != Localization::LocalizeMap.end())
{
header.localize = Localization::LocalizeMap[filename];
}
return header;
});
// Resolving hook
Utils::Hook(0x629B90, Localization::Get, HOOK_JUMP).Install()->Quick();
// Set loading entry point
Utils::Hook(0x41D859, Localization::SELoadLanguageStub, HOOK_CALL).Install()->Quick();
// Overwrite SetString
Utils::Hook(0x4CE5EE, Localization::SetStringStub, HOOK_CALL).Install()->Quick();
/*
2016-07-11 11:14:58 -04:00
// TODO: Get rid of those!
Localization::Set("MENU_SEARCHINGFORGAMES_100MS", "");
Localization::Set("MP_SEARCHING_FOR_PLAYER", "Waiting");
Localization::Set("MENU_WAITING_FOR_MORE_PLAYERS_TEAMS", "Waiting for more players to balance teams");
Localization::Set("MENU_MOTD", "News");
Localization::Set("MENU_MOTD_CAPS", "NEWS");
Localization::Set("MENU_MODS", "Mods");
Localization::Set("MENU_MODS_CAPS", "MODS");
Localization::Set("MPUI_DESC_MODS", "Browse your Mods.");
Localization::Set("MENU_THEATER", "Theater");
Localization::Set("MENU_THEATER_CAPS", "THEATER");
Localization::Set("MPUI_DESC_THEATER", "View your played matches.");
Localization::Set("MENU_FOV", "Field of View");
Localization::Set("MENU_NOBORDER", "Disable Window Border");
Localization::Set("MENU_NATIVECURSOR", "Display native cursor");
Localization::Set("MENU_MAXPACKETS", "Max. Packets per frame");
Localization::Set("MENU_SNAPS", "Snapshot rate");
Localization::Set("MENU_LAGOMETER", "Show Lagometer");
Localization::Set("MENU_DRAWFPS", "Show FPS");
Localization::Set("MENU_FPSLABELS", "Show FPS Labels");
Localization::Set("MENU_NEWCOLORS", "Use new color codes");
Localization::Set("MPUI_DESC_OPTIONS", "Set your game options.");
Localization::Set("MPUI_DESC_QUIT", "Quit the game.");
Localization::Set("PLATFORM_REFRESH_LIST", "Refresh List ^0- ^3F5");
Localization::Set("PLATFORM_REFRESH_LIST_CAPS", "REFRESH LIST ^0- ^/*3F5");
*/
2016-07-11 11:14:58 -04:00
Localization::UseLocalization = Dvar::Register<bool>("ui_localize", true, Game::dvar_flag::DVAR_FLAG_NONE, "Use localization strings");
}
Localization::~Localization()
{
Localization::ClearTemp();
Localization::LocalizeMap.clear();
2016-07-22 06:52:12 -04:00
Localization::MemAllocator.Clear();
2016-07-11 11:14:58 -04:00
}
}