├── BH.Injector ├── Release │ └── BH.Injector.unsuccessfulbuild ├── PEStructs.h ├── EventSink.h ├── BH.Injector.vcxproj.filters ├── cInjector.h ├── BH.Injector.h ├── EventSink.cpp └── BH.Injector.vcxproj ├── Packaging ├── UI.ini └── BH v1.7a BETA2.zip ├── Release └── BH.dll ├── BH ├── Modules │ ├── AutoTele │ │ ├── ATIncludes │ │ │ ├── CMapIncludes.h │ │ │ └── SyncObj.h │ │ ├── AutoTele.cpp │ │ └── AutoTele.h │ ├── Item │ │ ├── Item.cpp │ │ ├── ItemDisplay.cpp │ │ └── Item.h │ ├── ModuleManager.cpp │ ├── ScreenInfo │ │ ├── ScreenInfo.cpp │ │ └── ScreenInfo.h │ ├── ChatColor │ │ ├── ChatColor.h │ │ └── ChatColor.cpp │ ├── Party │ │ ├── Party.h │ │ └── Party.cpp │ ├── Bnet │ │ ├── Bnet.h │ │ └── Bnet.cpp │ ├── ModuleManager.h │ ├── Gamefilter │ │ └── Gamefilter.h │ ├── Module.h │ ├── StashExport │ │ └── StashExport.h │ ├── Maphack │ │ └── Maphack.h │ ├── ItemMover │ │ └── ItemMover.h │ └── Module.cpp ├── Drawing │ ├── Stats │ │ ├── StatsDisplay.cpp │ │ └── StatsDisplay.h │ ├── Advanced │ │ ├── Keyhook │ │ │ ├── Keyhook.cpp │ │ │ └── Keyhook.h │ │ ├── Inputhook │ │ │ ├── Inputhook.cpp │ │ │ └── Inputhook.h │ │ ├── Colorhook │ │ │ ├── Colorhook.h │ │ │ └── Colorhook.cpp │ │ ├── Combohook │ │ │ ├── Combohook.h │ │ │ └── Combohook.cpp │ │ └── Checkhook │ │ │ ├── Checkhook.h │ │ │ └── Checkhook.cpp │ ├── Basic │ │ ├── Crosshook │ │ │ ├── Crosshook.h │ │ │ └── Crosshook.cpp │ │ ├── Linehook │ │ │ ├── Linehook.h │ │ │ └── Linehook.cpp │ │ ├── Boxhook │ │ │ ├── Boxhook.h │ │ │ └── Boxhook.cpp │ │ ├── Framehook │ │ │ ├── Framehook.h │ │ │ └── Framehook.cpp │ │ └── Texthook │ │ │ ├── Texthook.h │ │ │ └── Texthook.cpp │ ├── UI │ │ ├── UITab.cpp │ │ ├── UITab.h │ │ └── UI.h │ └── Hook.h ├── Task.h ├── DllMain.cpp ├── D2Version.h ├── BitReader.h ├── D2Intercepts.h ├── Modules.h ├── D2Stubs.h ├── D2Handlers.h ├── Drawing.h ├── BitReader.cpp ├── Patch.h ├── D2Helpers.h ├── AsyncDrawBuffer.h ├── BH.h ├── Mustache.h ├── MPQInit.h ├── Task.cpp ├── D2Stubs.cpp ├── TableReader.h ├── D2Version.cpp ├── CMakeLists.txt ├── Config.h ├── AsyncDrawBuffer.cpp ├── RuleLookupCache.h ├── Patch.cpp ├── MPQReader.h ├── D2Intercepts.cpp ├── Common.h ├── D2Handlers.cpp ├── BH.vcxproj.filters ├── MPQReader.cpp ├── JSONObject.h └── BH.cpp ├── ThirdParty ├── StormLib.dll ├── StormLib.lib └── cpp-lru-cache │ ├── .gitignore │ ├── .travis.yml │ ├── README.md │ ├── ext │ └── gtest │ │ └── CMakeLists.txt │ ├── CMakeLists.txt │ ├── src │ └── test.cpp │ ├── LICENSE │ └── include │ └── lrucache.hpp ├── readme_gfx ├── map_boxes.png └── color_palette.png ├── CMakeLists.txt ├── .gitignore └── BH.sln /BH.Injector/Release/BH.Injector.unsuccessfulbuild: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Packaging/UI.ini: -------------------------------------------------------------------------------- 1 | [Settings] 2 | Minimized=1 3 | X=89 4 | Y=179 5 | -------------------------------------------------------------------------------- /Release/BH.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/Release/BH.dll -------------------------------------------------------------------------------- /BH/Modules/AutoTele/ATIncludes/CMapIncludes.h: -------------------------------------------------------------------------------- 1 | #include "CollisionMap.h" 2 | #include "TeleportPath.h" -------------------------------------------------------------------------------- /BH/Modules/Item/Item.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/BH/Modules/Item/Item.cpp -------------------------------------------------------------------------------- /ThirdParty/StormLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/ThirdParty/StormLib.dll -------------------------------------------------------------------------------- /ThirdParty/StormLib.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/ThirdParty/StormLib.lib -------------------------------------------------------------------------------- /readme_gfx/map_boxes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/readme_gfx/map_boxes.png -------------------------------------------------------------------------------- /BH/Modules/ModuleManager.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/BH/Modules/ModuleManager.cpp -------------------------------------------------------------------------------- /Packaging/BH v1.7a BETA2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/Packaging/BH v1.7a BETA2.zip -------------------------------------------------------------------------------- /readme_gfx/color_palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/readme_gfx/color_palette.png -------------------------------------------------------------------------------- /BH/Modules/AutoTele/AutoTele.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/BH/Modules/AutoTele/AutoTele.cpp -------------------------------------------------------------------------------- /BH/Modules/Item/ItemDisplay.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/BH/Modules/Item/ItemDisplay.cpp -------------------------------------------------------------------------------- /BH/Drawing/Stats/StatsDisplay.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/BH/Drawing/Stats/StatsDisplay.cpp -------------------------------------------------------------------------------- /BH/Modules/ScreenInfo/ScreenInfo.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/BH/Modules/ScreenInfo/ScreenInfo.cpp -------------------------------------------------------------------------------- /BH/Drawing/Advanced/Keyhook/Keyhook.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/BH/Drawing/Advanced/Keyhook/Keyhook.cpp -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7) 2 | find_library(STORM_LIBRARY NAMES StormLib HINTS "ThirdParty") 3 | add_subdirectory("BH") 4 | -------------------------------------------------------------------------------- /BH/Drawing/Advanced/Inputhook/Inputhook.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oskros/slashdiablo-maphack-plugy/HEAD/BH/Drawing/Advanced/Inputhook/Inputhook.cpp -------------------------------------------------------------------------------- /BH/Task.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace Task { 5 | void InitializeThreadPool(int size); 6 | void StopThreadPool(); 7 | 8 | void Enqueue(std::function task); 9 | } -------------------------------------------------------------------------------- /ThirdParty/cpp-lru-cache/.gitignore: -------------------------------------------------------------------------------- 1 | CMakeCache.txt 2 | CMakeFiles 3 | Makefile 4 | install_manifest.txt 5 | cmake_install.cmake 6 | 7 | nbproject 8 | build 9 | 10 | cpp-lru-cache-test 11 | obj-x86_64-linux-gnu/ 12 | -------------------------------------------------------------------------------- /ThirdParty/cpp-lru-cache/.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | compiler: 4 | - gcc 5 | 6 | script: 7 | - mkdir build 8 | - cd build 9 | - cmake .. 10 | - make check 11 | 12 | notifications: 13 | email: false 14 | -------------------------------------------------------------------------------- /BH/DllMain.cpp: -------------------------------------------------------------------------------- 1 | #include "BH.h" 2 | #include 3 | 4 | BOOL WINAPI DllMain(HMODULE instance, DWORD reason, VOID* reserved) { 5 | switch(reason) { 6 | case DLL_PROCESS_ATTACH: 7 | return BH::Startup(instance, reserved); 8 | break; 9 | case DLL_PROCESS_DETACH: 10 | return BH::Shutdown(); 11 | break; 12 | } 13 | } -------------------------------------------------------------------------------- /BH.Injector/PEStructs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace PE { 5 | 6 | /* Author: slayergod13 7 | * Taken from some C# code of mine, hence the type names 8 | */ 9 | typedef unsigned int uint; 10 | typedef unsigned short ushort; 11 | typedef unsigned char byte; 12 | typedef unsigned long long ulong; 13 | typedef long long int64; 14 | 15 | 16 | 17 | 18 | ulong GetFunctionOffset(std::string dllPath, std::string functionName); 19 | } -------------------------------------------------------------------------------- /BH/D2Version.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _D2VERSION_H 4 | #define _D2VERSION_H 5 | 6 | #include 7 | 8 | enum VersionID { 9 | INVALID = -1, 10 | VERSION_113c = 0, 11 | VERSION_113d 12 | }; 13 | 14 | namespace D2Version { 15 | extern VersionID versionID; 16 | VersionID GetGameVersionID(); 17 | void Init(); 18 | std::string GetGameVersionString(); 19 | std::string GetHumanReadableVersion(); 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | 9 | # Compiled Static libraries 10 | *.lai 11 | *.la 12 | *.a 13 | 14 | 15 | *.exe 16 | *.bin 17 | *.dll 18 | *.obj 19 | *.pdb 20 | *.ipch 21 | *.ilk 22 | *.idb 23 | *.tlog 24 | *.log 25 | *.lastbuildstate 26 | *.manifest 27 | *.user 28 | *.suo 29 | *.sdf 30 | *.opensdf 31 | 32 | *~ 33 | *.swp 34 | Debug/ 35 | Packaging/* 36 | BH/Release/* 37 | Release/* 38 | /.vs/* 39 | /BH.VC.db 40 | /out/* -------------------------------------------------------------------------------- /BH/BitReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | 6 | typedef unsigned long ulong; 7 | 8 | //extern std::size_t const bits_per_byte; 9 | 10 | class BitReader { 11 | public: 12 | std::size_t offset; 13 | const unsigned char *data; 14 | 15 | BitReader(const unsigned char *data) : data(data), offset(0) {}; 16 | 17 | bool readBool(); 18 | unsigned long read(unsigned int numBits); 19 | unsigned int getBit(unsigned int bitoffset); 20 | unsigned long getBits(unsigned int numBits); 21 | }; 22 | -------------------------------------------------------------------------------- /BH/D2Intercepts.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID GameDraw_Interception(); 4 | void GameAutomapDraw_Interception(); 5 | VOID OOGDraw_Interception(); 6 | 7 | void GameLoop_Interception(); 8 | 9 | 10 | VOID GamePacketRecv_Interception(); 11 | VOID ChatPacketRecv_Interception(); 12 | VOID RealmPacketRecv_Interception(); 13 | void GameInput_Interception(void); 14 | void ChannelInput_Interception(void); 15 | void ChannelWhisper_Interception(void); 16 | void ChannelChat_Interception(void); 17 | void ChannelEmote_Interception(void); -------------------------------------------------------------------------------- /BH/Modules.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Modules\ModuleManager.h" 4 | #include "Modules\Module.h" 5 | 6 | #include "Modules\Maphack\Maphack.h" 7 | #include "Modules\ScreenInfo\ScreenInfo.h" 8 | #include "Modules\Gamefilter\Gamefilter.h" 9 | #include "Modules\Bnet\Bnet.h" 10 | #include "Modules\Item\Item.h" 11 | #include "Modules\ItemMover\ItemMover.h" 12 | #include "Modules\AutoTele\AutoTele.h" 13 | #include "Modules\Party\Party.h" 14 | #include "Modules\StashExport\StashExport.h" 15 | #include "Modules\ChatColor\ChatColor.h" -------------------------------------------------------------------------------- /BH/Modules/ChatColor/ChatColor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../D2Structs.h" 3 | #include "../Module.h" 4 | #include "../../Config.h" 5 | #include "../../Common.h" 6 | 7 | class ChatColor : public Module { 8 | private: 9 | bool inGame; 10 | std::map whisperColors; 11 | public: 12 | ChatColor() : Module("Chat Color") {}; 13 | 14 | void Init(); 15 | 16 | void OnLoad(); 17 | void LoadConfig(); 18 | void OnGameJoin(); 19 | void OnGameExit(); 20 | void OnChatPacketRecv(BYTE* packet, bool *block); 21 | }; 22 | -------------------------------------------------------------------------------- /BH/D2Stubs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | DWORD __fastcall D2CLIENT_GetUnitName_STUB(DWORD UnitAny); 5 | DWORD __fastcall D2CLIENT_InitAutomapLayer(DWORD nLayerNo); 6 | DWORD __fastcall TestPvpFlag_STUB(DWORD planum1, DWORD planum2, DWORD flagmask); 7 | DWORD __fastcall D2CLIENT_GetLevelName_STUB(DWORD levelId); 8 | DWORD __fastcall D2CLIENT_GetUIVar_STUB(DWORD varno); 9 | CellFile* __fastcall D2CLIENT_LoadUiImage(CHAR* szPath); 10 | DWORD __fastcall D2CLIENT_ClickParty_ASM(RosterUnit* RosterUnit, DWORD Mode); 11 | void __fastcall D2CLIENT_PlaySound(int SoundNo); -------------------------------------------------------------------------------- /BH/D2Handlers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | void GameDraw(); 5 | void GameAutomapDraw(); 6 | void OOGDraw(); 7 | 8 | void GameLoop(); 9 | DWORD WINAPI GameThread(VOID* lpvoid); 10 | LONG WINAPI GameWindowEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 11 | 12 | BOOL ChatPacketRecv(DWORD dwSize,BYTE* pPacket); 13 | BOOL __fastcall RealmPacketRecv(BYTE* pPacket); 14 | DWORD __fastcall GamePacketRecv(BYTE* pPacket, DWORD dwSize); 15 | 16 | DWORD __fastcall GameInput(wchar_t* wMsg); 17 | DWORD __fastcall ChannelInput(wchar_t* wMsg); 18 | BOOL __fastcall ChatHandler(char* user, char* msg); -------------------------------------------------------------------------------- /BH/Drawing.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Drawing\Basic\Boxhook\Boxhook.h" 4 | #include "Drawing\Basic\Texthook\Texthook.h" 5 | #include "Drawing\Basic\Crosshook\Crosshook.h" 6 | #include "Drawing\Basic\Framehook\Framehook.h" 7 | #include "Drawing\Basic\Linehook\Linehook.h" 8 | 9 | #include "Drawing\Advanced\Checkhook\Checkhook.h" 10 | #include "Drawing\Advanced\Colorhook\Colorhook.h" 11 | #include "Drawing\Advanced\Combohook\Combohook.h" 12 | #include "Drawing\Advanced\Inputhook\Inputhook.h" 13 | #include "Drawing\Advanced\Keyhook\Keyhook.h" 14 | 15 | #include "Drawing\UI\UI.h" 16 | #include "Drawing\UI\UITab.h" 17 | 18 | #include "Drawing\Stats\StatsDisplay.h" 19 | -------------------------------------------------------------------------------- /BH/Modules/Party/Party.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Module.h" 3 | #include "../../Config.h" 4 | #include "../../Drawing.h" 5 | 6 | #define PARTY_NOT_IN_PARTY 0x00 7 | #define PARTY_IN_PARTY 0x01 8 | #define PARTY_INVITED_YOU 0x02 9 | #define PARTY_INVITED_BY_YOU 0x04 10 | 11 | class Party : public Module { 12 | private: 13 | map Toggles; 14 | map LootingPermission; 15 | void CheckParty(); 16 | int c; 17 | public: 18 | Party() : Module("Party") {}; 19 | void OnLoad(); 20 | void OnUnload(); 21 | void OnLoop(); 22 | void OnKey(bool up, BYTE key, LPARAM lParam, bool* block); 23 | void OnGameExit(); 24 | void OnGameJoin(); 25 | }; 26 | -------------------------------------------------------------------------------- /BH/BitReader.cpp: -------------------------------------------------------------------------------- 1 | #include "BitReader.h" 2 | 3 | 4 | bool BitReader::readBool() { 5 | return read(1) > 0; 6 | } 7 | 8 | unsigned long BitReader::read(unsigned int numBits) { 9 | unsigned long result = getBits(numBits); 10 | offset += numBits; 11 | return result; 12 | } 13 | 14 | unsigned int BitReader::getBit(unsigned int bitoffset) { 15 | unsigned int c = (unsigned int)(data[bitoffset >> 3]); 16 | unsigned int bitmask = 1 << (bitoffset & 7); 17 | return ((c & bitmask) != 0) ? 1 : 0; 18 | } 19 | 20 | unsigned long BitReader::getBits(unsigned int numBits) { 21 | unsigned int bits = 0, count = 0; 22 | for (unsigned int currentbit = offset; currentbit < offset + numBits; currentbit++, count++) { 23 | bits = bits | (getBit(currentbit) << count); 24 | } 25 | return bits; 26 | } 27 | -------------------------------------------------------------------------------- /ThirdParty/cpp-lru-cache/README.md: -------------------------------------------------------------------------------- 1 | cpp-lru-cache 2 | ============= 3 | 4 | Simple and reliable LRU (Least Recently Used) cache for c++ based on hashmap and linkedlist. The library is header only, simple test and example are included. 5 | It includes standard components and very little own logics that guarantees reliability. 6 | 7 | Example: 8 | 9 | ``` 10 | /**Creates cache with maximum size of three. When the 11 | size in achieved every next element will replace the 12 | least recently used one */ 13 | cache::lru_cache cache(3); 14 | 15 | cache.put("one", "one"); 16 | cache.put("two", "two"); 17 | 18 | const std::string& from_cache = cache.get("two") 19 | 20 | ``` 21 | 22 | How to run tests: 23 | 24 | ``` 25 | mkdir build 26 | cd build 27 | cmake .. 28 | make check 29 | ``` 30 | -------------------------------------------------------------------------------- /ThirdParty/cpp-lru-cache/ext/gtest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(gtest_builder C CXX) 3 | include(ExternalProject) 4 | 5 | ExternalProject_Add(googletest 6 | GIT_REPOSITORY https://github.com/google/googletest.git 7 | GIT_TAG release-1.7.0 8 | CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=DebugLibs 9 | -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=ReleaseLibs 10 | -DCMAKE_CXX_FLAGS=${MSVC_COMPILER_DEFS} 11 | -Dgtest_force_shared_crt=ON 12 | PREFIX "${CMAKE_CURRENT_BINARY_DIR}" 13 | INSTALL_COMMAND "" 14 | UPDATE_COMMAND "" 15 | ) 16 | 17 | ExternalProject_Get_Property(googletest source_dir) 18 | set(GTEST_INCLUDE_DIRS ${source_dir}/include PARENT_SCOPE) 19 | 20 | ExternalProject_Get_Property(googletest binary_dir) 21 | set(GTEST_LIBS_DIR ${binary_dir} PARENT_SCOPE) 22 | -------------------------------------------------------------------------------- /BH/Patch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | class Patch; 7 | 8 | enum Dll { D2CLIENT=0,D2COMMON,D2GFX,D2LANG,D2WIN,D2NET,D2GAME,D2LAUNCH,FOG,BNCLIENT, STORM, D2CMP, D2MULTI, D2MCPCLIENT}; 9 | enum PatchType { Jump=0xE9, Call=0xE8, NOP=0x90, Push=0x6A }; 10 | 11 | struct Offsets { 12 | int _113c; 13 | int _113d; 14 | }; 15 | 16 | class Patch { 17 | private: 18 | static std::vector Patches; 19 | Dll dll; 20 | PatchType type; 21 | Offsets offsets; 22 | int length, function; 23 | BYTE* oldCode; 24 | bool injected; 25 | public: 26 | Patch(PatchType type, Dll dll, Offsets offsets, int function, int length); 27 | 28 | bool Install (); 29 | bool Remove (); 30 | 31 | bool IsInstalled() { return injected; }; 32 | 33 | static int GetDllOffset(Dll dll, int offset); 34 | static bool WriteBytes(int address, int len, BYTE* bytes); 35 | }; 36 | -------------------------------------------------------------------------------- /BH/Drawing/Basic/Crosshook/Crosshook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Hook.h" 4 | 5 | namespace Drawing { 6 | class Crosshook : public Hook { 7 | private: 8 | unsigned int color;//Color of the cross hook 0-255. 9 | 10 | public: 11 | //Crosshook Initaliztors, one for basic hooks and one for groups. 12 | Crosshook(HookVisibility visiblity, unsigned int x, unsigned int y); 13 | Crosshook(HookGroup* group, unsigned int x, unsigned int y); 14 | 15 | //Returns the color of the cross hook. 16 | unsigned int GetColor(); 17 | 18 | //Sets the color of the cross hook. 19 | void SetColor(unsigned int newColor); 20 | 21 | //Filler to return nothing to base class. 22 | unsigned int GetXSize(); 23 | unsigned int GetYSize(); 24 | 25 | //Draw the text. 26 | void OnDraw(); 27 | 28 | //Static Cross Draw 29 | static bool Draw(unsigned int x, unsigned int y, unsigned int color); 30 | }; 31 | }; -------------------------------------------------------------------------------- /BH.Injector/EventSink.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENTSINK_H 2 | #define EVENTSINK_H 3 | 4 | #define _WIN32_DCOM 5 | #include 6 | using namespace std; 7 | #include 8 | #include 9 | 10 | # pragma comment(lib, "wbemuuid.lib") 11 | 12 | class EventSink : public IWbemObjectSink { 13 | LONG m_lRef; 14 | bool bDone; 15 | 16 | public: 17 | EventSink() { m_lRef = 0; } 18 | ~EventSink() { bDone = true; } 19 | 20 | virtual ULONG STDMETHODCALLTYPE AddRef(); 21 | virtual ULONG STDMETHODCALLTYPE Release(); 22 | virtual HRESULT 23 | STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv); 24 | 25 | virtual HRESULT STDMETHODCALLTYPE Indicate( 26 | LONG lObjectCount, 27 | IWbemClassObject __RPC_FAR *__RPC_FAR *apObjArray 28 | ); 29 | 30 | virtual HRESULT STDMETHODCALLTYPE SetStatus( 31 | /* [in] */ LONG lFlags, 32 | /* [in] */ HRESULT hResult, 33 | /* [in] */ BSTR strParam, 34 | /* [in] */ IWbemClassObject __RPC_FAR *pObjParam 35 | ); 36 | }; 37 | 38 | #endif -------------------------------------------------------------------------------- /BH/D2Helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "D2Structs.h" 7 | 8 | #define INVALID_PARTY_ID 0xFFFF 9 | 10 | bool IsValidMonster(UnitAny *pUnit); 11 | int GetRelation(UnitAny* unit); 12 | RosterUnit* FindPlayerRoster(DWORD unitId); 13 | void Print(char* format, ...); 14 | void PartyPrint(char* format, ...); 15 | 16 | CellFile *LoadBmpCellFile(BYTE *buf1, int width, int height); 17 | CellFile *LoadBmpCellFile(char *filename); 18 | CellFile *InitCellFile(CellFile *cf); 19 | void DeleteCellFile(CellFile *cf); 20 | 21 | DWORD GetDistanceSquared(DWORD x1, DWORD y1, DWORD x2, DWORD y2); 22 | bool SetSkill(WORD wSkillId, bool Left); 23 | bool GetSkill(WORD wSkillId); 24 | bool CastOnMap(WORD x, WORD y, bool Left); 25 | bool RunTo(WORD x, WORD y); 26 | bool Interact(DWORD UnitId, DWORD UnitType); 27 | 28 | std::string GetItemCode(int dwTxtFileNo); 29 | std::string GetItemName(UnitAny* item); 30 | bool IsTown(DWORD levelId); 31 | 32 | bool IsGameReady(); 33 | DWORD GetPlayerArea(); 34 | int ItemColorFromQuality(unsigned int quality); -------------------------------------------------------------------------------- /BH/Drawing/Advanced/Keyhook/Keyhook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Hook.h" 4 | 5 | namespace Drawing { 6 | class Keyhook : public Hook { 7 | private: 8 | unsigned int* key;//Pointer to the current key 9 | std::string name;//Name of the hotkey 10 | unsigned int timeout;//Timeout to change hotkey if clicked 11 | public: 12 | //Two Hook Initializations; one for basic hooks, one for grouped hooks. 13 | Keyhook(HookVisibility visibility, unsigned int x, unsigned int y, unsigned int* key, std::string hotkeyName); 14 | Keyhook(HookGroup* group, unsigned int x, unsigned int y, unsigned int* key, std::string hotkeyName); 15 | 16 | std::string GetName() { return name; }; 17 | void SetName(std::string newName) { Lock(); name = newName; Unlock(); }; 18 | 19 | unsigned int GetKey() { return *key; }; 20 | void SetKey(unsigned int* newKey) { Lock(); key = newKey; Unlock(); }; 21 | 22 | bool OnLeftClick(bool up, unsigned int x, unsigned int y); 23 | void OnDraw(); 24 | bool OnKey(bool up, BYTE key, LPARAM lParam); 25 | 26 | unsigned int GetXSize(); 27 | unsigned int GetYSize(); 28 | }; 29 | }; -------------------------------------------------------------------------------- /ThirdParty/cpp-lru-cache/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project(CPP-LRU_CACHE) 4 | 5 | find_package(Threads REQUIRED) 6 | 7 | set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 8 | set(EXT_PROJECTS_DIR ${PROJECT_SOURCE_DIR}/ext) 9 | add_subdirectory(${EXT_PROJECTS_DIR}/gtest) 10 | 11 | enable_testing() 12 | 13 | include_directories( 14 | ${GTEST_INCLUDE_DIRS} 15 | ${PROJECT_SOURCE_DIR}/include) 16 | 17 | add_executable( 18 | cpp-lru-cache-test 19 | src/test) 20 | 21 | add_dependencies(cpp-lru-cache-test googletest) 22 | 23 | target_link_libraries( 24 | cpp-lru-cache-test 25 | ${GTEST_LIBS_DIR}/libgtest.a 26 | ${GTEST_LIBS_DIR}/libgtest_main.a 27 | ${CMAKE_THREAD_LIBS_INIT}) 28 | 29 | set_target_properties(cpp-lru-cache-test PROPERTIES 30 | PREFIX "" 31 | SUFFIX "" 32 | COMPILE_FLAGS "-std=c++0x -W -Wall -pedantic") 33 | 34 | set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3") 35 | set(CMAKE_CSS_FLAGS_RELEASE "-03 -g") 36 | 37 | add_test( 38 | NAME cpp-lru-cache-test 39 | COMMAND cpp-lru-cache-test 40 | ) 41 | 42 | add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --verbose 43 | DEPENDS cpp-lru-cache-test) 44 | -------------------------------------------------------------------------------- /BH/AsyncDrawBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Task.h" 3 | 4 | class DrawBuffer; 5 | class DrawDirective; 6 | class AsyncDrawBuffer; 7 | 8 | typedef std::function fpDirector; 9 | 10 | class AsyncDrawBuffer 11 | { 12 | private: 13 | DrawBuffer* fg; 14 | DrawBuffer* bg; 15 | public: 16 | AsyncDrawBuffer(); 17 | ~AsyncDrawBuffer(); 18 | 19 | // Calls all buffered draw calls in the fore buffer 20 | void drawAll(); 21 | 22 | // Pushes a draw function into the back buffer 23 | void push(std::function drawCall); 24 | void push_top_layer(std::function drawCall); 25 | 26 | // Clears the backbuffer 27 | void clear(); 28 | 29 | // Switches the fore and back buffers to change the displayed frame 30 | void swapBuffers(); 31 | }; 32 | 33 | class DrawDirective { 34 | private: 35 | int frameCount; 36 | bool updatePending; 37 | AsyncDrawBuffer buffer; 38 | bool forcedUpdate; 39 | bool synchronous; 40 | void drawInternal(fpDirector director); 41 | public: 42 | unsigned int maxGhost; 43 | 44 | DrawDirective(bool synchronous, unsigned char _maxGhost); 45 | ~DrawDirective(); 46 | void draw(fpDirector director); 47 | void forceUpdate(); 48 | }; 49 | 50 | -------------------------------------------------------------------------------- /BH/Drawing/Advanced/Colorhook/Colorhook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Hook.h" 4 | 5 | namespace Drawing { 6 | class Colorhook; 7 | 8 | class Colorhook : public Hook { 9 | private: 10 | std::string text;//Text to have linked 11 | unsigned int* currentColor;//Color that we will be changing 12 | unsigned int curColor; 13 | public: 14 | static Colorhook* current;//Pointer to the current colorhook 15 | 16 | //Two Hook Initializations; one for basic hooks, one for grouped hooks. 17 | Colorhook(HookVisibility visibility, unsigned int x, unsigned int y, unsigned int* color, std::string formatString, ...); 18 | Colorhook(HookGroup* group, unsigned int x, unsigned int y, unsigned int* color, std::string formatString, ...); 19 | 20 | std::string GetText() { return text; }; 21 | void SetText(std::string newText); 22 | 23 | unsigned int GetColor() { return *currentColor; }; 24 | void SetColor(unsigned int newColor); 25 | 26 | bool OnLeftClick(bool up, unsigned int x, unsigned int y); 27 | bool OnRightClick(bool up, unsigned int x, unsigned int y); 28 | void OnDraw(); 29 | 30 | unsigned int GetXSize(); 31 | unsigned int GetYSize(); 32 | }; 33 | }; -------------------------------------------------------------------------------- /BH/BH.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "Modules/ModuleManager.h" 7 | #include "Config.h" 8 | #include "Drawing.h" 9 | #include "Patch.h" 10 | 11 | using namespace std; 12 | 13 | struct cGuardModule 14 | { 15 | union { 16 | HMODULE hModule; 17 | DWORD dwBaseAddress; 18 | }; 19 | DWORD _1; 20 | char szPath[MAX_PATH]; 21 | }; 22 | 23 | namespace BH { 24 | extern string path; 25 | extern HINSTANCE instance; 26 | extern ModuleManager* moduleManager; 27 | extern Config* config; 28 | extern Config* itemConfig; 29 | extern Drawing::UI* settingsUI; 30 | extern Drawing::StatsDisplay* statsDisplay; 31 | extern WNDPROC OldWNDPROC; 32 | extern map* MiscToggles; 33 | extern map* MiscToggles2; 34 | extern map* BnetBools; 35 | extern map* GamefilterBools; 36 | extern bool cGuardLoaded; 37 | extern bool initialized; 38 | extern Patch* oogDraw; 39 | 40 | extern bool Startup(HINSTANCE instance, VOID* reserved); 41 | extern "C" __declspec(dllexport) void Initialize(); 42 | extern bool Shutdown(); 43 | extern bool ReloadConfig(); 44 | }; 45 | -------------------------------------------------------------------------------- /BH/Drawing/UI/UITab.cpp: -------------------------------------------------------------------------------- 1 | #include "UITab.h" 2 | #include "../Basic/Texthook/Texthook.h" 3 | #include "../Basic/Framehook/Framehook.h" 4 | #include "../../D2Ptrs.h" 5 | 6 | using namespace Drawing; 7 | 8 | UITab::~UITab() { 9 | ui->Lock(); 10 | // Remove all hooks associated to the tab. 11 | for (auto it = Hooks.begin(); it != Hooks.end(); it++){ 12 | Hook* h = *it; 13 | delete h; 14 | } 15 | Hooks.clear(); 16 | 17 | // Remove tab from list. 18 | ui->Tabs.remove(this); 19 | 20 | } 21 | 22 | unsigned int UITab::GetTabPos() { 23 | unsigned int n = 0; 24 | for(std::list::iterator it = ui->Tabs.begin(); it != ui->Tabs.end(); it++, n++) 25 | if ((*it) == this) 26 | return n; 27 | return 0; 28 | } 29 | 30 | void UITab::OnDraw() { 31 | bool isHovering = IsHovering((*p_D2CLIENT_MouseX), (*p_D2CLIENT_MouseY)); 32 | 33 | if (IsActive()) 34 | for(std::list::iterator it = Hooks.begin(); it != Hooks.end(); it++) 35 | (*it)->OnDraw(); 36 | else 37 | Framehook::Draw(GetTabX(), GetTabY(), GetTabSize(), TAB_HEIGHT, 0, (ui->IsActive()?BTNormal:BTHighlight)); 38 | Texthook::Draw(GetTabX() + (GetTabSize() / 2), GetTabY() + 2, Center, 0, IsActive()?Grey:isHovering?Tan:Gold, name); 39 | } -------------------------------------------------------------------------------- /BH/Modules/Bnet/Bnet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Module.h" 3 | #include 4 | 5 | struct Control; 6 | 7 | class Bnet : public Module { 8 | private: 9 | std::map bools; 10 | bool* showLastGame; 11 | bool* showLastPass; 12 | bool* nextInstead; 13 | bool* keepDesc; 14 | static unsigned int failToJoin; 15 | static std::string lastName; 16 | static std::string lastPass; 17 | static std::string lastDesc; 18 | static std::regex reg; 19 | 20 | public: 21 | 22 | Bnet() : Module("Bnet") {}; 23 | 24 | void OnLoad(); 25 | void OnUnload(); 26 | void LoadConfig(); 27 | 28 | void OnGameJoin(); 29 | void OnGameExit(); 30 | 31 | void InstallPatches(); 32 | void RemovePatches(); 33 | 34 | std::map* GetBools() { return &bools; } 35 | 36 | static VOID __fastcall NextGamePatch(Control* box, BOOL (__stdcall *FunCallBack)(Control*, DWORD, DWORD)); 37 | static VOID __fastcall NextPassPatch(Control* box, BOOL(__stdcall *FunCallBack)(Control*, DWORD, DWORD)); 38 | static VOID __fastcall GameDescPatch(Control* box, BOOL(__stdcall *FunCallBack)(Control*, DWORD, DWORD)); 39 | static void RemovePassPatch(); 40 | }; 41 | 42 | void FailToJoin_Interception(); 43 | void RemovePass_Interception(); 44 | -------------------------------------------------------------------------------- /BH/Drawing/UI/UITab.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Hook.h" 3 | #include "UI.h" 4 | 5 | namespace Drawing { 6 | #define TAB_HEIGHT 13 7 | 8 | class UITab : public HookGroup { 9 | private: 10 | std::string name; 11 | UI* ui; 12 | public: 13 | UITab(std::string name, UI* nui) : name(name), ui(nui) {ui->Tabs.push_back(this); if (ui->Tabs.size() == 1) { ui->SetCurrentTab(this); }}; 14 | ~UITab(); 15 | 16 | unsigned int GetX() { return ui->GetX(); }; 17 | unsigned int GetY() { return ui->GetY() + TITLE_BAR_HEIGHT + TAB_HEIGHT; }; 18 | unsigned int GetXSize() { return ui->GetXSize(); }; 19 | unsigned int GetYSize() { return ui->GetYSize() - TITLE_BAR_HEIGHT - TAB_HEIGHT; }; 20 | 21 | unsigned int GetTabPos(); 22 | unsigned int GetTabSize() { return (ui->GetXSize() / ui->Tabs.size()); }; 23 | unsigned int GetTabX() { return ui->GetX() + GetTabPos() * GetTabSize(); }; 24 | unsigned int GetTabY() { return ui->GetY() + TITLE_BAR_HEIGHT; }; 25 | 26 | 27 | bool IsActive() { return ui->GetActiveTab() == this && !ui->IsMinimized(); }; 28 | 29 | bool IsHovering(unsigned int x, unsigned int y) { return x >= GetTabX() && y >= GetTabY() && x <= (GetTabX() + GetTabSize()) && y <= (GetTabY() + TAB_HEIGHT); }; 30 | 31 | void OnDraw(); 32 | }; 33 | }; -------------------------------------------------------------------------------- /BH/Mustache.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright: Chris Kellner 2015 3 | License: MIT 4 | */ 5 | #pragma once 6 | #include 7 | #include 8 | #include "JSONObject.h" 9 | 10 | /* 11 | Based on the spec located at: https://mustache.github.io/mustache.5.html 12 | */ 13 | namespace Mustache{ 14 | class Context; 15 | 16 | class AMustacheTemplate{ 17 | public: 18 | AMustacheTemplate(){} 19 | virtual ~AMustacheTemplate(){} 20 | 21 | virtual std::string render(Context &ctx){ return ""; }; 22 | }; 23 | 24 | class Context{ 25 | private: 26 | Context *parent; 27 | JSONElement *content; 28 | std::function templateFactory; 29 | 30 | public: 31 | Context(JSONElement *_content, std::function _templateFactory); 32 | Context(Context *_parent, JSONElement *_content); 33 | Context(Context &isolate); 34 | 35 | JSONElement* find(std::string path); 36 | AMustacheTemplate* findTemplate(std::string key); 37 | }; 38 | 39 | /* 40 | Parses the mustache template from the string. 41 | 42 | Returns: A pointer to a New mustache template. 43 | Caller must delete the returned pointer. 44 | */ 45 | AMustacheTemplate *parse(std::string templ); 46 | std::string render(std::string templ, Context& context); 47 | std::string renderTemplate(AMustacheTemplate *templ, Context& context); 48 | } -------------------------------------------------------------------------------- /BH/Modules/AutoTele/ATIncludes/SyncObj.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | // SyncObj.h 3 | // 4 | // Abin (abinn32@yahoo.com) 5 | ////////////////////////////////////////////////////////////////////// 6 | 7 | #ifndef __SYNCOBJ_H__ 8 | #define __SYNCOBJ_H__ 9 | 10 | #include 11 | #include 12 | 13 | class CSyncObj 14 | { 15 | public: 16 | 17 | ///////////////////////////////////////////////////////////////// 18 | // Constructor & Destructor 19 | ///////////////////////////////////////////////////////////////// 20 | CSyncObj() { ::InitializeCriticalSection(&m_cs); IsLocked = false;} 21 | virtual ~CSyncObj() { ::DeleteCriticalSection(&m_cs); } 22 | 23 | ///////////////////////////////////////////////////////////////// 24 | // Public Operations 25 | ///////////////////////////////////////////////////////////////// 26 | void Lock() { ::EnterCriticalSection((LPCRITICAL_SECTION)&m_cs); IsLocked = true; } 27 | void Unlock() { ::LeaveCriticalSection((LPCRITICAL_SECTION)&m_cs); IsLocked = false; } 28 | 29 | bool IsLocked; 30 | 31 | private: 32 | 33 | ///////////////////////////////////////////////////////////////// 34 | // Private Member Data 35 | ///////////////////////////////////////////////////////////////// 36 | CRITICAL_SECTION m_cs; 37 | }; 38 | 39 | #endif // __SYNCOBJ_H__ 40 | -------------------------------------------------------------------------------- /BH/Drawing/Basic/Linehook/Linehook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Hook.h" 4 | 5 | namespace Drawing { 6 | class Linehook : public Hook { 7 | private: 8 | unsigned int color;//Color of the line hook 0-255. 9 | unsigned int x2, y2;//2 of the line hook. 10 | 11 | public: 12 | //Linehook Initaliztors, one for basic hooks and one for groups. 13 | Linehook(HookVisibility visiblity, unsigned int x, unsigned int y, unsigned int x2, unsigned int y2); 14 | Linehook(HookGroup* group, unsigned int x, unsigned int y, unsigned int x2, unsigned int y2); 15 | 16 | //Returns the color of the line hook. 17 | unsigned int GetColor(); 18 | 19 | //Sets the color of the line hook. 20 | void SetColor(unsigned int newColor); 21 | 22 | 23 | //Get the size of the line hook. 24 | unsigned int GetX2(); 25 | 26 | //Set the size of the x hook. 27 | void SetX2(unsigned int newX); 28 | 29 | //Filler to return nothing to base class. 30 | unsigned int GetXSize(); 31 | unsigned int GetYSize(); 32 | 33 | //Get the height of the line hook. 34 | unsigned int GetY2(); 35 | 36 | //Set the height of the line hook. 37 | void SetY2(unsigned int newY); 38 | 39 | //Draw the text. 40 | void OnDraw(); 41 | 42 | //Static line draw 43 | static bool Draw(unsigned int x, unsigned int y, unsigned int x2, unsigned int y2, unsigned int color); 44 | }; 45 | }; -------------------------------------------------------------------------------- /BH/Modules/ModuleManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | class Module; 7 | using namespace std; 8 | 9 | class ModuleManager { 10 | private: 11 | map moduleList; 12 | 13 | void FixName(std::string& name); 14 | 15 | public: 16 | ModuleManager(); 17 | ~ModuleManager(); 18 | 19 | // Module Management 20 | void Add(Module* module); 21 | Module* Get(string name); 22 | void Remove(Module* module); 23 | 24 | void LoadModules(); 25 | void UnloadModules(); 26 | void ReloadConfig(); 27 | void MpqLoaded(); 28 | 29 | bool UserInput(wchar_t* module, wchar_t* msg, bool fromGame); 30 | 31 | __event void OnLoop(); 32 | 33 | __event void OnGameJoin(); 34 | __event void OnGameExit(); 35 | 36 | __event void OnDraw(); 37 | __event void OnAutomapDraw(); 38 | __event void OnOOGDraw(); 39 | 40 | __event void OnLeftClick(bool up, int x, int y, bool* block); 41 | __event void OnRightClick(bool up, int x, int y, bool* block); 42 | __event void OnKey(bool up, BYTE key, LPARAM lParam, bool* block); 43 | 44 | __event void OnChatPacketRecv(BYTE* packet, bool* block); 45 | __event void OnRealmPacketRecv(BYTE* packet, bool* block); 46 | __event void OnGamePacketRecv(BYTE* packet, bool* block); 47 | 48 | __event void OnChatMsg(const char* user, const char* msg, bool fromGame, bool* block); 49 | }; 50 | -------------------------------------------------------------------------------- /ThirdParty/cpp-lru-cache/src/test.cpp: -------------------------------------------------------------------------------- 1 | #include "lrucache.hpp" 2 | #include "gtest/gtest.h" 3 | 4 | const int NUM_OF_TEST1_RECORDS = 100; 5 | const int NUM_OF_TEST2_RECORDS = 100; 6 | const int TEST2_CACHE_CAPACITY = 50; 7 | 8 | TEST(CacheTest, SimplePut) { 9 | cache::lru_cache cache_lru(1); 10 | cache_lru.put(7, 777); 11 | EXPECT_TRUE(cache_lru.exists(7)); 12 | EXPECT_EQ(777, cache_lru.get(7)); 13 | EXPECT_EQ(1, cache_lru.size()); 14 | } 15 | 16 | TEST(CacheTest, MissingValue) { 17 | cache::lru_cache cache_lru(1); 18 | EXPECT_THROW(cache_lru.get(7), std::range_error); 19 | } 20 | 21 | TEST(CacheTest1, KeepsAllValuesWithinCapacity) { 22 | cache::lru_cache cache_lru(TEST2_CACHE_CAPACITY); 23 | 24 | for (int i = 0; i < NUM_OF_TEST2_RECORDS; ++i) { 25 | cache_lru.put(i, i); 26 | } 27 | 28 | for (int i = 0; i < NUM_OF_TEST2_RECORDS - TEST2_CACHE_CAPACITY; ++i) { 29 | EXPECT_FALSE(cache_lru.exists(i)); 30 | } 31 | 32 | for (int i = NUM_OF_TEST2_RECORDS - TEST2_CACHE_CAPACITY; i < NUM_OF_TEST2_RECORDS; ++i) { 33 | EXPECT_TRUE(cache_lru.exists(i)); 34 | EXPECT_EQ(i, cache_lru.get(i)); 35 | } 36 | 37 | size_t size = cache_lru.size(); 38 | EXPECT_EQ(TEST2_CACHE_CAPACITY, size); 39 | } 40 | 41 | int main(int argc, char **argv) { 42 | ::testing::InitGoogleTest(&argc, argv); 43 | int ret = RUN_ALL_TESTS(); 44 | return ret; 45 | } 46 | -------------------------------------------------------------------------------- /BH/Modules/Gamefilter/Gamefilter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Module.h" 3 | #include 4 | #include 5 | #include 6 | 7 | struct GameListEntry 8 | { 9 | WORD wRequestId; 10 | DWORD dwIndex; 11 | BYTE bPlayers; 12 | DWORD dwStatus; 13 | std::string sGameName; 14 | std::string sGameDesc; 15 | }; 16 | struct Control; 17 | 18 | class Gamefilter : public Module { 19 | private: 20 | std::map bools; 21 | bool* showDiff; 22 | bool* showGs; 23 | 24 | public: 25 | static std::list gameList; 26 | static std::vector filterVector; 27 | static std::vector gServerVector; 28 | static Control* filterBox; 29 | static int refreshTime; 30 | 31 | Gamefilter() : Module("Gamefilter") {}; 32 | 33 | void OnLoad(); 34 | void OnUnload(); 35 | void LoadConfig(); 36 | 37 | void OnGameJoin(); 38 | void OnGameExit(); 39 | 40 | void OnRealmPacketRecv(BYTE* pPacket, bool* blockPacket); 41 | void OnOOGDraw(); 42 | 43 | std::map* GetBools() { return &bools; } 44 | 45 | static void CreateGamelist(); 46 | static void __stdcall DestroyGamelist(Control* pControl); 47 | static void BuildGameList(std::string sFilter); 48 | static BOOL __stdcall Filterbox_InputHandler(Control* pControl, DWORD dwLength, CHAR* pChar); 49 | static BOOL __stdcall Filterbox_ReturnHandler(wchar_t* wText); 50 | }; 51 | 52 | VOID D2MULTI_CreateGameBox_Interception(VOID); 53 | VOID D2MULTI_GameListRefresh_Interception(VOID); -------------------------------------------------------------------------------- /ThirdParty/cpp-lru-cache/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, lamerman 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of lamerman nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /BH/Modules/Module.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "ModuleManager.h" 4 | 5 | using namespace std; 6 | 7 | class Module { 8 | private: 9 | friend class ModuleManager; 10 | 11 | string name; 12 | bool active; 13 | 14 | void Load(); 15 | void Unload(); 16 | 17 | public: 18 | Module(string name); 19 | virtual ~Module(); 20 | 21 | string GetName() { return name; }; 22 | bool IsActive() { return active; }; 23 | 24 | // Module Events 25 | virtual void OnLoad() {}; 26 | virtual void OnUnload() {}; 27 | 28 | virtual void LoadConfig() {}; 29 | virtual void MpqLoaded() {}; 30 | 31 | virtual void OnLoop() {}; 32 | 33 | // Game Events 34 | virtual void OnGameJoin() {} 35 | virtual void OnGameExit() {}; 36 | 37 | // Drawing Events 38 | virtual void OnDraw() {}; 39 | virtual void OnAutomapDraw() {}; 40 | virtual void OnOOGDraw() {}; 41 | 42 | virtual void OnLeftClick(bool up, int x, int y, bool* block) {}; 43 | virtual void OnRightClick(bool up, int x, int y, bool* block) {}; 44 | virtual void OnKey(bool up, BYTE key, LPARAM lParam, bool* block) {}; 45 | 46 | virtual void OnChatPacketRecv(BYTE* packet, bool* block) {}; 47 | virtual void OnRealmPacketRecv(BYTE* packet, bool* block) {}; 48 | virtual void OnGamePacketRecv(BYTE* packet, bool* block) {}; 49 | 50 | __event void UserInput(const wchar_t* msg, bool fromGame, bool* block); 51 | virtual void OnUserInput(const wchar_t* msg, bool fromGame, bool* block) {}; 52 | virtual void OnChatMsg(const char* user, const char* msg, bool fromGame, bool* block) {}; 53 | }; 54 | -------------------------------------------------------------------------------- /BH/Modules/ChatColor/ChatColor.cpp: -------------------------------------------------------------------------------- 1 | #include "ChatColor.h" 2 | #include "../../BH.h" 3 | #include "../../D2Ptrs.h" 4 | #include "../../D2Stubs.h" 5 | 6 | void ChatColor::Init() { 7 | 8 | } 9 | 10 | void Print(DWORD color, char* format, ...) { 11 | va_list vaArgs; 12 | va_start(vaArgs, format); 13 | int len = _vscprintf(format, vaArgs) + 1; 14 | char* str = new char[len]; 15 | vsprintf_s(str, len, format, vaArgs); 16 | va_end(vaArgs); 17 | 18 | wchar_t* wstr = new wchar_t[len]; 19 | MultiByteToWideChar(CODE_PAGE, 0, str, -1, wstr, len); 20 | D2CLIENT_PrintGameString(wstr, color); 21 | delete[] wstr; 22 | 23 | delete[] str; 24 | } 25 | 26 | void ChatColor::OnGameJoin() { 27 | inGame = true; 28 | } 29 | 30 | void ChatColor::OnGameExit() { 31 | inGame = false; 32 | } 33 | 34 | void ChatColor::OnLoad() { 35 | LoadConfig(); 36 | } 37 | 38 | void ChatColor::LoadConfig() { 39 | whisperColors.clear(); 40 | 41 | BH::config->ReadAssoc("Whisper Color", whisperColors); 42 | } 43 | 44 | void ChatColor::OnChatPacketRecv(BYTE* packet, bool* block) { 45 | if (packet[1] == 0x0F && inGame) { 46 | unsigned int event_id = *(unsigned short int*)&packet[4]; 47 | 48 | if (event_id == 4) { 49 | const char* from = (const char*)&packet[28]; 50 | unsigned int fromLen = strlen(from); 51 | 52 | const char* message = (const char*)&packet[28 + fromLen + 1]; 53 | unsigned int messageLen = strlen(message); 54 | 55 | bool replace = false; 56 | int color = 0; 57 | if (whisperColors.find(from) != whisperColors.end()) { 58 | replace = true; 59 | color = whisperColors[from]; 60 | } 61 | 62 | if (replace) { 63 | *block = true; 64 | 65 | Print(color, "%s | %s", from, message); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /BH/Drawing/Advanced/Combohook/Combohook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../../Hook.h" 4 | 5 | namespace Drawing { 6 | class Combohook : public Hook { 7 | private: 8 | std::vector options; 9 | unsigned int xSize; 10 | unsigned int font; 11 | unsigned int* currentIndex; 12 | bool active; 13 | public: 14 | Combohook(HookVisibility visibility, unsigned int x, unsigned int y, unsigned int xSize, unsigned int* currentIndex, std::vector options); 15 | Combohook(HookGroup* group, unsigned int x, unsigned int y, unsigned int xSize, unsigned int* currentIndex, std::vector options); 16 | 17 | std::vector GetOptions() { return options; }; 18 | unsigned int NewOption(std::string opt) { Lock(); options.push_back(opt); Unlock(); return options.size() - 1; }; 19 | unsigned int GetSelectedIndex() { return *currentIndex; }; 20 | void SetSelectedIndex(unsigned int index) { if (index > options.size()) { return; } Lock(); *currentIndex = index; Unlock(); }; 21 | 22 | unsigned int GetFont() { return font; }; 23 | void SetFont(unsigned int newFont) { Lock(); font = newFont; Unlock(); }; 24 | 25 | unsigned int GetXSize() { return xSize; }; 26 | void SetXSize(unsigned int size) { Lock(); xSize = size; Unlock(); }; 27 | 28 | unsigned int GetYSize() { unsigned int height[] = {10,11,18,24,10,13,7,13,10,12,8,8,7,12}; return height[GetFont()]; }; 29 | 30 | bool OnLeftClick(bool up, unsigned int x, unsigned int y); 31 | void OnDraw(); 32 | 33 | bool InHook(unsigned int nx, unsigned int ny) { return nx >= GetX() && ny >= GetY() && nx <= GetX() + GetXSize() + 5 && ny <= GetY() + GetYSize() + 3; }; 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /BH.Injector/BH.Injector.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 10 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 11 | 12 | 13 | {5e07673e-636b-4741-9ba7-5809f08220df} 14 | 15 | 16 | 17 | 18 | Source Files 19 | 20 | 21 | cInjector 22 | 23 | 24 | Common Files 25 | 26 | 27 | Source Files 28 | 29 | 30 | 31 | 32 | Source Files 33 | 34 | 35 | cInjector 36 | 37 | 38 | Common Files 39 | 40 | 41 | Source Files 42 | 43 | 44 | -------------------------------------------------------------------------------- /BH/Modules/StashExport/StashExport.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Module.h" 3 | #include "../../Constants.h" 4 | #include "../../Config.h" 5 | #include "../../Drawing.h" 6 | #include "../../JSONObject.h" 7 | #include "../../Mustache.h" 8 | 9 | #define MAX_FUNCTION 23 10 | 11 | struct UnitAny; 12 | 13 | struct IdNamePair{ 14 | int id; 15 | std::string name; 16 | }; 17 | 18 | class StashExport : public Module { 19 | private: 20 | 21 | string dfltExprt; 22 | map mustaches; 23 | unsigned int exportGear; 24 | unsigned int exportType; 25 | static UnitAny* viewingUnit; 26 | Drawing::UITab* settingsTab; 27 | std::vector options; 28 | 29 | static void fillStats(JSONArray* statsArray, JSONObject *itemDef, UnitAny *pItem, std::string codeKey, std::string paramKey, std::string minKey, std::string maxKey, int maxProps); 30 | public: 31 | static map Toggles; 32 | static map> MustacheTemplates; 33 | 34 | StashExport() : Module("StashExport"), exportType(0) { dfltExprt = "json"; }; 35 | 36 | void OnLoad(); 37 | void OnUnload(); 38 | 39 | void LoadConfig(); 40 | 41 | void OnLoop(); 42 | void OnKey(bool up, BYTE key, LPARAM lParam, bool* block); 43 | void WriteStash(); 44 | std::map* GetToggles() { return &Toggles; } 45 | static void GetItemInfo(UnitAny* pItem, JSONObject* pBuffer); 46 | static JSONObject* getStatEntry(WORD statId, WORD statId2, DWORD statVal, DWORD min, DWORD max); 47 | }; 48 | 49 | void ItemDesc_Interception(); 50 | 51 | std::function STAT_FUNCTIONS[]; 52 | char* QUALITY_NAMES[]; 53 | IdNamePair NODE_PAGES[]; 54 | IdNamePair CLASS_NAMES[]; 55 | IdNamePair SKILL_TABS[]; 56 | -------------------------------------------------------------------------------- /BH/MPQInit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "Constants.h" 10 | #include "Common.h" 11 | #include "D2Structs.h" 12 | 13 | /* 14 | * MPQInit handles the data we can initialize from MPQ files, provided we 15 | * are able to load StormLib. It also provides defaults in case we cannot 16 | * read the MPQ archive. 17 | */ 18 | 19 | extern unsigned int STAT_MAX; 20 | extern unsigned int SKILL_MAX; 21 | 22 | // Item attributes from ItemTypes.txt and Weapon/Armor/Misc.txt 23 | struct ItemAttributes { 24 | std::string name; 25 | char code[4]; 26 | std::string category; 27 | BYTE width; 28 | BYTE height; 29 | BYTE stackable; 30 | BYTE useable; 31 | BYTE throwable; 32 | BYTE itemLevel; // 1=normal, 2=exceptional, 3=elite 33 | BYTE unusedFlags; 34 | unsigned int flags; 35 | unsigned int flags2; 36 | BYTE qualityLevel; 37 | BYTE magicLevel; 38 | }; 39 | 40 | // Properties from ItemStatCost.txt that we need for parsing incoming 0x9c packets, among other things 41 | struct StatProperties { 42 | std::string name; 43 | BYTE saveBits; 44 | BYTE saveParamBits; 45 | BYTE saveAdd; 46 | BYTE op; 47 | BYTE sendParamBits; 48 | unsigned short ID; 49 | }; 50 | 51 | struct CharStats { 52 | int toHitFactor; 53 | }; 54 | 55 | extern std::vector AllStatList; 56 | extern std::unordered_map StatMap; 57 | extern std::vector CharList; 58 | extern std::map ItemAttributeMap; 59 | extern std::map InventoryLayoutMap; 60 | 61 | 62 | #define STAT_NUMBER(name) (StatMap[name]->ID) 63 | 64 | bool IsInitialized(); 65 | void InitializeMPQData(); 66 | -------------------------------------------------------------------------------- /BH/Task.cpp: -------------------------------------------------------------------------------- 1 | #include "Task.h" 2 | #include 3 | #include 4 | #include 5 | 6 | class TaskHolder { 7 | public: 8 | std::function task; 9 | 10 | TaskHolder(std::function _task){ 11 | task = _task; 12 | } 13 | }; 14 | 15 | class WorkerThread { 16 | public: 17 | bool canceled; 18 | HANDLE tHandle; 19 | 20 | WorkerThread() : 21 | canceled(false), 22 | tHandle(NULL){ 23 | } 24 | 25 | ~WorkerThread(){ 26 | canceled = true; 27 | CloseHandle(tHandle); 28 | } 29 | }; 30 | 31 | Concurrency::concurrent_queue taskQueue; 32 | std::vector> threadPool; 33 | HANDLE waitHandle = NULL; 34 | 35 | namespace Task { 36 | DWORD WINAPI QueueThread(void* arg){ 37 | WorkerThread *token = (WorkerThread*)arg; 38 | 39 | TaskHolder *t; 40 | while (!token->canceled){ 41 | WaitForSingleObject(waitHandle, 2000); 42 | if (token->canceled) break; 43 | 44 | if (taskQueue.try_pop(t)){ 45 | if (!taskQueue.empty()) { 46 | // Let the next task start while this one is processing 47 | SetEvent(waitHandle); 48 | } 49 | 50 | t->task(); 51 | delete t; 52 | } 53 | } 54 | return 0; 55 | } 56 | 57 | void InitializeThreadPool(int size){ 58 | waitHandle = CreateEvent(NULL, false, false, NULL); 59 | 60 | for (int i = 0; i < size; i++){ 61 | WorkerThread *t = new WorkerThread(); 62 | 63 | HANDLE tHandle = CreateThread(0, 0, QueueThread, (void*)t, 0, 0); 64 | t->tHandle = tHandle; 65 | threadPool.push_back(std::unique_ptr(t)); 66 | 67 | } 68 | } 69 | 70 | void StopThreadPool(){ 71 | CloseHandle(waitHandle); 72 | threadPool.clear(); 73 | } 74 | 75 | void Enqueue(std::function task){ 76 | taskQueue.push(new TaskHolder(task)); 77 | SetEvent(waitHandle); 78 | } 79 | } -------------------------------------------------------------------------------- /BH/Drawing/Advanced/Checkhook/Checkhook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../../Constants.h" 3 | #include "../../Hook.h" 4 | #include "../../Basic/Texthook/Texthook.h" 5 | 6 | namespace Drawing { 7 | class Checkhook : public Hook { 8 | private: 9 | bool* state;//Holds if the checkbox is checked. 10 | TextColor color, hoverColor;//Holds text color/hover color. 11 | std::string text;//The text beside the checkhook. 12 | public: 13 | Checkhook(HookVisibility visibility, unsigned int x, unsigned int y, bool* checked, std::string formatString, ...); 14 | Checkhook(HookGroup* group, unsigned int x, unsigned int y, bool* checked, std::string formatString, ...); 15 | 16 | //Returns if the check is checked. 17 | bool IsChecked(); 18 | 19 | //Sets if it is checked or not. 20 | void SetState(bool checked); 21 | 22 | //Returns the text color. 23 | TextColor GetTextColor(); 24 | 25 | //Returns the hover color 26 | TextColor GetHoverColor(); 27 | 28 | //Sets the text color 29 | void SetTextColor(TextColor newColor); 30 | 31 | //Sets the hover color 32 | void SetHoverColor(TextColor newColor); 33 | 34 | //Gets the text 35 | std::string GetText(); 36 | 37 | //Sets the text 38 | void SetText(std::string formatString, ...); 39 | 40 | //Returns the total width of the check hook 41 | unsigned int GetXSize(); 42 | 43 | //Returns the total hright of the check hook 44 | unsigned int GetYSize(); 45 | 46 | //Draw the text. 47 | void OnDraw(); 48 | 49 | //Checks if we've been clicked on and calls the handler if so. 50 | bool OnLeftClick(bool up, unsigned int x, unsigned int y); 51 | 52 | //Checks if we've been clicked on and calls the handler if so. 53 | bool OnRightClick(bool up, unsigned int x, unsigned int y); 54 | }; 55 | }; -------------------------------------------------------------------------------- /BH/D2Stubs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "D2Ptrs.h" 3 | 4 | DWORD __declspec(naked) __fastcall D2CLIENT_GetUnitName_STUB(DWORD UnitAny) 5 | { 6 | __asm 7 | { 8 | mov eax, ecx 9 | jmp D2CLIENT_GetUnitName_I 10 | } 11 | } 12 | 13 | DWORD __declspec(naked) __fastcall D2CLIENT_InitAutomapLayer(DWORD nLayerNo) 14 | { 15 | __asm 16 | { 17 | push eax; 18 | mov eax, ecx; 19 | call D2CLIENT_InitAutomapLayer_I; 20 | pop eax; 21 | ret; 22 | } 23 | } 24 | 25 | DWORD __declspec(naked) __fastcall TestPvpFlag_STUB(DWORD planum1, DWORD planum2, DWORD flagmask) 26 | { 27 | __asm 28 | { 29 | push esi; 30 | push [esp+8]; 31 | mov esi, edx; 32 | mov edx, ecx; 33 | call D2CLIENT_TestPvpFlag_I; 34 | pop esi; 35 | ret 4; 36 | } 37 | } 38 | 39 | DWORD __declspec(naked) __fastcall D2CLIENT_GetLevelName_STUB(DWORD levelId) 40 | { 41 | __asm 42 | { 43 | mov esi, ecx 44 | jmp D2CLIENT_GetLevelName_I 45 | } 46 | } 47 | 48 | DWORD __declspec(naked) __fastcall D2CLIENT_GetUIVar_STUB(DWORD varno) 49 | { 50 | __asm 51 | { 52 | mov eax, ecx; 53 | jmp D2CLIENT_GetUiVar_I; 54 | } 55 | } 56 | 57 | __declspec(naked) CellFile* __fastcall D2CLIENT_LoadUiImage(CHAR* szPath) 58 | { 59 | __asm 60 | { 61 | MOV EAX, ECX 62 | PUSH 0 63 | CALL D2CLIENT_LoadUiImage_I 64 | RETN 65 | } 66 | } 67 | 68 | DWORD __declspec(naked) __fastcall D2CLIENT_ClickParty_ASM(RosterUnit* RosterUnit, DWORD Mode) 69 | { 70 | __asm 71 | { 72 | mov eax, ecx 73 | jmp D2CLIENT_ClickParty_I 74 | } 75 | } 76 | 77 | void __declspec(naked) __fastcall D2CLIENT_PlaySound(int SoundNo) 78 | { 79 | __asm 80 | { 81 | push ebx 82 | mov ebx, ecx 83 | push 0 84 | push 0 85 | push 0 86 | push 0 87 | call D2CLIENT_PlaySound_I 88 | pop ebx; 89 | ret 90 | } 91 | } -------------------------------------------------------------------------------- /BH.Injector/cInjector.h: -------------------------------------------------------------------------------- 1 | /* 2 | cInjector - Class to inject/unload DLLs 3 | Copyright (C) 2009 Sheppard 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Affero General Public License as 7 | published by the Free Software Foundation, either version 3 of the 8 | License, or (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Affero General Public License for more details. 14 | 15 | You should have received a copy of the GNU Affero General Public License 16 | along with this program. If not, see . 17 | 18 | */ 19 | #pragma once 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace std; 25 | 26 | class cInjector 27 | { 28 | public: 29 | static BOOL EnableDebugPriv(VOID); 30 | static BOOL InjectDLL(DWORD dwPid, wstring wDLLPath); 31 | static BOOL InjectDLL(HWND hwnd, wstring wDLLPath); 32 | 33 | static BOOL UnloadDLL(DWORD dwPid, HMODULE hDll); 34 | static BOOL UnloadDLL(HWND hwnd, HMODULE hDll); 35 | 36 | static INT InjectToProcessByDLL(wstring wProcessDll, wstring wDllName); 37 | static INT InjectToProcess(wstring wProcName, wstring wDllName); 38 | 39 | static BOOL RunRemoteProc(DWORD dwPid, wstring wDllName, string wProcName); 40 | static BOOL RunRemoteProc(HWND hwnd, wstring wDllName, string wProcName); 41 | 42 | static HMODULE GetRemoteDll(DWORD dwPid, wstring wDllName); 43 | static HMODULE GetRemoteDll(HWND hwnd, wstring wDllName); 44 | }; 45 | BOOL IsUserAdmin(VOID); 46 | bool FindInjectedModule(DWORD processID); 47 | -------------------------------------------------------------------------------- /BH/Drawing/Basic/Boxhook/Boxhook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Hook.h" 4 | 5 | namespace Drawing { 6 | class Boxhook : public Hook { 7 | private: 8 | unsigned int color;//Color of the box hook 0-255. 9 | unsigned int xSize, ySize;//Size of the box hook. 10 | BoxTrans transparency;//Type of transparency. 11 | 12 | public: 13 | //Boxhook Initaliztors, one for basic hooks and one for groups. 14 | Boxhook(HookVisibility visiblity, unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize); 15 | Boxhook(HookGroup* group, unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize); 16 | 17 | //Returns the color of the box hook. 18 | unsigned int GetColor(); 19 | 20 | //Sets the color of the box hook. 21 | void SetColor(unsigned int newColor); 22 | 23 | 24 | //Get the size of the box hook. 25 | unsigned int GetXSize(); 26 | 27 | //Set the size of the x hook. 28 | void SetXSize(unsigned int newX); 29 | 30 | 31 | //Get the height of the box hook. 32 | unsigned int GetYSize(); 33 | 34 | //Set the height of the box hook. 35 | void SetYSize(unsigned int newY); 36 | 37 | 38 | //Returns the type of transparency used. 39 | BoxTrans GetTransparency(); 40 | 41 | //Set the box transparency. 42 | void SetTransparency(BoxTrans trans); 43 | 44 | //Draw the text. 45 | void OnDraw(); 46 | 47 | //Checks if we've been clicked on and calls the handler if so. 48 | bool OnLeftClick(bool up, unsigned int x, unsigned int y); 49 | 50 | //Checks if we've been clicked on and calls the handler if so. 51 | bool OnRightClick(bool up, unsigned int x, unsigned int y); 52 | 53 | //Static box draw 54 | static bool Draw(unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize, unsigned int color, BoxTrans trans); 55 | }; 56 | }; -------------------------------------------------------------------------------- /BH/TableReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "JSONObject.h" 3 | #include 4 | 5 | class TableReader; 6 | class Tables; 7 | 8 | class Table { 9 | friend class TableReader; 10 | friend class Tables; 11 | private: 12 | std::unique_ptr data; 13 | std::vector headers; 14 | void addEntry(JSONObject *entry); 15 | void removeWhere(std::function predicate); 16 | public: 17 | Table() : data(new JSONArray()){} 18 | Table(std::string filePath); 19 | 20 | JSONObject* findEntry(std::function predicate); 21 | JSONObject* findEntry(std::string field, std::string value); 22 | JSONObject* binarySearch(std::string field, int value); 23 | JSONObject* entryAt(int index); 24 | int size(); 25 | 26 | bool dump(std::string filePath); 27 | }; 28 | 29 | class TableReader 30 | { 31 | private: 32 | static bool readTextTable(std::string filePath, Table &table); 33 | static bool readTbl(std::string filePath, Table &table); 34 | public: 35 | static bool readTable(std::string filePath, Table &table); 36 | static bool loadMPQData(std::string archiveName, Table &table); 37 | }; 38 | 39 | class Tables { 40 | private: 41 | static bool init; 42 | 43 | Tables(){} 44 | public: 45 | static bool initTables(); 46 | 47 | static Table ItemStatCost; 48 | static Table ItemTypes; 49 | static Table Properties; 50 | static Table Runewords; 51 | static Table UniqueItems; 52 | static Table SetItems; 53 | static Table Skills; 54 | static Table MagicPrefix; 55 | static Table MagicSuffix; 56 | static Table RarePrefix; 57 | static Table RareSuffix; 58 | static Table CharStats; 59 | /*static Table Armor; 60 | static Table Weapons; 61 | static Table Misc;*/ 62 | 63 | static std::string getString(int index); 64 | 65 | static bool isInitialized(); 66 | }; 67 | 68 | inline 69 | void Table::addEntry(JSONObject *entry){ 70 | data->add(entry); 71 | } 72 | 73 | inline 74 | JSONObject* Table::entryAt(int index){ 75 | return data->getObject(index); 76 | } 77 | -------------------------------------------------------------------------------- /BH/Modules/ScreenInfo/ScreenInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../D2Structs.h" 3 | #include "../Module.h" 4 | #include "../../Config.h" 5 | #include "../../Drawing.h" 6 | #include 7 | 8 | 9 | struct AutomapReplace { 10 | std::string key; 11 | std::string value; 12 | }; 13 | 14 | struct StateCode { 15 | std::string name; 16 | unsigned int value; 17 | }; 18 | 19 | struct StateWarning { 20 | std::string name; 21 | ULONGLONG startTicks; 22 | StateWarning(string n, ULONGLONG ticks) : name(n), startTicks(ticks) {} 23 | }; 24 | 25 | class ScreenInfo : public Module { 26 | private: 27 | map SkillWarnings; 28 | std::vector automapInfo; 29 | std::map SkillWarningMap; 30 | std::deque CurrentWarnings; 31 | Drawing::Texthook* bhText; 32 | Drawing::Texthook* mpqVersionText; 33 | Drawing::Texthook* d2VersionText; 34 | DWORD gameTimer; 35 | 36 | int packetRequests; 37 | ULONGLONG warningTicks; 38 | ULONGLONG packetTicks; 39 | bool MephistoBlocked; 40 | bool DiabloBlocked; 41 | bool BaalBlocked; 42 | bool ReceivedQuestPacket; 43 | DWORD startExperience; 44 | int startLevel; 45 | 46 | void ScreenInfo::drawExperienceInfo(); 47 | public: 48 | static map Toggles; 49 | 50 | ScreenInfo() : 51 | Module("Screen Info"), warningTicks(BHGetTickCount()), packetRequests(0), 52 | MephistoBlocked(false), DiabloBlocked(false), BaalBlocked(false), ReceivedQuestPacket(false), 53 | startExperience(0), startLevel(0) {}; 54 | 55 | void OnLoad(); 56 | void LoadConfig(); 57 | void MpqLoaded(); 58 | void OnKey(bool up, BYTE key, LPARAM lParam, bool* block); 59 | void OnGameJoin(); 60 | void OnGameExit(); 61 | 62 | void OnRightClick(bool up, int x, int y, bool* block); 63 | void OnDraw(); 64 | void OnAutomapDraw(); 65 | void OnGamePacketRecv(BYTE* packet, bool *block); 66 | }; 67 | 68 | StateCode GetStateCode(unsigned int nKey); 69 | StateCode GetStateCode(const char* name); 70 | long long ExpByLevel[]; 71 | -------------------------------------------------------------------------------- /BH/Drawing/Basic/Framehook/Framehook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Hook.h" 4 | 5 | namespace Drawing { 6 | class Framehook : public Hook { 7 | private: 8 | unsigned int color;//Color of the frame hook 0-255. 9 | unsigned int xSize, ySize;//Size of the frame hook. 10 | BoxTrans transparency;//Type of transparency. 11 | 12 | public: 13 | //Framehook Initaliztors, one for basic hooks and one for groups. 14 | Framehook(HookVisibility visiblity, unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize); 15 | Framehook(HookGroup* group, unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize); 16 | 17 | //Returns the color of the frame hook. 18 | unsigned int GetColor(); 19 | 20 | //Sets the color of the frame hook. 21 | void SetColor(unsigned int newColor); 22 | 23 | 24 | //Get the size of the frame hook. 25 | unsigned int GetXSize(); 26 | 27 | //Set the size of the x hook. 28 | void SetXSize(unsigned int newX); 29 | 30 | 31 | //Get the height of the frame hook. 32 | unsigned int GetYSize(); 33 | 34 | //Set the height of the frame hook. 35 | void SetYSize(unsigned int newY); 36 | 37 | 38 | //Returns the type of transparency used. 39 | BoxTrans GetTransparency(); 40 | 41 | //Set the frame transparency. 42 | void SetTransparency(BoxTrans trans); 43 | 44 | //ASM Stub to move eax to ecx. 45 | static DWORD _fastcall Framehook::DrawRectStub(RECT *pRect); 46 | 47 | //Draw the text. 48 | void OnDraw(); 49 | 50 | //Checks if we've been clicked on and calls the handler if so. 51 | bool OnLeftClick(bool up, unsigned int x, unsigned int y); 52 | 53 | //Checks if we've been clicked on and calls the handler if so. 54 | bool OnRightClick(bool up, unsigned int x, unsigned int y); 55 | 56 | //Static Draw Function 57 | static bool Draw(unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize, unsigned int color, BoxTrans trans); 58 | }; 59 | }; -------------------------------------------------------------------------------- /ThirdParty/cpp-lru-cache/include/lrucache.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * File: lrucache.hpp 3 | * Author: Alexander Ponomarev 4 | * 5 | * Created on June 20, 2013, 5:09 PM 6 | */ 7 | 8 | #ifndef _LRUCACHE_HPP_INCLUDED_ 9 | #define _LRUCACHE_HPP_INCLUDED_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace cache { 17 | 18 | template 19 | class lru_cache { 20 | public: 21 | typedef typename std::pair key_value_pair_t; 22 | typedef typename std::list::iterator list_iterator_t; 23 | 24 | lru_cache(size_t max_size) : 25 | _max_size(max_size) { 26 | } 27 | 28 | void put(const key_t& key, const value_t& value) { 29 | auto it = _cache_items_map.find(key); 30 | _cache_items_list.push_front(key_value_pair_t(key, value)); 31 | if (it != _cache_items_map.end()) { 32 | _cache_items_list.erase(it->second); 33 | _cache_items_map.erase(it); 34 | } 35 | _cache_items_map[key] = _cache_items_list.begin(); 36 | 37 | if (_cache_items_map.size() > _max_size) { 38 | auto last = _cache_items_list.end(); 39 | last--; 40 | _cache_items_map.erase(last->first); 41 | _cache_items_list.pop_back(); 42 | } 43 | } 44 | 45 | const value_t& get(const key_t& key) { 46 | auto it = _cache_items_map.find(key); 47 | if (it == _cache_items_map.end()) { 48 | throw std::range_error("There is no such key in cache"); 49 | } else { 50 | _cache_items_list.splice(_cache_items_list.begin(), _cache_items_list, it->second); 51 | return it->second->second; 52 | } 53 | } 54 | 55 | bool exists(const key_t& key) const { 56 | return _cache_items_map.find(key) != _cache_items_map.end(); 57 | } 58 | 59 | size_t size() const { 60 | return _cache_items_map.size(); 61 | } 62 | 63 | private: 64 | std::list _cache_items_list; 65 | std::unordered_map _cache_items_map; 66 | size_t _max_size; 67 | }; 68 | 69 | } // namespace cache 70 | 71 | #endif /* _LRUCACHE_HPP_INCLUDED_ */ 72 | 73 | -------------------------------------------------------------------------------- /BH.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BH", "BH\BH.vcxproj", "{E549AF63-EF8D-4054-A95B-9C4AE6F51029}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BH.Injector", "BH.Injector\BH.Injector.vcxproj", "{0C10FFDA-E6F8-4180-BF7D-8A423A171748}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {E549AF63-EF8D-4054-A95B-9C4AE6F51029} = {E549AF63-EF8D-4054-A95B-9C4AE6F51029} 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Win32 = Debug|Win32 16 | Packaging|Win32 = Packaging|Win32 17 | Release|Win32 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {E549AF63-EF8D-4054-A95B-9C4AE6F51029}.Debug|Win32.ActiveCfg = Debug|Win32 21 | {E549AF63-EF8D-4054-A95B-9C4AE6F51029}.Debug|Win32.Build.0 = Debug|Win32 22 | {E549AF63-EF8D-4054-A95B-9C4AE6F51029}.Packaging|Win32.ActiveCfg = Packaging|Win32 23 | {E549AF63-EF8D-4054-A95B-9C4AE6F51029}.Packaging|Win32.Build.0 = Packaging|Win32 24 | {E549AF63-EF8D-4054-A95B-9C4AE6F51029}.Release|Win32.ActiveCfg = Release|Win32 25 | {E549AF63-EF8D-4054-A95B-9C4AE6F51029}.Release|Win32.Build.0 = Release|Win32 26 | {0C10FFDA-E6F8-4180-BF7D-8A423A171748}.Debug|Win32.ActiveCfg = Debug|Win32 27 | {0C10FFDA-E6F8-4180-BF7D-8A423A171748}.Debug|Win32.Build.0 = Debug|Win32 28 | {0C10FFDA-E6F8-4180-BF7D-8A423A171748}.Packaging|Win32.ActiveCfg = Packaging|Win32 29 | {0C10FFDA-E6F8-4180-BF7D-8A423A171748}.Packaging|Win32.Build.0 = Packaging|Win32 30 | {0C10FFDA-E6F8-4180-BF7D-8A423A171748}.Release|Win32.ActiveCfg = Release|Win32 31 | {0C10FFDA-E6F8-4180-BF7D-8A423A171748}.Release|Win32.Build.0 = Release|Win32 32 | EndGlobalSection 33 | GlobalSection(SolutionProperties) = preSolution 34 | HideSolutionNode = FALSE 35 | EndGlobalSection 36 | EndGlobal 37 | -------------------------------------------------------------------------------- /BH/Drawing/Stats/StatsDisplay.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "../Hook.h" 8 | #include "../../MPQInit.h" 9 | #include "../../Drawing.h" 10 | #include "../../Config.h" 11 | 12 | struct DisplayedStat { 13 | std::string name; 14 | int value; 15 | bool useValue; 16 | }; 17 | 18 | namespace Drawing { 19 | class StatsDisplay; 20 | 21 | class StatsDisplay : public HookGroup { 22 | private: 23 | std::map Toggles; 24 | static StatsDisplay *display; 25 | std::string name; 26 | unsigned int x, y, xSize, ySize; 27 | unsigned int statsKey; 28 | bool active, minimized; 29 | CRITICAL_SECTION crit; 30 | std::vector customStats; 31 | public: 32 | StatsDisplay(std::string name); 33 | ~StatsDisplay(); 34 | 35 | void LoadConfig(); 36 | 37 | void Lock() { EnterCriticalSection(&crit); }; 38 | void Unlock() { LeaveCriticalSection(&crit); }; 39 | 40 | std::string GetName() { return name; }; 41 | unsigned int GetX() { return x; }; 42 | unsigned int GetY() { return y; }; 43 | unsigned int GetXSize() { return xSize; }; 44 | unsigned int GetYSize() { return ySize; }; 45 | bool IsActive() { return active; }; 46 | bool IsMinimized() { return minimized; }; 47 | 48 | bool InRange(unsigned int x, unsigned int y); 49 | 50 | void SetX(unsigned int newX); 51 | void SetY(unsigned int newY); 52 | void SetXSize(unsigned int newXSize); 53 | void SetYSize(unsigned int newYSize); 54 | void SetName(std::string newName) { Lock(); name = newName; Unlock(); }; 55 | void SetActive(bool newState) { Lock(); active = newState; Unlock(); }; 56 | void SetMinimized(bool newState) { Lock(); minimized = newState; Unlock(); }; 57 | 58 | void OnDraw(); 59 | static void Draw(); 60 | 61 | bool OnClick(bool up, unsigned int mouseX, unsigned int mouseY); 62 | static bool Click(bool up, unsigned int mouseX, unsigned int mouseY); 63 | 64 | bool OnKey(bool up, BYTE key, LPARAM lParam); 65 | static bool KeyClick(bool bUp, BYTE bKey, LPARAM lParam); 66 | }; 67 | }; 68 | -------------------------------------------------------------------------------- /BH/Drawing/Basic/Crosshook/Crosshook.cpp: -------------------------------------------------------------------------------- 1 | #include "Crosshook.h" 2 | #include "../../../Common.h" 3 | #include "../../../D2Ptrs.h" 4 | 5 | using namespace std; 6 | using namespace Drawing; 7 | 8 | /* Basic Hook Initializer 9 | * Used for just drawing basic crosses of screen. 10 | */ 11 | Crosshook::Crosshook(HookVisibility visiblity, unsigned int x, unsigned int y) : 12 | Hook(visiblity, x, y) { 13 | //Set the extra variables 14 | SetColor(0); 15 | } 16 | 17 | /* Group Hook Initializer 18 | * Used in conjuction with other basic hooks to create an advanced hook. 19 | */ 20 | Crosshook::Crosshook(HookGroup* group, unsigned int x, unsigned int y) : 21 | Hook(group, x, y) { 22 | //Set the extra variables 23 | SetColor(0); 24 | } 25 | 26 | /* GetColor() 27 | * Returns the color of the crosshook. 28 | */ 29 | unsigned int Crosshook::GetColor() { 30 | return color; 31 | } 32 | 33 | /* SetColor(unsigned int color) 34 | * Sets the color of the crosshook. 35 | */ 36 | void Crosshook::SetColor(unsigned int newColor) { 37 | if (newColor < 0 || newColor > 255) 38 | return; 39 | Lock(); 40 | color = newColor; 41 | Unlock(); 42 | } 43 | 44 | /* Get(X/Y)Size() 45 | * Used by click handlers, fuck clicking crosss. 46 | */ 47 | unsigned int Crosshook::GetXSize() { return 0; }; 48 | unsigned int Crosshook::GetYSize() { return 0; }; 49 | 50 | 51 | /* OnDraw() 52 | * Draws the cross 53 | */ 54 | void Crosshook::OnDraw() { 55 | if (!IsActive()) 56 | return; 57 | 58 | Lock(); 59 | CHAR szLines[][2] = {0,-2, 4,-4, 8,-2, 4,0, 8,2, 4,4, 0,2, -4,4, -8,2, -4,0, -8,-2, -4,-4, 0,-2}; 60 | for(unsigned int x = 0; x < 12; x++) 61 | D2GFX_DrawLine(GetX() + szLines[x][0], GetY() + szLines[x][1], GetX() + szLines[x+1][0], GetY() + szLines[x+1][1], GetColor(), -1); 62 | Unlock(); 63 | } 64 | 65 | bool Crosshook::Draw(unsigned int x, unsigned int y, unsigned int color) { 66 | CHAR szLines[][2] = {0,-2, 4,-4, 8,-2, 4,0, 8,2, 4,4, 0,2, -4,4, -8,2, -4,0, -8,-2, -4,-4, 0,-2}; 67 | for(unsigned int n = 0; n < 12; n++) 68 | D2GFX_DrawLine(x + szLines[n][0], y + szLines[n][1], x + szLines[n+1][0], y + szLines[n+1][1], color, -1); 69 | return true; 70 | } -------------------------------------------------------------------------------- /BH/Modules/AutoTele/AutoTele.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../Constants.h" 3 | #include "../../D2Ptrs.h" 4 | #include "../Module.h" 5 | #include "../../Drawing.h" 6 | #include "../../Config.h" 7 | #include "ATIncludes\ArrayEx.h" 8 | 9 | typedef struct Vector_t 10 | { 11 | unsigned int dwType; 12 | unsigned int Id; 13 | unsigned int Id2; 14 | unsigned int Area; 15 | } Vector; 16 | 17 | class AutoTele : public Module { 18 | private: 19 | std::map Toggles; 20 | unsigned int NextKey, OtherKey, WPKey, PrevKey; 21 | unsigned int Colors[6]; 22 | Drawing::UITab* settingsTab; 23 | 24 | int Try; 25 | POINT End; 26 | DWORD _timer, _timer2, _InteractTimer; 27 | bool SetInteract, SetTele, CastTele, TeleActive, DoInteract; 28 | DWORD InteractType, InteractId; 29 | Room2* InteractRoom; 30 | DWORD LastArea; 31 | POINT Vectors[5]; 32 | CArrayEx TPath; 33 | HANDLE LoadHandle; 34 | 35 | //functions 36 | DWORD GetPlayerArea(); 37 | void ManageTele(Vector T); 38 | int MakePath(int x, int y, DWORD Areas[], DWORD count, bool MoveThrough); 39 | POINT FindPresetLocation(DWORD dwType, DWORD dwTxtFileNo, DWORD Area); 40 | bool GetSkill(WORD wSkillId); 41 | bool SetSkill(WORD wSkillId, bool Left); 42 | void PrintText(DWORD Color, char *szText, ...); 43 | bool CastOnMap(WORD x, WORD y, bool Left); 44 | bool Interact(DWORD UnitId, DWORD UnitType); 45 | DWORD GetUnitByXY(DWORD X, DWORD Y, Room2* pRoom); 46 | bool WaitingForMapData(); 47 | 48 | public: 49 | AutoTele() : Module("AutoTele"), LoadHandle(NULL) {}; 50 | void OnLoad(); 51 | void LoadConfig(); 52 | void OnLoop(); 53 | void OnAutomapDraw(); 54 | void OnKey(bool up, BYTE key, LPARAM lParam, bool* block); 55 | void OnGamePacketRecv(BYTE* packet, bool* block); 56 | 57 | std::map* GetToggles() { return &Toggles; } 58 | void GetVectors(); 59 | 60 | static Level* GetLevel(Act* pAct, int level); 61 | static DWORD GetDistanceSquared(DWORD x1, DWORD y1, DWORD x2, DWORD y2); 62 | }; 63 | 64 | enum TeleType { 65 | Next = 0, 66 | Other, 67 | WP, 68 | Prev 69 | }; 70 | 71 | DWORD WINAPI LoadNewArea(VOID* lpvoid); 72 | -------------------------------------------------------------------------------- /BH/Modules/Maphack/Maphack.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../D2Structs.h" 3 | #include "../Module.h" 4 | #include "../../Config.h" 5 | #include "../../Drawing.h" 6 | 7 | enum MaphackReveal { 8 | MaphackRevealGame = 0, 9 | MaphackRevealAct, 10 | MaphackRevealLevel 11 | }; 12 | 13 | struct LevelList { 14 | unsigned int levelId; 15 | unsigned int x, y, act; 16 | }; 17 | 18 | struct BaseSkill { 19 | WORD Skill; 20 | BYTE Level; 21 | }; 22 | 23 | class Maphack : public Module { 24 | private: 25 | int monsterResistanceThreshold; 26 | int lkLinesColor; 27 | int mbMonColor; 28 | unsigned int revealType; 29 | unsigned int maxGhostSelection; 30 | unsigned int reloadConfig; 31 | bool revealedGame, revealedAct[6], revealedLevel[255]; 32 | std::map MonsterColors; 33 | std::map SuperUniqueColors; 34 | std::map MonsterLines; 35 | std::map MonsterHides; 36 | std::map TextColorMap; 37 | std::map monsterColors; 38 | std::map missileColors; 39 | std::map automapMonsterColors; 40 | std::map automapSuperUniqueColors; 41 | std::map automapMonsterLines; 42 | std::list automapHiddenMonsters; 43 | std::list automapLevels; 44 | map Toggles; 45 | Drawing::UITab* settingsTab; 46 | std::map> Skills; 47 | 48 | public: 49 | Maphack(); 50 | 51 | void ReadConfig(); 52 | void OnLoad(); 53 | void OnUnload(); 54 | 55 | void LoadConfig(); 56 | 57 | void OnLoop(); 58 | void OnDraw(); 59 | void OnAutomapDraw(); 60 | void OnGameJoin(); 61 | void OnGamePacketRecv(BYTE* packet, bool *block); 62 | 63 | void ResetRevealed(); 64 | void ResetPatches(); 65 | 66 | void OnKey(bool up, BYTE key, LPARAM lParam, bool* block); 67 | 68 | void RevealGame(); 69 | void RevealAct(int act); 70 | void RevealLevel(Level* level); 71 | void RevealRoom(Room2* room); 72 | 73 | static Level* GetLevel(Act* pAct, int level); 74 | static AutomapLayer* InitLayer(int level); 75 | }; 76 | 77 | void Weather_Interception(); 78 | void Lighting_Interception(); 79 | void Infravision_Interception(); 80 | void __stdcall Shake_Interception(LPDWORD lpX, LPDWORD lpY); 81 | void HoverObject_Interception(); 82 | -------------------------------------------------------------------------------- /BH/D2Version.cpp: -------------------------------------------------------------------------------- 1 | #include "D2Version.h" 2 | #include 3 | 4 | #pragma comment(lib,"Version.lib") 5 | 6 | VersionID D2Version::versionID = INVALID; 7 | 8 | void D2Version::Init() { 9 | std::string version = GetGameVersionString(); 10 | 11 | if (version == "1.0.13.60") { 12 | versionID = VERSION_113c; 13 | } else if (version == "1.0.13.64") { 14 | versionID = VERSION_113d; 15 | } else { 16 | versionID = INVALID; 17 | MessageBox(NULL, "Game version not detected or is unsupported!", "Failed to Detect Game Version", MB_OK); 18 | exit(0); 19 | } 20 | } 21 | 22 | VersionID D2Version::GetGameVersionID() { 23 | if (versionID == INVALID) { 24 | Init(); 25 | } 26 | return versionID; 27 | } 28 | 29 | // Taken from StackOverflow user crashmstr 30 | std::string D2Version::GetGameVersionString() { 31 | LPSTR szVersionFile = "Game.exe"; 32 | DWORD verHandle = 0; 33 | UINT size = 0; 34 | LPBYTE lpBuffer = NULL; 35 | DWORD verSize = GetFileVersionInfoSize(szVersionFile, &verHandle); 36 | 37 | std::string returnValue; 38 | 39 | if (verSize != NULL) 40 | { 41 | LPSTR verData = new char[verSize]; 42 | 43 | if (GetFileVersionInfo(szVersionFile, verHandle, verSize, verData)) 44 | { 45 | if (VerQueryValue(verData, "\\", (VOID FAR* FAR*)&lpBuffer, &size)) 46 | { 47 | if (size) 48 | { 49 | VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *)lpBuffer; 50 | if (verInfo->dwSignature == 0xfeef04bd) 51 | { 52 | char szBuffer[MAX_PATH]; 53 | // Doesn't matter if you are on 32 bit or 64 bit, 54 | // DWORD is always 32 bits, so first two revision numbers 55 | // come from dwFileVersionMS, last two come from dwFileVersionLS 56 | std::sprintf(szBuffer, "%d.%d.%d.%d", 57 | (verInfo->dwFileVersionMS >> 16) & 0xffff, 58 | (verInfo->dwFileVersionMS >> 0) & 0xffff, 59 | (verInfo->dwFileVersionLS >> 16) & 0xffff, 60 | (verInfo->dwFileVersionLS >> 0) & 0xffff 61 | ); 62 | 63 | returnValue = std::string(szBuffer); 64 | } 65 | } 66 | } 67 | } 68 | delete[] verData; 69 | } 70 | return returnValue; 71 | } 72 | 73 | std::string D2Version::GetHumanReadableVersion() { 74 | std::string returnValue; 75 | 76 | switch (GetGameVersionID()) { 77 | case VERSION_113c : 78 | returnValue = "1.13c"; 79 | break; 80 | case VERSION_113d : 81 | returnValue = "1.13d"; 82 | break; 83 | default: 84 | returnValue = "unknown"; 85 | } 86 | 87 | return returnValue; 88 | } 89 | -------------------------------------------------------------------------------- /BH/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(BH) 2 | 3 | set(SOURCE_FILES "AsyncDrawBuffer.cpp" 4 | "BH.cpp" 5 | "BitReader.cpp" 6 | "Common.cpp" 7 | "Config.cpp" 8 | "D2Handlers.cpp" 9 | "D2Helpers.cpp" 10 | "D2Intercepts.cpp" 11 | "D2Stubs.cpp" 12 | "D2Version.cpp" 13 | "DllMain.cpp" 14 | "JSONObject.cpp" 15 | "MPQInit.cpp" 16 | "MPQReader.cpp" 17 | "Mustache.cpp" 18 | "Patch.cpp" 19 | "TableReader.cpp" 20 | "Task.cpp") 21 | 22 | set(MODULE_SOURCES "Modules/Module.cpp" 23 | "Modules/ModuleManager.cpp" 24 | "Modules/AutoTele/AutoTele.cpp" 25 | "Modules/Bnet/Bnet.cpp" 26 | "Modules/ChatColor/ChatColor.cpp" 27 | "Modules/Gamefilter/Gamefilter.cpp" 28 | "Modules/Item/Item.cpp" 29 | "Modules/Item/ItemDisplay.cpp" 30 | "Modules/ItemMover/ItemMover.cpp" 31 | "Modules/Maphack/Maphack.cpp" 32 | "Modules/Party/Party.cpp" 33 | "Modules/ScreenInfo/ScreenInfo.cpp" 34 | "Modules/StashExport/StashExport.cpp") 35 | 36 | set(DRAWING_SOURCES "Drawing/Hook.cpp" 37 | "Drawing/Advanced/Checkhook/Checkhook.cpp" 38 | "Drawing/Advanced/Colorhook/Colorhook.cpp" 39 | "Drawing/Advanced/Combohook/Combohook.cpp" 40 | "Drawing/Advanced/Inputhook/Inputhook.cpp" 41 | "Drawing/Advanced/Keyhook/Keyhook.cpp" 42 | "Drawing/Basic/Boxhook/Boxhook.cpp" 43 | "Drawing/Basic/Crosshook/Crosshook.cpp" 44 | "Drawing/Basic/Framehook/Framehook.cpp" 45 | "Drawing/Basic/Linehook/Linehook.cpp" 46 | "Drawing/Basic/Texthook/Texthook.cpp" 47 | "Drawing/Stats/StatsDisplay.cpp" 48 | "Drawing/UI/UI.cpp" 49 | "Drawing/UI/UITab.cpp") 50 | 51 | set(SOURCE_FILES ${SOURCE_FILES} ${MODULE_SOURCES} ${DRAWING_SOURCES}) 52 | add_library(BH ${SOURCE_FILES}) 53 | target_include_directories(BH PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/cpp-lru-cache/include) 54 | target_link_libraries(BH ${STORM_LIBRARY} Shlwapi) 55 | -------------------------------------------------------------------------------- /BH/Drawing/Basic/Texthook/Texthook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../../Constants.h" 3 | #include "../../Hook.h" 4 | #include 5 | 6 | namespace Drawing { 7 | class Texthook : public Hook { 8 | private: 9 | std::string text;//Text to be drawn. 10 | unsigned int font;//Determines which built-in diablo font to use. 11 | TextColor color, hoverColor;//Determines which color to use. 12 | public: 13 | //Two Hook Initializations; one for basic hooks, one for grouped hooks. 14 | Texthook(HookVisibility visibility, unsigned int x, unsigned int y, std::string formatString, ...); 15 | Texthook(HookGroup* group, unsigned int x, unsigned int y, std::string formatString, ...); 16 | 17 | //Returns what D2 Font we are drawing with. 18 | unsigned int GetFont(); 19 | 20 | //Sets what D2 Font to draw with 21 | void SetFont(unsigned int newFont); 22 | 23 | 24 | //Returns what D2 Color we are drawing with. 25 | TextColor GetColor(); 26 | 27 | //Sets what D2 Color we are drawing with. 28 | void SetColor(TextColor newColor); 29 | 30 | 31 | //Returns what D2 Color we want when mouse is hovering over text, default is disabled. 32 | TextColor GetHoverColor(); 33 | 34 | //Set what D2 Color we should draw with when hovered. 35 | void SetHoverColor(TextColor newHoverColor); 36 | 37 | 38 | //Returns what text we are drawing 39 | std::string GetText(); 40 | 41 | //Set what text you want drawn 42 | void SetText(std::string formatString, ...); 43 | 44 | //Determine the pixel length of the text. 45 | unsigned int GetXSize(); 46 | 47 | //Determine the pixel height of the text. 48 | unsigned int GetYSize(); 49 | 50 | //Draw the text. 51 | void OnDraw(); 52 | 53 | //Checks if we've been clicked on and calls the handler if so. 54 | bool OnLeftClick(bool up, unsigned int x, unsigned int y); 55 | 56 | //Checks if we've been clicked on and calls the handler if so. 57 | bool OnRightClick(bool up, unsigned int x, unsigned int y); 58 | 59 | //Handy function to have! 60 | static POINT GetTextSize(std::string text, unsigned int font); 61 | static POINT GetTextSize(wchar_t* text, unsigned int font); 62 | 63 | //Static draw text function 64 | static bool Draw(unsigned int x, unsigned int y, int align, unsigned int font, TextColor color, std::string text, ...); 65 | static bool Draw(unsigned int x, unsigned int y, int align, unsigned int font, TextColor color, wchar_t* text, ...); 66 | }; 67 | }; -------------------------------------------------------------------------------- /BH/Config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "Common.h" 9 | 10 | using namespace std; 11 | 12 | struct Toggle { 13 | unsigned int toggle; 14 | bool state; 15 | }; 16 | 17 | enum ConfigType { 18 | CTBoolean, 19 | CTString, 20 | CTInt, 21 | CTKey, 22 | CTToggle, 23 | CTArray, 24 | CTAssoc, 25 | CTAssocInt, 26 | CTAssocBool 27 | }; 28 | 29 | class ConfigEntry { 30 | public: 31 | ConfigType type; 32 | std::string key; 33 | std::string value; 34 | std::string comment; 35 | int line; 36 | void* pointer; 37 | Toggle* toggle; 38 | 39 | 40 | }; 41 | 42 | inline bool operator< (const ConfigEntry& lhs, const ConfigEntry& rhs) { 43 | // std::tuple's lexicographic ordering does all the actual work for you 44 | // and using std::tie means no actual copies are made 45 | return std::tie(lhs.value, lhs.key) < std::tie(rhs.value, rhs.key); 46 | } 47 | 48 | 49 | class Config { 50 | private: 51 | std::string configName; 52 | std::map contents; 53 | vector> orderedKeyVals; 54 | 55 | static bool HasChanged(ConfigEntry entry, string& value); 56 | static bool StringToBool(std::string input); 57 | public: 58 | Config(std::string name) : configName(name) {}; 59 | 60 | //Parse the config file and store results 61 | bool Parse(); 62 | bool Write(); 63 | std::list GetDefinedKeys(); 64 | 65 | std::string GetConfigName(); 66 | void SetConfigName(std::string name); 67 | 68 | //Functions to read values from the configuration 69 | bool ReadBoolean(std::string key, bool& value); 70 | std::string ReadString(std::string key, std::string& value); 71 | int ReadInt(std::string key, int& value); 72 | unsigned int ReadInt(std::string key, unsigned int& value); 73 | unsigned int ReadKey(std::string key, std::string toggle, unsigned int &value); 74 | Toggle ReadToggle(std::string key, std::string toggle, bool defaultState, Toggle& value); 75 | std::vector ReadArray(std::string key, std::vector& value); 76 | map ReadAssoc(std::string key, std::map& value); 77 | map ReadAssoc(std::string key, std::map& value); 78 | map ReadAssoc(std::string key, std::map& value); 79 | vector> ReadMapList(std::string key, vector>& value); 80 | }; -------------------------------------------------------------------------------- /BH.Injector/BH.Injector.h: -------------------------------------------------------------------------------- 1 | /* 2 | SpamFilter.Injector - Injects SpamFilter 3 | Copyright (C) 2009 McGod 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Affero General Public License as 7 | published by the Free Software Foundation, either version 3 of the 8 | License, or (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Affero General Public License for more details. 14 | 15 | You should have received a copy of the GNU Affero General Public License 16 | along with this program. If not, see . 17 | 18 | */ 19 | #pragma once 20 | 21 | #define DLL_NAME L"BH.dll" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "cInjector.h" 32 | 33 | using namespace std; 34 | 35 | namespace BH 36 | { 37 | extern wstring wPath; 38 | }; 39 | 40 | class DiabloWindow { 41 | public: 42 | HWND pHwnd; 43 | wchar_t szTitle[1024]; 44 | HMODULE pDll; 45 | DiabloWindow(HWND hwnd) : pHwnd(hwnd) { GetWindowText(pHwnd, szTitle, 1024); pDll = cInjector::GetRemoteDll(hwnd, DLL_NAME); }; 46 | 47 | BOOL IsInjected() { return !(pDll == NULL); }; 48 | 49 | VOID Inject() { 50 | if (IsInjected()) { 51 | return; 52 | } 53 | if (cInjector::InjectDLL(pHwnd, DLL_NAME)) { 54 | wprintf(L"Injected BH into %s(HWND: %X)\n", szTitle, pHwnd); 55 | } else { 56 | wprintf(L"Failed to inject %s into %s(HWND: %X)\n", DLL_NAME, szTitle, pHwnd); 57 | } 58 | }; 59 | VOID Unload() { 60 | if (!IsInjected()) { 61 | return; 62 | } 63 | if (cInjector::UnloadDLL(pHwnd, pDll)) { 64 | wprintf(L"Unloaded BH from %s(HWND: %X)\n", szTitle, pHwnd); 65 | } else { 66 | wprintf(L"Failed to unload %s from %s(HWND: %X)\n", DLL_NAME, szTitle, pHwnd); 67 | } 68 | }; 69 | 70 | VOID MenuMessage(INT nOpt) { 71 | RECT windowRect; 72 | GetWindowRect(pHwnd, &windowRect); 73 | if (!IsInjected()) { 74 | wprintf(L"\t%d) Inject BH into %s (HWND: %X, pos: %ld,%ld)\n", nOpt, szTitle, pHwnd, windowRect.left, windowRect.top); 75 | } else { 76 | wprintf(L"\t%d) Unload from %s (HWND: %X, pos: %ld,%ld)\n", nOpt, szTitle, pHwnd, windowRect.left, windowRect.top); 77 | } 78 | }; 79 | }; -------------------------------------------------------------------------------- /BH/Drawing/Basic/Linehook/Linehook.cpp: -------------------------------------------------------------------------------- 1 | #include "Linehook.h" 2 | #include "../../../Common.h" 3 | #include "../../../D2Ptrs.h" 4 | 5 | using namespace Drawing; 6 | 7 | /* Basic Hook Initializer 8 | * Used for just drawing basic lines of screen. 9 | */ 10 | Linehook::Linehook(HookVisibility visiblity, unsigned int x, unsigned int y, unsigned int x2, unsigned int y2) : 11 | Hook(visiblity, x, y) { 12 | //Set the extra variables 13 | SetX2(x2); 14 | SetY2(y2); 15 | SetColor(0); 16 | } 17 | 18 | /* Group Hook Initializer 19 | * Used in conjuction with other basic hooks to create an advanced hook. 20 | */ 21 | Linehook::Linehook(HookGroup* group, unsigned int x, unsigned int y, unsigned int x2, unsigned int y2) : 22 | Hook(group, x, y) { 23 | //Set the extra variables 24 | SetX2(x2); 25 | SetY2(y2); 26 | SetColor(0); 27 | } 28 | 29 | /* GetColor() 30 | * Returns the color of the linehook. 31 | */ 32 | unsigned int Linehook::GetColor() { 33 | return color; 34 | } 35 | 36 | /* SetColor(unsigned int color) 37 | * Sets the color of the linehook. 38 | */ 39 | void Linehook::SetColor(unsigned int newColor) { 40 | if (newColor < 0 || newColor > 255) 41 | return; 42 | Lock(); 43 | color = newColor; 44 | Unlock(); 45 | } 46 | 47 | /* GetX2() 48 | * Returns the X2 of the line hook. 49 | */ 50 | unsigned int Linehook::GetX2() { 51 | return x2; 52 | } 53 | 54 | /* SetX2(unsigned int newX) 55 | * Sets the new X2 of the linehook. 56 | */ 57 | void Linehook::SetX2(unsigned int newX) { 58 | Lock(); 59 | x2 = newX; 60 | Unlock(); 61 | } 62 | 63 | /* GetY2() 64 | * Returns the Y2 of the line hook. 65 | */ 66 | unsigned int Linehook::GetY2() { 67 | return y2; 68 | } 69 | 70 | /* SetY2(unsigned int y2) 71 | * Sets the Y2 of the line hook. 72 | */ 73 | void Linehook::SetY2(unsigned int newY) { 74 | Lock(); 75 | y2 = newY; 76 | Unlock(); 77 | } 78 | 79 | /* Get(X/Y)Size() 80 | * Used by click handlers, fuck clicking lines. 81 | */ 82 | unsigned int Linehook::GetXSize() { return 0; }; 83 | unsigned int Linehook::GetYSize() { return 0; }; 84 | 85 | 86 | /* OnDraw() 87 | * Draws the line 88 | */ 89 | void Linehook::OnDraw() { 90 | if (!IsActive()) 91 | return; 92 | 93 | Lock(); 94 | D2GFX_DrawLine(GetX(), GetY(), GetX2(), GetY2(), GetColor(), -1); 95 | Unlock(); 96 | } 97 | 98 | bool Linehook::Draw(unsigned int x, unsigned int y, unsigned int x2, unsigned int y2, unsigned int color) { 99 | D2GFX_DrawLine(x,y,x2,y2,color,-1); 100 | return true; 101 | } -------------------------------------------------------------------------------- /BH.Injector/EventSink.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "eventsink.h" 3 | #include "BH.Injector.h" 4 | 5 | extern string patchPath; 6 | 7 | BOOL CALLBACK EnumWindowsProcAutoInject(HWND hwnd, LPARAM lParam) { 8 | DWORD lpdwProcessId; 9 | GetWindowThreadProcessId(hwnd, &lpdwProcessId); 10 | wchar_t szClassName[1024]; 11 | GetClassName(hwnd, szClassName, 1024); 12 | 13 | //Check if it is Diablo II 14 | if (!wcscmp(szClassName, L"Diablo II")) { 15 | if (lpdwProcessId == lParam) { 16 | printf("\nDiablo 2 instance found. Injecting... \n"); 17 | 18 | char szFileName[1024]; 19 | HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, lpdwProcessId); 20 | if (hProcess) { 21 | UINT ret = GetModuleFileNameExA(hProcess, NULL, szFileName, 1024); 22 | patchPath.assign(szFileName); 23 | size_t start_pos = patchPath.find("Game.exe"); 24 | if (start_pos != std::string::npos) { 25 | patchPath.replace(start_pos, 8, "Patch_D2.mpq"); 26 | } 27 | } 28 | 29 | DiabloWindow dw = DiabloWindow(hwnd); 30 | dw.Inject(); 31 | return FALSE; 32 | } 33 | } 34 | return TRUE; 35 | } 36 | 37 | 38 | HRESULT EventSink::Indicate(long lObjectCount, 39 | IWbemClassObject **apObjArray) { 40 | HRESULT hr = S_OK; 41 | _variant_t vtProp; 42 | long processID; 43 | 44 | // Take TargetInstance.Handle out of this event and send it to EnumWindowsProcAutoInject as the process id to check. 45 | for (int i = 0; i < lObjectCount; i++) { 46 | hr = apObjArray[i]->Get(_bstr_t(L"TargetInstance"), 0, &vtProp, 0, 0); 47 | if (!FAILED(hr)) { 48 | IUnknown* str = vtProp; 49 | hr = str->QueryInterface(IID_IWbemClassObject, reinterpret_cast< void** >(&apObjArray[i])); 50 | if (SUCCEEDED(hr)) { 51 | _variant_t cn; 52 | hr = apObjArray[i]->Get(L"Handle", 0, &cn, NULL, NULL); 53 | if (SUCCEEDED(hr)) { 54 | if ((cn.vt != VT_NULL) && (cn.vt != VT_EMPTY)) { 55 | processID = _wtol(cn.bstrVal); 56 | EnumWindows(EnumWindowsProcAutoInject, processID); 57 | } 58 | } 59 | VariantClear(&cn); 60 | } 61 | } 62 | VariantClear(&vtProp); 63 | } 64 | 65 | return WBEM_S_NO_ERROR; 66 | } 67 | 68 | ULONG EventSink::AddRef() { 69 | return InterlockedIncrement(&m_lRef); 70 | } 71 | 72 | ULONG EventSink::Release() { 73 | LONG lRef = InterlockedDecrement(&m_lRef); 74 | if (lRef == 0) 75 | delete this; 76 | return lRef; 77 | } 78 | 79 | HRESULT EventSink::QueryInterface(REFIID riid, void** ppv) { 80 | if (riid == IID_IUnknown || riid == IID_IWbemObjectSink) { 81 | *ppv = (IWbemObjectSink *) this; 82 | AddRef(); 83 | return WBEM_S_NO_ERROR; 84 | } else return E_NOINTERFACE; 85 | } 86 | 87 | HRESULT EventSink::SetStatus( 88 | /* [in] */ LONG lFlags, 89 | /* [in] */ HRESULT hResult, 90 | /* [in] */ BSTR strParam, 91 | /* [in] */ IWbemClassObject __RPC_FAR *pObjParam 92 | ) { 93 | return WBEM_S_NO_ERROR; 94 | } -------------------------------------------------------------------------------- /BH/Modules/ItemMover/ItemMover.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../D2Structs.h" 3 | #include "../../Drawing.h" 4 | #include "../Module.h" 5 | #include "../../Config.h" 6 | #include "../../Common.h" 7 | #include "../../BitReader.h" 8 | #include "../Item/ItemDisplay.h" 9 | #include "../../MPQInit.h" 10 | 11 | extern int INVENTORY_WIDTH; 12 | extern int INVENTORY_HEIGHT; 13 | extern int STASH_WIDTH; 14 | extern int LOD_STASH_HEIGHT; 15 | extern int CLASSIC_STASH_HEIGHT; 16 | extern int CUBE_WIDTH; 17 | extern int CUBE_HEIGHT; 18 | 19 | extern int INVENTORY_LEFT; 20 | extern int INVENTORY_TOP; 21 | extern int STASH_LEFT; 22 | extern int LOD_STASH_TOP; 23 | extern int CLASSIC_STASH_TOP; 24 | extern int CUBE_LEFT; 25 | extern int CUBE_TOP; 26 | extern int CELL_SIZE; 27 | 28 | 29 | struct ItemPacketData { 30 | unsigned int itemId; 31 | unsigned int x; 32 | unsigned int y; 33 | ULONGLONG startTicks; 34 | unsigned int destination; 35 | }; 36 | 37 | class ItemMover : public Module { 38 | private: 39 | bool FirstInit; 40 | int *InventoryItemIds; 41 | int *StashItemIds; 42 | int *CubeItemIds; 43 | int tp_warn_quantity; 44 | unsigned int TpKey; 45 | unsigned int HealKey; 46 | unsigned int ManaKey; 47 | ItemPacketData ActivePacket; 48 | CRITICAL_SECTION crit; 49 | Drawing::UITab* settingsTab; 50 | public: 51 | ItemMover() : Module("Item Mover"), 52 | ActivePacket(), 53 | FirstInit(false), 54 | InventoryItemIds(NULL), 55 | StashItemIds(NULL), 56 | CubeItemIds(NULL), 57 | tp_warn_quantity(3){ 58 | 59 | InitializeCriticalSection(&crit); 60 | }; 61 | 62 | ~ItemMover() { 63 | if (InventoryItemIds) { 64 | delete [] InventoryItemIds; 65 | } 66 | if (StashItemIds) { 67 | delete [] StashItemIds; 68 | } 69 | if (CubeItemIds) { 70 | delete [] CubeItemIds; 71 | } 72 | DeleteCriticalSection(&crit); 73 | }; 74 | 75 | void Init(); 76 | 77 | void Lock() { EnterCriticalSection(&crit); }; 78 | void Unlock() { LeaveCriticalSection(&crit); }; 79 | 80 | bool LoadInventory(UnitAny *unit, int xpac, int source, int sourceX, int sourceY, bool shiftState, bool ctrlState, int stashUI, int invUI); 81 | bool FindDestination(int xpac, int destination, unsigned int itemId, BYTE xSize, BYTE ySize); 82 | void PickUpItem(); 83 | void PutItemInContainer(); 84 | void PutItemOnGround(); 85 | 86 | void LoadConfig(); 87 | 88 | void OnLoad(); 89 | void OnKey(bool up, BYTE key, LPARAM lParam, bool* block); 90 | void OnLeftClick(bool up, int x, int y, bool* block); 91 | void OnRightClick(bool up, int x, int y, bool* block); 92 | void OnGamePacketRecv(BYTE* packet, bool *block); 93 | void OnGameExit(); 94 | }; 95 | 96 | 97 | void ParseItem(const unsigned char *data, ItemInfo *ii, bool *success); 98 | bool ProcessStat(unsigned int statId, BitReader &reader, ItemProperty &itemProp); 99 | -------------------------------------------------------------------------------- /BH/Drawing/Advanced/Combohook/Combohook.cpp: -------------------------------------------------------------------------------- 1 | #include "Combohook.h" 2 | #include "../../Basic/Framehook/Framehook.h" 3 | #include "../../Basic/Texthook/Texthook.h" 4 | #include "../../../D2Ptrs.h" 5 | 6 | using namespace Drawing; 7 | using namespace std; 8 | 9 | Combohook::Combohook(HookVisibility visibility, unsigned int x, unsigned int y, unsigned int xSize, unsigned int* index, std::vector opts) 10 | : Hook(visibility, x, y) { 11 | SetXSize(xSize); 12 | currentIndex = index; 13 | options = opts; 14 | SetFont(0); 15 | active = false; 16 | } 17 | 18 | Combohook::Combohook(HookGroup* group, unsigned int x, unsigned int y, unsigned int xSize, unsigned int* index, std::vector opts) 19 | : Hook(group, x, y) { 20 | SetXSize(xSize); 21 | currentIndex = index; 22 | options = opts; 23 | SetFont(0); 24 | active = false; 25 | } 26 | 27 | bool Combohook::OnLeftClick(bool up, unsigned int x, unsigned int y) { 28 | // Check if we clicked on a inactive combo box. 29 | if (InHook(x, y) && !active) { 30 | if (up) 31 | active = true; 32 | 33 | return true; 34 | } 35 | if (active && x >= GetX() && y >= GetY() && x <= GetX() + GetXSize() && y <= GetY() + ((options.size() + 1) * (GetYSize() + 4))) { 36 | int n = 0; 37 | for (vector::iterator it = options.begin(); it < options.end(); it++,n++) { 38 | unsigned int textY = (GetY() + GetYSize() + 4 + (n * (GetYSize() + 4))); 39 | bool hovering = x >= GetX() && y >= textY && x <= GetX() + GetXSize() && y <= textY + GetYSize() + 4; 40 | if (hovering && up) { 41 | SetSelectedIndex(n); 42 | active = false; 43 | return true; 44 | } 45 | } 46 | if (up) 47 | active = false; 48 | return true; 49 | } 50 | active = false; 51 | return false; 52 | } 53 | 54 | void Combohook::OnDraw() { 55 | Framehook::Draw(GetX(), GetY(), GetXSize(), GetYSize() + 4, 0, BTNormal); 56 | Texthook::Draw(GetX() + 5, GetY() + 3, 0, GetFont(), Gold, options.at(GetSelectedIndex())); 57 | //Framehook::Draw(GetX() + GetXSize() - 16, GetY(), 8, GetYSize() + 4, 0, BTNormal); 58 | Texthook::Draw(GetX() + GetXSize() - 8, GetY() + 3, 0, GetFont(), InHook((*p_D2CLIENT_MouseX), (*p_D2CLIENT_MouseY))||active?Tan:Gold, "v"); 59 | 60 | if (active) { 61 | Framehook::Draw(GetX(), GetY() + GetYSize() + 4, GetXSize(), options.size() * (GetYSize() + 4), 0, BTNormal); 62 | unsigned int mouseX = (*p_D2CLIENT_MouseX); 63 | unsigned int mouseY = (*p_D2CLIENT_MouseY); 64 | unsigned int n = 0; 65 | for (vector::iterator it = options.begin(); it < options.end(); it++,n++) { 66 | unsigned int textY = (GetY() + GetYSize() + 4 + (n * (GetYSize() + 4))); 67 | bool hovering = mouseX >= GetX() && mouseY >= textY && mouseX <= GetX() + GetXSize() && mouseY <= textY + GetYSize() + 4; 68 | Texthook::Draw(GetX() + 5, textY + 2, 0, GetFont(), hovering?Tan:Gold, *it); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /BH/Modules/Module.cpp: -------------------------------------------------------------------------------- 1 | #include "Module.h" 2 | #include "../BH.h" 3 | 4 | Module::Module(string name) : name(name), active(false) { 5 | BH::moduleManager->Add(this); 6 | } 7 | 8 | Module::~Module() { 9 | //Unload(); 10 | //BH::moduleManager->Remove(this); 11 | } 12 | 13 | void Module::Load() { 14 | if (IsActive()) 15 | return; 16 | 17 | // Hook up all the events 18 | 19 | __hook(&ModuleManager::OnDraw, BH::moduleManager, &Module::OnDraw, this); 20 | __hook(&ModuleManager::OnAutomapDraw, BH::moduleManager, &Module::OnAutomapDraw, this); 21 | __hook(&ModuleManager::OnOOGDraw, BH::moduleManager, &Module::OnOOGDraw, this); 22 | 23 | __hook(&ModuleManager::OnGameJoin, BH::moduleManager, &Module::OnGameJoin, this); 24 | __hook(&ModuleManager::OnGameExit, BH::moduleManager, &Module::OnGameExit, this); 25 | 26 | __hook(&ModuleManager::OnLoop, BH::moduleManager, &Module::OnLoop, this); 27 | 28 | __hook(&ModuleManager::OnLeftClick, BH::moduleManager, &Module::OnLeftClick, this); 29 | __hook(&ModuleManager::OnRightClick, BH::moduleManager, &Module::OnRightClick, this); 30 | __hook(&ModuleManager::OnKey, BH::moduleManager, &Module::OnKey, this); 31 | 32 | __hook(&ModuleManager::OnChatPacketRecv, BH::moduleManager, &Module::OnChatPacketRecv, this); 33 | __hook(&ModuleManager::OnRealmPacketRecv, BH::moduleManager, &Module::OnRealmPacketRecv, this); 34 | __hook(&ModuleManager::OnGamePacketRecv, BH::moduleManager, &Module::OnGamePacketRecv, this); 35 | 36 | __hook(&ModuleManager::OnChatMsg, BH::moduleManager, &Module::OnChatMsg, this); 37 | __hook(&Module::UserInput, this, &Module::OnUserInput, this); 38 | 39 | active = true; 40 | OnLoad(); 41 | } 42 | 43 | void Module::Unload() { 44 | if (!IsActive()) 45 | return; 46 | 47 | // Unhook all events 48 | __unhook(&ModuleManager::OnDraw, BH::moduleManager, &Module::OnDraw, this); 49 | __unhook(&ModuleManager::OnAutomapDraw, BH::moduleManager, &Module::OnAutomapDraw, this); 50 | __unhook(&ModuleManager::OnOOGDraw, BH::moduleManager, &Module::OnOOGDraw, this); 51 | 52 | __unhook(&ModuleManager::OnGameJoin, BH::moduleManager, &Module::OnGameJoin, this); 53 | __unhook(&ModuleManager::OnGameExit, BH::moduleManager, &Module::OnGameExit, this); 54 | 55 | __unhook(&ModuleManager::OnLoop, BH::moduleManager, &Module::OnLoop, this); 56 | 57 | __unhook(&ModuleManager::OnLeftClick, BH::moduleManager, &Module::OnLeftClick, this); 58 | __unhook(&ModuleManager::OnRightClick, BH::moduleManager, &Module::OnRightClick, this); 59 | __unhook(&ModuleManager::OnKey, BH::moduleManager, &Module::OnKey, this); 60 | 61 | __unhook(&ModuleManager::OnChatPacketRecv, BH::moduleManager, &Module::OnChatPacketRecv, this); 62 | __unhook(&ModuleManager::OnRealmPacketRecv, BH::moduleManager, &Module::OnRealmPacketRecv, this); 63 | __unhook(&ModuleManager::OnGamePacketRecv, BH::moduleManager, &Module::OnGamePacketRecv, this); 64 | 65 | __unhook(&ModuleManager::OnChatMsg, BH::moduleManager, &Module::OnChatMsg, this); 66 | //__unhook(&Module::UserInput, this, &Module::OnUserInput, this); 67 | 68 | active = false; 69 | OnUnload(); 70 | } -------------------------------------------------------------------------------- /BH/AsyncDrawBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "AsyncDrawBuffer.h" 2 | #include 3 | #include 4 | 5 | class DrawItem { 6 | public: 7 | std::function drawFunc; 8 | 9 | DrawItem(std::function _drawFunc) : 10 | drawFunc(_drawFunc) {} 11 | }; 12 | 13 | class DrawBuffer { 14 | private: 15 | CRITICAL_SECTION cSec; 16 | public: 17 | std::vector drawItems; 18 | std::vector drawItemsTop; 19 | 20 | DrawBuffer(){ 21 | InitializeCriticalSection(&cSec); 22 | } 23 | 24 | ~DrawBuffer(){ 25 | DeleteCriticalSection(&cSec); 26 | } 27 | 28 | void draw(){ 29 | lock(); 30 | for (auto it = drawItems.begin(); it != drawItems.end(); it++){ 31 | it->drawFunc(); 32 | } 33 | for (auto it = drawItemsTop.begin(); it != drawItemsTop.end(); it++){ 34 | it->drawFunc(); 35 | } 36 | unlock(); 37 | } 38 | 39 | void clear(){ 40 | //lock(); 41 | drawItems.clear(); 42 | drawItemsTop.clear(); 43 | //unlock(); 44 | } 45 | 46 | void lock(){ 47 | EnterCriticalSection(&cSec); 48 | } 49 | 50 | void unlock(){ 51 | LeaveCriticalSection(&cSec); 52 | } 53 | }; 54 | 55 | AsyncDrawBuffer::AsyncDrawBuffer() 56 | { 57 | fg = new DrawBuffer(); 58 | bg = new DrawBuffer(); 59 | } 60 | 61 | 62 | AsyncDrawBuffer::~AsyncDrawBuffer() 63 | { 64 | delete bg; 65 | delete fg; 66 | } 67 | 68 | 69 | // Calls all buffered draws 70 | void AsyncDrawBuffer::drawAll() 71 | { 72 | fg->draw(); 73 | } 74 | 75 | 76 | // Pushes a draw function into the buffer 77 | void AsyncDrawBuffer::push(std::function drawCall) 78 | { 79 | bg->drawItems.push_back(DrawItem(drawCall)); 80 | } 81 | 82 | // Pushes a draw function into the buffer that gets drawn last 83 | void AsyncDrawBuffer::push_top_layer(std::function drawCall) 84 | { 85 | bg->drawItemsTop.push_back(DrawItem(drawCall)); 86 | } 87 | 88 | void AsyncDrawBuffer::clear() 89 | { 90 | bg->clear(); 91 | } 92 | 93 | void AsyncDrawBuffer::swapBuffers() 94 | { 95 | auto f = fg; 96 | f->lock(); 97 | fg = bg; 98 | bg = f; 99 | f->unlock(); 100 | } 101 | 102 | DrawDirective::DrawDirective(bool _synchronous, unsigned char _maxGhost) : 103 | frameCount(0), 104 | synchronous(_synchronous), 105 | maxGhost(_maxGhost), 106 | updatePending(false), 107 | forcedUpdate(false) 108 | { 109 | } 110 | 111 | DrawDirective::~DrawDirective() 112 | { 113 | } 114 | 115 | void DrawDirective::forceUpdate(){ 116 | forcedUpdate = true; 117 | } 118 | 119 | void DrawDirective::drawInternal(fpDirector director) 120 | { 121 | buffer.clear(); 122 | 123 | // The guts of the drawing 124 | director(buffer); 125 | 126 | buffer.swapBuffers(); 127 | updatePending = false; 128 | frameCount = 0; 129 | } 130 | 131 | void DrawDirective::draw(fpDirector director) 132 | { 133 | if (forcedUpdate || !updatePending && frameCount > maxGhost){ 134 | updatePending = true; 135 | forcedUpdate = false; 136 | if (synchronous){ 137 | drawInternal(director); 138 | } 139 | else{ 140 | Task::Enqueue([=]()->void{ 141 | drawInternal(director); 142 | }); 143 | } 144 | } 145 | 146 | buffer.drawAll(); 147 | frameCount++; 148 | } 149 | -------------------------------------------------------------------------------- /BH/Drawing/Advanced/Inputhook/Inputhook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../../Hook.h" 5 | #include "../../Basic/Texthook/Texthook.h" 6 | 7 | namespace Drawing { 8 | class Inputhook : public Hook { 9 | private: 10 | std::string text; //Text that is actually in the input box 11 | bool active, showCursor; //Booleans set if the hook is active / currently showing cursor. 12 | unsigned int xSize; //Length of the input box 13 | unsigned int cursorPos, cursorTick; //Cursor Position / Timer to control cursor blink 14 | unsigned int textPos;//Used to determine which part of the current text I should show 15 | unsigned int selectPos, selectLength; // Selection position and length 16 | unsigned int font; //What type of font to use in the input hook. 17 | public: 18 | Inputhook(HookVisibility visibility, unsigned int x, unsigned int y, unsigned int xSize, std::string formatString, ...); 19 | Inputhook(HookGroup* group, unsigned int x, unsigned int y, unsigned int xSize, std::string formatString, ...); 20 | 21 | //Getters and Setters 22 | 23 | //Text in the input box 24 | std::string GetText() { return text; }; 25 | void SetText(std::string newText, ...); 26 | 27 | //If the inputhook box is active(Can be typed in) 28 | bool IsActive() { return active; }; 29 | void SetActive(bool isActive) { Lock(); active = isActive; Unlock(); }; 30 | 31 | //Font Size 32 | unsigned int GetFont() { return font; }; 33 | void SetFont(unsigned int newFont); 34 | 35 | //X Size 36 | unsigned int GetXSize() { return xSize; }; 37 | void SetXSize(unsigned int newXSize); 38 | 39 | //Y Size 40 | unsigned int GetYSize() { unsigned int height[] = {10,11,18,24,10,13,7,13,10,12,8,8,7,12}; return height[GetFont()]; }; 41 | 42 | //If we are current showing the cursor, for blinking purposes! 43 | bool ShowCursor() { return showCursor; }; 44 | void SetCursorState(bool state) { Lock(); showCursor = state; Unlock(); }; 45 | void ToggleCursor() { SetCursorState(!ShowCursor()); }; 46 | 47 | void CursorTick(); 48 | void ResetCursorTick() { cursorTick = 0; }; 49 | 50 | unsigned int GetCursorPosition() { return cursorPos; }; 51 | void SetCursorPosition(unsigned int newPosition); 52 | void IncreaseCursorPosition(unsigned int len); 53 | void DecreaseCursorPosition(unsigned int len); 54 | 55 | unsigned int GetSelectionPosition() { return selectPos; }; 56 | void SetSelectionPosition(unsigned int pos); 57 | 58 | unsigned int GetSelectionLength() { return selectLength; }; 59 | void SetSelectionLength(unsigned int length); 60 | 61 | bool IsSelected() { return selectLength > 0; }; 62 | void ResetSelection() { Lock(); selectPos = 0; selectLength = 0; Unlock(); }; 63 | 64 | bool OnKey(bool up, BYTE key, LPARAM lParam); 65 | bool OnLeftClick(bool up, unsigned int x, unsigned int y); 66 | bool OnRightClick(bool up, unsigned int x, unsigned int y); 67 | 68 | unsigned int GetCharacterLimit(); 69 | 70 | unsigned int GetTextPos() { return textPos; }; 71 | void SetTextPos(unsigned int pos) { Lock(); textPos = pos; Unlock(); }; 72 | 73 | void OnDraw(); 74 | 75 | void InputText(std::string newText); 76 | void Backspace(); 77 | void Replace(unsigned int pos, unsigned int len, std::string str); 78 | void Erase(unsigned int pos, unsigned int len); 79 | }; 80 | }; -------------------------------------------------------------------------------- /BH/RuleLookupCache.h: -------------------------------------------------------------------------------- 1 | // A cache wrapper class useful for inserting caches around rule list lookups 2 | 3 | #ifndef RULE_LOOKUP_CACHE_H_ 4 | #define RULE_LOOKUP_CACHE_H_ 5 | 6 | struct UnitItemInfo; 7 | struct Rule; 8 | 9 | #include 10 | #include 11 | #include 12 | #include "lrucache.hpp" 13 | 14 | template 15 | class RuleLookupCache { 16 | std::unique_ptr>> cache; 17 | 18 | protected: 19 | const std::vector &RuleList; 20 | virtual T make_cached_T(UnitItemInfo *uInfo, Args&&... pack) = 0; 21 | virtual std::string to_str(const T &cached_T) { 22 | // This function only needs to be implemented for debug printing 23 | return std::string("???"); 24 | } 25 | 26 | public: 27 | RuleLookupCache(const std::vector &rule_list) 28 | : RuleList(rule_list), cache(new cache::lru_cache>(100)) {} 29 | 30 | void ResetCache() { 31 | //PrintText(1, "Reseting LRU cache."); 32 | cache.reset(new cache::lru_cache>(100)); 33 | } 34 | 35 | // TODO: UnitItemInfo should probably be const, but call to Evaluate needs non-const 36 | T Get(UnitItemInfo *uInfo, Args&&... pack) { 37 | // leave this false. doesn't work 38 | static DWORD last_printed_guid = 0; // to prevent excessive printing 39 | DWORD guid = uInfo->item->dwUnitId; // global unique identifier 40 | // TODO: should we also use fingerprint or seed? Currently we trigger cache updates based 41 | // on item flag changes. This should cover everything that I can think of, including IDing 42 | // items, crafting items, making runewords, etc. Still would be nice to get some reassurance 43 | // that GUIDs aren't reused in some unexpected way. Having a cache that is wrong is no bueno. 44 | DWORD flags = uInfo->item->pItemData->dwFlags; 45 | DWORD orig_cached_flags; // the cached flags 46 | T cached_T; // the cached T after rules applied 47 | bool cache_hit = false; 48 | // First check if the name exists in the cache 49 | if (cache && cache->exists(guid)) { 50 | orig_cached_flags = cache->get(guid).first; 51 | if (orig_cached_flags == flags) { 52 | cached_T = cache->get(guid).second; 53 | cache_hit = true; // needed because empty string is also a valid item name 54 | } else { 55 | // This print can give a hint if the GUID of an item ever changes. Problem is that it will also 56 | // print whenever you ID an item, make a runeword, personalize an item, etc. 57 | // Even seems to change when items get 'old'. 58 | //PrintText(1, "Detected change in item flags. Cached: %x Actual: %x", orig_cached_flags, flags); 59 | //PrintText(1, " Cached name str: %s", to_str(cache->get(guid).second).c_str()); 60 | } 61 | // cache_hit is false if the unmodified item name has changed from cached version 62 | } 63 | if (!cache_hit) { 64 | cached_T = make_cached_T(uInfo, pack...); 65 | if (cache && !cache_hit) { 66 | std::pair pair_to_cache(flags, cached_T); 67 | cache->put(guid, pair_to_cache); 68 | //PrintText(1, "Adding key value pair %u, (%s, %x) to cache.", guid, to_str(cached_T).c_str(), flags); 69 | } 70 | // Debug stuff below doesn't work anymore because there's no general comparison function implemented 71 | //else if (cached_name != name) { 72 | // only runs if item_name_debug is on 73 | // if (guid != last_printed_guid) { 74 | // PrintText(1, "Mismatch in modified item name! Cached: %s Actual: %s", cached_name.c_str(), name.c_str()); 75 | // last_printed_guid = guid; 76 | // } 77 | //} 78 | } 79 | return cached_T; 80 | } 81 | }; 82 | 83 | #endif // RULE_LOOKUP_CACHE_H_ 84 | -------------------------------------------------------------------------------- /BH/Patch.cpp: -------------------------------------------------------------------------------- 1 | #include "Patch.h" 2 | #include "D2Version.h" 3 | std::vector Patch::Patches; 4 | 5 | Patch::Patch(PatchType type, Dll dll, Offsets offsets, int function, int length) 6 | : type(type), dll(dll), offsets(offsets), function(function), length(length) { 7 | oldCode = new BYTE[length]; 8 | injected = false; 9 | Patches.push_back(this); 10 | } 11 | 12 | int Patch::GetDllOffset(Dll dll, int offset) { 13 | const char* szDlls[] = {"D2CLIENT.dll", "D2COMMON.dll", "D2GFX.dll", "D2LANG.dll", 14 | "D2WIN.dll", "D2NET.dll", "D2GAME.dll", "D2LAUNCH.dll", 15 | "FOG.dll", "BNCLIENT.dll", "STORM.dll", "D2CMP.dll", "D2MULTI.dll", "D2MCPCLIENT.dll", "D2CMP.dll"}; 16 | //Attempt to get the module of the given DLL 17 | HMODULE hModule = GetModuleHandle(szDlls[dll]); 18 | 19 | //If DLL hasn't been loaded, then load it up! 20 | if (!hModule) { 21 | hModule = LoadLibrary(szDlls[dll]); 22 | } 23 | 24 | //If the DLL isn't there, or failed to load, return. 25 | if (!hModule) 26 | return false; 27 | 28 | //Check if it is an ordinal, if so, get the proper address. 29 | if (offset < 0) 30 | return (DWORD)GetProcAddress(hModule, (LPCSTR)(-offset)); 31 | 32 | //If just regular offset, add the two and be done! 33 | return ((DWORD)hModule) + offset; 34 | } 35 | 36 | bool Patch::WriteBytes(int address, int len, BYTE* bytes) { 37 | DWORD dwOld; 38 | 39 | if(!VirtualProtect((void*)address, len, PAGE_READWRITE, &dwOld)) 40 | return FALSE; 41 | 42 | ::memcpy((void*)address, bytes, len); 43 | return !!VirtualProtect((void*)address, len, dwOld, &dwOld); 44 | } 45 | 46 | bool Patch::Install() { 47 | 48 | //Check if we have already installed this patch. 49 | if (IsInstalled()) 50 | return true; 51 | 52 | //Initalize variables for the exactly commands we are injecting. 53 | BYTE* code = new BYTE[length]; 54 | DWORD protect; 55 | 56 | // Select an offset based on D2 version 57 | int offset = *(&offsets._113c + D2Version::GetGameVersionID()); 58 | 59 | //Get the proper address that we are patching 60 | int address = GetDllOffset(dll, offset); 61 | 62 | //Read the old code to allow proper patch removal 63 | ReadProcessMemory(GetCurrentProcess(), (void*)address, oldCode, length, NULL); 64 | 65 | //Set the code with all NOPs by default 66 | memset(code, 0x90, length); 67 | 68 | if (type != NOP) { 69 | //Set the opcode 70 | code[0] = type; 71 | 72 | //Set the address to redirect to 73 | if (type == Call || type == Jump) { 74 | *(DWORD*)&code[1] = function - (address + 5); 75 | } else { 76 | code[1] = function; 77 | } 78 | } 79 | 80 | //Write the patch in 81 | VirtualProtect((VOID*)address, length, PAGE_EXECUTE_READWRITE, &protect); 82 | memcpy_s((VOID*)address, length, code, length); 83 | VirtualProtect((VOID*)address, length, protect, &protect); 84 | 85 | 86 | //Set that we successfully patched 87 | injected = true; 88 | 89 | return true; 90 | } 91 | 92 | bool Patch::Remove() { 93 | if (!IsInstalled()) 94 | return true; 95 | 96 | // Select an offset based on D2 version 97 | int offset = *(&offsets._113c + D2Version::GetGameVersionID()); 98 | 99 | //Get the proper address 100 | int address = GetDllOffset(dll, offset); 101 | DWORD protect; 102 | 103 | //Revert to the previous code 104 | VirtualProtect((VOID*)address, length, PAGE_EXECUTE_READWRITE, &protect); 105 | memcpy_s((VOID*)address, length, oldCode, length); 106 | VirtualProtect((VOID*)address, length, protect, &protect); 107 | 108 | 109 | injected = false; 110 | 111 | return true; 112 | } 113 | -------------------------------------------------------------------------------- /BH/Drawing/UI/UI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "../Hook.h" 7 | 8 | namespace Drawing { 9 | class UI; 10 | class UITab; 11 | 12 | #define TITLE_BAR_HEIGHT 15 13 | #define MINIMIZED_Y_POS 585 14 | #define MINIMIZED_X_POS 234 15 | 16 | class UI : public HookGroup { 17 | private: 18 | static std::list UIs; 19 | static std::list Minimized; 20 | unsigned int x, y, xSize, ySize, zOrder;//Position and Size and Order 21 | unsigned int minimizedX, minimizedY;//Position when minimized 22 | bool active, minimized, dragged, visible;//If UI is active or minimized or dragged 23 | unsigned int dragX, dragY;//Position where we grabbed it. 24 | unsigned int startX, startY;//Position where we grabbed it. 25 | std::string name;//Name of the UI 26 | UITab* currentTab;//Current tab open at the time. 27 | CRITICAL_SECTION crit;//Critical section 28 | 29 | void EnsureInBounds(); 30 | public: 31 | std::list Tabs; 32 | 33 | UI(std::string name, unsigned int xSize, unsigned int ySize); 34 | ~UI(); 35 | 36 | void Lock() { EnterCriticalSection(&crit); }; 37 | void Unlock() { LeaveCriticalSection(&crit); }; 38 | 39 | unsigned int GetX() { return x; }; 40 | unsigned int GetY() { return y; }; 41 | unsigned int GetXSize() { return xSize; }; 42 | unsigned int GetYSize() { return ySize; }; 43 | unsigned int GetMinimizedX() { return minimizedX; }; 44 | unsigned int GetMinimizedY() { return minimizedY; }; 45 | bool IsActive() { return active; }; 46 | bool IsMinimized() { return minimized; }; 47 | bool IsDragged() { return dragged; }; 48 | bool IsVisible() { return visible; }; 49 | std::string GetName() { return name; }; 50 | unsigned int GetZOrder() { return zOrder; }; 51 | 52 | void SetX(unsigned int newX); 53 | void SetY(unsigned int newY); 54 | void SetXSize(unsigned int newXSize); 55 | void SetYSize(unsigned int newYSize); 56 | void SetMinimizedX(unsigned int newX); 57 | void SetMinimizedY(unsigned int newY); 58 | void SetActive(bool newState) { Lock(); active = newState; Unlock(); }; 59 | void SetMinimized(bool newState); 60 | void SetVisible(bool newState); 61 | void SetName(std::string newName) { Lock(); name = newName; Unlock(); }; 62 | void SetDragged(bool state, bool write_file); // only write config to file if write_file is true 63 | void SetDragged(bool state); // never writes the config file 64 | void SetZOrder(unsigned int newZ) { Lock(); zOrder = newZ; Unlock(); }; 65 | 66 | UITab* GetActiveTab() { if (!currentTab) { currentTab = (*Tabs.begin()); } return currentTab; }; 67 | void SetCurrentTab(UITab* tab) { Lock(); currentTab = tab; Unlock(); }; 68 | 69 | void OnDraw(); 70 | static void Draw(); 71 | 72 | static void Sort(UI* zero); 73 | 74 | bool OnLeftClick(bool up, unsigned int mouseX, unsigned int mouseY); 75 | static bool LeftClick(bool up, unsigned int mouseX, unsigned int mouseY); 76 | 77 | bool OnRightClick(bool up, unsigned int mouseX, unsigned int mouseY); 78 | static bool RightClick(bool up, unsigned int mouseX, unsigned int mouseY); 79 | 80 | bool InWindow(unsigned int xPos, unsigned int yPos) { return xPos >= x && xPos <= x + xSize && yPos >= y && yPos <= y + ySize; }; 81 | bool InTitle(unsigned int xPos, unsigned int yPos) { return xPos >= x && xPos <= x + xSize && yPos >= y && yPos <= y + TITLE_BAR_HEIGHT; }; 82 | static bool InPos(unsigned int xPos, unsigned int yPos, unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize) { return xPos >= x && xPos <= x + xSize && yPos >= y && yPos <= y + ySize; }; 83 | }; 84 | }; 85 | -------------------------------------------------------------------------------- /BH/MPQReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | // Duplicated from ItemDisplay.h because VS2010 won't let me link/share headers 12 | #define ITEM_GROUP_HELM 0x00000001 13 | #define ITEM_GROUP_ARMOR 0x00000002 14 | #define ITEM_GROUP_SHIELD 0x00000004 15 | #define ITEM_GROUP_GLOVES 0x00000008 16 | #define ITEM_GROUP_BOOTS 0x00000010 17 | #define ITEM_GROUP_BELT 0x00000020 18 | #define ITEM_GROUP_DRUID_PELT 0x00000040 19 | #define ITEM_GROUP_BARBARIAN_HELM 0x00000080 20 | #define ITEM_GROUP_PALADIN_SHIELD 0x00000100 21 | #define ITEM_GROUP_NECROMANCER_SHIELD 0x00000200 22 | #define ITEM_GROUP_AXE 0x00000400 23 | #define ITEM_GROUP_MACE 0x00000800 24 | #define ITEM_GROUP_SWORD 0x00001000 25 | #define ITEM_GROUP_DAGGER 0x00002000 26 | #define ITEM_GROUP_THROWING 0x00004000 27 | #define ITEM_GROUP_JAVELIN 0x00008000 28 | #define ITEM_GROUP_SPEAR 0x00010000 29 | #define ITEM_GROUP_POLEARM 0x00020000 30 | #define ITEM_GROUP_BOW 0x00040000 31 | #define ITEM_GROUP_CROSSBOW 0x00080000 32 | #define ITEM_GROUP_STAFF 0x00100000 33 | #define ITEM_GROUP_WAND 0x00200000 34 | #define ITEM_GROUP_SCEPTER 0x00400000 35 | #define ITEM_GROUP_ASSASSIN_KATAR 0x00800000 36 | #define ITEM_GROUP_SORCERESS_ORB 0x01000000 37 | #define ITEM_GROUP_AMAZON_WEAPON 0x02000000 38 | #define ITEM_GROUP_NORMAL 0x04000000 39 | #define ITEM_GROUP_EXCEPTIONAL 0x08000000 40 | #define ITEM_GROUP_ELITE 0x10000000 41 | #define ITEM_GROUP_ALLARMOR 0x20000000 42 | #define ITEM_GROUP_ALLWEAPON 0x40000000 43 | #define ITEM_GROUP_CIRCLET 0x80000000 44 | 45 | #define ITEM_GROUP_CHIPPED 0x00000001 46 | #define ITEM_GROUP_FLAWED 0x00000002 47 | #define ITEM_GROUP_REGULAR 0x00000004 48 | #define ITEM_GROUP_FLAWLESS 0x00000008 49 | #define ITEM_GROUP_PERFECT 0x00000010 50 | #define ITEM_GROUP_AMETHYST 0x00000020 51 | #define ITEM_GROUP_DIAMOND 0x00000040 52 | #define ITEM_GROUP_EMERALD 0x00000080 53 | #define ITEM_GROUP_RUBY 0x00000100 54 | #define ITEM_GROUP_SAPPHIRE 0x00000200 55 | #define ITEM_GROUP_TOPAZ 0x00000400 56 | #define ITEM_GROUP_SKULL 0x00000800 57 | #define ITEM_GROUP_RUNE 0x00001000 58 | 59 | 60 | typedef bool (WINAPI *MPQOpenArchive)(const char *, DWORD, DWORD, HANDLE *); 61 | typedef bool (WINAPI *MPQCloseArchive)(HANDLE); 62 | typedef bool (WINAPI *MPQOpenFile)(HANDLE, const char *, DWORD, HANDLE *); 63 | typedef bool (WINAPI *MPQGetSize)(HANDLE, DWORD *); 64 | typedef bool (WINAPI *MPQReadFile)(HANDLE, VOID *, DWORD, DWORD *, LPOVERLAPPED); 65 | typedef bool (WINAPI *MPQCloseFile)(HANDLE); 66 | 67 | class MPQArchive { 68 | public: 69 | std::string name; 70 | int error; 71 | MPQArchive(const char *filename); 72 | ~MPQArchive(); 73 | HANDLE GetHandle(); 74 | private: 75 | HANDLE hMpq; 76 | }; 77 | 78 | class MPQFile { 79 | public: 80 | std::string name; 81 | int error; 82 | MPQFile(MPQArchive *archive, const char *filename); 83 | ~MPQFile(); 84 | HANDLE GetHandle(); 85 | private: 86 | HANDLE hMpqFile; 87 | }; 88 | 89 | class MPQData { 90 | public: 91 | int error; 92 | MPQData(MPQFile *file); 93 | ~MPQData(); 94 | std::vector fields; 95 | std::vector> data; 96 | private: 97 | }; 98 | 99 | extern std::map MpqDataMap; 100 | extern std::string MpqVersion; 101 | 102 | extern "C" __declspec(dllexport) bool ReadMPQFiles(std::string fileName); 103 | void FindAncestorTypes(std::string type, std::set& ancestors, std::map& map1, std::map& map2); 104 | unsigned int AssignClassFlags(std::string type, std::set& ancestors, unsigned int flags); 105 | -------------------------------------------------------------------------------- /BH/Drawing/Basic/Boxhook/Boxhook.cpp: -------------------------------------------------------------------------------- 1 | #include "Boxhook.h" 2 | #include "../../../Common.h" 3 | #include "../../../D2Ptrs.h" 4 | 5 | using namespace Drawing; 6 | 7 | /* Basic Hook Initializer 8 | * Used for just drawing basic boxes on screen. 9 | */ 10 | Boxhook::Boxhook(HookVisibility visiblity, unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize) : 11 | Hook(visiblity, x, y) { 12 | //Set the extra variables 13 | SetXSize(xSize); 14 | SetYSize(ySize); 15 | SetColor(0); 16 | SetTransparency(BTFull); 17 | } 18 | 19 | /* Group Hook Initializer 20 | * Used in conjuction with other basic hooks to create an advanced hook. 21 | */ 22 | Boxhook::Boxhook(HookGroup* group, unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize) : 23 | Hook(group, x, y) { 24 | //Set the extra variables 25 | SetXSize(xSize); 26 | SetYSize(ySize); 27 | SetColor(0); 28 | SetTransparency(BTFull); 29 | } 30 | 31 | /* GetColor() 32 | * Returns the color of the boxhook. 33 | */ 34 | unsigned int Boxhook::GetColor() { 35 | return color; 36 | } 37 | 38 | /* SetColor(unsigned int color) 39 | * Sets the color of the boxhook. 40 | */ 41 | void Boxhook::SetColor(unsigned int newColor) { 42 | if (newColor < 0 || newColor > 255) 43 | return; 44 | Lock(); 45 | color = newColor; 46 | Unlock(); 47 | } 48 | 49 | /* GetXSize() 50 | * Returns the width of the box hook. 51 | */ 52 | unsigned int Boxhook::GetXSize() { 53 | return xSize; 54 | } 55 | 56 | /* SetXSize(unsigned int newX) 57 | * Sets the new width of the boxhook. 58 | */ 59 | void Boxhook::SetXSize(unsigned int newX) { 60 | Lock(); 61 | xSize = newX; 62 | Unlock(); 63 | } 64 | 65 | /* GetYSize() 66 | * Returns the height of the box hook. 67 | */ 68 | unsigned int Boxhook::GetYSize() { 69 | return ySize; 70 | } 71 | 72 | /* SetYSize(unsigned int ySize) 73 | * Sets the height of the box hook. 74 | */ 75 | void Boxhook::SetYSize(unsigned int newY) { 76 | Lock(); 77 | ySize = newY; 78 | Unlock(); 79 | } 80 | 81 | /* GetTransparency() 82 | * Returns the transparency of the box hook. 83 | */ 84 | BoxTrans Boxhook::GetTransparency() { 85 | return transparency; 86 | } 87 | 88 | /* SetTransparency(BoxTrans trans) 89 | * Sets the transparency of the box hook. 90 | */ 91 | void Boxhook::SetTransparency(BoxTrans trans) { 92 | Lock(); 93 | transparency = trans; 94 | Unlock(); 95 | } 96 | 97 | /* OnDraw() 98 | * Draws the rectangle 99 | */ 100 | void Boxhook::OnDraw() { 101 | if (!IsActive()) 102 | return; 103 | 104 | Lock(); 105 | D2GFX_DrawRectangle(GetX(), GetY(), GetX() + GetXSize(), GetY() + GetYSize(), GetColor(), GetTransparency()); 106 | Unlock(); 107 | } 108 | 109 | /* OnLeftClick(bool up, unsigned int x, unsigned int y) 110 | * Check if the Box hook has been clicked on. 111 | */ 112 | bool Boxhook::OnLeftClick(bool up, unsigned int x, unsigned int y) { 113 | if (InRange(x,y) && GetLeftClickHandler()) { 114 | bool block = false; 115 | Lock(); 116 | block = GetLeftClickHandler()(up, this, GetLeftClickVoid()); 117 | Unlock(); 118 | return block; 119 | } 120 | return false; 121 | } 122 | 123 | /* OnRightClick(bool up, unsigned int x, unsigned int y) 124 | * Check if the Box hook has been clicked on. 125 | */ 126 | bool Boxhook::OnRightClick(bool up, unsigned int x, unsigned int y) { 127 | if (InRange(x,y) && GetRightClickHandler()) { 128 | bool block = false; 129 | Lock(); 130 | block = GetRightClickHandler()(up, this, GetRightClickVoid()); 131 | Unlock(); 132 | return block; 133 | } 134 | return false; 135 | } 136 | 137 | 138 | bool Boxhook::Draw(unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize, unsigned int color, BoxTrans trans) { 139 | D2GFX_DrawRectangle(x, y, x + xSize, y + ySize, color, trans); 140 | return true; 141 | } -------------------------------------------------------------------------------- /BH/D2Intercepts.cpp: -------------------------------------------------------------------------------- 1 | #include "D2Handlers.h" 2 | #include "D2Ptrs.h" 3 | 4 | VOID __declspec(naked) GameDraw_Interception() 5 | { 6 | __asm 7 | { 8 | call GameDraw; 9 | 10 | POP ESI 11 | POP EBX 12 | POP ECX 13 | RETN 4 14 | } 15 | } 16 | 17 | void __declspec(naked) GameAutomapDraw_Interception() 18 | { 19 | __asm 20 | { 21 | push eax; 22 | call GameAutomapDraw; 23 | pop eax; 24 | pop edi; 25 | pop esi; 26 | ret; 27 | } 28 | } 29 | 30 | VOID __declspec(naked) OOGDraw_Interception() 31 | { 32 | __asm 33 | { 34 | PUSHAD 35 | CALL OOGDraw 36 | POPAD 37 | MOV ESI,DWORD PTR DS:[ESI+0x3C] 38 | TEST ESI, ESI 39 | RETN 40 | } 41 | } 42 | 43 | void __declspec(naked) GameLoop_Interception() 44 | { 45 | __asm 46 | { 47 | pushad; 48 | call GameLoop; 49 | popad; 50 | 51 | pop eax; 52 | sub esp, 0x20; 53 | mov [esp + 0xC], ecx; 54 | push eax; 55 | ret; 56 | } 57 | } 58 | 59 | VOID __declspec(naked) GamePacketRecv_Interception() { 60 | __asm 61 | { 62 | pop ebp; 63 | pushad; 64 | 65 | call GamePacketRecv; 66 | test eax, eax; 67 | 68 | popad; 69 | jnz OldCode; 70 | 71 | mov edx, 0; 72 | 73 | OldCode: 74 | call D2NET_ReceivePacket_I; 75 | 76 | push ebp; 77 | ret; 78 | } 79 | } 80 | 81 | VOID __declspec(naked) ChatPacketRecv_Interception() 82 | { 83 | __asm 84 | { 85 | LEA EDX, [EBP - 4] 86 | LEA ECX, [ESI + 4] 87 | pushad 88 | call ChatPacketRecv 89 | TEST EAX,EAX; 90 | 91 | popad; 92 | jnz oldCall; 93 | 94 | MOV EAX,0; 95 | ret; 96 | oldCall: 97 | CALL eax 98 | ret; 99 | } 100 | } 101 | 102 | VOID __declspec(naked) RealmPacketRecv_Interception() 103 | { 104 | __asm 105 | { 106 | LEA ECX,DWORD PTR SS:[ESP+4] 107 | PUSHAD 108 | CALL RealmPacketRecv 109 | CMP EAX, 0 110 | POPAD 111 | JE Block 112 | CALL EAX 113 | Block: 114 | RETN 115 | } 116 | } 117 | 118 | void __declspec(naked) GameInput_Interception(void) 119 | { 120 | __asm { 121 | pushad 122 | mov ecx, ebx 123 | call GameInput 124 | cmp eax, -1 125 | popad 126 | je BlockIt 127 | call D2CLIENT_InputCall_I 128 | ret 129 | 130 | BlockIt: 131 | xor eax,eax 132 | ret 133 | } 134 | } 135 | 136 | void __declspec(naked) ChannelInput_Interception(void) 137 | { 138 | __asm 139 | { 140 | push ecx 141 | mov ecx, esi 142 | 143 | call ChannelInput 144 | 145 | test eax, eax 146 | pop ecx 147 | 148 | jz SkipInput 149 | call D2MULTI_ChannelInput_I 150 | 151 | SkipInput: 152 | ret 153 | } 154 | } 155 | 156 | void __declspec(naked) ChannelWhisper_Interception(void) 157 | { 158 | __asm 159 | { 160 | push ecx 161 | push edx 162 | mov ecx, edi 163 | mov edx, ebx 164 | 165 | call ChatHandler 166 | 167 | test eax, eax 168 | pop edx 169 | pop ecx 170 | 171 | jnz SkipWhisper 172 | jmp D2MULTI_ChannelWhisper_I 173 | 174 | SkipWhisper: 175 | ret 4 176 | } 177 | } 178 | 179 | void __declspec(naked) ChannelChat_Interception(void) 180 | { 181 | __asm 182 | { 183 | push ecx 184 | push edx 185 | mov ecx, dword ptr ss:[esp+0xC] 186 | mov edx, dword ptr ss:[esp+0x10] 187 | 188 | call ChatHandler 189 | 190 | test eax, eax 191 | pop edx 192 | pop ecx 193 | 194 | jnz SkipChat 195 | sub esp, 0x408 196 | jmp D2MULTI_ChannelChat_I 197 | 198 | SkipChat: 199 | ret 8 200 | } 201 | } 202 | 203 | void __declspec(naked) ChannelEmote_Interception(void) 204 | { 205 | __asm 206 | { 207 | push ecx 208 | push edx 209 | mov ecx, dword ptr ss:[esp+0xC] 210 | mov edx, dword ptr ss:[esp+0x10] 211 | 212 | call ChatHandler 213 | 214 | test eax, eax 215 | pop edx 216 | pop ecx 217 | 218 | jnz SkipChat 219 | sub esp, 0x4F8 220 | jmp D2MULTI_ChannelEmote_I 221 | 222 | SkipChat: 223 | ret 8 224 | } 225 | } -------------------------------------------------------------------------------- /BH/Modules/Item/Item.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Item.h 4 | * BH: Copyright 2011 (C) McGod 5 | * SlashDiablo Maphack: Copyright (C) SlashDiablo Community 6 | * 7 | * This file is part of SlashDiablo Maphack. 8 | * 9 | * SlashDiablo Maphack is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU Affero General Public License as published 11 | * by the Free Software Foundation, either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU Affero General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Affero General Public License 20 | * along with this program. If not, see . 21 | * 22 | * This file incorporates work covered by the following copyright and 23 | * permission notice: 24 | * 25 | * ========================================================== 26 | * D2Ex2 27 | * https://github.com/lolet/D2Ex2 28 | * ========================================================== 29 | * Copyright (c) 2011-2014 Bartosz Jankowski 30 | * 31 | * Licensed under the Apache License, Version 2.0 (the "License"); 32 | * you may not use this file except in compliance with the License. 33 | * You may obtain a copy of the License at 34 | * 35 | * http://www.apache.org/licenses/LICENSE-2.0 36 | * 37 | * Unless required by applicable law or agreed to in writing, software 38 | * distributed under the License is distributed on an "AS IS" BASIS, 39 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 40 | * See the License for the specific language governing permissions and 41 | * limitations under the License. 42 | * ========================================================== 43 | * 44 | */ 45 | 46 | #pragma once 47 | #include "../Module.h" 48 | #include "../../Constants.h" 49 | #include "../../Config.h" 50 | #include "../../Drawing.h" 51 | 52 | struct UnitAny; 53 | 54 | class Item : public Module { 55 | private: 56 | static map Toggles; 57 | unsigned int showPlayer; 58 | static UnitAny* viewingUnit; 59 | Drawing::UITab* settingsTab; 60 | static unsigned int filterLevelSetting; 61 | static unsigned int pingLevelSetting; 62 | public: 63 | 64 | Item() : Module("Item") {}; 65 | 66 | void OnLoad(); 67 | void OnUnload(); 68 | 69 | void LoadConfig(); 70 | void DrawSettings(); 71 | 72 | void OnGameJoin(); 73 | 74 | void OnLoop(); 75 | void OnKey(bool up, BYTE key, LPARAM lParam, bool* block); 76 | void OnLeftClick(bool up, int x, int y, bool* block); 77 | std::map* GetToggles() { return &Toggles; } 78 | 79 | static void __fastcall ItemNamePatch(wchar_t *name, UnitAny *item); 80 | static void OrigGetItemName(UnitAny *item, string &itemName, char *code); 81 | static void __stdcall OnProperties(wchar_t *wTxt); 82 | static BOOL __stdcall OnDamagePropertyBuild(UnitAny* pItem, DamageStats* pDmgStats, int nStat, wchar_t* wOut); 83 | static void __stdcall OnPropertyBuild(wchar_t* wOut, int nStat, UnitAny* pItem, int nStatParam); 84 | 85 | static UnitAny* GetViewUnit(); 86 | 87 | static unsigned int GetFilterLevel() { return filterLevelSetting; } 88 | static unsigned int GetPingLevel() { return pingLevelSetting; } 89 | 90 | }; 91 | 92 | void ItemName_Interception(); 93 | void __fastcall GetProperties_Interception(); 94 | void GetItemPropertyStringDamage_Interception(); 95 | void GetItemPropertyString_Interception(); 96 | void ViewInventoryPatch1_ASM(); 97 | void ViewInventoryPatch2_ASM(); 98 | void ViewInventoryPatch3_ASM(); 99 | struct UnitItemInfo; 100 | int CreateUnitItemInfo(UnitItemInfo *uInfo, UnitAny *item); 101 | 102 | // reset all rule lookup caches 103 | void ResetCaches(); 104 | 105 | -------------------------------------------------------------------------------- /BH/Common.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Common.h 4 | * BH: Copyright 2011 (C) McGod 5 | * SlashDiablo Maphack: Copyright (C) SlashDiablo Community 6 | * 7 | * This file is part of SlashDiablo Maphack. 8 | * 9 | * SlashDiablo Maphack is free software: you can redistribute it and/or modify 10 | * it under the terms of the GNU Affero General Public License as published 11 | * by the Free Software Foundation, either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU Affero General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Affero General Public License 20 | * along with this program. If not, see . 21 | * 22 | * This file incorporates work covered by the following copyright and 23 | * permission notice: 24 | * 25 | * ========================================================== 26 | * D2Ex2 27 | * https://github.com/lolet/D2Ex2 28 | * ========================================================== 29 | * Copyright (c) 2011-2014 Bartosz Jankowski 30 | * 31 | * Licensed under the Apache License, Version 2.0 (the "License"); 32 | * you may not use this file except in compliance with the License. 33 | * You may obtain a copy of the License at 34 | * 35 | * http://www.apache.org/licenses/LICENSE-2.0 36 | * 37 | * Unless required by applicable law or agreed to in writing, software 38 | * distributed under the License is distributed on an "AS IS" BASIS, 39 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 40 | * See the License for the specific language governing permissions and 41 | * limitations under the License. 42 | * ========================================================== 43 | * 44 | */ 45 | 46 | #pragma once 47 | #include 48 | #include 49 | #include 50 | #include "D2Ptrs.h" 51 | 52 | void Tokenize(const std::string& str, std::vector& tokens, const std::string& delimiters); 53 | wchar_t* AnsiToUnicode(const char* str); 54 | char* UnicodeToAnsi(const wchar_t* str); 55 | std::wstring GetColorCode(int ColNo); 56 | template 57 | bool from_string(T& t, 58 | const std::string& s, 59 | std::ios_base& (*f)(std::ios_base&)) 60 | { 61 | std::istringstream iss(s); 62 | return !(iss >> f >> t).fail(); 63 | } 64 | 65 | template< class type> std::string to_string( const type & value) 66 | { std::stringstream ss; ss << value; return ss.str(); } 67 | 68 | bool IsTrue(const char *str); 69 | bool StringToBool(std::string str); 70 | int StringToNumber(std::string str); 71 | 72 | std::string Trim(std::string source); 73 | 74 | void PrintText(DWORD Color, char *szText, ...); 75 | 76 | struct KeyCode { 77 | std::string name; 78 | unsigned int value; 79 | std::string literalName; 80 | }; 81 | 82 | KeyCode GetKeyCode(unsigned int nKey); 83 | KeyCode GetKeyCode(const char* name); 84 | ULONGLONG BHGetTickCount(void); 85 | 86 | std::string string_format(const std::string fmt_str, ...); 87 | 88 | 89 | VOID *memcpy2(void *dest, const void *src, size_t count); 90 | HANDLE OpenFileRead(char *filename); 91 | BYTE *AllocReadFile(char *filename); 92 | DWORD ReadFile(HANDLE hFile, void *buf, DWORD len); 93 | char *GetMyFileNameStrrchr(char *dest, char ch); 94 | 95 | long CalculateDistance(const POINT& pt1, const POINT& pt2); 96 | long CalculateAngle(const POINT& pt1, const POINT& pt2); 97 | long CalculateDistance(long x1, long y1, long x2, long y2); 98 | BOOL PtInCircle(const POINT& pt, const POINT& ptOrigin, int nRadius); 99 | void NormalizeAngle(int& rAngle); 100 | void NormalizeRect(RECT& rRect); 101 | void NormalizeRect(LPRECT lpRect); 102 | long CalculateAngle(long x1, long y1, long x2, long y2); 103 | POINT CalculatePointOnTrack(const POINT& ptOrigin, int nRadius, int nAngle); 104 | POINT CalculateRandomPosition(const POINT& ptOrigin, int nRadiusMin, int nRadiusMax, int nAngleMin/*=0*/, int nAngleMax/*=360*/); 105 | char *commaprint(unsigned long n); 106 | -------------------------------------------------------------------------------- /BH/Drawing/Basic/Framehook/Framehook.cpp: -------------------------------------------------------------------------------- 1 | #include "Framehook.h" 2 | #include "../../../Common.h" 3 | #include "../../../D2Ptrs.h" 4 | 5 | using namespace Drawing; 6 | 7 | /* Basic Hook Initializer 8 | * Used for just drawing basic framees on screen. 9 | */ 10 | Framehook::Framehook(HookVisibility visiblity, unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize) : 11 | Hook(visiblity, x, y) { 12 | //Set the extra variables 13 | SetXSize(xSize); 14 | SetYSize(ySize); 15 | SetColor(0); 16 | SetTransparency(BTFull); 17 | } 18 | 19 | /* Group Hook Initializer 20 | * Used in conjuction with other basic hooks to create an advanced hook. 21 | */ 22 | Framehook::Framehook(HookGroup* group, unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize) : 23 | Hook(group, x, y) { 24 | //Set the extra variables 25 | SetXSize(xSize); 26 | SetYSize(ySize); 27 | SetColor(0); 28 | SetTransparency(BTFull); 29 | } 30 | 31 | /* GetColor() 32 | * Returns the color of the framehook. 33 | */ 34 | unsigned int Framehook::GetColor() { 35 | return color; 36 | } 37 | 38 | /* SetColor(unsigned int color) 39 | * Sets the color of the framehook. 40 | */ 41 | void Framehook::SetColor(unsigned int newColor) { 42 | if (newColor < 0 || newColor > 255) 43 | return; 44 | Lock(); 45 | color = newColor; 46 | Unlock(); 47 | } 48 | 49 | /* GetXSize() 50 | * Returns the width of the frame hook. 51 | */ 52 | unsigned int Framehook::GetXSize() { 53 | return xSize; 54 | } 55 | 56 | /* SetXSize(unsigned int newX) 57 | * Sets the new width of the framehook. 58 | */ 59 | void Framehook::SetXSize(unsigned int newX) { 60 | Lock(); 61 | xSize = newX; 62 | Unlock(); 63 | } 64 | 65 | /* GetYSize() 66 | * Returns the height of the frame hook. 67 | */ 68 | unsigned int Framehook::GetYSize() { 69 | return ySize; 70 | } 71 | 72 | /* SetYSize(unsigned int ySize) 73 | * Sets the height of the frame hook. 74 | */ 75 | void Framehook::SetYSize(unsigned int newY) { 76 | Lock(); 77 | ySize = newY; 78 | Unlock(); 79 | } 80 | 81 | /* GetTransparency() 82 | * Returns the transparency of the frame hook. 83 | */ 84 | BoxTrans Framehook::GetTransparency() { 85 | return transparency; 86 | } 87 | 88 | /* SetTransparency(BoxTrans trans) 89 | * Sets the transparency of the frame hook. 90 | */ 91 | void Framehook::SetTransparency(BoxTrans trans) { 92 | Lock(); 93 | transparency = trans; 94 | Unlock(); 95 | } 96 | 97 | DWORD __declspec(naked) _fastcall Framehook::DrawRectStub(RECT *pRect) { 98 | __asm 99 | { 100 | mov eax, ecx 101 | jmp D2CLIENT_DrawRectFrame 102 | } 103 | } 104 | 105 | /* OnDraw() 106 | * Draws the rectangle 107 | */ 108 | void Framehook::OnDraw() { 109 | if (!IsActive()) 110 | return; 111 | 112 | Lock(); 113 | RECT pRect = {GetX(), GetY(), GetX() + GetXSize(), GetY() + GetYSize()}; 114 | D2GFX_DrawRectangle(GetX(), GetY(), GetX() + GetXSize(), GetY() + GetYSize(), GetColor(), GetTransparency()); 115 | Framehook::DrawRectStub(&pRect); 116 | Unlock(); 117 | } 118 | 119 | /* OnLeftClick(bool up, unsigned int x, unsigned int y) 120 | * Check if the Frame hook has been clicked on. 121 | */ 122 | bool Framehook::OnLeftClick(bool up, unsigned int x, unsigned int y) { 123 | if (InRange(x,y) && GetLeftClickHandler()) { 124 | bool block = false; 125 | Lock(); 126 | block = GetLeftClickHandler()(up, this, GetLeftClickVoid()); 127 | Unlock(); 128 | return block; 129 | } 130 | return false; 131 | } 132 | 133 | /* OnRightClick(bool up, unsigned int x, unsigned int y) 134 | * Check if the Frame hook has been clicked on. 135 | */ 136 | bool Framehook::OnRightClick(bool up, unsigned int x, unsigned int y) { 137 | if (InRange(x,y) && GetRightClickHandler()) { 138 | bool block = false; 139 | Lock(); 140 | block = GetRightClickHandler()(up, this, GetRightClickVoid()); 141 | Unlock(); 142 | return block; 143 | } 144 | return false; 145 | } 146 | 147 | bool Framehook::Draw(unsigned int x, unsigned int y, unsigned int xSize, unsigned int ySize, unsigned int color, BoxTrans trans) { 148 | RECT pRect = {x, y, x + xSize, y + ySize}; 149 | D2GFX_DrawRectangle(x, y, x + xSize, y + ySize, color, trans); 150 | Framehook::DrawRectStub(&pRect); 151 | return true; 152 | } -------------------------------------------------------------------------------- /BH/Drawing/Advanced/Colorhook/Colorhook.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../D2Ptrs.h" 2 | #include "../../../Common.h" 3 | #include "Colorhook.h" 4 | #include "../../Basic/Boxhook/Boxhook.h" 5 | #include "../../Basic/Framehook/Framehook.h" 6 | #include "../../Basic/Texthook/Texthook.h" 7 | #include "../../Basic/Crosshook/Crosshook.h" 8 | 9 | using namespace Drawing; 10 | 11 | Colorhook* Colorhook::current; 12 | 13 | /* Basic Hook Initializer 14 | * Used for just drawing basics. 15 | */ 16 | Colorhook::Colorhook(HookVisibility visibility, unsigned int x, unsigned int y, unsigned int* color, std::string formatString, ...) : 17 | Hook(visibility, x, y) { 18 | //Correctly format the string from the given arguments. 19 | currentColor = color; 20 | char buffer[4096]; 21 | va_list arg; 22 | va_start(arg, formatString); 23 | vsprintf_s(buffer, 4096, formatString.c_str(), arg); 24 | va_end(arg); 25 | text = buffer; 26 | } 27 | 28 | /* Group Hook Initializer 29 | * Used in conjuction with other basic hooks to create an advanced hook. 30 | */ 31 | Colorhook::Colorhook(HookGroup *group, unsigned int x, unsigned int y, unsigned int* color, std::string formatString, ...) : 32 | Hook(group, x, y) { 33 | //Correctly format the string from the given arguments. 34 | currentColor = color; 35 | char buffer[4096]; 36 | va_list arg; 37 | va_start(arg, formatString); 38 | vsprintf_s(buffer, 4096, formatString.c_str(), arg); 39 | va_end(arg); 40 | text = buffer; 41 | } 42 | 43 | void Colorhook::SetText(std::string newText) { 44 | char buffer[4096]; 45 | va_list arg; 46 | va_start(arg, newText); 47 | vsprintf_s(buffer, 4096, newText.c_str(), arg); 48 | va_end(arg); 49 | Lock(); 50 | text = buffer; 51 | Unlock(); 52 | } 53 | 54 | void Colorhook::SetColor(unsigned int newColor) { 55 | if (newColor < 0 || newColor > 255) 56 | return; 57 | Lock(); 58 | *currentColor = newColor; 59 | Unlock(); 60 | } 61 | 62 | bool Colorhook::OnLeftClick(bool up, unsigned int x, unsigned int y) { 63 | if (Colorhook::current == this && x >= 310 && y >= 205 && x <= 490 && y <= 385 && up) { 64 | SetColor(curColor); 65 | Colorhook::current = false; 66 | return true; 67 | } else if (InRange(x,y) && Colorhook::current == false) { 68 | if (up) 69 | Colorhook::current = this; 70 | return true; 71 | } 72 | return false; 73 | } 74 | 75 | bool Colorhook::OnRightClick(bool up, unsigned int x, unsigned int y) { 76 | if (Colorhook::current == this) { 77 | Colorhook::current = false; 78 | return true; 79 | } 80 | return false; 81 | } 82 | 83 | /* GetXSize() 84 | * Returns how long the text is. 85 | */ 86 | unsigned int Colorhook::GetXSize() { 87 | DWORD width, fileNo; 88 | wchar_t* wString = AnsiToUnicode(GetText().c_str()); 89 | DWORD oldFont = D2WIN_SetTextSize(0); 90 | D2WIN_GetTextWidthFileNo(wString, &width, &fileNo); 91 | D2WIN_SetTextSize(oldFont); 92 | delete[] wString; 93 | return width; 94 | } 95 | 96 | /* GetYSize() 97 | * Returns how tall the text is. 98 | */ 99 | unsigned int Colorhook::GetYSize() { 100 | return 10; 101 | } 102 | 103 | void Colorhook::OnDraw() { 104 | Lock(); 105 | if (Colorhook::current == this) { 106 | //Draw the shaded background 107 | Boxhook::Draw(0, 0, Hook::GetScreenWidth(), Hook::GetScreenHeight(), 0, BTOneHalf); 108 | //Draw the actual choose color box 109 | Framehook::Draw(310, 180, 180, 220, 0, BTNormal); 110 | //Draw title 111 | Texthook::Draw(360, 186, false, 0, White, "Choose Color"); 112 | int col = 1, boxX1, boxX2, boxY1, boxY2; 113 | int mX = (*p_D2CLIENT_MouseX); 114 | int mY = (*p_D2CLIENT_MouseY); 115 | for (int n = 1, row = 1; n <= 255; n++, row++) { 116 | if (row == 16) { 117 | col++; 118 | row = 0; 119 | } 120 | //Color square begin/end pixel coordinates 121 | boxX1 = 321 + (row * 10); 122 | boxX2 = 331 + (row * 10); 123 | boxY1 = 190 + (col * 10); 124 | boxY2 = 200 + (col * 10); 125 | //Set current color based on mouse location 126 | if (mX >= boxX1 && mY >= boxY1 && mX <= boxX2 && mY <= boxY2) 127 | curColor = n; 128 | //Draw each color box 129 | D2GFX_DrawRectangle(boxX1, boxY1, boxX2, boxY2, n, 5); 130 | } 131 | //Draw the +ish symbol showing the currently hovered color 132 | CHAR szLines[][2] = { 0,-2, 4,-4, 8,-2, 4,0, 8,2, 4,4, 0,2, -4,4, -8,2, -4,0, -8,-2, -4,-4, 0,-2 }; 133 | for (unsigned int x = 0; x < 12; x++) 134 | D2GFX_DrawLine(457 + szLines[x][0], 380 + szLines[x][1], 457 + szLines[x + 1][0], 380 + szLines[x + 1][1], curColor, -1); 135 | //Draw instructions 136 | Texthook::Draw(320, 384, false, 0, White, "Left Click - Select"); 137 | Texthook::Draw(320, 368, false, 0, White, "Right Click - Close"); 138 | } else { 139 | DWORD size = D2WIN_SetTextSize(0); 140 | wchar_t* wText = AnsiToUnicode(GetText().c_str()); 141 | D2WIN_DrawText(wText, GetX() + 13, GetY() + 10, InRange(*p_D2CLIENT_MouseX, *p_D2CLIENT_MouseY)?7:4, 0); 142 | delete[] wText; 143 | D2WIN_SetTextSize(size); 144 | Crosshook::Draw(GetX(), GetY() + 4, GetColor()); 145 | } 146 | Unlock(); 147 | } 148 | -------------------------------------------------------------------------------- /BH/Drawing/Advanced/Checkhook/Checkhook.cpp: -------------------------------------------------------------------------------- 1 | #include "Checkhook.h" 2 | #include "../../../Common.h" 3 | #include "../../../D2Ptrs.h" 4 | #include "../../Basic/Framehook/Framehook.h" 5 | 6 | using namespace Drawing; 7 | /* Basic Hook Initializer 8 | * Used for drawing a checkbox on screen. 9 | */ 10 | Checkhook::Checkhook(HookVisibility visibility, unsigned int x, unsigned int y, bool* checked, std::string formatString, ...) : 11 | Hook(visibility, x, y) { 12 | //Correctly format the string from the given arguments. 13 | SetTextColor(White); 14 | state = checked; 15 | SetHoverColor(Disabled); 16 | char buffer[4096]; 17 | va_list arg; 18 | va_start(arg, formatString); 19 | vsprintf_s(buffer, 4096, formatString.c_str(), arg); 20 | va_end(arg); 21 | text = buffer; 22 | } 23 | 24 | /* Group Hook Initializer 25 | * Used in conjuction with other basic hooks to create an advanced hook. 26 | */ 27 | Checkhook::Checkhook(HookGroup* group, unsigned int x, unsigned int y, bool* checked, std::string formatString, ...) : 28 | Hook(group, x, y) { 29 | //Correctly format the string from the given arguments. 30 | SetTextColor(Gold); 31 | state = checked; 32 | SetHoverColor(Tan); 33 | char buffer[4096]; 34 | va_list arg; 35 | va_start(arg, formatString); 36 | vsprintf_s(buffer, 4096, formatString.c_str(), arg); 37 | va_end(arg); 38 | text = buffer; 39 | } 40 | 41 | /* GetColor() 42 | * Returns what color the text will be drawn. 43 | */ 44 | TextColor Checkhook::GetTextColor() { 45 | return color; 46 | } 47 | 48 | /* SetColor() 49 | * Sets what color the text will be drawn in. 50 | */ 51 | void Checkhook::SetTextColor(TextColor newColor) { 52 | Lock(); 53 | color = newColor; 54 | Unlock(); 55 | } 56 | 57 | /* GetHoverColor() 58 | * Return what color the text will be when hovered. 59 | */ 60 | TextColor Checkhook::GetHoverColor() { 61 | return hoverColor; 62 | } 63 | 64 | /* SetHoverColor() 65 | * Sets what color to draw when hovered. 66 | */ 67 | void Checkhook::SetHoverColor(TextColor newHoverColor) { 68 | Lock(); 69 | hoverColor = newHoverColor; 70 | Unlock(); 71 | } 72 | 73 | /* GetCheck() 74 | * Returns what text will be drawn. 75 | */ 76 | std::string Checkhook::GetText() { 77 | return text; 78 | } 79 | 80 | /* SetCheck(string formaString, ...) 81 | * Sets a new formatted string as the text 82 | */ 83 | void Checkhook::SetText(std::string formatString, ...) { 84 | char buffer[4096]; 85 | va_list arg; 86 | va_start(arg, formatString); 87 | vsprintf_s(buffer, 4096, formatString.c_str(), arg); 88 | va_end(arg); 89 | text = buffer; 90 | } 91 | 92 | /* GetXSize() 93 | * Returns how long the text is. 94 | */ 95 | unsigned int Checkhook::GetXSize() { 96 | DWORD width, fileNo; 97 | wchar_t* wString = AnsiToUnicode(text.c_str()); 98 | DWORD oldFont = D2WIN_SetTextSize(0); 99 | D2WIN_GetTextWidthFileNo(wString, &width, &fileNo); 100 | D2WIN_SetTextSize(oldFont); 101 | delete[] wString; 102 | return width + 20; 103 | } 104 | 105 | /* GetXSize() 106 | * Returns how tall the text is. 107 | */ 108 | unsigned int Checkhook::GetYSize() { 109 | return 12; 110 | } 111 | 112 | /* IsChecked() 113 | * Returns if the check is checked 114 | */ 115 | bool Checkhook::IsChecked() { 116 | return *state; 117 | } 118 | 119 | /* SetState() 120 | * Sets the state of the check box. 121 | */ 122 | void Checkhook::SetState(bool checked) { 123 | Lock(); 124 | *state = checked; 125 | Unlock(); 126 | } 127 | 128 | /* Draw() 129 | * Draws the text, must be called inside a Draw Patch 130 | */ 131 | void Checkhook::OnDraw() { 132 | if (!IsActive()) 133 | return; 134 | 135 | Lock(); 136 | 137 | Framehook::Draw(GetX(), GetY(), 12, 12, 0, BTFull); 138 | 139 | 140 | unsigned int drawColor = color; 141 | unsigned int checkColor = White; 142 | if (InRange(*p_D2CLIENT_MouseX, *p_D2CLIENT_MouseY) && GetHoverColor() != Disabled) { 143 | drawColor = hoverColor; 144 | checkColor = hoverColor; 145 | } 146 | 147 | if (IsChecked()) 148 | Texthook::Draw(GetX() + 3, GetY() + 2, false, 0, (TextColor)checkColor, "X"); 149 | 150 | Texthook::Draw(GetX() + 18, GetY() + 2, false, 0, (TextColor)drawColor, text); 151 | Unlock(); 152 | } 153 | 154 | /* OnLeftClick(bool up, unsigned int x, unsigned int y) 155 | * Check if the text hook has been clicked on. 156 | */ 157 | bool Checkhook::OnLeftClick(bool up, unsigned int x, unsigned int y) { 158 | if (InRange(x,y)) { 159 | Lock(); 160 | if (up) 161 | SetState(!IsChecked()); 162 | if (GetLeftClickHandler()) 163 | GetLeftClickHandler()(up, this, GetLeftClickVoid()); 164 | Unlock(); 165 | return true; 166 | } 167 | return false; 168 | } 169 | 170 | /* OnRightClick(bool up, unsigned int x, unsigned int y) 171 | * Check if the text hook has been clicked on. 172 | */ 173 | bool Checkhook::OnRightClick(bool up, unsigned int x, unsigned int y) { 174 | if (InRange(x,y) && GetRightClickHandler()) { 175 | bool block = false; 176 | Lock(); 177 | block = GetRightClickHandler()(up, this, GetRightClickVoid()); 178 | Unlock(); 179 | return block; 180 | } 181 | return false; 182 | } -------------------------------------------------------------------------------- /BH/D2Handlers.cpp: -------------------------------------------------------------------------------- 1 | #include "D2Ptrs.h" 2 | #include "BH.h" 3 | #include "D2Stubs.h" 4 | 5 | #include 6 | 7 | void GameDraw() { 8 | __raise BH::moduleManager->OnDraw(); 9 | Drawing::UI::Draw(); 10 | Drawing::StatsDisplay::Draw(); 11 | Drawing::Hook::Draw(Drawing::InGame); 12 | } 13 | 14 | void GameAutomapDraw() { 15 | __raise BH::moduleManager->OnAutomapDraw(); 16 | } 17 | 18 | void OOGDraw() { 19 | Drawing::Hook::Draw(Drawing::OutOfGame); 20 | __raise BH::moduleManager->OnOOGDraw(); 21 | } 22 | 23 | void GameLoop() { 24 | __raise BH::moduleManager->OnLoop(); 25 | } 26 | 27 | DWORD WINAPI GameThread(VOID* lpvoid) { 28 | bool inGame = false; 29 | while(true) { 30 | if ((*p_D2WIN_FirstControl) && inGame) { 31 | inGame = false; 32 | __raise BH::moduleManager->OnGameExit(); 33 | BH::config->Write(); 34 | BH::oogDraw->Install(); 35 | } else if (D2CLIENT_GetPlayerUnit() && !inGame) { 36 | inGame = true; 37 | __raise BH::moduleManager->OnGameJoin(); 38 | BH::oogDraw->Remove(); 39 | } 40 | Sleep(10); 41 | } 42 | } 43 | 44 | LONG WINAPI GameWindowEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 45 | 46 | bool blockEvent = false; 47 | int mouseX = (*p_D2CLIENT_MouseX); 48 | int mouseY = (*p_D2CLIENT_MouseY); 49 | 50 | if (uMsg == WM_LBUTTONDOWN) { 51 | if (Drawing::Hook::LeftClick(false, mouseX, mouseY)) 52 | blockEvent = true; 53 | if (Drawing::UI::LeftClick(false, mouseX, mouseY)) 54 | blockEvent = true; 55 | if (Drawing::StatsDisplay::Click(false, mouseX, mouseY)) 56 | blockEvent = true; 57 | __raise BH::moduleManager->OnLeftClick(false, mouseX, mouseY, &blockEvent); 58 | } 59 | 60 | if (uMsg == WM_LBUTTONUP) { 61 | if (Drawing::Hook::LeftClick(true, mouseX, mouseY)) 62 | blockEvent = true; 63 | if (Drawing::UI::LeftClick(true, mouseX, mouseY)) 64 | blockEvent = true; 65 | if (Drawing::StatsDisplay::Click(true, mouseX, mouseY)) 66 | blockEvent = true; 67 | __raise BH::moduleManager->OnLeftClick(true, mouseX, mouseY, &blockEvent); 68 | } 69 | 70 | if (uMsg == WM_RBUTTONDOWN) { 71 | if (Drawing::Hook::RightClick(false, mouseX, mouseY)) 72 | blockEvent = true; 73 | if (Drawing::UI::RightClick(false, mouseX, mouseY)) 74 | blockEvent = true; 75 | if (Drawing::StatsDisplay::Click(false, mouseX, mouseY)) 76 | blockEvent = true; 77 | __raise BH::moduleManager->OnRightClick(false, mouseX, mouseY, &blockEvent); 78 | } 79 | 80 | if (uMsg == WM_RBUTTONUP) { 81 | if (Drawing::Hook::RightClick(true, mouseX, mouseY)) 82 | blockEvent = true; 83 | if (Drawing::UI::RightClick(true, mouseX, mouseY)) 84 | blockEvent = true; 85 | if (Drawing::StatsDisplay::Click(true, mouseX, mouseY)) 86 | blockEvent = true; 87 | __raise BH::moduleManager->OnRightClick(true, mouseX, mouseY, &blockEvent); 88 | } 89 | 90 | if (!D2CLIENT_GetUIState(0x05)) { 91 | if (uMsg == WM_KEYDOWN) { 92 | if (Drawing::Hook::KeyClick(false, wParam, lParam)) 93 | return NULL; 94 | if (Drawing::StatsDisplay::KeyClick(false, wParam, lParam)) 95 | return NULL; 96 | __raise BH::moduleManager->OnKey(false, wParam, lParam, &blockEvent); 97 | } 98 | 99 | if (uMsg == WM_KEYUP) { 100 | if (Drawing::Hook::KeyClick(true, wParam, lParam)) 101 | return NULL; 102 | if (Drawing::StatsDisplay::KeyClick(true, wParam, lParam)) 103 | return NULL; 104 | __raise BH::moduleManager->OnKey(true, wParam, lParam, &blockEvent); 105 | } 106 | } 107 | 108 | return blockEvent ? NULL : (LONG)CallWindowProcA(BH::OldWNDPROC, hWnd, uMsg, wParam, lParam); 109 | } 110 | 111 | BOOL ChatPacketRecv(DWORD dwSize,BYTE* pPacket) { 112 | bool blockPacket = false; 113 | __raise BH::moduleManager->OnChatPacketRecv(pPacket, &blockPacket); 114 | return !blockPacket; 115 | } 116 | 117 | BOOL __fastcall RealmPacketRecv(BYTE* pPacket) { 118 | bool blockPacket = false; 119 | __raise BH::moduleManager->OnRealmPacketRecv(pPacket, &blockPacket); 120 | return !blockPacket; 121 | } 122 | 123 | DWORD __fastcall GamePacketRecv(BYTE* pPacket, DWORD dwSize) { 124 | switch(pPacket[0]) 125 | { 126 | case 0xAE: if(!BH::cGuardLoaded) return false; break; 127 | case 0x26: { 128 | char* pName = (char*)pPacket+10; 129 | char* pMessage = (char*)pPacket + strlen(pName) + 11; 130 | bool blockMessage = false; 131 | __raise BH::moduleManager->OnChatMsg(pName, pMessage, true, &blockMessage); 132 | } break; 133 | } 134 | bool blockPacket = false; 135 | __raise BH::moduleManager->OnGamePacketRecv(pPacket, &blockPacket); 136 | return !blockPacket; 137 | } 138 | 139 | DWORD __fastcall GameInput(wchar_t* wMsg) 140 | { 141 | bool hasCmd = wcslen(wMsg) > 1 && wMsg[0] == '.'; 142 | if(hasCmd) 143 | { 144 | wchar_t *buf = wMsg+1, *ctx = NULL, *seps = L" "; 145 | wchar_t* token = wcstok_s(buf, seps, &ctx); 146 | wchar_t* wparam = buf+wcslen(token)+1; 147 | int len = wcslen(wparam)+1; 148 | if(len > 0) 149 | { 150 | if(!BH::moduleManager->UserInput(token, wparam, true)) hasCmd = false; 151 | } 152 | } 153 | 154 | return hasCmd ? -1 : 0; 155 | } 156 | 157 | DWORD __fastcall ChannelInput(wchar_t* wMsg) 158 | { 159 | bool hasCmd = wcslen(wMsg) > 1 && wMsg[0] == '.'; 160 | if(hasCmd) 161 | { 162 | wchar_t *buf = wMsg+1, *ctx = NULL, *seps = L" "; 163 | wchar_t* token = wcstok_s(buf, seps, &ctx); 164 | wchar_t* wparam = buf+wcslen(token)+1; 165 | int len = wcslen(wparam)+1; 166 | if(len > 0) 167 | { 168 | if(!BH::moduleManager->UserInput(token, wparam, false)) hasCmd = false; 169 | D2WIN_SetControlText(*p_D2MULTI_ChatInputBox, L""); 170 | } 171 | } 172 | 173 | return hasCmd ? FALSE : TRUE; 174 | } 175 | 176 | BOOL __fastcall ChatHandler(char* user, char* msg) 177 | { 178 | bool block = false; 179 | __raise BH::moduleManager->OnChatMsg(user, msg, false, &block); 180 | return block; 181 | } -------------------------------------------------------------------------------- /BH/BH.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /BH/Modules/Bnet/Bnet.cpp: -------------------------------------------------------------------------------- 1 | #include "Bnet.h" 2 | #include "../../D2Ptrs.h" 3 | #include "../../BH.h" 4 | 5 | unsigned int Bnet::failToJoin; 6 | std::string Bnet::lastName; 7 | std::string Bnet::lastPass; 8 | std::string Bnet::lastDesc; 9 | std::regex Bnet::reg = std::regex("^(.*?)(\\d+)$"); 10 | 11 | Patch* nextGame1 = new Patch(Call, D2MULTI, { 0x14D29, 0xADAB }, (int)Bnet::NextGamePatch, 5); 12 | Patch* nextGame2 = new Patch(Call, D2MULTI, { 0x14A0B, 0xB5E9 }, (int)Bnet::NextGamePatch, 5); 13 | Patch* nextPass1 = new Patch(Call, D2MULTI, { 0x14D64, 0xADE6 }, (int)Bnet::NextPassPatch, 5); 14 | Patch* nextPass2 = new Patch(Call, D2MULTI, { 0x14A46, 0xB624 }, (int)Bnet::NextPassPatch, 5); 15 | 16 | Patch* gameDesc = new Patch(Call, D2MULTI, { 0x14D8F, 0xB64F }, (int)Bnet::GameDescPatch, 5); 17 | 18 | Patch* ftjPatch = new Patch(Call, D2CLIENT, { 0x4363E, 0x443FE }, (int)FailToJoin_Interception, 6); 19 | Patch* removePass = new Patch(Call, D2MULTI, { 0x1250, 0x1AD0 }, (int)RemovePass_Interception, 5); 20 | 21 | void Bnet::OnLoad() { 22 | showLastGame = &bools["Autofill Last Game"]; 23 | *showLastGame = true; 24 | 25 | showLastPass = &bools["Autofill Last Password"]; 26 | *showLastPass = true; 27 | 28 | nextInstead = &bools["Autofill Next Game"]; 29 | *nextInstead = true; 30 | 31 | keepDesc = &bools["Autofill Description"]; 32 | *keepDesc = true; 33 | 34 | failToJoin = 4000; 35 | LoadConfig(); 36 | } 37 | 38 | void Bnet::LoadConfig() { 39 | BH::config->ReadBoolean("Autofill Last Game", *showLastGame); 40 | BH::config->ReadBoolean("Autofill Last Password", *showLastPass); 41 | BH::config->ReadBoolean("Autofill Next Game", *nextInstead); 42 | BH::config->ReadBoolean("Autofill Description", *keepDesc); 43 | BH::config->ReadInt("Fail To Join", failToJoin); 44 | 45 | InstallPatches(); 46 | } 47 | 48 | void Bnet::InstallPatches() { 49 | if (*showLastGame || *nextInstead) { 50 | nextGame1->Install(); 51 | nextGame2->Install(); 52 | } 53 | 54 | if (*showLastPass) { 55 | nextPass1->Install(); 56 | nextPass2->Install(); 57 | removePass->Install(); 58 | } 59 | 60 | if (*keepDesc) { 61 | gameDesc->Install(); 62 | } 63 | 64 | if (failToJoin > 0 && !D2CLIENT_GetPlayerUnit()) 65 | ftjPatch->Install(); 66 | } 67 | 68 | void Bnet::RemovePatches() { 69 | nextGame1->Remove(); 70 | nextGame2->Remove(); 71 | 72 | nextPass1->Remove(); 73 | nextPass2->Remove(); 74 | 75 | gameDesc->Remove(); 76 | 77 | ftjPatch->Remove(); 78 | removePass->Remove(); 79 | } 80 | 81 | void Bnet::OnUnload() { 82 | RemovePatches(); 83 | } 84 | 85 | void Bnet::OnGameJoin() { 86 | if ( strlen((*p_D2LAUNCH_BnData)->szGameName) > 0) 87 | lastName = (*p_D2LAUNCH_BnData)->szGameName; 88 | 89 | if ( strlen((*p_D2LAUNCH_BnData)->szGamePass) > 0) 90 | lastPass = (*p_D2LAUNCH_BnData)->szGamePass; 91 | else 92 | lastPass = ""; 93 | 94 | if ( strlen((*p_D2LAUNCH_BnData)->szGameDesc) > 0) 95 | lastDesc = (*p_D2LAUNCH_BnData)->szGameDesc; 96 | else 97 | lastDesc = ""; 98 | 99 | RemovePatches(); 100 | } 101 | 102 | void Bnet::OnGameExit() { 103 | if (*nextInstead) { 104 | std::smatch match; 105 | if (std::regex_search(Bnet::lastName, match, Bnet::reg) && match.size() == 3) { 106 | std::string name = match.format("$1"); 107 | if (name.length() != 0) { 108 | int count = atoi(match.format("$2").c_str()); 109 | 110 | //Restart at 1 if the next number would exceed the max game name length of 15 111 | if (lastName.length() == 15) { 112 | int maxCountLength = 15 - name.length(); 113 | int countLength = 1; 114 | int tempCount = count + 1; 115 | while (tempCount > 9) { 116 | countLength++; 117 | tempCount /= 10; 118 | } 119 | if (countLength > maxCountLength) { 120 | count = 1; 121 | } else { 122 | count++; 123 | } 124 | } else { 125 | count++; 126 | } 127 | char buffer[16]; 128 | sprintf_s(buffer, sizeof(buffer), "%s%d", name.c_str(), count); 129 | lastName = std::string(buffer); 130 | } 131 | } 132 | } 133 | 134 | InstallPatches(); 135 | } 136 | 137 | VOID __fastcall Bnet::NextGamePatch(Control* box, BOOL (__stdcall *FunCallBack)(Control*, DWORD, DWORD)) { 138 | if (Bnet::lastName.size() == 0) 139 | return; 140 | 141 | wchar_t *wszLastGameName = AnsiToUnicode(Bnet::lastName.c_str()); 142 | 143 | D2WIN_SetControlText(box, wszLastGameName); 144 | D2WIN_SelectEditBoxText(box); 145 | 146 | // original code 147 | D2WIN_SetEditBoxProc(box, FunCallBack); 148 | delete [] wszLastGameName; 149 | } 150 | 151 | VOID __fastcall Bnet::NextPassPatch(Control* box, BOOL(__stdcall *FunCallBack)(Control*, DWORD, DWORD)) { 152 | if (Bnet::lastPass.size() == 0) 153 | return; 154 | wchar_t *wszLastPass = AnsiToUnicode(Bnet::lastPass.c_str()); 155 | 156 | D2WIN_SetControlText(box, wszLastPass); 157 | 158 | // original code 159 | D2WIN_SetEditBoxProc(box, FunCallBack); 160 | delete[] wszLastPass; 161 | } 162 | 163 | VOID __fastcall Bnet::GameDescPatch(Control* box, BOOL(__stdcall *FunCallBack)(Control*, DWORD, DWORD)) { 164 | if (Bnet::lastDesc.size() == 0) 165 | return; 166 | wchar_t *wszLastDesc = AnsiToUnicode(Bnet::lastDesc.c_str()); 167 | 168 | D2WIN_SetControlText(box, wszLastDesc); 169 | 170 | // original code 171 | D2WIN_SetEditBoxProc(box, FunCallBack); 172 | delete[] wszLastDesc; 173 | } 174 | 175 | void __declspec(naked) RemovePass_Interception() { 176 | __asm { 177 | PUSHAD 178 | CALL [Bnet::RemovePassPatch] 179 | POPAD 180 | 181 | ; Original code 182 | XOR EAX, EAX 183 | SUB ECX, 01 184 | RET 185 | } 186 | } 187 | 188 | void Bnet::RemovePassPatch() { 189 | Control* box = *p_D2MULTI_PassBox; 190 | 191 | if (Bnet::lastPass.size() == 0 || box == nullptr) { 192 | return; 193 | } 194 | 195 | wchar_t *wszLastPass = AnsiToUnicode(""); 196 | D2WIN_SetControlText(box, wszLastPass); 197 | delete[] wszLastPass; 198 | } 199 | 200 | void __declspec(naked) FailToJoin_Interception() 201 | { 202 | /* 203 | Changes the amount of time, in milliseconds, that we wait for the loading 204 | door to open before the client confirms that it failed to join the game. 205 | */ 206 | __asm 207 | { 208 | cmp esi, Bnet::failToJoin; 209 | ret; 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /BH/Drawing/Hook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Drawing { 7 | // HookGroups allow use of the basic hooks(Line,Text,Box,Frame) 8 | // in more advanced hooks(Input,UI,Button) that require 9 | // multiple basic hooks. 10 | class Hook; 11 | class HookGroup { 12 | public: 13 | std::list Hooks; 14 | virtual unsigned int GetX() = 0; 15 | virtual unsigned int GetY() = 0; 16 | virtual unsigned int GetXSize() = 0; 17 | virtual unsigned int GetYSize() = 0; 18 | virtual bool IsActive() = 0; 19 | }; 20 | 21 | enum HookVisibility {InGame,OutOfGame,Automap,Perm,Group}; 22 | enum BoxTrans {BTThreeFourths, BTOneHalf, BTOneFourth, BTWhite, BTBlack, BTNormal, BTScreen, BTHighlight, BTFull}; 23 | enum {None=0, Center=1, Right=2, Top=4}; 24 | 25 | 26 | typedef std::list HookList; 27 | typedef std::list::iterator HookIterator; 28 | typedef bool (__cdecl *OnClick)(bool,Hook*,void*); 29 | 30 | class Hook { 31 | private: 32 | static HookList Hooks;//Holds a list of every basic hook used. 33 | HookVisibility visibility;//When we should show the hook. 34 | unsigned int x, y, z;//Hooks screen coordinates and the z-order. 35 | CRITICAL_SECTION crit;//Critical Section so we don't have race conditions. 36 | bool active;//Boolean to hold if we should draw the hook or not. 37 | int alignment;//Holds what type of alignment(if any) we should use. 38 | HookGroup* group;//Holds the group this hook is associated with. 39 | OnClick left;//Click callback handler for left clicking 40 | void* leftVoid;//Holds data to give back to the callback for things like knowing your proper class. 41 | OnClick right;//Click callback handler for right clicking 42 | void* rightVoid;//Holds data to give back to the callback for things like knowing your proper class. 43 | public: 44 | //Two Hook Initializations; one for basic hooks, one for grouped hooks. 45 | Hook(HookVisibility visibility, unsigned int x, unsigned int y); 46 | Hook(HookGroup* group, unsigned int x, unsigned int y); 47 | //~Hook(); 48 | 49 | //Critical Section Helpers. 50 | void Lock(); 51 | void Unlock(); 52 | 53 | //Returns the x position of where the hook will be drawn. 54 | unsigned int GetX(); 55 | 56 | //Returns the base x position not calculating in groups or alignment. 57 | unsigned int GetBaseX(); 58 | 59 | //Sets the base x position, or offset from groups x position. 60 | void SetBaseX(unsigned int xPos); 61 | 62 | //Returns the width of the hook, determine by super-class. 63 | virtual unsigned int GetXSize() = 0; 64 | 65 | 66 | //Returns the y position of where the hook will be drawn. 67 | unsigned int GetY(); 68 | 69 | //Returns the base y position not calculating in groups or alignment. 70 | unsigned int GetBaseY(); 71 | 72 | //Sets the base y position, or offset from groups y position. 73 | void SetBaseY(unsigned int yPos); 74 | 75 | //Returns the height of the hook, determine by super-class. 76 | virtual unsigned int GetYSize() = 0; 77 | 78 | 79 | //Returns when the hook will be drawn compared to other hooks. 80 | int GetZOrder(); 81 | 82 | //Sets when the hook will be drawn compared to the other hooks. 83 | void SetZOrder(int zPos); 84 | 85 | 86 | //Returns when the hook will be visible 87 | HookVisibility GetVisibility(); 88 | 89 | //Sets when the hook will be visible 90 | void SetVisibility(HookVisibility newVisibility); 91 | 92 | 93 | //Returns if we are drawing the hook currently. 94 | bool IsActive(); 95 | 96 | //Sets if we should be drawing the hook. 97 | void SetActive(bool newActive); 98 | 99 | 100 | //Returns how we are going to align the hook. 101 | int GetAlignment(); 102 | 103 | //Sets how we are to align the hook. 104 | void SetAlignment(int newAlign); 105 | 106 | 107 | //Returns the hook's group. 108 | HookGroup* GetGroup(); 109 | 110 | //Sets the hook's group. 111 | void SetGroup(HookGroup* newGroup); 112 | 113 | //Returns the callback handler for left clicks 114 | OnClick GetLeftClickHandler(); 115 | 116 | //Return the callback void handler for left clicks 117 | void* GetLeftClickVoid(); 118 | 119 | //Set the callback for left clicks 120 | void SetLeftCallback(OnClick leftHandler, void* voidVar); 121 | 122 | 123 | //Returns the callback handler for right clicks 124 | OnClick GetRightClickHandler(); 125 | 126 | //Return the callback void handler for right clicks 127 | void* GetRightClickVoid(); 128 | 129 | //Set the callback for right clicks 130 | void SetRightCallback(OnClick rightHandler, void* voidVar); 131 | 132 | //Determine if the given x/y set is within the hooks drawing area. 133 | bool InRange(unsigned int x, unsigned int y); 134 | 135 | //This is the function in super-class we actually draw the function. 136 | virtual void OnDraw() = 0; 137 | 138 | //Function gets called when someone clicks, return true to block the click. 139 | virtual bool OnLeftClick(bool up, unsigned int x, unsigned int y) { return false; }; 140 | virtual bool OnRightClick(bool up, unsigned int x, unsigned int y) { return false; }; 141 | 142 | //Function gets called when someone types, return true to block the input. 143 | virtual bool OnKey(bool up, BYTE key, LPARAM lParam) { return false; }; 144 | 145 | 146 | //Static function to draw all the hooks with the given visibility. 147 | static void Draw(HookVisibility type); 148 | 149 | //Static function to check if we interacted with any hooks. 150 | static bool LeftClick(bool up, unsigned int x, unsigned int y); 151 | static bool RightClick(bool up, unsigned int x, unsigned int y); 152 | static bool KeyClick(bool bUp, BYTE bKey, LPARAM lParam); 153 | 154 | //Misc Hook Functions needed 155 | static unsigned int GetScreenHeight(); 156 | static unsigned int GetScreenWidth(); 157 | static void ScreenToAutomap(POINT* ptPos, int x, int y); 158 | static void AutomapToScreen(POINT* ptPos, int x, int y); 159 | 160 | }; 161 | }; -------------------------------------------------------------------------------- /BH/MPQReader.cpp: -------------------------------------------------------------------------------- 1 | #include "MPQReader.h" 2 | #include "BH.h" 3 | 4 | std::map MpqDataMap; 5 | std::string MpqVersion; 6 | 7 | #define SFILE_INVALID_SIZE 0xFFFFFFFF 8 | #define STREAM_FLAG_READ_ONLY 0x00000100 // Stream is read only 9 | 10 | MPQOpenArchive SFileOpenArchive; 11 | MPQCloseArchive SFileCloseArchive; 12 | MPQOpenFile SFileOpenFileEx; 13 | MPQGetSize SFileGetFileSize; 14 | MPQReadFile SFileReadFile; 15 | MPQCloseFile SFileCloseFile; 16 | 17 | MPQArchive::MPQArchive(const char *filename) : name(filename), error(ERROR_SUCCESS) { 18 | if (!SFileOpenArchive(filename, 0, STREAM_FLAG_READ_ONLY, &hMpq)) { 19 | error = GetLastError(); 20 | } 21 | } 22 | MPQArchive::~MPQArchive() { 23 | if (hMpq != NULL) { 24 | SFileCloseArchive(hMpq); 25 | } 26 | } 27 | HANDLE MPQArchive::GetHandle() { 28 | return hMpq; 29 | } 30 | 31 | 32 | MPQFile::MPQFile(MPQArchive *archive, const char *filename) : name(filename), error(ERROR_SUCCESS) { 33 | if (!SFileOpenFileEx(archive->GetHandle(), filename, 0, &hMpqFile)) { 34 | error = GetLastError(); 35 | } 36 | } 37 | MPQFile::~MPQFile() { 38 | if (hMpqFile != NULL) { 39 | SFileCloseFile(hMpqFile); 40 | } 41 | } 42 | HANDLE MPQFile::GetHandle() { 43 | return hMpqFile; 44 | } 45 | 46 | 47 | MPQData::MPQData(MPQFile *file) : error(ERROR_SUCCESS) { 48 | DWORD dwBytes = 1; 49 | std::string buffer; 50 | char szBuffer[0x10000]; 51 | while (dwBytes > 0) { 52 | SFileReadFile(file->GetHandle(), szBuffer, sizeof(szBuffer), &dwBytes, NULL); 53 | if (dwBytes > 0) { 54 | buffer.append(szBuffer, dwBytes); 55 | } 56 | } 57 | 58 | // TODO: need to remove \r, \n chars here 59 | if (error == ERROR_SUCCESS) { 60 | std::stringstream ss(buffer); 61 | std::string line; 62 | std::string field; 63 | if (std::getline(ss, line)) { // read the header first 64 | std::stringstream hss(line); 65 | while (std::getline(hss, field, '\t')) { 66 | fields.push_back(field); 67 | } 68 | while (std::getline(ss, line)) { 69 | std::map linedata; 70 | std::stringstream fss(line); 71 | for (std::vector::iterator it = fields.begin(); it != fields.end(); it++) { 72 | if (!std::getline(fss, field, '\t')) { 73 | field.clear(); 74 | } 75 | linedata[(*it)] = field; 76 | } 77 | data.push_back(linedata); 78 | } 79 | } 80 | } 81 | } 82 | MPQData::~MPQData() {} 83 | 84 | // To handle servers with customized mpq files, try to read Patch_D2.mpq using Stormlib 85 | // (http://www.zezula.net/en/mpq/stormlib.html). We load the StormLib dll with LoadLibrary 86 | // to avoid imposing any run- or compile-time dependencies on the user. If we can't load 87 | // the dll or read the mpq, we will fall back on a hard-coded list of the standard items. 88 | // 89 | // We do all this in the injector and write the info to a temp file because of problems 90 | // calling LoadLibrary in the injected dll. 91 | // Update: Can now load the dll from BH.dll, so no need to write to external files anymore 92 | bool ReadMPQFiles(std::string fileName) { 93 | int successfulFileCount = 0, desiredFileCount = 0; 94 | HMODULE dllHandle = LoadLibrary((BH::path + "StormLib.dll").c_str()); 95 | if (dllHandle) { 96 | SFileOpenArchive = (MPQOpenArchive)GetProcAddress(dllHandle, "SFileOpenArchive"); 97 | SFileCloseArchive = (MPQCloseArchive)GetProcAddress(dllHandle, "SFileCloseArchive"); 98 | SFileOpenFileEx = (MPQOpenFile)GetProcAddress(dllHandle, "SFileOpenFileEx"); 99 | SFileGetFileSize = (MPQGetSize)GetProcAddress(dllHandle, "SFileGetFileSize"); 100 | SFileReadFile = (MPQReadFile)GetProcAddress(dllHandle, "SFileReadFile"); 101 | SFileCloseFile = (MPQCloseFile)GetProcAddress(dllHandle, "SFileCloseFile"); 102 | 103 | HANDLE pMutex = CreateMutex(NULL, true, "Global\\BH_PATCH_D2_MPQ_MUTEX"); 104 | WaitForSingleObject( 105 | pMutex, // handle to mutex 106 | INFINITE); // no time-out interval 107 | 108 | if (SFileOpenArchive && SFileCloseArchive && SFileOpenFileEx && SFileCloseFile && SFileGetFileSize && SFileReadFile) { 109 | MPQArchive archive(fileName.c_str()); 110 | 111 | const int NUM_MPQS = 16; 112 | std::string mpqFiles[NUM_MPQS] = { 113 | "UniqueItems", 114 | "Armor", 115 | "Weapons", 116 | "Misc", 117 | "ItemTypes", 118 | "ItemStatCost", 119 | "Inventory", 120 | "Properties", 121 | "Runes", 122 | "SetItems", 123 | "skills", 124 | "MagicPrefix", 125 | "MagicSuffix", 126 | "RarePrefix", 127 | "RareSuffix", 128 | "CharStats" 129 | }; 130 | if (archive.error == ERROR_SUCCESS) { 131 | for (int i = 0; i < NUM_MPQS; i++){ 132 | std::string path = "data\\global\\excel\\" + mpqFiles[i] + ".txt"; 133 | MPQFile mpqFile(&archive, path.c_str()); desiredFileCount++; 134 | if (mpqFile.error == ERROR_SUCCESS) { 135 | successfulFileCount++; 136 | std::string key = mpqFiles[i]; 137 | std::transform(key.begin(), key.end(), key.begin(), ::tolower); 138 | MpqDataMap[key] = new MPQData(&mpqFile); 139 | } 140 | } 141 | } 142 | // read mpq version 143 | std::string path = "data\\version.txt"; 144 | MPQFile mpqFile(&archive, path.c_str()); 145 | if (mpqFile.error == ERROR_SUCCESS) { 146 | MPQData mpqversion(&mpqFile); 147 | MpqVersion = mpqversion.fields[0]; 148 | } 149 | } 150 | FreeLibrary(dllHandle); 151 | 152 | ReleaseMutex(pMutex); 153 | CloseHandle(pMutex); 154 | } 155 | return true; 156 | } 157 | 158 | void FindAncestorTypes(std::string type, std::set& ancestors, std::map& map1, std::map& map2) { 159 | ancestors.insert(type); 160 | std::map::iterator it1 = map1.find(type); 161 | if (it1 != map1.end()) { 162 | FindAncestorTypes(it1->second, ancestors, map1, map2); 163 | } 164 | std::map::iterator it2 = map2.find(type); 165 | if (it2 != map2.end()) { 166 | FindAncestorTypes(it2->second, ancestors, map1, map2); 167 | } 168 | } 169 | 170 | unsigned int AssignClassFlags(std::string type, std::set& ancestors, unsigned int flags) { 171 | if (ancestors.find("amaz") != ancestors.end()) { 172 | flags |= ITEM_GROUP_AMAZON_WEAPON; 173 | } else if (ancestors.find("barb") != ancestors.end()) { 174 | flags |= ITEM_GROUP_BARBARIAN_HELM; 175 | } else if (ancestors.find("necr") != ancestors.end()) { 176 | flags |= ITEM_GROUP_NECROMANCER_SHIELD; 177 | } else if (ancestors.find("pala") != ancestors.end()) { 178 | flags |= ITEM_GROUP_PALADIN_SHIELD; 179 | } else if (ancestors.find("sorc") != ancestors.end()) { 180 | flags |= ITEM_GROUP_SORCERESS_ORB; 181 | } else if (ancestors.find("assn") != ancestors.end()) { 182 | flags |= ITEM_GROUP_ASSASSIN_KATAR; 183 | } else if (ancestors.find("drui") != ancestors.end()) { 184 | flags |= ITEM_GROUP_DRUID_PELT; 185 | } 186 | return flags; 187 | } 188 | -------------------------------------------------------------------------------- /BH/JSONObject.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright: Chris Kellner 2015 3 | License: MIT 4 | */ 5 | #pragma once 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | enum JSONElementType{ 14 | JSON_NULL, 15 | JSON_BOOL, 16 | JSON_NUMBER, 17 | JSON_STRING, 18 | JSON_OBJECT, 19 | JSON_ARRAY 20 | }; 21 | 22 | enum SerializationOptions { 23 | SER_OPT_NONE = 0, 24 | SER_OPT_FORMATTED = 1 25 | }; 26 | 27 | std::string Json_Escape(const std::string &input); 28 | std::string Json_Unescape(const std::string &input); 29 | 30 | class JSONWriter { 31 | private: 32 | SerializationOptions _options; 33 | std::string &_buffer; 34 | int indent; 35 | std::stack typeStack; 36 | 37 | void writeIndented(std::string value); 38 | void writeNewlyIndented(std::string value); 39 | 40 | public: 41 | JSONWriter(std::string &buffer, SerializationOptions options) : 42 | _buffer(buffer), 43 | _options(options), 44 | indent(0), 45 | typeStack(){ 46 | typeStack.push(JSON_NULL); 47 | } 48 | 49 | SerializationOptions getOptions() { return _options; } 50 | 51 | void writeKey(std::string key); 52 | void writeValue(std::string value); 53 | void writeNext(); 54 | void writeRaw(std::string value); 55 | void writeStartObject(); 56 | void writeEndObject(); 57 | void writeStartArray(); 58 | void writeEndArray(); 59 | }; 60 | 61 | class JSONElement { 62 | protected: 63 | JSONElementType type; 64 | public: 65 | virtual ~JSONElement() {} 66 | 67 | JSONElementType getType() const { return type; } 68 | 69 | virtual bool toBool() const { return hasValue(); } 70 | virtual int toInt() const { return 0; } 71 | virtual float toFloat() const { return 0.0f; } 72 | virtual std::string toString() const { return ""; } 73 | 74 | virtual bool serialize(JSONWriter &writer) = 0; 75 | virtual bool hasValue() const = 0; 76 | 77 | operator bool() const { return hasValue(); } 78 | 79 | virtual bool equals(JSONElement *other) = 0; 80 | 81 | /* 82 | Finds the child element within this element using the specified path. 83 | */ 84 | virtual JSONElement* find(std::string path) const; 85 | 86 | static JSONElement* Null(); 87 | }; 88 | 89 | class JSONBool : public JSONElement{ 90 | private: 91 | bool _value; 92 | public: 93 | JSONBool(bool value); 94 | bool serialize(JSONWriter &writer); 95 | bool hasValue() const { return _value; } 96 | 97 | bool getValue() const { return _value; } 98 | 99 | bool toBool() const { return _value; } 100 | int toInt() const { return _value ? 1 : 0; } 101 | float toFloat() const { return _value ? 1.0f : 0.0f; } 102 | std::string toString() const { return _value ? "true" : "false"; } 103 | bool equals(JSONElement *other) { return other && other->getType() == JSON_BOOL && _value == ((JSONBool*)other)->_value; } 104 | }; 105 | 106 | class JSONNumber : public JSONElement{ 107 | private: 108 | float _fvalue; 109 | int _ivalue; 110 | public: 111 | JSONNumber(float value); 112 | JSONNumber(int value); 113 | bool serialize(JSONWriter &writer); 114 | bool hasValue() const { return _ivalue || _fvalue; } 115 | 116 | float getValue() const { return _ivalue ? _ivalue : _fvalue; } 117 | 118 | bool toBool() const { return hasValue(); } 119 | int toInt() const { return _ivalue ? _ivalue : (int)_fvalue; } 120 | float toFloat() const { return _fvalue ? _fvalue : (float)_ivalue; } 121 | std::string toString() const; 122 | bool equals(JSONElement *other) { return other && other->getType() == JSON_NUMBER && getValue() == ((JSONNumber*)other)->getValue(); } 123 | }; 124 | 125 | class JSONString : public JSONElement{ 126 | private: 127 | std::string _value; 128 | public: 129 | JSONString(std::string value); 130 | bool serialize(JSONWriter &writer); 131 | bool hasValue() const { return _value.length() > 0; } 132 | 133 | std::string getValue() const { return _value; } 134 | 135 | bool toBool() const; 136 | int toInt() const; 137 | float toFloat() const; 138 | std::string toString() const { return _value; } 139 | bool equals(JSONElement *other) { return other && other->getType() == JSON_STRING && getValue().compare(((JSONString*)other)->getValue()) == 0; } 140 | }; 141 | 142 | class JSONArray; 143 | class JSONObject : public JSONElement{ 144 | private: 145 | std::map> _properties; 146 | protected: 147 | void addEntry(std::string key, JSONElement* value); 148 | public: 149 | JSONObject() : _properties() { 150 | type = JSON_OBJECT; 151 | }; 152 | 153 | ~JSONObject(); 154 | 155 | bool serialize(JSONWriter &writer); 156 | bool hasValue() const { return _properties.size() > 0; } 157 | int length() const { return _properties.size(); } 158 | 159 | JSONElement* get(std::string key) const; 160 | std::string getString(std::string key) const; 161 | float getNumber(std::string key) const; 162 | bool getBool(std::string key) const; 163 | JSONObject* getObject(std::string key) const; 164 | JSONArray* getArray(std::string key) const; 165 | 166 | void set(std::string key, std::string value); 167 | void set(std::string key, bool value); 168 | void set(std::string key, int value); 169 | void set(std::string key, float value); 170 | void set(std::string key, JSONObject* value); 171 | void set(std::string key, JSONArray* value); 172 | 173 | JSONElement* find(std::string path) const; 174 | 175 | bool equals(JSONElement *other); 176 | }; 177 | 178 | class JSONArray : public JSONElement{ 179 | private: 180 | std::vector> _elements; 181 | protected: 182 | void addEntry(JSONElement* value); 183 | public: 184 | JSONArray(); 185 | ~JSONArray(); 186 | bool serialize(JSONWriter &writer); 187 | bool hasValue() const { return _elements.size() > 0; } 188 | 189 | int length() const { return _elements.size(); } 190 | 191 | JSONElement* get(unsigned int index) const; 192 | std::string getString(unsigned int index) const; 193 | float getNumber(unsigned int index) const; 194 | bool getBool(unsigned int index) const; 195 | JSONObject* getObject(unsigned int index) const; 196 | JSONArray* getArray(unsigned int index) const; 197 | 198 | void add(std::string value); 199 | void add(bool value); 200 | void add(int value); 201 | void add(float value); 202 | void add(JSONObject* value); 203 | void add(JSONArray* value); 204 | 205 | void remove(std::vector>::iterator elem); 206 | void removeWhere(std::function predicate); 207 | 208 | std::vector>::iterator begin() { return _elements.begin(); } 209 | std::vector>::iterator end() { return _elements.end(); } 210 | 211 | JSONElement* find(std::string path) const; 212 | 213 | // Searches through the array for an element equal to the specified target element 214 | // Returns: The element contained in the array or null 215 | JSONElement* contains(JSONElement* target) const; 216 | 217 | bool equals(JSONElement *other); 218 | }; -------------------------------------------------------------------------------- /BH.Injector/BH.Injector.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Packaging 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | 18 | {0C10FFDA-E6F8-4180-BF7D-8A423A171748} 19 | BHInjector 20 | 10.0.16299.0 21 | 22 | 23 | 24 | Application 25 | true 26 | Unicode 27 | v120 28 | 29 | 30 | Application 31 | false 32 | true 33 | Unicode 34 | v120 35 | 36 | 37 | Application 38 | false 39 | true 40 | Unicode 41 | v120 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | $(INCLUDE);$(IncludePath) 58 | 59 | 60 | $(LIBPATH);$(LibraryPath) 61 | 62 | 63 | E:\Program Files (x86)\Diablo II\plugins\StormLib-master-8.20\src;$(IncludePath) 64 | 65 | 66 | $(LIBPATH);$(LibraryPath) 67 | 68 | 69 | $(INCLUDE);$(IncludePath) 70 | 71 | 72 | $(LIBPATH);$(LibraryPath) 73 | 74 | 75 | 76 | Level3 77 | Disabled 78 | _DEBUG;%(PreprocessorDefinitions) 79 | 80 | 81 | true 82 | kernel32.lib;psapi.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 83 | 84 | 85 | 86 | 87 | Level3 88 | MaxSpeed 89 | true 90 | true 91 | 92 | 93 | true 94 | true 95 | true 96 | 97 | 98 | 99 | 100 | Level3 101 | MaxSpeed 102 | true 103 | true 104 | 105 | 106 | false 107 | true 108 | true 109 | kernel32.lib;psapi.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /BH/BH.cpp: -------------------------------------------------------------------------------- 1 | #define _DEFINE_PTRS 2 | #include "BH.h" 3 | #include 4 | #include 5 | #include "D2Ptrs.h" 6 | #include "D2Intercepts.h" 7 | #include "D2Handlers.h" 8 | #include "Modules.h" 9 | #include "MPQReader.h" 10 | #include "MPQInit.h" 11 | #include "TableReader.h" 12 | #include "Task.h" 13 | 14 | string BH::path; 15 | HINSTANCE BH::instance; 16 | ModuleManager* BH::moduleManager; 17 | Config* BH::config; 18 | Config* BH::itemConfig; 19 | Drawing::UI* BH::settingsUI; 20 | Drawing::StatsDisplay* BH::statsDisplay; 21 | bool BH::initialized; 22 | bool BH::cGuardLoaded; 23 | WNDPROC BH::OldWNDPROC; 24 | map* BH::MiscToggles; 25 | map* BH::MiscToggles2; 26 | map* BH::BnetBools; 27 | map* BH::GamefilterBools; 28 | 29 | Patch* patches[] = { 30 | new Patch(Call, D2CLIENT, { 0x44230, 0x45280 }, (int)GameLoop_Interception, 7), 31 | 32 | new Patch(Jump, D2CLIENT, { 0xC3DB4, 0x1D7B4 }, (int)GameDraw_Interception, 6), 33 | new Patch(Jump, D2CLIENT, { 0x626C9, 0x73469 }, (int)GameAutomapDraw_Interception, 5), 34 | 35 | new Patch(Call, BNCLIENT, { 0xEAB6, 0xCEB6 }, (int)ChatPacketRecv_Interception, 0xEABE - 0xEAB6), 36 | new Patch(Call, D2MCPCLIENT, { 0x69D7, 0x6297 }, (int)RealmPacketRecv_Interception, 5), 37 | new Patch(Call, D2CLIENT, { 0xACE61, 0x83301 }, (int)GamePacketRecv_Interception, 5), 38 | new Patch(Call, D2CLIENT, { 0x70B75, 0xB24FF }, (int)GameInput_Interception, 5), 39 | new Patch(Call, D2MULTI, { 0xD753, 0x11D63 }, (int)ChannelInput_Interception, 5), 40 | new Patch(Call, D2MULTI, { 0x10781, 0x14A9A }, (int)ChannelWhisper_Interception, 5), 41 | new Patch(Jump, D2MULTI, { 0x108A0, 0x14BE0 }, (int)ChannelChat_Interception, 6), 42 | new Patch(Jump, D2MULTI, { 0x107A0, 0x14850 }, (int)ChannelEmote_Interception, 6), 43 | }; 44 | 45 | Patch* BH::oogDraw = new Patch(Call, D2WIN, { 0x18911, 0xEC61 }, (int)OOGDraw_Interception, 5); 46 | 47 | unsigned int index = 0; 48 | bool BH::Startup(HINSTANCE instance, VOID* reserved) { 49 | 50 | BH::instance = instance; 51 | if (reserved != NULL) { 52 | cGuardModule* pModule = (cGuardModule*)reserved; 53 | if (!pModule) 54 | return FALSE; 55 | path.assign(pModule->szPath); 56 | cGuardLoaded = true; 57 | } 58 | else { 59 | char szPath[MAX_PATH]; 60 | GetModuleFileName(BH::instance, szPath, MAX_PATH); 61 | PathRemoveFileSpec(szPath); 62 | path.assign(szPath); 63 | path += "\\"; 64 | cGuardLoaded = false; 65 | } 66 | 67 | 68 | initialized = false; 69 | Initialize(); 70 | return true; 71 | } 72 | 73 | DWORD WINAPI LoadMPQData(VOID* lpvoid){ 74 | char szFileName[1024]; 75 | std::string patchPath; 76 | UINT ret = GetModuleFileName(NULL, szFileName, 1024); 77 | patchPath.assign(szFileName); 78 | size_t start_pos = patchPath.rfind("\\"); 79 | if (start_pos != std::string::npos) { 80 | start_pos++; 81 | if (start_pos < patchPath.size()){ 82 | patchPath.replace(start_pos, patchPath.size() - start_pos, "Patch_D2.mpq"); 83 | } 84 | } 85 | 86 | ReadMPQFiles(patchPath); 87 | InitializeMPQData(); 88 | Tables::initTables(); 89 | 90 | return 0; 91 | } 92 | 93 | void BH::Initialize() 94 | { 95 | moduleManager = new ModuleManager(); 96 | config = new Config("BH_settings.cfg"); 97 | if(!config->Parse()) { 98 | config->SetConfigName("BH_Default.cfg"); 99 | if(!config->Parse()) { 100 | string msg = "Could not find BH settings.\nAttempted to load " + 101 | path + "BH_settings.cfg (failed).\nAttempted to load "+ 102 | path + "BH_Default.cfg (failed).\n\nDefaults loaded."; 103 | MessageBox(NULL, msg.c_str(), "Failed to load BH config", MB_OK); 104 | } 105 | } 106 | itemConfig = new Config("BH.cfg"); 107 | itemConfig->Parse(); 108 | 109 | // Do this asynchronously because D2GFX_GetHwnd() will be null if 110 | // we inject on process start 111 | Task::Enqueue([]() -> void { 112 | std::chrono::milliseconds duration(200); 113 | while(!D2GFX_GetHwnd()) { 114 | std::this_thread::sleep_for(duration); 115 | } 116 | BH::OldWNDPROC = (WNDPROC)GetWindowLong(D2GFX_GetHwnd(), GWL_WNDPROC); 117 | SetWindowLong(D2GFX_GetHwnd(), GWL_WNDPROC, (LONG)GameWindowEvent); 118 | }); 119 | 120 | settingsUI = new Drawing::UI(BH_VERSION, 400, 277); 121 | 122 | Task::InitializeThreadPool(2); 123 | 124 | // Read the MPQ Data asynchronously 125 | //CreateThread(0, 0, LoadMPQData, 0, 0, 0); 126 | Task::Enqueue([]() -> void { 127 | LoadMPQData(NULL); 128 | moduleManager->MpqLoaded(); 129 | }); 130 | 131 | 132 | new ScreenInfo(); 133 | new Gamefilter(); 134 | new Bnet(); 135 | new Item(); 136 | new AutoTele(); 137 | new Party(); 138 | new ItemMover(); 139 | new StashExport(); 140 | new Maphack(); 141 | new ChatColor(); 142 | 143 | BnetBools = ((Bnet*)moduleManager->Get("bnet"))->GetBools(); 144 | GamefilterBools = ((Gamefilter*)moduleManager->Get("gamefilter"))->GetBools(); 145 | 146 | moduleManager->LoadModules(); 147 | 148 | statsDisplay = new Drawing::StatsDisplay("Stats"); 149 | 150 | MiscToggles = ((AutoTele*)moduleManager->Get("autotele"))->GetToggles(); 151 | MiscToggles2 = ((Item*)moduleManager->Get("item"))->GetToggles(); 152 | 153 | // Injection would occasionally deadlock (I only ever saw it when using Tabbed Diablo 154 | // but theoretically it could happen during regular injection): 155 | // Worker thread in DllMain->LoadModules->AutoTele::OnLoad->UITab->SetCurrentTab->Lock() 156 | // Main thread in GameDraw->UI::OnDraw->D2WIN_SetTextSize->GetDllOffset->GetModuleHandle() 157 | // GetModuleHandle can invoke the loader lock which causes the deadlock, so delay patch 158 | // installation until after all startup initialization is done. 159 | for (int n = 0; n < (sizeof(patches) / sizeof(Patch*)); n++) { 160 | patches[n]->Install(); 161 | } 162 | 163 | if (!D2CLIENT_GetPlayerUnit()) 164 | oogDraw->Install(); 165 | 166 | // GameThread can potentially run oogDraw->Install, so create the thread after all 167 | // loading/installation finishes. 168 | CreateThread(0, 0, GameThread, 0, 0, 0); 169 | 170 | initialized = true; 171 | } 172 | 173 | bool BH::Shutdown() { 174 | if (initialized){ 175 | moduleManager->UnloadModules(); 176 | 177 | delete moduleManager; 178 | delete settingsUI; 179 | delete statsDisplay; 180 | 181 | SetWindowLong(D2GFX_GetHwnd(), GWL_WNDPROC, (LONG)BH::OldWNDPROC); 182 | for (int n = 0; n < (sizeof(patches) / sizeof(Patch*)); n++) { 183 | delete patches[n]; 184 | } 185 | 186 | oogDraw->Remove(); 187 | delete config; 188 | delete itemConfig; 189 | } 190 | 191 | return true; 192 | } 193 | 194 | bool BH::ReloadConfig() { 195 | if (initialized){ 196 | if (D2CLIENT_GetPlayerUnit()) { 197 | PrintText(0, "Reloading config: %s", config->GetConfigName().c_str()); 198 | PrintText(0, "Reloading Item config: %s", itemConfig->GetConfigName().c_str()); 199 | } 200 | config->Parse(); 201 | itemConfig->Parse(); 202 | moduleManager->ReloadConfig(); 203 | statsDisplay->LoadConfig(); 204 | } 205 | return true; 206 | } 207 | -------------------------------------------------------------------------------- /BH/Modules/Party/Party.cpp: -------------------------------------------------------------------------------- 1 | #include "Party.h" 2 | #include "../../D2Ptrs.h" 3 | #include "../../BH.h" 4 | #include "../../D2Stubs.h" 5 | #include "../../D2Helpers.h" 6 | 7 | using namespace std; 8 | using namespace Drawing; 9 | Drawing::Hook* PartyHook; 10 | Drawing::Hook* LootHook; 11 | 12 | void Party::OnLoad() { 13 | BH::config->ReadToggle("Party Enabled", "None", true, Toggles["Enabled"]); 14 | BH::config->ReadToggle("Looting Enabled", "None", true, Toggles["LootEnabled"]); 15 | c = 0; 16 | 17 | PartyHook = new Drawing::Checkhook(Drawing::InGame, 100, 100, &Toggles["Enabled"].state, "Autoparty Enabled"); 18 | PartyHook->SetActive(0); 19 | LootHook = new Drawing::Checkhook(Drawing::InGame, 240, 100, &Toggles["LootEnabled"].state, "Autoloot Enabled"); 20 | LootHook->SetActive(0); 21 | } 22 | 23 | void Party::OnGameJoin() { 24 | } 25 | 26 | void Party::OnUnload() { 27 | 28 | } 29 | 30 | void Party::OnLoop() { 31 | if(Toggles["Enabled"].state || Toggles["LootEnabled"].state) 32 | CheckParty(); 33 | if(D2CLIENT_GetUIState(0x16) && PartyHook->IsActive() == 0) { 34 | PartyHook->SetBaseX(*p_D2CLIENT_PanelOffsetX + 20); 35 | PartyHook->SetActive(1); 36 | } 37 | else if(D2CLIENT_GetUIState(0x16) == 0 && PartyHook->IsActive()) 38 | PartyHook->SetActive(0); 39 | 40 | BnetData* pData = (*p_D2LAUNCH_BnData); 41 | if(!pData) 42 | return; 43 | if(D2CLIENT_GetUIState(0x16) && LootHook->IsActive() == 0 && pData->nCharFlags & PLAYER_TYPE_HARDCORE) { 44 | LootHook->SetBaseX(*p_D2CLIENT_PanelOffsetX + 160); 45 | LootHook->SetActive(1); 46 | } 47 | else if(D2CLIENT_GetUIState(0x16) == 0 && LootHook->IsActive()) 48 | LootHook->SetActive(0); 49 | } 50 | 51 | void Party::CheckParty() { 52 | if(c == 0) { 53 | std::map CurrentParty; 54 | UnitAny* Me = *p_D2CLIENT_PlayerUnit; 55 | RosterUnit* MyRoster = FindPlayerRoster(Me->dwUnitId); 56 | BnetData* pData = (*p_D2LAUNCH_BnData); 57 | 58 | WORD current_min_party_id = 0xFFFF; 59 | 60 | // first pass: check that the data is sane 61 | RosterUnit *Party = *p_D2CLIENT_PlayerUnitList; if (!Party) return; 62 | do { 63 | if(!_stricmp(Party->szName, MyRoster->szName)) 64 | continue; 65 | if(!Party->wLevel) { 66 | //PrintText(1, "!Party->wLevel"); 67 | c++; 68 | return; 69 | } 70 | if ((Party->wPartyId == INVALID_PARTY_ID && Party->dwPartyFlags & PARTY_IN_PARTY) || 71 | (Party->wPartyId != INVALID_PARTY_ID && Party->dwPartyFlags & PARTY_NOT_IN_PARTY)) { 72 | // Avoid crashing when multiple players in a game have auto-party enabled 73 | // (there seems to be a brief window in which the party data can be invalid) 74 | c++; return; 75 | } 76 | } while (Party = Party->pNext); 77 | 78 | // second pass: gather some info 79 | Party = *p_D2CLIENT_PlayerUnitList; if (!Party) return; 80 | do { 81 | if(!_stricmp(Party->szName, MyRoster->szName)) 82 | continue; 83 | current_min_party_id = min(Party->wPartyId, current_min_party_id); 84 | } while (Party=Party->pNext); 85 | 86 | // third pass: do stuff 87 | Party = *p_D2CLIENT_PlayerUnitList; if (!Party) return; 88 | do { 89 | if(!_stricmp(Party->szName, MyRoster->szName)) 90 | continue; 91 | if (pData && pData->nCharFlags & PLAYER_TYPE_HARDCORE) { 92 | CurrentParty[Party->szName] = true; 93 | if (Toggles["LootEnabled"].state) { 94 | string s(Party->szName); 95 | if (LootingPermission.find(s) == LootingPermission.end()) { 96 | //PrintText(1, "Enabling loot for %s.", s.c_str()); 97 | BYTE PacketData[7] = {0x5d,1,1,0,0,0,0}; 98 | *reinterpret_cast(PacketData + 3) = Party->dwUnitId; 99 | D2NET_SendPacket(7, 1, PacketData); 100 | LootingPermission[s] = true; 101 | } 102 | } 103 | } 104 | if ((Party->wPartyId == INVALID_PARTY_ID || Party->wPartyId != MyRoster->wPartyId) && Toggles["Enabled"].state) { 105 | //PrintText(1, "Party->wPartyID=%hu, MyRoster->wPartyId=%hu, min_party_id=%hu", 106 | // Party->wPartyId, MyRoster->wPartyId, current_min_party_id); 107 | if(Party->dwPartyFlags & PARTY_INVITED_YOU) { 108 | if (current_min_party_id != INVALID_PARTY_ID) { 109 | if (Party->wPartyId == current_min_party_id) { 110 | //PrintText(1, "Found the right party"); 111 | D2CLIENT_ClickParty(Party, 2); 112 | c++; 113 | return; 114 | } 115 | } else { 116 | //PrintText(1, "PARTY_INVITED_YOU, clicking party"); 117 | D2CLIENT_ClickParty(Party, 2); 118 | c++; 119 | return; 120 | } 121 | } 122 | if(Party->wPartyId == INVALID_PARTY_ID) { 123 | //PrintText(1, "INVALID_PARTY_ID"); 124 | if(Party->dwPartyFlags & PARTY_INVITED_BY_YOU) { 125 | //PrintText(1, "PARTY_INVITED_BY_YOU"); 126 | continue; 127 | } 128 | if (current_min_party_id != INVALID_PARTY_ID) { 129 | if (MyRoster->wPartyId == current_min_party_id) { 130 | //PrintText(1, "I'm in the right party, inviting another."); 131 | D2CLIENT_ClickParty(Party, 2); 132 | c++; 133 | return; 134 | } 135 | } else { 136 | //PrintText(1, "There's no master party, trying to form one."); 137 | D2CLIENT_ClickParty(Party, 2); 138 | c++; 139 | return; 140 | } 141 | } 142 | } 143 | 144 | } while (Party = Party->pNext); 145 | // Leave the party if we're in the wrong one 146 | if (Toggles["Enabled"].state && current_min_party_id != INVALID_PARTY_ID 147 | && MyRoster->wPartyId != current_min_party_id && MyRoster->wPartyId != INVALID_PARTY_ID) { 148 | //PrintText(1, "Not in the right party!"); 149 | //PrintText(1, "min_party_id=%hu, MyRoster->wPartyId=%hu", current_min_party_id, MyRoster->wPartyId); 150 | D2CLIENT_LeaveParty(); 151 | c++; 152 | return; 153 | } 154 | // Remove looting permissions for players no longer in the game 155 | for (auto it = LootingPermission.cbegin(); it != LootingPermission.cend(); ) { 156 | if (CurrentParty.find((*it).first) == CurrentParty.end()) { 157 | //PrintText(1, "Removing %s from looting map.", ((*it).first).c_str()); 158 | LootingPermission.erase(it++); 159 | } else { 160 | ++it; 161 | } 162 | } 163 | } 164 | c++; 165 | if(c>=25) 166 | c = 0; 167 | } 168 | 169 | void Party::OnKey(bool up, BYTE key, LPARAM lParam, bool* block) { 170 | if(!D2CLIENT_GetPlayerUnit()) 171 | return; 172 | 173 | if (D2CLIENT_GetUIState(UI_INVENTORY) || D2CLIENT_GetUIState(UI_STASH) || D2CLIENT_GetUIState(UI_CUBE)) { 174 | // Avoid toggling state when pressing number keys to drop/withdraw/deposit gold. 175 | // There is no UI state for the gold dialogs, so we have to disable whenever 176 | // stash/inventory are open. 177 | return; 178 | } 179 | 180 | for (map::iterator it = Toggles.begin(); it != Toggles.end(); it++) { 181 | if (key == (*it).second.toggle) { 182 | *block = true; 183 | if (up) { 184 | (*it).second.state = !(*it).second.state; 185 | } 186 | return; 187 | } 188 | } 189 | } 190 | 191 | void Party::OnGameExit() { 192 | LootingPermission.clear(); 193 | } 194 | -------------------------------------------------------------------------------- /BH/Drawing/Basic/Texthook/Texthook.cpp: -------------------------------------------------------------------------------- 1 | #include "Texthook.h" 2 | #include "../../../Common.h" 3 | #include "../../../D2Ptrs.h" 4 | 5 | using namespace std; 6 | using namespace Drawing; 7 | 8 | /* Basic Hook Initializer 9 | * Used for just drawing basic text on screen. 10 | */ 11 | Texthook::Texthook(HookVisibility visibility, unsigned int x, unsigned int y, std::string formatString, ...) : 12 | Hook(visibility, x, y) { 13 | //Correctly format the string from the given arguments. 14 | SetFont(0); 15 | SetColor(White); 16 | SetHoverColor(Disabled); 17 | char buffer[4096]; 18 | va_list arg; 19 | va_start(arg, formatString); 20 | vsprintf_s(buffer, 4096, formatString.c_str(), arg); 21 | va_end(arg); 22 | text = buffer; 23 | } 24 | 25 | /* Group Hook Initializer 26 | * Used in conjuction with other basic hooks to create an advanced hook. 27 | */ 28 | Texthook::Texthook(HookGroup *group, unsigned int x, unsigned int y, std::string formatString, ...) : 29 | Hook(group, x, y) { 30 | //Correctly format the string from the given arguments. 31 | SetFont(0); 32 | SetColor(White); 33 | SetHoverColor(Disabled); 34 | char buffer[4096]; 35 | va_list arg; 36 | va_start(arg, formatString); 37 | vsprintf_s(buffer, 4096, formatString.c_str(), arg); 38 | va_end(arg); 39 | text = buffer; 40 | } 41 | 42 | /* GetFont() 43 | * Returns what d2 font we use to draw. 44 | */ 45 | unsigned int Texthook::GetFont() { 46 | return font; 47 | } 48 | 49 | /* SetFont(unsigned int newFont) 50 | * Sets when the font to draw with. 51 | */ 52 | void Texthook::SetFont(unsigned int newFont) { 53 | Lock(); 54 | font = newFont; 55 | Unlock(); 56 | } 57 | 58 | /* GetColor() 59 | * Returns what color the text will be drawn. 60 | */ 61 | TextColor Texthook::GetColor() { 62 | return color; 63 | } 64 | 65 | /* SetColor() 66 | * Sets what color the text will be drawn in. 67 | */ 68 | void Texthook::SetColor(TextColor newColor) { 69 | Lock(); 70 | color = newColor; 71 | Unlock(); 72 | } 73 | 74 | /* GetHoverColor() 75 | * Return what color the text will be when hovered. 76 | */ 77 | TextColor Texthook::GetHoverColor() { 78 | return hoverColor; 79 | } 80 | 81 | /* SetHoverColor() 82 | * Sets what color to draw when hovered. 83 | */ 84 | void Texthook::SetHoverColor(TextColor newHoverColor) { 85 | Lock(); 86 | hoverColor = newHoverColor; 87 | Unlock(); 88 | } 89 | 90 | /* GetText() 91 | * Returns what text will be drawn. 92 | */ 93 | std::string Texthook::GetText() { 94 | return text; 95 | } 96 | 97 | /* SetText(string formaString, ...) 98 | * Sets a new formatted string as the text 99 | */ 100 | void Texthook::SetText(std::string formatString, ...) { 101 | char buffer[4096]; 102 | va_list arg; 103 | va_start(arg, formatString); 104 | vsprintf_s(buffer, 4096, formatString.c_str(), arg); 105 | va_end(arg); 106 | text = buffer; 107 | } 108 | 109 | /* GetXSize() 110 | * Returns how long the text is. 111 | */ 112 | unsigned int Texthook::GetXSize() { 113 | DWORD width, fileNo; 114 | wchar_t* wString = AnsiToUnicode(text.c_str()); 115 | DWORD oldFont = D2WIN_SetTextSize(font); 116 | D2WIN_GetTextWidthFileNo(wString, &width, &fileNo); 117 | D2WIN_SetTextSize(oldFont); 118 | delete[] wString; 119 | return width; 120 | } 121 | 122 | /* GetXSize() 123 | * Returns how tall the text is. 124 | */ 125 | unsigned int Texthook::GetYSize() { 126 | unsigned int nHeight[] = {10,11,18,24,10,13,7,13,10,12,8,8,7,12}; 127 | return nHeight[font]; 128 | } 129 | 130 | /* Draw() 131 | * Draws the text, must be called inside a Draw Patch 132 | */ 133 | void Texthook::OnDraw() { 134 | if (!IsActive()) 135 | return; 136 | 137 | Lock(); 138 | wchar_t* wString = AnsiToUnicode(text.c_str()); 139 | 140 | unsigned int drawColor = color; 141 | if (InRange(*p_D2CLIENT_MouseX, *p_D2CLIENT_MouseY) && GetHoverColor() != Disabled) 142 | drawColor = hoverColor; 143 | 144 | DWORD oldFont = D2WIN_SetTextSize(font); 145 | D2WIN_DrawText(wString, GetX(), GetY() + GetYSize(), drawColor, 0); 146 | D2WIN_SetTextSize(oldFont); 147 | delete[] wString; 148 | Unlock(); 149 | } 150 | 151 | /* OnLeftClick(bool up, unsigned int x, unsigned int y) 152 | * Check if the text hook has been clicked on. 153 | */ 154 | bool Texthook::OnLeftClick(bool up, unsigned int x, unsigned int y) { 155 | if (InRange(x,y) && GetLeftClickHandler()) { 156 | bool block = false; 157 | Lock(); 158 | block = GetLeftClickHandler()(up, this, GetLeftClickVoid()); 159 | Unlock(); 160 | return block; 161 | } 162 | return false; 163 | } 164 | 165 | /* OnRightClick(bool up, unsigned int x, unsigned int y) 166 | * Check if the text hook has been clicked on. 167 | */ 168 | bool Texthook::OnRightClick(bool up, unsigned int x, unsigned int y) { 169 | if (InRange(x,y) && GetRightClickHandler()) { 170 | bool block = false; 171 | Lock(); 172 | block = GetRightClickHandler()(up, this, GetRightClickVoid()); 173 | Unlock(); 174 | return block; 175 | } 176 | return false; 177 | } 178 | 179 | /* GetTextSize(string text, unsigned int font) 180 | * Returns the dimensions of the given text! 181 | */ 182 | POINT Texthook::GetTextSize(string text, unsigned int font) { 183 | unsigned int height[] = {10,11,18,24,10,13,7,13,10,12,8,8,7,12}; 184 | DWORD width, fileNo; 185 | wchar_t* wString = AnsiToUnicode(text.c_str()); 186 | DWORD oldFont = D2WIN_SetTextSize(font); 187 | D2WIN_GetTextWidthFileNo(wString, &width, &fileNo); 188 | D2WIN_SetTextSize(oldFont); 189 | POINT point = {width, height[font]}; 190 | delete[] wString; 191 | return point; 192 | } 193 | 194 | POINT Texthook::GetTextSize(wchar_t* text, unsigned int font) { 195 | unsigned int height[] = { 10,11,18,24,10,13,7,13,10,12,8,8,7,12 }; 196 | DWORD width, fileNo; 197 | DWORD oldFont = D2WIN_SetTextSize(font); 198 | D2WIN_GetTextWidthFileNo(text, &width, &fileNo); 199 | D2WIN_SetTextSize(oldFont); 200 | POINT point = { width, height[font] }; 201 | return point; 202 | } 203 | 204 | /* Draw(unsigned int x, unsigned int y, unsigned int font, TextColor color, std::string text, ...) 205 | * Static function to wrap drawing text on screen, to be used for things that are rapidly changing(Monsters on map, etc..) 206 | */ 207 | bool Texthook::Draw(unsigned int x, unsigned int y, int align, unsigned int font, TextColor color, std::string text, ...) { 208 | //Convert all %s's into proper values. 209 | char buffer[4096]; 210 | va_list arg; 211 | va_start(arg, text); 212 | vsprintf_s(buffer, 4096, text.c_str(), arg); 213 | va_end(arg); 214 | 215 | //Convert multi-byte to wide character 216 | wchar_t* wString = AnsiToUnicode(buffer); 217 | 218 | unsigned int properX = x; 219 | if (align == Center) 220 | x = x - (GetTextSize(buffer, font).x / 2); 221 | 222 | if (align == Right) 223 | x = x - GetTextSize(buffer, font).x; 224 | 225 | //Draw the text! 226 | unsigned int height[] = {10,11,18,24,10,13,7,13,10,12,8,8,7,12}; 227 | DWORD size = D2WIN_SetTextSize(font); 228 | D2WIN_DrawText(wString, x, y + height[font], color, 0); 229 | D2WIN_SetTextSize(size); 230 | 231 | delete[] wString; 232 | return true; 233 | } 234 | 235 | bool Texthook::Draw(unsigned int x, unsigned int y, int align, unsigned int font, TextColor color, wchar_t* text, ...) { 236 | //Convert all %s's into proper values. 237 | wchar_t* buffer = new wchar_t[4096]; 238 | va_list arg; 239 | va_start(arg, text); 240 | vswprintf_s(buffer, 4096, text, arg); 241 | va_end(arg); 242 | 243 | unsigned int properX = x; 244 | if (align == Center) 245 | x = x - (GetTextSize(buffer, font).x / 2); 246 | 247 | if (align == Right) 248 | x = x - GetTextSize(buffer, font).x; 249 | 250 | //Draw the text! 251 | unsigned int height[] = { 10,11,18,24,10,13,7,13,10,12,8,8,7,12 }; 252 | DWORD size = D2WIN_SetTextSize(font); 253 | D2WIN_DrawText(buffer, x, y + height[font], color, 0); 254 | D2WIN_SetTextSize(size); 255 | 256 | delete[] buffer; 257 | return true; 258 | } --------------------------------------------------------------------------------