-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Thousandths.as
161 lines (131 loc) · 4.26 KB
/
Thousandths.as
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
157
158
159
160
161
[Setting name="Enabled"]
bool enabled = true;
#if MP4
[Setting name="Force enable on servers" description="Most servers will already display thousandths; enabling this might duplicate the last digit"]
bool serverOverride = false;
#endif
bool errored = false;
uint64 ptr_template_fast = 0;
uint64 ptr_template_slow = 0;
uint64 ptr_ms_conversion = 0;
string bytes_template_fast = "";
string bytes_template_slow = "";
string bytes_ms_conversion = "";
string fmt_ptr = "0x%016x";
void RenderMenu() {
if(UI::MenuItem("\\$f0f" + Icons::ClockO + "\\$z Show Thousandths", "", enabled && !errored, !errored)) {
enabled = !enabled;
if(enabled) {
enable();
} else {
disable();
}
}
}
void Main() {
#if TURBO && MANIA32 || MP41 && MANIA64
// String literal "%s%d:%.2d.%.2d" used for M:Ss.Cc
ptr_template_fast = Dev::FindPattern("25 73 25 64 3A 25 2E 32 64 2E 25 2E 32 64 00");
// String literal "%s%d:%.2d:%.2d.%.2d" used for H:Mm:Ss.Cc
ptr_template_slow = Dev::FindPattern("25 73 25 64 3A 25 2E 32 64 3A 25 2E 32 64 2E 25 2E 32 64 00");
#if TURBO
// Code to calculate hundredths from raw time
ptr_ms_conversion = Dev::FindPattern("B8 CD CC CC CC F7 E7 8B 44 24 20 C1 EA 03");
#elif MP4
// Code to calculate hundredths from raw time
ptr_ms_conversion = Dev::FindPattern("B8 CD CC CC CC 45 2B D0 41 F7 E2 48 8B 44 24 30 C1 EA 03");
#endif
print("Thousandths fast ptr: " + Text::Format(fmt_ptr, ptr_template_fast));
print("Thousandths slow ptr: " + Text::Format(fmt_ptr, ptr_template_slow));
print("Thousandths conv ptr: " + Text::Format(fmt_ptr, ptr_ms_conversion));
if(ptr_template_fast == 0 || ptr_template_slow == 0 || ptr_ms_conversion == 0) {
error("Thousandths: ERROR unable to locate byte replacement patterns, cannot continue!");
errored = true;
return;
}
if(enabled) {
enable();
}
#else
error("Thousandths plugin only works for 32-bit Turbo and 64-bit Maniaplanet 4.1");
errored = true;
#endif
}
void OnEnabled() {
if(enabled) {
enable();
}
}
void OnDisabled() {
if(enabled) {
disable();
}
}
void OnDestroyed() {
if(enabled) {
disable();
}
}
void enable() {
if(errored) return;
bytes_template_fast = Dev::Patch(ptr_template_fast, "25 73 25 64 3A 25 2E 32 64 2E 25 2E 33 64 00");
bytes_template_slow = Dev::Patch(ptr_template_slow, "25 73 25 64 3A 25 2E 32 64 3A 25 2E 32 64 2E 25 2E 33 64 00");
#if TURBO
bytes_ms_conversion = Dev::Patch(ptr_ms_conversion, "90 90 90 90 90 8B D7 8B 44 24 20 90 90 90");
#elif MP4
bytes_ms_conversion = Dev::Patch(ptr_ms_conversion, "90 90 90 90 90 45 2B D0 41 8B D2 48 8B 44 24 30 90 90 90");
#endif
trace("Thousandths: patch applied");
}
void disable() {
if(errored) return;
Dev::Patch(ptr_template_fast, bytes_template_fast);
Dev::Patch(ptr_template_slow, bytes_template_slow);
Dev::Patch(ptr_ms_conversion, bytes_ms_conversion);
string bytes_template_fast = "";
string bytes_template_slow = "";
string bytes_ms_conversion = "";
trace("Thousandths: patch removed");
}
#if TURBO
void Update(float dt) {
if(!enabled) return;
FixUI::Turbo();
}
#elif MP4
/*
This is ugly, but required, since MP4 menus add the extra digit on already.
This would cause the last digit to be duplicated: 1:23.456 -> 1:23.4566
See: https://github.com/Phlarx/tm-thousandths/issues/1
*/
bool inGame = true;
void Update(float dt) {
if(!enabled) return;
bool nextInGame = true;
auto playground = cast<CTrackManiaRaceNew>(GetApp().CurrentPlayground);
if(playground is null
|| playground.GameTerminals.Length <= 0
|| cast<CTrackManiaPlayer>(playground.GameTerminals[0].GUIPlayer) is null) {
nextInGame = false;
} else {
auto scriptPlayer = cast<CTrackManiaPlayer>(playground.GameTerminals[0].GUIPlayer).ScriptAPI;
if(scriptPlayer is null
|| scriptPlayer.RaceState != CTrackManiaPlayer::ERaceState::Running) {
nextInGame = false;
}
auto serverInfo = GetApp().Network is null ? null : cast<CGameCtnNetServerInfo>(GetApp().Network.ServerInfo);
if(serverInfo !is null
&& serverInfo.ServerLogin.Length > 0) {
nextInGame = serverOverride;
}
}
if(inGame != nextInGame) {
inGame = nextInGame;
if(inGame) {
enable();
} else {
disable();
}
}
}
#endif