2016-01-04 14:58:00 -05:00
|
|
|
#include "STDInclude.hpp"
|
2015-12-25 17:17:29 -05:00
|
|
|
|
|
|
|
namespace Components
|
|
|
|
{
|
2015-12-25 20:51:58 -05:00
|
|
|
Dvar::Var Localization::UseLocalization;
|
2016-01-12 13:08:26 -05:00
|
|
|
std::map<std::string, Game::LocalizedEntry*> Localization::LocalizeMap;
|
|
|
|
std::map<std::string, Game::LocalizedEntry*> Localization::TempLocalizeMap;
|
2015-12-25 17:17:29 -05:00
|
|
|
|
|
|
|
void Localization::Set(const char* key, const char* value)
|
|
|
|
{
|
2016-02-06 13:22:40 -05:00
|
|
|
if (Localization::LocalizeMap.find(key) != Localization::LocalizeMap.end())
|
|
|
|
{
|
|
|
|
Game::LocalizedEntry* entry = Localization::LocalizeMap[key];
|
|
|
|
|
|
|
|
char* newStaticValue = Utils::Memory::DuplicateString(value);
|
|
|
|
if (!newStaticValue) return;
|
|
|
|
if (entry->value) Utils::Memory::Free(entry->value);
|
|
|
|
entry->value = newStaticValue;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-12 13:08:26 -05:00
|
|
|
Game::LocalizedEntry* entry = Utils::Memory::AllocateArray<Game::LocalizedEntry>(1);
|
|
|
|
if (!entry) return;
|
|
|
|
|
|
|
|
entry->name = Utils::Memory::DuplicateString(key);
|
|
|
|
if (!entry->name)
|
|
|
|
{
|
|
|
|
Utils::Memory::Free(entry);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
entry->value = Utils::Memory::DuplicateString(value);
|
|
|
|
if (!entry->value)
|
|
|
|
{
|
|
|
|
Utils::Memory::Free(entry->name);
|
|
|
|
Utils::Memory::Free(entry);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Localization::LocalizeMap[key] = entry;
|
2015-12-25 17:17:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
const char* Localization::Get(const char* key)
|
|
|
|
{
|
2015-12-25 20:51:58 -05:00
|
|
|
if (!Localization::UseLocalization.Get<bool>()) return key;
|
|
|
|
|
2016-01-12 13:08:26 -05:00
|
|
|
Game::LocalizedEntry* entry = nullptr;
|
|
|
|
|
|
|
|
if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end())
|
2015-12-25 17:17:29 -05:00
|
|
|
{
|
2016-01-12 13:08:26 -05:00
|
|
|
entry = Localization::TempLocalizeMap[key];
|
|
|
|
}
|
|
|
|
else if (Localization::LocalizeMap.find(key) != Localization::LocalizeMap.end())
|
|
|
|
{
|
|
|
|
entry = Localization::LocalizeMap[key];
|
2015-12-25 17:17:29 -05:00
|
|
|
}
|
|
|
|
|
2016-01-12 13:08:26 -05:00
|
|
|
if (!entry || !entry->value) entry = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_LOCALIZE, key).localize;
|
2015-12-25 17:17:29 -05:00
|
|
|
|
2016-01-12 13:08:26 -05:00
|
|
|
if (entry && entry->value)
|
2015-12-25 17:17:29 -05:00
|
|
|
{
|
|
|
|
return entry->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return key;
|
|
|
|
}
|
|
|
|
|
2016-01-12 13:08:26 -05:00
|
|
|
void Localization::SetTemp(std::string key, std::string value)
|
|
|
|
{
|
|
|
|
if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end())
|
|
|
|
{
|
|
|
|
Game::LocalizedEntry* entry = Localization::TempLocalizeMap[key];
|
|
|
|
if(entry->value) Utils::Memory::Free(entry->value);
|
|
|
|
entry->value = Utils::Memory::DuplicateString(value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Game::LocalizedEntry* entry = Utils::Memory::AllocateArray<Game::LocalizedEntry>(1);
|
|
|
|
if (!entry) return;
|
|
|
|
|
|
|
|
entry->name = Utils::Memory::DuplicateString(key);
|
|
|
|
if (!entry->name)
|
|
|
|
{
|
|
|
|
Utils::Memory::Free(entry);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
entry->value = Utils::Memory::DuplicateString(value);
|
|
|
|
if (!entry->value)
|
|
|
|
{
|
|
|
|
Utils::Memory::Free(entry->name);
|
|
|
|
Utils::Memory::Free(entry);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Localization::TempLocalizeMap[key] = entry;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Localization::ClearTemp()
|
|
|
|
{
|
2016-01-24 13:58:13 -05:00
|
|
|
for (auto i = Localization::TempLocalizeMap.begin(); i != Localization::TempLocalizeMap.end(); ++i)
|
2016-01-12 13:08:26 -05:00
|
|
|
{
|
|
|
|
if (i->second)
|
|
|
|
{
|
|
|
|
if (i->second->name) Utils::Memory::Free(i->second->name);
|
|
|
|
if (i->second->value) Utils::Memory::Free(i->second->value);
|
|
|
|
Utils::Memory::Free(i->second);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Localization::TempLocalizeMap.clear();
|
|
|
|
}
|
|
|
|
|
2016-01-03 09:44:51 -05:00
|
|
|
void __stdcall Localization::SetStringStub(const char* key, const char* value, bool isEnglish)
|
|
|
|
{
|
|
|
|
Localization::Set(key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD Localization::SELoadLanguageStub()
|
|
|
|
{
|
|
|
|
//'official' iw4m localized strings
|
|
|
|
Game::SE_Load("localizedstrings/iw4m.str", 0);
|
|
|
|
|
|
|
|
return Utils::Hook::Call<DWORD()>(0x629E20)();
|
|
|
|
}
|
|
|
|
|
2015-12-25 17:17:29 -05:00
|
|
|
Localization::Localization()
|
|
|
|
{
|
2016-02-06 07:37:23 -05:00
|
|
|
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_LOCALIZE, [] (Game::XAssetType, std::string filename)
|
2016-01-12 13:08:26 -05:00
|
|
|
{
|
|
|
|
Game::XAssetHeader header = { 0 };
|
|
|
|
|
|
|
|
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;
|
|
|
|
});
|
|
|
|
|
2016-01-03 09:44:51 -05:00
|
|
|
// Resolving hook
|
2015-12-25 17:17:29 -05:00
|
|
|
Utils::Hook(0x629B90, Localization::Get, HOOK_JUMP).Install()->Quick();
|
|
|
|
|
2016-01-03 09:44:51 -05:00
|
|
|
// Set loading entry point
|
|
|
|
Utils::Hook(0x41D859, Localization::SELoadLanguageStub, HOOK_CALL).Install()->Quick();
|
|
|
|
|
|
|
|
// Overwrite SetString
|
|
|
|
Utils::Hook(0x4CE5EE, Localization::SetStringStub, HOOK_CALL).Install()->Quick();
|
|
|
|
|
|
|
|
// TODO: Get rid of those!
|
2015-12-29 22:19:52 -05:00
|
|
|
Localization::Set("MENU_SEARCHINGFORGAMES_100MS", "");
|
2015-12-30 09:37:53 -05:00
|
|
|
Localization::Set("MP_SEARCHING_FOR_PLAYER", "Waiting");
|
|
|
|
Localization::Set("MENU_WAITING_FOR_MORE_PLAYERS_TEAMS", "Waiting for more players to balance teams");
|
2015-12-30 15:29:48 -05:00
|
|
|
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");
|
2016-01-02 18:37:07 -05:00
|
|
|
Localization::Set("MENU_NATIVECURSOR", "Display native cursor");
|
2015-12-30 15:29:48 -05:00
|
|
|
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");
|
2016-01-02 18:37:07 -05:00
|
|
|
Localization::Set("MENU_NEWCOLORS", "Use new color codes");
|
2015-12-30 15:29:48 -05:00
|
|
|
Localization::Set("MPUI_DESC_OPTIONS", "Set your game options.");
|
|
|
|
Localization::Set("MPUI_DESC_QUIT", "Quit the game.");
|
2015-12-30 09:37:53 -05:00
|
|
|
|
2016-01-02 21:30:55 -05:00
|
|
|
Localization::Set("PLATFORM_REFRESH_LIST", "Refresh List ^0- ^3F5");
|
|
|
|
Localization::Set("PLATFORM_REFRESH_LIST_CAPS", "REFRESH LIST ^0- ^3F5");
|
|
|
|
|
2015-12-26 21:56:00 -05:00
|
|
|
Localization::UseLocalization = Dvar::Register<bool>("ui_localize", true, Game::dvar_flag::DVAR_FLAG_NONE, "Use localization strings");
|
2015-12-25 17:17:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
Localization::~Localization()
|
|
|
|
{
|
2016-01-12 13:08:26 -05:00
|
|
|
Localization::ClearTemp();
|
|
|
|
|
2016-01-24 13:58:13 -05:00
|
|
|
for (auto i = Localization::LocalizeMap.begin(); i != Localization::LocalizeMap.end(); ++i)
|
2016-01-12 13:08:26 -05:00
|
|
|
{
|
|
|
|
if (i->second)
|
|
|
|
{
|
|
|
|
if (i->second->name) Utils::Memory::Free(i->second->name);
|
|
|
|
if (i->second->value) Utils::Memory::Free(i->second->value);
|
|
|
|
Utils::Memory::Free(i->second);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-25 17:17:29 -05:00
|
|
|
Localization::LocalizeMap.clear();
|
|
|
|
}
|
|
|
|
}
|