void BH::Initialize() { moduleManager = new ModuleManager(); config = new Config("BH.cfg"); config->Parse(); if (D2GFX_GetHwnd()) { BH::OldWNDPROC = (WNDPROC)GetWindowLong(D2GFX_GetHwnd(), GWL_WNDPROC); SetWindowLong(D2GFX_GetHwnd(), GWL_WNDPROC, (LONG)GameWindowEvent); } settingsUI = new Drawing::UI("Settings", 350, 200); Task::InitializeThreadPool(2); // Read the MPQ Data asynchronously //CreateThread(0, 0, LoadMPQData, 0, 0, 0); Task::Enqueue([]() -> void { LoadMPQData(NULL); }); new ScreenInfo(); new Gamefilter(); new Bnet(); new Item(); new SpamFilter(); new AutoTele(); new Party(); new ItemMover(); new StashExport(); new Maphack(); moduleManager->LoadModules(); statsDisplay = new Drawing::StatsDisplay("Stats"); MiscToggles = ((AutoTele*)moduleManager->Get("autotele"))->GetToggles(); MiscToggles2 = ((Item*)moduleManager->Get("item"))->GetToggles(); // Injection would occasionally deadlock (I only ever saw it when using Tabbed Diablo // but theoretically it could happen during regular injection): // Worker thread in DllMain->LoadModules->AutoTele::OnLoad->UITab->SetCurrentTab->Lock() // Main thread in GameDraw->UI::OnDraw->D2WIN_SetTextSize->GetDllOffset->GetModuleHandle() // GetModuleHandle can invoke the loader lock which causes the deadlock, so delay patch // installation until after all startup initialization is done. for (int n = 0; n < (sizeof(patches) / sizeof(Patch*)); n++) { patches[n]->Install(); } if (!D2CLIENT_GetPlayerUnit()) oogDraw->Install(); // GameThread can potentially run oogDraw->Install, so create the thread after all // loading/installation finishes. CreateThread(0, 0, GameThread, 0, 0, 0); initialized = true; }
bool InitHooks(void) { int i = 0; while(!Vars.bActive) { if(i >= 300) { MessageBox(0, "Failed to set hooks, exiting!", "D2BS", 0); return false; } if(D2GFX_GetHwnd() && (ClientState() == ClientStateMenu || ClientState() == ClientStateInGame)) { if(!Vars.oldWNDPROC) Vars.oldWNDPROC = (WNDPROC)SetWindowLong(D2GFX_GetHwnd(), GWL_WNDPROC, (LONG)GameEventHandler); if(!Vars.oldWNDPROC) continue; Vars.uTimer = SetTimer(D2GFX_GetHwnd(), 1, 0, TimerProc); DWORD mainThread = GetWindowThreadProcessId(D2GFX_GetHwnd(),0); if(mainThread) { if(!Vars.hKeybHook) Vars.hKeybHook = SetWindowsHookEx(WH_KEYBOARD, KeyPress, NULL, mainThread); if(!Vars.hMouseHook) Vars.hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseMove, NULL, mainThread); } } else continue; if(Vars.hKeybHook && Vars.hMouseHook) { if(!ScriptEngine::Startup()) return false; Vars.bActive = TRUE; if(ClientState() == ClientStateMenu && Vars.bStartAtMenu) clickControl(*p_D2WIN_FirstControl); } Sleep(50); i++; } return true; }
void Shutdown(void) { if(!Vars.bNeedShutdown) return; Vars.bActive = FALSE; if(!Vars.bShutdownFromDllMain) WaitForSingleObject(hD2Thread, INFINITE); SetWindowLong(D2GFX_GetHwnd(),GWL_WNDPROC,(LONG)Vars.oldWNDPROC); RemovePatches(); Genhook::Destroy(); ShutdownDdeServer(); KillTimer(D2GFX_GetHwnd(), Vars.uTimer); UnhookWindowsHookEx(Vars.hMouseHook); UnhookWindowsHookEx(Vars.hKeybHook); DeleteCriticalSection(&Vars.cRoomSection); DeleteCriticalSection(&Vars.cMiscSection); DeleteCriticalSection(&Vars.cScreenhookSection); DeleteCriticalSection(&Vars.cPrintSection); DeleteCriticalSection(&Vars.cBoxHookSection); DeleteCriticalSection(&Vars.cFrameHookSection); DeleteCriticalSection(&Vars.cLineHookSection); DeleteCriticalSection(&Vars.cImageHookSection); DeleteCriticalSection(&Vars.cTextHookSection); DeleteCriticalSection(&Vars.cFlushCacheSection); DeleteCriticalSection(&Vars.cConsoleSection); DeleteCriticalSection(&Vars.cGameLoopSection); DeleteCriticalSection(&Vars.cUnitListSection); DeleteCriticalSection(&Vars.cFileSection); Log("D2BS Shutdown complete."); Vars.bNeedShutdown = false; }
bool BH::Shutdown() { if (initialized){ moduleManager->UnloadModules(); delete moduleManager; delete settingsUI; delete statsDisplay; SetWindowLong(D2GFX_GetHwnd(), GWL_WNDPROC, (LONG)BH::OldWNDPROC); for (int n = 0; n < (sizeof(patches) / sizeof(Patch*)); n++) { delete patches[n]; } oogDraw->Remove(); delete config; } return true; }