dllmain.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. #include <iostream>
  2. #include <vector>
  3. #include <Windows.h>
  4. #include <Dbt.h>
  5. #include <stdio.h>
  6. #include "Constants.h"
  7. #include "framework.h"
  8. #include "pluginconfig.h"
  9. #include "Input/Mouse/Mouse.h"
  10. #include "Input/Xinput/Xinput.h"
  11. #include "Input/Keyboard/Keyboard.h"
  12. #include "Input/DirectInput/DirectInput.h"
  13. #include "Input/DirectInput/Ds4/DualShock4.h"
  14. #include "Input/DirectInput/GenericUsb/GenericUsbInput.h"
  15. #include "Components/ComponentsManager.h"
  16. #include <tchar.h>
  17. #include <GL/freeglut.h>
  18. #include <detours.h>
  19. #include <fstream>
  20. #pragma comment(lib, "detours.lib")
  21. void(__cdecl* divaEngineUpdate)() = (void(__cdecl*)())0x14018CC40;
  22. void(__cdecl* divaEngineDraw2D)(void* addr) = (void(__cdecl*)(void* addr))ENGINE_DRAW_2D_ADDRESS;
  23. LRESULT CALLBACK MessageWindowProcessCallback(HWND, UINT, WPARAM, LPARAM);
  24. DWORD WINAPI WindowMessageDispatcher(LPVOID);
  25. VOID RegisterMessageWindowClass();
  26. struct
  27. {
  28. DWORD ID = NULL;
  29. HANDLE Handle = NULL;
  30. } MessageThread;
  31. const wchar_t* MessageWindowClassName = TEXT("MessageWindowClass");
  32. const wchar_t* MessageWindowName = TEXT("MessageWindowTitle");
  33. namespace TLAC
  34. {
  35. Components::ComponentsManager ComponentsManager;
  36. bool DeviceConnected = true;
  37. bool FirstUpdateTick = true;
  38. bool HasWindowFocus, HadWindowFocus;
  39. void InitializeTick()
  40. {
  41. RegisterMessageWindowClass();
  42. if ((MessageThread.Handle = CreateThread(0, 0, WindowMessageDispatcher, 0, 0, 0)) == NULL)
  43. printf("[TLAC] InitializeTick(): CreateThread() Error: %d\n", GetLastError());
  44. framework::DivaWindowHandle = WindowFromDC(wglGetCurrentDC());
  45. HRESULT diInitResult = Input::InitializeDirectInput(framework::Module);
  46. if (FAILED(diInitResult))
  47. printf("[TLAC] InitializeTick(): Failed to initialize DirectInput. Error: 0x%08X\n", diInitResult);
  48. ComponentsManager.Initialize();
  49. }
  50. void UpdateTick()
  51. {
  52. if (FirstUpdateTick)
  53. {
  54. FirstUpdateTick = false;
  55. InitializeTick();
  56. }
  57. if (DeviceConnected)
  58. {
  59. DeviceConnected = false;
  60. if (!Input::DualShock4::InstanceInitialized())
  61. {
  62. if (Input::DualShock4::TryInitializeInstance())
  63. printf("[TLAC] UpdateTick(): DualShock4 connected and initialized\n");
  64. }
  65. if (!Input::GenericUsbInput::InstanceInitialized())
  66. {
  67. if (Input::GenericUsbInput::TryInitializeInstance())
  68. printf("[TLAC] UpdateTick(): GenericUsbInput connected and initialized\n");
  69. }
  70. }
  71. ComponentsManager.Update();
  72. HadWindowFocus = HasWindowFocus;
  73. HasWindowFocus = framework::DivaWindowHandle == NULL || GetForegroundWindow() == framework::DivaWindowHandle;
  74. if ((HasWindowFocus) && (!framework::inputDisable))
  75. {
  76. Input::Keyboard::GetInstance()->PollInput();
  77. Input::Mouse::GetInstance()->PollInput();
  78. Input::Xinput::GetInstance()->PollInput();
  79. if (Input::DualShock4::GetInstance() != nullptr)
  80. {
  81. if (!Input::DualShock4::GetInstance()->PollInput())
  82. {
  83. Input::DualShock4::DeleteInstance();
  84. printf("[TLAC] UpdateTick(): DualShock4 connection lost\n");
  85. }
  86. }
  87. if (Input::GenericUsbInput::GetInstance() != nullptr)
  88. {
  89. if (!Input::GenericUsbInput::GetInstance()->PollInput())
  90. {
  91. Input::GenericUsbInput::DeleteInstance();
  92. printf("[TLAC] UpdateTick(): GenericUsbInput connection lost\n");
  93. }
  94. }
  95. ComponentsManager.UpdateInput();
  96. }
  97. ComponentsManager.UpdatePostInput();
  98. if ((framework::inputDisable))
  99. {
  100. Input::Keyboard::GetInstance()->PollInput();
  101. Input::Mouse::GetInstance()->PollInput();
  102. Input::Xinput::GetInstance()->PollInput();
  103. if (Input::DualShock4::GetInstance() != nullptr)
  104. {
  105. if (!Input::DualShock4::GetInstance()->PollInput())
  106. {
  107. Input::DualShock4::DeleteInstance();
  108. printf("[TLAC] UpdateTick(): DualShock4 connection lost\n");
  109. }
  110. }
  111. if (Input::GenericUsbInput::GetInstance() != nullptr)
  112. {
  113. if (!Input::GenericUsbInput::GetInstance()->PollInput())
  114. {
  115. Input::GenericUsbInput::DeleteInstance();
  116. printf("[TLAC] UpdateTick(): GenericUsbInput connection lost\n");
  117. }
  118. }
  119. }
  120. if (HasWindowFocus && !HadWindowFocus)
  121. ComponentsManager.OnFocusGain();
  122. if (!HasWindowFocus && HadWindowFocus)
  123. ComponentsManager.OnFocusLost();
  124. }
  125. void UpdateDraw2D()
  126. {
  127. ComponentsManager.UpdateDraw2D();
  128. }
  129. /*void InitializeExtraSettings()
  130. {
  131. const LPCTSTR RESOLUTION_CONFIG_FILE_NAME = _T(".\\config.ini");
  132. auto nTAA = GetPrivateProfileIntW(L"graphics", L"taa", TRUE, RESOLUTION_CONFIG_FILE_NAME);
  133. auto nMLAA = GetPrivateProfileIntW(L"graphics", L"mlaa", TRUE, RESOLUTION_CONFIG_FILE_NAME);
  134. if (!nTAA)
  135. {
  136. {
  137. // set TAA var (shouldn't be needed but whatever)
  138. *(byte*)0x00000001411AB67C = 0;
  139. }
  140. {
  141. // make constructor/init not set TAA
  142. DWORD oldProtect, bck;
  143. VirtualProtect((BYTE*)0x00000001404AB11D, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
  144. *((byte*)0x00000001404AB11D + 0) = 0x90;
  145. *((byte*)0x00000001404AB11D + 1) = 0x90;
  146. *((byte*)0x00000001404AB11D + 2) = 0x90;
  147. VirtualProtect((BYTE*)0x00000001404AB11D, 3, oldProtect, &bck);
  148. }
  149. {
  150. // not sure, but it's somewhere in TaskPvGame init
  151. // just make it set TAA to 0 instead of 1 to avoid possible issues
  152. DWORD oldProtect, bck;
  153. VirtualProtect((BYTE*)0x00000001401063CE, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
  154. *((byte*)0x00000001401063CE + 0) = 0x00;
  155. VirtualProtect((BYTE*)0x00000001401063CE, 1, oldProtect, &bck);
  156. }
  157. {
  158. // prevent re-enabling after taking photos
  159. DWORD oldProtect, bck;
  160. VirtualProtect((BYTE*)0x000000014048FBA9, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
  161. *((byte*)0x000000014048FBA9 + 0) = 0x00;
  162. VirtualProtect((BYTE*)0x000000014048FBA9, 1, oldProtect, &bck);
  163. }
  164. printf("[TLAC] TAA disabled\n");
  165. }
  166. if (!nMLAA)
  167. {
  168. {
  169. // set MLAA var (shouldn't be needed but whatever)
  170. *(byte*)0x00000001411AB680 = 0;
  171. }
  172. {
  173. // make constructor/init not set MLAA
  174. DWORD oldProtect, bck;
  175. VirtualProtect((BYTE*)0x00000001404AB11A, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
  176. *((byte*)0x00000001404AB11A + 0) = 0x90;
  177. *((byte*)0x00000001404AB11A + 1) = 0x90;
  178. *((byte*)0x00000001404AB11A + 2) = 0x90;
  179. VirtualProtect((BYTE*)0x00000001404AB11A, 3, oldProtect, &bck);
  180. }
  181. printf("[TLAC] MLAA disabled\n");
  182. }
  183. /*if (nMagFilter > -1)
  184. {
  185. {
  186. // set MAG filter var
  187. *(byte*)0x00000001411AC518 = nMagFilter;
  188. }
  189. {
  190. // make constructor/init not set MAG filter (1)
  191. DWORD oldProtect, bck;
  192. VirtualProtect((BYTE*)0x00000001404AB13C, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
  193. *((byte*)0x00000001404AB13C + 0) = 0x90;
  194. *((byte*)0x00000001404AB13C + 1) = 0x90;
  195. *((byte*)0x00000001404AB13C + 2) = 0x90;
  196. *((byte*)0x00000001404AB13C + 3) = 0x90;
  197. *((byte*)0x00000001404AB13C + 4) = 0x90;
  198. *((byte*)0x00000001404AB13C + 5) = 0x90;
  199. VirtualProtect((BYTE*)0x00000001404AB13C, 6, oldProtect, &bck);
  200. }
  201. {
  202. // make constructor/init not set MAG filter (2)
  203. DWORD oldProtect, bck;
  204. VirtualProtect((BYTE*)0x00000001404A863F, 10, PAGE_EXECUTE_READWRITE, &oldProtect);
  205. *((byte*)0x00000001404A863F + 0) = 0x90;
  206. *((byte*)0x00000001404A863F + 1) = 0x90;
  207. *((byte*)0x00000001404A863F + 2) = 0x90;
  208. *((byte*)0x00000001404A863F + 3) = 0x90;
  209. *((byte*)0x00000001404A863F + 4) = 0x90;
  210. *((byte*)0x00000001404A863F + 5) = 0x90;
  211. *((byte*)0x00000001404A863F + 6) = 0x90;
  212. *((byte*)0x00000001404A863F + 7) = 0x90;
  213. *((byte*)0x00000001404A863F + 8) = 0x90;
  214. *((byte*)0x00000001404A863F + 9) = 0x90;
  215. VirtualProtect((BYTE*)0x00000001404A863F, 10, oldProtect, &bck);
  216. }
  217. printf("[TLAC] MAG Filter set to %d\n", nMagFilter);
  218. }*
  219. }*/
  220. void Dispose()
  221. {
  222. ComponentsManager.Dispose();
  223. delete Input::Keyboard::GetInstance();
  224. delete Input::Mouse::GetInstance();
  225. delete Input::DualShock4::GetInstance();
  226. delete Input::GenericUsbInput::GetInstance();
  227. Input::DisposeDirectInput();
  228. PostThreadMessage(MessageThread.ID, WM_QUIT, 0, 0);
  229. }
  230. }
  231. DWORD WINAPI WindowMessageDispatcher(LPVOID lpParam)
  232. {
  233. HWND windowHandle = CreateWindowW(
  234. MessageWindowClassName,
  235. MessageWindowName,
  236. WS_OVERLAPPEDWINDOW,
  237. CW_USEDEFAULT, CW_USEDEFAULT,
  238. CW_USEDEFAULT, CW_USEDEFAULT,
  239. NULL, NULL,
  240. TLAC::framework::Module,
  241. NULL);
  242. if (!windowHandle)
  243. {
  244. printf("[TLAC] WindowMessageDispatcher(): CreateWindowW() Error: %d\n", GetLastError());
  245. return 1;
  246. }
  247. MessageThread.ID = GetCurrentThreadId();
  248. MSG message;
  249. DWORD returnValue;
  250. printf("[TLAC] WindowMessageDispatcher(): Entering message loop...\n");
  251. while (1)
  252. {
  253. returnValue = GetMessage(&message, NULL, 0, 0);
  254. if (returnValue != -1)
  255. {
  256. TranslateMessage(&message);
  257. DispatchMessage(&message);
  258. }
  259. else
  260. {
  261. printf("[TLAC] WindowMessageDispatcher(): GetMessage() Error: %d\n", returnValue);
  262. }
  263. }
  264. DestroyWindow(windowHandle);
  265. return 0;
  266. }
  267. BOOL RegisterDeviceInterface(HWND hWnd, HDEVNOTIFY* hDeviceNotify)
  268. {
  269. DEV_BROADCAST_DEVICEINTERFACE NotificationFilter = {};
  270. NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
  271. NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
  272. *hDeviceNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
  273. return *hDeviceNotify != NULL;
  274. }
  275. LRESULT CALLBACK MessageWindowProcessCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  276. {
  277. switch (message)
  278. {
  279. case WM_CREATE:
  280. {
  281. HDEVNOTIFY hDevNotify = NULL;
  282. if (!RegisterDeviceInterface(hWnd, &hDevNotify))
  283. printf("[TLAC] MessageWindowProcessCallback(): RegisterDeviceInterface() Error: %d\n", GetLastError());
  284. break;
  285. }
  286. case WM_DEVICECHANGE:
  287. {
  288. switch (wParam)
  289. {
  290. case DBT_DEVICEARRIVAL:
  291. TLAC::DeviceConnected = true;
  292. break;
  293. default:
  294. break;
  295. }
  296. }
  297. default:
  298. return DefWindowProc(hWnd, message, wParam, lParam);
  299. }
  300. return 0;
  301. }
  302. VOID RegisterMessageWindowClass()
  303. {
  304. WNDCLASS windowClass = { };
  305. windowClass.lpfnWndProc = MessageWindowProcessCallback;
  306. windowClass.hInstance = TLAC::framework::Module;
  307. windowClass.lpszClassName = MessageWindowClassName;
  308. RegisterClass(&windowClass);
  309. }
  310. void hookedEngineUpdate()
  311. {
  312. TLAC::UpdateTick();
  313. //divaEngineUpdate();
  314. }
  315. void hookedEngineDraw2D(void* addr)
  316. {
  317. TLAC::UpdateDraw2D();
  318. divaEngineDraw2D(addr);
  319. }
  320. BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
  321. {
  322. HWND consoleHandle = GetConsoleWindow();
  323. switch (ul_reason_for_call)
  324. {
  325. case DLL_PROCESS_ATTACH:
  326. // Are you a dev and want to debug? Want to always be able to watch the console upon game initialization? Comment this.
  327. ShowWindow(consoleHandle, SW_HIDE);
  328. printf("[TLAC] DllMain(): Installing hooks...\n");
  329. //InstallHook((void*)ENGINE_UPDATE_HOOK_TARGET_ADDRESS, (void*)UpdateTick, 0xE);
  330. DisableThreadLibraryCalls(hModule);
  331. DetourTransactionBegin();
  332. DetourUpdateThread(GetCurrentThread());
  333. DetourAttach(&(PVOID&)divaEngineUpdate, hookedEngineUpdate);
  334. DetourTransactionCommit();
  335. DetourTransactionBegin();
  336. DetourUpdateThread(GetCurrentThread());
  337. DetourAttach(&(PVOID&)divaEngineDraw2D, hookedEngineDraw2D);
  338. DetourTransactionCommit();
  339. //TLAC::InitializeExtraSettings();
  340. TLAC::framework::Module = hModule;
  341. break;
  342. case DLL_PROCESS_DETACH:
  343. TLAC::Dispose();
  344. break;
  345. }
  346. return TRUE;
  347. }