Skip to content

Commit 8fd8b82

Browse files
committed
switch to mat-dash
1 parent 7a4e935 commit 8fd8b82

File tree

7 files changed

+93
-110
lines changed

7 files changed

+93
-110
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@
1111
[submodule "libraries/cocos-headers"]
1212
path = libraries/cocos-headers
1313
url = https://github.com/HJfod/cocos-headers.git
14+
[submodule "libraries/mat-dash"]
15+
path = libraries/mat-dash
16+
url = [email protected]:matcool/mat-dash.git

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ set(CMAKE_CXX_STANDARD 17)
33
set(CMAKE_CXX_STANDARD_REQUIRED ON)
44
set(CMAKE_CXX_EXTENSIONS OFF)
55

6+
include(libraries/mat-dash/include.cmake)
7+
68
project(replay-bot)
79

810
find_file(WINDOWS_HEADER windows.h)

libraries/mat-dash

Submodule mat-dash added at 3fe4116

src/dllmain.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#include "includes.h"
22
#include <fstream>
3+
#include <matdash.hpp>
34

45
#include "hooks.hpp"
56

6-
DWORD WINAPI thread_entry(void* module) {
7+
void mod_main(HMODULE module) {
78
#ifdef SHOW_CONSOLE
89
AllocConsole();
910
std::ofstream conout("CONOUT$", std::ios::out);
@@ -12,14 +13,10 @@ DWORD WINAPI thread_entry(void* module) {
1213
std::cin.rdbuf(conin.rdbuf());
1314
#endif
1415

15-
DisableThreadLibraryCalls(cast<HMODULE>(module));
16-
17-
MH_Initialize();
16+
DisableThreadLibraryCalls(module);
1817

1918
Hooks::init();
2019

21-
MH_EnableHook(MH_ALL_HOOKS);
22-
2320
#ifdef SHOW_CONSOLE
2421
std::getline(std::cin, std::string());
2522
MH_Uninitialize();
@@ -28,14 +25,6 @@ DWORD WINAPI thread_entry(void* module) {
2825
FreeConsole();
2926
FreeLibraryAndExitThread(cast<HMODULE>(module), 0);
3027
#endif
31-
32-
return 0;
3328
}
3429

35-
BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
36-
if (reason == DLL_PROCESS_ATTACH) {
37-
auto handle = CreateThread(0, 0, thread_entry, module, 0, 0);
38-
if (handle) CloseHandle(handle);
39-
}
40-
return TRUE;
41-
}
30+
#include <matdash/boilerplate.hpp>

src/hooks.cpp

Lines changed: 58 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,45 @@
33
#include "overlay_layer.hpp"
44
#include "recorder.hpp"
55
#include <chrono>
6+
#include <matdash/minhook.hpp>
67

7-
auto add_gd_hook(uintptr_t offset, void* hook, void* orig) {
8-
return MH_CreateHook(cast<void*>(gd::base + offset), hook, cast<void**>(orig));
8+
auto cocos(const char* symbol) {
9+
static auto mod = GetModuleHandleA("libcocos2d.dll");
10+
return GetProcAddress(mod, symbol);
911
}
10-
#define ADD_GD_HOOK(o, f) add_gd_hook(o, f##_H, &f)
11-
12-
auto add_cocos_hook(const char* symbol, void* hook, void* orig) {
13-
return MH_CreateHook(GetProcAddress(GetModuleHandleA("libcocos2d.dll"), symbol), hook, cast<void**>(orig));
14-
}
15-
#define ADD_COCOS_HOOK(o, f) add_cocos_hook(o, f##_H, &f)
1612

1713
void Hooks::init() {
18-
ADD_COCOS_HOOK("?update@CCScheduler@cocos2d@@UAEXM@Z", CCScheduler_update);
19-
ADD_COCOS_HOOK("?dispatchKeyboardMSG@CCKeyboardDispatcher@cocos2d@@QAE_NW4enumKeyCodes@2@_N@Z", CCKeyboardDispatcher_dispatchKeyboardMSG);
20-
ADD_GD_HOOK(0x20ddd0, CheckpointObject_create);
14+
add_hook<&CCScheduler_update, Thiscall>(cocos("?update@CCScheduler@cocos2d@@UAEXM@Z"));
15+
add_hook<&CCKeyboardDispatcher_dispatchKeyboardMSG>(cocos("?dispatchKeyboardMSG@CCKeyboardDispatcher@cocos2d@@QAE_NW4enumKeyCodes@2@_N@Z"));
16+
add_hook<&CheckpointObject_create, Optfastcall>(gd::base + 0x20ddd0);
2117

22-
ADD_GD_HOOK(0x2029C0, PlayLayer::update);
18+
add_hook<&PlayLayer::update, Thiscall>(gd::base + 0x2029C0);
2319

24-
ADD_GD_HOOK(0x111500, PlayLayer::pushButton);
25-
ADD_GD_HOOK(0x111660, PlayLayer::releaseButton);
26-
ADD_GD_HOOK(0x20BF00, PlayLayer::resetLevel);
20+
add_hook<&PlayLayer::pushButton>(gd::base + 0x111500);
21+
add_hook<&PlayLayer::releaseButton>(gd::base + 0x111660);
22+
add_hook<&PlayLayer::resetLevel>(gd::base + 0x20BF00);
2723

28-
ADD_GD_HOOK(0x20D3C0, PlayLayer::pauseGame);
24+
add_hook<&PlayLayer::pauseGame>(gd::base + 0x20D3C0);
2925

30-
ADD_GD_HOOK(0x1FD3D0, PlayLayer::levelComplete);
31-
ADD_GD_HOOK(0x20D810, PlayLayer::onQuit);
32-
ADD_GD_HOOK(0x1E60E0, PlayLayer::onEditor);
26+
add_hook<&PlayLayer::levelComplete>(gd::base + 0x1FD3D0);
27+
add_hook<&PlayLayer::onQuit>(gd::base + 0x20D810);
28+
add_hook<&PauseLayer_onEditor>(gd::base + 0x1E60E0);
3329

34-
ADD_GD_HOOK(0x205460, PlayLayer::updateVisiblity);
30+
add_hook<&PlayLayer::updateVisiblity>(gd::base + 0x205460);
3531

36-
ADD_GD_HOOK(0x1E4620, PauseLayer_init);
32+
add_hook<&PauseLayer_init>(gd::base + 0x1E4620);
3733

38-
ADD_GD_HOOK(0x1f4ff0, PlayerObject_ringJump);
39-
ADD_GD_HOOK(0xef0e0, GameObject_activateObject);
40-
ADD_GD_HOOK(0x10ed50, GJBaseGameLayer_bumpPlayer);
34+
add_hook<&PlayerObject_ringJump>(gd::base + 0x1f4ff0);
35+
add_hook<&GameObject_activateObject>(gd::base + 0xef0e0);
36+
add_hook<&GJBaseGameLayer_bumpPlayer>(gd::base + 0x10ed50);
4137
}
4238

4339
// yes these are global, too lazy to store them in replaysystem or smth
4440
// not like theyre used anywhere else atm
4541
bool g_disable_render = false;
4642
float g_left_over = 0.f;
4743

48-
void __fastcall Hooks::CCScheduler_update_H(CCScheduler* self, int, float dt) {
44+
void Hooks::CCScheduler_update(CCScheduler* self, float dt) {
4945
auto& rs = ReplaySystem::get_instance();
5046
if (rs.recorder.m_recording || rs.is_playing() || rs.is_recording() && gd::GameManager::sharedState()->getPlayLayer()) {
5147
const auto fps = rs.get_replay().get_fps();
@@ -54,19 +50,19 @@ void __fastcall Hooks::CCScheduler_update_H(CCScheduler* self, int, float dt) {
5450
const float target_dt = 1.f / fps / speedhack;
5551

5652
if (!rs.real_time_mode)
57-
return CCScheduler_update(self, target_dt);
53+
return orig<&CCScheduler_update, Thiscall>(self, target_dt);
5854

5955
// todo: find ways to disable more render stuff
6056
g_disable_render = false;
6157

6258
unsigned times = static_cast<int>((dt + g_left_over) / target_dt);
6359
if (dt == 0.f)
64-
return CCScheduler_update(self, target_dt);
60+
return orig<&CCScheduler_update, Thiscall>(self, target_dt);
6561
auto start = std::chrono::high_resolution_clock::now();
6662
for (unsigned i = 0; i < times; ++i) {
6763
// if (i == times - 1)
6864
// g_disable_render = false;
69-
CCScheduler_update(self, target_dt);
65+
orig<&CCScheduler_update, Thiscall>(self, target_dt);
7066
using namespace std::literals;
7167
if (std::chrono::high_resolution_clock::now() - start > 33.333ms) {
7268
times = i + 1;
@@ -75,39 +71,39 @@ void __fastcall Hooks::CCScheduler_update_H(CCScheduler* self, int, float dt) {
7571
}
7672
g_left_over += dt - target_dt * times;
7773
} else {
78-
CCScheduler_update(self, dt);
74+
orig<&CCScheduler_update, Thiscall>(self, dt);
7975
}
8076
}
8177

82-
void __fastcall Hooks::CCKeyboardDispatcher_dispatchKeyboardMSG_H(CCKeyboardDispatcher* self, int, int key, bool down) {
78+
void Hooks::CCKeyboardDispatcher_dispatchKeyboardMSG(CCKeyboardDispatcher* self, int key, bool down) {
8379
auto& rs = ReplaySystem::get_instance();
8480
if (down) {
8581
auto play_layer = gd::GameManager::sharedState()->getPlayLayer();
8682
if (rs.is_recording() && play_layer) {
8783
if (key == 'C') {
8884
rs.set_frame_advance(false);
89-
PlayLayer::update_H(play_layer, 0, 1.f / rs.get_default_fps());
85+
PlayLayer::update(play_layer, 1.f / rs.get_default_fps());
9086
rs.set_frame_advance(true);
9187
} else if (key == 'F') {
9288
rs.set_frame_advance(false);
9389
} else if (key == 'R') {
94-
PlayLayer::resetLevel_H(play_layer, 0);
90+
PlayLayer::resetLevel(play_layer);
9591
}
9692
}
9793
}
98-
CCKeyboardDispatcher_dispatchKeyboardMSG(self, key, down);
94+
orig<&CCKeyboardDispatcher_dispatchKeyboardMSG>(self, key, down);
9995
}
10096

10197
float g_xpos_time = 0.f;
10298

103-
void __fastcall Hooks::PlayLayer::update_H(gd::PlayLayer* self, int, float dt) {
99+
void Hooks::PlayLayer::update(gd::PlayLayer* self, float dt) {
104100
auto& rs = ReplaySystem::get_instance();
105101
if (rs.get_frame_advance()) return;
106102
if (rs.is_playing()) rs.handle_playing();
107103
if (rs.recorder.m_recording) {
108104
rs.recorder.handle_recording(self, dt);
109105
}
110-
update(self, dt);
106+
orig<&update, Thiscall>(self, dt);
111107
}
112108

113109

@@ -120,29 +116,28 @@ bool _player_button_handler(bool hold, bool button) {
120116
return false;
121117
}
122118

123-
int __fastcall Hooks::PlayLayer::pushButton_H(gd::PlayLayer* self, int, int idk, bool button) {
124-
if (_player_button_handler(true, button)) return 0;
125-
return pushButton(self, idk, button);
119+
void Hooks::PlayLayer::pushButton(gd::PlayLayer* self, int idk, bool button) {
120+
if (_player_button_handler(true, button)) return;
121+
orig<&pushButton>(self, idk, button);
126122
}
127123

128-
int __fastcall Hooks::PlayLayer::releaseButton_H(gd::PlayLayer* self, int, int idk, bool button) {
129-
if (_player_button_handler(false, button)) return 0;
130-
return releaseButton(self, idk, button);
124+
void Hooks::PlayLayer::releaseButton(gd::PlayLayer* self, int idk, bool button) {
125+
if (_player_button_handler(false, button)) return;
126+
orig<&releaseButton>(self, idk, button);
131127
}
132128

133-
int __fastcall Hooks::PlayLayer::resetLevel_H(gd::PlayLayer* self, int) {
134-
auto ret = resetLevel(self);
129+
void Hooks::PlayLayer::resetLevel(gd::PlayLayer* self) {
130+
orig<&resetLevel>(self);
135131
auto& rs = ReplaySystem::get_instance();
136132
rs.on_reset();
137133
// from what i've checked rob doesnt store this anywhere, so i have to calculate it again
138134
if (rs.recorder.m_recording)
139135
rs.recorder.m_song_start_offset = self->timeForXPos2(
140136
self->m_player1->m_position.x, self->m_isTestMode) + self->m_levelSettings->m_songStartOffset;
141-
return ret;
142137
}
143138

144139

145-
void __fastcall Hooks::PlayLayer::pauseGame_H(gd::PlayLayer* self, int, bool idk) {
140+
void Hooks::PlayLayer::pauseGame(gd::PlayLayer* self, bool idk) {
146141
auto addr = cast<void*>(gd::base + 0x20D43C);
147142
auto& rs = ReplaySystem::get_instance();
148143
if (rs.is_recording())
@@ -152,39 +147,39 @@ void __fastcall Hooks::PlayLayer::pauseGame_H(gd::PlayLayer* self, int, bool idk
152147
if (should_patch)
153148
patch(addr, {0x83, 0xC4, 0x04, 0x90, 0x90});
154149

155-
pauseGame(self, idk);
150+
orig<&pauseGame>(self, idk);
156151

157152
if (should_patch)
158153
patch(addr, {0xe8, 0x2f, 0x7b, 0xfe, 0xff});
159154
}
160155

161156

162-
CCObject* __fastcall Hooks::CheckpointObject_create_H() {
157+
CCObject* Hooks::CheckpointObject_create() {
163158
return CheckpointObjectMod::create();
164159
}
165160

166-
void* __fastcall Hooks::PlayLayer::levelComplete_H(gd::PlayLayer* self, int) {
161+
void Hooks::PlayLayer::levelComplete(gd::PlayLayer* self) {
167162
ReplaySystem::get_instance().reset_state();
168-
return levelComplete(self);
163+
return orig<&levelComplete>(self);
169164
}
170165

171166
void _on_exit_level() {
172167
auto& rs = ReplaySystem::get_instance();
173168
rs.reset_state();
174169
}
175170

176-
void* __fastcall Hooks::PlayLayer::onQuit_H(gd::PlayLayer* self, int) {
171+
void Hooks::PlayLayer::onQuit(gd::PlayLayer* self) {
177172
_on_exit_level();
178-
return onQuit(self);
173+
orig<&onQuit>(self);
179174
}
180175

181-
void* __fastcall Hooks::PlayLayer::onEditor_H(gd::PlayLayer* self, int, void* idk) {
176+
void Hooks::PauseLayer_onEditor(gd::PauseLayer* self, CCObject* idk) {
182177
_on_exit_level();
183-
return onEditor(self, idk);
178+
orig<&PauseLayer_onEditor>(self, idk);
184179
}
185180

186-
bool __fastcall Hooks::PauseLayer_init_H(gd::PauseLayer* self, int) {
187-
if (PauseLayer_init(self)) {
181+
bool Hooks::PauseLayer_init(gd::PauseLayer* self) {
182+
if (orig<&PauseLayer_init>(self)) {
188183
auto win_size = CCDirector::sharedDirector()->getWinSize();
189184

190185
auto menu = CCMenu::create();
@@ -217,28 +212,28 @@ void _handle_activated_object(bool a, bool b, gd::GameObject* object) {
217212
}
218213
}
219214

220-
void __fastcall Hooks::PlayerObject_ringJump_H(gd::PlayerObject* self, int, gd::GameObject* ring) {
215+
void Hooks::PlayerObject_ringJump(gd::PlayerObject* self, gd::GameObject* ring) {
221216
bool a = ring->m_hasBeenActivated;
222217
bool b = ring->m_hasBeenActivatedP2;
223-
PlayerObject_ringJump(self, ring);
218+
orig<&PlayerObject_ringJump>(self, ring);
224219
_handle_activated_object(a, b, ring);
225220
}
226221

227-
void __fastcall Hooks::GameObject_activateObject_H(gd::GameObject* self, int, gd::PlayerObject* player) {
222+
void Hooks::GameObject_activateObject(gd::GameObject* self, gd::PlayerObject* player) {
228223
bool a = self->m_hasBeenActivated;
229224
bool b = self->m_hasBeenActivatedP2;
230-
GameObject_activateObject(self, player);
225+
orig<&GameObject_activateObject>(self, player);
231226
_handle_activated_object(a, b, self);
232227
}
233228

234-
void __fastcall Hooks::GJBaseGameLayer_bumpPlayer_H(gd::GJBaseGameLayer* self, int, gd::PlayerObject* player, gd::GameObject* object) {
229+
void Hooks::GJBaseGameLayer_bumpPlayer(gd::GJBaseGameLayer* self, gd::PlayerObject* player, gd::GameObject* object) {
235230
bool a = object->m_hasBeenActivated;
236231
bool b = object->m_hasBeenActivatedP2;
237-
GJBaseGameLayer_bumpPlayer(self, player, object);
232+
orig<&GJBaseGameLayer_bumpPlayer>(self, player, object);
238233
_handle_activated_object(a, b, object);
239234
}
240235

241-
void __fastcall Hooks::PlayLayer::updateVisiblity_H(gd::PlayLayer* self, int) {
236+
void Hooks::PlayLayer::updateVisiblity(gd::PlayLayer* self) {
242237
if (!g_disable_render)
243-
updateVisiblity(self);
238+
orig<&updateVisiblity>(self);
244239
}

src/hooks.hpp

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,36 @@
11
#pragma once
22
#include "includes.h"
33
#include <vector>
4-
5-
#define _THISCALL_HOOK(name, ret_type, self_type, ...) \
6-
inline ret_type(__thiscall* name)(self_type* self, __VA_ARGS__); \
7-
ret_type __fastcall name##_H(self_type* self, int, __VA_ARGS__);
8-
9-
#define _FASTCALL_HOOK(name, ret_type, ...) \
10-
inline ret_type(__fastcall* name)(__VA_ARGS__); \
11-
ret_type __fastcall name##_H(__VA_ARGS__);
4+
#include <matdash.hpp>
125

136
namespace Hooks {
147
void init();
158

16-
_THISCALL_HOOK(CCScheduler_update, void, CCScheduler, float dt)
17-
_THISCALL_HOOK(CCKeyboardDispatcher_dispatchKeyboardMSG, void, CCKeyboardDispatcher, int key, bool down)
18-
_FASTCALL_HOOK(CheckpointObject_create, CCObject*)
9+
void CCScheduler_update(CCScheduler*, float dt);
10+
void CCKeyboardDispatcher_dispatchKeyboardMSG(CCKeyboardDispatcher*, int key, bool down);
11+
CCObject* CheckpointObject_create();
1912

2013
namespace PlayLayer {
21-
_THISCALL_HOOK(update, void, gd::PlayLayer, float dt)
14+
void update(gd::PlayLayer*, float dt);
2215

23-
_THISCALL_HOOK(pushButton, int, gd::PlayLayer, int, bool)
24-
_THISCALL_HOOK(releaseButton, int, gd::PlayLayer, int, bool)
25-
_THISCALL_HOOK(resetLevel, int, gd::PlayLayer)
16+
void pushButton(gd::PlayLayer*, int, bool);
17+
void releaseButton(gd::PlayLayer*, int, bool);
18+
void resetLevel(gd::PlayLayer*);
2619

27-
_THISCALL_HOOK(pauseGame, void, gd::PlayLayer, bool)
20+
void pauseGame(gd::PlayLayer*, bool);
2821

29-
_THISCALL_HOOK(levelComplete, void*, gd::PlayLayer)
22+
void levelComplete(gd::PlayLayer*);
3023
// these are only for stopping recording/playing
3124
// maybe hook the destructor instead ?
32-
_THISCALL_HOOK(onQuit, void*, gd::PlayLayer)
33-
_THISCALL_HOOK(onEditor, void*, gd::PlayLayer, void*)
25+
void onQuit(gd::PlayLayer*);
3426

35-
_THISCALL_HOOK(updateVisiblity, void, gd::PlayLayer)
27+
void updateVisiblity(gd::PlayLayer*);
3628
}
3729

38-
_THISCALL_HOOK(PauseLayer_init, bool, gd::PauseLayer)
30+
void PauseLayer_onEditor(gd::PauseLayer*, CCObject*);
31+
bool PauseLayer_init(gd::PauseLayer*);
3932

40-
_THISCALL_HOOK(PlayerObject_ringJump, void, gd::PlayerObject, gd::GameObject* ring)
41-
_THISCALL_HOOK(GameObject_activateObject, void, gd::GameObject, gd::PlayerObject* player)
42-
_THISCALL_HOOK(GJBaseGameLayer_bumpPlayer, void, gd::GJBaseGameLayer, gd::PlayerObject* player, gd::GameObject* object)
33+
void PlayerObject_ringJump(gd::PlayerObject*, gd::GameObject* ring);
34+
void GameObject_activateObject(gd::GameObject*, gd::PlayerObject* player);
35+
void GJBaseGameLayer_bumpPlayer(gd::GJBaseGameLayer*, gd::PlayerObject* player, gd::GameObject* object);
4336
}

0 commit comments

Comments
 (0)