diff --git a/ASLR_fix.patch b/ASLR_fix.patch new file mode 100644 index 0000000..1c302ca --- /dev/null +++ b/ASLR_fix.patch @@ -0,0 +1,286 @@ +diff --git a/PlugY/D2wrapper.cpp b/PlugY/D2wrapper.cpp +index d13608e..ffd02f2 100644 +--- a/PlugY/D2wrapper.cpp ++++ b/PlugY/D2wrapper.cpp +@@ -291,6 +291,7 @@ void loadCustomLibraries() + log_msg("\n\n"); + } + ++/* + void loadLibrary(LPCSTR libName, int* libVersion, DWORD* libOffset, int shift, DWORD v109b, DWORD v109d, DWORD v110, DWORD v111, DWORD v111b, DWORD v112, DWORD v113c) + { + *libOffset = (DWORD)LoadLibrary(libName); +@@ -386,6 +387,273 @@ void initD2modules() + + log_msg("\n\n"); + } ++*/ ++ ++IMAGE_NT_HEADERS* GetHeader(LPBYTE pBase) { ++ if (pBase == NULL) ++ return NULL; ++ ++ IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)pBase; ++ ++ if (IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER))) ++ return NULL; ++ ++ if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) ++ return NULL; ++ ++ IMAGE_NT_HEADERS* pHeader = (IMAGE_NT_HEADERS*)(pBase + pDosHeader->e_lfanew); ++ if (IsBadReadPtr(pHeader, sizeof(IMAGE_NT_HEADERS))) ++ return NULL; ++ ++ if (pHeader->Signature != IMAGE_NT_SIGNATURE) ++ return NULL; ++ ++ return pHeader; ++} ++ ++void initD2modules() ++{ ++ log_msg("***** Get D2 Modules address and version *****\n\n"); ++ ++ offset_D2Client = (DWORD)LoadLibrary("D2Client.dll"); ++ offset_D2CMP = (DWORD)LoadLibrary("D2CMP.dll"); ++ offset_D2Common = (DWORD)LoadLibrary("D2Common.dll"); ++ offset_D2Game = (DWORD)LoadLibrary("D2Game.dll"); ++ offset_D2gfx = (DWORD)LoadLibrary("D2gfx.dll"); ++ offset_D2Lang = (DWORD)LoadLibrary("D2Lang.dll"); ++ offset_D2Launch = (DWORD)LoadLibrary("D2Launch.dll"); ++ offset_D2Net = (DWORD)LoadLibrary("D2Net.dll"); ++ offset_D2Win = (DWORD)LoadLibrary("D2Win.dll"); ++ offset_Fog = (DWORD)LoadLibrary("Fog.dll"); ++ offset_Storm = (DWORD)LoadLibrary("Storm.dll"); ++ ++ int count_109b = 0; ++ int count_109d = 0; ++ int count_110f = 0; ++ int count_111 = 0; ++ int count_111b = 0; ++ int count_112a = 0; ++ int count_113c = 0; ++ int count_113d = 0; ++ int count_114a = 0; ++ int count_114b = 0; ++ int count_114c = 0; ++ int count_114d = 0; ++ ++ IMAGE_NT_HEADERS* pHeader; ++ ++ if (offset_D2Client != NULL) { ++ pHeader = GetHeader((LPBYTE)offset_D2Client); ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C234D) count_109b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C16CD) count_109d++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C1C1D) count_110f++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045E6) count_111++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045EE) count_111b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045FA) count_112a++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045F6) count_113c++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045DE) count_113d++; ++ } ++ ++ if (offset_D2CMP != NULL) { ++ pHeader = GetHeader((LPBYTE)offset_D2CMP); ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00011361) count_109b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00011361) count_109d++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00010E61) count_110f++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_111++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_111b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_112a++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_113c++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_113d++; ++ } ++ ++ if (offset_D2Common != NULL) { ++ pHeader = GetHeader((LPBYTE)offset_D2Common); ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00074D1D) count_109b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00074E2D) count_109d++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000856DD) count_110f++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C94) count_111++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C8D) count_111b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C97) count_112a++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C8F) count_113c++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000047C7) count_113d++; ++ } ++ ++ if (offset_D2Game != NULL) { ++ pHeader = GetHeader((LPBYTE)offset_D2Game); ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C66AC) count_109b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C6D5C) count_109d++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000EDC2C) count_110f++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000036E6) count_111++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000373D) count_111b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000374B) count_112a++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000373C) count_113c++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003747) count_113d++; ++ } ++ ++ if (offset_D2gfx != NULL) { ++ pHeader = GetHeader((LPBYTE)offset_D2gfx); ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054EB) count_109b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054EB) count_109d++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054A5) count_110f++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_111++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_111b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_112a++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_113c++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_113d++; ++ } ++ ++ if (offset_D2Lang != NULL) { ++ pHeader = GetHeader((LPBYTE)offset_D2Lang); ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005148) count_109b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005138) count_109d++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005048) count_110f++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A6A) count_111++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A5B) count_111b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A75) count_112a++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A71) count_113c++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A5A) count_113d++; ++ } ++ ++ if (offset_D2Launch != NULL) { ++ pHeader = GetHeader((LPBYTE)offset_D2Launch); ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000172C3) count_109b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00017243) count_109d++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00018DC7) count_110f++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A84) count_111++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A85) count_111b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A85) count_112a++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A87) count_113c++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A84) count_113d++; ++ } ++ ++ if (offset_D2Net != NULL) { ++ pHeader = GetHeader((LPBYTE)offset_D2Net); ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002BCE) count_109b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002BCE) count_109d++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C6E) count_110f++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_111++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_111b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000167E) count_112a++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_113c++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000167E) count_113d++; ++ } ++ ++ if (offset_D2Win != NULL) { ++ pHeader = GetHeader((LPBYTE)offset_D2Win); ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00014F38) count_109b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00014F38) count_109d++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00012EC0) count_110f++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_111++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_111b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000188E) count_112a++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_113c++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001887) count_113d++; ++ } ++ ++ if (offset_Fog != NULL) { ++ pHeader = GetHeader((LPBYTE)offset_Fog); ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00013658) count_109b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000142E7) count_109d++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000162B0) count_110f++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003159) count_111++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_111b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000314A) count_112a++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003162) count_113c++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_113d++; ++ } ++ ++ if (offset_Storm != NULL) { ++ pHeader = GetHeader((LPBYTE)offset_Storm); ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00013658) count_109b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000142E7) count_109d++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000162B0) count_110f++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003159) count_111++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_111b++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000314A) count_112a++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003162) count_113c++; ++ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0003C3E0) count_113d++; ++ } ++ ++ int minimum_match_dll = 7; ++ ++ if (count_109b >= minimum_match_dll) version_Game = V109b; ++ if (count_109d >= minimum_match_dll) version_Game = V109d; ++ if (count_110f >= minimum_match_dll) version_Game = V110; ++ if (count_111 >= minimum_match_dll) version_Game = V111; ++ if (count_111b >= minimum_match_dll) version_Game = V111b; ++ if (count_112a >= minimum_match_dll) version_Game = V112; ++ if (count_113c >= minimum_match_dll) version_Game = V113c; ++ if (count_113d >= minimum_match_dll) version_Game = V113d; ++ ++ //version_SmackW32 = version_Game; ++ version_D2Common = version_Game; ++ //version_ijl11 = version_Game; ++ //version_D2Gdi = version_Game; ++ version_D2Win = version_Game; ++ //version_D2sound = version_Game; ++ //version_D2MCPCLI = version_Game; ++ version_D2Launch = version_Game; ++ version_D2gfx = version_Game; ++ version_D2Client = version_Game; ++ version_D2Net = version_Game; ++ version_D2Lang = version_Game; ++ version_D2Game = version_Game; ++ version_D2CMP = version_Game; ++ //version_Bnclient = version; ++ version_Fog = version_Game; ++ version_Storm = version_Game; ++ ++ log_msg("DLL match for version 1.09b :\t%d\n", count_109b); ++ log_msg("DLL match for version 1.09d :\t%d\n", count_109d); ++ log_msg("DLL match for version 1.10f :\t%d\n", count_110f); ++ log_msg("DLL match for version 1.11 :\t%d\n", count_111); ++ log_msg("DLL match for version 1.11b :\t%d\n", count_111b); ++ log_msg("DLL match for version 1.12a :\t%d\n", count_112a); ++ log_msg("DLL match for version 1.13c :\t%d\n", count_113c); ++ log_msg("\n"); ++ ++ offset_Game = (DWORD)GetModuleHandle("Game.exe"); ++ if (offset_Game != NULL) { ++ version_Game = GetD2Version((HMODULE)offset_Game); ++ log_msg("Game.exe loaded at:\t%08X (%s)\n", offset_Game, GetVersionString(version_Game)); ++ if (version_Game >= V114a) ++ { ++ //version_SmackW32 = version_Game; ++ version_D2Common = version_Game; ++ //version_ijl11 = version_Game; ++ //version_D2Gdi = version_Game; ++ version_D2Win = version_Game; ++ //version_D2sound = version_Game; ++ //version_D2MCPCLI = version_Game; ++ version_D2Launch = version_Game; ++ version_D2gfx = version_Game; ++ version_D2Client = version_Game; ++ version_D2Net = version_Game; ++ version_D2Lang = version_Game; ++ version_D2Game = version_Game; ++ version_D2CMP = version_Game; ++ //version_Bnclient = version; ++ version_Fog = version_Game; ++ version_Storm = version_Game; ++ } ++ } ++ ++ //if (offset_Game != NULL) { ++ // pHeader = GetHeader((LPBYTE)offset_Game); ++ // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00291342) count_114a++; ++ // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x002854F2) count_114b++; ++ // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x002850E2) count_114c++; ++ // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00282985) count_114d++; ++ //} ++ ++ log_msg("Version game is:\t(%s)\n\n", GetVersionString(version_Game)); ++ ++ if (version_Game == UNKNOWN) ++ { ++ MessageBoxA(NULL, "This version of Diablo II is not supported by Plugy. Please upgrade or downgrade to a supported version.", "Plugy 14.03", MB_OK); ++ } ++} ++ + //////////////////////////////////// EXPORTS FUNCTIONS //////////////////////////////////// + + diff --git a/HD_fix.patch b/HD_fix.patch new file mode 100644 index 0000000..a527c15 --- /dev/null +++ b/HD_fix.patch @@ -0,0 +1,887 @@ +diff --git a/PlugY/InfinityStash.cpp b/PlugY/InfinityStash.cpp +index 22e9c35..ea09d36 100644 +--- a/PlugY/InfinityStash.cpp ++++ b/PlugY/InfinityStash.cpp +@@ -26,6 +26,7 @@ bool active_sharedStash = false; + bool separateHardSoftStash = false; + bool active_sharedGold=false; + char* sharedStashFilename = NULL; ++DWORD saveFileStackSize = 0x2000; + + typedef int (*TchangeToSelectedStash)(Unit* ptChar, Stash* newStash, DWORD bOnlyItems, DWORD bIsClient); + +@@ -422,7 +423,7 @@ void saveStashList(Unit* ptChar, Stash* ptStash, BYTE** data, DWORD* maxSize, DW + + while(ptStash) + { +- if (*curSize + 0x2000 > *maxSize) ++ if (*curSize + saveFileStackSize > *maxSize) + { + BYTE* oldData = *data; + *maxSize *= 2; +diff --git a/PlugY/Interface_Skills.cpp b/PlugY/Interface_Skills.cpp +index 90178f7..8a07c2a 100644 +--- a/PlugY/Interface_Skills.cpp ++++ b/PlugY/Interface_Skills.cpp +@@ -49,9 +49,10 @@ Unit* STDCALL skillsPageMouseDown(sWinMessage* msg) + if (active_SkillsPoints && !onRealm && D2isLODGame() && isOnButtonUnassignSkill(D2GetMouseX(),D2GetMouseY())) + { + log_msg("push down left button unassign skill\n"); +- btnSkillIsDown = 1; ++ //btnSkillIsDown = 1; + D2PlaySound(4,0,0,0,0); + freeMessage(msg); ++ updateServer(US_UNASSIGN_SKILLS); + return NULL; + } + return ptChar; +@@ -233,6 +234,7 @@ void Install_InterfaceSkills() + //6FAE1112 > C745 18 00000000 MOV DWORD PTR SS:[EBP+18],0 + //004ABC1A |> C746 18 00000000 MOV DWORD PTR DS:[ESI+18],0 + ++ /* Conflicts with D2ExpRes + // Manage mouse up + mem_seek R8(D2Client, 7BC40, 7BC40, 78466, 17558, 8C078, 80248, 795F8, 30AA8, ABC96); + MEMJ_REF4( D2FreeWinMessage, caller_skillsPageMouseUp);//0xFFF93B0A +@@ -243,6 +245,7 @@ void Install_InterfaceSkills() + //6FB295F7 .^E9 8828F9FF JMP + //6FAE0AA7 .^E9 E0B2FDFF JMP + //004ABC95 |. E8 F645F7FF CALL Game.00420290 ++ */ + + log_msg("\n"); + +diff --git a/PlugY/Interface_Stats.cpp b/PlugY/Interface_Stats.cpp +index 85e6029..1d3a4cf 100644 +--- a/PlugY/Interface_Stats.cpp ++++ b/PlugY/Interface_Stats.cpp +@@ -13,6 +13,7 @@ + #include "common.h" + #include + ++/* + static struct + { + union{ +@@ -35,6 +36,7 @@ static struct + #define getYNextPageBtn() RY(D2GetResolution()?0x40:0x70) + #define getHNextPageBtn() 32 + #define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn()) ++*/ + + + +@@ -49,7 +51,7 @@ void STDCALL printStatsPageBtns() + sDrawImageInfo data; + ZeroMemory(&data,sizeof(data)); + +- if (printBackgroundOnMainPage && D2GetResolution()) ++ if (printBackgroundOnMainPage) + { + setImage(&data, statsBackgroundImages); + setFrame(&data, 1); +@@ -57,16 +59,14 @@ void STDCALL printStatsPageBtns() + } + + setImage(&data, D2LoadBuySelBtn()); +- if (D2GetResolution()) +- { +- setFrame(&data, 12 + isDownBtn.previousPage); +- D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0); +- } ++ setFrame(&data, 12 + isDownBtn.previousPage); ++ D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0); ++ + setFrame(&data, 14 + isDownBtn.nextPage); + D2PrintImage(&data, getXNextPageBtn(), getYNextPageBtn(), -1, 5, 0); + + D2SetFont(1); +- if (D2GetResolution() && isOnPreviousPageBtn(mx,my)) //print popup "previous page" ++ if (isOnPreviousPageBtn(mx,my)) //print popup "previous page" + { + lpText = getLocalString(STR_PREVIOUS_PAGE); + D2PrintPopup(lpText, getXPreviousPageBtn()+getLPreviousPageBtn()/2, getYPreviousPageBtn()-getHPreviousPageBtn(), WHITE, 1); +@@ -84,6 +84,12 @@ Unit* STDCALL statsPageMouseDown(sWinMessage* msg) + + if (!active_newInterfaces || !D2isLODGame() ) return ptChar; + ++ if (statsLeftDown(msg)) { ++ freeMessage(msg); ++ return NULL; ++ } ++ ++ /* + if (D2GetResolution() && isOnPreviousPageBtn(msg->x,msg->y)) + { + log_msg("push down left button previous page\n"); +@@ -100,6 +106,7 @@ Unit* STDCALL statsPageMouseDown(sWinMessage* msg) + freeMessage(msg); + return NULL; + } ++ */ + return ptChar; + } + +@@ -110,6 +117,13 @@ Unit* STDCALL statsPageMouseUp(sWinMessage* msg) + + if (!active_newInterfaces || !D2isLODGame() ) return ptChar; + ++ if (statsLeftUp(msg)) { ++ isDownBtn.all=0; ++ freeMessage(msg); ++ return NULL; ++ } ++ ++ /* + if (D2GetResolution() && isOnPreviousPageBtn(msg->x,msg->y)) + { + log_msg("push up left button previous page\n"); +@@ -134,6 +148,7 @@ Unit* STDCALL statsPageMouseUp(sWinMessage* msg) + return NULL; + } + } ++ */ + + isDownBtn.all=0; + return ptChar; +diff --git a/PlugY/LocalizedStrings.cpp b/PlugY/LocalizedStrings.cpp +index 70595ee..3c76d87 100644 +--- a/PlugY/LocalizedStrings.cpp ++++ b/PlugY/LocalizedStrings.cpp +@@ -51,7 +51,7 @@ LPCWSTR getLocalTypeString(DWORD code) + { + if (sLocalizedTypeStrings[i].code == code) + { +- log_msg("Code=%08X\n", code); ++ //log_msg("Code=%08X\n", code); + if (sLocalizedTypeStrings[i].itemStr) + return StripGender(D2GetStringFromString(sLocalizedTypeStrings[i].itemStr)); + LPWSTR text = StripGender(sLocalizedTypeStrings[i].typeLocalizedString); +@@ -300,6 +300,8 @@ void loadLocalizedStrings(int language) + LOAD(STR_SHARED_GOLD_QUANTITY); + LOAD(STR_PREVIOUS_PAGE); + LOAD(STR_NEXT_PAGE); ++ LOAD(STR_PREVIOUS_RUNE); ++ LOAD(STR_NEXT_RUNE); + LOAD(STR_ITEM_LEVEL); + LOAD(STR_PAGE_TYPE_CHANGE); + +diff --git a/PlugY/LocalizedStrings.h b/PlugY/LocalizedStrings.h +index 9fb08e7..0e7b83d 100644 +--- a/PlugY/LocalizedStrings.h ++++ b/PlugY/LocalizedStrings.h +@@ -37,6 +37,8 @@ enum eStringList + STR_SHARED_GOLD_QUANTITY, + STR_PREVIOUS_PAGE, + STR_NEXT_PAGE, ++ STR_PREVIOUS_RUNE, ++ STR_NEXT_RUNE, + STR_ITEM_LEVEL, + STR_PAGE_TYPE_CHANGE, + // +diff --git a/PlugY/NewInterface_CubeListing.cpp b/PlugY/NewInterface_CubeListing.cpp +index 1c54331..d50c8bc 100644 +--- a/PlugY/NewInterface_CubeListing.cpp ++++ b/PlugY/NewInterface_CubeListing.cpp +@@ -233,12 +233,6 @@ DWORD print(CubeMainBIN* curForm, LPWSTR buf, LPINT len, DWORD)//maxsize) + printInputItem(&curForm->input6, buf, len, &realNbInputs); + printInputItem(&curForm->input7, buf, len, &realNbInputs); + +- if (realNbInputs != curForm->numinputs) +- { +- PRINT(BUF, L" *** ERROR : numInputs(%d) != realNbInputs(%d) ***", curForm->numinputs, realNbInputs); +- return 1; +- } +- + PRINT(BUF,L" => "); + int realNbOutputs=0; + +@@ -269,6 +263,9 @@ DWORD print(CubeMainBIN* curForm, LPWSTR buf, LPINT len, DWORD)//maxsize) + // if (curForm->version == 100) + // sprintf(BUF, " [expansion only]"); + ++ if (realNbInputs != curForm->numinputs) ++ PRINT(BUF, L" *** ERROR : numInputs(%d) != realNbInputs(%d) ***", curForm->numinputs, realNbInputs); ++ + return 1; + } + #undef BUF +diff --git a/PlugY/NewInterface_Runewords.cpp b/PlugY/NewInterface_Runewords.cpp +index 99d1f38..13efd9f 100644 +--- a/PlugY/NewInterface_Runewords.cpp ++++ b/PlugY/NewInterface_Runewords.cpp +@@ -12,6 +12,7 @@ + #include "common.h" + #include + ++/* + #define NB_RUNES_PER_PAGE 25 + + #define getXCloseBtn() 360 +@@ -53,6 +54,7 @@ static struct + }; + }; + } isDownBtn; ++*/ + + + void printRuneword(RunesBIN* runesData, DWORD pos) +@@ -64,7 +66,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos) + D2SetFont(6); + DWORD nbPixel = D2GetPixelLen(lpText); + DWORD x1 = (nbPixel >= 195) ? 0 : 195-nbPixel; +- D2PrintString(lpText, x1, 10 + pos*20, GOLD, 0);//MILIEU(0x00,0x70,nbPixel) ++ D2PrintString(lpText, posXRunesList + RX(x1), posYRunesList + 10 + pos*20, GOLD, 0);//MILIEU(0x00,0x70,nbPixel) + + typesList[0]=L'\0'; + DWORD numItype=0; +@@ -80,7 +82,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos) + } + nbPixel = D2GetPixelLen(typesList); + x1 = (nbPixel >= 195) ? 0 : 195-nbPixel; +- D2PrintString(typesList, x1, 20 + pos*20, WHITE, 0);//MILIEU(0x70,0xA0,nbPixel) ++ D2PrintString(typesList, posXRunesList + RX(x1), posYRunesList + 20 + pos*20, WHITE, 0);//MILIEU(0x70,0xA0,nbPixel) + + runesList[0]=L'\0'; + DWORD numRune=0; +@@ -115,7 +117,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos) + } + + // x1 = (nbPixel < 145) ? 155 : 300-nbPixel; +- D2PrintString(runesList, x1, y1 + pos*20, WHITE, 0);//MILIEU(0xD0,0xA0,nbPixel) ++ D2PrintString(runesList, posXRunesList + RX(x1), posYRunesList + y1 + pos*20, WHITE, 0);//MILIEU(0xD0,0xA0,nbPixel) + } + + +@@ -123,48 +125,58 @@ void printRuneword(RunesBIN* runesData, DWORD pos) + //6FB21FAA + void STDCALL printRunewordsPage() + { +- if (!D2isLODGame() || !D2GetResolution()) return D2PrintStatsPage(); ++ if (!D2isLODGame()) return D2PrintStatsPage(); + + LPWSTR lpText; +- bDontPrintBorder = true; ++ bDontPrintBorder = D2GetResolution()? true : false; + + //Init data for print image + sDrawImageInfo data; + ZeroMemory(&data,sizeof(data)); + + //print background +-/* setImage(&data, newStatsInterfaceImages); ++ fillRect(RX(0), RY(ResolutionY), 512, 768, 0, 5); ++ setImage(&data, newStatsInterfaceImages); + setFrame(&data, 0); +- D2PrintImage(&data, 0, 256, -1, 5, 0); ++ D2PrintImage(&data, RX(0), RY(ResolutionY-256), -1, 5, 0); + setFrame(&data, 1); +- D2PrintImage(&data, 256,256, -1, 5, 0); ++ D2PrintImage(&data, RX(256),RY(ResolutionY-256), -1, 5, 0); + setFrame(&data, 2); +- D2PrintImage(&data, 0, 512, -1, 5, 0); ++ D2PrintImage(&data, RX(0), RY(ResolutionY-256*2), -1, 5, 0); + setFrame(&data, 3); +- D2PrintImage(&data, 256,512, -1, 5, 0); ++ D2PrintImage(&data, RX(256),RY(ResolutionY-256*2), -1, 5, 0); + setFrame(&data, 4); +- D2PrintImage(&data, 0, 552, -1, 5, 0); ++ D2PrintImage(&data, RX(0), RY(ResolutionY-256*3), -1, 5, 0); + setFrame(&data, 5); +- D2PrintImage(&data, 256,552, -1, 5, 0); +-*/ +- fillRect(0,0,400,552,0,5); ++ D2PrintImage(&data, RX(256),RY(ResolutionY-256*3), -1, 5, 0); ++ ++ if (printBackgroundOnMainPage) ++ { ++ setImage(&data, statsBackgroundImages); ++ setFrame(&data, 1); ++ D2PrintImage(&data, getXPreviousPageBtn()-7, getYPreviousPageBtn()+8, -1, 5, 0); ++ D2PrintImage(&data, getXPrevRunesBtn()-7, getYPrevRunesBtn()+8, -1, 5, 0); ++ } + + //print button close + setImage(&data, D2LoadBuySelBtn()); + setFrame(&data, 10 + isDownBtn.close); + D2PrintImage(&data, getXCloseBtn(), getYCloseBtn(), -1, 5, 0); + ++ //print previous page button ++ setFrame(&data, 12 + isDownBtn.previousPage); ++ D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0); ++ + //print next page button +- setFrame(&data, isDownBtn.nextPage); ++ setFrame(&data, 14 + isDownBtn.nextPage); + D2PrintImage(&data, getXNextPageBtn(), getYNextPageBtn(), -1, 5, 0); + + //print previous runes button +- setImage(&data, stashBtnsImages); +- setFrame(&data, isDownBtn.prevRunes); ++ setFrame(&data, 12 + isDownBtn.prevRunes); + D2PrintImage(&data, getXPrevRunesBtn(), getYPrevRunesBtn(), -1, 5, 0); + + //print previous runes button +- setFrame(&data, 2 + isDownBtn.nextRunes); ++ setFrame(&data, 14 + isDownBtn.nextRunes); + D2PrintImage(&data, getXNextRunesBtn(), getYNextRunesBtn(), -1, 5, 0); + + D2SetFont(6); +@@ -181,11 +193,11 @@ void STDCALL printRunewordsPage() + { + if (!runesData->Complete || runesData->Server) continue; + nbRunesCompleted++; +- if ( (curRunesPage * NB_RUNES_PER_PAGE < nbRunesCompleted) && +- (nbRunesCompleted <= (curRunesPage+1) * NB_RUNES_PER_PAGE) ) ++ if ( (curRunesPage * runesPerPage < nbRunesCompleted) && ++ (nbRunesCompleted <= (curRunesPage+1) * runesPerPage) ) + printRuneword(runesData, curNbRunes++); + } +- maxRunesPage = nbRunesCompleted ? (nbRunesCompleted-1) / NB_RUNES_PER_PAGE : 0; ++ maxRunesPage = nbRunesCompleted ? (nbRunesCompleted-1) / runesPerPage : 0; + + + //////////////////// POPUP PRINTING //////////////////// +@@ -197,11 +209,26 @@ void STDCALL printRunewordsPage() + { + D2PrintPopup(D2GetStringFromIndex(0x1030), getXCloseBtn()+getLCloseBtn()/2, getYCloseBtn()-getHCloseBtn(), WHITE, 1); + } ++ else if (isOnPreviousPageBtn(x,y)) //print popup "previous page" ++ { ++ lpText = getLocalString(STR_PREVIOUS_PAGE); ++ D2PrintPopup(lpText, getXPreviousPageBtn()+getLPreviousPageBtn()/2, getYPreviousPageBtn()-getHPreviousPageBtn(), WHITE, 1); ++ } + else if (isOnNextPageBtn(x,y)) // print popup "next page" + { + lpText = getLocalString(STR_NEXT_PAGE); + D2PrintPopup(lpText, getXNextPageBtn()+getLNextPageBtn()/2, getYNextPageBtn()-getHNextPageBtn(), WHITE, 1); + } ++ else if (isOnPrevRunesBtn(x,y)) // print popup "previous rune" ++ { ++ lpText = getLocalString(STR_PREVIOUS_RUNE); ++ D2PrintPopup(lpText, getXPrevRunesBtn()+getLPrevRunesBtn()/2, getYPrevRunesBtn()-getHPrevRunesBtn(), WHITE, 1); ++ } ++ else if (isOnNextRunesBtn(x,y)) // print popup "next rune" ++ { ++ lpText = getLocalString(STR_NEXT_RUNE); ++ D2PrintPopup(lpText, getXNextRunesBtn()+getLNextRunesBtn()/2, getYNextRunesBtn()-getHNextRunesBtn(), WHITE, 1); ++ } + } + + ////////////////////////////////////////////////////////////////////////////////////////////// +diff --git a/PlugY/NewInterface_Stats.cpp b/PlugY/NewInterface_Stats.cpp +index 10fa32d..d73c5da 100644 +--- a/PlugY/NewInterface_Stats.cpp ++++ b/PlugY/NewInterface_Stats.cpp +@@ -13,6 +13,7 @@ + #include + + ++/* + #define getXCloseBtn() 360 + #define getLCloseBtn() 32 + #define getYCloseBtn() (ResolutionY - 60) +@@ -92,6 +93,7 @@ void** ptD2AssignStatsPointsBtnImages = (void**)0x6FBB5BB4; + + + ++/* + static struct + { + union{ +@@ -111,6 +113,7 @@ static struct + }; + }; + } isDownBtn; ++*/ + + + void print2Lines(WORD id, LPWSTR lpText, DWORD x, DWORD l, DWORD y) +diff --git a/PlugY/NewInterface_StatsPageTwo.cpp b/PlugY/NewInterface_StatsPageTwo.cpp +index dfdc8a1..6215dd6 100644 +--- a/PlugY/NewInterface_StatsPageTwo.cpp ++++ b/PlugY/NewInterface_StatsPageTwo.cpp +@@ -12,6 +12,7 @@ + #include "common.h" + #include + ++/* + #define getXCloseBtn() RX(0x110) + #define getLCloseBtn() 32 + #define getYCloseBtn() RY(0x40) +@@ -29,11 +30,13 @@ + #define getYNextPageBtn() RY(0x40) + #define getHNextPageBtn() 32 + #define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn()) ++*/ + + const char * STATS_INTERFACE_FILENAME = "PlugY\\statsinterface.txt"; + + #define BUFSIZE 0x400 + ++/* + static struct + { + union{ +@@ -45,6 +48,7 @@ static struct + }; + }; + } isDownBtn; ++*/ + + + struct statsInterfaceBIN +@@ -337,8 +341,7 @@ void STDCALL printNewStatsPageTwo(int currentPage) + + WCHAR text[BUFSIZE]; + LPWSTR lpText; +- bDontPrintBorder = false; +- ++ bDontPrintBorder = D2GetResolution()? true : false; + Unit* ptChar = D2GetClientPlayer(); + + d2_assert(!ptChar, "Printing stats page : no character selected",__FILE__,__LINE__); +@@ -349,16 +352,20 @@ void STDCALL printNewStatsPageTwo(int currentPage) + ZeroMemory(&data,sizeof(data)); + + //print background +- fillRect(RX(0),RY(480),320,432,0,5);//552 ++ fillRect(RX(0), RY(ResolutionY), 512, 768, 0, 5); + setImage(&data, newStatsInterfaceImages); + setFrame(&data, 0); +- D2PrintImage(&data, RX(0), RY(224), -1, 5, 0); ++ D2PrintImage(&data, RX(0), RY(ResolutionY-256), -1, 5, 0); + setFrame(&data, 1); +- D2PrintImage(&data, RX(256),RY(224), -1, 5, 0);//256 ++ D2PrintImage(&data, RX(256),RY(ResolutionY-256), -1, 5, 0); + setFrame(&data, 2); +- D2PrintImage(&data, RX(0), RY(48), -1, 5, 0);//432 ++ D2PrintImage(&data, RX(0), RY(ResolutionY-256*2), -1, 5, 0); + setFrame(&data, 3); +- D2PrintImage(&data, RX(256),RY(48), -1, 5, 0); ++ D2PrintImage(&data, RX(256),RY(ResolutionY-256*2), -1, 5, 0); ++ setFrame(&data, 4); ++ D2PrintImage(&data, RX(0), RY(ResolutionY-256*3), -1, 5, 0); ++ setFrame(&data, 5); ++ D2PrintImage(&data, RX(256),RY(ResolutionY-256*3), -1, 5, 0); + + D2SetFont(1); + for (int i=0; i= 0) && (page <= lastPage + (D2GetResolution()? extraHiddenPage : 0)) ) ++ if ( (page >= 0) && (page <= (lastPage + extraHiddenPage)) ) + selectedPage = page; ++ else if (page < 0) ++ selectedPage = lastPage + extraHiddenPage; ++ else ++ selectedPage = 0; + } + + int GetCurrentPage() +@@ -83,6 +115,16 @@ DWORD STDCALL mouseCustomPageLeftDown(sWinMessage* msg) + DWORD STDCALL mouseCustomPageLeftUp(sWinMessage* msg) + { + if(onRealm) return -1; ++ ++ if (selectedPage == 0) return -1; ++ if (!isOnStatsPage(msg->x,msg->y)) return 1; ++ statsLeftUp(msg); ++ D2CleanStatMouseUp(); ++ freeMessage(msg); ++ isDownBtn.all=0; ++ return 0; ++ ++ /* + if ( (selectedPage > 0) && (selectedPage <= lastPage) ) + return mouseNewStatsPageTwoLeftUp(msg); + else if (selectedPage == lastPage+1) +@@ -91,6 +133,87 @@ DWORD STDCALL mouseCustomPageLeftUp(sWinMessage* msg) + return mouseNewStatsPageLeftUp(msg); + else + return -1; ++ */ ++} ++ ++DWORD STDCALL statsLeftDown(sWinMessage* msg) ++{ ++ if (isOnCloseBtn(msg->x,msg->y) && selectedPage != 0) ++ { ++ log_msg("push down left button close\n"); ++ isDownBtn.close = 1; ++ D2PlaySound(4,0,0,0,0); ++ return 1; ++ } ++ else if (isOnPreviousPageBtn(msg->x,msg->y)) ++ { ++ log_msg("push down left button previous page\n"); ++ isDownBtn.previousPage = 1; ++ D2PlaySound(4,0,0,0,0); ++ return 1; ++ } ++ else if (isOnNextPageBtn(msg->x,msg->y)) ++ { ++ log_msg("push down left button next page\n"); ++ isDownBtn.nextPage = 1; ++ D2PlaySound(4,0,0,0,0); ++ return 1; ++ } ++ else if (isOnPrevRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage)) ++ { ++ log_msg("push down left button prev runes\n"); ++ isDownBtn.prevRunes = 1; ++ D2PlaySound(4,0,0,0,0); ++ return 1; ++ } ++ else if (isOnNextRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage)) ++ { ++ log_msg("push down left button next runes\n"); ++ isDownBtn.nextRunes = 1; ++ D2PlaySound(4,0,0,0,0); ++ return 1; ++ } ++ return 0; ++} ++ ++DWORD STDCALL statsLeftUp(sWinMessage* msg) ++{ ++ if (isOnCloseBtn(msg->x,msg->y) && selectedPage != 0) ++ { ++ log_msg("push up left button close\n"); ++ if (isDownBtn.close) ++ D2TogglePage(2,1,0); ++ return 1; ++ } ++ else if (isOnPreviousPageBtn(msg->x,msg->y)) ++ { ++ log_msg("push up left button previous page\n"); ++ if (isDownBtn.previousPage) ++ GoStatPage(selectedPage-1); ++ return 1; ++ } ++ else if (isOnNextPageBtn(msg->x,msg->y)) ++ { ++ log_msg("push up left button next page\n"); ++ if (isDownBtn.nextPage) ++ GoStatPage(selectedPage+1); ++ return 1; ++ } ++ else if (isOnPrevRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage)) ++ { ++ log_msg("push up left button prev runes\n"); ++ if (isDownBtn.prevRunes && curRunesPage) ++ curRunesPage--; ++ return 1; ++ } ++ else if (isOnNextRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage)) ++ { ++ log_msg("push up left button next runes\n"); ++ if (isDownBtn.nextRunes && (curRunesPage < maxRunesPage)) ++ curRunesPage++; ++ return 1; ++ } ++ return 0; + } + + FCT_ASM ( caller_DontPrintBorder_114 ) +@@ -474,6 +597,7 @@ void Install_NewInterfaces() + //00498636 |. 6A 48 PUSH 48 + //00498638 |. 8D45 B8 LEA EAX,DWORD PTR SS:[EBP-48] + ++ /* Conflicts with D2ExpRes + // Manage mouse down (Play sound) + mem_seek R8(D2Client, 2A9DC, 2A9CC, 312A5, 82736, 891B6, 6B116, BCD36, BF4D6, A7731); + memt_byte( 0x8D, 0xE8 ); // CALL +@@ -486,6 +610,7 @@ void Install_NewInterfaces() + //6FB6CD36 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80] + //6FB6F4D6 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80] + //004A7731 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80] ++ */ + + // Manage mouse up + mem_seek R8(D2Client, 2ABBB, 2ABAB, 3148D, 836D9, 8A159, 6C0B9, BDCB9, C0459, A78DA); +diff --git a/PlugY/Parameters.cpp b/PlugY/Parameters.cpp +index b4dc915..392c112 100644 +--- a/PlugY/Parameters.cpp ++++ b/PlugY/Parameters.cpp +@@ -58,6 +58,7 @@ const char* S_dllFilenames2 = "DllToLoad2"; + const char* S_active_Commands = "ActiveCommands"; + const char* S_active_CheckMemory = "ActiveCheckMemory"; + const char* S_active_othersFeatures = "ActiveAllOthersFeatures"; ++const char* S_saveFileStackSize = "SaveFileStackSize"; + + const char* S_WINDOWED = "WINDOWED"; + const char* S_ActiveWindowed = "ActiveWindowed"; +@@ -214,6 +215,19 @@ const char* S_INTERFACE = "INTERFACE"; + const char* S_active_newInterfaces = "ActiveNewStatsInterface"; + const char* S_selectMainPageOnOpenning = "SelectMainPageOnOpenning"; + const char* S_printBackgroundOnMainPage = "PrintButtonsBackgroundOnMainStatsPage"; ++const char* S_posXNextPageBtn = "PosXNextPageBtn"; ++const char* S_posYNextPageBtn = "PosYNextPageBtn"; ++const char* S_posXPrevPageBtn = "PosXPrevPageBtn"; ++const char* S_posYPrevPageBtn = "PosYPrevPageBtn"; ++const char* S_posXClosePageBtn = "PosXClosePageBtn"; ++const char* S_posYClosePageBtn = "PosYClosePageBtn"; ++const char* S_posXNextRuneBtn = "PosXNextRuneBtn"; ++const char* S_posYNextRuneBtn = "PosYNextRuneBtn"; ++const char* S_posXPrevRuneBtn = "PosXPrevRuneBtn"; ++const char* S_posYPrevRuneBtn = "PosYPrevRuneBtn"; ++const char* S_posXRunesList = "PosXRunesList"; ++const char* S_posYRunesList = "PosYRunesList"; ++const char* S_runesPerPage = "RunesPerPage"; + + const char* S_EXTRA = "EXTRA"; + const char* S_active_RunLODs = "ActiveLaunchAnyNumberOfLOD"; +@@ -316,6 +330,10 @@ void init_General(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFi + active_othersFeatures = atoi(buffer) != 0; + log_msg("active_othersFeatures\t\t= %u\n", active_othersFeatures); + ++ GET_PRIVATE_PROFILE_STRING(S_GENERAL, S_saveFileStackSize, "8192"); ++ saveFileStackSize = atoi(buffer); ++ log_msg("SaveFileStackSize\t\t\t= %u\n", saveFileStackSize); ++ + log_msg("\n"); + } + +@@ -1032,6 +1050,52 @@ void init_NewInterfaces(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDef + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_printBackgroundOnMainPage, "1"); + printBackgroundOnMainPage = atoi(buffer) != 0; + log_msg("printBackgroundOnMainPage\t= %u\n", printBackgroundOnMainPage); ++ ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXNextPageBtn, "161"); ++ posXNextPageBtn = atoi(buffer); ++ log_msg("posXNextPageBtn\t= %d\n", posXNextPageBtn); ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYNextPageBtn, "64"); ++ posYNextPageBtn = atoi(buffer); ++ log_msg("posYNextPageBtn\t= %d\n", posYNextPageBtn); ++ ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXPrevPageBtn, "119"); ++ posXPrevPageBtn = atoi(buffer); ++ log_msg("posXPrevPageBtn\t= %d\n", posXPrevPageBtn); ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYPrevPageBtn, "64"); ++ posYPrevPageBtn = atoi(buffer); ++ log_msg("posYPrevPageBtn\t= %d\n", posYPrevPageBtn); ++ ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXClosePageBtn, "360"); ++ posXClosePageBtn = atoi(buffer); ++ log_msg("posXClosePageBtn\t= %d\n", posXClosePageBtn); ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYClosePageBtn, "64"); ++ posYClosePageBtn = atoi(buffer); ++ log_msg("posYClosePageBtn\t= %d\n", posYClosePageBtn); ++ ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXNextRuneBtn, "302"); ++ posXNextRuneBtn = atoi(buffer); ++ log_msg("posXNextRuneBtn\t= %d\n", posXNextRuneBtn); ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYNextRuneBtn, "64"); ++ posYNextRuneBtn = atoi(buffer); ++ log_msg("posYNextRuneBtn\t= %d\n", posYNextRuneBtn); ++ ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXPrevRuneBtn, "260"); ++ posXPrevRuneBtn = atoi(buffer); ++ log_msg("posXPrevRuneBtn\t= %d\n", posXPrevRuneBtn); ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYPrevRuneBtn, "64"); ++ posYPrevRuneBtn = atoi(buffer); ++ log_msg("posYPrevRuneBtn\t= %d\n", posYPrevRuneBtn); ++ ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXRunesList, "50"); ++ posXRunesList = atoi(buffer); ++ log_msg("posXRunesList\t= %d\n", posXRunesList); ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYRunesList, "45"); ++ posYRunesList = atoi(buffer); ++ log_msg("posYRunesList\t= %d\n", posYRunesList); ++ ++ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_runesPerPage, "30"); ++ runesPerPage = atoi(buffer); ++ log_msg("runesPerPage\t= %d\n", runesPerPage); + } + log_msg("\n"); + } +diff --git a/PlugY/infinityStash.h b/PlugY/infinityStash.h +index 0ca6b4d..123705d 100644 +--- a/PlugY/infinityStash.h ++++ b/PlugY/infinityStash.h +@@ -18,6 +18,7 @@ extern bool active_sharedStash; + extern bool active_sharedGold; + extern bool separateHardSoftStash; + extern char* sharedStashFilename; ++extern DWORD saveFileStackSize; + + extern bool displaySharedSetItemNameInGreen; + extern int posXPreviousBtn; +diff --git a/PlugY/newInterfaces.h b/PlugY/newInterfaces.h +index de51f26..c4c4ff3 100644 +--- a/PlugY/newInterfaces.h ++++ b/PlugY/newInterfaces.h +@@ -9,20 +9,94 @@ + #include "common.h" + + #define MILIEU(X,L,N) (X + ((Ne_magic != IMAGE_DOS_SIGNATURE) + return NULL; + + IMAGE_NT_HEADERS* pHeader = (IMAGE_NT_HEADERS*)(pBase + pDosHeader->e_lfanew); + if (IsBadReadPtr(pHeader, sizeof(IMAGE_NT_HEADERS))) + return NULL; + + if (pHeader->Signature != IMAGE_NT_SIGNATURE) + return NULL; + + return pHeader; +} + +void initD2modules() +{ + log_msg("***** Get D2 Modules address and version *****\n\n"); + + offset_D2Client = (DWORD)LoadLibrary("D2Client.dll"); + offset_D2CMP = (DWORD)LoadLibrary("D2CMP.dll"); + offset_D2Common = (DWORD)LoadLibrary("D2Common.dll"); + offset_D2Game = (DWORD)LoadLibrary("D2Game.dll"); + offset_D2gfx = (DWORD)LoadLibrary("D2gfx.dll"); + offset_D2Lang = (DWORD)LoadLibrary("D2Lang.dll"); + offset_D2Launch = (DWORD)LoadLibrary("D2Launch.dll"); + offset_D2Net = (DWORD)LoadLibrary("D2Net.dll"); + offset_D2Win = (DWORD)LoadLibrary("D2Win.dll"); + offset_Fog = (DWORD)LoadLibrary("Fog.dll"); + offset_Storm = (DWORD)LoadLibrary("Storm.dll"); + + int count_109b = 0; + int count_109d = 0; + int count_110f = 0; + int count_111 = 0; + int count_111b = 0; + int count_112a = 0; + int count_113c = 0; + int count_113d = 0; + int count_114a = 0; + int count_114b = 0; + int count_114c = 0; + int count_114d = 0; + + IMAGE_NT_HEADERS* pHeader; + + if (offset_D2Client != NULL) { + pHeader = GetHeader((LPBYTE)offset_D2Client); + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C234D) count_109b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C16CD) count_109d++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C1C1D) count_110f++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045E6) count_111++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045EE) count_111b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045FA) count_112a++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045F6) count_113c++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045DE) count_113d++; + } + + if (offset_D2CMP != NULL) { + pHeader = GetHeader((LPBYTE)offset_D2CMP); + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00011361) count_109b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00011361) count_109d++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00010E61) count_110f++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_111++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_111b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_112a++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_113c++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_113d++; + } + + if (offset_D2Common != NULL) { + pHeader = GetHeader((LPBYTE)offset_D2Common); + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00074D1D) count_109b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00074E2D) count_109d++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000856DD) count_110f++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C94) count_111++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C8D) count_111b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C97) count_112a++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C8F) count_113c++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000047C7) count_113d++; + } + + if (offset_D2Game != NULL) { + pHeader = GetHeader((LPBYTE)offset_D2Game); + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C66AC) count_109b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C6D5C) count_109d++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000EDC2C) count_110f++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000036E6) count_111++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000373D) count_111b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000374B) count_112a++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000373C) count_113c++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003747) count_113d++; + } + + if (offset_D2gfx != NULL) { + pHeader = GetHeader((LPBYTE)offset_D2gfx); + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054EB) count_109b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054EB) count_109d++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054A5) count_110f++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_111++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_111b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_112a++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_113c++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_113d++; + } + + if (offset_D2Lang != NULL) { + pHeader = GetHeader((LPBYTE)offset_D2Lang); + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005148) count_109b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005138) count_109d++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005048) count_110f++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A6A) count_111++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A5B) count_111b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A75) count_112a++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A71) count_113c++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A5A) count_113d++; + } + + if (offset_D2Launch != NULL) { + pHeader = GetHeader((LPBYTE)offset_D2Launch); + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000172C3) count_109b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00017243) count_109d++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00018DC7) count_110f++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A84) count_111++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A85) count_111b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A85) count_112a++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A87) count_113c++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A84) count_113d++; + } + + if (offset_D2Net != NULL) { + pHeader = GetHeader((LPBYTE)offset_D2Net); + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002BCE) count_109b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002BCE) count_109d++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C6E) count_110f++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_111++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_111b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000167E) count_112a++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_113c++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000167E) count_113d++; + } + + if (offset_D2Win != NULL) { + pHeader = GetHeader((LPBYTE)offset_D2Win); + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00014F38) count_109b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00014F38) count_109d++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00012EC0) count_110f++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_111++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_111b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000188E) count_112a++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_113c++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001887) count_113d++; + } + + if (offset_Fog != NULL) { + pHeader = GetHeader((LPBYTE)offset_Fog); + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00013658) count_109b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000142E7) count_109d++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000162B0) count_110f++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003159) count_111++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_111b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000314A) count_112a++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003162) count_113c++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_113d++; + } + + if (offset_Storm != NULL) { + pHeader = GetHeader((LPBYTE)offset_Storm); + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00013658) count_109b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000142E7) count_109d++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000162B0) count_110f++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003159) count_111++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_111b++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000314A) count_112a++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003162) count_113c++; + if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0003C3E0) count_113d++; + } + + int minimum_match_dll = 7; + + if (count_109b >= minimum_match_dll) version_Game = V109b; + if (count_109d >= minimum_match_dll) version_Game = V109d; + if (count_110f >= minimum_match_dll) version_Game = V110; + if (count_111 >= minimum_match_dll) version_Game = V111; + if (count_111b >= minimum_match_dll) version_Game = V111b; + if (count_112a >= minimum_match_dll) version_Game = V112; + if (count_113c >= minimum_match_dll) version_Game = V113c; + if (count_113d >= minimum_match_dll) version_Game = V113d; + + //version_SmackW32 = version_Game; + version_D2Common = version_Game; + //version_ijl11 = version_Game; + //version_D2Gdi = version_Game; + version_D2Win = version_Game; + //version_D2sound = version_Game; + //version_D2MCPCLI = version_Game; + version_D2Launch = version_Game; + version_D2gfx = version_Game; + version_D2Client = version_Game; + version_D2Net = version_Game; + version_D2Lang = version_Game; + version_D2Game = version_Game; + version_D2CMP = version_Game; + //version_Bnclient = version; + version_Fog = version_Game; + version_Storm = version_Game; + + log_msg("DLL match for version 1.09b :\t%d\n", count_109b); + log_msg("DLL match for version 1.09d :\t%d\n", count_109d); + log_msg("DLL match for version 1.10f :\t%d\n", count_110f); + log_msg("DLL match for version 1.11 :\t%d\n", count_111); + log_msg("DLL match for version 1.11b :\t%d\n", count_111b); + log_msg("DLL match for version 1.12a :\t%d\n", count_112a); + log_msg("DLL match for version 1.13c :\t%d\n", count_113c); + log_msg("\n"); + + offset_Game = (DWORD)GetModuleHandle("Game.exe"); + if (offset_Game != NULL) { + version_Game = GetD2Version((HMODULE)offset_Game); + log_msg("Game.exe loaded at:\t%08X (%s)\n", offset_Game, GetVersionString(version_Game)); + if (version_Game >= V114a) + { + //version_SmackW32 = version_Game; + version_D2Common = version_Game; + //version_ijl11 = version_Game; + //version_D2Gdi = version_Game; + version_D2Win = version_Game; + //version_D2sound = version_Game; + //version_D2MCPCLI = version_Game; + version_D2Launch = version_Game; + version_D2gfx = version_Game; + version_D2Client = version_Game; + version_D2Net = version_Game; + version_D2Lang = version_Game; + version_D2Game = version_Game; + version_D2CMP = version_Game; + //version_Bnclient = version; + version_Fog = version_Game; + version_Storm = version_Game; + } + } + + //if (offset_Game != NULL) { + // pHeader = GetHeader((LPBYTE)offset_Game); + // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00291342) count_114a++; + // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x002854F2) count_114b++; + // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x002850E2) count_114c++; + // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00282985) count_114d++; + //} + + log_msg("Version game is:\t(%s)\n\n", GetVersionString(version_Game)); + + if (version_Game == UNKNOWN) + { + MessageBoxA(NULL, "This version of Diablo II is not supported by Plugy. Please upgrade or downgrade to a supported version.", "Plugy 14.03", MB_OK); + } +} + //////////////////////////////////// EXPORTS FUNCTIONS //////////////////////////////////// diff --git a/PlugY/Debug/PlugY.dll.recipe b/PlugY/Debug/PlugY.dll.recipe new file mode 100644 index 0000000..10f807f --- /dev/null +++ b/PlugY/Debug/PlugY.dll.recipe @@ -0,0 +1,11 @@ + + + + + D:\VSCode\PlugY\PlugY\Debug\PlugY.dll + + + + + + \ No newline at end of file diff --git a/PlugY/Debug/PlugY.exp b/PlugY/Debug/PlugY.exp new file mode 100644 index 0000000..6da0479 Binary files /dev/null and b/PlugY/Debug/PlugY.exp differ diff --git a/PlugY/Debug/PlugY.ilk b/PlugY/Debug/PlugY.ilk new file mode 100644 index 0000000..741dcfc Binary files /dev/null and b/PlugY/Debug/PlugY.ilk differ diff --git a/PlugY/Debug/PlugY.log b/PlugY/Debug/PlugY.log new file mode 100644 index 0000000..dff1163 --- /dev/null +++ b/PlugY/Debug/PlugY.log @@ -0,0 +1,20 @@ +cl : command line warning D9035: option 'Gm' has been deprecated and will be removed in a future release + UpdateServer.cpp + UpdateClient.cpp + SharedSaveFile.cpp + SavePlayerData.cpp + PlayerCustomData.cpp + Parameters.cpp + NewInterface_Runewords.cpp + LoadPlayerData.cpp + Interface_Stash.cpp + InfinityStash.cpp + GlobalVariable.cpp + ExtraOptions.cpp + ExtendedSaveFile.cpp + D2wrapper.cpp + Commands.cpp + Generating Code... +VersionInfo.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification + Creating library D:\VSCode\PlugY\PlugY\Debug\PlugY.lib and object D:\VSCode\PlugY\PlugY\Debug\PlugY.exp + PlugY.vcxproj -> D:\VSCode\PlugY\PlugY\Debug\PlugY.dll diff --git a/PlugY/Debug/PlugY.pdb b/PlugY/Debug/PlugY.pdb new file mode 100644 index 0000000..19f9526 Binary files /dev/null and b/PlugY/Debug/PlugY.pdb differ diff --git a/PlugY/Debug/PlugY.res b/PlugY/Debug/PlugY.res new file mode 100644 index 0000000..41895c7 Binary files /dev/null and b/PlugY/Debug/PlugY.res differ diff --git a/PlugY/Debug/PlugY.tlog/CL.command.1.tlog b/PlugY/Debug/PlugY.tlog/CL.command.1.tlog new file mode 100644 index 0000000..b6c5a80 Binary files /dev/null and b/PlugY/Debug/PlugY.tlog/CL.command.1.tlog differ diff --git a/PlugY/Debug/PlugY.tlog/CL.read.1.tlog b/PlugY/Debug/PlugY.tlog/CL.read.1.tlog new file mode 100644 index 0000000..f86849a Binary files /dev/null and b/PlugY/Debug/PlugY.tlog/CL.read.1.tlog differ diff --git a/PlugY/Debug/PlugY.tlog/CL.write.1.tlog b/PlugY/Debug/PlugY.tlog/CL.write.1.tlog new file mode 100644 index 0000000..469b335 Binary files /dev/null and b/PlugY/Debug/PlugY.tlog/CL.write.1.tlog differ diff --git a/PlugY/Debug/PlugY.tlog/PlugY.lastbuildstate b/PlugY/Debug/PlugY.tlog/PlugY.lastbuildstate new file mode 100644 index 0000000..9cc39d3 --- /dev/null +++ b/PlugY/Debug/PlugY.tlog/PlugY.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native32Bit:VCToolsVersion=14.32.31326:TargetPlatformVersion=10.0.19041.0: +Debug|Win32|D:\VSCode\PlugY\PlugY\| diff --git a/PlugY/Debug/PlugY.tlog/PlugY.write.1u.tlog b/PlugY/Debug/PlugY.tlog/PlugY.write.1u.tlog new file mode 100644 index 0000000..be98dc6 Binary files /dev/null and b/PlugY/Debug/PlugY.tlog/PlugY.write.1u.tlog differ diff --git a/PlugY/Debug/PlugY.tlog/link.command.1.tlog b/PlugY/Debug/PlugY.tlog/link.command.1.tlog new file mode 100644 index 0000000..512ec07 Binary files /dev/null and b/PlugY/Debug/PlugY.tlog/link.command.1.tlog differ diff --git a/PlugY/Debug/PlugY.tlog/link.read.1.tlog b/PlugY/Debug/PlugY.tlog/link.read.1.tlog new file mode 100644 index 0000000..0afc5e0 Binary files /dev/null and b/PlugY/Debug/PlugY.tlog/link.read.1.tlog differ diff --git a/PlugY/Debug/PlugY.tlog/link.write.1.tlog b/PlugY/Debug/PlugY.tlog/link.write.1.tlog new file mode 100644 index 0000000..9230e68 Binary files /dev/null and b/PlugY/Debug/PlugY.tlog/link.write.1.tlog differ diff --git a/PlugY/Debug/PlugY.tlog/rc.command.1.tlog b/PlugY/Debug/PlugY.tlog/rc.command.1.tlog new file mode 100644 index 0000000..a974b6d Binary files /dev/null and b/PlugY/Debug/PlugY.tlog/rc.command.1.tlog differ diff --git a/PlugY/Debug/PlugY.tlog/rc.read.1.tlog b/PlugY/Debug/PlugY.tlog/rc.read.1.tlog new file mode 100644 index 0000000..7fc1984 Binary files /dev/null and b/PlugY/Debug/PlugY.tlog/rc.read.1.tlog differ diff --git a/PlugY/Debug/PlugY.tlog/rc.write.1.tlog b/PlugY/Debug/PlugY.tlog/rc.write.1.tlog new file mode 100644 index 0000000..2b34193 Binary files /dev/null and b/PlugY/Debug/PlugY.tlog/rc.write.1.tlog differ diff --git a/PlugY/Debug/PlugY.vcxproj.FileListAbsolute.txt b/PlugY/Debug/PlugY.vcxproj.FileListAbsolute.txt new file mode 100644 index 0000000..5fbc182 --- /dev/null +++ b/PlugY/Debug/PlugY.vcxproj.FileListAbsolute.txt @@ -0,0 +1 @@ +D:\VSCode\PlugY\PlugY\Debug\PlugY.dll diff --git a/PlugY/Debug/vc143.idb b/PlugY/Debug/vc143.idb new file mode 100644 index 0000000..bd01b0d Binary files /dev/null and b/PlugY/Debug/vc143.idb differ diff --git a/PlugY/Debug/vc143.pdb b/PlugY/Debug/vc143.pdb new file mode 100644 index 0000000..1598951 Binary files /dev/null and b/PlugY/Debug/vc143.pdb differ diff --git a/PlugY/InfinityStash.cpp b/PlugY/InfinityStash.cpp index 22e9c35..ea09d36 100644 --- a/PlugY/InfinityStash.cpp +++ b/PlugY/InfinityStash.cpp @@ -26,6 +26,7 @@ bool active_sharedStash = false; bool separateHardSoftStash = false; bool active_sharedGold=false; char* sharedStashFilename = NULL; +DWORD saveFileStackSize = 0x2000; typedef int (*TchangeToSelectedStash)(Unit* ptChar, Stash* newStash, DWORD bOnlyItems, DWORD bIsClient); @@ -422,7 +423,7 @@ void saveStashList(Unit* ptChar, Stash* ptStash, BYTE** data, DWORD* maxSize, DW while(ptStash) { - if (*curSize + 0x2000 > *maxSize) + if (*curSize + saveFileStackSize > *maxSize) { BYTE* oldData = *data; *maxSize *= 2; diff --git a/PlugY/Interface_Skills.cpp b/PlugY/Interface_Skills.cpp index 90178f7..8a07c2a 100644 --- a/PlugY/Interface_Skills.cpp +++ b/PlugY/Interface_Skills.cpp @@ -49,9 +49,10 @@ Unit* STDCALL skillsPageMouseDown(sWinMessage* msg) if (active_SkillsPoints && !onRealm && D2isLODGame() && isOnButtonUnassignSkill(D2GetMouseX(),D2GetMouseY())) { log_msg("push down left button unassign skill\n"); - btnSkillIsDown = 1; + //btnSkillIsDown = 1; D2PlaySound(4,0,0,0,0); freeMessage(msg); + updateServer(US_UNASSIGN_SKILLS); return NULL; } return ptChar; @@ -233,6 +234,7 @@ void Install_InterfaceSkills() //6FAE1112 > C745 18 00000000 MOV DWORD PTR SS:[EBP+18],0 //004ABC1A |> C746 18 00000000 MOV DWORD PTR DS:[ESI+18],0 + /* Conflicts with D2ExpRes // Manage mouse up mem_seek R8(D2Client, 7BC40, 7BC40, 78466, 17558, 8C078, 80248, 795F8, 30AA8, ABC96); MEMJ_REF4( D2FreeWinMessage, caller_skillsPageMouseUp);//0xFFF93B0A @@ -243,6 +245,7 @@ void Install_InterfaceSkills() //6FB295F7 .^E9 8828F9FF JMP //6FAE0AA7 .^E9 E0B2FDFF JMP //004ABC95 |. E8 F645F7FF CALL Game.00420290 + */ log_msg("\n"); diff --git a/PlugY/Interface_Stash.cpp b/PlugY/Interface_Stash.cpp index ebcf2b6..a82329e 100644 --- a/PlugY/Interface_Stash.cpp +++ b/PlugY/Interface_Stash.cpp @@ -13,6 +13,13 @@ #include "plugYFiles.h" // Install_PlugYImagesFiles() #include "common.h" #include +#include // Include ctime for srand and rand functions +#include +#include +#include +#include +#include +#include static struct { @@ -69,6 +76,26 @@ int posYStashGoldField = -1; int posWStashGoldField = 152; int posHStashGoldField = 18; +#include + +// Define a type alias for clarity +using namespace std::chrono; + +// Global variable to store start time +time_point startTime; + +// Function to start the timer +void StartTimer() { + startTime = steady_clock::now(); +} + +// Function to check if 5000ms have elapsed +bool HasElapsed() { + auto currentTime = steady_clock::now(); + auto elapsed = duration_cast(currentTime - startTime); + return elapsed.count() >= 5000; +} + DWORD PersonalNormalPageColor = WHITE; DWORD PersonalIndexPageColor = DARK_GREEN; @@ -355,10 +382,9 @@ void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color, WCHAR text[21]; getCurrentStashName(text, 21, ptChar); - // Replace character # by number page. int j = 0; - for (int i=0; text[i]; i++) + for (int i = 0; text[i]; i++) { if (text[i] == L'#') { @@ -368,7 +394,7 @@ void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color, { nbDigits++; val /= 10; - } while(val); + } while (val); j += nbDigits; val = currentId; @@ -378,7 +404,7 @@ void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color, nbDigits++; popupText[j - nbDigits] = (WCHAR)(val % 10 + 48); val /= 10; - } while(val); + } while (val); } else popupText[j++] = text[i]; @@ -388,7 +414,7 @@ void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color, // Check text length vs field name length int pixelLen = D2GetPixelLen(popupText); int len = wcslen(popupText); - while(len > 0 && pixelLen > posWStashNameField - 5) + while (len > 0 && pixelLen > posWStashNameField - 5) { len--; popupText[len] = NULL; @@ -396,24 +422,344 @@ void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color, } DWORD color = isShared ? (isMainIndex ? SharedMainIndexPageColor : isIndex ? SharedIndexPageColor : SharedNormalPageColor) : (isMainIndex ? PersonalMainIndexPageColor : isIndex ? PersonalIndexPageColor : PersonalNormalPageColor); - D2PrintString(popupText, x, y, color, bfalse); - if (isOnStashNameField(mx, my)) - { - _snwprintf(popupText, 0x400, getLocalString(STR_PAGE_TYPE_CHANGE), currentId); - D2PrintPopup(popupText, getXStashNameField() + posWStashNameField/2, getYStashNameField() - posHStashNameField - 2, WHITE, 1); - } - } + // By HashCasper + D2PrintString(popupText, 152, 605, color, bfalse); + + WCHAR HashString[] = L"Ironman Mod by Hash"; + D2PrintString(HashString, 152, 75, color, bfalse); + + // Print Random Tips + + // Define an array of tips + const wchar_t* tips[] = { + L"Consume spirits like potions to increase Spirits Quaffed stat in character stat sheet page.", + L"Cube Souls with Energy Sphere to capture Soul Energy and use it to create powerful items. Recipes will come later.", + L"Collect Demon souls from demons and regular souls from monsters; Demon souls morph you into the demon whose soul you have.", + L"Spirits can be consumed like potions or put on as rings to add to Souls Consumed count.", + L"Cube underused magic/rare/set/unique items with Energy Sphere to collect their magic energy for creating new items.", + L"Cube white items with Energy Sphere to break down into simple item parts for creating base item types with smithing hammers.", + L"Use Rare Shard, Set Stone, or Unique Particle with smithing hammers and Energy Sphere to create rare/set/unique items.", + L"Acquire smithing hammers to create base item types, each requiring X number of collected item parts.", + L"Capture Talisman of Corruption and cube to corrupt items for new magical properties; a gamble with potential rewards.", + L"Use Experience Book for extra experience, Infinite Mana Elixir for massive mana regeneration, and Regeneration Elixir for life regeneration.", + L"Use Elixirs to permanently boost stats like Strength, Dexterity, Health, Stamina, Mana, and resistances.", + L"Equip Sling Stone for increased throwing potion damage, various elemental stones for resistance boosts, and Mastery Stones for skill damage boosts.", + L"Use Portable Shrines for temporary buffs like increased defense, damage, experience gained, mana regeneration, and skill levels.", + L"In Ironman, gold is nonexistent, town portals are disabled; rely on items, waypoints, and strategic gameplay to progress.", + L"Inventory management is critical; use items conservatively and intelligently switch gear based on monster types and situations.", + L"Hybrid character builds and creative weapon choices are encouraged in Ironman; experiment and adapt strategies accordingly.", + L"Protect hirelings actively as they are essential allies; they can be hired for 0 gold but lose items if they die.", + L"Coordinate with teammates in MultiPlayer; teamwork, resource sharing, and strategy are key to success in Ironman.", + L"In Hardcore Ironman, caution and careful planning are crucial; falling back, potion management, and adaptability are essential for survival.", + L"Utilize waypoints for inter-level travel in Ironman; waypoints become crucial for navigating the game world.", + L"Always have backup gear in your backpack in Ironman; switch out gear intelligently based on monster types and challenges.", + L"Experiment with different weapons and gear in Ironman; adapt your strategies to overcome various monster types and situations.", + L"Keep a close watch on your hirelings' health in Ironman; losing a hireling means losing their equipped items as well.", + L"Plan and communicate effectively in MultiPlayer Ironman games; teamwork and coordination are key to overcoming challenges.", + L"Be conservative with resources in Hardcore Ironman; strategic planning and careful execution are vital for survival.", + L"Craft rare/set/unique items using collected item parts and smithing hammers in Ironman; choose item types wisely for your build.", + L"Capture and corrupt items using Talisman of Corruption for new magical properties in Ironman; take calculated risks for potential rewards.", + L"Use Portable Shrines strategically in Ironman for temporary buffs; timing and placement of shrines can turn the tide of battle.", + L"Keep track of Souls Consumed and Spirits Quaffed stats in Ironman; they reflect your progress and resource utilization in the game.", + L"Enhance your character with Elixirs and Stones for permanent stat boosts and bonuses in Ironman; plan your upgrades wisely.", + L"Master the art of retreating and regrouping in Hardcore Ironman; strategic fallbacks can save your character's life in tough situations.", + L"Stay vigilant and adapt your strategies in MultiPlayer Ironman games; synergy and cooperation with teammates are essential for success.", + L"Experiment with different skill synergies and builds in Ironman; explore the full potential of your character's abilities.", + L"Craft and equip powerful unique items using collected Magic Essence Points and recipes in Ironman; customize your gear for optimal performance.", + L"Explore new areas and challenges in Ironman; discover hidden secrets and encounters by venturing off the beaten path.", + L"Combine different magic/rare/set/unique items with the Energy Sphere to collect their magic energy in Ironman.", + L"Cube white items with the Energy Sphere to break them down into simple item parts for crafting in Ironman.", + L"Use smithing hammers with the Energy Sphere to create base item types for crafting in Ironman.", + L"Combine Rare Shard, Set Stone, or Unique Particle with base item types and Magic Essence Points to create rare/set/unique items in Ironman.", + L"Cube Souls with the Energy Sphere to capture their energy and use it for creating more powerful items in Ironman.", + + L"+ to Amazon Skills increases the Minimum and Maximum skill levels for Amazon skills.", + L"+ to Assassin Skills increases the Minimum and Maximum skill levels for Assassin skills.", + L"+ to Barbarian Skills increases the Minimum and Maximum skill levels for Barbarian skills.", + L"+ to Druid Skills increases the Minimum and Maximum skill levels for Druid skills.", + L"+ to Necromancer Skills increases the Minimum and Maximum skill levels for Necromancer skills.", + L"+ to Paladin Skills increases the Minimum and Maximum skill levels for Paladin skills.", + L"+ to Sorceress Skills increases the Minimum and Maximum skill levels for Sorceress skills.", + L"+ to All Skills increases the Minimum and Maximum skill levels for all skills.", + L"+ to Fire Skills increases the Minimum and Maximum skill levels for Fire skills.", + L"+ to Cold Skills increases the Minimum and Maximum skill levels for Cold skills.", + L"+ to Lightning Skills increases the Minimum and Maximum skill levels for Lightning skills.", + L"+ to Poison Skills increases the Minimum and Maximum skill levels for Poison skills.", + L"+ to Magic Skills increases the Minimum and Maximum skill levels for Magic skills.", + L"+ to Single Skills increases the Minimum and Maximum levels for a specific skill.", + L"+ to Single Skill Tabs increases the Minimum and Maximum levels for a specific skill tab.", + L"Chance to cast a skill when attacking triggers a specified skill with a certain chance and skill level.", + L"Chance to cast a skill when hitting triggers a specified skill with a certain chance and skill level.", + L"Chance to cast a skill when getting hit triggers a specified skill with a certain chance and skill level.", + L"Skill Charges grant a certain number of charges to a specific skill with a designated skill level.", + L"Using an Aura when equipped activates a specified aura skill with Minimum and Maximum levels.", + L"Cast a skill when a monster is killed has a chance to trigger a specified skill at a certain skill level.", + L"Cast a skill when a player is killed has a chance to trigger a specified skill at a certain skill level.", + L"Cast a skill when a player level-up has a chance to trigger a specified skill at a certain skill level.", + L"Spawns a random skill within a range of specified skills with corresponding skill levels.", + L"+ to other char classes grants skills from other character classes with Minimum and Maximum levels.", + + L"+ to AC increases the Armor Class within a specified range.", + L"+ X to AC per level increases Armor Class by a certain value per character level.", + L"+ X to AC Based on Strength increases Armor Class based on Strength by a certain value.", + L"+ X to AC Based on Dexterity increases Armor Class based on Dexterity by a certain value.", + L"+% to AC increases Armor Class by a percentage within a specified range.", + L"+% X to AC per level increases Armor Class by a certain percentage per character level.", + L"+% X to AC Based on Strength increases Armor Class based on Strength by a certain percentage.", + L"+% X to AC Based on Dexterity increases Armor Class based on Dexterity by a certain percentage.", + L"+ to AC vs Melee increases Armor Class against melee attacks within a specified range.", + L"+ to AC vs Missiles increases Armor Class against missile attacks within a specified range.", + + L"+ to Durability increases the durability of an item within a specified range.", + L"+% to Durability increases the durability of an item by a percentage within a specified range.", + L"Indestructible makes an item not lose durability.", + L"Repair 1 Dur per 100/X seconds repairs an item's durability over time.", + L"Repair 1 Qnt per 100/X seconds repairs an item's quantity over time.", + L"Increase Stack by X amount increases the stack size of an item by a certain value.", + + L"+ to AR increases Attack Rating within a specified range.", + L"+ Attack Rating per level increases Attack Rating by a certain value per character level.", + L"+ Attack Rating based on Strength increases Attack Rating based on Strength by a certain value.", + L"+ Attack Rating based on Dexterity increases Attack Rating based on Dexterity by a certain value.", + L"+% to AR increases Attack Rating by a percentage within a specified range.", + L"+% AR per level increases Attack Rating by a certain percentage per character level.", + L"+% AR based on Strength increases Attack Rating based on Strength by a certain percentage.", + L"+% AR based on Dexterity increases Attack Rating based on Dexterity by a certain percentage.", + L"+ to AR vs Demons increases Attack Rating against Demons within a specified range.", + L"+ to AR vs Undead increases Attack Rating against Undead within a specified range.", + L"+% to AR vs Montype increases Attack Rating against a specified monster type within a specified range.", + + L"+ to Damage increases both Minimum and Maximum damage values for an item within a specified range.", + L"+% to Damage increases both Minimum and Maximum damage values by a percentage within a specified range.", + L"+ to Minimum Damage increases Minimum damage within a specified range.", + L"+ to Minimum Damage per Level increases Minimum damage by a certain value per character level.", + L"+ to Minimum Damage based on Strength increases Minimum damage based on Strength by a certain value.", + L"+ to Minimum Damage based on Dexterity increases Minimum damage based on Dexterity by a certain value.", + L"+% to Minimum Damage per level increases Minimum damage by a percentage per character level.", + L"+ to Maximum Damage increases Maximum damage within a specified range.", + L"+ to Maximum Damage per level increases Maximum damage by a certain value per character level.", + L"+ to Maximum Damage based on Strength increases Maximum damage based on Strength by a certain value.", + L"+ to Maximum Damage based on Dexterity increases Maximum damage based on Dexterity by a certain value.", + L"+% to Maximum damage per level increases Maximum damage by a percentage per character level.", + L"+% to Maximum Damage based on Strength increases Maximum damage based on Strength by a certain percentage.", + L"+% to Maximum Damage based on Dexterity increases Maximum damage based on Dexterity by a certain percentage.", + L"+ to Minimum & Maximum Damage increases both Minimum and Maximum damage values for an item within a specified range.", + L"+% to Damage vs Demons increases damage against Demons within a specified range.", + L"+% damage to demons per level increases damage against Demons by a certain percentage per character level.", + L"+% to Damage vs Undead increases damage against Undead within a specified range.", + L"+% damage to undead per level increases damage against Undead by a certain percentage per character level.", + L"+% to crushing blow increases the chance to cause a crushing blow within a specified range.", + L"+% crushing blow per level increases the chance to cause a crushing blow by a certain percentage per character level.", + L"+% crushing blow based on Strength increases the chance to cause a crushing blow based on Strength by a certain percentage.", + L"+% crushing blow based on Dexterity increases the chance to cause a crushing blow based on Dexterity by a certain percentage.", + L"+% to deadly strike increases the chance to cause a deadly strike within a specified range.", + L"+% deadly strike per level increases the chance to cause a deadly strike by a certain percentage per character level.", + L"+% deadly strike based on Strength increases the chance to cause a deadly strike based on Strength by a certain percentage.", + L"+% deadly strike Based on Dexterity increases the chance to cause a deadly strike based on Dexterity by a certain percentage.", + L"+ to throw damage increases throwing damage within a specified range.", + L"+% to Damage vs Montype increases damage against a specified monster type within a specified range.", + + L"Ignores Target Defense (ITD) ignores the target's defense.", + L"+% pierce increases the chance to pierce enemy resistances within a specified range.", + L"+% pierce based on Level increases the chance to pierce enemy resistances based on character level.", + L"+% pierce based on Strength increases the chance to pierce enemy resistances based on Strength.", + L"Knockback has a chance to knockback enemies on hit.", + L"+% life stolen grants life steal within a specified range.", + L"+% mana stolen grants mana steal within a specified range.", + L"+# mana after each kill grants mana regeneration after each kill within a specified range.", + L"+# after each demon kill grants health after each demon kill within a specified range.", + L"Prevents monster healing prevents monsters from healing.", + L"+% chance to cause open wounds increases the chance to cause open wounds within a specified range.", + L"+% open wounds per level increases the chance to cause open wounds based on character level.", + L"+% open wounds based on Strength increases the chance to cause open wounds based on Strength.", + L"+% open wounds Based on Dexterity increases the chance to cause open wounds based on Dexterity.", + L"Enemy Is slowed by X% slows enemies by a percentage within a specified range.", + L"Enemy Is slowed by X% based on Level slows enemies based on character level.", + L"Chance to Blind Target has a chance to blind the target.", + L"Chance to Blind Target based on Level has a chance to blind the target based on character level.", + L"Freeze Target X seconds freezes the target for a specified duration.", + L"Freeze Target X seconds based on Level freezes the target based on character level.", + L"Freeze Target X seconds based on Energy freezes the target based on character Energy.", + L"Reduce AC by X% reduces the target's Armor Class by a percentage within a specified range.", + L"Reduce AC by X reduces the target's Armor Class within a specified range.", + L"+ to Kicking Damage increases kicking damage within a specified range.", + L"+ Kick damage per level increases kicking damage based on character level.", + L"+ Kick damage based on Strength increases kicking damage based on Strength.", + L"+ Kick damage based on Dexterity increases kicking damage based on Dexterity.", + L"+% chance to reanimate target increases the chance to reanimate a target within a specified range.", + L"Reduces monster fire resistance reduces a monster's fire resistance within a specified range.", + L"Reduces monster lightning resistance reduces a monster's lightning resistance within a specified range.", + L"Reduces monster cold resistance reduces a monster's cold resistance within a specified range.", + L"Reduces monster poison resistance reduces a monster's poison resistance within a specified range.", + L"HP gained after every kill grants health regeneration after each kill within a specified range.", + L"Corspe cannot be ressurected/Targeted prevents corpses from being resurrected or targeted.", + + L"+% damage taken goes to mana converts a percentage of damage taken to mana within a specified range.", + L"Damage reduced by X amount reduces incoming damage by a specific amount within a specified range.", + L"Damage reduced by X% reduces incoming damage by a percentage within a specified range.", + L"Damage reduced by X% based on Level reduces incoming damage based on character level.", + L"Damage reduced by X% based on Vitality reduces incoming damage based on character Vitality.", + L"Magic damage reduced by X reduces incoming magic damage within a specified range.", + L"Magic damage reduced by X per Level reduces incoming magic damage based on character level.", + L"Magic damage reduced by X per Energy reduces incoming magic damage based on character Energy.", + L"Attacker takes X damage when hitting causes an attacker to take damage when hitting.", + L"Attacker takes X damage per level causes an attacker to take damage based on character level.", + L"Attacker takes X ltng dmg when hitting causes an attacker to take lightning damage when hitting.", + L"Attacker takes X fire dmg when hitting causes an attacker to take fire damage when hitting.", + L"Attacker takes X cold dmg when hitting causes an attacker to take cold damage when hitting.", + L"Attacker X chance to flee when hitting gives the attacker a chance to flee when hitting.", + L"Attacker X chance get blinded when hitting gives the attacker a chance to get blinded when hitting.", + + L"Cold Damage adds cold damage to attacks or skills over a specified duration.", + L"Minimum Cold Damage sets the minimum cold damage for attacks or skills.", + L"Maximum Cold Damage sets the maximum cold damage for attacks or skills.", + L"Cold Duration sets the duration of cold effects caused by attacks or skills.", + L"Poison Damage adds poison damage to attacks or skills over a specified duration.", + L"Minimum Poison Damage sets the minimum poison damage for attacks or skills.", + L"Maximum Poison Damage sets the maximum poison damage for attacks or skills.", + L"Poison Duration sets the duration of poison effects caused by attacks or skills.", + L"Damage per Poison Level increases poison damage per character level.", + L"Poison Length Reduction reduces the duration of poison effects caused by attacks or skills.", + L"Poison Length Reduction per level reduces the duration of poison effects based on character level.", + L"Poison Length Reduction per Vitality reduces the duration of poison effects based on character Vitality.", + L"Fire Damage adds fire damage to attacks or skills over a specified duration.", + L"Minimum Fire Damage sets the minimum fire damage for attacks or skills.", + L"Maximum Fire Damage sets the maximum fire damage for attacks or skills.", + L"Fire Duration sets the duration of fire effects caused by attacks or skills.", + L"Fire Length Reduction reduces the duration of fire effects caused by attacks or skills.", + L"Fire Length Reduction per level reduces the duration of fire effects based on character level.", + L"Fire Length Reduction per Vitality reduces the duration of fire effects based on character Vitality.", + L"Lightning Damage adds lightning damage to attacks or skills over a specified duration.", + L"Minimum Lightning Damage sets the minimum lightning damage for attacks or skills.", + L"Maximum Lightning Damage sets the maximum lightning damage for attacks or skills.", + L"Lightning Duration sets the duration of lightning effects caused by attacks or skills.", + L"Magic Damage adds magic damage to attacks or skills over a specified duration.", + L"Minimum Magic Damage sets the minimum magic damage for attacks or skills.", + L"Maximum Magic Damage sets the maximum magic damage for attacks or skills.", + L"Magic Duration sets the duration of magic effects caused by attacks or skills.", + L"Damage per Magic Level increases magic damage per character level.", + L"Magic Resistance Reduction reduces enemy resistance against magic attacks.", + L"Monster Flee X% causes monsters to flee with a certain chance.", + L"Chance to create an explosion creates an explosion with a certain chance.", + L"Fire explosive arrows causes arrows to explode on impact with a certain chance.", + L"Half Freeze Duration halves the duration of freeze effects.", + L"Cannot be Frozen prevents the character from being frozen.", + L"+% to Resist All increases resistance to all damage types within a specified range.", + L"+% to Resist All based on Level increases resistance to all damage types based on character level.", + L"+% to Resist Cold increases resistance to cold damage within a specified range.", + L"+% to Resist Cold per level increases resistance to cold damage based on character level.", + L"+% to Resist Fire increases resistance to fire damage within a specified range.", + L"+% to Resist Fire per level increases resistance to fire damage based on character level.", + L"+% to Resist Lightning increases resistance to lightning damage within a specified range.", + L"+% to Resist Lightning per level increases resistance to lightning damage based on character level.", + L"+% to Resist Poison increases resistance to poison damage within a specified range.", + L"+% to Resist Poison per level increases resistance to poison damage based on character level.", + L"+% to Resist Magic increases resistance to magic damage within a specified range.", + L"+% to Resist Magic based on Level increases resistance to magic damage based on character level.", + L"+% to Resist Magic based on Energy increases resistance to magic damage based on character Energy.", + L"+% to Maximum Resist All increases maximum resistance to all damage types within a specified range.", + L"+% to Maximum Resist Cold increases maximum resistance to cold damage within a specified range.", + L"+% to Maximum Resist Fire increases maximum resistance to fire damage within a specified range.", + L"+% to Maximum Resist Lightning increases maximum resistance to lightning damage within a specified range.", + L"+% to Maximum Resist Poison increases maximum resistance to poison damage within a specified range.", + L"+% to Maximum Resist Magic increases maximum resistance to magic damage within a specified range.", + L"Reduce Poison Duration reduces the duration of poison effects on the character.", + L"Reduce Poison Duration per Level reduces the duration of poison effects based on character level.", + L"Reduce Poison Duration per Vitality reduces the duration of poison effects based on character Vitality.", + L"Reduce Curse Duration reduces the duration of curse effects on the character.", + L"Reduce Curse Duration per Level reduces the duration of curse effects based on character level.", + L"Reduce Curse Duration per Energy reduces the duration of curse effects based on character Energy.", + + L"Presence of 'res-all-max-hidden', 'res-all-hidden', 'res-all-max%', 'all-zero-display' on the same item displays and modifies all resistances.", + L"+ to Dexterity increases Dexterity within a specified range.", + L"+ to Dexterity per level increases Dexterity by a certain value per character level.", + L"+% to Dexterity increases Dexterity by a percentage within a specified range.", + L"+% to Dexterity per level increases Dexterity by a percentage per character level.", + L"+ to Strength increases Strength within a specified range.", + L"+ to Strength per level increases Strength by a certain value per character level.", + L"+% to Strength increases Strength by a percentage within a specified range.", + L"+% to Strength per level increases Strength by a percentage per character level.", + L"+ to Vitality increases Vitality within a specified range.", + L"+ to Vitality per level increases Vitality by a certain value per character level.", + L"+% to Vitality increases Vitality by a percentage within a specified range.", + L"+% to Vitality per level increases Vitality by a percentage per character level.", + L"+ to Energy increases Energy within a specified range.", + L"+ to Energy per level increases Energy by a certain value per character level.", + L"+% to Energy increases Energy by a percentage within a specified range.", + L"+% to Energy per level increases Energy by a percentage per character level.", + L"Adds + to All stats increases all stats within a specified range.", + L"+ to Health increases Health within a specified range.", + L"+ to Health per level increases Health by a certain value per character level.", + L"+ to Health based on Vitality increases Health based on Vitality by a certain value.", + L"+% to Health increases Health by a percentage within a specified range.", + L"+ to Mana increases Mana within a specified range.", + L"+ to Mana per level increases Mana by a certain value per character level.", + L"+ to Mana based on Energy increases Mana based on Energy by a certain value.", + L"+% to Mana increases Mana by a percentage within a specified range.", + L"+ to Replenish Life grants life replenishment within a specified range.", + L"+% to Mana Regeneration increases Mana regeneration by a percentage within a specified range.", + L"+% run/walk speed increases running and walking speed within a specified range.", + L"+% run/walk speed based on Level increases running and walking speed based on character level.", + L"+% run/walk speed based on Vitality increases running and walking speed based on Vitality.", + L"+ to stamina increases Stamina within a specified range.", + L"+ stamina per level increases Stamina by a certain value per character level.", + L"+% reduce stamina drain decreases the rate at which stamina is drained within a specified range.", + L"+% stamina regeneration increases stamina regeneration rate within a specified range.", + L"+% regenerate stamina per level increases stamina regeneration rate based on character level.", + L"+% attack speed increases attack speed within a specified range.", + L"+% attack speed based on Level increases attack speed based on character level.", + L"+% attack speed based on Strength increases attack speed based on Strength.", + L"+% attack speed based on Dexterity increases attack speed based on Dexterity.", + L"+% chance to block increases the chance to block within a specified range.", + L"+% chance to block based on Level increases the chance to block based on character level.", + L"+% chance to block based on Strength increases the chance to block based on Strength.", + L"+% chance to block based on Dexterity increases the chance to block based on Dexterity.", + L"+% block speed increases block speed within a specified range.", + L"+% block speed based on Level increases block speed based on character level.", + L"+% block speed based on Strength increases block speed based on Strength.", + L"+% block speed based on Dexterity increases block speed based on Dexterity.", + L"+% cast speed increases casting speed within a specified range.", + L"+% cast speed based on Level increases casting speed based on character level.", + L"+% cast speed based on Energy increases casting speed based on character Energy.", + L"+% hit recovery speed increases hit recovery speed within a specified range.", + L"+% hit recovery speed based on Level increases hit recovery speed based on character level.", + L"+% hit recovery speed based on Vitality increases hit recovery speed based on Vitality.", + L"+ to Light Radius increases the light radius within a specified range.", + L"Fire Magic Arrows enables firing magical arrows.", + L"Fire Explosive Arrows enables firing explosive arrows.", + L"+% chance to find magic items increases the chance to find magic items within a specified range.", + L"+ Magic Find per level increases the chance to find magic items based on character level.", + L"+% increased gold drops increases the amount of gold dropped by monsters within a specified range.", + L"+ More Gold per Level increases the amount of gold dropped by monsters based on character level.", + L"Altered Item Requirements reduces the requirements to equip an item within a specified range.", + L"Chance to make enemies flee increases the chance of causing enemies to flee within a specified range.", + L"Add X Sockets to an Item adds a specific number of sockets to an item.", + L"Makes any item throwable enables throwing any item.", + L"Adds additional blood increases the amount of blood displayed when hitting enemies.", + L"+% additional xp gained increases the amount of experience gained within a specified range.", + L"+ additional xp gained per level increases the amount of experience gained based on character level.", + L"+ additional xp gained based on Energy increases the amount of experience gained based on character Energy.", + L"Reduce vendor cost reduces the cost of items bought from vendors within a specified range.", + L"Reduce vendor cost based on Level reduces the cost of items based on character level.", + L"Applies fade state changes the character to a faded state within a specified range.", + L"Adds additional level requirements increases the level requirement to use an item.", + L"Force spawns item as ethereal makes an item always spawn as an ethereal item." + + }; + + // Calculate the number of tips in the array + int numTips = sizeof(tips) / sizeof(tips[0]); + + // Seed the random number generator + srand(static_cast(time(nullptr))); + + // Generate a random index + int randomIndex = rand() % numTips; + + // Print the randomly selected tip using D2PrintString function + D2PrintString(const_cast(tips[randomIndex]), 152, 95, WHITE, 0); - //printGoldMaxPopup - if (isOnStashGoldField(mx, my)) - { - if (active_sharedGold) - { - _snwprintf(popupText, 0x400, L"%s\n%s: %u", maxGoldText, getLocalString(STR_SHARED_GOLD_QUANTITY), PCPY->sharedGold); - D2PrintPopup(popupText, getXStashGoldField() + posWStashGoldField/2, getYStashGoldField() - posHStashGoldField - 2, WHITE, 1); - } else - D2PrintPopup(maxGoldText, getXStashGoldField() + posWStashGoldField/2, getYStashGoldField() - posHStashGoldField - 2, WHITE, 1); } } @@ -625,7 +971,14 @@ void Install_InterfaceStash() // print page number mem_seek R8(D2Client, 3903C, 3903C, 3F375, B0FE3, 7DF63, B3633, 99A33, 9DE03, 8F2E5); + + StartTimer(); + + MEMJ_REF4( D2PrintString, printPageNumber); + + + //6FADF374 |. E8 3FCC0800 CALL //6FB60FE2 |. E8 99C2F5FF CALL //6FB2DF62 |. E8 19F3F8FF CALL diff --git a/PlugY/Interface_Stats.cpp b/PlugY/Interface_Stats.cpp index 85e6029..1d3a4cf 100644 --- a/PlugY/Interface_Stats.cpp +++ b/PlugY/Interface_Stats.cpp @@ -13,6 +13,7 @@ #include "common.h" #include +/* static struct { union{ @@ -35,6 +36,7 @@ static struct #define getYNextPageBtn() RY(D2GetResolution()?0x40:0x70) #define getHNextPageBtn() 32 #define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn()) +*/ @@ -49,7 +51,7 @@ void STDCALL printStatsPageBtns() sDrawImageInfo data; ZeroMemory(&data,sizeof(data)); - if (printBackgroundOnMainPage && D2GetResolution()) + if (printBackgroundOnMainPage) { setImage(&data, statsBackgroundImages); setFrame(&data, 1); @@ -57,16 +59,14 @@ void STDCALL printStatsPageBtns() } setImage(&data, D2LoadBuySelBtn()); - if (D2GetResolution()) - { - setFrame(&data, 12 + isDownBtn.previousPage); - D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0); - } + setFrame(&data, 12 + isDownBtn.previousPage); + D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0); + setFrame(&data, 14 + isDownBtn.nextPage); D2PrintImage(&data, getXNextPageBtn(), getYNextPageBtn(), -1, 5, 0); D2SetFont(1); - if (D2GetResolution() && isOnPreviousPageBtn(mx,my)) //print popup "previous page" + if (isOnPreviousPageBtn(mx,my)) //print popup "previous page" { lpText = getLocalString(STR_PREVIOUS_PAGE); D2PrintPopup(lpText, getXPreviousPageBtn()+getLPreviousPageBtn()/2, getYPreviousPageBtn()-getHPreviousPageBtn(), WHITE, 1); @@ -84,6 +84,12 @@ Unit* STDCALL statsPageMouseDown(sWinMessage* msg) if (!active_newInterfaces || !D2isLODGame() ) return ptChar; + if (statsLeftDown(msg)) { + freeMessage(msg); + return NULL; + } + + /* if (D2GetResolution() && isOnPreviousPageBtn(msg->x,msg->y)) { log_msg("push down left button previous page\n"); @@ -100,6 +106,7 @@ Unit* STDCALL statsPageMouseDown(sWinMessage* msg) freeMessage(msg); return NULL; } + */ return ptChar; } @@ -110,6 +117,13 @@ Unit* STDCALL statsPageMouseUp(sWinMessage* msg) if (!active_newInterfaces || !D2isLODGame() ) return ptChar; + if (statsLeftUp(msg)) { + isDownBtn.all=0; + freeMessage(msg); + return NULL; + } + + /* if (D2GetResolution() && isOnPreviousPageBtn(msg->x,msg->y)) { log_msg("push up left button previous page\n"); @@ -134,6 +148,7 @@ Unit* STDCALL statsPageMouseUp(sWinMessage* msg) return NULL; } } + */ isDownBtn.all=0; return ptChar; diff --git a/PlugY/LocalizedStrings.cpp b/PlugY/LocalizedStrings.cpp index 70595ee..3c76d87 100644 --- a/PlugY/LocalizedStrings.cpp +++ b/PlugY/LocalizedStrings.cpp @@ -51,7 +51,7 @@ LPCWSTR getLocalTypeString(DWORD code) { if (sLocalizedTypeStrings[i].code == code) { - log_msg("Code=%08X\n", code); + //log_msg("Code=%08X\n", code); if (sLocalizedTypeStrings[i].itemStr) return StripGender(D2GetStringFromString(sLocalizedTypeStrings[i].itemStr)); LPWSTR text = StripGender(sLocalizedTypeStrings[i].typeLocalizedString); @@ -300,6 +300,8 @@ void loadLocalizedStrings(int language) LOAD(STR_SHARED_GOLD_QUANTITY); LOAD(STR_PREVIOUS_PAGE); LOAD(STR_NEXT_PAGE); + LOAD(STR_PREVIOUS_RUNE); + LOAD(STR_NEXT_RUNE); LOAD(STR_ITEM_LEVEL); LOAD(STR_PAGE_TYPE_CHANGE); diff --git a/PlugY/LocalizedStrings.h b/PlugY/LocalizedStrings.h index 9fb08e7..0e7b83d 100644 --- a/PlugY/LocalizedStrings.h +++ b/PlugY/LocalizedStrings.h @@ -37,6 +37,8 @@ enum eStringList STR_SHARED_GOLD_QUANTITY, STR_PREVIOUS_PAGE, STR_NEXT_PAGE, + STR_PREVIOUS_RUNE, + STR_NEXT_RUNE, STR_ITEM_LEVEL, STR_PAGE_TYPE_CHANGE, // diff --git a/PlugY/NewInterface_CubeListing.cpp b/PlugY/NewInterface_CubeListing.cpp index 1c54331..d50c8bc 100644 --- a/PlugY/NewInterface_CubeListing.cpp +++ b/PlugY/NewInterface_CubeListing.cpp @@ -233,12 +233,6 @@ DWORD print(CubeMainBIN* curForm, LPWSTR buf, LPINT len, DWORD)//maxsize) printInputItem(&curForm->input6, buf, len, &realNbInputs); printInputItem(&curForm->input7, buf, len, &realNbInputs); - if (realNbInputs != curForm->numinputs) - { - PRINT(BUF, L" *** ERROR : numInputs(%d) != realNbInputs(%d) ***", curForm->numinputs, realNbInputs); - return 1; - } - PRINT(BUF,L" => "); int realNbOutputs=0; @@ -269,6 +263,9 @@ DWORD print(CubeMainBIN* curForm, LPWSTR buf, LPINT len, DWORD)//maxsize) // if (curForm->version == 100) // sprintf(BUF, " [expansion only]"); + if (realNbInputs != curForm->numinputs) + PRINT(BUF, L" *** ERROR : numInputs(%d) != realNbInputs(%d) ***", curForm->numinputs, realNbInputs); + return 1; } #undef BUF diff --git a/PlugY/NewInterface_Runewords.cpp b/PlugY/NewInterface_Runewords.cpp index 99d1f38..13efd9f 100644 --- a/PlugY/NewInterface_Runewords.cpp +++ b/PlugY/NewInterface_Runewords.cpp @@ -12,6 +12,7 @@ #include "common.h" #include +/* #define NB_RUNES_PER_PAGE 25 #define getXCloseBtn() 360 @@ -53,6 +54,7 @@ static struct }; }; } isDownBtn; +*/ void printRuneword(RunesBIN* runesData, DWORD pos) @@ -64,7 +66,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos) D2SetFont(6); DWORD nbPixel = D2GetPixelLen(lpText); DWORD x1 = (nbPixel >= 195) ? 0 : 195-nbPixel; - D2PrintString(lpText, x1, 10 + pos*20, GOLD, 0);//MILIEU(0x00,0x70,nbPixel) + D2PrintString(lpText, posXRunesList + RX(x1), posYRunesList + 10 + pos*20, GOLD, 0);//MILIEU(0x00,0x70,nbPixel) typesList[0]=L'\0'; DWORD numItype=0; @@ -80,7 +82,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos) } nbPixel = D2GetPixelLen(typesList); x1 = (nbPixel >= 195) ? 0 : 195-nbPixel; - D2PrintString(typesList, x1, 20 + pos*20, WHITE, 0);//MILIEU(0x70,0xA0,nbPixel) + D2PrintString(typesList, posXRunesList + RX(x1), posYRunesList + 20 + pos*20, WHITE, 0);//MILIEU(0x70,0xA0,nbPixel) runesList[0]=L'\0'; DWORD numRune=0; @@ -115,7 +117,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos) } // x1 = (nbPixel < 145) ? 155 : 300-nbPixel; - D2PrintString(runesList, x1, y1 + pos*20, WHITE, 0);//MILIEU(0xD0,0xA0,nbPixel) + D2PrintString(runesList, posXRunesList + RX(x1), posYRunesList + y1 + pos*20, WHITE, 0);//MILIEU(0xD0,0xA0,nbPixel) } @@ -123,48 +125,58 @@ void printRuneword(RunesBIN* runesData, DWORD pos) //6FB21FAA void STDCALL printRunewordsPage() { - if (!D2isLODGame() || !D2GetResolution()) return D2PrintStatsPage(); + if (!D2isLODGame()) return D2PrintStatsPage(); LPWSTR lpText; - bDontPrintBorder = true; + bDontPrintBorder = D2GetResolution()? true : false; //Init data for print image sDrawImageInfo data; ZeroMemory(&data,sizeof(data)); //print background -/* setImage(&data, newStatsInterfaceImages); + fillRect(RX(0), RY(ResolutionY), 512, 768, 0, 5); + setImage(&data, newStatsInterfaceImages); setFrame(&data, 0); - D2PrintImage(&data, 0, 256, -1, 5, 0); + D2PrintImage(&data, RX(0), RY(ResolutionY-256), -1, 5, 0); setFrame(&data, 1); - D2PrintImage(&data, 256,256, -1, 5, 0); + D2PrintImage(&data, RX(256),RY(ResolutionY-256), -1, 5, 0); setFrame(&data, 2); - D2PrintImage(&data, 0, 512, -1, 5, 0); + D2PrintImage(&data, RX(0), RY(ResolutionY-256*2), -1, 5, 0); setFrame(&data, 3); - D2PrintImage(&data, 256,512, -1, 5, 0); + D2PrintImage(&data, RX(256),RY(ResolutionY-256*2), -1, 5, 0); setFrame(&data, 4); - D2PrintImage(&data, 0, 552, -1, 5, 0); + D2PrintImage(&data, RX(0), RY(ResolutionY-256*3), -1, 5, 0); setFrame(&data, 5); - D2PrintImage(&data, 256,552, -1, 5, 0); -*/ - fillRect(0,0,400,552,0,5); + D2PrintImage(&data, RX(256),RY(ResolutionY-256*3), -1, 5, 0); + + if (printBackgroundOnMainPage) + { + setImage(&data, statsBackgroundImages); + setFrame(&data, 1); + D2PrintImage(&data, getXPreviousPageBtn()-7, getYPreviousPageBtn()+8, -1, 5, 0); + D2PrintImage(&data, getXPrevRunesBtn()-7, getYPrevRunesBtn()+8, -1, 5, 0); + } //print button close setImage(&data, D2LoadBuySelBtn()); setFrame(&data, 10 + isDownBtn.close); D2PrintImage(&data, getXCloseBtn(), getYCloseBtn(), -1, 5, 0); + //print previous page button + setFrame(&data, 12 + isDownBtn.previousPage); + D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0); + //print next page button - setFrame(&data, isDownBtn.nextPage); + setFrame(&data, 14 + isDownBtn.nextPage); D2PrintImage(&data, getXNextPageBtn(), getYNextPageBtn(), -1, 5, 0); //print previous runes button - setImage(&data, stashBtnsImages); - setFrame(&data, isDownBtn.prevRunes); + setFrame(&data, 12 + isDownBtn.prevRunes); D2PrintImage(&data, getXPrevRunesBtn(), getYPrevRunesBtn(), -1, 5, 0); //print previous runes button - setFrame(&data, 2 + isDownBtn.nextRunes); + setFrame(&data, 14 + isDownBtn.nextRunes); D2PrintImage(&data, getXNextRunesBtn(), getYNextRunesBtn(), -1, 5, 0); D2SetFont(6); @@ -181,11 +193,11 @@ void STDCALL printRunewordsPage() { if (!runesData->Complete || runesData->Server) continue; nbRunesCompleted++; - if ( (curRunesPage * NB_RUNES_PER_PAGE < nbRunesCompleted) && - (nbRunesCompleted <= (curRunesPage+1) * NB_RUNES_PER_PAGE) ) + if ( (curRunesPage * runesPerPage < nbRunesCompleted) && + (nbRunesCompleted <= (curRunesPage+1) * runesPerPage) ) printRuneword(runesData, curNbRunes++); } - maxRunesPage = nbRunesCompleted ? (nbRunesCompleted-1) / NB_RUNES_PER_PAGE : 0; + maxRunesPage = nbRunesCompleted ? (nbRunesCompleted-1) / runesPerPage : 0; //////////////////// POPUP PRINTING //////////////////// @@ -197,11 +209,26 @@ void STDCALL printRunewordsPage() { D2PrintPopup(D2GetStringFromIndex(0x1030), getXCloseBtn()+getLCloseBtn()/2, getYCloseBtn()-getHCloseBtn(), WHITE, 1); } + else if (isOnPreviousPageBtn(x,y)) //print popup "previous page" + { + lpText = getLocalString(STR_PREVIOUS_PAGE); + D2PrintPopup(lpText, getXPreviousPageBtn()+getLPreviousPageBtn()/2, getYPreviousPageBtn()-getHPreviousPageBtn(), WHITE, 1); + } else if (isOnNextPageBtn(x,y)) // print popup "next page" { lpText = getLocalString(STR_NEXT_PAGE); D2PrintPopup(lpText, getXNextPageBtn()+getLNextPageBtn()/2, getYNextPageBtn()-getHNextPageBtn(), WHITE, 1); } + else if (isOnPrevRunesBtn(x,y)) // print popup "previous rune" + { + lpText = getLocalString(STR_PREVIOUS_RUNE); + D2PrintPopup(lpText, getXPrevRunesBtn()+getLPrevRunesBtn()/2, getYPrevRunesBtn()-getHPrevRunesBtn(), WHITE, 1); + } + else if (isOnNextRunesBtn(x,y)) // print popup "next rune" + { + lpText = getLocalString(STR_NEXT_RUNE); + D2PrintPopup(lpText, getXNextRunesBtn()+getLNextRunesBtn()/2, getYNextRunesBtn()-getHNextRunesBtn(), WHITE, 1); + } } ////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/PlugY/NewInterface_Stats.cpp b/PlugY/NewInterface_Stats.cpp index 10fa32d..d73c5da 100644 --- a/PlugY/NewInterface_Stats.cpp +++ b/PlugY/NewInterface_Stats.cpp @@ -13,6 +13,7 @@ #include +/* #define getXCloseBtn() 360 #define getLCloseBtn() 32 #define getYCloseBtn() (ResolutionY - 60) @@ -92,6 +93,7 @@ void** ptD2AssignStatsPointsBtnImages = (void**)0x6FBB5BB4; +/* static struct { union{ @@ -111,6 +113,7 @@ static struct }; }; } isDownBtn; +*/ void print2Lines(WORD id, LPWSTR lpText, DWORD x, DWORD l, DWORD y) diff --git a/PlugY/NewInterface_StatsPageTwo.cpp b/PlugY/NewInterface_StatsPageTwo.cpp index dfdc8a1..6215dd6 100644 --- a/PlugY/NewInterface_StatsPageTwo.cpp +++ b/PlugY/NewInterface_StatsPageTwo.cpp @@ -12,6 +12,7 @@ #include "common.h" #include +/* #define getXCloseBtn() RX(0x110) #define getLCloseBtn() 32 #define getYCloseBtn() RY(0x40) @@ -29,11 +30,13 @@ #define getYNextPageBtn() RY(0x40) #define getHNextPageBtn() 32 #define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn()) +*/ const char * STATS_INTERFACE_FILENAME = "PlugY\\statsinterface.txt"; #define BUFSIZE 0x400 +/* static struct { union{ @@ -45,6 +48,7 @@ static struct }; }; } isDownBtn; +*/ struct statsInterfaceBIN @@ -337,8 +341,7 @@ void STDCALL printNewStatsPageTwo(int currentPage) WCHAR text[BUFSIZE]; LPWSTR lpText; - bDontPrintBorder = false; - + bDontPrintBorder = D2GetResolution()? true : false; Unit* ptChar = D2GetClientPlayer(); d2_assert(!ptChar, "Printing stats page : no character selected",__FILE__,__LINE__); @@ -349,16 +352,20 @@ void STDCALL printNewStatsPageTwo(int currentPage) ZeroMemory(&data,sizeof(data)); //print background - fillRect(RX(0),RY(480),320,432,0,5);//552 + fillRect(RX(0), RY(ResolutionY), 512, 768, 0, 5); setImage(&data, newStatsInterfaceImages); setFrame(&data, 0); - D2PrintImage(&data, RX(0), RY(224), -1, 5, 0); + D2PrintImage(&data, RX(0), RY(ResolutionY-256), -1, 5, 0); setFrame(&data, 1); - D2PrintImage(&data, RX(256),RY(224), -1, 5, 0);//256 + D2PrintImage(&data, RX(256),RY(ResolutionY-256), -1, 5, 0); setFrame(&data, 2); - D2PrintImage(&data, RX(0), RY(48), -1, 5, 0);//432 + D2PrintImage(&data, RX(0), RY(ResolutionY-256*2), -1, 5, 0); setFrame(&data, 3); - D2PrintImage(&data, RX(256),RY(48), -1, 5, 0); + D2PrintImage(&data, RX(256),RY(ResolutionY-256*2), -1, 5, 0); + setFrame(&data, 4); + D2PrintImage(&data, RX(0), RY(ResolutionY-256*3), -1, 5, 0); + setFrame(&data, 5); + D2PrintImage(&data, RX(256),RY(ResolutionY-256*3), -1, 5, 0); D2SetFont(1); for (int i=0; i= 0) && (page <= lastPage + (D2GetResolution()? extraHiddenPage : 0)) ) + if ( (page >= 0) && (page <= (lastPage + extraHiddenPage)) ) selectedPage = page; + else if (page < 0) + selectedPage = lastPage + extraHiddenPage; + else + selectedPage = 0; } int GetCurrentPage() @@ -83,6 +115,16 @@ DWORD STDCALL mouseCustomPageLeftDown(sWinMessage* msg) DWORD STDCALL mouseCustomPageLeftUp(sWinMessage* msg) { if(onRealm) return -1; + + if (selectedPage == 0) return -1; + if (!isOnStatsPage(msg->x,msg->y)) return 1; + statsLeftUp(msg); + D2CleanStatMouseUp(); + freeMessage(msg); + isDownBtn.all=0; + return 0; + + /* if ( (selectedPage > 0) && (selectedPage <= lastPage) ) return mouseNewStatsPageTwoLeftUp(msg); else if (selectedPage == lastPage+1) @@ -91,6 +133,87 @@ DWORD STDCALL mouseCustomPageLeftUp(sWinMessage* msg) return mouseNewStatsPageLeftUp(msg); else return -1; + */ +} + +DWORD STDCALL statsLeftDown(sWinMessage* msg) +{ + if (isOnCloseBtn(msg->x,msg->y) && selectedPage != 0) + { + log_msg("push down left button close\n"); + isDownBtn.close = 1; + D2PlaySound(4,0,0,0,0); + return 1; + } + else if (isOnPreviousPageBtn(msg->x,msg->y)) + { + log_msg("push down left button previous page\n"); + isDownBtn.previousPage = 1; + D2PlaySound(4,0,0,0,0); + return 1; + } + else if (isOnNextPageBtn(msg->x,msg->y)) + { + log_msg("push down left button next page\n"); + isDownBtn.nextPage = 1; + D2PlaySound(4,0,0,0,0); + return 1; + } + else if (isOnPrevRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage)) + { + log_msg("push down left button prev runes\n"); + isDownBtn.prevRunes = 1; + D2PlaySound(4,0,0,0,0); + return 1; + } + else if (isOnNextRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage)) + { + log_msg("push down left button next runes\n"); + isDownBtn.nextRunes = 1; + D2PlaySound(4,0,0,0,0); + return 1; + } + return 0; +} + +DWORD STDCALL statsLeftUp(sWinMessage* msg) +{ + if (isOnCloseBtn(msg->x,msg->y) && selectedPage != 0) + { + log_msg("push up left button close\n"); + if (isDownBtn.close) + D2TogglePage(2,1,0); + return 1; + } + else if (isOnPreviousPageBtn(msg->x,msg->y)) + { + log_msg("push up left button previous page\n"); + if (isDownBtn.previousPage) + GoStatPage(selectedPage-1); + return 1; + } + else if (isOnNextPageBtn(msg->x,msg->y)) + { + log_msg("push up left button next page\n"); + if (isDownBtn.nextPage) + GoStatPage(selectedPage+1); + return 1; + } + else if (isOnPrevRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage)) + { + log_msg("push up left button prev runes\n"); + if (isDownBtn.prevRunes && curRunesPage) + curRunesPage--; + return 1; + } + else if (isOnNextRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage)) + { + log_msg("push up left button next runes\n"); + if (isDownBtn.nextRunes && (curRunesPage < maxRunesPage)) + curRunesPage++; + return 1; + } + return 0; } FCT_ASM ( caller_DontPrintBorder_114 ) @@ -474,6 +597,7 @@ void Install_NewInterfaces() //00498636 |. 6A 48 PUSH 48 //00498638 |. 8D45 B8 LEA EAX,DWORD PTR SS:[EBP-48] + /* Conflicts with D2ExpRes // Manage mouse down (Play sound) mem_seek R8(D2Client, 2A9DC, 2A9CC, 312A5, 82736, 891B6, 6B116, BCD36, BF4D6, A7731); memt_byte( 0x8D, 0xE8 ); // CALL @@ -486,6 +610,7 @@ void Install_NewInterfaces() //6FB6CD36 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80] //6FB6F4D6 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80] //004A7731 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80] + */ // Manage mouse up mem_seek R8(D2Client, 2ABBB, 2ABAB, 3148D, 836D9, 8A159, 6C0B9, BDCB9, C0459, A78DA); diff --git a/PlugY/Parameters.cpp b/PlugY/Parameters.cpp index b4dc915..392c112 100644 --- a/PlugY/Parameters.cpp +++ b/PlugY/Parameters.cpp @@ -58,6 +58,7 @@ const char* S_dllFilenames2 = "DllToLoad2"; const char* S_active_Commands = "ActiveCommands"; const char* S_active_CheckMemory = "ActiveCheckMemory"; const char* S_active_othersFeatures = "ActiveAllOthersFeatures"; +const char* S_saveFileStackSize = "SaveFileStackSize"; const char* S_WINDOWED = "WINDOWED"; const char* S_ActiveWindowed = "ActiveWindowed"; @@ -214,6 +215,19 @@ const char* S_INTERFACE = "INTERFACE"; const char* S_active_newInterfaces = "ActiveNewStatsInterface"; const char* S_selectMainPageOnOpenning = "SelectMainPageOnOpenning"; const char* S_printBackgroundOnMainPage = "PrintButtonsBackgroundOnMainStatsPage"; +const char* S_posXNextPageBtn = "PosXNextPageBtn"; +const char* S_posYNextPageBtn = "PosYNextPageBtn"; +const char* S_posXPrevPageBtn = "PosXPrevPageBtn"; +const char* S_posYPrevPageBtn = "PosYPrevPageBtn"; +const char* S_posXClosePageBtn = "PosXClosePageBtn"; +const char* S_posYClosePageBtn = "PosYClosePageBtn"; +const char* S_posXNextRuneBtn = "PosXNextRuneBtn"; +const char* S_posYNextRuneBtn = "PosYNextRuneBtn"; +const char* S_posXPrevRuneBtn = "PosXPrevRuneBtn"; +const char* S_posYPrevRuneBtn = "PosYPrevRuneBtn"; +const char* S_posXRunesList = "PosXRunesList"; +const char* S_posYRunesList = "PosYRunesList"; +const char* S_runesPerPage = "RunesPerPage"; const char* S_EXTRA = "EXTRA"; const char* S_active_RunLODs = "ActiveLaunchAnyNumberOfLOD"; @@ -316,6 +330,10 @@ void init_General(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFi active_othersFeatures = atoi(buffer) != 0; log_msg("active_othersFeatures\t\t= %u\n", active_othersFeatures); + GET_PRIVATE_PROFILE_STRING(S_GENERAL, S_saveFileStackSize, "8192"); + saveFileStackSize = atoi(buffer); + log_msg("SaveFileStackSize\t\t\t= %u\n", saveFileStackSize); + log_msg("\n"); } @@ -1032,6 +1050,52 @@ void init_NewInterfaces(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDef GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_printBackgroundOnMainPage, "1"); printBackgroundOnMainPage = atoi(buffer) != 0; log_msg("printBackgroundOnMainPage\t= %u\n", printBackgroundOnMainPage); + + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXNextPageBtn, "161"); + posXNextPageBtn = atoi(buffer); + log_msg("posXNextPageBtn\t= %d\n", posXNextPageBtn); + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYNextPageBtn, "64"); + posYNextPageBtn = atoi(buffer); + log_msg("posYNextPageBtn\t= %d\n", posYNextPageBtn); + + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXPrevPageBtn, "119"); + posXPrevPageBtn = atoi(buffer); + log_msg("posXPrevPageBtn\t= %d\n", posXPrevPageBtn); + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYPrevPageBtn, "64"); + posYPrevPageBtn = atoi(buffer); + log_msg("posYPrevPageBtn\t= %d\n", posYPrevPageBtn); + + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXClosePageBtn, "360"); + posXClosePageBtn = atoi(buffer); + log_msg("posXClosePageBtn\t= %d\n", posXClosePageBtn); + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYClosePageBtn, "64"); + posYClosePageBtn = atoi(buffer); + log_msg("posYClosePageBtn\t= %d\n", posYClosePageBtn); + + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXNextRuneBtn, "302"); + posXNextRuneBtn = atoi(buffer); + log_msg("posXNextRuneBtn\t= %d\n", posXNextRuneBtn); + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYNextRuneBtn, "64"); + posYNextRuneBtn = atoi(buffer); + log_msg("posYNextRuneBtn\t= %d\n", posYNextRuneBtn); + + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXPrevRuneBtn, "260"); + posXPrevRuneBtn = atoi(buffer); + log_msg("posXPrevRuneBtn\t= %d\n", posXPrevRuneBtn); + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYPrevRuneBtn, "64"); + posYPrevRuneBtn = atoi(buffer); + log_msg("posYPrevRuneBtn\t= %d\n", posYPrevRuneBtn); + + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXRunesList, "50"); + posXRunesList = atoi(buffer); + log_msg("posXRunesList\t= %d\n", posXRunesList); + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYRunesList, "45"); + posYRunesList = atoi(buffer); + log_msg("posYRunesList\t= %d\n", posYRunesList); + + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_runesPerPage, "30"); + runesPerPage = atoi(buffer); + log_msg("runesPerPage\t= %d\n", runesPerPage); } log_msg("\n"); } diff --git a/PlugY/PlugY.aps b/PlugY/PlugY.aps new file mode 100644 index 0000000..33a5e63 Binary files /dev/null and b/PlugY/PlugY.aps differ diff --git a/PlugY/PlugY.sln b/PlugY/PlugY.sln index 188f79b..f21d45b 100644 --- a/PlugY/PlugY.sln +++ b/PlugY/PlugY.sln @@ -1,7 +1,9 @@  -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlugY", "PlugY.vcproj", "{EB63DF4E-A019-4522-A140-9E8C7350B331}" +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32505.173 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlugY", "PlugY.vcxproj", "{EB63DF4E-A019-4522-A140-9E8C7350B331}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -17,4 +19,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {83A1632A-5376-46CE-89D9-F2D4E74FFE31} + EndGlobalSection EndGlobal diff --git a/PlugY/infinityStash.h b/PlugY/infinityStash.h index 0ca6b4d..123705d 100644 --- a/PlugY/infinityStash.h +++ b/PlugY/infinityStash.h @@ -18,6 +18,7 @@ extern bool active_sharedStash; extern bool active_sharedGold; extern bool separateHardSoftStash; extern char* sharedStashFilename; +extern DWORD saveFileStackSize; extern bool displaySharedSetItemNameInGreen; extern int posXPreviousBtn; diff --git a/PlugY/newInterfaces.h b/PlugY/newInterfaces.h index de51f26..c4c4ff3 100644 --- a/PlugY/newInterfaces.h +++ b/PlugY/newInterfaces.h @@ -9,20 +9,94 @@ #include "common.h" #define MILIEU(X,L,N) (X + ((N