Repository navigation
Expand file tree
/
Copy pathcore.cpp
More file actions
263 lines (222 loc) · 8.27 KB
/
Copy pathcore.cpp
File metadata and controls
263 lines (222 loc) · 8.27 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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
// used: [win] shgetknownfolderpath
#include <shlobj_core.h>
#include "core.h"
// used: features setup
#include "features.h"
// used: string copy
#include "utilities/crt.h"
// used: mem
#include "utilities/memory.h"
// used: l_print
#include "utilities/log.h"
// used: inputsystem setup/restore
#include "utilities/inputsystem.h"
// used: draw destroy
#include "utilities/draw.h"
// used: interfaces setup/destroy
#include "core/interfaces.h"
// used: sdk setup
#include "core/sdk.h"
// used: config setup & variables
#include "core/variables.h"
// used: hooks setup/destroy
#include "core/hooks.h"
// used: schema setup/dump
#include "core/schema.h"
// used: convar setup
#include "core/convars.h"
// used: menu
#include "core/menu.h"
// used: product version
#include "sdk/interfaces/iengineclient.h"
bool CORE::GetWorkingPath(wchar_t* wszDestination)
{
bool bSuccess = false;
PWSTR wszPathToDocuments = nullptr;
// get path to user documents
if (SUCCEEDED(::SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_CREATE, nullptr, &wszPathToDocuments)))
{
CRT::StringCat(CRT::StringCopy(wszDestination, wszPathToDocuments), CS_XOR(L"\\.Leerware\\"));
bSuccess = true;
// create directory if it doesn't exist
if (!::CreateDirectoryW(wszDestination, nullptr))
{
if (::GetLastError() != ERROR_ALREADY_EXISTS)
{
L_PRINT(LOG_ERROR) << CS_XOR("failed to create default working directory, because one or more intermediate directories don't exist");
bSuccess = false;
}
}
}
::CoTaskMemFree(wszPathToDocuments);
return bSuccess;
}
static bool Setup(HMODULE hModule)
{
#ifdef CS_LOG_CONSOLE
if (!L::AttachConsole(CS_XOR(L"Leerware developer-mode")))
{
CS_ASSERT(false); // failed to attach console
return false;
}
#endif
#ifdef CS_LOG_FILE
if (!L::OpenFile(CS_XOR(L"leerware.log")))
{
CS_ASSERT(false); // failed to open file
return false;
}
#endif
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("logging system initialization completed");
// setup game's exported functions
if (!MEM::Setup())
{
CS_ASSERT(false); // failed to setup memory system
return false;
}
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("memory system initialization completed");
if (!MATH::Setup())
{
CS_ASSERT(false); // failed to setup math system
return false;
}
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("math system initialization completed");
// grab game's interfaces
if (!I::Setup())
{
CS_ASSERT(false); // failed to setup interfaces
return false;
}
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("interfaces initialization completed");
if (!SDK::Setup())
{
CS_ASSERT(false); // failed to setup sdk
return false;
}
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("sdk initialization completed");
// setup input system and replace game's window messages processor with our
if (!IPT::Setup())
{
CS_ASSERT(false); // failed to setup input system
return false;
}
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("input system initialization completed");
// @note: sleep to wait finishing font building
D::Setup(IPT::hWindow, I::Device, I::DeviceContext);
MENU::UpdateStyle(nullptr);
while (D::bInitialized == false)
::Sleep(200U);
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("renderer backend initialization completed");
// initialize feature-related stuff
if (!F::Setup())
{
CS_ASSERT(false); // failed to setup features
return false;
}
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("features initialization completed");
// iterate all valid modules for schema
std::vector<std::string> vecNeededModules = { CS_XOR("client.dll"), CS_XOR("engine2.dll"), CS_XOR("schemasystem.dll"), CS_XOR("matchmaking.dll") };
for (auto& szModule : vecNeededModules)
{
if (!SCHEMA::Setup(CS_XOR(L"schema.txt"), szModule.c_str()))
{
CS_ASSERT(false); // failed to setup schema system
return false;
}
}
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("schema system initialization completed");
if (!CONVAR::Dump(CS_XOR(L"convars.txt")))
{
CS_ASSERT(false); // failed to setup convars system
return false;
}
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("convars dumped completed, output: \"convars.txt\"");
if (!CONVAR::Setup())
{
CS_ASSERT(false); // failed to setup convars system
return false;
}
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("convars system initialization completed");
// setup hooks
if (!H::Setup())
{
CS_ASSERT(false); // failed to setup hooks
return false;
}
L_PRINT(LOG_NONE) << CS_XOR("hooks initialization completed");
// setup values to save/load cheat variables into/from files and load default configuration
if (!C::Setup(CS_XOR(CS_CONFIGURATION_DEFAULT_FILE_NAME)))
// this error is not critical, only show that
L_PRINT(LOG_WARNING) << CS_XOR("failed to setup and/or load default configuration");
else
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_GREEN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("configuration system initialization completed");
// @note: this doesn't affect much, but it's good to know if we're using different version of the game
if (CRT::StringCompare(I::Engine->GetProductVersionString(), CS_PRODUCTSTRINGVERSION) != 0)
L_PRINT(LOG_WARNING) << L::SetColor(LOG_COLOR_FORE_YELLOW | LOG_COLOR_FORE_INTENSITY) << CS_XOR("version mismatch! local CS2 version: ") << CS_PRODUCTSTRINGVERSION << CS_XOR(", current CS2 version: ") << I::Engine->GetProductVersionString() << CS_XOR(". Leerware might not function as normal.");
L_PRINT(LOG_NONE) << L::SetColor(LOG_COLOR_FORE_CYAN | LOG_COLOR_FORE_INTENSITY) << CS_XOR("Leerware initialization completed, version: ") << CS_STRINGIFY(CS_VERSION);
return true;
}
// @todo: some of those may crash while closing process, because we dont have any dependencies from the game modules, it means them can be unloaded and destruct interfaces etc before our module | modify ldrlist?
static void Destroy()
{
// restore window messages processor to original
IPT::Destroy();
// restore hooks
H::Destroy();
// destroy renderer backend
D::Destroy();
// destroy chams dependent stuff
F::Destroy();
#ifdef CS_LOG_CONSOLE
L::DetachConsole();
#endif
#ifdef CS_LOG_FILE
L::CloseFile();
#endif
}
DWORD WINAPI PanicThread(LPVOID lpParameter)
{
// don't let proceed unload until user press specified key
while (!IPT::IsKeyReleased(C_GET(unsigned int, Vars.nPanicKey)))
::Sleep(500UL);
// call detach code and exit this thread
::FreeLibraryAndExitThread(static_cast<HMODULE>(lpParameter), EXIT_SUCCESS);
}
extern "C" BOOL WINAPI _CRT_INIT(HMODULE hModule, DWORD dwReason, LPVOID lpReserved);
BOOL APIENTRY CoreEntryPoint(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
// Disables the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications for the specified dynamic-link library (DLL). This can reduce the size of the working set for some applications
DisableThreadLibraryCalls(hModule);
// process destroy of the cheat before crt calls atexit table
if (dwReason == DLL_PROCESS_DETACH)
Destroy();
// dispatch reason for c-runtime, initialize/destroy static variables, TLS etc
if (!_CRT_INIT(hModule, dwReason, lpReserved))
return FALSE;
if (dwReason == DLL_PROCESS_ATTACH)
{
CORE::hProcess = MEM::GetModuleBaseHandle(nullptr);
// basic process check
if (CORE::hProcess == nullptr)
return FALSE;
/*
* check did all game modules have been loaded
* @note: navsystem.dll is the last loaded module
*/
if (MEM::GetModuleBaseHandle(NAVSYSTEM_DLL) == nullptr)
return FALSE;
// save our module handle
CORE::hDll = hModule;
// check did we perform main initialization successfully
if (!Setup(hModule))
{
// undo the things we've done
Destroy();
return FALSE;
}
// create panic thread, it isn't critical error if it fails
if (const HANDLE hThread = ::CreateThread(nullptr, 0U, &PanicThread, hModule, 0UL, nullptr); hThread != nullptr)
::CloseHandle(hThread);
}
return TRUE;
}