You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2929 line
111 KiB

  1. // dllmain.cpp : Defines the entry point for the DLL application.
  2. #ifndef WIN32_LEAN_AND_MEAN
  3. #define WIN32_LEAN_AND_MEAN
  4. #endif
  5. #include <string>
  6. #include <windows.h>
  7. #include <iostream>
  8. #include <fstream>
  9. #include <vector>
  10. #include <tuple>
  11. #include <unordered_set>
  12. #include <inttypes.h>
  13. #include <wchar.h>
  14. #include <filesystem>
  15. #include <stack>
  16. // Link with ws2_32.lib
  17. #pragma comment(lib, "Ws2_32.lib")
  18. #include "F:/Programmieren/C++/json.hpp"
  19. using json = nlohmann::json;
  20. #include "include/easywsclient.hpp"
  21. #include "include/easywsclient.cpp"
  22. #include "include/MinHook.h"
  23. #ifdef __clang__
  24. #pragma comment(lib, "lib/libMinHook-MD.x64.Clang.lib")
  25. #else
  26. #pragma comment(lib, "lib/libMinHook-MD.x64.lib")
  27. #endif
  28. //#include "F:/Programmieren/C++/myhelpers/xorstr.h"
  29. #define JM_XORSTR_DISABLE_AVX_INTRINSICS 1
  30. #include "F:/Programmieren/C++/xorstr-master/include/xorstr.hpp"
  31. #include "F:/Programmieren/C++/myhelpers/SuspendResume.hpp"
  32. #include "include/patternscan.hpp"
  33. //
  34. #include "F:/Programmieren/C++/myhelpers/DebugHelper.hpp"
  35. //
  36. //#include "C:/SDK_GEN/BL3/SDK/BL3_Basic.hpp"
  37. //#include "C:/SDK_GEN/BL3/SDK/BL3_CoreUObject_classes.hpp"
  38. #include "C:/SDK_GEN/BL3-2021-4-9/SDK.hpp"
  39. #include "BL3Lua.h"
  40. #include "LuaUtility.h"
  41. #include "Patterns.h"
  42. #include "spdlog/spdlog.h"
  43. #include "spdlog/sinks/basic_file_sink.h"
  44. #pragma comment(lib, "lib/spdlog.lib")
  45. using namespace SDK;
  46. std::string proxyURLA = "https://127.0.0.1:";
  47. std::string proxyPort = "9999";
  48. //static bool alreadyRunning = false;
  49. static bool gObjInit;
  50. static bool gNameInit;
  51. static bool wantsExit;
  52. static bool inCustomOptionsMenu;
  53. //CRITICAL_SECTION critsec;
  54. BL3Lua *luamgr = NULL;
  55. sol::environment* nonScriptEnv;
  56. using easywsclient::WebSocket;
  57. WebSocket::pointer ws = NULL;
  58. WebSocket::pointer iws = NULL;
  59. bool disconnected = false;
  60. bool idisconnected = false;
  61. spdlog::logger* Logger;
  62. struct UIData {
  63. public:
  64. std::string DisplayName;
  65. EOptionItemType UIElementType;
  66. };
  67. struct UITitle : UIData {
  68. public:
  69. };
  70. struct UIButton : UIData {
  71. public:
  72. std::string DescriptionTitle;
  73. std::string DescriptionText;
  74. sol::function OnChangedOrClicked;
  75. lua_State* state;
  76. };
  77. struct UISlider : UIData {
  78. std::string DescriptionTitle;
  79. std::string DescriptionText;
  80. sol::function OnChangedOrClicked;
  81. float Value;
  82. float Min;
  83. float Max;
  84. float Step;
  85. bool bIsInt;
  86. lua_State* state;
  87. };
  88. struct UISpinner : UIData {
  89. std::string DescriptionTitle;
  90. std::string DescriptionText;
  91. sol::function OnChangedOrClicked;
  92. int Index;
  93. sol::table Options;
  94. lua_State* state;
  95. };
  96. struct UIBoolSpinner : UIData {
  97. std::string DescriptionTitle;
  98. std::string DescriptionText;
  99. sol::function OnChangedOrClicked;
  100. bool Value;
  101. std::string OnText;
  102. std::string OffText;
  103. lua_State* state;
  104. };
  105. struct UIDropdown : UIData {
  106. std::string DescriptionTitle;
  107. std::string DescriptionText;
  108. sol::function OnChangedOrClicked;
  109. int Index;
  110. sol::table Options;
  111. lua_State* state;
  112. };
  113. struct UIControl : UIData {
  114. std::string DescriptionTitle;
  115. std::string DescriptionText;
  116. sol::function OnChangedOrClicked;
  117. lua_State* state;
  118. };
  119. struct MenuToCreate {
  120. lua_State* s;
  121. std::string ButtonText;
  122. sol::function OnClick;
  123. sol::function BuildUI;
  124. sol::function ConditionToShow;
  125. MenuToCreate()
  126. {
  127. s = NULL;
  128. ButtonText = "";
  129. OnClick = sol::lua_nil;
  130. BuildUI = sol::lua_nil;
  131. ConditionToShow = sol::lua_nil;
  132. }
  133. };
  134. static UFunction* onGraphicsClickedFunc = NULL;
  135. UGbxGFxButton* lastPressedButton = NULL;
  136. UGbxGFxButton* bLuaMenuBtn = NULL;
  137. std::unordered_map<void*, std::tuple<sol::reference, sol::reference, lua_State*>> createdMenuItems;
  138. std::unordered_map<void*, UIData*> uiData;
  139. std::stack<MenuToCreate> myMenuStack;
  140. MenuToCreate* bluaMenu = new MenuToCreate;
  141. std::vector<MenuToCreate> menusToCreate;
  142. sol::table b3hmTable;
  143. void WebSocketClientThread()
  144. {
  145. INT rc;
  146. WSADATA wsaData;
  147. rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
  148. if (rc)
  149. {
  150. printf("WSAStartup Failed.\n");
  151. return;
  152. }
  153. EnterCriticalSection(&luamgr->luaCritSec);
  154. b3hmTable.set_function("Send", [](const std::string& message) {if (ws) ws->send(message); });
  155. LeaveCriticalSection(&luamgr->luaCritSec);
  156. while (true)
  157. {
  158. ws = WebSocket::from_url("ws://localhost:9998/ws", "",true);
  159. if (!ws)
  160. continue;
  161. while (ws->getReadyState() != easywsclient::WebSocket::OPEN)
  162. {
  163. Sleep(5);
  164. }
  165. EnterCriticalSection(&luamgr->luaCritSec);
  166. luamgr->lua->set("websocket", std::ref(ws));
  167. LeaveCriticalSection(&luamgr->luaCritSec);
  168. disconnected = false;
  169. while (ws->getReadyState() != WebSocket::CLOSED)
  170. {
  171. ws->poll();
  172. ws->dispatch([&](const std::string &msg) {
  173. json j = json::from_msgpack(msg);
  174. auto eventName = j["EventName"];
  175. auto content = j["Content"];
  176. auto bindata = content.get_binary();
  177. auto output = std::string(bindata.begin(), bindata.end());
  178. json fin;
  179. fin["EventName"] = j["EventName"];
  180. fin["Content"] = output;
  181. fin["Error"] = j["Error"];
  182. if (luamgr)
  183. {
  184. luamgr->RunCallbacks("OnSocketMessage", sol::make_object(*luamgr->lua, fin.dump()));
  185. }
  186. });
  187. }
  188. EnterCriticalSection(&luamgr->luaCritSec);
  189. luamgr->lua->set("websocket", sol::nil);
  190. LeaveCriticalSection(&luamgr->luaCritSec);
  191. disconnected = true;
  192. delete ws;
  193. ws = NULL;
  194. }
  195. }
  196. void iWebSocketClientThread()
  197. {
  198. INT rc;
  199. WSADATA wsaData;
  200. rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
  201. if (rc)
  202. {
  203. printf("WSAStartup Failed.\n");
  204. return;
  205. }
  206. EnterCriticalSection(&luamgr->luaCritSec);
  207. /*luamgr->lua->new_usertype<WebSocket>(
  208. "ImmediateWebSocket", sol::no_constructor,*/
  209. b3hmTable.set_function("Connected", []() {return iws != NULL; });
  210. b3hmTable.set_function("SendAndReceive",
  211. /*"SendData", */[](/*WebSocket::pointer pSocket,*/sol::this_state s, const std::string& msg, const std::string& eventToReceive = "")
  212. {
  213. if (!iws)
  214. return sol::make_object(s.L, sol::lua_nil);
  215. if (iws && iws->getReadyState() != WebSocket::CLOSED)
  216. iws->send(msg);
  217. while (iws && iws->getReadyState() != WebSocket::CLOSED) {
  218. iws->poll();
  219. std::string response;
  220. iws->dispatch([&](const std::string& incMsg) {
  221. try {
  222. json j = json::from_msgpack(incMsg);
  223. auto eventName = j["EventName"];
  224. auto content = j["Content"];
  225. auto bindata = content.get_binary();
  226. auto output = std::string(bindata.begin(), bindata.end());
  227. json fin;
  228. fin["EventName"] = j["EventName"];
  229. fin["Content"] = output;
  230. fin["Error"] = j["Error"];
  231. if (eventToReceive.size() > 0 && eventName == eventToReceive)
  232. response = fin.dump();
  233. }
  234. catch (...) {}
  235. });
  236. if (response.size() > 0)
  237. return sol::make_object(s.L, response);
  238. }});
  239. /*});*/
  240. LeaveCriticalSection(&luamgr->luaCritSec);
  241. while (true)
  242. {
  243. iws = WebSocket::from_url("ws://localhost:9998/ws", "", false);
  244. if (!iws || !ws)
  245. continue;
  246. while (iws->getReadyState() != easywsclient::WebSocket::OPEN)
  247. {
  248. Sleep(5);
  249. }
  250. EnterCriticalSection(&luamgr->luaCritSec);
  251. //luamgr->lua->set("iwebsocket", std::ref(iws));
  252. //luamgr->lua->set("iwebsocket", [&]() {return iws; });
  253. LeaveCriticalSection(&luamgr->luaCritSec);
  254. idisconnected = false;
  255. while (ws && ws->getReadyState() != WebSocket::CLOSED)
  256. {
  257. /*iws->poll(-1);
  258. iws->dispatch([&](const std::string& msg) {
  259. json j = json::from_msgpack(msg);
  260. auto eventName = j["EventName"];
  261. auto content = j["Content"];
  262. auto bindata = content.get_binary();
  263. auto output = std::string(bindata.begin(), bindata.end());
  264. json fin;
  265. fin["EventName"] = j["EventName"];
  266. fin["Content"] = output;
  267. fin["Error"] = j["Error"];
  268. if (luamgr)
  269. {
  270. luamgr->RunCallbacks("OnSocketMessage", sol::make_object(*luamgr->lua, fin.dump()));
  271. }
  272. });*/
  273. Sleep(10);
  274. }
  275. EnterCriticalSection(&luamgr->luaCritSec);
  276. luamgr->lua->set("iwebsocket", sol::nil);
  277. LeaveCriticalSection(&luamgr->luaCritSec);
  278. idisconnected = true;
  279. delete iws;
  280. iws = NULL;
  281. }
  282. }
  283. void callAtExit()
  284. {
  285. wantsExit = true;
  286. if (!disconnected)
  287. {
  288. if (ws)
  289. ws->close();
  290. }
  291. if (!idisconnected)
  292. {
  293. if (iws)
  294. iws->close();
  295. }
  296. MH_DisableHook(MH_ALL_HOOKS);
  297. MH_Uninitialize();
  298. if (luamgr && luamgr->lua)
  299. {
  300. b3hmTable.clear();
  301. b3hmTable = sol::lua_nil;
  302. lua_close(*luamgr->lua);
  303. }
  304. }
  305. static UConsole *console = NULL;
  306. void ConsoleSetup()
  307. {
  308. while (!*GEngine)
  309. Sleep(20);
  310. if (*GEngine && !console)
  311. {
  312. UEngine *eng = *GEngine;
  313. UInputSettings *settings = NULL;
  314. FName key = FName("F6");
  315. static FKey consoleKey = {0};
  316. consoleKey.KeyName = key;
  317. while (!settings)
  318. settings = UObject::FindObject<UInputSettings>("InputSettings Engine.Default__InputSettings");
  319. UInputSettings *staticSettings = settings->GetInputSettings();
  320. staticSettings->ConsoleKeys.Data = nullptr;
  321. staticSettings->ConsoleKeys.Count = 0;
  322. staticSettings->ConsoleKeys.Add(consoleKey);
  323. while (!eng->GameViewport)
  324. {
  325. Sleep(20);
  326. }
  327. if (eng && eng->GameViewport && eng->GameViewport->ViewportConsole)
  328. {
  329. console = eng->GameViewport->ViewportConsole;
  330. }
  331. else
  332. {
  333. UConsole *defaultCon = UObject::FindObject<UConsole>("Console Engine.Default__Console");
  334. console = reinterpret_cast<UConsole *>(StaticConstructObject(defaultCon->Class, defaultCon->Outer, FName("UConsole"), EObjectFlags(0)));
  335. }
  336. while (true)
  337. {
  338. try
  339. {
  340. if (eng->GameViewport && eng->GameViewport->World && eng->GameViewport->World->OwningGameInstance && eng->GameViewport->World->OwningGameInstance->LocalPlayers.Num() > 0)
  341. {
  342. console->ConsoleTargetPlayer = eng->GameViewport->World->OwningGameInstance->LocalPlayers[0];
  343. eng->GameViewport->ViewportConsole = console;
  344. break;
  345. }
  346. }
  347. catch (...)
  348. {
  349. }
  350. Sleep(10);
  351. }
  352. }
  353. }
  354. void AddConsoleKey(const std::string &keyName)
  355. {
  356. static UInputSettings *settings = NULL;
  357. FName key = FName(keyName);
  358. FKey consoleKey = {0};
  359. consoleKey.KeyName = key;
  360. while (!settings)
  361. settings = UObject::FindObject<UInputSettings>("InputSettings Engine.Default__InputSettings");
  362. UInputSettings *staticSettings = settings->GetInputSettings();
  363. staticSettings->ConsoleKeys.Add(consoleKey);
  364. staticSettings->ConsoleKeys.Count++;
  365. }
  366. void SetConsoleKey(const std::string &keyName)
  367. {
  368. static UInputSettings *settings = NULL;
  369. FName key = FName(keyName);
  370. FKey consoleKey = {0};
  371. consoleKey.KeyName = key;
  372. while (!settings)
  373. settings = UObject::FindObject<UInputSettings>("InputSettings Engine.Default__InputSettings");
  374. if (settings && settings->IsValidLowLevel())
  375. {
  376. UInputSettings *staticSettings = settings->GetInputSettings();
  377. staticSettings->ConsoleKeys.Data = nullptr;
  378. staticSettings->ConsoleKeys.Count = 0;
  379. staticSettings->ConsoleKeys.Add(consoleKey);
  380. }
  381. }
  382. static UOakCheatManager *cheatManager = NULL;
  383. void CreateCheatManager()
  384. {
  385. AOakPlayerController* pc = UObject::GetPlayerController();
  386. while (!pc) {
  387. pc = UObject::GetPlayerController();
  388. Sleep(20);
  389. }
  390. if (!pc->CheatManager) {
  391. pc->CheatManager = static_cast<UOakCheatManager*>(StaticConstructObject(pc->CheatClass, pc, FName("UOakCheatManager")));
  392. pc->CheatManager->ReceiveInitCheatManager();
  393. }
  394. if (pc->CheatManager) {
  395. EnterCriticalSection(&luamgr->luaCritSec);
  396. UWorld* world = UObject::GetCurrentWorld();
  397. while (!world){
  398. world = UObject::GetCurrentWorld();
  399. Sleep(20);
  400. }
  401. luamgr->lua->set_function("TutorialMessage", []() {((UOakCheatManager*)UObject::GetPlayerController()->CheatManager)->TestTutorialWidget(); });
  402. luamgr->lua->set_function("DumpSave2Json", []() {((UOakCheatManager*)UObject::GetPlayerController()->CheatManager)->DumpSaveToJson(); });
  403. LeaveCriticalSection(&luamgr->luaCritSec);
  404. }
  405. }
  406. sol::object GetParamData(lua_State *s, UProperty *property, void *params)
  407. {
  408. int32_t currentOffset = property->Offset_Internal;
  409. if (property->IsA(UObjectProperty::StaticClass()))
  410. {
  411. sol::table objectData(s, sol::create);
  412. UProperty *current = static_cast<UProperty *>(property->Next);
  413. if (!current)
  414. {
  415. return sol::make_object(s, reinterpret_cast<UObject *>((uintptr_t)params + currentOffset));
  416. }
  417. while (current && current->IsValidLowLevel())
  418. {
  419. std::string propName = current->GetName();
  420. if (propName.size() > 0)
  421. {
  422. objectData[propName] = GetParamData(s, current, params);
  423. }
  424. current = static_cast<UProperty *>(current->Next);
  425. }
  426. return objectData;
  427. }
  428. else if (property->IsA(UStrProperty::StaticClass()))
  429. {
  430. return sol::make_object(s, *reinterpret_cast<FString *>((uintptr_t)params + property->Offset_Internal));
  431. }
  432. else if (property->IsA(UIntProperty::StaticClass()))
  433. {
  434. return sol::make_object(s, *reinterpret_cast<int32_t *>((uintptr_t)params + property->Offset_Internal));
  435. }
  436. else if (property->IsA(UFloatProperty::StaticClass()))
  437. {
  438. return sol::make_object(s, *reinterpret_cast<float *>((uintptr_t)params + property->Offset_Internal));
  439. }
  440. else if (property->IsA(USoftObjectProperty::StaticClass()))
  441. {
  442. return sol::make_object(s, *reinterpret_cast<FSoftObjectPtr *>((uintptr_t)params + property->Offset_Internal));
  443. }
  444. // I don't think this is working correctly
  445. else if (property->IsA(UStructProperty::StaticClass()))
  446. {
  447. std::string currentName = property->GetName();
  448. UStructProperty *currentStructProperty = reinterpret_cast<UStructProperty *>((uintptr_t)property);
  449. if (!currentStructProperty)
  450. return sol::nil;
  451. UStruct *currentStruct = currentStructProperty->Struct;
  452. sol::table objectData(s, sol::create);
  453. while (currentStruct)
  454. {
  455. for (UProperty *current = static_cast<UProperty *>(currentStruct->Children); current; current = static_cast<UProperty *>(current->Next))
  456. {
  457. std::string propName = current->GetName();
  458. if (propName.size() > 0)
  459. {
  460. objectData[propName] = GetParamData(s, current, reinterpret_cast<void *>((uintptr_t)params + property->Offset_Internal));
  461. }
  462. }
  463. currentStruct = currentStruct->SuperField;
  464. }
  465. return objectData;
  466. }
  467. // Implement proper reading/writing of these
  468. else if (property->IsA(UBoolProperty::StaticClass()))
  469. {
  470. return sol::make_object(s, *reinterpret_cast<bool *>((uintptr_t)params + property->Offset_Internal));
  471. }
  472. else if (property->IsA(UNameProperty::StaticClass()))
  473. {
  474. return sol::make_object(s, *reinterpret_cast<FName *>((uintptr_t)params + property->Offset_Internal));
  475. }
  476. else if (property->IsA(UInt64Property::StaticClass()))
  477. {
  478. return sol::make_object(s, *reinterpret_cast<int64_t *>((uintptr_t)params + property->Offset_Internal));
  479. }
  480. else if (property->IsA(UUInt64Property::StaticClass()))
  481. {
  482. return sol::make_object(s, *reinterpret_cast<uint64_t *>((uintptr_t)params + property->Offset_Internal));
  483. }
  484. //else if (property->IsA(UFunction::StaticClass())) {
  485. // return sol::make_object(s, *reinterpret_cast<UFunction*>(property);
  486. //}
  487. else if (property->IsA(UEnumProperty::StaticClass()))
  488. {
  489. return sol::make_object(s, *reinterpret_cast<UEnumProperty *>((uintptr_t)params + property->Offset_Internal));
  490. }
  491. else
  492. {
  493. char buffer[255];
  494. sprintf_s(buffer, "\"%s\" is a property that is currently not being handled!", property->Class->GetName().c_str());
  495. std::cout << buffer << std::endl;
  496. return sol::make_object(s, sol::nil);
  497. //throw(buffer);
  498. }
  499. return sol::nil;
  500. }
  501. sol::object GetObjectMembers(lua_State *s, UObject *obj)
  502. {
  503. if (!obj)
  504. return sol::nil;
  505. UStruct *currentClass = static_cast<UStruct *>(obj->Class);
  506. sol::table objectData(s, sol::create);
  507. while (currentClass)
  508. {
  509. for (UProperty *current = static_cast<UProperty *>(currentClass->Children); current; current = reinterpret_cast<UProperty *>(current->Next))
  510. {
  511. std::string propName = current->GetName();
  512. if (propName.size() > 0 && !current->IsA(UFunction::StaticClass()))
  513. {
  514. objectData[propName] = GetParamData(s, current, obj);
  515. }
  516. }
  517. currentClass = currentClass->SuperField;
  518. }
  519. return objectData;
  520. }
  521. sol::object GetFuncParams(lua_State *s, UFunction *func, void *params)
  522. {
  523. uint8_t numParams = func->NumParms;
  524. uint16_t returnValueOffset = func->ReturnValueOffset;
  525. bool doesReturnAnything = returnValueOffset != 0xFFFF;
  526. sol::table paramTable(s, sol::create);
  527. UProperty *current = static_cast<UProperty *>(func->Children);
  528. while (current && current->IsValidLowLevel())
  529. {
  530. std::string name = current->GetName();
  531. if (name.size() > 0)
  532. paramTable[name] = GetParamData(s, current, params);
  533. current = static_cast<UProperty *>(current->Next);
  534. }
  535. //if (!doesReturnAnything)
  536. // return sol::nil;
  537. return paramTable;
  538. }
  539. std::string GetFuncReturnType(UFunction *func)
  540. {
  541. uint8_t numParams = func->NumParms;
  542. uint16_t returnValueOffset = func->ReturnValueOffset;
  543. bool doesReturnAnything = returnValueOffset != 0xFFFF;
  544. if (!doesReturnAnything)
  545. return "";
  546. UProperty *current = static_cast<UProperty *>(func->Children);
  547. while (current && current->IsValidLowLevel())
  548. {
  549. std::string name = current->GetName();
  550. if (name.size() > 0)
  551. if (current->PropertyFlags & EPropertyFlags::CPF_ReturnParm)
  552. return current->Class->GetName();
  553. current = static_cast<UProperty *>(current->Next);
  554. }
  555. }
  556. static void PrintGameConsole(const std::string &text)
  557. {
  558. if (console)
  559. {
  560. FString fStringToPrint = FString(text.c_str());
  561. console->OutputText(&fStringToPrint);
  562. }
  563. }
  564. void hkProcessEvent(UObject *obj, UFunction *fn, void *parms)
  565. {
  566. std::string fName = fn->GetFullName();
  567. const char* funcName = fName.c_str();
  568. /* Possibly interesting to inject menudata
  569. Function GbxUI.GbxHintBarWidgetContainer.HintBarInitOwnerInfo
  570. Function GbxUI.GbxHintBarWidgetContainer.HintBarSetVisible
  571. Function GbxUI.GbxGFxButton.K2_HandleFocusableWidgetStateChanged
  572. Function OakGame.OakPlayerController.OnUIMenuActivated
  573. Function OakGame.OakPlayerController.ServerOnUIMenuActivated
  574. Function OakGame.GFxFrontendMenu.OnMenuStackChanged
  575. Function OakGame.MenuMapMenuFlow.OnMenuStackPush
  576. Function GbxUI.GbxHintBarWidgetContainer.HintBarClearAllHints
  577. Function GbxUI.GbxHintBarWidgetContainer.HintBarAppendHint
  578. Function GbxUI.GbxHintWidget.HintWidgetSetVisible
  579. */
  580. //if (funcName.find("Function OakGame.GFxFrontendMenu.OnMenuStackChanged") != std::string::npos) {
  581. //if (funcName.find("Function OakGame.GFxLoadedNewsImage.OnNewsImageLoadComplete") != std::string::npos) {
  582. /*if (funcName.find("Function Engine.HUD.ReceiveDrawHUD") != std::string::npos) {
  583. }*/
  584. /*if(strcmp(funcName, "Function Engine.Actor.ReceiveTick") != 0 &&
  585. strcmp(funcName, "Function Engine.ActorComponent.ReceiveTick") != 0 &&
  586. strcmp(funcName, "Function Engine.HUD.ReceiveDrawHUD") != 0 &&
  587. strcmp(funcName, "Function Engine.CameraModifier.BlueprintModifyCamera") != 0 &&
  588. strcmp(funcName, "Function Engine.CameraModifier.BlueprintModifyPostProcess") != 0 &&
  589. strcmp(funcName, "Function Engine.GameMode.ReadyToEndMatch") != 0 &&
  590. strcmp(funcName, "Function GbxCameraModes.CameraBehavior.Update") != 0 &&
  591. strcmp(funcName, "Function MenuMap_P.MenuMap_P_C.HandRotate__UpdateFunc") != 0 &&
  592. strcmp(funcName, "Function BP_TimeOfDay_Base.BP_TimeOfDay_Base_C.ReceiveTick") != 0 &&
  593. strcmp(funcName, "Function Engine.AnimNotifyState.Received_NotifyTick") != 0 &&
  594. strcmp(funcName, "Function Engine.ActorComponent.ReceiveEndPlay") != 0 &&
  595. strcmp(funcName, "Function Engine.AnimInstance.BlueprintInitializeAnimation") != 0 &&
  596. strcmp(funcName, "Function Engine.ActorComponent.ReceiveBeginPlay") != 0 &&
  597. strcmp(funcName, "Function Engine.Actor.ReceiveBeginPlay") != 0 &&
  598. strcmp(funcName, "Function Engine.AnimInstance.BlueprintPostEvaluateAnimation") != 0)
  599. std::cout << funcName << std::endl;*/
  600. if (strcmp(funcName, "Function GbxUI.GbxGFxListItemSpinner.OnSpinnerValueUpdated") == 0) {
  601. EnterCriticalSection(&luamgr->luaCritSec);
  602. if (uiData.find(obj) != uiData.end()) {
  603. UGbxGFxListItemSpinner* current = reinterpret_cast<UGbxGFxListItemSpinner*>(obj);
  604. int index = current->GetSelectionIndex();
  605. UISpinner* spinner = static_cast<UISpinner*>(uiData[obj]);
  606. spinner->Index = index;
  607. sol::protected_function func = spinner->OnChangedOrClicked;
  608. if (func.valid()) {
  609. sol::protected_function_result result;
  610. if (spinner->UIElementType == EOptionItemType::BooleanSpinner)
  611. {
  612. UIBoolSpinner* bSp = reinterpret_cast<UIBoolSpinner*>(spinner);
  613. result = func(bSp, bSp->Value);
  614. }
  615. else {
  616. result = func(spinner, index);
  617. }
  618. if (!result.valid())
  619. {
  620. PrintGameConsole("Failed to call spinner-callback");
  621. sol::error err = result;
  622. PrintGameConsole(err.what());
  623. Logger->error(err.what());
  624. }
  625. else {
  626. LeaveCriticalSection(&luamgr->luaCritSec);
  627. // Call default handler to update UI-Value and such
  628. return oProcessEvent(obj, fn, parms);
  629. }
  630. }
  631. }
  632. LeaveCriticalSection(&luamgr->luaCritSec);
  633. }
  634. else if (strcmp(funcName, "Function GbxUI.GbxGFxListItemNumber.OnSliderUpdated") == 0) {
  635. EnterCriticalSection(&luamgr->luaCritSec);
  636. if (uiData.find(obj) != uiData.end()) {
  637. UGbxGFxListItemNumber* current = reinterpret_cast<UGbxGFxListItemNumber*>(obj);
  638. float value = current->GetCurrentValue();
  639. UISlider* slider = static_cast<UISlider*>(uiData[obj]);
  640. slider->Value = value;
  641. sol::protected_function func = slider->OnChangedOrClicked;
  642. if (func.valid()) {
  643. sol::protected_function_result result;
  644. if(slider->bIsInt)
  645. result = func(slider, (int64_t)value);
  646. else
  647. result = func(slider, value);
  648. if (!result.valid())
  649. {
  650. PrintGameConsole("Failed to call slider-callback");
  651. sol::error err = result;
  652. PrintGameConsole(err.what());
  653. Logger->error(err.what());
  654. }
  655. else {
  656. LeaveCriticalSection(&luamgr->luaCritSec);
  657. // Call default handler to update UI-Value and such
  658. return oProcessEvent(obj, fn, parms);
  659. }
  660. }
  661. }
  662. LeaveCriticalSection(&luamgr->luaCritSec);
  663. }
  664. else if (strcmp(funcName, "Function OakGame.GFxGraphicsOptions.OnResolutionDropDownSelectionChanged") == 0) {
  665. UGFxGraphicsOptions_OnResolutionDropDownSelectionChanged_Params* thisParams = reinterpret_cast<UGFxGraphicsOptions_OnResolutionDropDownSelectionChanged_Params*>(parms);
  666. EnterCriticalSection(&luamgr->luaCritSec);
  667. if (uiData.find(thisParams->ComboBoxItem) != uiData.end()) {
  668. UGbxGFxListItemComboBox* current = thisParams->ComboBoxItem;
  669. int index = current->GetSelectedIndex();
  670. UIDropdown* dropdown = static_cast<UIDropdown*>(uiData[thisParams->ComboBoxItem]);
  671. dropdown->Index = index;
  672. sol::protected_function func = dropdown->OnChangedOrClicked;
  673. if (func.valid()) {
  674. sol::protected_function_result result = func(dropdown, index);
  675. if (!result.valid())
  676. {
  677. PrintGameConsole("Failed to call slider-callback");
  678. sol::error err = result;
  679. PrintGameConsole(err.what());
  680. Logger->error(err.what());
  681. }
  682. }
  683. LeaveCriticalSection(&luamgr->luaCritSec);
  684. // Call default handler to update UI-Value and such
  685. return oProcessEvent(obj, fn, parms);
  686. }
  687. LeaveCriticalSection(&luamgr->luaCritSec);
  688. }
  689. else if (strcmp(funcName, "Function OakGame.GFxGraphicsOptions.OnBenchmarkRunClicked") == 0) {
  690. EnterCriticalSection(&luamgr->luaCritSec);
  691. UGFxMainAndPauseBaseMenu_OnGraphicsClicked_Params* thisParams = reinterpret_cast<UGFxMainAndPauseBaseMenu_OnGraphicsClicked_Params*>(parms);
  692. if (uiData.find(thisParams->PressedButton) != uiData.end()) {
  693. UIButton* btn = static_cast<UIButton*>(uiData[thisParams->PressedButton]);
  694. sol::protected_function func = btn->OnChangedOrClicked;
  695. if (func.valid()) {
  696. sol::protected_function_result result = func(btn);
  697. if (!result.valid())
  698. {
  699. PrintGameConsole("Failed to call button-callback");
  700. sol::error err = result;
  701. PrintGameConsole(err.what());
  702. Logger->error(err.what());
  703. }
  704. else {
  705. LeaveCriticalSection(&luamgr->luaCritSec);
  706. return;
  707. }
  708. }
  709. }
  710. // This really can only be the intended "benchmark"-button
  711. else {
  712. LeaveCriticalSection(&luamgr->luaCritSec);
  713. // Call default handler to update UI-Value and such
  714. return oProcessEvent(obj, fn, parms);
  715. }
  716. }
  717. // Handle button-submenu MAIN menu
  718. else if (strcmp(funcName, "Function OakGame.GFxOakMainMenu.OnOptionsClicked") == 0) {
  719. UGFxOakMainMenu_OnOptionsClicked_Params* thisParams = static_cast<UGFxOakMainMenu_OnOptionsClicked_Params*>(parms);
  720. if(thisParams->PressedButton == bLuaMenuBtn){
  721. lastPressedButton = bLuaMenuBtn;
  722. inCustomOptionsMenu = true;
  723. EnterCriticalSection(&luamgr->luaCritSec);
  724. UGFxOakMainMenu* menuToUse = NULL;
  725. if (oGetMapName && oGetMapName().ToString().find("MenuMap_P") != std::string::npos) {
  726. menuToUse = mainMenu;
  727. oProcessEvent(obj, fn, parms);
  728. UGbxGFxGridScrollingList* list = menuToUse->MenuList;
  729. if (list) {
  730. menuToUse->RemoveAllItems();
  731. for (auto& c : menusToCreate) {
  732. if (menuToUse && menuToUse->IsValidLowLevel())
  733. {
  734. bool bShow = false;
  735. if (c.ConditionToShow.valid()) {
  736. sol::protected_function_result result = c.ConditionToShow();
  737. if (result.valid())
  738. bShow = result;
  739. }
  740. else {
  741. bShow = true;
  742. }
  743. if (bShow) {
  744. int newIndex = menuToUse->AddMenuItem(c.ButtonText, "", false, -1);
  745. if (menuToUse->MenuItems.Data && menuToUse->MenuItems[newIndex].MenuItem)
  746. {
  747. createdMenuItems[menuToUse->MenuItems[newIndex].MenuItem] = std::make_tuple(c.OnClick, c.BuildUI, c.s);
  748. /*if (c.BuildUI.valid()) {*/
  749. menuToUse->MenuItems[newIndex].MenuItem->OnClicked.FunctionName = onGraphicsClickedFunc->Name;
  750. //}
  751. }
  752. }
  753. }
  754. }
  755. LeaveCriticalSection(&luamgr->luaCritSec);
  756. return;
  757. }
  758. }
  759. LeaveCriticalSection(&luamgr->luaCritSec);
  760. return;
  761. }
  762. else {
  763. lastPressedButton = thisParams->PressedButton;
  764. }
  765. }
  766. // Handle button-submenu PAUSE menu
  767. else if (strcmp(funcName, "Function OakGame.GFxPauseMenu.OnOptionsClicked") == 0) {
  768. UGFxPauseMenu_OnOptionsClicked_Params* thisParams = static_cast<UGFxPauseMenu_OnOptionsClicked_Params*>(parms);
  769. if (thisParams->PressedButton == bLuaMenuBtn) {
  770. lastPressedButton = bLuaMenuBtn;
  771. inCustomOptionsMenu = true;
  772. EnterCriticalSection(&luamgr->luaCritSec);
  773. UGFxPauseMenu* menuToUse = NULL;
  774. if (oGetMapName && oGetMapName().ToString().find("MenuMap_P") == std::string::npos) {
  775. menuToUse = pauseMenu;
  776. oProcessEvent(obj, fn, parms);
  777. UGbxGFxGridScrollingList* list = menuToUse->MenuList;
  778. if (list) {
  779. menuToUse->RemoveAllItems();
  780. for (auto& c : menusToCreate) {
  781. if (menuToUse && menuToUse->IsValidLowLevel())
  782. {
  783. bool bShow = false;
  784. if (c.ConditionToShow.valid()) {
  785. sol::protected_function_result result = c.ConditionToShow();
  786. if (result.valid())
  787. bShow = result;
  788. }
  789. else {
  790. bShow = true;
  791. }
  792. if (bShow) {
  793. int newIndex = menuToUse->AddMenuItem(c.ButtonText, "", false, -1);
  794. if (menuToUse->MenuItems.Data && menuToUse->MenuItems[newIndex].MenuItem)
  795. {
  796. createdMenuItems[menuToUse->MenuItems[newIndex].MenuItem] = std::make_tuple(c.OnClick, c.BuildUI, c.s);
  797. /*if (c.BuildUI.valid()) {*/
  798. menuToUse->MenuItems[newIndex].MenuItem->OnClicked.FunctionName = onGraphicsClickedFunc->Name;
  799. //}
  800. }
  801. }
  802. }
  803. }
  804. LeaveCriticalSection(&luamgr->luaCritSec);
  805. return;
  806. }
  807. }
  808. LeaveCriticalSection(&luamgr->luaCritSec);
  809. return;
  810. }
  811. else {
  812. lastPressedButton = NULL;
  813. }
  814. }
  815. //else if (strcmp(funcName, "Function GbxUI.GbxGFxButton.K2_HandleFocusableWidgetStateChanged") == 0) {
  816. // UGbxGFxButton_K2_HandleFocusableWidgetStateChanged_Params* params = reinterpret_cast<UGbxGFxButton_K2_HandleFocusableWidgetStateChanged_Params*>(parms);
  817. // if (!parms || !reinterpret_cast<UGbxGFxButton*>(obj)->IsFocusableWidgetStateDown(params->NewState))
  818. // {
  819. // return oProcessEvent(obj, fn, parms);
  820. // }
  821. // EnterCriticalSection(&luamgr->luaCritSec);
  822. // for (auto& cell : createdMenuItems) {
  823. // UGbxGFxListCell* target = reinterpret_cast<UGbxGFxListCell*>(cell.first);
  824. // if (target) {
  825. // if (target == obj) {
  826. // lua_State* lua = std::get<2>(cell.second);
  827. // // Check if there is a "buildUI"-function bound to this
  828. // //sol::reference current(lua, sol::ref_index(std::get<1>(cell.second).registry_index()));
  829. // sol::reference current = std::get<1>(cell.second);
  830. // if (current.valid()) {
  831. // // We don't need to actually call the "buildUI"-func in here. That's handled somewhere else
  832. // UGFxMainAndPauseBaseMenu* menuToUse = NULL;
  833. // if (oGetMapName && oGetMapName().ToString().find("MenuMap_P") != std::string::npos) {
  834. // menuToUse = mainMenu;
  835. // if (menuToUse->MenuItems.Count == 5)
  836. // createdMenuItems.clear();
  837. // }
  838. // else {
  839. // menuToUse = pauseMenu;
  840. // if (menuToUse->MenuItems.Count == 6)
  841. // createdMenuItems.clear();
  842. // }
  843. // if (menuToUse) {
  844. // FGbxMenuInputEvent irrelevant;
  845. // // TODO: This appears to cause the bug that randomly opens the graphics options menu
  846. // menuToUse->OnGraphicsClicked(target, irrelevant);
  847. // }
  848. // LeaveCriticalSection(&luamgr->luaCritSec);
  849. // return;
  850. //
  851. // }
  852. // // If there's no "buildUI"-function assigned to this, this is a simple click-handler
  853. // else {
  854. // //sol::reference current(lua, sol::ref_index(std::get<0>(cell.second).registry_index()));
  855. // sol::protected_function current = std::get<0>(cell.second);
  856. // if (current.valid()) {
  857. // //sol::protected_function func(lua, sol::ref_index(std::get<0>(cell.second).registry_index()));
  858. // //sol::protected_function func = std::get<0>(cell.second);
  859. // sol::protected_function_result result = current(obj, fn, parms);
  860. // if (!result.valid())
  861. // {
  862. // sol::error err = result;
  863. // std::cout << "Error running button handler: " << err.what() << std::endl;
  864. // }
  865. // else
  866. // {
  867. // LeaveCriticalSection(&luamgr->luaCritSec);
  868. // return;
  869. // }
  870. // }
  871. // }
  872. // }
  873. // }
  874. // }
  875. // LeaveCriticalSection(&luamgr->luaCritSec);
  876. //}
  877. else if (strcmp(funcName, "Function OakGame.GFxMainAndPauseBaseMenu.OnGraphicsClicked") == 0) {
  878. UGFxMainAndPauseBaseMenu_OnGraphicsClicked_Params* thisParam = reinterpret_cast<UGFxMainAndPauseBaseMenu_OnGraphicsClicked_Params*>(parms);
  879. lastPressedButton = thisParam->PressedButton;
  880. EnterCriticalSection(&luamgr->luaCritSec);
  881. for (auto& cell : createdMenuItems) {
  882. UGbxGFxListCell* target = reinterpret_cast<UGbxGFxListCell*>(cell.first);
  883. if (target) {
  884. if (target == lastPressedButton) {
  885. sol::reference clickHandler = std::get<0>(cell.second);
  886. if (clickHandler.valid()) {
  887. // Call click-handler if there is one
  888. sol::protected_function current = clickHandler;
  889. if (current.valid()) {
  890. sol::protected_function_result result = current(obj, fn, parms);
  891. if (!result.valid())
  892. {
  893. sol::error err = result;
  894. std::cout << "Error running button handler: " << err.what() << std::endl;
  895. Logger->error(err.what());
  896. }
  897. }
  898. }
  899. //Check if there is a "buildUI"-function bound to this
  900. sol::reference buildUIFunc = std::get<1>(cell.second);
  901. if (!buildUIFunc.valid()) {
  902. LeaveCriticalSection(&luamgr->luaCritSec);
  903. return;
  904. }
  905. /*for (auto& m : menusToCreate) {
  906. if (m.BuildUI.valid() && m.BuildUI == buildUIFunc) {
  907. myMenuStack.push(m);
  908. break;
  909. }
  910. }*/
  911. }
  912. }
  913. }
  914. LeaveCriticalSection(&luamgr->luaCritSec);
  915. return oProcessEvent(obj, fn, parms);
  916. }
  917. else if (strcmp(funcName, "Function OakGame.GFxFrontendMenu.OnMenuStackChanged") == 0) {
  918. UGFxFrontendMenu_OnMenuStackChanged_Params* thisParam = reinterpret_cast<UGFxFrontendMenu_OnMenuStackChanged_Params*>(parms);
  919. UGFxMainAndPauseBaseMenu* menuToUse = NULL;
  920. if (oGetMapName && oGetMapName().ToString().find("MenuMap_P") != std::string::npos) {
  921. menuToUse = mainMenu;
  922. if (menuToUse->MenuItems.Count == 5)
  923. createdMenuItems.clear();
  924. }
  925. else {
  926. menuToUse = pauseMenu;
  927. if (menuToUse->MenuItems.Count == 6)
  928. createdMenuItems.clear();
  929. }
  930. // TODO: If other projects figure out or use the same approach, this will most likely fail again :(
  931. // TODO: Properly work out a solution with my own MenuStack
  932. if (menuToUse && menuToUse->MenuList && inCustomOptionsMenu
  933. && wcscmp(menuToUse->MenuList->AllCells[0].Cell->Label->TextFieldData->Text, L"VISUALS") == NULL
  934. && wcscmp(menuToUse->MenuList->AllCells[1].Cell->Label->TextFieldData->Text, L"SOUND") == NULL) {
  935. //if (menuToUse && menuToUse->MenuList && inCustomOptionsMenu && !myMenuStack.empty()) {
  936. oProcessEvent(obj, fn, parms);
  937. menuToUse->RemoveAllItems();
  938. for (auto& c : menusToCreate) {
  939. if (menuToUse && menuToUse->IsValidLowLevel())
  940. {
  941. bool bShow = false;
  942. if (c.ConditionToShow.valid()) {
  943. sol::protected_function_result result = c.ConditionToShow();
  944. if (result.valid())
  945. bShow = result;
  946. }
  947. else {
  948. bShow = true;
  949. }
  950. if (bShow) {
  951. int newIndex = menuToUse->AddMenuItem(c.ButtonText, "", false, -1);
  952. if (menuToUse->MenuItems.Data && menuToUse->MenuItems[newIndex].MenuItem)
  953. {
  954. createdMenuItems[mainMenu->MenuItems[newIndex].MenuItem] = std::make_tuple(c.OnClick, c.BuildUI, c.s);
  955. /*if (c.BuildUI.valid()) {*/
  956. menuToUse->MenuItems[newIndex].MenuItem->OnClicked.FunctionName = onGraphicsClickedFunc->Name;
  957. //}
  958. }
  959. }
  960. }
  961. }
  962. //LeaveCriticalSection(&luamgr->luaCritSec);
  963. //myMenuStack.pop();
  964. return;
  965. }
  966. return oProcessEvent(obj, fn, parms);
  967. }
  968. //if (strstr(funcName, "GbxGFxButton") != 0) {
  969. // std::cout << funcName << std::endl;
  970. //}
  971. //if (strstr(funcName, "MenuStack") != 0) {
  972. // std::cout << funcName << std::endl;
  973. //}
  974. //if (strstr(funcName, "OnBLuaClicked") != 0) {
  975. // std::cout << funcName << std::endl;
  976. //}
  977. //if (strcmp(funcName, "Function ScaleformUI.GFxMoviePlayer.ReceiveGFxCommand") == 0) {
  978. // std::cout << funcName << std::endl;
  979. //}
  980. if (luamgr && luamgr->lua)
  981. {
  982. EnterCriticalSection(&luamgr->luaCritSec);
  983. // TODO: Probably need to move this into a lua-function to avoid jumping into and out of lua
  984. if (luamgr->procEventHooks.find(funcName) != luamgr->procEventHooks.end())
  985. {
  986. for (auto &hook : luamgr->procEventHooks[funcName])
  987. {
  988. try {
  989. lua_State* lua = std::get<1>(hook);
  990. //sol::protected_function current(lua, sol::ref_index(std::get<0>(hook).registry_index()));
  991. sol::reference current = std::get<0>(hook);
  992. if (current.valid())
  993. {
  994. /* sol::object objData = GetObjectMembers(lua, obj);
  995. sol::object paramObj = GetFuncParams(lua, fn, parms);
  996. if (!objData.valid())*/
  997. //sol::object objData = sol::make_object(lua, obj);
  998. //if (!paramObj.valid())
  999. //sol::object paramObj = sol::make_object(lua, parms);
  1000. bool isPreHook = std::get<2>(hook);
  1001. if (isPreHook)
  1002. {
  1003. /*sol::protected_function func(lua, sol::ref_index(std::get<0>(hook).registry_index()));
  1004. if (!func.valid()) {
  1005. LeaveCriticalSection(&luamgr->procEventCritSec);
  1006. return oProcessEvent(obj, fn, parms);
  1007. }*/
  1008. sol::protected_function_result result;
  1009. //result = func(objData, fn, paramObj);
  1010. sol::protected_function func = current;
  1011. result = func(obj);
  1012. if (!result.valid())
  1013. {
  1014. sol::error err = result;
  1015. std::cout << "Error running hook: " << err.what() << std::endl;
  1016. Logger->error(err.what());
  1017. }
  1018. else
  1019. {
  1020. if (result.return_count() == 1)
  1021. {
  1022. bool returnValue = result;
  1023. if (returnValue)
  1024. {
  1025. LeaveCriticalSection(&luamgr->luaCritSec);
  1026. return;
  1027. }
  1028. }
  1029. //else if (result.return_count() == 3) {
  1030. // /*std::tuple<UObject*, UObject*, void*> returnedObjects = result;
  1031. // obj = std::get<0>(returnedObjects);
  1032. // fn = reinterpret_cast<UFunction*>(std::get<1>(returnedObjects));
  1033. // parms = std::get<2>(returnedObjects);*/
  1034. //}
  1035. }
  1036. }
  1037. else
  1038. {
  1039. oProcessEvent(obj, fn, parms);
  1040. if (fn->ReturnValueOffset == 0xFFFF)
  1041. {
  1042. LeaveCriticalSection(&luamgr->luaCritSec);
  1043. return;
  1044. }
  1045. //Handle postHook to pass and return result
  1046. sol::object paramObj = GetFuncParams(lua, fn, parms);
  1047. std::string returnValueTypeName = GetFuncReturnType(fn);
  1048. //sol::protected_function func(lua, sol::ref_index(std::get<0>(hook).registry_index()));
  1049. sol::reference funcRef = std::get<0>(hook);
  1050. if (funcRef.valid()) {
  1051. sol::protected_function func = std::get<0>(hook);
  1052. sol::protected_function_result result;
  1053. result = func(obj, fn, parms);
  1054. if (!result.valid())
  1055. {
  1056. sol::error err = result;
  1057. std::cout << "Error running hook: " << err.what() << std::endl;
  1058. Logger->error(err.what());
  1059. }
  1060. else
  1061. {
  1062. if (result.return_count() == 1)
  1063. {
  1064. sol::object returnValue = result;
  1065. if (returnValue.valid())
  1066. {
  1067. if (returnValueTypeName == "FloatProperty")
  1068. {
  1069. if (returnValue.is<float>())
  1070. {
  1071. (*(float*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<float>();
  1072. }
  1073. }
  1074. else if (returnValueTypeName == "DoubleProperty")
  1075. {
  1076. if (returnValue.is<double>())
  1077. {
  1078. (*(double*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<double>();
  1079. }
  1080. }
  1081. else if (returnValueTypeName == "BoolProperty")
  1082. {
  1083. if (returnValue.is<bool>())
  1084. {
  1085. (*(bool*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<bool>();
  1086. }
  1087. }
  1088. else if (returnValueTypeName == "ByteProperty")
  1089. {
  1090. if (returnValue.is<uint8_t>())
  1091. {
  1092. (*(uint8_t*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<uint8_t>();
  1093. }
  1094. }
  1095. else if (returnValueTypeName == "IntProperty")
  1096. {
  1097. if (returnValue.is<int>())
  1098. {
  1099. (*(int*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<int>();
  1100. }
  1101. }
  1102. else if (returnValueTypeName == "Int8Property")
  1103. {
  1104. if (returnValue.is<int8_t>())
  1105. {
  1106. (*(int8_t*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<int8_t>();
  1107. }
  1108. }
  1109. else if (returnValueTypeName == "Int16Property")
  1110. {
  1111. if (returnValue.is<int16_t>())
  1112. {
  1113. (*(int16_t*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<int16_t>();
  1114. }
  1115. }
  1116. else if (returnValueTypeName == "Int64Property")
  1117. {
  1118. if (returnValue.is<int64_t>())
  1119. {
  1120. (*(int64_t*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<int64_t>();
  1121. }
  1122. }
  1123. else if (returnValueTypeName == "UInt16Property")
  1124. {
  1125. if (returnValue.is<uint16_t>())
  1126. {
  1127. (*(uint32_t*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<uint16_t>();
  1128. }
  1129. }
  1130. else if (returnValueTypeName == "UInt32Property")
  1131. {
  1132. if (returnValue.is<uint32_t>())
  1133. {
  1134. (*(uint32_t*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<uint32_t>();
  1135. }
  1136. }
  1137. else if (returnValueTypeName == "UInt64Property")
  1138. {
  1139. if (returnValue.is<uint64_t>())
  1140. {
  1141. (*(uint64_t*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<uint64_t>();
  1142. }
  1143. }
  1144. else if (returnValueTypeName == "UInt64Property")
  1145. {
  1146. if (returnValue.is<uint64_t>())
  1147. {
  1148. (*(uint64_t*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<uint64_t>();
  1149. }
  1150. }
  1151. else if (returnValueTypeName == "StrProperty")
  1152. {
  1153. if (returnValue.is<FString>())
  1154. {
  1155. (*(FString*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<FString>();
  1156. }
  1157. }
  1158. else if (returnValueTypeName == "TextProperty")
  1159. {
  1160. if (returnValue.is<FText>())
  1161. {
  1162. (*(FText*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<FText>();
  1163. }
  1164. }
  1165. else if (returnValueTypeName == "NameProperty")
  1166. {
  1167. if (returnValue.is<FName>())
  1168. {
  1169. (*(FName*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<FName>();
  1170. }
  1171. }
  1172. else if (returnValueTypeName == "VectorProperty")
  1173. {
  1174. if (returnValue.is<FVector>())
  1175. {
  1176. (*(FVector*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<FVector>();
  1177. }
  1178. }
  1179. else if (returnValueTypeName == "RotatorProperty")
  1180. {
  1181. if (returnValue.is<FRotator>())
  1182. {
  1183. (*(FRotator*)((uintptr_t)parms + fn->ReturnValueOffset)) = returnValue.as<FRotator>();
  1184. }
  1185. }
  1186. }
  1187. LeaveCriticalSection(&luamgr->luaCritSec);
  1188. return;
  1189. }
  1190. }
  1191. }
  1192. }
  1193. }
  1194. }
  1195. catch(...){}
  1196. }
  1197. }
  1198. LeaveCriticalSection(&luamgr->luaCritSec);
  1199. }
  1200. return oProcessEvent(obj, fn, parms);
  1201. }
  1202. static bool endsWith(std::wstring str, std::wstring suffix)
  1203. {
  1204. return str.size() >= suffix.size() && 0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix);
  1205. }
  1206. /*
  1207. * Find Case Insensitive Sub String in a given substring
  1208. */
  1209. static size_t findCaseInsensitive(std::string data, std::string toSearch, size_t pos = 0)
  1210. {
  1211. // Convert complete given String to lower case
  1212. std::transform(data.begin(), data.end(), data.begin(), ::tolower);
  1213. // Convert complete given Sub String to lower case
  1214. std::transform(toSearch.begin(), toSearch.end(), toSearch.begin(), ::tolower);
  1215. // Find sub string in given string
  1216. return data.find(toSearch, pos);
  1217. }
  1218. static void ToggleNoclip()
  1219. {
  1220. static bool flyIsActive = false;
  1221. AOakPlayerController *pc = UObject::GetPlayerController();
  1222. if (pc)
  1223. {
  1224. ACharacter *character = pc->GetAssociatedCharacter();
  1225. if (character)
  1226. {
  1227. if (flyIsActive)
  1228. {
  1229. character->CharacterMovement->bCheatFlying = 0;
  1230. character->CharacterMovement->MovementMode = EMovementMode::MOVE_Walking;
  1231. character->CharacterMovement->MaxFlySpeed.Value = 600.0f;
  1232. character->SetActorEnableCollision(true);
  1233. flyIsActive = false;
  1234. PrintGameConsole("noclip off");
  1235. }
  1236. else
  1237. {
  1238. character->CharacterMovement->bCheatFlying = 1;
  1239. character->CharacterMovement->MovementMode = EMovementMode::MOVE_Flying;
  1240. character->CharacterMovement->MaxFlySpeed.Value = 2000.0f;
  1241. character->SetActorEnableCollision(false);
  1242. flyIsActive = true;
  1243. PrintGameConsole("noclip on");
  1244. }
  1245. }
  1246. }
  1247. }
  1248. static void ToggleCam()
  1249. {
  1250. static bool isThirdPerson = false;
  1251. static FName defaultCam = FName("Default");
  1252. static FName thirdPerson = FName("ThirdPerson");
  1253. AOakPlayerController *pc = UObject::GetPlayerController();
  1254. if (pc)
  1255. {
  1256. if (!isThirdPerson)
  1257. {
  1258. pc->ClientSetCameraMode(thirdPerson);
  1259. isThirdPerson = true;
  1260. PrintGameConsole("Thirdperson cam activated!");
  1261. }
  1262. else
  1263. {
  1264. pc->ClientSetCameraMode(defaultCam);
  1265. isThirdPerson = false;
  1266. PrintGameConsole("Firstperson cam activated!");
  1267. }
  1268. }
  1269. }
  1270. bool hkStaticExec(UWorld *world, const wchar_t *input, FOutputDevice &outputDevice)
  1271. {
  1272. if (wcsncmp(input, L"cls", 3) == NULL)
  1273. {
  1274. console->ClearOutput();
  1275. console->SBHead = 0;
  1276. system("cls");
  1277. return true;
  1278. }
  1279. else if (wcsncmp(input, L"noclip", 6) == NULL)
  1280. {
  1281. ToggleNoclip();
  1282. return true;
  1283. }
  1284. else if (wcsncmp(input, L"togglecam", 9) == NULL)
  1285. {
  1286. ToggleCam();
  1287. return true;
  1288. }
  1289. else if (wcsncmp(input, L"lua ", 4) == NULL)
  1290. {
  1291. if (wcslen(input) <= 5)
  1292. return false;
  1293. std::wstring data(input + 5);
  1294. std::string luaData(data.begin(), data.end());
  1295. if (luamgr)
  1296. luamgr->ExecuteScriptString(luaData.c_str(), true);
  1297. return true;
  1298. }
  1299. else if (wcsncmp(input, L"luaex", 5) == NULL)
  1300. {
  1301. if (wcslen(input) <= 6)
  1302. return false;
  1303. std::wstring data(input + 6);
  1304. std::string luaData(data.begin(), data.end());
  1305. if (findCaseInsensitive(luaData, "./lua/") == std::string::npos) {
  1306. luaData = "./lua/" + luaData;
  1307. }
  1308. if (luamgr)
  1309. return luamgr->ExecuteScriptFile(luaData.c_str(), true);
  1310. return true;
  1311. }
  1312. // The returned numbers did not make any sense?
  1313. // Memory usage was the same with this injected and without
  1314. /*else if (wcsncmp(input, L"luamem", 6) == NULL)
  1315. {
  1316. sol::protected_function func = (*luamgr->lua)["PrintGameConsole"];
  1317. if (func.valid()) {
  1318. char buf[150];
  1319. size_t memory = sol::total_memory_used(luamgr->lua->lua_state());
  1320. sprintf_s(buf, sizeof(buf), "%dkB (%dMB) memory in use by sol (lua).", memory, memory / 1024);
  1321. func(buf);
  1322. }
  1323. return true;
  1324. }*/
  1325. if (luamgr && luamgr->lua)
  1326. {
  1327. EnterCriticalSection(&luamgr->luaCritSec);
  1328. for (auto &commands : luamgr->consoleCommands)
  1329. {
  1330. size_t prefixLength = std::get<2>(commands.second);
  1331. std::wstring widenedPrefix = std::wstring(commands.first.begin(), commands.first.end());
  1332. if (!endsWith(widenedPrefix, std::wstring(L" ")))
  1333. widenedPrefix.append(L" ");
  1334. if (widenedPrefix.size() >= wcslen(input))
  1335. {
  1336. LeaveCriticalSection(&luamgr->luaCritSec);
  1337. return false;
  1338. }
  1339. if (wcsncmp(widenedPrefix.c_str(), input, widenedPrefix.size()) == NULL)
  1340. {
  1341. lua_State *lua = std::get<1>(commands.second);
  1342. //sol::reference current(lua, sol::ref_index(std::get<0>(commands.second).registry_index()));
  1343. sol::protected_function current = std::get<0>(commands.second);
  1344. if (current.valid())
  1345. {
  1346. //sol::protected_function func(lua, sol::ref_index(std::get<0>(commands.second).registry_index()));
  1347. sol::protected_function_result result = current(input + prefixLength + 1);
  1348. if (!result.valid())
  1349. {
  1350. sol::error err = result;
  1351. std::cout << "Error running console command: " << err.what() << std::endl;
  1352. Logger->error(err.what());
  1353. }
  1354. else
  1355. {
  1356. if (result.return_count() == 1)
  1357. {
  1358. bool returnValue = result;
  1359. LeaveCriticalSection(&luamgr->luaCritSec);
  1360. return returnValue;
  1361. }
  1362. }
  1363. }
  1364. }
  1365. }
  1366. LeaveCriticalSection(&luamgr->luaCritSec);
  1367. }
  1368. bool returnVal = oStaticExec(world, input, outputDevice);
  1369. // This was not handled by anything. Possibly invalid, but still trying to run it as lua-code
  1370. if (!returnVal)
  1371. {
  1372. if (luamgr)
  1373. {
  1374. EnterCriticalSection(&luamgr->luaCritSec);
  1375. std::wstring tmp(input);
  1376. std::string narrowed(tmp.begin(), tmp.end());
  1377. bool result = luamgr->ExecuteScriptString(narrowed.c_str());
  1378. LeaveCriticalSection(&luamgr->luaCritSec);
  1379. return result;
  1380. }
  1381. }
  1382. return returnVal;
  1383. }
  1384. void hkCallFunction(UObject* thisZ, FFrame& frame, void* paramResult, UFunction* func) {
  1385. const char* funcName = func->GetFullNameC();
  1386. if (strstr(funcName, "BLua") != 0) {
  1387. std::cout << "Tried to call a func containing \"BLua\"" << std::endl;
  1388. }
  1389. if (thisZ == bLuaMenuBtn) {
  1390. std::cout << "BLuaMenuBtn called: " << funcName << std::endl;
  1391. }
  1392. if (!oCallFunc) return;
  1393. return oCallFunc(thisZ, frame, paramResult, func);
  1394. }
  1395. struct FUniqueNetId {
  1396. char unknown[0x18];
  1397. };
  1398. typedef void(__fastcall* tDoSparkAuth)(void* FOakPlayerManager, const TSharedRef<FUniqueNetId>& something, void* something2);
  1399. tDoSparkAuth oDoSparkAuth = NULL;
  1400. void* oakPlayerManager = NULL;
  1401. TSharedRef<FUniqueNetId>* Something = new TSharedRef<FUniqueNetId>;
  1402. void* Something2 = NULL;
  1403. void hkDoSparkAuth(void* FOakPlayerManager, const TSharedRef<FUniqueNetId>& something, void* something2) {
  1404. oakPlayerManager = FOakPlayerManager;
  1405. //Something = something;
  1406. something2 = something2;
  1407. memcpy(Something, &something, sizeof(TSharedRef<FUniqueNetId>));
  1408. return oDoSparkAuth(FOakPlayerManager, something, something2);
  1409. }
  1410. class FOakStartupProcess
  1411. {
  1412. public:
  1413. char pad_0000[60]; //0x0000
  1414. uint8_t StepToPerform; //0x003C
  1415. bool bInitDone; //0x003D
  1416. char pad_003E[162]; //0x003E
  1417. }; //Size: 0x00E0
  1418. static_assert(sizeof(FOakStartupProcess) == 0xE0);
  1419. typedef void(__fastcall* tStartupProcessPerformStep)(FOakStartupProcess* startupProcess/*, const FName& seemsWrong*/);
  1420. tStartupProcessPerformStep oStartupProcessPerformStep = NULL;
  1421. FOakStartupProcess* oakStartupProcess = new FOakStartupProcess;
  1422. //void* Something2 = NULL;
  1423. void hkStartupProcessPerformStep(FOakStartupProcess* startupProcess/*, void* seemsWrong*/) {
  1424. if (startupProcess->StepToPerform == 0)
  1425. memcpy(oakStartupProcess, startupProcess, sizeof(FOakStartupProcess));
  1426. //oakStartupProcess = startupProcess;
  1427. return oStartupProcessPerformStep(startupProcess/*, NULL*/);
  1428. }
  1429. void* FGbxSparkModule = NULL;
  1430. typedef void* (__fastcall* tGbxSparkModuleGet)();
  1431. tGbxSparkModuleGet oGbxSparkModuleGet = NULL;
  1432. struct testStruct {
  1433. char unknown[0x340];
  1434. };
  1435. typedef bool (__fastcall* tFSparkInitProcessStartProcess)(testStruct*);
  1436. tFSparkInitProcessStartProcess oFSparkInitProcessStartProcess = NULL;
  1437. testStruct* sparkInitProcess = new testStruct;
  1438. testStruct* gameSparkInitProcess = NULL;
  1439. bool hkSparkInitProcessStartProcess(testStruct* thisZ) {
  1440. bool result = false;
  1441. gameSparkInitProcess = thisZ;
  1442. if (oFSparkInitProcessStartProcess && thisZ != sparkInitProcess) {
  1443. memcpy(sparkInitProcess, thisZ, sizeof(testStruct));
  1444. }
  1445. result = oFSparkInitProcessStartProcess(thisZ);
  1446. return result;
  1447. }
  1448. typedef void* (__fastcall* tFSparkInitProcessReadDiscovery)(testStruct*, bool baseInitWasDone);
  1449. tFSparkInitProcessReadDiscovery oFSparkInitProcessReadDiscovery = NULL;
  1450. void* hkSparkInitProcessReadDiscovery(testStruct* thisZ, bool baseInitWasDone) {
  1451. void* result = NULL;
  1452. if (oFSparkInitProcessReadDiscovery)
  1453. result = oFSparkInitProcessReadDiscovery(thisZ, baseInitWasDone);
  1454. return result;
  1455. }
  1456. static void* somethingNecessary = NULL;
  1457. static void* somethingNecessary2 = NULL;
  1458. void* hkOakGameInstanceProcessPendingMicropatches(UOakGameInstance* thisZ) {
  1459. if(!somethingNecessary)
  1460. somethingNecessary = *(void**)((uintptr_t)thisZ + 0x11A0);
  1461. if(!somethingNecessary2)
  1462. somethingNecessary2 = *(void**)((uintptr_t)thisZ + 0x11A8);
  1463. //void* somethingNecessary = (void*)&thisZ->UnknownData10[0x27B];
  1464. void* result = NULL;
  1465. result = oOakGameInstanceProcessPendingMicropatches(thisZ);
  1466. return result;
  1467. }
  1468. FOakStartupProcess* test = NULL;
  1469. void RefreshHotfixes()
  1470. {
  1471. if (oFSparkInitProcessReadDiscovery && gameSparkInitProcess){
  1472. UOakGameInstance* instance = UObject::GetGameInstance();
  1473. if (instance) {
  1474. if (somethingNecessary && somethingNecessary2) {
  1475. *(void**)((uintptr_t)instance + 0x11A0) = somethingNecessary;
  1476. *(void**)((uintptr_t)instance + 0x11A8) = somethingNecessary2;
  1477. }
  1478. oFSparkInitProcessReadDiscovery(gameSparkInitProcess, false);
  1479. oFSparkInitProcessReadDiscovery(gameSparkInitProcess, true);
  1480. //hkOakGameInstanceProcessPendingMicropatches(instance);
  1481. if (somethingNecessary && somethingNecessary2) {
  1482. *(void**)((uintptr_t)instance + 0x11A0) = somethingNecessary;
  1483. *(void**)((uintptr_t)instance + 0x11A8) = somethingNecessary2;
  1484. }
  1485. FGbxMenuInputEvent event = { 0 };
  1486. instance->OnConfirmApplyMicropatches(NULL, FName("Yes"), event);
  1487. AOakGameState* state = UObject::GetGameState();
  1488. if (state)
  1489. state->RefreshMicropatchSwitches();
  1490. }
  1491. }
  1492. /*if (oFSparkInitProcessStartProcess && sparkInitProcess)
  1493. hkSparkInitProcessStartProcess(sparkInitProcess);*/
  1494. /*if (oGbxSparkModuleGet)
  1495. FGbxSparkModule = oGbxSparkModuleGet();*/
  1496. /*if (oStartupProcessPerformStep && oakStartupProcess) {
  1497. if (test)
  1498. free(test);
  1499. test = new FOakStartupProcess;
  1500. memcpy(test, oakStartupProcess, sizeof(FOakStartupProcess));
  1501. test->bInitDone = true;
  1502. oStartupProcessPerformStep(test);
  1503. }*/
  1504. /*if (oDoSparkAuth && oakPlayerManager) {
  1505. AOakPlayerController* pc = UObject::GetPlayerController();
  1506. if(pc){
  1507. FUniqueNetIdRepl id = ((AOakPlayerState*)(pc->PlayerState))->ShiftUniqueId;
  1508. oDoSparkAuth(oakPlayerManager, *Something, Something2);
  1509. }
  1510. }*/
  1511. /*static uintptr_t doSparkAuth = PatternScan::FindSignature(NULL, FOakPlayerManager__DoSparkAuthentication.crypt_get());
  1512. while(!doSparkAuth)
  1513. doSparkAuth = PatternScan::FindSignature(NULL, FOakPlayerManager__DoSparkAuthentication.crypt_get());*/
  1514. /*UOakGameInstance* gameInstance = UObject::GetGameInstance();
  1515. while(!gameInstance)
  1516. gameInstance = UObject::GetGameInstance();*/
  1517. /*typedef char(__fastcall* tProcessPendingMicropatches)(UOakGameInstance*);
  1518. static tProcessPendingMicropatches oProcessPendingMicropatches = (tProcessPendingMicropatches)test;*/
  1519. //char result = oProcessPendingMicropatches(gameInstance);
  1520. /*typedef LRESULT(__cdecl * tRefresh)();
  1521. static tRefresh oRefresh = NULL;
  1522. if (!oRefresh)
  1523. {
  1524. HMODULE proxyDLLHandle = GetModuleHandleA("BL3ProxySettings.dll");
  1525. if (proxyDLLHandle)
  1526. {
  1527. FARPROC address = GetProcAddress(proxyDLLHandle, "RefreshHotfixes");
  1528. if (address)
  1529. {
  1530. oRefresh = (tRefresh)address;
  1531. }
  1532. }
  1533. }
  1534. if (oRefresh)
  1535. oRefresh();*/
  1536. }
  1537. HMODULE thisDLL;
  1538. static HMODULE forRefCount;
  1539. void FindPatternsForTypedefs()
  1540. {
  1541. while (!oGetTransientPackage)
  1542. {
  1543. uintptr_t patternAddress = PatternScan::FindSignature(NULL, getTransientPackagePattern.crypt_get());
  1544. if (patternAddress)
  1545. {
  1546. patternAddress -= 72 + 5;
  1547. int32_t offset = *(int32_t *)(patternAddress + 1);
  1548. if (offset)
  1549. {
  1550. oGetTransientPackage = (tGetTransientPackage)(patternAddress + offset + 5);
  1551. }
  1552. }
  1553. }
  1554. while (!oMalloc)
  1555. oMalloc = (tMalloc)PatternScan::FindSignature(NULL, mallocPattern.crypt_get());
  1556. while (!oRealloc)
  1557. oRealloc = (tRealloc)PatternScan::FindSignature(NULL, reallocPattern.crypt_get());
  1558. while (!oFNameCtor)
  1559. oFNameCtor = (tFNameCtor)PatternScan::FindSignature(NULL, fnamectorPattern.crypt_get());
  1560. while (!oFTextFromString)
  1561. oFTextFromString = (tFtextFromString)PatternScan::FindSignature(NULL, ftextfromstringPattern.crypt_get());
  1562. while (!oGetWorldFromContextObject)
  1563. oGetWorldFromContextObject = (tGetWorldFromContextObject)PatternScan::FindSignature(NULL, getWorldFromContextObjectPattern.crypt_get());
  1564. while (!oIsValidLowLevel)
  1565. oIsValidLowLevel = (tIsValidLowLevel)PatternScan::FindSignature(NULL, isValidLowLevelPattern.crypt_get());
  1566. while (!oStaticConstructObject)
  1567. oStaticConstructObject = (tStaticConstructObject)PatternScan::FindSignature(NULL, staticConstructObjectPattern.crypt_get());
  1568. while (!oStaticDuplicateObject)
  1569. oStaticDuplicateObject = (tStaticDuplicateObject)PatternScan::FindSignature(NULL, staticDuplicateObjectPattern.crypt_get());
  1570. /*while (!oNewObject)
  1571. oNewObject = (tNewObject)PatternScan::FindSignature(NULL, newObjectPattern.crypt_get());*/
  1572. while (!oGetWorld)
  1573. oGetWorld = (tGetWorld)PatternScan::FindSignature(NULL, getWorldPattern.crypt_get());
  1574. while (!oSpawnActor)
  1575. oSpawnActor = (tSpawnActor)PatternScan::FindSignature(NULL, spawnActorPattern.crypt_get());
  1576. while (!oGetMapName)
  1577. oGetMapName = (tGetMapName)PatternScan::FindSignature(NULL, getMapNamePattern.crypt_get());
  1578. while (!oFuncInvoke)
  1579. oFuncInvoke = (tFuncInvoke)PatternScan::FindSignature(NULL, functionInvokePattern.crypt_get());
  1580. while (!oCallFunc)
  1581. {
  1582. uintptr_t patternAddress = PatternScan::FindSignature(NULL, callFuncPattern.crypt_get());
  1583. if (patternAddress)
  1584. {
  1585. patternAddress += 100;
  1586. int32_t offset = *(int32_t *)(patternAddress + 1);
  1587. if (offset)
  1588. {
  1589. oCallFunc = (tCallFunc)(patternAddress + offset + 5);
  1590. }
  1591. }
  1592. }
  1593. while (!oStaticExec)
  1594. {
  1595. uintptr_t patternAddress = PatternScan::FindSignature(NULL, staticExecPattern.crypt_get());
  1596. if (patternAddress)
  1597. {
  1598. patternAddress += 102;
  1599. int32_t offset = *(int32_t *)(patternAddress + 1);
  1600. if (offset)
  1601. {
  1602. oStaticExec = (tStaticExec)(patternAddress + offset + 5);
  1603. }
  1604. }
  1605. }
  1606. while (!oGetGlobalLogSingleton)
  1607. oGetGlobalLogSingleton = (tGetGlobalLogSingleton)PatternScan::FindSignature(NULL, getGlobalLogSingletonPattern.crypt_get());
  1608. while (!oOutputDeviceShow)
  1609. oOutputDeviceShow = (tOutputDeviceShow)PatternScan::FindSignature(NULL, consoleOutputDeviceShowPattern.crypt_get());
  1610. while (!oAddOutputDevice)
  1611. oAddOutputDevice = (tAddOutputDevice)PatternScan::FindSignature(NULL, addOutputDevicePattern.crypt_get());
  1612. while (!oCreateConsoleOutputDevice)
  1613. oCreateConsoleOutputDevice = (tCreateConsoleOutputDevice)PatternScan::FindSignature(NULL, createConsoleOutputDevice.crypt_get());
  1614. while (!oConsoleOutputText)
  1615. oConsoleOutputText = (tConsoleOutputText)PatternScan::FindSignature(NULL, consoleOutputTextPattern.crypt_get());
  1616. while (!oConsoleClearOutput)
  1617. oConsoleClearOutput = (tConsoleClearOutput)PatternScan::FindSignature(NULL, consoleClearOutputPattern.crypt_get());
  1618. while (!oAddToViewport)
  1619. oAddToViewport = (tAddToViewport)PatternScan::FindSignature(NULL, addToViewportPattern.crypt_get());
  1620. while (!oStaticFindObject)
  1621. oStaticFindObject = (tStaticFindObject)PatternScan::FindSignature(NULL, staticFindObjectPattern.crypt_get());
  1622. while (!oMainAndPauseMenuAddMenuItem)
  1623. oMainAndPauseMenuAddMenuItem = (tMainAndPauseMenuAddMenuItem)PatternScan::FindSignature(NULL, mainAndPauseMenuAddMenuItemPattern.crypt_get());
  1624. while (!oMainAndPauseMenuRemoveAllItems)
  1625. oMainAndPauseMenuRemoveAllItems = (tMainAndPauseMenuRemoveAllItems)PatternScan::FindSignature(NULL, mainAndPauseMenuRemoveAllItemsPattern.crypt_get());
  1626. while (!oMainAndPauseMenuStartMenuTransition)
  1627. oMainAndPauseMenuStartMenuTransition = (tMainAndPauseMenuStartMenuTransition)PatternScan::FindSignature(NULL, mainAndPauseMenuStartMenuTransitionPattern.crypt_get());
  1628. while (!oGridScrollingListInsertListItem)
  1629. oGridScrollingListInsertListItem = (tGridScrollingListInsertListItem)PatternScan::FindSignature(NULL, scrollingListInsertListItemPattern.crypt_get());
  1630. while (!oListItemNumberInitializeItem)
  1631. oListItemNumberInitializeItem = (tListItemNumberInitializeItem)PatternScan::FindSignature(NULL, listItemNumberInitializeItemPattern.crypt_get());
  1632. while (!oOptionBaseCreateContentPanel)
  1633. oOptionBaseCreateContentPanel = (tOptionBaseCreateContentPanel)PatternScan::FindSignature(NULL, optionBaseCreateContentPanelPattern.crypt_get());
  1634. while (!oOptionBaseCreateContentPanelItem)
  1635. oOptionBaseCreateContentPanelItem = (tOptionBaseCreateContentPanelItem)PatternScan::FindSignature(NULL, optionBaseCreateContentPanelItemPattern.crypt_get());
  1636. while (!oOptionBaseSetupSpinnerItem)
  1637. oOptionBaseSetupSpinnerItem = (tOptionBaseSetupSpinnerItem)PatternScan::FindSignature(NULL, optionBaseSetupSpinnerItemPattern.crypt_get());
  1638. while (!oOptionBaseSetupSpinnerItemAsBoolean)
  1639. oOptionBaseSetupSpinnerItemAsBoolean = (tOptionBaseSetupSpinnerItemAsBoolean)PatternScan::FindSignature(NULL, optionBaseSetupSpinnerItemAsBooleanPattern.crypt_get());
  1640. while (!oOptionBaseSetupSpinnerItemWithText)
  1641. oOptionBaseSetupSpinnerItemWithText = (tOptionBaseSetupSpinnerItemWithText)PatternScan::FindSignature(NULL, optionBaseSetupSpinnerItemWithTextPattern.crypt_get());
  1642. while (!oOptionBaseSetupButtonItem)
  1643. oOptionBaseSetupButtonItem = (tOptionBaseSetupButtonItem)PatternScan::FindSignature(NULL, optionBaseSetupButtonItemPattern.crypt_get());
  1644. while (!oOptionBaseSetupTitleItem)
  1645. oOptionBaseSetupTitleItem = (tOptionBaseSetupTitleItem)PatternScan::FindSignature(NULL, optionBaseSetupTitleItemPattern.crypt_get());
  1646. while (!oOptionBaseSetupSliderItem)
  1647. oOptionBaseSetupSliderItem = (tOptionBaseSetupSliderItem)PatternScan::FindSignature(NULL, optionBaseSetupSliderItemPattern.crypt_get());
  1648. while (!oOptionBaseSetupDropdownListItem)
  1649. oOptionBaseSetupDropdownListItem = (tOptionBaseSetupDropdownListItem)PatternScan::FindSignature(NULL, optionBaseSetupDropdownListItemPattern.crypt_get());
  1650. while (!oOptionBaseSetupControlsItem)
  1651. oOptionBaseSetupControlsItem = (tOptionBaseSetupControlsItem)PatternScan::FindSignature(NULL, optionBaseSetupControlsItemPattern.crypt_get());
  1652. while (!oGFxOptionsMenuLoadBaseOptionsMenu)
  1653. oGFxOptionsMenuLoadBaseOptionsMenu = (tGFxOptionsMenuLoadBaseOptionsMenu)PatternScan::FindSignature(NULL, optionBaseMenuLoadBaseOptionsMenuPattern.crypt_get());
  1654. while (!oGFxOptionsMenuCreateOptionPanel)
  1655. oGFxOptionsMenuCreateOptionPanel = (tGFxOptionsMenuCreateOptionPanel)PatternScan::FindSignature(NULL, gfxOptionsMenuCreateOptionPanelPattern.crypt_get());
  1656. while (!oGFxOptionsMenuOnGFxMenuIsInitedAndStartedBegin)
  1657. oGFxOptionsMenuOnGFxMenuIsInitedAndStartedBegin = (tGFxOptionsMenuOnGFxMenuIsInitedAndStartedBegin)PatternScan::FindSignature(NULL, gfxOptionsMenuOnGFxMenuIsInitedAndStartedBeginPattern.crypt_get());
  1658. while (!oListItemSpinnerSetDefaultValue)
  1659. oListItemSpinnerSetDefaultValue = (tListItemSpinnerSetDefaultValue)PatternScan::FindSignature(NULL, listItemSpinnerSetDefaultValuePattern.crypt_get());
  1660. while (!oListItemNumberGetCurrentValue)
  1661. {
  1662. uintptr_t patternAddress = PatternScan::FindSignature(NULL, listItemNumberGetCurrentValuePattern.crypt_get());
  1663. if (patternAddress)
  1664. {
  1665. patternAddress += 41;
  1666. int32_t offset = *(int32_t*)(patternAddress + 1);
  1667. if (offset)
  1668. {
  1669. oListItemNumberGetCurrentValue = (tListItemNumberGetCurrentValue)(patternAddress + offset + 5);
  1670. }
  1671. }
  1672. }
  1673. while (!oListItemNumberSetDefaultValue)
  1674. oListItemNumberSetDefaultValue = (tListItemNumberSetDefaultValue)PatternScan::FindSignature(NULL, listItemNumberSetDefaultValuePattern.crypt_get());
  1675. while (!oListItemComboBoxGetSelectedIndex)
  1676. oListItemComboBoxGetSelectedIndex = (tListItemComboBoxGetSelectedIndex)PatternScan::FindSignature(NULL, listItemComboBoxGetSelectedIndexPattern.crypt_get());
  1677. while (!oListItemComboBoxSetDefaultValue)
  1678. oListItemComboBoxSetDefaultValue = (tListItemComboBoxSetDefaultValue)PatternScan::FindSignature(NULL, listItemComboBoxSetDefaultValuePattern.crypt_get());
  1679. while (!oListItemSpinnerGetSelectionIndex)
  1680. oListItemSpinnerGetSelectionIndex = (tListItemSpinnerGetSelectionIndex)PatternScan::FindSignature(NULL, listItemSpinnerGetCurrentSelectionIndexPattern.crypt_get());
  1681. while (!oGbxSparkModuleGet)
  1682. oGbxSparkModuleGet = (tGbxSparkModuleGet)PatternScan::FindSignature(NULL, FGbxSparkModuleGetPattern.crypt_get());
  1683. while (!oFSparkInitProcessStartProcess)
  1684. oFSparkInitProcessStartProcess = (tFSparkInitProcessStartProcess)PatternScan::FindSignature(NULL, FSparkInitProcessStartProcessPattern.crypt_get());
  1685. while (!oFSparkInitProcessReadDiscovery)
  1686. oFSparkInitProcessReadDiscovery = (tFSparkInitProcessReadDiscovery)PatternScan::FindSignature(NULL, FSparkInitProcessReadDiscoveryPattern.crypt_get());
  1687. while (!oOakGameInstanceProcessPendingMicropatches)
  1688. oOakGameInstanceProcessPendingMicropatches = (tOakGameInstanceProcessPendingMicropatches)PatternScan::FindSignature(NULL, oakGameInstanceProcessPendingMicropatchesPattern.crypt_get());
  1689. while (!oOakGameStateRefreshMicropatchSwitches)
  1690. oOakGameStateRefreshMicropatchSwitches = (tOakGameStateRefreshMicropatchSwitches)PatternScan::FindSignature(NULL, oakGameStateRefreshMicropatchSwitchesPattern.crypt_get());
  1691. /*while (!oDumpObjectToString)
  1692. oDumpObjectToString = (tDumpObjectToString)PatternScan::FindSignature(NULL, dumpObjectToStringPattern.crypt_get());*/
  1693. }
  1694. static FWindowsConsoleOutputDevice *myConsoleOutputDevice;
  1695. static AOakPlayerController *Test(UOakDeveloperPerks *thisz)
  1696. {
  1697. return UObject::GetPlayerController();
  1698. }
  1699. void hkAddToViewport(UUserWidget *thisZ, int32_t ZOrder)
  1700. {
  1701. std::cout << thisZ->GetFullName() << std::endl;
  1702. return oAddToViewport(thisZ, ZOrder);
  1703. }
  1704. typedef void(__fastcall *tRegisterFunction)(UClass *pClass, const char *funcName, void *pFunc);
  1705. tRegisterFunction oRegisterFunction = NULL;
  1706. //
  1707. // Blueprint VM intrinsic return value declaration.
  1708. //
  1709. #define RESULT_PARAM Z_Param__Result
  1710. #define RESULT_DECL void *const RESULT_PARAM
  1711. /** The type of a native function callable by script */
  1712. typedef void (*FNativeFuncPtr)(UObject *Context, FFrame &TheStack, RESULT_DECL);
  1713. // This class is deliberately simple (i.e. POD) to keep generated code size down.
  1714. struct FNameNativePtrPair
  1715. {
  1716. const char *NameUTF8;
  1717. FNativeFuncPtr Pointer;
  1718. };
  1719. typedef void(__fastcall *tRegisterFunctionOther)(UClass *pClass, const FNameNativePtrPair *InArray, int32_t NumFunctions);
  1720. tRegisterFunctionOther oRegisterFunctionOther = NULL;
  1721. void hkRegisterFunction(UClass *pClass, const char *funcName, void *pFunc)
  1722. {
  1723. char buffer[1024];
  1724. sprintf_s(buffer, sizeof(buffer), "Function \"%s\" is at %X", funcName, (uintptr_t)pFunc);
  1725. std::cout << buffer << std::endl;
  1726. return oRegisterFunction(pClass, funcName, pFunc);
  1727. }
  1728. void hkRegisterFunctionOther(UClass *pClass, const FNameNativePtrPair *InArray, int32_t NumFunctions)
  1729. {
  1730. //char buffer[1024];
  1731. uintptr_t startArray = (uintptr_t)InArray;
  1732. int32_t oldNumFunctions = NumFunctions;
  1733. /*for (; NumFunctions; ++InArray, --NumFunctions)
  1734. {
  1735. uintptr_t address = (uintptr_t)InArray->Pointer;
  1736. sprintf_s(buffer, sizeof(buffer), "Function %s is at 0x%" PRIx64"", InArray->NameUTF8, address);
  1737. std::cout << buffer << std::endl;
  1738. }*/
  1739. return oRegisterFunctionOther(pClass, reinterpret_cast<FNameNativePtrPair *>(startArray), oldNumFunctions);
  1740. }
  1741. /*const FLinkerInstancingContext**/
  1742. typedef UObject *(__fastcall *tStaticLoadObject)(UClass *pClass, UObject *pObj, const wchar_t *pName, const wchar_t *pFileName, uint32_t LoadFlags, UPackageMap *Sandbox, bool bAllowObjectReconciliation/*, void *InstancingContext*/);
  1743. tStaticLoadObject oStaticLoadObject = NULL;
  1744. UObject *hkStaticLoadObject(UClass *pClass, UObject *pOuter, const wchar_t *pName, const wchar_t *pFileName, uint32_t LoadFlags, UPackageMap *Sandbox, bool bAllowObjectReconciliation/*, void *InstancingContext*/)
  1745. {
  1746. //std::wcout << L"******* StaticLoadObject *******" << std::endl;
  1747. //std::wcout << L"Class: " << pClass->GetName().c_str() << std::endl;
  1748. //if (pOuter)
  1749. // std::wcout << L"Outer: " << pOuter->GetName().c_str() << std::endl;
  1750. //std::wcout << L"Name: " << pName << std::endl;
  1751. //if (pFileName)
  1752. // std::wcout << L"FileName: " << pFileName << std::endl;
  1753. //std::wcout << std::endl;
  1754. //if (wcsstr(pName, L"/Game/UI/MainMenu/MainMenu.MainMenu") != NULL)
  1755. //{
  1756. // USwfMovie *result = static_cast<USwfMovie *>(oStaticLoadObject(pClass, pOuter, pName, pFileName, LoadFlags, Sandbox, bAllowObjectReconciliation));
  1757. // if (result && result->RawData.Count > 0)
  1758. // {
  1759. // std::ofstream fout;
  1760. // fout.open("mainmenu.swf", std::ios::binary | std::ios::out);
  1761. // fout.write((char *)result->RawData.Data, result->RawData.Max);
  1762. // fout.close();
  1763. // }
  1764. // return result;
  1765. //}
  1766. //else if (wcsstr(pName, L"/Game/UI/FrontEndContainers/FrontEndContainer.FrontEndContainer") != NULL)
  1767. //{
  1768. // USwfMovie *result = static_cast<USwfMovie *>(oStaticLoadObject(pClass, pOuter, pName, pFileName, LoadFlags, Sandbox, bAllowObjectReconciliation));
  1769. // if (result && result->RawData.Count > 0)
  1770. // {
  1771. // std::ofstream fout;
  1772. // fout.open("frontendContainer.swf", std::ios::binary | std::ios::out);
  1773. // fout.write((char *)result->RawData.Data, result->RawData.Max);
  1774. // fout.close();
  1775. // }
  1776. // return result;
  1777. //}
  1778. //else if (wcsstr(pName, L"/Game/UI/_Shared/Fonts/fonts_en.fonts_en") != NULL)
  1779. //{
  1780. // USwfMovie *result = static_cast<USwfMovie *>(oStaticLoadObject(pClass, pOuter, pName, pFileName, LoadFlags, Sandbox, bAllowObjectReconciliation));
  1781. // if (result && result->RawData.Count > 0)
  1782. // {
  1783. // std::ofstream fout;
  1784. // fout.open("../_Shared/Fonts/fonts_en.swf", std::ios::binary | std::ios::out);
  1785. // fout.write((char *)result->RawData.Data, result->RawData.Max);
  1786. // fout.close();
  1787. // }
  1788. // return result;
  1789. //}
  1790. //else if (wcsstr(pName, L"/Game/UI/HintBar/HintBar.HintBar") != NULL)
  1791. //{
  1792. // USwfMovie *result = static_cast<USwfMovie *>(oStaticLoadObject(pClass, pOuter, pName, pFileName, LoadFlags, Sandbox, bAllowObjectReconciliation));
  1793. // if (result && result->RawData.Count > 0)
  1794. // {
  1795. // std::ofstream fout;
  1796. // fout.open("../HintBar/HintBar.swf", std::ios::binary | std::ios::out);
  1797. // fout.write((char *)result->RawData.Data, result->RawData.Max);
  1798. // fout.close();
  1799. // }
  1800. // return result;
  1801. //}
  1802. //else if (wcsstr(pName, L"/Game/UI/DialogWindow/DialogWindow.DialogWindow") != NULL)
  1803. //{
  1804. // USwfMovie *result = static_cast<USwfMovie *>(oStaticLoadObject(pClass, pOuter, pName, pFileName, LoadFlags, Sandbox, bAllowObjectReconciliation));
  1805. // if (result && result->RawData.Count > 0)
  1806. // {
  1807. // std::ofstream fout;
  1808. // fout.open("DialogWindow.swf", std::ios::binary | std::ios::out);
  1809. // fout.write((char *)result->RawData.Data, result->RawData.Max);
  1810. // fout.close();
  1811. // }
  1812. // return result;
  1813. //}
  1814. //else if (wcsstr(pName, L"/Game/UI/MainMenu/BPMenu_GFxMainMenu.BPMenu_GFxMainMenu_C") != NULL)
  1815. //{
  1816. // UGFxOakMainMenu *result = static_cast<UGFxOakMainMenu *>(oStaticLoadObject(pClass, pOuter, pName, pFileName, LoadFlags, Sandbox, bAllowObjectReconciliation));
  1817. // return result;
  1818. //}
  1819. //else if (wcsstr(pName, L"/Game/UI/Options/OptionsMenu.OptionsMenu") != NULL)
  1820. //{
  1821. // UObject *result = static_cast<UObject*>(oStaticLoadObject(pClass, pOuter, pName, pFileName, LoadFlags, Sandbox, bAllowObjectReconciliation));
  1822. // std::cout << pClass->GetFullName() << std::endl;
  1823. // return result;
  1824. //}
  1825. //else if (wcsstr(pName, L"/Game/UI/Options/BPMenu_OptionsMenu.BPMenu_OptionsMenu_C") != NULL)
  1826. //{
  1827. // UObject* result = static_cast<UObject*>(oStaticLoadObject(pClass, pOuter, pName, pFileName, LoadFlags, Sandbox, bAllowObjectReconciliation));
  1828. // /*std::cout << pClass->GetFullName() << std::endl;
  1829. // for (auto super = result->Class; super; super = static_cast<UClass*>(super->SuperField))
  1830. // {
  1831. // std::cout << super->GetFullName() << std::endl;
  1832. // }*/
  1833. // return result;
  1834. //}
  1835. return oStaticLoadObject(pClass, pOuter, pName, pFileName, LoadFlags, Sandbox, bAllowObjectReconciliation);
  1836. }
  1837. void CreateMenuItems(sol::this_state s, const std::string& btnText, sol::function func) {
  1838. EnterCriticalSection(&luamgr->luaCritSec);
  1839. UGFxMainAndPauseBaseMenu* menuToUse = NULL;
  1840. if (oGetMapName && oGetMapName().ToString().find("MenuMap_P") != std::string::npos) {
  1841. menuToUse = mainMenu;
  1842. if (menuToUse->MenuItems.Count == 5) {
  1843. createdMenuItems.clear();
  1844. /*createdButtonItems.clear();
  1845. createdDropdownListItems.clear();
  1846. createdSliderItems.clear();
  1847. createdSpinnerItems.clear();*/
  1848. }
  1849. }
  1850. else {
  1851. menuToUse = pauseMenu;
  1852. if (menuToUse->MenuItems.Count == 6) {
  1853. createdMenuItems.clear();
  1854. /*createdButtonItems.clear();
  1855. createdDropdownListItems.clear();
  1856. createdSliderItems.clear();
  1857. createdSpinnerItems.clear();*/
  1858. }
  1859. }
  1860. if (menuToUse && menuToUse->IsValidLowLevel())
  1861. {
  1862. int newIndex = menuToUse->AddMenuItem(btnText, "OnGraphicsClicked", false, -1);
  1863. if (menuToUse->MenuItems.Data && menuToUse->MenuItems[newIndex].MenuItem)
  1864. {
  1865. createdMenuItems[menuToUse->MenuItems[newIndex].MenuItem] = std::make_tuple(func, sol::lua_nil, s.L);
  1866. }
  1867. }
  1868. LeaveCriticalSection(&luamgr->luaCritSec);
  1869. }
  1870. void CreateMenuItemUI(sol::this_state s, const std::string& btnText, sol::function clickFunc, sol::function buildUIFunc, sol::function conditionToShow) {
  1871. EnterCriticalSection(&luamgr->luaCritSec);
  1872. MenuToCreate menuToCreate;
  1873. menuToCreate.s = s.L;
  1874. menuToCreate.ButtonText = btnText;
  1875. if(clickFunc.valid())
  1876. menuToCreate.OnClick = clickFunc;
  1877. if(buildUIFunc.valid())
  1878. menuToCreate.BuildUI = buildUIFunc;
  1879. if(conditionToShow.valid())
  1880. menuToCreate.ConditionToShow = conditionToShow;
  1881. if (!buildUIFunc.valid())
  1882. menuToCreate.BuildUI = sol::lua_nil;
  1883. menusToCreate.push_back(menuToCreate);
  1884. LeaveCriticalSection(&luamgr->luaCritSec);
  1885. return;
  1886. }
  1887. typedef void* (__fastcall* tFuncBind)(UObject* thisZ, const FFrame& frame, void* something, void* something2);
  1888. tFuncBind oFuncBind = NULL;
  1889. void* hkUFuncBind(UObject* thisZ, FFrame& frame, UFunction* something, void* something2) {
  1890. //std::cout << thisZ->GetFullName() << " wants to bind: " << something->GetFullName() << std::endl;
  1891. void* result = oFuncBind(thisZ, frame, something, something2);
  1892. return result;
  1893. }
  1894. typedef void *(__fastcall *tBuildMainMenu)(UGFxOakMainMenu *);
  1895. tBuildMainMenu oBuildMainMenu = NULL;
  1896. void MyTest(class UGbxGFxButton* PressedButton, const struct FGbxMenuInputEvent& InputInfo) {
  1897. std::cout << "Hello" << std::endl;
  1898. }
  1899. void* hkBuildMainMenu(UGFxOakMainMenu* menuToUse)
  1900. {
  1901. inCustomOptionsMenu = false;
  1902. static UFunction* onOptionsClickedFunc = UObject::FindObject<UFunction>("Function OakGame.GFxOakMainMenu.OnOptionsClicked");
  1903. void* result = oBuildMainMenu(menuToUse);
  1904. if (menuToUse && menuToUse->MenuList)
  1905. menuToUse->MenuList->PositionOfFirstItem.Y = 0.0f;
  1906. int newIndex = menuToUse->AddMenuItem("BLua", "", false, -1);
  1907. if (newIndex > 0) {
  1908. bLuaMenuBtn = menuToUse->MenuItems.Data[newIndex].MenuItem;
  1909. bLuaMenuBtn->OnClicked.FunctionName = onOptionsClickedFunc->Name;
  1910. }
  1911. while (!onGraphicsClickedFunc)
  1912. onGraphicsClickedFunc = UObject::FindObject<UFunction>("Function OakGame.GFxMainAndPauseBaseMenu.OnGraphicsClicked");
  1913. return result;
  1914. }
  1915. typedef void* (__fastcall* tBuildPauseMenu)(UGFxPauseMenu*);
  1916. tBuildPauseMenu oBuildPauseMenu = NULL;
  1917. void* hkBuildPauseMenu(UGFxPauseMenu* menuToUse)
  1918. {
  1919. inCustomOptionsMenu = false;
  1920. static UFunction* onOptionsClickedFunc = UObject::FindObject<UFunction>("Function OakGame.GFxPauseMenu.OnOptionsClicked");
  1921. void* result = oBuildPauseMenu(menuToUse);
  1922. if(menuToUse && menuToUse->MenuList)
  1923. menuToUse->MenuList->PositionOfFirstItem.Y = 0.0f;
  1924. int newIndex = menuToUse->AddMenuItem("BLua", "", false, -1);
  1925. if (newIndex > 0) {
  1926. bLuaMenuBtn = menuToUse->MenuItems.Data[newIndex].MenuItem;
  1927. bLuaMenuBtn->OnClicked.FunctionName = onOptionsClickedFunc->Name;
  1928. }
  1929. return result;
  1930. }
  1931. void* hkOptionBaseCreatePanel(UGFxOptionBase* thisZ, UGFxOptionsMenu* pMenu, TArray<UOptionDescriptionItem*>& items, UGbxGFxGridScrollingList* scrollingList, AOakPlayerController* pc, UOakProfile* profile, UOakGameInstance* instance) {
  1932. if (!thisZ->IsA(UGFxGraphicsOptions::StaticClass())) {
  1933. void* result = oOptionBaseCreateContentPanel(thisZ, pMenu, items, scrollingList, pc, profile, instance);
  1934. return result;
  1935. }
  1936. EnterCriticalSection(&luamgr->luaCritSec);
  1937. for (auto& cell : createdMenuItems) {
  1938. UGbxGFxListCell* target = reinterpret_cast<UGbxGFxListCell*>(cell.first);
  1939. if (target) {
  1940. if (target == lastPressedButton && inCustomOptionsMenu) {
  1941. lastPressedButton = NULL;
  1942. lua_State* lua = std::get<2>(cell.second);
  1943. sol::protected_function current = std::get<1>(cell.second);
  1944. if (current.valid()) {
  1945. sol::protected_function_result result = current();
  1946. if (!result.valid())
  1947. {
  1948. sol::error err = result;
  1949. std::cout << "Error creating UI: " << err.what() << std::endl;
  1950. PrintGameConsole(err.what());
  1951. Logger->error(err.what());
  1952. }
  1953. else
  1954. {
  1955. if (result.return_count() == 1)
  1956. {
  1957. sol::table elements = result;
  1958. std::vector<UIData*> returnValue = elements.as<std::vector<UIData*>>();
  1959. if (returnValue.size() > 0)
  1960. {
  1961. UOptionDescriptionItem** tempPrevious = items.Data;
  1962. int32_t prevCount = items.Count;
  1963. int32_t prevMax = items.Max;
  1964. // Save previous items, otherwise they'll be gone "forever"
  1965. items.Data = NULL;
  1966. items.Count = 0;
  1967. items.Max = 0;
  1968. ZeroMemory(&pMenu->MainPanel->SubtitleBarItems, sizeof(FSubtitleBarItems));
  1969. void* result = oOptionBaseCreateContentPanel(thisZ, pMenu, items, scrollingList, pc, profile, instance);
  1970. items.Data = tempPrevious;
  1971. items.Count = prevCount;
  1972. items.Max = prevMax;
  1973. for (auto& i : returnValue)
  1974. {
  1975. switch (i->UIElementType)
  1976. {
  1977. case EOptionItemType::Title:{
  1978. thisZ->SetupTitleItem(i->DisplayName);
  1979. break;
  1980. }
  1981. case EOptionItemType::Spinner:{
  1982. UISpinner* current = static_cast<UISpinner*>(i);
  1983. UOptionDescriptionItem* item = static_cast<UOptionDescriptionItem*>(StaticConstructObject(UOptionDescriptionItem::StaticClass(), GetTransientPackage(), FName("")));
  1984. if(item){
  1985. item->OptionItemType = i->UIElementType;
  1986. item->OptionDescriptionText = current->DescriptionText;
  1987. item->OptionDescriptionTitle = current->DescriptionTitle;
  1988. item->OptionItemName = current->DisplayName;
  1989. std::vector<std::string> options = current->Options.as<std::vector<std::string>>();
  1990. for (auto& o : options)
  1991. item->SpinnerOptions.Add(FText(o));
  1992. UGbxGFxListItemSpinner* spinner = thisZ->SetupSpinnerItem(item, current->Index, "OnAnisotropicFilteringChanged");
  1993. if (spinner) {
  1994. if (current->Index < 0 || current->Index > options.size() - 1)
  1995. spinner->SetDefaultValue(0);
  1996. else
  1997. spinner->SetDefaultValue(current->Index);
  1998. uiData[spinner] = i;
  1999. }
  2000. }
  2001. break;
  2002. }
  2003. case EOptionItemType::BooleanSpinner: {
  2004. UIBoolSpinner* current = static_cast<UIBoolSpinner*>(i);
  2005. UOptionDescriptionItem* item = static_cast<UOptionDescriptionItem*>(StaticConstructObject(UOptionDescriptionItem::StaticClass(), GetTransientPackage(), FName("")));
  2006. if (item) {
  2007. item->OptionItemType = i->UIElementType;
  2008. item->OptionDescriptionText = current->DescriptionText;
  2009. item->OptionDescriptionTitle = current->DescriptionTitle;
  2010. item->OptionItemName = current->DisplayName;
  2011. item->BooleanOnText = current->OnText;
  2012. item->BooleanOffText = current->OffText;
  2013. UGbxGFxListItemSpinner* spinner = thisZ->SetupSpinnerItemAsBoolean(item, current->Value, "OnAnisotropicFilteringChanged");
  2014. if (spinner) {
  2015. spinner->SetDefaultValue((int)current->Value);
  2016. //spinner->SetDefaultValue(current->Index);
  2017. //createdSpinnerItems.push_back(spinner);
  2018. uiData[spinner] = i;
  2019. }
  2020. }
  2021. break;
  2022. }
  2023. case EOptionItemType::Button:{
  2024. UIButton* current = static_cast<UIButton*>(i);
  2025. UOptionDescriptionItem* item = static_cast<UOptionDescriptionItem*>(StaticConstructObject(UOptionDescriptionItem::StaticClass(), GetTransientPackage(), FName("")));
  2026. if (item) {
  2027. item->OptionItemType = i->UIElementType;
  2028. item->OptionDescriptionText = current->DescriptionText;
  2029. item->OptionDescriptionTitle = current->DescriptionTitle;
  2030. item->OptionItemName = current->DisplayName;
  2031. UGbxGFxListCellWithData* btn = thisZ->SetupButtonItem(item, "OnBenchmarkRunClicked");
  2032. //createdButtonItems.push_back(btn);
  2033. uiData[btn] = i;
  2034. }
  2035. break;
  2036. }
  2037. case EOptionItemType::Slider: {
  2038. UISlider* current = static_cast<UISlider*>(i);
  2039. UOptionDescriptionItem* item = static_cast<UOptionDescriptionItem*>(StaticConstructObject(UOptionDescriptionItem::StaticClass(), GetTransientPackage(), FName("")));
  2040. if (item) {
  2041. item->OptionItemType = i->UIElementType;
  2042. item->OptionDescriptionText = current->DescriptionText;
  2043. item->OptionDescriptionTitle = current->DescriptionTitle;
  2044. item->OptionItemName = current->DisplayName;
  2045. item->SliderMax = current->Max;
  2046. item->SliderMin = current->Min;
  2047. item->SliderStep = current->Step;
  2048. item->SliderIsInteger = current->bIsInt;
  2049. UGbxGFxListItemNumber* number = thisZ->SetupSliderItem(item, current->Value, "");
  2050. if (current->Value < current->Min || current->Value > current->Max)
  2051. number->SetDefaultValue(current->Min);
  2052. else
  2053. number->SetDefaultValue(current->Value);
  2054. // TODO: Add function to set default value
  2055. //createdSliderItems.push_back(number);
  2056. uiData[number] = i;
  2057. }
  2058. break;
  2059. }
  2060. case EOptionItemType::DropDownList: {
  2061. UIDropdown* current = static_cast<UIDropdown*>(i);
  2062. UOptionDescriptionItem* item = static_cast<UOptionDescriptionItem*>(StaticConstructObject(UOptionDescriptionItem::StaticClass(), GetTransientPackage(), FName("")));
  2063. if (item) {
  2064. item->OptionItemType = i->UIElementType;
  2065. item->OptionDescriptionText = current->DescriptionText;
  2066. item->OptionDescriptionTitle = current->DescriptionTitle;
  2067. item->OptionItemName = current->DisplayName;
  2068. std::vector<std::string> options = current->Options.as<std::vector<std::string>>();
  2069. for (auto& o : options)
  2070. item->DropDownOptions.Add(FText(o));
  2071. UGbxGFxListItemComboBox* obj = thisZ->SetupDropDownlistItem(item, item->DropDownOptions, current->Index, "OnResolutionDropDownSelectionChanged");
  2072. if(current->Index < 0 || current->Index > options.size() - 1)
  2073. obj->SetDefaultValue(0);
  2074. else
  2075. obj->SetDefaultValue(current->Index);
  2076. //createdDropdownListItems.push_back(obj);
  2077. uiData[obj] = i;
  2078. }
  2079. break;
  2080. }
  2081. // TODO: Figure out how to get this to work instead of crashing
  2082. case EOptionItemType::Keybinding_Button: {
  2083. UIControl* current = static_cast<UIControl*>(i);
  2084. UOptionDescriptionItem* item = static_cast<UOptionDescriptionItem*>(StaticConstructObject(UOptionDescriptionItem::StaticClass(), GetTransientPackage(), FName("")));
  2085. if (item) {
  2086. item->OptionItemType = i->UIElementType;
  2087. item->OptionDescriptionText = current->DescriptionText;
  2088. item->OptionDescriptionTitle = current->DescriptionTitle;
  2089. item->OptionItemName = current->DisplayName;
  2090. UGFxObject* obj = thisZ->SetupControlsItem(
  2091. item,
  2092. FText(R"(<img src="img://Game/UI/_Shared/GamepadButtonIcons/Keyboard/PC_W.PC_W"/>)"),
  2093. FText(R"(<img src="img://Game/UI/_Shared/GamepadButtonIcons/Keyboard/PC_W.PC_W"/>)"),
  2094. EBindingType::Common,
  2095. NULL);
  2096. //createdDropdownListItems.push_back(obj);
  2097. uiData[obj] = i;
  2098. }
  2099. break;
  2100. }
  2101. }
  2102. }
  2103. LeaveCriticalSection(&luamgr->luaCritSec);
  2104. return result;
  2105. }
  2106. }
  2107. }
  2108. }
  2109. }
  2110. }
  2111. }
  2112. LeaveCriticalSection(&luamgr->luaCritSec);
  2113. void* result = oOptionBaseCreateContentPanel(thisZ, pMenu, items, scrollingList, pc, profile, instance);
  2114. return result;
  2115. }
  2116. void hkOptionBaseCreatePanelItem(UGFxOptionBase* thisZ, UOptionDescriptionItem* item) {
  2117. return oOptionBaseCreateContentPanelItem(thisZ, item);
  2118. }
  2119. typedef void* (__fastcall* tBuildOptionsMenu)(UGFxOptionsMenu*);
  2120. tBuildOptionsMenu oBuildOptionsMenu = NULL;
  2121. void* hkBuildOptionsMenu(UGFxOptionsMenu* menuToUse) {
  2122. void* result = oBuildOptionsMenu(menuToUse);
  2123. return result;
  2124. }
  2125. UGFxObject* hkSetupControlsItem(UGFxOptionBase* thisZ, UOptionDescriptionItem* item, const FText& unknownText, const FText& unknownText2, EBindingType type, void* someThing) {
  2126. void* mysomething = oRealloc(0, 144, 0);
  2127. UGFxObject* result = oOptionBaseSetupControlsItem(thisZ, item, unknownText, unknownText2, type, someThing);
  2128. return result;
  2129. }
  2130. void ApplyBaseHooks()
  2131. {
  2132. uintptr_t staticExec = NULL;
  2133. while (!staticExec)
  2134. {
  2135. uintptr_t patternAddress = PatternScan::FindSignature(NULL, staticExecPattern.crypt_get());
  2136. if (patternAddress)
  2137. {
  2138. patternAddress += 110;
  2139. int32_t offset = *(int32_t *)(patternAddress + 1);
  2140. if (offset)
  2141. {
  2142. staticExec = (patternAddress + offset + 5);
  2143. }
  2144. }
  2145. }
  2146. /*uintptr_t addToViewport = PatternScan::FindSignature(NULL, addToViewportPattern.crypt_get());
  2147. while (addToViewport == NULL) {
  2148. addToViewport = PatternScan::FindSignature(NULL, addToViewportPattern.crypt_get());
  2149. Sleep(20);
  2150. }*/
  2151. /*uintptr_t registerFunc = PatternScan::FindSignature(NULL, registerFunctionAPattern.crypt_get());
  2152. while (registerFunc == NULL) {
  2153. registerFunc = PatternScan::FindSignature(NULL, registerFunctionAPattern.crypt_get());
  2154. Sleep(20);
  2155. }
  2156. oRegisterFunction = (tRegisterFunction)registerFunc;*/
  2157. /*
  2158. uintptr_t registerFuncOther = PatternScan::FindSignature(NULL, registerFunctionOtherPattern.crypt_get());
  2159. while (registerFuncOther == NULL) {
  2160. registerFuncOther = PatternScan::FindSignature(NULL, registerFunctionOtherPattern.crypt_get());
  2161. Sleep(20);
  2162. }*/
  2163. /*uintptr_t callFunc = NULL;
  2164. while (!callFunc)
  2165. {
  2166. uintptr_t patternAddress = PatternScan::FindSignature(NULL, callFuncPattern.crypt_get());
  2167. if (patternAddress)
  2168. {
  2169. patternAddress += 100;
  2170. int32_t offset = *(int32_t*)(patternAddress + 1);
  2171. if (offset)
  2172. {
  2173. oCallFunc = (tCallFunc)(patternAddress + offset + 5);
  2174. callFunc = (patternAddress + offset + 5);
  2175. }
  2176. }
  2177. }*/
  2178. uintptr_t staticLoadObject = PatternScan::FindSignature(NULL, staticLoadObjectPattern.crypt_get());
  2179. while(!staticLoadObject){
  2180. staticLoadObject = PatternScan::FindSignature(NULL, staticLoadObjectPattern.crypt_get());
  2181. Sleep(20);
  2182. }
  2183. /*uintptr_t funcBind = PatternScan::FindSignature(NULL, ufunctionBindPattern.crypt_get());
  2184. while (!funcBind) {
  2185. funcBind = PatternScan::FindSignature(NULL, ufunctionBindPattern.crypt_get());
  2186. Sleep(20);
  2187. }*/
  2188. /*uintptr_t staticFindObject = PatternScan::FindSignature(NULL, staticFindObjectPattern.crypt_get());
  2189. while (!staticFindObject) {
  2190. staticFindObject = PatternScan::FindSignature(NULL, staticFindObjectPattern.crypt_get());
  2191. Sleep(20);
  2192. }*/
  2193. uintptr_t staticConstructObject = PatternScan::FindSignature(NULL, staticConstructObjectPattern.crypt_get());
  2194. while (!staticConstructObject)
  2195. {
  2196. staticConstructObject = PatternScan::FindSignature(NULL, staticConstructObjectPattern.crypt_get());
  2197. Sleep(20);
  2198. }
  2199. uintptr_t optionBaseCreateContentPanel = PatternScan::FindSignature(NULL, optionBaseCreateContentPanelPattern.crypt_get());
  2200. while (!optionBaseCreateContentPanel)
  2201. {
  2202. optionBaseCreateContentPanel = PatternScan::FindSignature(NULL, optionBaseCreateContentPanelPattern.crypt_get());
  2203. Sleep(20);
  2204. }
  2205. uintptr_t optionBaseCreateContentPanelItem = PatternScan::FindSignature(NULL, optionBaseCreateContentPanelItemPattern.crypt_get());
  2206. while (!optionBaseCreateContentPanelItem)
  2207. {
  2208. optionBaseCreateContentPanelItem = PatternScan::FindSignature(NULL, optionBaseCreateContentPanelItemPattern.crypt_get());
  2209. Sleep(20);
  2210. }
  2211. uintptr_t buildMainMenu = PatternScan::FindSignature(NULL, buildMainMenuPattern.crypt_get());
  2212. while (!buildMainMenu) {
  2213. buildMainMenu = PatternScan::FindSignature(NULL, buildMainMenuPattern.crypt_get());
  2214. Sleep(20);
  2215. }
  2216. uintptr_t buildPauseMenu = PatternScan::FindSignature(NULL, buildPauseMenuPattern.crypt_get());
  2217. while (!buildPauseMenu) {
  2218. buildPauseMenu = PatternScan::FindSignature(NULL, buildPauseMenuPattern.crypt_get());
  2219. Sleep(20);
  2220. }
  2221. uintptr_t buildOptionsMenu = PatternScan::FindSignature(NULL, buildOptionsMenuPattern.crypt_get());
  2222. while (!buildOptionsMenu) {
  2223. buildOptionsMenu = PatternScan::FindSignature(NULL, buildOptionsMenuPattern.crypt_get());
  2224. Sleep(20);
  2225. }
  2226. uintptr_t doSparkAuth = PatternScan::FindSignature(NULL, FOakPlayerManager__DoSparkAuthenticationPattern.crypt_get());
  2227. while (!doSparkAuth) {
  2228. doSparkAuth = PatternScan::FindSignature(NULL, FOakPlayerManager__DoSparkAuthenticationPattern.crypt_get());
  2229. Sleep(20);
  2230. }
  2231. uintptr_t startupProcessPerformstep = PatternScan::FindSignature(NULL, FOakStartupProcess__PerformStepPattern.crypt_get());
  2232. while (!startupProcessPerformstep) {
  2233. startupProcessPerformstep = PatternScan::FindSignature(NULL, FOakStartupProcess__PerformStepPattern.crypt_get());
  2234. Sleep(20);
  2235. }
  2236. uintptr_t gbxSparkModuleGet = PatternScan::FindSignature(NULL, FGbxSparkModuleGetPattern.crypt_get());
  2237. while (!gbxSparkModuleGet) {
  2238. gbxSparkModuleGet = PatternScan::FindSignature(NULL, FGbxSparkModuleGetPattern.crypt_get());
  2239. Sleep(20);
  2240. }
  2241. uintptr_t sparkInitProcessStartProcess = PatternScan::FindSignature(NULL, FSparkInitProcessStartProcessPattern.crypt_get());
  2242. while (!sparkInitProcessStartProcess) {
  2243. sparkInitProcessStartProcess = PatternScan::FindSignature(NULL, FSparkInitProcessStartProcessPattern.crypt_get());
  2244. Sleep(20);
  2245. }
  2246. uintptr_t sparkInitProcessReadDiscovery = PatternScan::FindSignature(NULL, FSparkInitProcessReadDiscoveryPattern.crypt_get());
  2247. while (!sparkInitProcessReadDiscovery) {
  2248. sparkInitProcessReadDiscovery = PatternScan::FindSignature(NULL, FSparkInitProcessReadDiscoveryPattern.crypt_get());
  2249. Sleep(20);
  2250. }
  2251. uintptr_t oakGameInstanceProcessPendingMicropatches = PatternScan::FindSignature(NULL, oakGameInstanceProcessPendingMicropatchesPattern.crypt_get());
  2252. while (!oakGameInstanceProcessPendingMicropatches) {
  2253. oakGameInstanceProcessPendingMicropatches = PatternScan::FindSignature(NULL, oakGameInstanceProcessPendingMicropatchesPattern.crypt_get());
  2254. Sleep(20);
  2255. }
  2256. uintptr_t setupControlsItem = PatternScan::FindSignature(NULL, optionBaseSetupControlsItemPattern.crypt_get());
  2257. while (!setupControlsItem) {
  2258. setupControlsItem = PatternScan::FindSignature(NULL, optionBaseSetupControlsItemPattern.crypt_get());
  2259. Sleep(20);
  2260. }
  2261. /*std::string test = xorstr("4D 89 ?? ?? 4D 89 ?? ?? 4C 8B ?? 44 89 ?? ?? ?? 4C 39 ?? ?? 0F 84 ?? ?? ?? ?? 48 8B ?? ?? 48 85 ?? 0F 84 ?? ?? ?? ?? 33 C0 F0 44 ?? ?? ?? ?? 85 C0 7E ?? 49 8B ?? ?? 4C 89 ?? ?? ?? 48 89 ?? ?? ?? 48 85 ?? 74 ?? 33 C0 F0 44 ?? ?? ?? ?? 74 ?? 8D 48 ?? F0 0F ?? ?? ?? 74 ?? 33 C0 F0 44 ?? ?? ?? ?? 75 ?? 4C 8B ?? ?? ?? 48 8D ?? ?? ?? 4C 89 ?? ?? ?? 41 BE ?? ?? ?? ?? EB ?? 48 8B ?? ?? ?? 48 85 ?? 74 ?? 49 8B ?? ?? 48 89 ?? ?? ?? 4C 8B ?? ?? ?? 48 8D ?? ?? ?? 41 BE ?? ?? ?? ?? EB ?? 0F 57 ?? 48 8D ?? ?? ?? F3 0F ?? ?? ?? ?? 41 BE ?? ?? ?? ?? 4D 8B ?? 48 8B ?? ?? BF ?? ?? ?? ?? 4C 89 ?? ?? 4C 89 ?? 48 89 ?? ?? ?? ?? ?? ?? 41 F6 C6 ?? 74 ?? 48 8B ?? ?? 41 83 E6 ?? 48 85 ?? 74 ?? 8B C7 F0 0F ?? ?? ?? 83 F8 ?? 75 ?? 48 8B ?? ?? 48 8B ?? 48 8B ?? FF 10 8B C7 F0 0F ?? ?? ?? 83 F8 ?? 75 ?? 48 8B ?? ?? 8D 57 ?? 48 8B ?? FF 50 ?? 41 F6 C6 ?? 4C 8B ?? ?? ?? ?? ?? ?? 74 ?? 48 8B ?? ?? ?? 48 85 ?? 74 ?? 8B C7 F0 0F ?? ?? ?? 83 F8 ?? 75 ?? 48 8B ?? ?? ?? 48 8B ?? 48 8B ?? FF 10 8B C7 F0 0F ?? ?? ?? 83 F8 ?? 75 ?? 48 8B ?? ?? ?? BA ?? ?? ?? ?? 48 8B ?? FF 50 ?? 4D 85 ?? 0F 84 ?? ?? ?? ?? 48 8D ?? ?? 4C 89 ?? ?? B9 ?? ?? ?? ?? 44 89 ?? ?? E8 ?? ?? ?? ?? 48 85 ?? 74 ?? 48 8D ?? ?? ?? ?? ?? 4C 89 ?? ?? 48 89 ?? 48 8D ?? ?? ?? ?? ?? 4C 89 ?? ?? ?? 33 D2 48 89 ?? ?? 48 8D ?? ?? ?? 48 C7 44 24 60 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B ?? ?? ?? 4C 8D ?? ?? ?? ?? ?? 41 B9 ?? ?? ?? ?? B8 ?? ?? ?? ?? 41 8B ?? 66 89 ?? ?? ?? E8 ?? ?? ?? ?? 4C 8D ?? ?? 48 8D ?? ?? ?? 48 8D ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8D ?? ?? FF 15 ?? ?? ?? ?? 48 8B ?? ?? B9 ?? ?? ?? ?? 48 89 ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 ?? 74 ?? 48 8B ?? E8 ?? ?? ?? ?? 48 8B ?? EB ?? 49 8B ?? B9 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 ?? 74 ?? 48 8D ?? ?? ?? ?? ?? C7 40 08 ?? ?? ?? ?? 48 89 ?? C7 40 0C ?? ?? ?? ?? 48 89 ?? ?? EB ?? 49 8B ?? 4C 8B ?? 48 89 ?? ?? ?? 48 8B ?? 48 89 ?? ?? ?? 48 8D ?? ?? ?? E8 ?? ?? ?? ?? 48 8B ?? ?? ?? C6 40 10 ?? 48 8B ?? ?? 48 8B ?? 48 85 ?? 74 ?? F0 FF ?? ?? 48 89 ?? ?? ?? 48 8D ?? ?? ?? ?? ?? 48 89 ?? ?? ?? ?? ?? 48 8D ?? ?? ?? 4C 89 ?? ?? ?? E8 ?? ?? ?? ?? 48 8B ?? ?? ?? 48 85 ?? 74 ?? 8B C7 F0 0F ?? ?? ?? 83 F8 ?? 75 ?? 48 8B ?? ?? ?? 48 8B ?? 48 8B ?? FF 10 8B C7 F0 0F ?? ?? ?? 83 F8 ?? 75 ?? 48 8B ?? ?? ?? BA ?? ?? ?? ?? 48 8B ?? FF 50 ?? 48 8D ?? ?? ?? ?? ?? 4C 89 ?? ?? ?? ?? ?? B9 ?? ?? ?? ?? 44 89 ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 ?? 74 ?? 48 8D ?? ?? ?? ?? ?? 48 89 ?? 48 8D ?? ?? ?? ?? ?? 48 89 ?? ?? 48 8D ?? ?? ?? ?? ?? 48 89 ?? ?? ?? ?? ?? 48 8B ?? ?? ?? 48 89 ?? ?? 48 8B ?? ?? ?? 48 89 ?? ?? 48 85 ?? 74 ?? F0 FF ?? ?? 48 8D ?? ?? ?? ?? ?? 48 8D ?? ?? E8 ?? ?? ?? ?? 48 8D ?? ?? 4C 89 ?? ?? B9 ?? ?? ?? ?? 44 89 ?? ?? E8 ?? ?? ?? ?? 48 8B ?? 48 85 ?? 74 ?? 48 8D ?? ?? ?? ?? ?? 48 89 ?? 48 8B ?? ?? 48 89 ?? ?? 48 8B ?? ?? 48 89 ?? ?? 48 85 ?? 74 ?? 48 8B ?? ?? F0 FF ?? ?? 48 8D ?? ?? 48 8D ?? ?? E8 ?? ?? ?? ?? 48 8D ?? ?? ?? ?? ?? 48 8B ?? ?? 48 89 ?? ?? 44 39 ?? ?? ?? ?? ?? 74 ?? 48 85 ?? 4C 8D ?? ?? 4D 0F ?? ?? 4C 0B ?? 74 ?? 49 8B ?? 33 D2 49 8B ?? FF 50 ?? 48 8B ?? ?? 48 85 ?? 74 ?? E8 ?? ?? ?? ?? 48 8B ?? ?? 48 85 ?? 74 ?? 8B C7 F0 0F ?? ?? ?? 83 F8 ?? 75 ?? 48 8B ?? 48 8B ?? FF 10 8B C7 F0 0F ?? ?? ?? 83 F8 ?? 75 ?? 48 8B ?? BA ?? ?? ?? ?? 48 8B ?? FF 50 ?? 48 8B ?? ?? ?? ?? ?? 44 39 ?? ?? ?? ?? ?? 74 ?? 48 85 ?? 4C 8D ?? ?? ?? ?? ?? 4D 0F ?? ?? 4C 0B ?? 74 ?? 49 8B ?? 33 D2 49 8B ?? FF 50 ?? 48 8B ?? ?? ?? ?? ?? 48 85 ?? 74 ?? E8 ?? ?? ?? ?? 48 8B ?? ?? ?? 48 85 ?? 74 ?? 8B C7 F0 0F ?? ?? ?? 83 F8 ?? 75 ?? 48 8B ?? 48 8B ?? FF 10 8B C7 F0 0F ?? ?? ?? 83 F8 ?? 75 ?? 48 8B ?? BA ?? ?? ?? ?? 48 8B ?? FF 50 ?? 48 8D ?? ?? 49 8B ?? E8 ?? ?? ?? ?? 48 8D ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8D ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C 8B ?? ?? ?? ?? ?? ?? 4C 8B ?? ?? ?? ?? ?? ?? 4C 8B ?? ?? ?? ?? ?? ?? 48 8B ?? ?? ?? ?? ?? ?? 48 85 ?? 74 ?? 8B C7 F0 0F ?? ?? ?? 83 F8 ?? 75 ?? 48 8B ?? 48 8B ?? FF 10 F0 0F ?? ?? ?? 83 FF ?? 75 ?? 48 8B ?? 8B D7 48 8B ?? FF 50 ?? 48 8B ?? ?? ?? ?? ?? 48 33 ?? E8 ?? ?? ?? ?? 48 81 C4 ?? ?? ?? ?? 5F 5E 5D C3 CC CC CC CC CC CC CC CC CC 4C 8B");
  2262. uintptr_t removeAllListItems = PatternScan::FindSignature(NULL, test.crypt_get());
  2263. while (!removeAllListItems) {
  2264. removeAllListItems = PatternScan::FindSignature(NULL, test.crypt_get());
  2265. Sleep(20);
  2266. }*/
  2267. SuspendResume::Suspend();
  2268. while (MH_CreateHookEx((LPVOID)staticExec, &hkStaticExec, &oStaticExec) != MH_OK)
  2269. Sleep(200);
  2270. /*while (MH_CreateHookEx((LPVOID)addToViewport, &hkAddToViewport, &oAddToViewport) != MH_OK)
  2271. Sleep(200);
  2272. while (MH_CreateHookEx((LPVOID)registerFunc, &hkRegisterFunction, &oRegisterFunction) != MH_OK)
  2273. Sleep(200);
  2274. while (MH_CreateHookEx((LPVOID)registerFuncOther, &hkRegisterFunctionOther, &oRegisterFunctionOther) != MH_OK)
  2275. Sleep(200);*/
  2276. while (MH_CreateHookEx((LPVOID)staticLoadObject, &hkStaticLoadObject, &oStaticLoadObject) != MH_OK)
  2277. Sleep(200);
  2278. /*while (MH_CreateHookEx((LPVOID)staticFindObject, &StaticFindObject, &oStaticFindObject) != MH_OK)
  2279. Sleep(200);*/
  2280. /*while (MH_CreateHookEx((LPVOID)callFunc, &hkCallFunction, &oCallFunc) != MH_OK)
  2281. Sleep(200); */
  2282. /*while (MH_CreateHookEx((LPVOID)funcBind, &hkUFuncBind, &oFuncBind) != MH_OK)
  2283. Sleep(200);*/
  2284. while (MH_CreateHookEx((LPVOID)staticConstructObject, &StaticConstructObject, &oStaticConstructObject) != MH_OK)
  2285. Sleep(200);
  2286. while (MH_CreateHookEx((LPVOID)optionBaseCreateContentPanel, &hkOptionBaseCreatePanel, &oOptionBaseCreateContentPanel) != MH_OK)
  2287. Sleep(200);
  2288. while (MH_CreateHookEx((LPVOID)optionBaseCreateContentPanelItem, &hkOptionBaseCreatePanelItem, &oOptionBaseCreateContentPanelItem) != MH_OK)
  2289. Sleep(200);
  2290. while (MH_CreateHookEx((LPVOID)buildMainMenu, &hkBuildMainMenu, &oBuildMainMenu) != MH_OK)
  2291. Sleep(200);
  2292. while (MH_CreateHookEx((LPVOID)buildPauseMenu, &hkBuildPauseMenu, &oBuildPauseMenu) != MH_OK)
  2293. Sleep(200);
  2294. while (MH_CreateHookEx((LPVOID)buildOptionsMenu, &hkBuildOptionsMenu, &oBuildOptionsMenu) != MH_OK)
  2295. Sleep(200);
  2296. while (MH_CreateHookEx((LPVOID)doSparkAuth, &hkDoSparkAuth, &oDoSparkAuth) != MH_OK)
  2297. Sleep(200);
  2298. while (MH_CreateHookEx((LPVOID)startupProcessPerformstep, &hkStartupProcessPerformStep, &oStartupProcessPerformStep) != MH_OK)
  2299. Sleep(200);
  2300. while (MH_CreateHookEx((LPVOID)sparkInitProcessStartProcess, &hkSparkInitProcessStartProcess, &oFSparkInitProcessStartProcess) != MH_OK)
  2301. Sleep(200);
  2302. while (MH_CreateHookEx((LPVOID)sparkInitProcessReadDiscovery, &hkSparkInitProcessReadDiscovery, &oFSparkInitProcessReadDiscovery) != MH_OK)
  2303. Sleep(200);
  2304. while (MH_CreateHookEx((LPVOID)oakGameInstanceProcessPendingMicropatches, &hkOakGameInstanceProcessPendingMicropatches, &oOakGameInstanceProcessPendingMicropatches) != MH_OK)
  2305. Sleep(200);
  2306. while (MH_CreateHookEx((LPVOID)setupControlsItem, &hkSetupControlsItem, &oOptionBaseSetupControlsItem) != MH_OK)
  2307. Sleep(200);
  2308. /*while (MH_CreateHookEx((LPVOID)removeAllListItems, &hkRemoveAllListItems, &oRemoveAllListItems) != MH_OK)
  2309. Sleep(200);*/
  2310. MH_EnableHook(MH_ALL_HOOKS);
  2311. SuspendResume::Resume();
  2312. }
  2313. void HotkeyThread()
  2314. {
  2315. std::string hk1;
  2316. std::string hk2;
  2317. std::string hk3;
  2318. while (true)
  2319. {
  2320. if (wantsExit)
  2321. ExitThread(0);
  2322. //SetConsoleKey("F6");
  2323. if (!luamgr)
  2324. {
  2325. Sleep(50);
  2326. continue;
  2327. }
  2328. luamgr->ValidateHotkeys();
  2329. EnterCriticalSection(&luamgr->luaCritSec);
  2330. std::unordered_map<int, sol::protected_function> funcToCall;
  2331. for (auto &hk : luamgr->registeredHotkeys)
  2332. {
  2333. hk1 = std::get<2>(hk);
  2334. hk2 = std::get<3>(hk);
  2335. hk3 = std::get<4>(hk);
  2336. if (hk1.size() > 0)
  2337. {
  2338. if (hk2.size() > 0)
  2339. {
  2340. if (hk3.size() > 0)
  2341. {
  2342. if (LuaUtility::IsKeyPressed(hk1, hk2, hk3))
  2343. {
  2344. lua_State *lua = std::get<1>(hk);
  2345. //sol::protected_function func(lua, sol::ref_index(std::get<0>(hk).registry_index()));
  2346. sol::protected_function func = std::get<0>(hk);
  2347. if (func.valid())
  2348. {
  2349. funcToCall.insert_or_assign(std::get<0>(hk).registry_index(), func);
  2350. }
  2351. }
  2352. }
  2353. else
  2354. {
  2355. if (LuaUtility::IsKeyPressed(hk1, hk2))
  2356. {
  2357. lua_State *lua = std::get<1>(hk);
  2358. //sol::protected_function func(lua, sol::ref_index(std::get<0>(hk).registry_index()));
  2359. sol::protected_function func = std::get<0>(hk);
  2360. if (func.valid())
  2361. {
  2362. funcToCall.insert_or_assign(std::get<0>(hk).registry_index(), func);
  2363. }
  2364. }
  2365. }
  2366. }
  2367. else
  2368. {
  2369. if (LuaUtility::IsKeyPressed(hk1))
  2370. {
  2371. lua_State *lua = std::get<1>(hk);
  2372. //sol::protected_function func(lua, sol::ref_index(std::get<0>(hk).registry_index()));
  2373. sol::protected_function func = std::get<0>(hk);
  2374. if (func.valid())
  2375. {
  2376. funcToCall.insert_or_assign(std::get<0>(hk).registry_index(), func);
  2377. }
  2378. }
  2379. }
  2380. }
  2381. }
  2382. if (hk1.size() > 0)
  2383. {
  2384. if (hk2.size() > 0)
  2385. {
  2386. if (hk3.size() > 0)
  2387. {
  2388. while (LuaUtility::IsKeyPressed(hk1, hk2, hk3))
  2389. Sleep(5);
  2390. }
  2391. else
  2392. {
  2393. while (LuaUtility::IsKeyPressed(hk1, hk2))
  2394. Sleep(5);
  2395. }
  2396. }
  2397. else
  2398. {
  2399. while (LuaUtility::IsKeyPressed(hk1))
  2400. Sleep(5);
  2401. }
  2402. }
  2403. for (auto &f : funcToCall)
  2404. {
  2405. f.second();
  2406. }
  2407. LeaveCriticalSection(&luamgr->luaCritSec);
  2408. Sleep(20);
  2409. }
  2410. }
  2411. void CreateGUIBindings() {
  2412. // UIData
  2413. sol::usertype<UIData> uidatatype = luamgr->lua->new_usertype<UIData>("UIData", sol::no_constructor);
  2414. // UIButton
  2415. sol::usertype<UIButton> uibuttontype = luamgr->lua->new_usertype<UIButton>("UIButton", sol::no_constructor,
  2416. sol::base_classes, sol::bases<UIData>());
  2417. uibuttontype.set_function("New", [](sol::this_state s) {UIButton* data = new UIButton; data->UIElementType = EOptionItemType::Button; data->state = s.L; return data; });
  2418. uibuttontype.set("DisplayName", &UIButton::DisplayName);
  2419. uibuttontype.set("DescriptionText", &UIButton::DescriptionText);
  2420. uibuttontype.set("DescriptionTitle", &UIButton::DescriptionTitle);
  2421. uibuttontype.set("OnClicked", &UIButton::OnChangedOrClicked);
  2422. // UISlider
  2423. sol::usertype<UISlider> uislidertype = luamgr->lua->new_usertype<UISlider>("UISlider", sol::no_constructor,
  2424. sol::base_classes, sol::bases<UIData>());
  2425. uislidertype.set_function("New", [](sol::this_state s) {UISlider* data = new UISlider; data->UIElementType = EOptionItemType::Slider; data->state = s.L; return data; });
  2426. uislidertype.set("DisplayName", &UISlider::DisplayName);
  2427. uislidertype.set("DescriptionText", &UISlider::DescriptionText);
  2428. uislidertype.set("DescriptionTitle", &UISlider::DescriptionTitle);
  2429. uislidertype.set("OnValueChanged", &UISlider::OnChangedOrClicked);
  2430. uislidertype.set("Value", &UISlider::Value);
  2431. uislidertype.set("Min", &UISlider::Min);
  2432. uislidertype.set("Max", &UISlider::Max);
  2433. uislidertype.set("Step", &UISlider::Step);
  2434. uislidertype.set("bIsInt", &UISlider::bIsInt);
  2435. // UISpinner
  2436. sol::usertype<UISpinner> uispinnertype = luamgr->lua->new_usertype<UISpinner>("UISpinner", sol::no_constructor,
  2437. sol::base_classes, sol::bases<UIData>());
  2438. uispinnertype.set_function("New", [](sol::this_state s) {UISpinner* data = new UISpinner; data->UIElementType = EOptionItemType::Spinner; data->state = s.L; return data; });
  2439. uispinnertype.set("DisplayName", &UISpinner::DisplayName);
  2440. uispinnertype.set("DescriptionText", &UISpinner::DescriptionText);
  2441. uispinnertype.set("DescriptionTitle", &UISpinner::DescriptionTitle);
  2442. uispinnertype.set("OnSelectionChanged", &UISpinner::OnChangedOrClicked);
  2443. uispinnertype.set("Index", &UISpinner::Index);
  2444. uispinnertype.set("Options", &UISpinner::Options);
  2445. // UIBoolSpinner
  2446. sol::usertype<UIBoolSpinner> uiboolspinnertype = luamgr->lua->new_usertype<UIBoolSpinner>("UIBoolSpinner", sol::no_constructor,
  2447. sol::base_classes, sol::bases<UIData>());
  2448. uiboolspinnertype.set_function("New", [](sol::this_state s) {UIBoolSpinner* data = new UIBoolSpinner; data->UIElementType = EOptionItemType::BooleanSpinner; data->state = s.L; return data; });
  2449. uiboolspinnertype.set("DisplayName", &UIBoolSpinner::DisplayName);
  2450. uiboolspinnertype.set("DescriptionText", &UIBoolSpinner::DescriptionText);
  2451. uiboolspinnertype.set("DescriptionTitle", &UIBoolSpinner::DescriptionTitle);
  2452. uiboolspinnertype.set("OnSelectionChanged", &UIBoolSpinner::OnChangedOrClicked);
  2453. uiboolspinnertype.set("Value", &UIBoolSpinner::Value);
  2454. uiboolspinnertype.set("OnText", &UIBoolSpinner::OnText);
  2455. uiboolspinnertype.set("OffText", &UIBoolSpinner::OffText);
  2456. // UIDropdown
  2457. sol::usertype<UIDropdown> uidropdowntype = luamgr->lua->new_usertype<UIDropdown>("UIDropdown", sol::no_constructor,
  2458. sol::base_classes, sol::bases<UIData>());
  2459. uidropdowntype.set_function("New", [](sol::this_state s) {UIDropdown* data = new UIDropdown; data->UIElementType = EOptionItemType::DropDownList; data->state = s.L; return data; });
  2460. uidropdowntype.set("DisplayName", &UIDropdown::DisplayName);
  2461. uidropdowntype.set("DescriptionText", &UIDropdown::DescriptionText);
  2462. uidropdowntype.set("DescriptionTitle", &UIDropdown::DescriptionTitle);
  2463. uidropdowntype.set("OnSelectionChanged", &UIDropdown::OnChangedOrClicked);
  2464. uidropdowntype.set("Index", &UIDropdown::Index);
  2465. uidropdowntype.set("Options", &UIDropdown::Options);
  2466. // UIControl
  2467. sol::usertype<UIControl> uicontrolstype = luamgr->lua->new_usertype<UIControl>("UIControl", sol::no_constructor,
  2468. sol::base_classes, sol::bases<UIData>());
  2469. uicontrolstype.set_function("New", [](sol::this_state s) {UIControl* data = new UIControl; data->UIElementType = EOptionItemType::Keybinding_Button; data->state = s.L; return data; });
  2470. uicontrolstype.set("DisplayName", &UIControl::DisplayName);
  2471. uicontrolstype.set("DescriptionText", &UIControl::DescriptionText);
  2472. uicontrolstype.set("DescriptionTitle", &UIControl::DescriptionTitle);
  2473. uicontrolstype.set("OnSelectionChanged", &UIControl::OnChangedOrClicked);
  2474. // UITitle
  2475. sol::usertype<UITitle> uititletype = luamgr->lua->new_usertype<UITitle>("UITitle", sol::no_constructor,
  2476. sol::base_classes, sol::bases<UIData>());
  2477. uititletype.set_function("New", [](sol::this_state s) {UITitle* data = new UITitle; data->UIElementType = EOptionItemType::Title; return data; });
  2478. uititletype.set("DisplayName", &UITitle::DisplayName);
  2479. luamgr->lua->set_function("AddMenuButton", sol::overload(
  2480. [](sol::this_state s, const std::string& btnText, sol::object clickFunc) {
  2481. CreateMenuItemUI(s, btnText, clickFunc, sol::lua_nil, sol::lua_nil);
  2482. },
  2483. [](sol::this_state s, const std::string& btnText, sol::lua_nil_t clickFunc, sol::object buildGUIFunc) {
  2484. CreateMenuItemUI(s, btnText, sol::lua_nil, buildGUIFunc, sol::lua_nil);
  2485. },
  2486. [](sol::this_state s, const std::string& btnText, sol::lua_nil_t clickFunc, sol::object buildGUIFunc, sol::object conditionToShow) {
  2487. CreateMenuItemUI(s, btnText, sol::lua_nil, buildGUIFunc, conditionToShow);
  2488. },
  2489. [](sol::this_state s, const std::string& btnText, sol::lua_nil_t clickFunc, sol::object buildGUIFunc, sol::lua_nil_t conditionToShow) {
  2490. CreateMenuItemUI(s, btnText, sol::lua_nil, buildGUIFunc, sol::lua_nil);
  2491. },
  2492. [](sol::this_state s, const std::string& btnText, sol::object clickFunc, sol::object buildGUIFunc) {
  2493. CreateMenuItemUI(s, btnText, clickFunc, buildGUIFunc, sol::lua_nil);
  2494. },
  2495. [](sol::this_state s, const std::string& btnText, sol::object clickFunc, sol::object buildGUIFunc, sol::object conditionToShow) {
  2496. CreateMenuItemUI(s, btnText, clickFunc, buildGUIFunc, conditionToShow);
  2497. }
  2498. ));
  2499. // UEditableText
  2500. /*sol::usertype<UEditableText> editabletexttype = luamgr->lua->new_usertype<UEditableText>("UEditableText", sol::no_constructor,
  2501. sol::meta_function::index, &UObject::GetPropertyByName,
  2502. sol::meta_function::new_index, &UObject::SetPropertyByNameLua,
  2503. sol::meta_function::to_string, &UObject::to_string,
  2504. sol::base_classes, sol::bases<UObject, UVisual, UWidget>());
  2505. editabletexttype.set_function("New", []()
  2506. {
  2507. UEditableText* rv = static_cast<UEditableText*>(StaticConstructObject(UEditableText::StaticClass(), GetTransientPackage(), FName("EditableText")));
  2508. if (rv)
  2509. rv->SetText(FText("Testtext"));
  2510. rv->SetIsEnabled(true);
  2511. rv->SetVisibility(ESlateVisibility::Visible);
  2512. return rv;
  2513. });
  2514. editabletexttype.set("HintText", &UEditableText::HintText);
  2515. editabletexttype.set("MinWidth", &UEditableText::MinimumDesiredWidth);
  2516. editabletexttype.set("Text", &UEditableText::Text);
  2517. editabletexttype.set("TooltipText", &UEditableText::ToolTipText);*/
  2518. }
  2519. void CreateBLuaMenu() {
  2520. bluaMenu->ButtonText = "BLua";
  2521. }
  2522. void LoadAllCustomUIScripts() {
  2523. EnterCriticalSection(&luamgr->luaCritSec);
  2524. if (!std::filesystem::exists("./lua"))
  2525. std::filesystem::create_directory("./lua");
  2526. if(!std::filesystem::exists("./lua/UI"))
  2527. std::filesystem::create_directory("./lua/UI");
  2528. for (auto& p : std::filesystem::directory_iterator("./lua/UI")) {
  2529. try{
  2530. sol::protected_function_result result = luamgr->lua->safe_script_file(p.path().string());
  2531. if (!result.valid()) {
  2532. sol::error err = result;
  2533. PrintGameConsole(err.what());
  2534. Logger->error(err.what());
  2535. }
  2536. }
  2537. catch(...){}
  2538. }
  2539. LeaveCriticalSection(&luamgr->luaCritSec);
  2540. }
  2541. void RefreshCustomUIs() {
  2542. EnterCriticalSection(&luamgr->luaCritSec);
  2543. createdMenuItems.clear();
  2544. menusToCreate.clear();
  2545. LoadAllCustomUIScripts();
  2546. LeaveCriticalSection(&luamgr->luaCritSec);
  2547. }
  2548. void SetupB3HMTable() {
  2549. sol::table globals = luamgr->lua->globals();
  2550. b3hmTable = luamgr->lua->create_table();
  2551. globals["B3HM"] = b3hmTable;
  2552. }
  2553. void BindLogger() {
  2554. if (!Logger) return;
  2555. luamgr->lua->set_function("LogInfo", [](const std::string& message) {if (Logger) Logger->info(message); });
  2556. luamgr->lua->set_function("LogError", [](const std::string& message) {if (Logger) Logger->error(message); });
  2557. luamgr->lua->set_function("LogCritical", [](const std::string& message) {if (Logger) Logger->critical(message); });
  2558. luamgr->lua->set_function("LogWarning", [](const std::string& message) {if (Logger) Logger->warn(message); });
  2559. }
  2560. void ReadAndBindConfig() {
  2561. sol::table global = luamgr->lua->globals();
  2562. sol::protected_function_result funcResult = luamgr->lua->safe_script_file("./lua/Configs/config.lua");
  2563. if (!funcResult.valid()) {
  2564. sol::error err = funcResult;
  2565. PrintGameConsole(err.what());
  2566. Logger->error("Failed to read config-file: {}", err.what());
  2567. }
  2568. if (!global["config"].valid()) {
  2569. sol::table configTable = luamgr->lua->create_table();
  2570. global["config"] = configTable;
  2571. }
  2572. }
  2573. DWORD WINAPI MainThread(LPVOID param)
  2574. {
  2575. atexit(callAtExit);
  2576. DebugHelper::CreateConsole();
  2577. GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, L"BL3Lua.dll", &forRefCount);
  2578. uintptr_t procEvent = PatternScan::FindSignature(NULL, processEventPattern.crypt_get());
  2579. while (procEvent == NULL)
  2580. {
  2581. procEvent = PatternScan::FindSignature(NULL, processEventPattern.crypt_get());
  2582. Sleep(50);
  2583. }
  2584. MH_STATUS status;
  2585. status = MH_Initialize();
  2586. while (status == MH_ERROR_NOT_INITIALIZED)
  2587. {
  2588. Sleep(200);
  2589. status = MH_Initialize();
  2590. if (status == MH_ERROR_ALREADY_INITIALIZED)
  2591. break;
  2592. }
  2593. try {
  2594. Logger = spdlog::basic_logger_mt("Testlogger", "./logs/BLua.log", true).get();
  2595. Logger->set_pattern("[%H:%M:%S %z] [%l] %v");
  2596. spdlog::flush_on(spdlog::level::level_enum::info);
  2597. }
  2598. catch (spdlog::spdlog_ex& ex) {
  2599. std::cout << "Failed to initialize logger: " << ex.what() << std::endl;
  2600. }
  2601. uintptr_t gObjAddress = NULL;
  2602. uintptr_t gNameAddress = NULL;
  2603. int tries = 0;
  2604. while (tries < 20)
  2605. {
  2606. if (gObjAddress == NULL)
  2607. {
  2608. gObjAddress = PatternScan::FindSignature(NULL, gObjPattern.crypt_get());
  2609. }
  2610. if (gObjAddress != NULL)
  2611. {
  2612. const auto gObjOffset = *reinterpret_cast<uint32_t *>(gObjAddress + 8);
  2613. UObject::GObjects = reinterpret_cast<decltype(UObject::GObjects)>(gObjAddress + 12 + (int)gObjOffset);
  2614. gObjInit = true;
  2615. }
  2616. if (gNameAddress == NULL)
  2617. {
  2618. gNameAddress = PatternScan::FindSignature(NULL, gNamesPattern.crypt_get());
  2619. }
  2620. if (gNameAddress != NULL)
  2621. {
  2622. const auto gNameOffset = *reinterpret_cast<uint32_t *>(gNameAddress + 7);
  2623. FName::GNames = reinterpret_cast<decltype(FName::GNames)>(*reinterpret_cast<uintptr_t *>(gNameAddress + 4 + 7 + (int)gNameOffset));
  2624. gNameInit = true;
  2625. }
  2626. if (gObjInit && gNameInit)
  2627. {
  2628. SuspendResume::Suspend();
  2629. while (MH_CreateHookEx((LPVOID)procEvent, &hkProcessEvent, &oProcessEvent) != MH_OK)
  2630. Sleep(200);
  2631. MH_EnableHook(MH_ALL_HOOKS);
  2632. SuspendResume::Resume();
  2633. Logger->info("Create LuaMgr");
  2634. luamgr = new BL3Lua();
  2635. luamgr->lua->set_function("AddHook", sol::overload(
  2636. [](sol::this_state s, sol::this_environment e, const std::string &funcName, sol::function func) { luamgr->AddHook(s, e, funcName, func, true); },
  2637. [](sol::this_state s, sol::this_environment e, const std::string &funcName, sol::function func, bool isPreHook) { luamgr->AddHook(s, e, funcName, func, isPreHook); }));
  2638. luamgr->lua->set_function("RemoveHook", &BL3Lua::RemoveHook, luamgr);
  2639. luamgr->lua->set_function("tdump", &BL3Lua::TDump, luamgr);
  2640. luamgr->lua->set_function("AddConsoleCommand", &BL3Lua::AddConsoleCommand, luamgr);
  2641. luamgr->lua->set_function("RemoveConsoleCommand", &BL3Lua::RemoveConsoleCommand, luamgr);
  2642. luamgr->lua->set_function("togglecam", &ToggleCam);
  2643. luamgr->lua->set_function("noclip", &ToggleNoclip);
  2644. luamgr->lua->set_function("AddConsoleKey", &AddConsoleKey);
  2645. luamgr->lua->set_function("SetConsoleKey", &SetConsoleKey);
  2646. //luamgr->lua->set_function("GetGlobalLog", []() { return GetGlobalLogSingleton(); });
  2647. /*luamgr->lua->set_function("SetConsoleLogging", [&](bool enable) {
  2648. FOutputDeviceRedirector *logSingleton = GetGlobalLogSingleton();
  2649. if (!myConsoleOutputDevice)
  2650. {
  2651. myConsoleOutputDevice = static_cast<FWindowsConsoleOutputDevice *>(oCreateConsoleOutputDevice());
  2652. logSingleton->AddOutputDevice(myConsoleOutputDevice);
  2653. }
  2654. myConsoleOutputDevice->Show(enable);
  2655. });*/
  2656. BindLogger();
  2657. Logger->info("Create GUI-Bindings");
  2658. CreateGUIBindings();
  2659. CreateBLuaMenu();
  2660. luamgr->lua->set_function("PrintGameConsole", &PrintGameConsole);
  2661. luamgr->lua->set_function("RefreshHotfixes", &RefreshHotfixes);
  2662. luamgr->lua->set_function("ReloadUI", &RefreshCustomUIs);
  2663. //ReadAndBindConfig();
  2664. Logger->info("Applying BaseHooks");
  2665. ApplyBaseHooks();
  2666. Logger->info("Scanning for more patterns.");
  2667. FindPatternsForTypedefs();
  2668. Logger->info("Create & setup Console");
  2669. ConsoleSetup();
  2670. Logger->info("Load UI-Files");
  2671. LoadAllCustomUIScripts();
  2672. nonScriptEnv = std::make_unique<sol::environment>(sol::environment(luamgr->lua->lua_state(), sol::create, luamgr->lua->globals())).get();
  2673. luamgr->lua->collect_garbage();
  2674. UObject::GetGameplayGlobals();
  2675. SetupB3HMTable();
  2676. //CreateCheatManager();
  2677. break;
  2678. }
  2679. Sleep(150);
  2680. }
  2681. CreateThread(nullptr, NULL, (LPTHREAD_START_ROUTINE)WebSocketClientThread, NULL, NULL, nullptr);
  2682. CreateThread(nullptr, NULL, (LPTHREAD_START_ROUTINE)iWebSocketClientThread, NULL, NULL, nullptr);
  2683. CreateThread(nullptr, NULL, (LPTHREAD_START_ROUTINE)HotkeyThread, NULL, NULL, nullptr);
  2684. return TRUE;
  2685. }
  2686. //extern "C" __declspec(dllexport) DWORD __stdcall RunScriptFile(const char *filePath)
  2687. //{
  2688. // while (!luamgr)
  2689. // {
  2690. // Sleep(50);
  2691. // }
  2692. // if (luamgr)
  2693. // if (strstr(filePath, "NewDevScript") != NULL)
  2694. // {
  2695. // luamgr->ClearCallbacks();
  2696. // luamgr->RemoveAllHooks();
  2697. // }
  2698. // luamgr->ExecuteScriptFile(filePath);
  2699. // return true;
  2700. //}
  2701. //extern "C" __declspec(dllexport) DWORD __stdcall RunLuaFunc(const char *funcName)
  2702. //{
  2703. // while (!luamgr)
  2704. // {
  2705. // Sleep(50);
  2706. // }
  2707. // if (luamgr)
  2708. // {
  2709. // sol::protected_function f = (*luamgr->lua)[funcName];
  2710. // sol::protected_function_result result = f();
  2711. // if (!result.valid())
  2712. // {
  2713. // sol::error err = result;
  2714. // std::cout << err.what() << std::endl;
  2715. // Logger->error(err.what());
  2716. // }
  2717. // }
  2718. // return true;
  2719. //}
  2720. //extern "C" __declspec(dllexport) LRESULT CALLBACK WndProc(int nCode, WPARAM wParam, LPARAM lParam)
  2721. //{
  2722. // //std::cout << "Looks like this is working!" << std::endl;
  2723. // return CallNextHookEx(0, nCode, wParam, lParam);
  2724. //};
  2725. BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
  2726. {
  2727. switch (ul_reason_for_call)
  2728. {
  2729. case DLL_PROCESS_ATTACH:
  2730. //InitializeCriticalSection(&critsec);
  2731. DisableThreadLibraryCalls(hModule);
  2732. thisDLL = hModule;
  2733. CreateThread(nullptr, NULL, (LPTHREAD_START_ROUTINE)MainThread, hModule, NULL, nullptr);
  2734. break;
  2735. case DLL_THREAD_ATTACH:
  2736. case DLL_THREAD_DETACH:
  2737. case DLL_PROCESS_DETACH:
  2738. break;
  2739. }
  2740. return TRUE;
  2741. }