@@ -23,27 +23,42 @@ void GameMainThread::RepeatedTaskQueue::Drain()
23
23
++taskIt;
24
24
}
25
25
}
26
- GameMainThread::StateTickOverride::StateTickOverride (const char * acpRealFunctionName)
26
+ GameMainThread::StateTickOverride::StateTickOverride (uint32_t aHash, const char * acpRealFunctionName)
27
27
{
28
+ const RED4ext::UniversalRelocPtr<uint8_t > func (aHash);
29
+ Location = func.GetAddr ();
30
+
31
+ if (Location)
32
+ {
33
+ if (MH_CreateHook (Location, reinterpret_cast <void *>(&GameMainThread::HookStateTick), reinterpret_cast <void **>(&RealFunction)) != MH_OK || MH_EnableHook (Location) != MH_OK)
34
+ Log::Error (" Could not hook main thread function {}! Main thread is not completely hooked!" , acpRealFunctionName);
35
+ else
36
+ Log::Info (" Main thread function {} hook complete!" , acpRealFunctionName);
37
+ }
38
+ else
39
+ Log::Error (" Could not locate {}! Main thread is not completely hooked!" , acpRealFunctionName);
28
40
}
29
41
30
42
GameMainThread::StateTickOverride::~StateTickOverride ()
31
43
{
44
+ MH_DisableHook (Location);
45
+
46
+ Location = nullptr ;
47
+ RealFunction = nullptr ;
32
48
}
33
49
34
50
bool GameMainThread::StateTickOverride::OnTick (RED4ext::IGameState* apThisState, RED4ext::CGameApplication* apGameApplication)
35
51
{
36
52
Tasks.Drain ();
37
53
38
- return true ;
54
+ return RealFunction (apThisState, apGameApplication) ;
39
55
}
40
56
41
- static GameMainThread* s_gameMainThread = nullptr ;
42
-
43
57
GameMainThread& GameMainThread::Get ()
44
58
{
45
- assert (s_gameMainThread);
46
- return *s_gameMainThread;
59
+ static GameMainThread s_gameMainThread;
60
+
61
+ return s_gameMainThread;
47
62
}
48
63
49
64
void GameMainThread::AddBaseInitializationTask (const std::function<bool ()>& aFunction)
@@ -75,76 +90,14 @@ void GameMainThread::AddGenericTask(const std::function<bool()>& aFunction)
75
90
m_genericQueue.AddTask (aFunction);
76
91
}
77
92
78
- void GameMainThread::Create (RED4ext::PluginHandle aHandle, const RED4ext::Sdk* aSdk)
79
- {
80
- if (!s_gameMainThread)
81
- s_gameMainThread = new GameMainThread (aHandle, aSdk);
82
- }
83
-
84
- GameMainThread::GameMainThread (RED4ext::PluginHandle aHandle, const RED4ext::Sdk* sdk)
85
- {
86
- {
87
- RED4ext::GameState state{nullptr , &HookBaseInitStateTick, nullptr };
88
- sdk->gameStates ->Add (aHandle, RED4ext::EGameStateType::BaseInitialization, &state);
89
- }
90
- {
91
- RED4ext::GameState state{nullptr , &HookInitStateTick, nullptr };
92
- sdk->gameStates ->Add (aHandle, RED4ext::EGameStateType::Initialization, &state);
93
- }
94
- {
95
- RED4ext::GameState state{nullptr , &HookRunningStateTick, nullptr };
96
- sdk->gameStates ->Add (aHandle, RED4ext::EGameStateType::Running, &state);
97
- }
98
- {
99
- RED4ext::GameState state{nullptr , &HookShutdownStateTick, nullptr };
100
- sdk->gameStates ->Add (aHandle, RED4ext::EGameStateType::Shutdown, &state);
101
- }
102
- }
103
-
104
- bool GameMainThread::HookBaseInitStateTick (RED4ext::CGameApplication* apGameApplication)
93
+ bool GameMainThread::HookStateTick (RED4ext::IGameState* apThisState, RED4ext::CGameApplication* apGameApplication)
105
94
{
106
95
auto & gmt = Get ();
107
96
108
97
// drain generic tasks
109
98
gmt.m_genericQueue .Drain ();
110
99
111
- gmt.m_stateTickOverrides [0 ].OnTick (apGameApplication->currState , apGameApplication);
112
-
113
- return true ;
114
- }
115
-
116
- bool GameMainThread::HookInitStateTick (RED4ext::CGameApplication* apGameApplication)
117
- {
118
- auto & gmt = Get ();
119
-
120
- // drain generic tasks
121
- gmt.m_genericQueue .Drain ();
122
-
123
- gmt.m_stateTickOverrides [1 ].OnTick (apGameApplication->currState , apGameApplication);
124
-
125
- return true ;
126
- }
127
-
128
- bool GameMainThread::HookRunningStateTick (RED4ext::CGameApplication* apGameApplication)
129
- {
130
- auto & gmt = Get ();
131
-
132
- // drain generic tasks
133
- gmt.m_genericQueue .Drain ();
134
-
135
- gmt.m_stateTickOverrides [2 ].OnTick (apGameApplication->currState , apGameApplication);
136
-
137
- return false ;
138
- }
139
-
140
- bool GameMainThread::HookShutdownStateTick (RED4ext::CGameApplication* apGameApplication)
141
- {
142
- auto & gmt = Get ();
143
-
144
- // drain generic tasks
145
- gmt.m_genericQueue .Drain ();
146
-
147
- gmt.m_stateTickOverrides [3 ].OnTick (apGameApplication->currState , apGameApplication);
148
-
149
- return true ;
100
+ // execute specific state tasks, including original function
101
+ const auto cStateIndex = static_cast <size_t >(apThisState->GetType ());
102
+ return gmt.m_stateTickOverrides [cStateIndex].OnTick (apThisState, apGameApplication);
150
103
}
0 commit comments