-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMain.cpp
More file actions
156 lines (148 loc) · 6.99 KB
/
Copy pathMain.cpp
File metadata and controls
156 lines (148 loc) · 6.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include "plugin.h"
#include "TextFileTable.h"
#include <map>
using namespace plugin;
using namespace std;
using namespace filesystem;
uintptr_t gSetLanguage = 0, gGetString = 0, gStringAssign = 0, gEnforceCase = 0, gGetHash = 0;
map<unsigned int, string>& GetTranslationEntries() {
static map<unsigned int, string> entries;
return entries;
}
void LoadTranslationEntries(char const *languageCode) {
GetTranslationEntries().clear();
for (const auto& p : recursive_directory_iterator(L"plugins\\")) {
if (ToLower(p.path().extension().string()) == ".tr") {
TextFileTable file;
if (file.Read(p.path(), L'\t')) {
bool canAddEntries = true;
for (size_t r = 0; r < file.NumRows(); r++) {
auto const &row = file.Row(r);
auto numColumns = row.size();
if (numColumns >= 1) {
auto& col1 = row[0];
if (!col1.empty() && col1[0] != ';') {
if (col1[0] == '[') {
auto bcPos = col1.find(']', 1);
if (bcPos != std::string::npos) {
std::string currTranslationLanguage = col1.substr(1, bcPos - 1);
Trim(currTranslationLanguage);
if (currTranslationLanguage.empty())
canAddEntries = true;
else {
canAddEntries = false;
currTranslationLanguage = ToLower(currTranslationLanguage);
auto languages = Split(currTranslationLanguage, ',', true, true, false);
for (auto const& l : languages) {
if (l == languageCode) {
canAddEntries = true;
break;
}
}
}
continue;
}
}
if (canAddEntries) {
auto hash = CallAndReturnDynGlobal<unsigned int>(gGetHash, col1.c_str());
GetTranslationEntries()[hash] = (numColumns >= 2) ? row[1] : string();
}
}
}
}
}
}
}
}
int METHOD LocalizationInterface_SetLanguage(void *t, DUMMY_ARG, const char *languageCode, const char *countryCode) {
int result = CallMethodAndReturnDynGlobal<int>(gSetLanguage, t, languageCode, countryCode);
LoadTranslationEntries(languageCode);
return result;
}
int METHOD LocalizationInterface_GetString(void *t, DUMMY_ARG, void *pDstStringUTF8, unsigned int uKey, unsigned int eCase) {
auto it = GetTranslationEntries().find(uKey);
if (it != GetTranslationEntries().end()) {
CallMethodDynGlobal(gStringAssign, pDstStringUTF8, (*it).second.c_str());
CallMethodDynGlobal(gEnforceCase, t, pDstStringUTF8, eCase);
return 1;
}
return CallMethodAndReturnDynGlobal<int>(gGetString, t, pDstStringUTF8, uKey, eCase);
}
int METHOD LocalizationInterface_GetString_12(void *t, DUMMY_ARG, void *pDstStringUTF8, unsigned int uKey, unsigned int eCase) {
auto it = GetTranslationEntries().find(uKey);
if (it != GetTranslationEntries().end()) {
char const *newStr = (*it).second.c_str();
CallMethodDynGlobal(gStringAssign, pDstStringUTF8, newStr, newStr + strlen(newStr));
CallMethodDynGlobal(gEnforceCase, t, pDstStringUTF8, eCase);
return 1;
}
return CallMethodAndReturnDynGlobal<int>(gGetString, t, pDstStringUTF8, uKey, eCase);
}
class FifaTextLoader {
public:
FifaTextLoader() {
if (!CheckPluginName(Magic<'T','e','x','t','L','o','a','d','e','r','.','a','s','i'>()))
return;
auto v = FIFA::GetAppVersion();
switch (v.id()) {
case ID_FIFA14_1700:
gGetString = patch::RedirectCall(0x25A2CBD, LocalizationInterface_GetString);
gSetLanguage = patch::SetPointer(0x3D65770, LocalizationInterface_SetLanguage);
gStringAssign = 0x49F0E0;
gEnforceCase = 0x25A2460;
gGetHash = 0x490020;
break;
case ID_FIFA14_1400_3DM:
gGetString = patch::RedirectCall(0x259F4BD, LocalizationInterface_GetString);
gSetLanguage = patch::SetPointer(0x3D10630, LocalizationInterface_SetLanguage);
gStringAssign = 0x49EFB0;
gEnforceCase = 0x259EC60;
gGetHash = 0x48FEE0;
break;
case ID_FIFA13_1700_RLD:
gGetString = patch::RedirectCall(0x1BA3B9D, LocalizationInterface_GetString);
gSetLanguage = patch::RedirectCall(0x60D972, LocalizationInterface_SetLanguage);
gStringAssign = 0x493420;
gEnforceCase = 0x1BA33C0;
gGetHash = 0x484380;
break;
case ID_FIFA13_1800:
gGetString = patch::RedirectCall(0x1B9F2CD, LocalizationInterface_GetString);
gSetLanguage = patch::RedirectCall(0x6089F2, LocalizationInterface_SetLanguage);
gStringAssign = 0x48E480;
gEnforceCase = 0x1B9EAF0;
gGetHash = 0x47F3D0;
break;
case ID_FIFA12_1700:
gGetString = patch::RedirectCall(0x112C11D, LocalizationInterface_GetString_12);
gSetLanguage = patch::RedirectCall(0x10B78A1, LocalizationInterface_SetLanguage);
gStringAssign = 0x42F820;
gEnforceCase = 0x112BC20;
gGetHash = 0x428450;
break;
case ID_FIFA12_1500_SKD:
gGetString = patch::RedirectCall(0x112B03D, LocalizationInterface_GetString_12);
gSetLanguage = patch::RedirectCall(0x10B66A1, LocalizationInterface_SetLanguage);
gStringAssign = 0x42F720;
gEnforceCase = 0x112AB40;
gGetHash = 0x428350;
break;
case ID_FIFA12_1000_RLD:
gGetString = patch::RedirectCall(0xF7436D, LocalizationInterface_GetString_12);
gSetLanguage = patch::RedirectCall(0xE97FA1, LocalizationInterface_SetLanguage);
gStringAssign = 0x42E730;
gEnforceCase = 0xF73E70;
gGetHash = 0x427380;
break;
case ID_FIFA11_1010_FLT:
case ID_FIFA11_1010:
gGetString = patch::RedirectJump(0x468BB7, LocalizationInterface_GetString);
gSetLanguage = patch::RedirectCall(0x466629, LocalizationInterface_SetLanguage);
patch::RedirectCall(0x4663D6, LocalizationInterface_SetLanguage);
gStringAssign = 0x454410;
gEnforceCase = 0x4274B0;
gGetHash = 0x41CFE0;
break;
}
}
} fifaTextLoader;