diff --git a/Commons/D2Funcs.h b/Commons/D2Funcs.h new file mode 100644 index 0000000..9e923ea --- /dev/null +++ b/Commons/D2Funcs.h @@ -0,0 +1,856 @@ +/*====================================================================== + File created by Yohann NICOLAS. + + Declares the type for a STDCALL or FASTCALL function pointer + called N with arguments list P, returning R, namedInDLL D and at @A + +======================================================================*/ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//D2Common : +////D2S(D2Common,10001, DWORD, D2GetActIDFromLevel, (DWORD levelID)); +//D2S(D2Common,11084, DWORD, D2Common11084, (Room* ptRoom, DWORD zero));//use only in 1.11/1.11b +//D2S(D2Common,11021, DWORD, D2GetLevelID, (Room* ptRoom));//1.11b +//D2S(D2Common,10491, Room*, D2GetDropRoom, (Room* ptRoom, Position*, Position*, DWORD, DWORD, DWORD, DWORD));//1.11b +////D2S(D2Common,10149, Inventory*, D2GetInventory, (Unit* ptUnit)); +//D2S(D2Common,10242, Unit*, D2Common10242, (Inventory* ptInventory, Unit* ptItem, DWORD bIsClient)); +//D2S(D2Common,10813, Unit*, D2CanPutItemInInv, (Inventory* ptInventory, Unit* ptItem, DWORD p3, DWORD zero, Unit* ptUnit, const char* file, DWORD line));//ONLY 1.11b +//D2S(D2Common,10827, Unit*, D2InvRemoveItem, (Inventory* ptInventory, Unit* ptItem));//ONLY 1.11b +//D2S(D2Common,11068, DWORD, D2InvAddItem, (Inventory* ptInventory, Unit* ptItem, DWORD posX, DWORD posY, DWORD vValueC, DWORD bIsClient, BYTE page));//ONLY 1.11b result : boolean 0=echec ; vValueC = 0 for Game.dll, 1 for Clientdll +//D2S(D2Common,10250, DWORD, D2Common10250, (const char* file, DWORD line, Inventory* ptInventory, DWORD posX, DWORD posY, DWORD vValueC, DWORD bIsClient, BYTE page));// result : boolean 0=echec ; vValueC = 0 for Game.dll, 1 for Clientdll +////D2S(D2Common,10257, Unit*, D2GetItemFromBodyLoc, (Inventory* ptInventory, DWORD bodyloc)); +//D2S(D2Common,10273, DWORD, D2Common10273, (Inventory* ptInventory, void* unknow)); +//D2S(D2Common,10535, Unit*, D2InventoryGetFirstItem, (Inventory* ptInventory));//ONLY 1.11b +//D2S(D2Common,11140, Unit*, D2UnitGetNextItem, (Unit* ptItem));//ONLY 1.11b +//D2S(D2Common,10748, Unit*, D2GetRealItem, (Unit* ptUnit));//ONLY 1.11b +////D2S(D2Common,10321, SkillData*, D2GetLeftSkill, (Unit* ptChar)); +////D2S(D2Common,10322, SkillData*, D2GetRightSkill, (Unit* ptChar)); +//D2S(D2Common,10326, DWORD, D2GetPosX, (Unit* ptUnit));//NOT IN 1.10 +////D2S(D2Common,10328, void, D2SetPosX, (Unit* ptUnit, DWORD pos)); +//D2S(D2Common,10329, DWORD, D2GetPosY, (Unit* ptUnit));//NOT IN 1.10 +////D2S(D2Common,10331, void, D2SetPosY, (Unit* ptUnit, DWORD pos)); +//D2S(D2Common,10056, void, D2GetPosition, (Unit* ptUnit, Position* pos));//1.11b +//D2S(D2Common,10864, DWORD, D2GetMaxGoldBank, (Unit* ptUnit));//1.11b +//D2S(D2Common,10933, Room*, D2GetRoom, (Unit* ptUnit));//1.11b +////D2S(D2Common,10348, void, D2SetUnitMode, (Unit* ptUnit, DWORD mode)); +//D2S(D2Common,10394, ObjectsBIN*,D2GetObjectsBIN, (Unit* ptObject)); +//D2S(D2Common,10079, PlayerData*,D2InitPlayerData, (Unit* ptChar));//1.11b +//D2S(D2Common,10329, DWORD, D2FreePlayerData, (DWORD game1C, Unit* ptChar));//1.11b +//D2S(D2Common,10800, PlayerData*,D2GetPlayerData, (Unit* ptChar));//ONLY 1.11b +//D2S(D2Common,10431, DWORD, D2GetDefence, (Unit* ptChar)); +//D2S(D2Common,10433, DWORD, D2GetChanceToBlock, (Unit* ptChar, DWORD isLODGame)); +//D2S(D2Common,11131, DWORD, D2GetMaxGold, (Unit* ptUnit));//1.11b +//D2S(D2Common,10572, DWORD, D2Common10572, (Unit* ptObject, DWORD value));//use only in 1.11/1.11b +////D2S(D2Common,10463, DWORD, D2SetStatWithNoTest, ( Stats* ptStats, DWORD statID, DWORD statValue, DWORD statIndex)); +////D2S(D2Common,10464, void, D2AddStat, (Stats* ptStats, DWORD statID, DWORD statValue, DWORD statIndex)); +////D2S(D2Common,10465, DWORD, D2SetStat, (Stats* ptStats, DWORD statID, DWORD statValue, DWORD statIndex)); +////D2S(D2Common,10466, int, D2GetStat, (Stats* ptStats, DWORD statID, DWORD statIndex)); +////D2S(D2Common,10470, Stats*, D2AllocNewStats, (DWORD nUnitId, DWORD flags, DWORD uk18, DWORD nUnitType, DWORD nItemNum)); +//D2S(D2Common,11160, BYTE, D2GetObjectFlags, (Unit* ptObject)); +//D2S(D2Common,11048, void, D2SetObjectFlags, (Unit* ptObject, BYTE flags)); +////D2S(D2Common,10471, DWORD, D2Common10471, (void*));//UNTL 1.10 +////D2S(D2Common,10472, DWORD, D2Common10472, (void*)); +////D2S(D2Common,10475, void, D2UpdateDisabledStat, (Stats* ptCharStats, Stats* ptStats, DWORD one)); +////D2S(D2Common,10481, void*, D2Common10481, (Unit* ptUnit, DWORD flags)); +////D2S(D2Common,10484, Stats*, D2GetAffixStats, (Unit* ptItem, DWORD, DWORD)); +////D2S(D2Common,10485, void, D2FreeStats, (Stats* ptStats)); +//D2S(D2Common,10487, DWORD, D2isInState, (Unit* ptChar, DWORD isLODGame)); +////D2S(D2Common,10517, void, D2SetPlayerStat, (Unit* ptChar, DWORD statID, int amount, DWORD index)); +//D2S(D2Common,10627, void, D2AddPlayerStat, (Unit* ptChar, DWORD statID, int amount, DWORD index));//ONLY 1.11b +//D2S(D2Common,10061, int, D2GetPlayerStat, (Unit* ptChar, DWORD statID, DWORD index));//ONLY 1.11b +////D2S(D2Common,10520, int, D2GetPlayerStat20, (Unit* ptChar, DWORD statID, DWORD index)); +//D2S(D2Common,10550, int, D2GetPlayerBaseStat, (Unit* ptChar, DWORD statID, DWORD index));//ONLY 1.11b +////D2S(D2Common,10527, DWORD, D2Common10527, (Unit* ptUnit)); +//D2S(D2Common,10539, DWORD, D2haveDefenceBonus, (Unit* ptChar)); +//D2S(D2Common,10540, DWORD, D2haveFireResBonus, (Unit* ptChar)); +//D2S(D2Common,10541, DWORD, D2haveColdResBonus, (Unit* ptChar)); +//D2S(D2Common,10542, DWORD, D2haveLightResBonus, (Unit* ptChar)); +//D2S(D2Common,10543, DWORD, D2havePoisonResBonus, (Unit* ptChar)); +//D2S(D2Common,10546, DWORD, D2haveDefenceMalus, (Unit* ptChar)); +//D2S(D2Common,10547, DWORD, D2haveFireResMalus, (Unit* ptChar)); +//D2S(D2Common,10548, DWORD, D2haveColdResMalus, (Unit* ptChar)); +//D2S(D2Common,10549, DWORD, D2haveLightResMalus, (Unit* ptChar)); +//D2S(D2Common,10550, DWORD, D2havePoisonResMalus, (Unit* ptChar)); +////D2S(D2Common,10552, DWORD, D2Common10552, (Unit* ptUnit)); +////D2S(D2Common,10567, DWORD, D2CanBeBroken, (Unit* ptItem)); +////D2S(D2Common,10573, void, D2CopyStats, (Stats* ptDestStats, Stats* ptSrcStats)); +////D2S(D2Common,10574, void*, D2SetEnabledStat, (Unit* ptItem, DWORD statId, DWORD disabled)); +////D2S(D2Common,10575, void, D2FreeBinFiles, ()); +////D2S(D2Common,10576, void, D2LoadBinFiles, (DWORD zero1, DWORD zero2, bool)); +////D2S(D2Common,10651, DWORD, D2CheckQuestState, (void* ptQuest, DWORD index, DWORD value));//ONLY 1.11 +//D2S(D2Common,10496, void*, D2CompileTxtFile, (DWORD unused, const char* filename, BINField* ptFields, DWORD* ptRecordCount, DWORD recordLength));//ONLY 1.11b +//D2S(D2Common,10262, ItemsBIN*, D2GetItemsBIN, (DWORD itemID));//ONLY 1.11b +////D2S(D2Common,10601, ItemsBIN*, D2GetByCodeItemStatsBIN, (DWORD code, DWORD* itemID)); +////D2S(D2Common,10604, AffixBIN*, D2GetAffixBIN, (int affixID)); +//D2S(D2Common,10523, GemsBIN*, D2GetGemsBIN, (DWORD gemID));//1.11b +//D2S(D2Common,10258, CubeMainBIN*,D2GetCubeMainBIN, (DWORD cubemainID));//ONLY 1.11b +//D2S(D2Common,11135, int, D2GetNbCubeMainBIN, ());//ONLY 1.11b +////D2S(D2Common,10737, LevelsBIN*, D2GetLevelsBIN, (DWORD levelID)); +//D2S(D2Common,10628, DWORD, D2GetNextLevelXP, (DWORD classID, DWORD level)); +//D2S(D2Common,10629, DWORD, D2GetMaxLevel, (DWORD classID)); +//D2S(D2Common,10309, DifficultyLevelsBIN*, D2GetDifficultyLevelsBIN, (DWORD difficultyLevel)); +////D2S(D2Common,10659, TreasureClassBIN*, D2GetTreasureClassBIN, (WORD id, DWORD uk)); +////D2S(D2Common,10953, SuperUniqueBIN*, D2GetSuperUniqueBIN, (WORD id));//1.11b +//D2S(D2Common,10899, DWORD, D2GetItemQuality, (Unit* ptItem));//1.11b +//D2S(D2Common,10303, DWORD, D2TestFlags, (Unit* ptUnit, DWORD flags, DWORD line, const char* file));//ONLY 1.11b +////D2S(D2Common,10708, void, D2SetFlags, (Unit* ptUnit, DWORD flags, DWORD bitNewValue)); +////D2S(D2Common,10709, DWORD, D2GetFlags, (Unit* ptUnit)); +////D2S(D2Common,10711, void, D2ItemSetFlags, (Unit* ptItem, DWORD flags, DWORD toSet));// toSet = 0 for set to 0 the selected flags else set to 1 +//D2S(D2Common,10100, DWORD, D2GetItemLevel, (Unit* ptItem));//ONLY 1.11b +//D2S(D2Common,10505, BYTE, D2ItemGetPage, (Unit* ptUnit));//ONLY 1.11b +//D2S(D2Common,10608, void, D2ItemSetPage, (Unit* ptItem, BYTE page));//ONLY 1.11b +//D2S(D2Common,10890, DWORD, D2CheckItemType, (Unit* ptItem, DWORD itype));//ONLY 1.11b +//D2S(D2Common,10685, int, D2GetUniqueID, (Unit* ptItem));//1.11b +//D2S(D2Common,10734, void, D2SetAnim, (Unit* ptUnit, int anim)); +////D2S(D2Common,10749, void, D2GetWidthHeight, (Unit* ptItem, BYTE* Width, BYTE* Height); +////D2S(D2Common,10751, DWORD, D2GetItemType, (Unit* ptUnit)); +////D2S(D2Common,10757, DWORD, D2GetItemLevelReq, (Unit* ptChar, Unit* ptItem)); +//D2S(D2Common,10877, int*, D2GetNbRunesBIN, ());//ONLY 1.11b //return the point on th number +//D2S(D2Common,10296, RunesBIN*, D2GetRunesBIN, (int runesID));//ONLY 1.11b +////D2S(D2Common,10792, DWORD, D2CanBeRare, (Unit* ptItem)); +////D2S(D2Common,10810, BYTE, D2CheckHasInv, (Unit* ptItem)); +////D2S(D2Common,10813, DWORD, D2GetStaffMods, (Unit* ptItem)); +////D2S(D2Common,11085, DWORD, D2GetNbSocket, (Unit* ptItem));//1.11b +////D2S(D2Common,10840, DWORD, D2Common10840, (Unit* ptItem, Unit* ptChar)); +////D2S(D2Common,10855, void, D2AddAffix, (DWORD, DWORD, Unit* ptItem, AffixBIN* ptAffix, DWORD, DWORD)); +////D2S(D2Common,10872, DWORD, D2WarpPlayer, (Path* ptPath, Unit* ptChar, Room* ptRoom, DWORD x, DWORD y)); +////D2S(D2Common,10875, WORD, D2GetItemVersion, (Unit* ptItem)); +//D2S(D2Common,11068, DWORD, D2isEtheral, (Unit* ptItem));//ONLY UNTIL 1.10 //1.11b +//D2S(D2Common,11156, DWORD, D2SaveItem, (Unit* ptItem, saveBitField* data, DWORD startSize, DWORD p4, DWORD p5, DWORD p6));//1.11b +////D2S(D2Common,10916, void, DoNothing916, ()); +////D2S(D2Common,10105, void, D2Common10027, (Unit* ptChar, DWORD skillID));//ONLY 1.11b +////D2S(D2Common,10950, SkillData*, D2GetSkillPointer, (Unit* ptChar, WORD SkillID)); +////D2S(D2Common,10256, SkillData*, D2IncSkillBaseLevel, (Unit* ptChar, DWORD skillID));//ONLY 1.11b +//D2S(D2Common,10255, void, D2SetSkillBaseLevel,(Unit* ptChar, DWORD skillID, DWORD slvl, DWORD bRemove, char*, DWORD));//ONLY 1.11b +////D2S(D2Common,10963, DWORD, D2GetSkillID, (SkillData* ptSkill, const char* file, DWORD line)); +////D2F(D2Common,10966, SkillsBIN*, D2GetSkillsBIN, (SkillData* ptSkill)); +//D2S(D2Common,10109, DWORD, D2GetSkillLevel, (Unit* ptChar, SkillData* ptSkill, DWORD includingBonus));//ONLY 1.11b +////D2S(D2Common,11023, DWORD, D2GetCriticalStrikeFromMasteries, (Unit* ptChar, Unit* ptItem, DWORD zero, DWORD two)); +////D2S(D2Common,11007, bool, D2TestQuestState, (void* ptQuest, DWORD QuestID, DWORD QuestState)); +////D2S(D2Common,11041, int, D2GetPlayerSkillID, (DWORD playerID, DWORD skillNumber)); +////D2S(D2Common,11042, int, D2GetNbSkillsPerPlayer, (DWORD playerID)); +////D2S(D2Common,11269, DWORD, D2GetAllIndexFromStat, (Stats* ptStats, DWORD statID, D2Stat* allIndex, DWORD maxIndex)); +////D2S(D2Common,11270, DWORD, D2GetAllIndexFromStatID, (Unit* ptItem, DWORD statID, D2Stat* allIndex, DWORD)); +//D2S(D2Common,10074, DWORD, D2GetSkillCost, (Unit* ptChar, int skpoints, DWORD skillID, DWORD curSkillLevel));//ONLY 1.11b (not 10447) +//E2F(D2Common,1800, CharStatsBIN*, D2GetCharStatsBIN, (DWORD charID));//1.11b /NOT in 1.10 +//E2F(D2Common,1A100, DWORD, D2CompileCubeInput, (CubeInput* cubeinput, char* s, DWORD p1, DWORD p2));//1.11b +//E2F(D2Common,19B40, DWORD, D2CompileCubeOutput, (CubeOutput* cubeoutput, char* s, DWORD p1, DWORD p2));//1.11b +//E2F(D2Common,1380, ItemTypesBIN*, D2GetItemTypesBIN, (DWORD itemTypesId));//ONLY 1.11b +////E2F(D2Common,62FD0, void, D2EncodeValueCheckMax, (saveBitField* data, DWORD value, DWORD bitSize)); +//E2F(D2Common,12F0, ItemStatCostBIN*, D2GetItemStatCostBIN, (DWORD id));//ONLY 1.11b +////E2F(D2Common,764A0, void*, D2Common764A0, (Stats* ptStats, DWORD stat, ItemStatCostBIN* itemStatCost ,DWORD)); +////E2S(D2Common,76E30, void, D2PreUpdateDisabledStat, (Stats* ptStats)); +////E2F(D2Common,76C10, void, D2ApplyStat,(Stats* ptCharStats, DWORD statId, DWORD value, Unit* ptItem)); +//E2F(D2Common,98D0, void*, D2ReadFile,(DWORD unused, char* filename, DWORD* size, const char*, DWORD));//1.11b +////E2F(D2Common,94D0, void*, D2GetStringIDForTxtFile,(const char * string)); +//E2S(D2Common,32AA0, void, D2LoadSuperuniques,(DWORD mempool));//FASCALL UNTIL 1.10 (1.11b) + + + +//F7(STD, D2Common,00000,00000,00000,00000,10001,00000,00000, DWORD, D2GetActIDFromLevel, (DWORD levelID)); +F7(STD, D2Common,00000,00000,00000,10188,11084,11109,10346, DWORD, D2Common11084, (Room* ptRoom, DWORD zero)); +F7(STD, D2Common,10057,10057,10057,10332,11021,10511,10826, DWORD, D2GetLevelID, (Room* ptRoom)); +F7(STD, D2Common,10138,10138,10138,10623,10491,11043,10654, Room*, D2GetDropRoom, (Room* ptRoom, Position*, Position*, DWORD, DWORD, DWORD, DWORD)); +//F7(STD, D2Common,10149,10149,10149,00000,00000,00000,00000, Inventory*, D2GetInventory, (Unit* ptUnit)); +F7(STD, D2Common,10242,10242,10242,00000,00000,00000,00000, Unit*, D2Common10242, (Inventory* ptInventory, Unit* ptItem, DWORD bIsClient)); +F7(STD, D2Common,10246,10246,10246,10855,10813,10289,10133, Unit*, D2CanPutItemInInv, (Inventory* ptInventory, Unit* ptItem, DWORD p3, DWORD zero, Unit* ptUnit, const char* file, DWORD line)); +F7(STD, D2Common,10243,10243,10243,10461,10827,10936,10646, Unit*, D2InvRemoveItem, (Inventory* ptInventory, Unit* ptItem)); +F7(STD, D2Common,10249,10249,10249,10880,11068,10436,11107, DWORD, D2InvAddItem, (Inventory* ptInventory, Unit* ptItem, DWORD posX, DWORD posY, DWORD vValueC, DWORD bIsClient, BYTE page));//result : boolean 0=echec ; vValueC = 0 for Game.dll, 1 for Clientdll +F7(STD, D2Common,10250,10250,10250,00000,00000,00000,00000, DWORD, D2Common10250, (const char* file, DWORD line, Inventory* ptInventory, DWORD posX, DWORD posY, DWORD vValueC, DWORD bIsClient, BYTE page));// result : boolean 0=echec ; vValueC = 0 for Game.dll, 1 for Clientdll +//F7(STD, D2Common,10257,10257,10257,00000,00000,00000,00000, Unit*, D2GetItemFromBodyLoc, (Inventory* ptInventory, DWORD bodyloc)); +F7(STD, D2Common,10273,10273,10273,00000,00000,00000,00000, DWORD, D2Common10273, (Inventory* ptInventory, void* unknow)); +F7(STD, D2Common,10277,10277,10277,10402,10535,11151,10460, Unit*, D2InventoryGetFirstItem, (Inventory* ptInventory)); +F7(STD, D2Common,10304,10304,10304,10934,11140,10770,10464, Unit*, D2UnitGetNextItem, (Unit* ptItem)); +F7(STD, D2Common,10305,10305,10305,11095,10748,10852,11147, Unit*, D2GetRealItem, (Unit* ptUnit)); +//F7(STD, D2Common,10321,10321,10321,00000,00000,00000,00000, SkillData*, D2GetLeftSkill, (Unit* ptChar)); +//F7(STD, D2Common,10322,10322,10322,00000,00000,00000,00000, SkillData*, D2GetRightSkill, (Unit* ptChar)); +F7(STD, D2Common,10326,10326,00000,00000,00000,00000,00000, DWORD, D2GetPosX, (Unit* ptUnit));//NOT IN 1.10 +//F7(STD, D2Common,10328,10328,10328,00000,00000,00000,00000, void, D2SetPosX, (Unit* ptUnit, DWORD pos)); +F7(STD, D2Common,10329,10329,00000,00000,00000,00000,00000, DWORD, D2GetPosY, (Unit* ptUnit));//NOT IN 1.10 +//F7(STD, D2Common,10331,10331,10331,00000,00000,00000,00000, void, D2SetPosY, (Unit* ptUnit, DWORD pos)); +F7(STD, D2Common,10332,10332,10332,11080,10056,10543,10141, void, D2GetPosition, (Unit* ptUnit, Position* pos)); +F7(STD, D2Common,10339,10339,10339,10455,10864,10941,11060, DWORD, D2GetMaxGoldBank, (Unit* ptUnit)); +F7(STD, D2Common,10342,10342,10342,10172,10933,10366,10331, Room*, D2GetRoom, (Unit* ptUnit)); +//F7(STD, D2Common,10348,10348,10348,00000,00000,00000,00000, void, D2SetUnitMode, (Unit* ptUnit, DWORD mode)); +//F7(STD, D2Common,10394,10394,10394,00000,00000,00000,00000, ObjectsBIN*,D2GetObjectsBIN, (Unit* ptObject)); +F7(STD, D2Common,10420,10420,10420,10218,10079,11097,10356, PlayerData*,D2InitPlayerData, (Unit* ptChar)); +//F7(STD, D2Common,10421,10421,10421,10914,10329,00000,00000, DWORD, D2FreePlayerData, (DWORD game1C, Unit* ptChar)); +F7(STD, D2Common,10424,10424,10424,10562,10800,10860,10920, PlayerData*,D2GetPlayerData, (Unit* ptChar)); +F7(STD, D2Common,10431,10431,10431,00000,00000,00000,00000, DWORD, D2GetDefence, (Unit* ptChar)); +F7(STD, D2Common,10433,10433,10433,00000,00000,00000,00000, DWORD, D2GetChanceToBlock, (Unit* ptChar, DWORD isLODGame)); +F7(STD, D2Common,10439,10439,10439,10343,11131,10729,10049, DWORD, D2GetMaxGold, (Unit* ptUnit)); +F7(STD, D2Common,00000,00000,00000,10440,10572,10481,11090, DWORD, D2Common10572, (Unit* ptObject, DWORD value)); +//F7(STD, D2Common,10463,10463,10463,00000,00000,00000,00000, DWORD, D2SetStatWithNoTest, ( Stats* ptStats, DWORD statID, DWORD statValue, DWORD statIndex)); +//F7(STD, D2Common,10464,10464,10464,00000,00000,00000,00000, void, D2AddStat, (Stats* ptStats, DWORD statID, DWORD statValue, DWORD statIndex)); +//F7(STD, D2Common,10465,10465,10465,00000,00000,00000,00000, DWORD, D2SetStat, (Stats* ptStats, DWORD statID, DWORD statValue, DWORD statIndex)); +//F7(STD, D2Common,10466,10466,10466,00000,00000,00000,00000, int, D2GetStat, (Stats* ptStats, DWORD statID, DWORD statIndex)); +//F7(STD, D2Common,10470,10470,10470,00000,00000,00000,00000, Stats*, D2AllocNewStats, (DWORD nUnitId, DWORD flags, DWORD uk18, DWORD nUnitType, DWORD nItemNum)); +F7(STD, D2Common,00000,00000,00000,10471,11160,10866,10258, BYTE, D2GetObjectFlags, (Unit* ptObject)); +F7(STD, D2Common,00000,00000,00000,10572,11048,10150,10111, void, D2SetObjectFlags, (Unit* ptObject, BYTE flags)); +//F7(STD, D2Common,10471,10471,10471,00000,00000,00000,00000, DWORD, D2Common10471, (void*)); +//F7(STD, D2Common,10472,10472,10472,00000,00000,00000,00000, DWORD, D2Common10472, (void*)); +//F7(STD, D2Common,10475,10475,10475,00000,00000,00000,00000, void, D2UpdateDisabledStat, (Stats* ptCharStats, Stats* ptStats, DWORD one)); +//F7(STD, D2Common,10481,10481,10481,00000,00000,00000,00000, void*, D2Common10481, (Unit* ptUnit, DWORD flags)); +//F7(STD, D2Common,10484,10484,10484,00000,00000,00000,00000, Stats*, D2GetAffixStats, (Unit* ptItem, DWORD, DWORD)); +//F7(STD, D2Common,10485,10485,10485,00000,00000,00000,00000, void, D2FreeStats, (Stats* ptStats)); +F7(STD, D2Common,10487,10487,10487,00000,00000,00000,00000, DWORD, D2isInState, (Unit* ptChar, DWORD isLODGame)); +//F7(STD, D2Common,10517,10517,10517,00000,00000,00000,00000, void, D2SetPlayerStat, (Unit* ptChar, DWORD statID, int amount, DWORD index)); +F7(STD, D2Common,10518,10518,10518,10109,10627,10762,10551, void, D2AddPlayerStat, (Unit* ptChar, DWORD statID, int amount, DWORD index));//ONLY 1.11b +F7(STD, D2Common,10519,10519,10519,11092,10061,10658,10973, int, D2GetPlayerStat, (Unit* ptChar, DWORD statID, DWORD index));//ONLY 1.11b +//F7(STD, D2Common,10520,10520,10520,00000,00000,00000,00000, int, D2GetPlayerStat20, (Unit* ptChar, DWORD statID, DWORD index)); +F7(STD, D2Common,10521,10521,10521,10733,10550,10494,10587, int, D2GetPlayerBaseStat, (Unit* ptChar, DWORD statID, DWORD index));//ONLY 1.11b +//F7(STD, D2Common,10527,10527,10527,00000,00000,00000,00000, DWORD, D2Common10527, (Unit* ptUnit)); +F7(STD, D2Common,10539,10539,10539,00000,00000,00000,00000, DWORD, D2haveDefenceBonus, (Unit* ptChar)); +F7(STD, D2Common,10540,10540,10540,00000,00000,00000,00000, DWORD, D2haveFireResBonus, (Unit* ptChar)); +F7(STD, D2Common,10541,10541,10541,00000,00000,00000,00000, DWORD, D2haveColdResBonus, (Unit* ptChar)); +F7(STD, D2Common,10542,10542,10542,00000,00000,00000,00000, DWORD, D2haveLightResBonus, (Unit* ptChar)); +F7(STD, D2Common,10543,10543,10543,00000,00000,00000,00000, DWORD, D2havePoisonResBonus, (Unit* ptChar)); +F7(STD, D2Common,10546,10546,10546,00000,00000,00000,00000, DWORD, D2haveDefenceMalus, (Unit* ptChar)); +F7(STD, D2Common,10547,10547,10547,00000,00000,00000,00000, DWORD, D2haveFireResMalus, (Unit* ptChar)); +F7(STD, D2Common,10548,10548,10548,00000,00000,00000,00000, DWORD, D2haveColdResMalus, (Unit* ptChar)); +F7(STD, D2Common,10549,10549,10549,00000,00000,00000,00000, DWORD, D2haveLightResMalus, (Unit* ptChar)); +F7(STD, D2Common,10550,10550,10550,00000,00000,00000,00000, DWORD, D2havePoisonResMalus, (Unit* ptChar)); +//F7(STD, D2Common,10552,10552,10552,00000,00000,00000,00000, DWORD, D2Common10552, (Unit* ptUnit)); +//F7(STD, D2Common,10567,10567,10567,00000,00000,00000,00000, DWORD, D2CanBeBroken, (Unit* ptItem)); +//F7(STD, D2Common,10573,10573,10573,00000,00000,00000,00000, void, D2CopyStats, (Stats* ptDestStats, Stats* ptSrcStats)); +//F7(STD, D2Common,10574,10574,10574,00000,00000,00000,00000, void*, D2SetEnabledStat, (Unit* ptItem, DWORD statId, DWORD disabled)); +//F7(STD, D2Common,10575,10575,10575,00000,00000,00000,00000, void, D2FreeBinFiles, ()); +//F7(STD, D2Common,10576,10576,10576,00000,00000,00000,00000, void, D2LoadBinFiles, (DWORD zero1, DWORD zero2, bool)); +//F7(STD, D2Common,00000,00000,00000,10651,10651,00000,00000, DWORD, D2CheckQuestState, (void* ptQuest, DWORD index, DWORD value)); +F7(STD, D2Common,10578,10578,10578,10653,10496,10244,10849, void*, D2CompileTxtFile, (DWORD unused, const char* filename, BINField* ptFields, DWORD* ptRecordCount, DWORD recordLength)); +F7(STD, D2Common,10600,10600,10600,10573,10262,10887,10695, ItemsBIN*, D2GetItemsBIN, (DWORD itemID)); +//F7(STD, D2Common,10601,10601,10601,00000,00000,00000,00000, ItemsBIN*, D2GetByCodeItemStatsBIN, (DWORD code, DWORD* itemID)); +//F7(STD, D2Common,10604,10604,10604,00000,00000,00000,00000, AffixBIN*, D2GetAffixBIN, (int affixID)); +F7(STD, D2Common,10616,10616,10616,10500,10523,10774,10806, GemsBIN*, D2GetGemsBIN, (DWORD gemID)); +F7(STD, D2Common,11232,11232,11232,10746,10258,10913,10783, CubeMainBIN*,D2GetCubeMainBIN, (DWORD cubemainID)); +F7(STD, D2Common,11233,11233,11233,10639,11135,10390,10675, int, D2GetNbCubeMainBIN, ()); +//F7(STD, D2Common,10737,10737,10737,00000,00000,00000,00000, LevelsBIN*, D2GetLevelsBIN, (DWORD levelID)); +F7(STD, D2Common,10628,10628,10628,00000,00000,00000,00000, DWORD, D2GetNextLevelXP, (DWORD classID, DWORD level)); +F7(STD, D2Common,10629,10629,10629,00000,00000,00000,00000, DWORD, D2GetMaxLevel, (DWORD classID)); +F7(STD, D2Common,10655,10655,10655,10655,10309,10297,10218, DifficultyLevelsBIN*, D2GetDifficultyLevelsBIN, (DWORD difficultyLevel)); +//F7(STD, D2Common,10659,10659,10659,00000,00000,00000,00000, TreasureClassBIN*, D2GetTreasureClassBIN, (WORD id, DWORD uk)); +//F7(STD, D2Common,10668,10668,10668,10450,10953,00000,00000, SuperUniqueBIN*, D2GetSuperUniqueBIN, (WORD id)); +F7(STD, D2Common,10695,10695,10695,10927,10899,10276,10106, DWORD, D2GetItemQuality, (Unit* ptItem)); +F7(STD, D2Common,10707,10707,10707,10911,10303,10989,10202, DWORD, D2TestFlags, (Unit* ptUnit, DWORD flags, DWORD line, const char* file)); +//F7(STD, D2Common,10708,10708,10708,00000,00000,00000,00000, void, D2SetFlags, (Unit* ptUnit, DWORD flags, DWORD bitNewValue)); +//F7(STD, D2Common,10709,10709,10709,00000,00000,00000,00000, DWORD, D2GetFlags, (Unit* ptUnit)); +//F7(STD, D2Common,10711,10711,10711,00000,00000,00000,00000, void, D2ItemSetFlags, (Unit* ptItem, DWORD flags, DWORD toSet));// toSet = 0 for set to 0 the selected flags else set to 1 +F7(STD, D2Common,10717,10717,10717,10898,10100,10410,10086, DWORD, D2GetItemLevel, (Unit* ptItem)); +F7(STD, D2Common,10719,10719,10719,10820,10505,10370,10020, BYTE, D2ItemGetPage, (Unit* ptUnit)); +F7(STD, D2Common,10720,10720,10720,10485,10608,10223,10012, void, D2ItemSetPage, (Unit* ptItem, BYTE page)); +F7(STD, D2Common,10731,10731,10731,11017,10890,10231,10744, DWORD, D2CheckItemType, (Unit* ptItem, DWORD itype)); +F7(STD, D2Common,10732,10732,10732,10692,10685,10280,10620, int, D2GetUniqueID, (Unit* ptItem)); +F7(STD, D2Common,10734,10734,10734,00000,00000,00000,00000, void, D2SetAnim, (Unit* ptUnit, int anim)); +//F7(STD, D2Common,10749,10749,10749,00000,00000,00000,00000, void, D2GetWidthHeight, (Unit* ptItem, BYTE* Width, BYTE* Height); +//F7(STD, D2Common,10751,10751,10751,00000,00000,00000,00000, DWORD, D2GetItemType, (Unit* ptUnit)); +//F7(STD, D2Common,10757,10757,10757,00000,00000,00000,00000, DWORD, D2GetItemLevelReq, (Unit* ptChar, Unit* ptItem)); +F7(STD, D2Common,10619,10619,10619,10687,10877,10321,11032, int*, D2GetNbRunesBIN, ());//return the point on th number +F7(STD, D2Common,10620,10620,10620,10775,10296,10622,10006, RunesBIN*, D2GetRunesBIN, (int runesID)); +//F7(STD, D2Common,10792,10792,10792,00000,00000,00000,00000, DWORD, D2CanBeRare, (Unit* ptItem)); +//F7(STD, D2Common,10810,10810,10810,00000,00000,00000,00000, BYTE, D2CheckHasInv, (Unit* ptItem)); +//F7(STD, D2Common,10813,10813,10813,00000,00000,00000,00000, DWORD, D2GetStaffMods, (Unit* ptItem)); +//F7(STD, D2Common,10816,10816,10816,10816,11085,00000,00000, DWORD, D2GetNbSocket, (Unit* ptItem)); +//F7(STD, D2Common,10840,10840,10840,00000,00000,00000,00000, DWORD, D2Common10840, (Unit* ptItem, Unit* ptChar)); +//F7(STD, D2Common,10855,10855,10855,00000,00000,00000,00000, void, D2AddAffix, (DWORD, DWORD, Unit* ptItem, AffixBIN* ptAffix, DWORD, DWORD)); +//F7(STD, D2Common,10872,10872,10872,00000,00000,00000,00000, DWORD, D2WarpPlayer, (Path* ptPath, Unit* ptChar, Room* ptRoom, DWORD x, DWORD y)); +//F7(STD, D2Common,10875,10875,10875,00000,00000,00000,00000, WORD, D2GetItemVersion, (Unit* ptItem)); +F7(STD, D2Common,11163,11163,11163,10880,11068,10436,11107, DWORD, D2isEtheral, (Unit* ptItem));//ONLY UNTIL 1.10 +F7(STD, D2Common,10881,10881,10881,10956,11156,10218,10987, DWORD, D2SaveItem, (Unit* ptItem, saveBitField* data, DWORD startSize, DWORD p4, DWORD p5, DWORD p6)); +//F7(STD, D2Common,10916,10916,10916,00000,00000,00000,00000, void, DoNothing916, ()); +//F7(STD, D2Common,10940,10940,10940,10027,10105,10953,00000, void, D2Common10027, (Unit* ptChar, DWORD skillID)); +//F7(STD, D2Common,10950,10950,10950,00000,00000,00000,00000, SkillData*, D2GetSkillPointer, (Unit* ptChar, WORD SkillID)); +//F7(STD, D2Common,10952,10952,10952,10950,10256,10858,00000, SkillData*, D2IncSkillBaseLevel, (Unit* ptChar, DWORD skillID)); +F7(STD, D2Common,10953,10953,10953,10099,10255,10210,10302, void, D2SetSkillBaseLevel,(Unit* ptChar, DWORD skillID, DWORD slvl, DWORD bRemove, char*, DWORD)); +//F7(STD, D2Common,10963,10963,10963,00000,00000,00000,00000, DWORD, D2GetSkillID, (SkillData* ptSkill, const char* file, DWORD line)); +//F7(FAST, D2Common,10966,10966,10966,00000,00000,00000,00000, SkillsBIN*, D2GetSkillsBIN, (SkillData* ptSkill)); +F7(STD, D2Common,10968,10968,10968,10700,10109,10904,10306, DWORD, D2GetSkillLevel, (Unit* ptChar, SkillData* ptSkill, DWORD includingBonus)); +//F7(STD, D2Common,11023,11023,11023,00000,00000,00000,00000, DWORD, D2GetCriticalStrikeFromMasteries, (Unit* ptChar, Unit* ptItem, DWORD zero, DWORD two)); +//F7(STD, D2Common,11007,11007,11007,00000,00000,00000,00000, bool, D2TestQuestState, (void* ptQuest, DWORD QuestID, DWORD QuestState)); +//F7(STD, D2Common,11041,11041,11041,00000,00000,00000,00000, int, D2GetPlayerSkillID, (DWORD playerID, DWORD skillNumber)); +//F7(STD, D2Common,11042,11042,11042,00000,00000,00000,00000, int, D2GetNbSkillsPerPlayer, (DWORD playerID)); +//F7(STD, D2Common,11269,11269,11269,00000,00000,00000,00000, DWORD, D2GetAllIndexFromStat, (Stats* ptStats, DWORD statID, D2Stat* allIndex, DWORD maxIndex)); +//F7(STD, D2Common,11270,11270,11270,00000,00000,00000,00000, DWORD, D2GetAllIndexFromStatID, (Unit* ptItem, DWORD statID, D2Stat* allIndex, DWORD)); +F7(STD, D2Common,11276,11276,11276,10254,10074,10111,10435, DWORD, D2GetSkillCost, (Unit* ptChar, int skpoints, DWORD skillID, DWORD curSkillLevel));//not 10447 +A7(FAST, D2Common,00000,00000,82C80, 15D0, 1800, 1220, 12D0, CharStatsBIN*, D2GetCharStatsBIN, (DWORD charID)); +A7(FAST, D2Common,00000,00000,12410,5D7D0,1A100,116C0,1C020, DWORD, D2CompileCubeInput, (CubeInput* cubeinput, char* s, DWORD p1, DWORD p2)); +A7(FAST, D2Common,00000,00000,12910,5D210,19B40,11100,1BA60, DWORD, D2CompileCubeOutput, (CubeOutput* cubeoutput, char* s, DWORD p1, DWORD p2)); +A7(FAST, D2Common,00000,00000,2B1A0, 11F0, 1380, 1140, 1300, ItemTypesBIN*, D2GetItemTypesBIN, (DWORD itemTypesId)); +//A7(FAST, D2Common,00000,00000,62FD0,00000,00000,00000,00000, void, D2EncodeValueCheckMax, (saveBitField* data, DWORD value, DWORD bitSize)); +A7(FAST, D2Common,00000,00000,642B0, 13F0, 12F0, 1540, 17A0, ItemStatCostBIN*,D2GetItemStatCostBIN, (DWORD id)); +//A7(FAST, D2Common,00000,00000,764A0,00000,00000,00000,00000, void*, D2Common764A0, (Stats* ptStats, DWORD stat, ItemStatCostBIN* itemStatCost ,DWORD)); +//A7(STD, D2Common,00000,00000,76E30,00000,00000,00000,00000, void, D2PreUpdateDisabledStat, (Stats* ptStats)); +//A7(FAST, D2Common,00000,00000,76C10,00000,00000,00000,00000, void, D2ApplyStat,(Stats* ptCharStats, DWORD statId, DWORD value, Unit* ptItem)); +A7(FAST, D2Common,738A4,739B4,84268, 96E0, 98D0, 9900, 9900, void*, D2ReadFile,(DWORD unused, char* filename, DWORD* size, const char*, DWORD)); +//A7(FAST, D2Common,00000,00000, 94D0,00000,00000,00000,00000, void*, D2GetStringIDForTxtFile,(const char * string)); +A7(STD, D2Common,1F500,1F510,29FA0,71EB0,32AA0,7D2A0,59870, void, D2LoadSuperuniques,(DWORD mempool));//FASCALL UNTIL 1.10 + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//D2Client : 6FAA0000 +//E2F(D2Client,A9070, void*, D2LoadImage, (const char* filename, DWORD filetype));//1.11 +//E2F(D2Client,0000, void, D2FreeImage, (void* image));//6FAA1140 // NOT IN 1.11 +//E2F(D2Client,5E4E0, void, D2SendMsgToAll,(BYTE* data));//1.11 and 1.11b by ESI !! +////E2S(D2Client,15A80, int, D2GetAvgChanceMonsterWillHitYou, ());//6FAB5A80 +//E2S(D2Client,15A80, DWORD, D2GetLastMonsterIDFight, ());//6FAB5A80 +//E2S(D2Client,89320, void, D2PrintStatsPage, ());//ONLY 1.11b +////E2F(D2Client,45990, Unit*, D245990, (Inventory*,DWORD idItem);//6FAE5990 +//E2F(D2Client,21250, DWORD, D2PrintStat,(Unit* ptItem, Stats* ptStats, DWORD statID, DWORD statIndex, DWORD statValue, LPWSTR lpText));//statID=EAX, lpText=ESI 1.11b +//E2F(D2Client,62070, LPWSTR, D2SetColorPopup, (LPWSTR popupText, DWORD color));//1.11 and 1.11b BY EDI +////E2F(D2Client,869F0, Unit*, D2ClientGetObject, (DWORD itemNum, DWORD type));//6FB269F0 +//E2F(D2Client,54210, DWORD, D2PlaySound, (DWORD id, DWORD, DWORD, DWORD, DWORD));//1.11b +////E2F(D2Client,BB0F0, void, D2FillRect,(DWORD x, DWORD y, DWORD Width, DWORD Height, DWORD color, DWORD transTbl));//UNITL 1.10 +//E2F(D2Client,571C0, Unit*, D2GetCurrentNPC, ());//1.11b +//E2F(D2Client,5DE40, void, D2SendToServerXX,(DWORD size, BYTE * data));//ONLY 1.11b by EBX +//E2F(D2Client,65690, void, D2TogglePage, (DWORD a, DWORD b, DWORD c));//1.11b +//E2F(D2Client,710C0, void, D2ClickOnStashButton, (DWORD x, DWORD y));//STRICT 1.11/1.11b BY x=ESI y=EDI +//E2S(D2Client,621C0, void*, D2LoadBuySelBtn, ());//1.11b +//E2F(D2Client,5BA90, void, D2ReloadGambleScreen, ());//1.11b +//E2F(D2Client,1FEB0, void, D2OpenNPCMenu, (Unit* ptNPC));//1.11b by ESI + +A7(FAST, D2Client, 1000, 1000, 1000,75D00,A9070,BEF70,2B420, void*, D2LoadImage, (const char* filename, DWORD filetype)); +A7(FAST, D2Client, 1150, 1150, 1140,00000,00000,00000,00000, void, D2FreeImage, (void* image));//6FAA1140 +A7(FAST, D2Client, D640, D630, DB50,73620,5E4E0,79670,147A0, void, D2SendMsgToAll,(BYTE* data));//1.11 and 1.11b by ESI !! +//A7(STD, D2Client,00000,00000,15A80,00000,00000,00000,00000, int, D2GetAvgChanceMonsterWillHitYou, ());//6FAB5A80 +A7(STD, D2Client,00000,00000,15A80,00000,00000,00000,00000, DWORD, D2GetLastMonsterIDFight, ());//6FAB5A80 +A7(STD, D2Client,29800,297F0,2FD60,828A0,89320,6B280,BCEA0, void, D2PrintStatsPage, ()); +//A7(FAST, D2Client,00000,00000,45990,00000,00000,00000,00000, Unit*, D245990, (Inventory*,DWORD idItem);//6FAE5990 +A7(FAST, D2Client,4BB20,4BB20,521C0,B8CB0,21250,88EA0,54E10, DWORD, D2PrintStat,(Unit* ptItem, Stats* ptStats, DWORD statID, DWORD statIndex, DWORD statValue, LPWSTR lpText));//statID=EAX, lpText=ESI 1.11b +A7(FAST, D2Client,85A60,84DE0,80430,9EEB0,62070,8B7A0,BF5F0, LPWSTR, D2SetColorPopup, (LPWSTR popupText, DWORD color));//1.11 and 1.11b BY EDI +//A7(FAST, D2Client,00000,00000,869F0,00000,00000,00000,00000, Unit*, D2ClientGetObject, (DWORD itemNum, DWORD type));//6FB269F0 +A7(FAST, D2Client,B4360,B36E0,B5820,3ACC0,54210,31FA0,88A70, DWORD, D2PlaySound, (DWORD id, DWORD, DWORD, DWORD, DWORD)); +//A7(FAST, D2Client,B9970,B8CF0,BB0F0,00000,00000,00000,00000, void, D2FillRect,(DWORD x, DWORD y, DWORD Width, DWORD Height, DWORD color, DWORD transTbl)); +A7(FAST, D2Client,00000,00000,00000,00000,571C0,18450,46150, Unit*, D2GetCurrentNPC, ()); +A7(FAST, D2Client,00000,00000,00000,73260,5DE40,791A0,143E0, void, D2SendToServerXX,(DWORD size, BYTE * data));//by EBX +A7(FAST, D2Client,88940,87CC0,83260,A1F30,65690,8EF00,C2790, void, D2TogglePage, (DWORD a, DWORD b, DWORD c)); +A7(FAST, D2Client,00000,00000,00000,A6520,710C0,A6640,8CD00, void, D2ClickOnStashButton, (DWORD x, DWORD y));//BY x=ESI y=EDI +A7(STD, D2Client,897B0,88B30,84110,9E3B0,621C0,8B8F0,BEAF0, void*, D2LoadBuySelBtn, ()); +A7(FAST, D2Client,00000,00000,00000,8E480,5BA90,1CC00,4ABE0, void, D2ReloadGambleScreen, ()); +//A7(FAST, D2Client,00000,00000,00000,00000,1FEB0,5CDD0,00000, void, D2OpenNPCMenu, (Unit* ptNPC));//by ESI + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//D2Game : 6FC30000 +//D2F(D2Game,10007, void, D2SetNbPlayers, (DWORD nbPlayers));//1.11b +////E2F(D2Game,01DE0, void*, D2GetClientByClientID, (Game* ptGame, DWORD clientID));//6FC31DE0 +//E2F(D2Game,E8210, void, D2AddClient, (DWORD clientID));//BY EAX //1.11b +//E2S(D2Game,E49A0, Game*, D2GetGameByClientID, (DWORD clientID));//6FC394E0 //1.11b +//E2F(D2Game,E36D0, void, D2BroadcastFunction, (Game* ptGame, void* fct, void* param));//00DAB0E0//1.11b +//E2F(D2Game,A0D50, DWORD, D2SendPacket, (void* ptNetClient, LPVOID pData, DWORD size));//EAX=ptNetClient [ESP]=pData //1.11b +//E2F(D2Game,A3F20, void, D2SetSkillBaseLevelOnClient, (void* ptClient, Unit* ptChar, DWORD skillID, DWORD sLvl, DWORD bRemove));//ONLY 1.11 by EAX,ESI,EBX +////E2F(D2Game,0E6F0, void, D2UpdateClientItem, (NetClient* ptNetClient, Unit* ptChar, Unit* ptItem,DWORD,DWORD,DWORD));//6FC3E6F0 +////E2F(D2Game,10FB0, DWORD, D2UpdateInventory, (Game* ptGame, Unit* ptChar, void* ptNetClient, Inventory* pInventory));//6FC40FB0 +////E2F(D2Game,110E0, DWORD, D2UpdateItem, (Unit* ptChar, Unit* ptItem, Unit* ptSocketedItem, void* ptNetClient));//6FC410E0 +//E2S(D2Game,109F0, DWORD, D2LinkPortal, (Game* ptGame, Unit* ptObject, DWORD levelEndID, DWORD levelStartID));//ONLY 1.11b +//E2F(D2Game,43E60, DWORD, D2VerifIfNotCarry1, (Unit* ptItem, ItemsBIN* itemsData, Unit* ptFirstItem));// BY EBX=itemsData EAX=ptFirstItem [ESP]=ptItem//1.11b +////E2F(D2Game,1ED80, Unit*, D2CreateItem, (Game* ptGame, ItemGenerationData* itemGenerationData, DWORD));//6FC4ED80 +//E2F(D2Game,01DF0, Room*, D2TestPositionInRoom, (Room* ptRoom, DWORD x, DWORD y));//1.11b +////E2F(D2Game,22410, void, D2AddStaffModAffixes, (Unit* ptItem, ItemGenerationData* itemParam));//6FC52410 +////E2F(D2Game,22C00, WORD, D2GetNewAffix, (Unit* ptItem, DWORD testIfSpawnable, DWORD mustSelectOne, DWORD addToItem, DWORD isPrefix, int affixID, WORD autoAffixGroupID));//6FC52C00 +////E2F(D2Game,23610, WORD, D2GetRareAffixName, (Unit* ptItem, DWORD wantPrefix));//6FC53610 +////E2F(D2Game,3AD10, DWORD, D2GetSuperUniqueMonsterID, (Game* ptGame, Unit* ptMonster));//6FC6AD10 +//E2F(D2Game,EC7E0, DWORD, D2SpawnMonster, (Game* ptGame, Room* ptRoom, DWORD zero1, DWORD x, DWORD y, DWORD minusOne, DWORD superuniqueID, DWORD zero2));//1.11b (wrong param) +//E2S(D2Game,235C0, void, D2Game235C0, (Game* ptGame, Room* ptRoom));//1.11/1.11b +//E2F(D2Game,4C7B0, Unit*, D2GetSkillItem, (Unit* ptChar));//6FC7C7B0 +////E2F(D2Game,5A500, DWORD, D2SavePlayer, (Game* ptGame, Unit* ptChar, char* playername, DWORD zero));//6FC8A500 +//E2F(D2Game,25D50, DWORD, D2LoadInventory, (Game* ptGame, Unit* pChar, saveBitField* pdata, DWORD p2, DWORD maxSize, DWORD p4, DWORD *ptNbBytesRead));//6FC8B8A0//1.11b +//E2F(D2Game,BEF80, Unit*, D2GameGetObject, (Game* ptGame, DWORD type, DWORD itemNum));//6FCBBB00//1.11b +//E2F(D2Game,F1C50, Unit*, D2GetOwnerMonster, (Unit* ptMonster));//ONLY 1.11b +////E2F(D2Game,E08D0, void, D2UpdateSkillDataAfterUnassignment, (Game* ptGame, Unit* ptChar, DWORD skillID));//6FD108D0 +//E2F(D2Game,C09E0, Unit*, D2CreateUnit, (DWORD type, DWORD id, DWORD x, DWORD y, Game* ptGame, Room* ptRoom, DWORD uk1, DWORD uk2, DWORD uk3));//1.11b +//E2F(D2Game,34920, void, D2OpenPandPortal, (Game* ptGame, Unit* ptChar));//1.11b +//E2F(D2Game,34910, void, D2OpenPandFinalPortal, (Game* ptGame, Unit* ptChar));//1.11b +//E2F(D2Game,85AA0, void, D2MephIA, (Game* ptGame, Unit* ptMonster, DWORD*));//1.11b +//E2F(D2Game,D7BD0, void, D2DiabloIA, (Game* ptGame, Unit* ptMonster, DWORD*));//1.11b +//E2F(D2Game,2BC80, void, D2BaalIA, (Game* ptGame, Unit* ptMonster, DWORD*));//1.11b +//E2F(D2Game,D2D70, void, D2UberMephIA, (Game* ptGame, Unit* ptMonster, DWORD*));//1.11b +//E2F(D2Game,7FE60, void, D2UberDiabloIA, (Game* ptGame, Unit* ptMonster, DWORD*));//1.11b +//E2F(D2Game,2A300, void, D2UberBaalIA, (Game* ptGame, Unit* ptMonster, DWORD*));//1.11b +////E2F(D2Game,92420, void, D2ReloadGambleScreenGame, (Unit* ptNPC, Game* ptGame, Unit* ptChar, DWORD, DWORD one));//1.11b +//E2S(D2Game,E66D0, void, D2SaveGame, (Game* ptGame));//1.11b + + +F7(FAST, D2Game,10059,10059,10059,10039,10007,10037,10049, void, D2SetNbPlayers, (DWORD nbPlayers)); +//A7(FAST, D2Game,00000,00000,01DE0,00000,00000,00000,00000, void*, D2GetClientByClientID, (Game* ptGame, DWORD clientID));//6FC31DE0 +A7(FAST, D2Game,00000,00000, 6C60,E3DA0,E8210,EB060,49930, void, D2AddClient, (DWORD clientID));//BY EAX +A7(STD, D2Game,00000,00000, 94E0,E0520,E49A0,A6360,2AAE0, Game*, D2GetGameByClientID, (DWORD clientID));//6FC394E0 +A7(FAST, D2Game,00000,00000, B0E0,DF250,E36D0,A5080,29820, void, D2BroadcastFunction, (Game* ptGame, void* fct, void* param));//00DAB0E0 +A7(FAST, D2Game, C380, C650, C710,41420,A0D50,7D220,8A3E0, DWORD, D2SendPacket, (void* ptNetClient, LPVOID pData, DWORD size));//EAX=ptNetClient [ESP]=pData +A7(FAST, D2Game, D650, D920, DB50,44D00,A3F20,802E0,8D5F0, void, D2SetSkillBaseLevelOnClient, (void* ptClient, Unit* ptChar, DWORD skillID, DWORD sLvl, DWORD bRemove));//by EAX,ESI,EBX +//A7(FAST, D2Game,00000,00000,0E6F0,00000,00000,00000,00000, void, D2UpdateClientItem, (NetClient* ptNetClient, Unit* ptChar, Unit* ptItem,DWORD,DWORD,DWORD));//6FC3E6F0 +//A7(FAST, D2Game,00000,00000,10FB0,00000,00000,00000,00000, DWORD, D2UpdateInventory, (Game* ptGame, Unit* ptChar, void* ptNetClient, Inventory* pInventory));//6FC40FB0 +//A7(FAST, D2Game,00000,00000,110E0,00000,00000,00000,00000, DWORD, D2UpdateItem, (Unit* ptChar, Unit* ptItem, Unit* ptSocketedItem, void* ptNetClient));//6FC410E0 +A7(STD, D2Game,00000,00000,00000,27230,109F0,AE930,A22E0, DWORD, D2LinkPortal, (Game* ptGame, Unit* ptObject, DWORD levelEndID, DWORD levelStartID)); +A7(FAST, D2Game,00000,00000,128F0,38D90,43E60,11FF0,D2070, DWORD, D2VerifIfNotCarry1, (Unit* ptItem, ItemsBIN* itemsData, Unit* ptFirstItem));// BY EBX=itemsData EAX=ptFirstItem [ESP]=ptItem +//A7(FAST, D2Game,00000,00000,1ED80,00000,00000,00000,00000, Unit*, D2CreateItem, (Game* ptGame, ItemGenerationData* itemGenerationData, DWORD));//6FC4ED80 +A7(FAST, D2Game,00000,00000,22070, 1090, 1DF0, 11F0, 1280, Room*, D2TestPositionInRoom, (Room* ptRoom, DWORD x, DWORD y)); +//A7(FAST, D2Game,00000,00000,22410,00000,00000,00000,00000, void, D2AddStaffModAffixes, (Unit* ptItem, ItemGenerationData* itemParam));//6FC52410 +//A7(FAST, D2Game,00000,00000,22C00,00000,00000,00000,00000, WORD, D2GetNewAffix, (Unit* ptItem, DWORD testIfSpawnable, DWORD mustSelectOne, DWORD addToItem, DWORD isPrefix, int affixID, WORD autoAffixGroupID));//6FC52C00 +//A7(FAST, D2Game,00000,00000,23610,00000,00000,00000,00000, WORD, D2GetRareAffixName, (Unit* ptItem, DWORD wantPrefix));//6FC53610 +//A7(FAST, D2Game,00000,00000,3AD10,00000,00000,00000,00000, DWORD, D2GetSuperUniqueMonsterID, (Game* ptGame, Unit* ptMonster));//6FC6AD10 +A7(FAST, D2Game,00000,00000,3F220,4ABE0,EC7E0,40B90,24950, DWORD, D2SpawnMonster, (Game* ptGame, Room* ptRoom, DWORD zero1, DWORD x, DWORD y, DWORD minusOne, DWORD superuniqueID, DWORD zero2));//wrong param +A7(STD, D2Game,00000,00000,00000,D6D10,235C0, D410,200E0, void, D2Game235C0, (Game* ptGame, Room* ptRoom)); +//A7(FAST, D2Game,00000,00000,4C7B0,00000,00000,00000,00000, Unit*, D2GetSkillItem, (Unit* ptChar));//6FC7C7B0 +//A7(FAST, D2Game,00000,00000,5A500,00000,00000,00000,00000, DWORD, D2SavePlayer, (Game* ptGame, Unit* ptChar, char* playername, DWORD zero));//6FC8A500 +A7(FAST, D2Game,4F100,4F500,5B8A0,B9D70,25D50,44950,54810, DWORD, D2LoadInventory, (Game* ptGame, Unit* pChar, saveBitField* pdata, DWORD p2, DWORD maxSize, DWORD p4, DWORD *ptNbBytesRead));//6FC8B8A0 +A7(FAST, D2Game,7BAE0,7BFD0,8BB00,97620,BEF80,93650,E03A0, Unit*, D2GameGetObject, (Game* ptGame, DWORD type, DWORD itemNum));//6FCBBB00 +//A7(FAST, D2Game,00000,00000,9F320,501C0,F1C50,F1A50,F3220, Unit*, D2GetOwnerMonster, (Unit* ptMonster)); +//A7(FAST, D2Game,00000,00000,E08D0,00000,00000,00000,00000, void, D2UpdateSkillDataAfterUnassignment, (Game* ptGame, Unit* ptChar, DWORD skillID));//6FD108D0 +A7(FAST, D2Game,00000,00000,00000,99760,C09E0,94E70,E1D90, Unit*, D2CreateUnit, (DWORD type, DWORD id, DWORD x, DWORD y, Game* ptGame, Room* ptRoom, DWORD uk1, DWORD uk2, DWORD uk3)); +A7(FAST, D2Game,00000,00000,00000,9B480,34920,D1AA0,70180, void, D2OpenPandPortal, (Game* ptGame, Unit* ptChar)); +A7(FAST, D2Game,00000,00000,00000,9B470,34910,D1A90,70170, void, D2OpenPandFinalPortal, (Game* ptGame, Unit* ptChar)); +A7(FAST, D2Game,00000,00000,00000,84730,85AA0,DBE90,A9610, void, D2MephIA, (Game* ptGame, Unit* ptMonster, DWORD*)); +A7(FAST, D2Game,00000,00000,00000,75980,D7BD0,CD0F0,85B60, void, D2DiabloIA, (Game* ptGame, Unit* ptMonster, DWORD*)); +A7(FAST, D2Game,00000,00000,00000,EAB20,2BC80,B3B90,B8610, void, D2BaalIA, (Game* ptGame, Unit* ptMonster, DWORD*)); +A7(FAST, D2Game,00000,00000,00000,70320,D2D70,C2A90,7B4E0, void, D2UberMephIA, (Game* ptGame, Unit* ptMonster, DWORD*)); +A7(FAST, D2Game,00000,00000,00000,7F200,7FE60,D6250,A39D0, void, D2UberDiabloIA, (Game* ptGame, Unit* ptMonster, DWORD*)); +A7(FAST, D2Game,00000,00000,00000,E92B0,2A300,B2210,B6C80, void, D2UberBaalIA, (Game* ptGame, Unit* ptMonster, DWORD*)); +//A7(FAST, D2Game,00000,00000,00000,00000,92420,00000,00000, void, D2ReloadGambleScreenGame, (Unit* ptNPC, Game* ptGame, Unit* ptChar, DWORD, DWORD one)); +A7(STD, D2Game,00000,00000, 89C0,E2390,E66D0,A8090,2C830, void, D2SaveGame, (Game* ptGame) ); + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//D2Net : 6FC00000 +//D2S(D2Net,10020, DWORD, D2SendToServer, (DWORD size, DWORD one, void* data));//ONLY 1.11b +//D2S(D2Net,10018, DWORD, D2SendToClient, (DWORD zero, DWORD clientID, void* data, DWORD size));//ONLY 1.11b + +F7(STD, D2Net, 10005,10005,10005,10035,10020,10036,10024, DWORD, D2SendToServer, (DWORD size, DWORD one, void* data));//(DWORD zero, void* data, DWORD size) for 1.10 and before +F7(STD, D2Net, 10006,10006,10006,10018,10018,10015,10002, DWORD, D2SendToClient, (DWORD zero, DWORD clientID, void* data, DWORD size)); + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Fog : 6FF50000 +//D2S(Fog,10023, void, D2FogAssertOld, (const char* ptMessage, DWORD eip, DWORD line));//ONLY 1.11/1.11b (STDCALL until 1.10) +//D2F(Fog,10024, void, D2FogAssert, (const char* ptMessage, DWORD eip, DWORD line));//ONLY 1.11/1.11b (STDCALL until 1.10) +//D2F(Fog,10042, void*, D2FogMemAlloc, (DWORD dwMemSize, LPCSTR lpszErrFile, DWORD ErrLine, DWORD Zero)); +//D2F(Fog,10043, void*, D2FogMemDeAlloc, (void* ptMemLoc, LPCSTR lpszErrFile, DWORD ErrLine, DWORD Zero));//1.11b +//D2F(Fog,10045, void*, D2AllocMem, (DWORD,DWORD dwMemSize, LPCSTR lpszErrFile, DWORD ErrLine, DWORD Zero));//1.11b +//D2F(Fog,10046, void*, D2FreeMem, (DWORD,void* ptMemLoc, LPCSTR lpszErrFile, DWORD ErrLine, DWORD Zero));//1.11b +//D2F(Fog,10102, DWORD, D2MPQOpenFile, (char* ptPath, void** buf));//1.11 +//D2F(Fog,10103, DWORD, D2MPQCloseFile, (void* mpqfile));//1.11 +//D2F(Fog,10104, DWORD, D2MPQReadFile, (void* mpqfile, BYTE* buffer, DWORD nbToRead, DWORD* nbRead,DWORD,DWORD,DWORD));//1.11 +//D2F(Fog,10105, DWORD, D2MPQGetSizeFile, (void* mpqfile, DWORD* toReset));//1.11 +//D2F(Fog,10115, void, D2FogGetSavePath, (char* ptPath, DWORD maxsize));//1.11b +//D2F(Fog,10116, void, D2FogGetInstallPath, (char* ptPath, DWORD maxsize));//1.11b +////D2S(Fog,10126, DWORD, D2InitBitField, (saveBitField* data, BYTE* buf, DWORD bufsize));//6FF536C0 +////D2S(Fog,10127, DWORD, D2GetBitFieldSize, (saveBitField* data));//6FF536C0 +////D2S(Fog,10128, void, D2EncodeValue, (saveBitField* data, DWORD value, DWORD bitSize));//6FF536C0 +////D2S(Fog,10130, DWORD, D2DecodeValue, (saveBitField* data,DWORD readingSize));//6FF53840 +//D2S(Fog,10212, void, D2Fog10212, (DWORD unknow));//1.11b +////D2S(Fog,10217, int, D2GetIDFromLookUpTable, (void* table, char* string, bool));//6FF53840 +//D2S(Fog,10265, int, D2GetInstructionPointer, ());//ONLY 1.11/1.11b NOT 1.10 + +F7(STD, Fog, 10023,10023,10023,00000,00000,00000,00000, void, D2FogAssertOld, (const char* ptMessage, DWORD eip, DWORD line));//(STDCALL until 1.10) +F7(FAST, Fog, 00000,00000,00000,10024,10024,10024,10024, void, D2FogAssert, (const char* ptMessage, DWORD eip, DWORD line)); +F7(FAST, Fog, 10042,10042,10042,10042,10042,10042,10042, void*, D2FogMemAlloc, (DWORD dwMemSize, LPCSTR lpszErrFile, DWORD ErrLine, DWORD Zero)); +F7(FAST, Fog, 10043,10043,10043,10043,10043,10043,10043, void*, D2FogMemDeAlloc, (void* ptMemLoc, LPCSTR lpszErrFile, DWORD ErrLine, DWORD Zero)); +F7(FAST, Fog, 10045,10045,10045,10045,10045,10045,10045, void*, D2AllocMem, (DWORD,DWORD dwMemSize, LPCSTR lpszErrFile, DWORD ErrLine, DWORD Zero)); +F7(FAST, Fog, 10046,10046,10046,10046,10046,10046,10046, void*, D2FreeMem, (DWORD,void* ptMemLoc, LPCSTR lpszErrFile, DWORD ErrLine, DWORD Zero)); +F7(FAST, Fog, 10102,10102,10102,10102,10102,10102,10102, DWORD, D2MPQOpenFile, (char* ptPath, void** buf)); +F7(FAST, Fog, 10103,10103,10103,10103,10103,10103,10103, DWORD, D2MPQCloseFile, (void* mpqfile)); +F7(FAST, Fog, 10104,10104,10104,10104,10104,10104,10104, DWORD, D2MPQReadFile, (void* mpqfile, BYTE* buffer, DWORD nbToRead, DWORD* nbRead,DWORD,DWORD,DWORD)); +F7(FAST, Fog, 10105,10105,10105,10105,10105,10105,10105, DWORD, D2MPQGetSizeFile, (void* mpqfile, DWORD* toReset)); +F7(FAST, Fog, 10115,10115,10115,10115,10115,10115,10115, void, D2FogGetSavePath, (char* ptPath, DWORD maxsize)); +F7(FAST, Fog, 10116,10116,10116,10116,10116,10116,10116, void, D2FogGetInstallPath, (char* ptPath, DWORD maxsize)); +//F7(STD, Fog, 10126,10126,10126,10126,10126,10126,10126, DWORD, D2InitBitField, (saveBitField* data, BYTE* buf, DWORD bufsize));//6FF536C0 +//F7(STD, Fog, 10127,10127,10127,10127,10127,10127,10127, DWORD, D2GetBitFieldSize, (saveBitField* data));//6FF536C0 +//F7(STD, Fog, 10128,10128,10128,10128,10128,10128,10128, void, D2EncodeValue, (saveBitField* data, DWORD value, DWORD bitSize));//6FF536C0 +//F7(STD, Fog, 10130,10130,10130,10130,10130,10130,10130, DWORD, D2DecodeValue, (saveBitField* data,DWORD readingSize));//6FF53840 +F7(STD, Fog, 10212,10212,10212,10212,10212,10212,10212, void, D2Fog10212, (DWORD unknow)); +//F7(STD, Fog, 10217,10217,10217,10217,10217,10217,10217, int, D2GetIDFromLookUpTable, (void* table, char* string, bool));//6FF53840 +F7(STD, Fog, 00000,00000,00000,10265,10265,10265,10265, int, D2GetInstructionPointer, ()); +//Fog10213 getIndexFromLookupTable (&table,code,bool) + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//D2Lang : 6FC10000 +////D2F(D2Lang,10003, LPWSTR, D2GetStringFromString, (const char* ptString));//6FC13BC0 +//D2F(D2Lang,10000, LPWSTR, D2GetStringFromIndex, (WORD dwIndexNum));//ONLY 1.11b +////D2S(D2Lang,10006, void, D2GetStringLang, (LPSTR ptLang, DWORD Zero));//6FC13FB0 +//D2S(D2Lang,10013, DWORD, D2GetLang, ());//ONLY 1.11b +//D2S(D2Lang,10010, DWORD, D2PrintBigNumber, (LPWSTR ptBuf , DWORD number, DWORD size));//6FC14210 +////D2S(D2Lang,10013, DWORD, D2GetStringAndIndexFromString, (const char* ptString , LPWSTR result));//6FC13960 +////E2F(D2Lang,29B0, DWORD, D2UnicodeWidth, (DWORD MemLoc, WORD Size));//6FC129B0 +////E2F(D2Lang,2E60, LPWSTR, D2GetStrFromIndex , (void* ptFile, void* ptMemLoc, DWORD dwIndexNum));//6FC12E60 +////E2F(D2Lang,3640, TblHeader*, D2LoadTblFile, (LPCSTR lpszFileName));//6FC13640 +////E2F(D2Lang,3A90, WORD, D2GetStrAndIndexFromString, (void* ptFile, void* ptMemLoc, LPSTR String, LPWSTR RetString));//6FC13A90 +////E2F(D2Lang,2CD0, DWORD, D2unicodenwidth, (char* ptChar, DWORD size));//6FC12CD0_unicodenwidth +////E2S(D2Lang,1670, DWORD, D2swprintf, (DWORD bufSize, LPWSTR buf, LPWSTR string, ...));//6FC11670_sprintf + +//F7(FAST, D2Lang, 10003,10003,10003,00000,00000,00000,00000, LPWSTR, D2GetStringFromString, (const char* ptString));//6FC13BC0 +F7(FAST, D2Lang, 10004,10004,10004,10005,10000,10005,10003, LPWSTR, D2GetStringFromIndex, (WORD dwIndexNum)); +//F7(STD, D2Lang, 10006,10006,10006,00000,00000,00000,00000, void, D2GetStringLang, (LPSTR ptLang, DWORD Zero));//6FC13FB0 +F7(STD, D2Lang, 10007,10007,10007,10009,10013,10002,10009, DWORD, D2GetLang, ()); +F7(STD, D2Lang, 10010,10010,10010,00000,00000,00000,00000, DWORD, D2PrintBigNumber, (LPWSTR ptBuf , DWORD number, DWORD size));//6FC14210 +//F7(STD, D2Lang, 10013,10013,10013,00000,00000,00000,00000, DWORD, D2GetStringAndIndexFromString, (const char* ptString , LPWSTR result));//6FC13960 +//A7(FAST, D2Lang, 00000,00000,029B0,00000,00000,00000,00000, DWORD, D2UnicodeWidth, (DWORD MemLoc, WORD Size));//6FC129B0 +//A7(FAST, D2Lang, 00000,00000,02E60,00000,00000,00000,00000, LPWSTR, D2GetStrFromIndex , (void* ptFile, void* ptMemLoc, DWORD dwIndexNum));//6FC12E60 +//A7(FAST, D2Lang, 00000,00000,03640,00000,00000,00000,00000, TblHeader*, D2LoadTblFile, (LPCSTR lpszFileName));//6FC13640 +//A7(FAST, D2Lang, 00000,00000,03A90,00000,00000,00000,00000, WORD, D2GetStrAndIndexFromString, (void* ptFile, void* ptMemLoc, LPSTR String, LPWSTR RetString));//6FC13A90 +//A7(FAST, D2Lang, 00000,00000,02CD0,00000,00000,00000,00000, DWORD, D2unicodenwidth, (char* ptChar, DWORD size));//6FC12CD0_unicodenwidth +//A7(STD, D2Lang, 00000,00000,01670,00000,00000,00000,00000, DWORD, D2swprintf, (DWORD bufSize, LPWSTR buf, LPWSTR string, ...));//6FC11670_sprintf + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Storm : 6FFB0000 +////D2S(Storm,253, void, D2StormMPQCloseFile, (void* mpqfile)); +//D2S(Storm,268, DWORD, D2StormMPQOpenFile, (DWORD zero, LPCSTR fileName, DWORD dwSearchScope, void** buffer));//1.11b +//D2S(Storm,503, void, D2Storm503, (DWORD, DWORD, DWORD)); //+1.11 +//D2S(Storm,511, void, D2FreeWinMessage, (sWinMessage* msg));//1.11/1.11b + +//F7(STD, Storm, 253, 253, 253, 253, 253, 253, 000, void, D2StormMPQCloseFile, (void* mpqfile)); +F7(STD, Storm, 268, 268, 268, 268, 268, 268, 268, DWORD, D2StormMPQOpenFile, (DWORD zero, LPCSTR fileName, DWORD dwSearchScope, void** buffer)) +F7(STD, Storm, 503, 503, 503, 503, 503, 503, 503, void, D2Storm503, (DWORD, DWORD, DWORD)); +F7(STD, Storm, 511, 511, 511, 511, 511, 511, 511, void, D2FreeWinMessage, (sWinMessage* msg)); + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//D2gfx : 6FA70000 +//D2S(D2gfx,10063, DWORD, D2GetResolution,() );//ONLY 1.11b +////D2S(D2gfx,10023, DWORD, D2CreateMainWindow,(DWORD,DWORD) ); +////D2S(D2gfx,10026, DWORD, D2ShowWindow,() ); +////D2S(D2gfx,10027, HWND, D2GetWindowHandle,() );//6FA749C0 +//D2S(D2gfx,10000, void, D2FillArea,(DWORD x1, DWORD y1, DWORD x2, DWORD y2, DWORD color, DWORD transTbl));//ONLY 1.11b +//D2S(D2gfx,10044, void, D2PrintImage,(sDrawImageInfo* data, DWORD x, DWORD y, DWORD p4, DWORD p5, DWORD p6) );//ONLY 1.11b + +F7(STD, D2gfx, 10005,10005,10005,10000,10063,10043,10031, DWORD, D2GetResolution,() ); +//F7,STD, D2gfx, 10023,10023,10023,00000,00000,00000,00000, DWORD, D2CreateMainWindow,(DWORD,DWORD) ); +//F7(STD, D2gfx, 10026,10026,10026,00000,00000,00000,00000, DWORD, D2ShowWindow,() ); +//F7,STD, D2gfx, 10027,10027,10027,00000,00000,00000,00000, HWND, D2GetWindowHandle,() );//6FA749C0 +F7(STD, D2gfx, 10055,10055,10055,10028,10000,10062,10014, void, D2FillArea,(DWORD x1, DWORD y1, DWORD x2, DWORD y2, DWORD color, DWORD transTbl)); +F7(STD, D2gfx, 10072,10072,10072,10047,10044,10024,10041, void, D2PrintImage,(sDrawImageInfo* data, DWORD x, DWORD y, DWORD p4, DWORD p5, DWORD p6) ); + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//D2Win : 6F8E0000 (1.10 and 1.11) +//D2F(D2Win,10075, void, D2PrintLineOnTextBox,(void* screen, char* s, DWORD color) );//ONLY 1.11b +//D2F(D2Win,10064, void, D2PrintString,(LPWSTR s, DWORD x, DWORD y, DWORD color, DWORD bfalse) );//ONLY 1.11b +//D2F(D2Win,10128, DWORD, D2GetPixelLen,(LPWSTR s) );//ONLY 1.11b +//D2F(D2Win,10170, DWORD, D2SetFont,(DWORD fontID) );//ONLY 1.11b +//D2F(D2Win,10039, void, D2PrintPopup,(LPWSTR s, DWORD x, DWORD y, DWORD color, DWORD center) );//ONLY 1.11b +//D2F(D2Win,10131, void, D2GetPixelRect,(LPWSTR s, DWORD* x, DWORD* y) );//6F8AB260 +//D2F(D2Win,10132, DWORD, D2PrintTextPopup,(LPWSTR s, DWORD x, DWORD y, DWORD uk, DWORD type, DWORD color) );//6F8AB080 +//D2S(D2Win,10113, void*, D2CreateTextBox,(DWORD* data) );//ONLY 1.11b + +F7(FAST, D2Win, 10046,10046,10046,10061,10075,10015,10022, void, D2PrintLineOnTextBox,(void* screen, char* s, DWORD color) ); +F7(FAST, D2Win, 10117,10117,10117,10020,10064,10001,10150, void, D2PrintString,(LPWSTR s, DWORD x, DWORD y, DWORD color, DWORD bfalse) ); +F7(FAST, D2Win, 10121,10121,10121,10034,10128,10132,10028, DWORD, D2GetPixelLen,(LPWSTR s) ); +F7(FAST, D2Win, 10127,10127,10127,10141,10170,10010,10184, DWORD, D2SetFont,(DWORD fontID) ); +F7(FAST, D2Win, 10129,10129,10129,10118,10039,10031,10085, void, D2PrintPopup,(LPWSTR s, DWORD x, DWORD y, DWORD color, DWORD center) ); +F7(FAST, D2Win, 10131,10131,10131,00000,00000,00000,00000, void, D2GetPixelRect,(LPWSTR s, DWORD* x, DWORD* y) );//6F8AB260 +F7(FAST, D2Win, 10132,10132,10132,00000,00000,00000,00000, DWORD, D2PrintTextPopup,(LPWSTR s, DWORD x, DWORD y, DWORD uk, DWORD type, DWORD color) );//6F8AB080 +F7(STD, D2Win, 10017,10017,10017,10147,10113,10098,10098, void*, D2CreateTextBox,(DWORD* data) ); + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//D2CMP : ????0000 +//D2S(D2CMP,10014, DWORD, D2CMP10014, (void* image) );//ONLY 1.11 + +F7(STD, D2CMP, 10032,10032,10032,10021,10014,10106,10065, DWORD, D2CMP10014, (void* image) ); + + +//ONLY UNTIL 1.10 : +A7(FAST, D2Client, BA00, B9F0, C080,00000,00000,00000,00000, DWORD, D2isLODGame, ());//6FAAC080 +A7(FAST, D2Client, 00000,00000, C090,00000,00000,00000,00000, BYTE, D2GetDifficultyLevel, ());//6FAAC090 1.09 should be BA10 (b) BA00 (d) +A7(STD, D2Client, B6670,B59F0,B7BC0,00000,00000,00000,00000, DWORD, D2GetMouseX, ());//6FB57BC0 +A7(STD, D2Client, B6680,B5A00,B7BD0,00000,00000,00000,00000, DWORD, D2GetMouseY, ());//6FB57BD0 +A7(STD, D2Client, 8DC40,8CFC0,883D0,00000,00000,00000,00000, Unit*, D2GetClientPlayer, ());//6FB283D0 +A7(FAST, D2Client, B920, B910, BF60,00000,00000,00000,00000, void, D2CleanStatMouseUp, ());//6FAABF60 +A7(FAST, D2Client, D210, D200, D990,00000,00000,00000,00000, void, D2SendToServer3, (BYTE type, WORD p));//6FAAD990 +//A7(FAST, D2Client, 00000,00000, DA20,00000,00000,00000,00000, void, D2SendToServer5, (BYTE type, DWORD p));//6FAADA20 +//A7(FAST, D2Client, 00000,00000, D9E0,00000,00000,00000,00000, void, D2SendToServer7, (BYTE type, WORD p1, WORD p2, WORD p3));//6FAAD9E0 +//A7(FAST, D2Client, 00000,00000, DA40,00000,00000,00000,00000, void, D2SendToServer9, (BYTE type, DWORD p1, DWORD p2));//6FAADA40 +//A7(FAST, D2Client, 00000,00000, DA70,00000,00000,00000,00000, void, D2SendToServer13,(BYTE type, DWORD p1, DWORD p2, DWORD p3));//6FAADA70 +A7(FAST, D2Game, 7C2C0,7C7B0,8C2E0,00000,00000,00000,00000, NetClient*, D2GetClient, (Unit* ptUnit, char* lpszErrFile, DWORD ErrLine));//6FCBC2E0 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////// VARIABLES //////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//Data D2Client : 6FAA0000 +////E2C(D2Common,96A20, DataTables*,SgptDataTables); //03836A20 - 037A0000 //01EE6A20 +//E2C(D2Client,F4FC8, DWORD, ResolutionY);//0x258 = 600 //1.11b +//E2C(D2Client,F4FC4, DWORD, ResolutionX);//0x320 = 800 //1.11b +//E2C(D2Client,11BEFC,DWORD, NegWindowStartY);//0xFFFFFFC4 = -60 //1.11b +//E2C(D2Client,11BEF8,DWORD, WindowStartX);//0x50 = 80 //1.11b +////E2C(D2Launch,2CD5C, DWORD, GameTypeMode);//0x50 = 80 //6FA3CD5C-6FA10000 +//E2C(D2Game, 111718,NetClient*, ClientTable);//1.11 +////E2C(D2Client,104225,DWORD, CurrentNPCNum);//1.11b +//E2C(D2Client,11A2F4,DWORD, IsLodGame);//1.11 +//E2C(D2Client,11BFB8,BYTE, DifficultyLevel);//1.11 +//E2C(D2Client,11B414,DWORD, MouseY);//0x258 = 600 //1.11b +//E2C(D2Client,11B418,DWORD, MouseX);//0x320 = 800 //1.11b +//E2C(D2Client,11C1E0,Unit*, ptClientChar);//1.11b + +//C7(D2Common,000000,000000, 96A20, 9B74C, 9EE8C, 9B500, 99E1C, DataTables*,SgptDataTables); //03836A20 - 037A0000 //01EE6A20 +C7(D2Client, D50E8, D40E0, D40F0, F5C60, F4FC8, DC6E4, DBC4C, DWORD, ResolutionY);//0x258 = 600 +C7(D2Client, D50EC, D40E4, D40F4, F5C5C, F4FC4, DC6E0, DBC48, DWORD, ResolutionX);//0x320 = 800 +C7(D2Client,125AD8,124958,11A74C,11BD28,11BEFC,11BD2C,11B9A4, DWORD, NegWindowStartY);//0xFFFFFFC4 = -60 +C7(D2Client,125AD4,124954,11A748,11BD24,11BEF8,11BD28,11B9A0, DWORD, WindowStartX);//0x50 = 80 +//C7(D2Launch, 55818, 56088, 2CD5C,000000, 2CD5C,000000,000000, DWORD, GameTypeMode);//0x50 = 80 //6FA3CD5C-6FA10000 +C7(D2Game, F2A80, F2918,113FB8,111718,1115E0,1105E0,1107B8, NetClient*, ClientTable); +//C7(D2Client,000000,000000,000000,000000,104225,000000,000000, DWORD, CurrentNPCNum); +C7(D2Client,000000,000000,000000, FB3F4,11A2F4,10330C,119854, DWORD, IsLodGame); +C7(D2Client,000000,000000,10795C,11BFB8,11C2A8,11BFF4,000000, BYTE, DifficultyLevel); +C7(D2Client,000000,000000,000000,10A40C,11B414,101634,11B824, DWORD, MouseY);//0x258 = 600 +C7(D2Client,000000,000000,000000,10A410,11B418,101638,11B828, DWORD, MouseX);//0x320 = 800 +C7(D2Client,000000,000000,000000,11C4F0,11C1E0,11C3D0,11BBFC, Unit*, ptClientChar); + + +C7(D2Client, DB918, DA828,000000,000000,000000,000000,000000, DWORD, NbStatDesc); +C7(D2Client, DAF98, D9EA8,000000,000000,000000,000000,000000, DWORD, StatDescTable); + +/* NEXT NOT TESTED IN 1.10 (1.09b fct) +D2_STD(D2Common10066, void, D2RemoveFromRoom, (DrlgRoom1* hRoom, DWORD untitype, DWORD unitID), 0x6FD7CFD0); +D2_STD(D2Common10082, DWORD, D2IsTown, (DrlgRoom1* hRoom), 0x6FD7D8A0); +D2_STD(D2Common10180, Unit*, D2GetTargetFromPath, (Path* hPath), 0x6FD9C4C0); +D2_STD(D2Common10184, void, D2SetPathParameter, (Path* hPath, DWORD value), 0x6FD9C5D0); +D2_STD(D2Common10240, Inventory*, D2InitInventory, (DWORD zero, DWORD param1, DWORD param2, DWORD param3, DWORD one), 0x6FD7E920); +D2_STD(D2Common10253, bool, D2EquipUnit, (Unit* ptTaker, Unit* ptItem, DWORD bodyloc), 0x6FD80020); +D2_STD(D2Common10258, Unit*, D2GetWeaponUnit, (Inventory* ptInventory), 0x6FD802D0); +D2_STD(D2Common10261, void*, D2SetMouseItem, (Inventory* ptInventory, Unit* ptUnit), 0x6FD80520); +D2_STD(D2Common10310, Node*, D2GetNodeForItem, (Inventory* ptInventory, Unit* ptUnit), 0x6FD82FB0); +D2_STD(D2Common10320, SkillData*, D2GetStartingSkill, (Unit* ptUnit), 0x6FDAD8C0); +D2_STD(D2Common10321, SkillData*, D2GetLeftHandSkill, (Unit* ptUnit), 0x6FDAD900); +//D2_STD(D2Common10322, SkillData*, D2GetRightSkill, (Unit* ptUnit), 0x6FDAD940); +D2_STD(D2Common10323, SkillData*, D2GetCurrentSkill, (Unit* ptUnit), 0x6FDAD9C0); +D2_STD(D2Common10326, DWORD, D2UNITGetXpos, ( Unit* ptUnit ), 0x6FDADA00); +D2_STD(D2Common10329, DWORD, D2UNITGetYpos, ( Unit* ptUnit ), 0x6FDADB70); +//D2_STD(D2Common10348, void, D2SetUnitMode, (Unit* ptUnit, DWORD mode), 0x6FDAEBD0); +D2_STD(D2Common10395, ShrinesTXT*, D2GetShrinesTXTRowFromID, (DWORD shrineID), 0x6FDAFE20); +D2_STD(D2Common10659, void*, D2GetTCFromID, (DWORD TCIndex), 0x6FD5E1C0); +//D2_STD(D2Common10517, void, D2SetPlayerStat, (Unit* ptChar, DWORD statID, DWORD Amount), 0x6FDA7D30); +//D2_STD(D2Common10581, CharStatsBIN*,D2GetCharStatsBIN, (DWORD classID), offset_D2Common + 0x6FD47430); +D2_STD(D2Common10746, DWORD, D2GetCode, (Unit* ptUnit), 0x6FD8AD70); +D2_STD(D2Common10749, void, D2ITEMSGetItemDimensions, (Unit* ptItem, DWORD* x, DWORD* y, char* filename, DWORD line), 0x6FD8AF00); +D2_STD(D2Common10795, DWORD, D2GetMaxStack, (Unit* ptUnit), 0x6FD8EEF0); +D2_STD(D2Common10804, DWORD, D2GetSpellIcon, (Unit* ptUnit), 0x6FD8F190); +D2_STD(D2Common10821, DWORD, D2IsSocketValid, (Unit* ptItem ), 0x6FD8FD70); +//D2_STD(D2Common10854, void, D2RemoveItem, (Unit* ptUnit, BYTE page), 0x6FD89DC0); +D2_STD(D2Common10868, void, D2SetMod, (Unit* ptUnit, ItemMod* ptProperty, int one), 0x6FD88950); +D2_FST(D2Common10918, DWORD, D2GetRandomInt, (D2Seed* ptSeed, int max), 0x6FDA0B10); +D2_STD(D2Common10952, Unit*, D2AddSingleSkill, (Unit* ptChar, WORD SkillID), 0x6FDA1CB0); // WORD ? +D2_FST(D2Common10966, Unit*, D2GetSkillPointerFromClient, (Unit* ptClientChar), 0x6FDA33A0); +D2_FST(D2Common6FC82E00,DWORD, D2GetItemNum, (D2Game* ptGame, DWORD lvl, DWORD typenum), 0x6FC82E00); + +D2_FST(D2Game6FC3E3F0, void, D2ClientItemRemove, (void* ptClient, Unit* ptChar, Unit* ptItem, DWORD twenty), 0x6FC3E3F0); +D2_FST(D2Game6FC3E640, void, D2FireScrollGraph, (void* ptClient, Unit* ptItem, int one, DWORD dwStatID, DWORD dwStatNum), 0x6FC3E640); +D2_FST(D2Game6FC3E6C0, void, D2SetMouseIcon, (void* ptGame, Unit* ptChar, int nSpellicon, int zero, int one, DWORD dwUnknown), 0x6FC3E6C0); +D2_FST(D2Game6FC3E740, void*, D2ResetMouse, (void* ptClient, Unit* ptChar), 0x6FC3E740); +D2_FST(D2Game6FC45BD0, DWORD, D2SwapItem, (D2Game* ptGame, Unit* ptChar, DWORD dwSrcID, DWORD dwTrgID, int x, int y, void* ptMouse), 0x6FC45BD0); +D2_FST(D2Game6FC45FE0, void, D2RemoveItemMem, (D2Game* ptGame, Unit* ptChar, Unit* ptItem, DWORD zero), 0x6FC45FE0); +D2_FST(D2Game6FC480D0, DWORD, D2PutScroll, (D2Game* ptGame, Unit* ptChar, DWORD dwSrcID, DWORD dwTrgID, void* ptMouse), 0x6FC480D0); +D2_FST(D2Game6FC497B0, void, D2UpdatePlayer, (void * ptGame, Unit* ptChar, DWORD nUnitType), 0x6FC497B0); +D2_FST(D2Game6FC4E170, void*, D2RemoveItemFromMem, (void* ptGame, Unit* ptItem), 0x6FC4E170); +D2_FST(D2Game6FC4E290, void*, D2GetPtrFromCode, (void* ptChar, DWORD itemcode), 0x6FC4E290); +D2_FST(D2Game6FC87E40, void, D2SpawnItem, (void* ptGame, Unit* ptChar, DWORD itemCode, DWORD ilvl, DWORD quality, DWORD one), 0x6FC87E40); +D2_FST(D2Game6FC4EF60, void, D2DropTC, (void* ptGame, Unit* ptChar, Unit* ptNPC, void* ptTC, DWORD z5, DWORD ilvl, DWORD z1, DWORD z2, DWORD z3, DWORD z4), 0x6FC4EF60); +D2_FST(D2Game6FCABAE0, Unit*, D2GetPtrFromID, (D2Game* ptGame, int UnitType, DWORD UniqueID), 0x6FCABAE0); +D2_FST(D2Game6FCABB70, void, D2SpawnPlague, (void* u1,Unit* ptMissile), 0x6FCABB70); + +D2_FST(D2Client6FAB9AF0,void, D2FireClientMissile, (Unit* ptUnit), 0x6FAB9AF0); +D2_FST(D2Client6FAE6600,void, D2CubeLight, (DWORD code), 0x6FAE6600); +D2_FST(D2Client6FB22270,void, D2ScrollText, (Unit* ptUnit, DWORD ptText, int zero), 0x6FB22270); +D2_FST(D2Client6FB2C1E0,Unit*, D2GetClientUnit, (DWORD itemID, DWORD nUnitType), 0x6FB2C1E0); +D2_FST(D2Client6FB30470,void, D2ClientUpdatePlayer, (Unit* ptChar, DWORD nUnitType), 0x6FB30470); + + +Storm 1.09: +251 SFileAuthenticateArchive +252 SFileCloseArchive +253 SFileCloseFile +254 SFileDdaBegin +255 SFileDdaBeginEx +256 SFileDdaDestroy +257 SFileDdaEnd +258 SFileDdaGetPos +259 SFileDdaGetVolume +260 SFileDdaInitialize +261 SFileDdaSetVolume +262 SFileDestroy +263 SFileEnableDirectAccess +264 SFileGetFileArchive +265 SFileGetFileSize +266 SFileOpenArchive +267 SFileOpenFile +268 SFileOpenFileEx +269 SFileReadFile +270 SFileSetBasePath +271 SFileSetFilePointer +272 SFileSetLocale +273 SFileGetBasePath +274 SFileSetIoErrorMode +275 SFileGetArchiveName +276 SFileGetFileName +277 SFileGetArchiveInfo +278 SFileSetPlatform +279 SFileLoadFile +280 SFileUnloadFile +281 SFileLoadFileEx +282 SFilePrioritizeRequest +283 SFile_CancelRequest +284 SFileSetAsyncBudget +285 SFileSetDataChunkSize +286 SFileEnableSeekOptimization +287 SFileReadFileEx +288 SFile_CancelRequestEx +289 SFileReadFileEx2 +290 SFileLoadFileEx2 + +Storm1.08 +401 SMemAlloc +403 SMemFree +404 SMemGetSize +405 SMemReAlloc +481 SMemFindNextBlock +482 SMemFindNextHeap +483 SMemGetHeapByCaller +484 SMemGetHeapByPtr +485 SMemHeapAlloc +486 SMemHeapCreate +487 SMemHeapDestroy +488 SMemHeapFree +489 SMemHeapReAlloc +490 SMemHeapSize +491 SMemCopy +492 SMemFill +493 SMemMove +494 SMemZero +495 SMemCmp +496 SMemSetDebugFlags +497 SMemDumpState +*/ +//Kingpin: D2Common #10027 is used to get dest unit (used for get type5 object in next room) +//D2Common10247, (ptInventory, ptItem, x,y,0xC,void*,void*,BYTE page) verif if items can be put in inventory +//D2Common10252 CheckGrid mouse over inventory/stash/etc. grid +//D2Common10284 returns current number of used sockets arg1 = ptInventory //KP +//D2Common10367 Returns number of rows in belt Kingpin: arg1 = ptItem +//D2Common10526 Kingpin know arg1 = ptUnit, arg3 = _FILE_, arg4 = ptGame +//D2Common10573 arg2 ptStatsList +//D2Common10660 is for sure returning tc entry it uses act, difficulty as params and one more, arg3 = depends of area level (0-2) +//D2Common11064 Kingpin: Check if monster and check if current animation mode is allowed arg1 = ptUnit +//D2Common11257 Get MaxID from SuperUnique.bin adress in memory arg1 = hcIdx + +//D2LoadItem D2Common10883 + 0x60370);//01D40370-1ce0000 +//D2TcEx (select what item to drop from the treasureclass) at:6FC51360 +//D2_STD(D2Common10578, BYTE*, D2LoadBinFile, (...), offset_D2Common + 0xFD70); //01CFFD70-01CF0000 +//Kingpin :I have noted that 10732 is this: get set/unique # [[+70]+24] +/* +Kingpin: d2common #11270 +Kingpin: Check MonType.txt line to see if it match (returns a boolan) +Kingpin: arg1 = unknown +arg2 = damage_vs_montype (stat from intestatscost.txt) +arg3 = ptUnit +arg4 = 80 (maxline maybe, but is only guessing) + +//d2game.6FD1D660 reverse player name :P + + +Kingpin: figured out a new t hing related to D2common #10466 :P +Yohann: ah ? +Kingpin: get stat (from itemstatscost.txt) used to calculated frames (life, missile, mana e.tc) +Kingpin: arg1 = ptUnit +Kingpin: arg2 = stat_id +Kingpin: arg3 = table index + + +D2Game.6FCBC900 Get Target ptUnit + +Kingpin: D2Client.6FB18770 returns a boolean if you have enough mana for skill +Kingpin: D2Client.6FB18AC0 sets it to selectable or not +D2Common #10480 Return ptState arg1 = ptUnit, arg2 = state_id +D2Common #10479 Get State_ID from ptState+14 +D2Common #11265 Get Skill_ID from ptState+1C Arg1 = ptState + +Kingpin: D2Common #10497 Get Duration of State +Kingpin: arg1 = state_id + + +D2Client.6FB5B0F0 +Function: Draw Filled Rectangle +void FASTCALL D2ClientFillRect(int x, int y, int Width, int Height, ULONG ulColor, ULONG transTbl); +D2_FST(D2Client6FB5B0F0,void, D2ClientFillRect,(int x, int y, int Width, int Height, DWORD col, DWORD transTbl), offset_D2Client + 0xBB0F0);//6FB5B0F0-6FAA0000 +D2Gfx.#10055 +Function: Draw Filled Rectangle +void STDCALL D2GfxFillRect(int left, int top, int right, int bottom, ULONG ulColor, ULONG transTbl); +NOTES: +color = Palette index. +transTbl = pl2 transform table index ... +0 = 75% transparent +1 = 50% transparent +2 = 25% transparent +3 = color blend 1 //white is transparent black is solid +4 = color blend 2 //black is transparent white is solid +5 = normal draw +6 = color blend 3 // screen + color +7 = hilight + + +6FAE7831 E8 9A380800 CALL ; click inventory +6FAE8D44 E8 87230800 CALL ; Right click inventory +6FAE8972 E8 59270800 CALL ; mouse over + + +D2Client.6FACFCD0 then that set color for the text (it calls in this function #10121 and 10117) +Kingpin: and the position +Kingpin: arg1 = Xpos +arg2 = Ypos +arg3 = Pointer to Unicode String +arg4 = Color + +Kingpin: 10470 has as first arg ptGame +1C (memory alloc thing) +Kingpin: arg2 = flags i guess since they use 0x40 again +Kingpin: arg3 = 0 (no idea what it used for) +Kingpin: arg4 = 4 (same here, no idea) +Kingpin: arg5 = uniqueID + +Kingpin: 10868 SetMod +arg1 = ptItem +arg2 = ItemMod +arg3 = 1 +Kingpin: 11232 Get Cube Recipe Record (Line) from Cubemain.bin Address in memory +Kingpin: i have no parameters for 11232 +Kingpin: 11233 Get Number of Cube Recipes + +Kingpin: edi contains target unit +Kingpin: 10342 get ptRoom from target unit +Kingpin: ecx = unique unit id +Kingpin: ebx = unit type +Kingpin: eax = ptRoom +Kingpin: 10066 remove unit from room + +D2Game.6FCBC900 ; Get Target Unit +Arg1 = ptPlayer (ptUnit) +Arg2 = ptGame + + + +#10962 Add skill to player +Kingpin: arg1 ptPlayer +arg2 SkillID +Kingpin: arg3 Skill Level + +10602 Gets an item ID # from an item code + +Kingpin: get Prefix/suffix +Kingpin: #10699 arg1 = ptItem, arg2 = prefix Index +Kingpin: #10701 arg1 = ptItem, arg2 = suffix index + + +D2EquipUnit STDCALL_FUNCTION(int, D2Common280D, (Inventory* ptInventory, Unit* ptItem, int bodylocation)); +D2AddItemToInventory STDCALL_FUNCTION(int, D2Common2802, (Inventory* ptInventory, Unit* ptItem, int nodePage)); +Kingpin: in my notes it should start here +Kingpin: 6FC51360 /$ 55 PUSH EBP + +D2DropTC FASTCALL_FUNCTION(void, D2Game6FC51360, (D2Game* ptGame, Unit* ptChar, Unit* ptNPC, void* ptTC, DWORD z5, DWORD ilvl, DWORD z1, DWORD z2, DWORD z3, DWORD z4)); + +Kingpin: D2CreateItemUnit FASTCALL_FUNCTION(Unit*, D2Game6FC501A0, (Unit* ptPlayer, DWORD itemCode, D2Game* ptGame, DWORD uk1, DWORD quality, DWORD uk3, DWORD uk4, DWORD Lvl, DWORD uk5, DWORD uk6, DWORD uk7)); +ptItem = D2CreateItemUnit(ptPlayer, D2GetItemIDfromCode(CharstatTXT->Item1), PCGame, 4, 2, 1, 1, D2GetUnitStat(ptPlayer,STATS_LEVEL,0), 0, 0, 0); + +Kingpin: monsterData +28 holds ptGame +Kingpin: ptGame +2C UniqueID (owner ID) +Kingpin: ptGame +30 UnitType +srvDoFunc 15 adds temporarly a stat + +Kingpin: we have 10041 that get ptRoom from ptAct, XOffset&Yoffset + +*/ +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/Commons/D2UnitStruct.h b/Commons/D2UnitStruct.h new file mode 100644 index 0000000..8ef16a8 --- /dev/null +++ b/Commons/D2UnitStruct.h @@ -0,0 +1,672 @@ +/*================================================================= + File created by Yohann NICOLAS. + + @brief Diablo II Unit Structures definitions. + + NOT TESTED IN 1.10 (1.09b) + +=================================================================*/ + +#pragma once + +#include +struct CBPlayerData; +struct CBItemData; +struct Unit; + +/*=================================================================*/ +/* Skill Structure. */ +/*=================================================================*/ + +struct SkillData +{ //Offset from Code. (size = 0x3C or 0x40) + SkillsBIN* ptSkillBin; //+00 + SkillData* ptNextSkill; //+04 + DWORD mode; //+08 + DWORD uk1[3]; //+0C + DWORD targetInfo; //+18 + DWORD targetType; //+1c + DWORD targetUNID; //+20 + DWORD uk2; //+24 + DWORD slvl; //+28 + DWORD slvlBonus; //+2c + DWORD uk3; //+30 + int state; //+34 (-1 if index exist) + DWORD param1; //+38 (nb current charge) + DWORD param2; //+3C +}; + +struct Skills +{ //Offset from Code. + DWORD gameRelated; //+00 + SkillData* ptFirstSkill; //+04 + SkillData* ptLeftSkill; //+08 + SkillData* ptRightSkill; //+0c + SkillData* ptCurrentSkill; //+10 +}; + + +/*=================================================================*/ +/* Unit Data Structure. */ +/*=================================================================*/ + +struct Position +{ + DWORD x; + DWORD y; +}; + +struct Room//size=0x80 +{ +//ptRoom +48 0 = spawn new units (monster, objects e.tc), 1 = don't spawn any new units + DWORD seed1; //+00 + DWORD seed2; //+04 + BYTE uk8[0x1C]; //+08 + Room* ptNearRooms; //+24 + DWORD nbNearRooms; //+28 + Unit* unit; //+2C + BYTE uk5[0x44]; //+30 + Room* ptNextRoom; //+74 + union + { + BYTE flags; //+78 + struct + { + BYTE isGenerated:1; + BYTE isGenerated2:1;//??? + }; + }; +}; + +struct ActMap//ptGame+BC size=0x60 +{ + DWORD isNotManaged; + DWORD uk4; + DWORD uk8;//size = 0x488 + Room* ptFirstRoom; +}; + +struct NetClient; +//ptGame : 04E4007C +struct Game +{ //Offset from Code. + BYTE uk1[0x18]; //+00 + DWORD _ptLock; //+18 Unknown + DWORD memoryPool; //+1C Memory Pool (??) + BYTE uk2[0x4D]; //+20 + BYTE difficultyLevel; //+6D (Difficulty 0,1 or 2) + WORD unknown1; //+6E Cube puts 4 here + DWORD isLODGame; //+70 (D2=0 LOD =1) (DWORD ?) + BYTE uk3[0x04]; //+71 + WORD unknown2; //+78 + BYTE uk4[0x0E]; //+7A + NetClient* ptClient; //+88 + BYTE uk8C[0x30]; //+8C + ActMap* mapAct[5]; //+BC + BYTE ukD0[0x1024]; //+D0 + DWORD* game10F4; //+10F4 + BYTE uk6[0x28]; //+10F8 + Unit* units[0xA00]; //+1120 + Unit* roomtitles[0x200]; //+1B20 +}; +//WORD ptGame+28 game ID ? + + + +struct Path //(8 dword) +{ //Offset from Code. Size: 20 + WORD uk1; //+00 + WORD mapx; //+02 + WORD uk2; //+04 + WORD mapy; //+06 + DWORD uk3; //+08 + DWORD x; //+0C + DWORD y; //+10 + DWORD uk6; //+14 + DWORD uk7; //+18 + Room* ptRoom; //+1C +}; + + +struct Inventory +{ //Offset from Code. Size: 30 40 + DWORD tag; //+00 = 0x01020304 + BYTE uk1[0x04]; //+04 =? 0 + Unit* ptChar; //+08 + Unit* ptItem; //+0C + BYTE uk2[0x10]; //+10 + Unit* inventory1; //+20 + BYTE uk3[0x04]; //+24 + DWORD currentUsedSocket; //+28 //Kingpin : a variable to know how many sockets that have added to item + DWORD Inventory2C; //+2C //one value + DWORD Inventory30; //+30 + void* ptCorpse; //+34 + BYTE uk5[0x04]; //+38 + DWORD nextCorpseId; //+3C //max = 15 + BYTE uk6[0x04]; //+40 +}; + +struct D2Stat +{ + WORD index; + WORD id; + int value; +}; + + +struct Stats //sizeof(Stats)=0x64 +{ + DWORD nUnitId; //+00 + Unit* ptUnit; //+04 + DWORD nUnitType; //+08 + DWORD nItemNum; //+0C + union + { + DWORD flags; //+10 + struct + { + DWORD fuk1:13; //0x00001FFF + DWORD isDisabled:1; //0x00002000 + DWORD fuk2:17; //0x7FFFC000 + DWORD dontUseBaseValue:1;//0x80000000 + }; + }; + DWORD id; //+14 + DWORD uk18; //+18 + BYTE uk2[0x08]; //+1C + D2Stat* ptBaseStatsTable; //+24 + WORD nbBaseStats; //+28 + WORD sizeOfBaseStatsTable; //+2A ?? + Stats* ptStats; //+2C + BYTE uk3[0x04]; //+30 + Stats* ptItemStats; //+34 + BYTE uk4[0x04]; //+38 + Stats* ptAffixStats; //+3C + Stats* ptNextStats2; //+40 + union + { + Unit* ptChar; //+44 + Unit* ptItem; + }; + D2Stat* ptStatsTable; //+48 + WORD nbStats; //+4C + WORD sizeOfStatsTable; //+4E ?? + BYTE uk5[0x8]; //+50 + BYTE* unknow0; //+58 (sizeof(*unknow0)=0x30 (calculated) + DWORD unknow1; //+5C (=0) + DWORD unknow2; //+60 (=0) +}; + + +struct MonsterData // sizeof(MonsterData)=0x60 +{ //Offset from Code. + BYTE uk[0x16]; //+00 + union { + WORD flags; //+16 + struct { + WORD fuk1:1; + WORD isSuperUnique:1; + WORD isChampion:1; + WORD isUnique:1; + WORD fuk2:13; + }; + }; + BYTE uk1[0x0E]; //+18 + WORD superUniqueID; //+26 + void* unknow1; //+28 + BYTE uk2[0x38]; //+28 +}; + +struct ObjectData +{ + ObjectsBIN* ptObjectsBIN; + BYTE levelID; +}; +/* +Kingpin: struct MonsterData +{ + BYTE uk1[0x13]; // +00 + DWORD Flags; // +14 + DWORD uk2; // +18 + DWORD MinionOwnerID; // +1C + BYTE uk3[0x5]; // +20 + WORD SuperUniqueID; // +26 Superunique ID of monster + D2Game* ptGame; // +28 ptGame +}; +*/ + +#define F2_ITEM_IS_IDENTIFIED 0x10 //or F_IS_IDENTIFIED ? + +struct ItemData//size=0x74 +{ //Offset from Code. + DWORD quality; //+00 + DWORD seedLow; //+04 + DWORD seedHi; //+08 + DWORD playerID; //+0C #10734 / #10735 (PCInventory->ptPlayer->0C) + DWORD seedStarting; //+10 + DWORD flags1; //+14 + union { + DWORD flags2; //+18 + struct { + DWORD fuk1:1; //0x00000001 + DWORD isIndentified:1; //0x00000002 + DWORD fuk2:2; //0x0000000C + DWORD isUnindentified:1; //0x00000010 + DWORD fuk3:3; //0x000000E0 + DWORD isBroken:1; //0x00000100 + DWORD fuk4:2; //0x00000600 + DWORD isSocketed:1; //0x00000800 + DWORD fuk5:10; //0x003FF000 + DWORD isEtheral:1; //0x00400000 + DWORD fuk6:3; //0x03800000 + DWORD isRuneword:1; //0x04000000 + DWORD fuk7:1; //0x08000000 + DWORD isPersonalized:1; //0x10000000 + DWORD fuk8:3; //0xE0000000 + }; + }; +/* +ITEMFLAG_NEWITEM = 0x00000001, +ITEMFLAG_TAGETING = 0x00000004, +ITEMFLAG_UNIDENTIFIED = 0x00000010, +ITEMFLAG_QUANTITY = 0x00000020, +ITEMFLAG_Durability = 0x00000100, +ITEMFLAG_UNKNOWN2 = 0x00000400, +ITEMFLAG_SOCKETED = 0x00000800, +ITEMFLAG_NON_SELLABLE = 0x00001000, +ITEMFLAG_NEWITEM2 = 0x00002000, +ITEMFLAG_UNKNOWN3 = 0x00004000, +ITEMFLAG_CHECKSECPRICE = 0x00010000, +ITEMFLAG_CHECKGAMBLEPRICE = 0x00020000, +ITEMFLAG_UNKNOWN4 = 0x00080000, +ITEMFLAG_INDESTRUCTIBLE(ETHERAL) = 0x00400000, +ITEMFLAG_UNKNOWN5 = 0x00800000, +ITEMFLAG_FROMPLAYER = 0x01000000, +ITEMFLAG_RUNEWORD = 0x04000000 +*/ + DWORD guid1; //+1C Global Unique ID 1 + DWORD guid2; //+20 Global Unique ID 2 + DWORD guid3; //+24 Global Unique ID 3 + DWORD uniqueID; //+28 + BYTE ilvl; //+2C + BYTE uk1[0x03]; //+2D + WORD version; //+30 + WORD rarePrefix; //+32 + WORD rareSuffix; //+34 + WORD autoPref; //+36 + WORD prefix[3]; //+38 + WORD suffix[3]; //+3E + BYTE equipLoc; //+44 + /* emplacement si quip + * 00 = noequip/inBelt + * 01 = head + * 02 = neck + * 03 = tors + * 04 = rarm + * 05 = larm + * 06 = lrin + * 07 = rrin + * 08 = belt + * 09 = feet + * 0A = glov + * 0B = ralt + * 0C = lalt +*/ + BYTE page; //+45 + /* page dans laquel se trouve l'item + * FF = mouse/equip/onEarth + * 00 = inventory + * 01 = cube + * 04 = stash + */ + BYTE uk4[0x01]; //+46 + BYTE ItemData3; //+47 //D2Common10854 D2Common10853 + BYTE pEarLevel; //+48 + BYTE varGfx; //+49 + char IName[0x12]; //+4A //inscribed/ear name + Inventory* ptInventory; //+5C + Unit* ptPrevItem; //+60 + Unit* ptNextItem; //+64 + BYTE uk8[0x01]; //+68 + BYTE ItemData2; //+69 + BYTE uk9[0x0A]; //+6A +}; + + +struct NetClient +{ + DWORD clientID; //+00 + BYTE uk1[0x06]; //+04 + union { //+0A + WORD flag; + struct { + WORD f1:1; + WORD f2:1; + WORD isHardCoreGame:1; + }; + }; + BYTE uk2[0x170]; //+0C + BYTE* savefile; //+17C + DWORD finalSize; //+180 + DWORD counter; //+184 + DWORD currentSize; //+188 + BYTE uk3[0x1C]; //+18C + Game* ptGame; //+1A8 + //+1A8 is ptGame + //+4A8 ptNextClient +/* +Kingpin: ptPclient ++16C is either act or unit type ++170 Active UniqueID for player ++174 Active ptPlayer on Client ++1a8 ptGame ++1b4 Current or next ptRoom +*/ +}; +/* +struct PlayerData +{ + char name[0x10]; //+00 (size min 0x08 max 0x11) + BYTE uk1[0x8C]; //+10 + NetClient* ptNetClient; //+9C +}; +*/ +struct PlayerData +{ + char name[0x10]; //+00 Player Name + void* ptQuest[3]; //+10 Quest Pointers for each difficulty + BYTE uk1[0x18]; //+1C //before : 0x14 + void* ptArenaUnit; //+34 ptArena for the Unit + BYTE uk2[0x4]; //+38 //before : 0x7 + WORD MPSourcePortalUniqueID; //+3C Source Portal Unique_ID + BYTE uk3[0x2]; //+3E + WORD MPDestPortalUniqueID; //+40 Destination Portal Unique_ID + BYTE uk4[0x06]; //+42 + BYTE ptObjectUnID; //+48 Object UniqueID for TownPortals + BYTE uk5[0x53]; //+49 + NetClient* ptNetClient; //+9C ptClient +}; + + +#define F1_IS_SPAWNED 0x10 //or F_IS_IDENTIFIED ? +#define F2_IS_LOD 0x2000000 +struct Unit +{ //Offset from Code. Size: 0xF4+4 + DWORD nUnitType; //+00 + union{ + DWORD nPlayerClass; + DWORD nTxtFileNo; + }; //+04 + DWORD nUnitId; //+08 + DWORD nItemNum; //+0C + DWORD CurrentAnim; //+10 + union{ + MonsterData* ptMonsterData; + ObjectData* ptObjectData; + ItemData* ptItemData; + PlayerData* ptPlayerData; + }; //+14 + BYTE act; //+18 + BYTE uk12[3]; //+19 + void* ptAct; //+1C + DWORD SeedLow; //+20 + DWORD SeedHi; //+24 + DWORD SeedStarting; //+28 + Path* path; //+2C + BYTE uk1[0x08]; //+30 + Path* ptPos; //+38 + DWORD animSpeed; //+3C + BYTE uk2[0x04]; //+40 + DWORD curFrame; //+44 + DWORD remainingFrame; //+48 + WORD animSpeedW; //+4C + BYTE actionFlag; //+4E + BYTE uk3[0x1]; //+4F + void* ptAnimData; //+50 + BYTE uk4[0x08]; //+54 + Stats* ptStats; //+5C + Inventory* ptInventory; //+60 + BYTE uk5[0x1C]; //+64 + Game* ptGame; //+80 + BYTE uk6[0x24]; //+84 + Skills* ptSkills; //+A8 + void* ptCombatData; //+AC + BYTE uk7[0x08]; //+B0 + DWORD itemCode; //+B8 for an item being dropped by this unit + BYTE uk8[0x08]; //+BC + DWORD flags1; //+C4 + union{ + DWORD flags2; //+C8 //flags + struct{ + DWORD ukf1:25; + DWORD isLod:1; + }; + }; + BYTE uk9[0x04]; //+CC + DWORD clientId; //+D0 + BYTE uk10[0x0C]; //+D4 + Unit* ptFirstMonster; //+E0 + Unit* Unit1; //+E4 + Unit* Unit2; //+E8 + BYTE uk11[0x08]; //+EC + union{ + CBPlayerData* ptCBPlayerData; + CBItemData* ptCBItemData; + void* ptCBData; + }; //+F4 +}; + + + +/* +struct D2Game +{ + DWORD unknown[19]; + WORD difficulty; +}; + +struct ItemMod +{ + DWORD mID; // +00 Mod ID, get it from properties.txt + DWORD mParam; // +04 First Property + DWORD mMinimum; // +04 Second Property, Min Value + DWORD mMaximum; // +04 Third Property, Max Value +}; + +struct AIStruct +{ + DWORD mSpawn; // +00 + void* mAIFunc; // +04 + DWORD mUnknown1[8]; // +08 + D2Game* mGame; // +28 + DWORD mMinionOwner; // +2C + DWORD mOwnerType; // +30 +}; + + +struct LocInfo +{ //Offset from Code + Unit* noneLoc; //+00 + Unit* headLoc; //+04 + Unit* neckLoc; //+08 + Unit* torsoLoc; //+0c + Unit* rightArmLoc; //+10 + Unit* leftArmLoc; //+14 + Unit* rightRingLoc; //+18 + Unit* leftRingLoc; //+1c + Unit* beltLoc; //+20 + Unit* feetLoc; //+24 + Unit* glovesLoc; //+28 +}; + +struct ItemData +{ // Offset from Code + DWORD quality; // +00. + DWORD lowSeed; // +04. + DWORD highSeed; // +08. + DWORD unknown1; // +0c. + DWORD startLowSeed; // +10. + DWORD cmdFlags; // +14. + DWORD flags; // +18. + DWORD unknown2[2]; // +1C + DWORD originID; // +24. + DWORD iLvl; // +28. + WORD version; // +2C. + WORD prefix; // +2E. + WORD suffix; // +30. + WORD autoPrefix; // +32. + WORD prefix1; // +34. + WORD prefix2; // +36. + WORD prefix3; // +38. + WORD suffix1; // +3A. + WORD suffix2; // +3C. + WORD suffix3; // +3E. + BYTE bodyLoc; // +40. // 0=inv/stash 4=gaucheS 5=droiteS + BYTE inPage; // +41. // FF=equip 00=inv 04=stash + BYTE unknown3[3]; // +42 + BYTE picture[8]; // +45 + DWORD ilvl; // +4C +}; + +struct PresetUnit +{ //Offset from Code + DWORD unitType; //+00 + DWORD txtFileNo; //+04 + DWORD unknown1[1]; //Unkonwn Data at +08 + DWORD xPos; //+0c + DWORD yPos; //+10 + DWORD unknown2[2]; //Unknown data at +14 + PresetUnit* pNext; //+1c +}; + +struct MissileData +{ ++04 flags ++08 0 on start ++0c -1 on start ++20 nDirection ++28 range? ++2c range? ++30 level ++34 number of pierces (byte) ++35 (byte) ++36 (byte) ++37 (byte) ++38 range-activate +}; + + +struct Combat +{ + DWORD mHeader; // +00 : Always 0x32 + DWORD mDisplayFlag; // +04 : Affect critical hit etc ... + DWORD mPhysicalDmg; // +08 : Values are << 8 + DWORD mUnknown1; // +0C + DWORD mFireDmg; // +10 : Values are << 8 + DWORD mUnknown2; // +14 + DWORD mBurnLeng; // +18 + DWORD mLtngDmg; // +1C : values are << 8 + DWORD mMagDmg; // +20 : values are << 8 + DWORD mColdDmg; // +24 : values are << 8 + DWORD mPoisDmg; // +28 : ?? + DWORD mPoisLeng; // +2C + DWORD mColdLeng; // +30 + DWORD mFreezeLeng; // +34 + DWORD mLifeSteal; // +38 + DWORD mManaSteal; // +3C + DWORD mUnknwon3; // +40 + DWORD mStunLeng; // +44 + DWORD mUnknown4; // +48 + DWORD mTotalDamage; // +4C + DWORD mUnknown5[6]; // +50 + DWORD mOverlay; // +68 + DWORD mUnknwon6; // +6C +}; + + +struct Node +{ //Offset from Code. + DWORD flag; //+00 //Yoh : null->flag + Unit* ptItem; //+04 //Yoh : ItemData=>Unit + DWORD unID; //+08 + DWORD page; //+0c //Yoh plutot etat : inventory/stash=1; inv-belt=2; equip=3 + Node* nextNode; //+10 +}; + + + +struct MonsterData // size110 : 60 +{ + AIStruct* AIPtr; + void* unkonwPtr1; + void* uniqueInfo; + void* spawnInfo; + void* unknownPtr2; + DWORD unkown[8]; + void* lvlPtr; + MonStatTxt* monstatPtr; +}; + + +struct Unit +{ //Offset from Code. + DWORD nUnitType; //+00 + union + { + DWORD nTxtFileNo; + DWORD nPlayerClass; + }; //+04 + + DWORD nUnitId; //+08 + DWORD eMode; //+0c + DWORD* unknow1; //+10 + DWORD nAct; //+14 + DWORD pActRelated; //+18 + DWORD unknown2[4]; //Unknown Data at +1C + D2Seed nSeed; //+2C + DWORD startSeed; //+34 + Path* pPos; //+38 + DWORD unknown3[6]; //Unknown Data at +3C + DWORD animSpeed; //+54 + DWORD unknown32[2]; //+58 + BYTE COFString[12]; //+60 + Stats* ptStats; //+6C + + union + { + PlayerData* pPlayerData; + MonsterData* pMonsterData; + ItemData* pItemData; + MissileData* pMissile; + ObjectData* pObjectData; + }; //+70 + + DWORD unknown5[2]; //+74 + BYTE unknown6[2]; //+7C + BYTE rndDmg[2]; //+7e + DWORD unknown7; //+80 + Inventory* ptInventory; //+84 + DWORD unknown8[4]; //+88 + DWORD startNull; //+98 + DWORD unknown9[2]; //+9c + D2Game* ptGame; //+a4 + DWORD unknown10[4]; //+a8 + DWORD nOwnerType; //+b8 + DWORD nOwnerId; //+bc + DWORD unknown11[3]; //+c0 + D2Info* ptInfo; //+cc + Combat* ptCombat; //+d0 + DWORD unknown12[5]; //+d4 + DWORD flags; //+e8 + DWORD LODflag; //+ec + DWORD unknown13[7]; //+f0 + Unit* pNext; //+10c + DWORD unknown14[2]; //+110 //YOH + union + { + ItemData* ptItemData; + void* ptData; + }; //+118 //YOH +}; +*/ +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/Commons/d2BinFile.h b/Commons/d2BinFile.h new file mode 100644 index 0000000..3e99d99 --- /dev/null +++ b/Commons/d2BinFile.h @@ -0,0 +1,1263 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Stucture of binary file + +=================================================================*/ + +#pragma once + +#include +/* +struct D2ShrinesTXT +{ + BYTE Code; //+00 + BYTE NotUsed1[3]; //+01 + DWORD Arg1; //+04 + DWORD Arg2; //+08 + DWORD DurInFrames; //+0C + BYTE ResetTimeInMinutes; //+10 + BYTE Rarity; //+11 + char ViewName[0x1F]; //+12 + char NiftyPhrase[0x7F]; //+32 + BYTE EffectClass; //+B2 + BYTE NotUsed2; //+B3 + DWORD LevelMin; //+B4 + };*/ + +enum D2CubeItemFlag +{ + CUBE_COWPORTAL =1, + CUBE_USEITEM =0xFF, + CUBE_USETYPE =0xFE, + CUBE_TYPE =0xFD, + CUBE_ITEM =0xFC +}; + + +struct CubeOutput//size: 0x54=84 (source total : fct of dll) +{ + union { + WORD flag; //+00 + struct { + WORD keepModifiers:1; //",mod" + WORD haveSockets:1; //",sock=#nbsocket" + WORD isEthereal:1; //",eth" + WORD isSpecificItem:1; //"#itemUniqueName" or "#itemSetName" (set byItemID too) + WORD destroysFillers :1; //",uns" + WORD removeFillers:1; //",rem" + WORD regeneratesUnique:1; //",reg" + WORD upgradeToExceptional:1; //",exc" + WORD upgradeToElite:1; //",eli" + WORD repair:1; //",rep" + WORD recharge:1; //",rch" + }; + }; + WORD ID; //+02 + WORD specificID; //+04 + BYTE quality; //+06 1=",low"; 2=",nor"; 3=",hiq"; 4=",mag"; 5=",set"; 6=",rar"; 7=",uni"; 8=",crf"; 9=",tmp" + BYTE quantityOrNbSockets;//+07 ",qty=#quantity" Or ",sock=#nbsocket" + BYTE outputType; //+08 02="Pand. Portal" 01="Cow Portal" FF="usetype"; FE="useitem" FC="#item4Code" FD="#type4Code" + BYTE lvl; //+09 //+55 + BYTE plvl; //+0A //+56 + BYTE ilvl; //+0B //+57 + WORD Prefix; //+0C + WORD PrefixMin; //+0E (always 0) + WORD PrefixMax; //+10 (always 0) + WORD Suffix; //+12 + WORD SuffixMin; //+14 (always 0) + WORD SuffixMax; //+16 (always 0) + DWORD mod1; //+18 //+64(13) + WORD mod1param; //+1C //+68 + WORD mod1min; //+1E //+6A + WORD mod1max; //+20 //+6C + BYTE mod1chance; //+22 //+6E + DWORD mod2; //+24 //+70 + WORD mod2param; //+28 //+74 + WORD mod2min; //+2A //+76 + WORD mod2max; //+2C //+78 + BYTE mod2chance; //+2E //+7A + DWORD mod3; //+30 //+7C + WORD mod3param; //+34 //+80 + WORD mod3min; //+36 //+82 + WORD mod3max; //+38 //+84 + BYTE mod3chance; //+3A //+86 + DWORD mod4; //+3C //+88 + WORD mod41param; //+40 //+8C + WORD mod4min; //+42 //+8E + WORD mod4max; //+44 //+90 + BYTE mod4chance; //+46 //+92 + DWORD mod5; //+48 //+94 + WORD mod5param; //+4C //+98 + WORD mod5min; //+4E //+9A + WORD mod5max; //+50 //+9C + BYTE mod5chance; //+52 //+9E +}; + + +struct CubeInput//size: 8 (source total : fct of dll) +{ + union { + WORD flag; //+00 + struct { + WORD byItemID:1; //"#item4Code" or "any" + WORD byItemTypeID:1; //"#itemType4Code" + WORD haveNoSocket:1; //",nos" + WORD haveSockets:1; //",sock" + WORD isEthereal:1; //",eth" + WORD isNotEthereal:1; //",noe" + WORD isSpecificItem:1; //"#itemUniqueName" or "#itemSetName" (set byItemID too) + WORD includeUpgradedVersions:1; //",upg" + WORD isBasic:1; //",bas" + WORD isExceptional:1; //",exc" + WORD isElite:1; //",eli" + WORD isNotRuneword:1; //",nru" + }; + }; + WORD ID; //+02 FFFF = any items + WORD specificID; //+04 + BYTE quality; //+06 1=",low"; 2=",nor"; 3=",hiq"; 4=",mag"; 5=",set"; 6=",rar"; 7=",uni"; 8=",crf"; 9=",tmp" + BYTE quantity; //+07 ",qty=#quantity" +}; + + +struct CubeMainBIN//size: 0x148=328 (source total : fct of dll) (total size in LoD1.10 : BDA0) +{ + BYTE enabled; //+00 + BYTE ladder; //+01 + BYTE minDiff; //+02 + BYTE playerClass;//+03 FF=all classes + BYTE op; //+04 + DWORD param; //+08 + DWORD value; //+0C + BYTE numinputs; //+10 + WORD version; //+12 + CubeInput input1; //+14 + CubeInput input2; //+1C + CubeInput input3; //+24 + CubeInput input4; //+2C + CubeInput input5; //+34 + CubeInput input6; //+3C + CubeInput input7; //+44 + CubeOutput output1; //+4C + CubeOutput output2; //+A0 + CubeOutput output3; //+F4 +}; + +struct TreasureClassBIN +{ + +}; + +struct ObjectsBIN +{ + +}; + +struct LevelsBIN//size=0x220 +{ + +}; + +struct GemsBIN //size: 0xC0=192 (source : fct of dll) +{ + char name[0x20]; //+00 + char letter[6]; //+20 + BYTE uk1[2]; //+26 + DWORD code; //+28 + BYTE uk2[2]; //+2C + BYTE nummods; //+2E + BYTE transform; //+2F + int weaponmod1code; //+30 + DWORD weaponmod1param;//+34 + DWORD weaponmod1min; //+38 + DWORD weaponmod1max; //+3C + int weaponmod2code; //+40 + DWORD weaponmod2param;//+44 + DWORD weaponmod2min; //+48 + DWORD weaponmod2max; //+4C + int weaponmod3code; //+50 + DWORD weaponmod3param;//+54 + DWORD weaponmod3min; //+58 + DWORD weaponmod3max; //+5C + int helmmod1code; //+60 + DWORD helmmod1param; //+64 + DWORD helmmod1min; //+68 + DWORD helmmod1max; //+6C + int helmmod2code; //+70 + DWORD helmmod2param; //+74 + DWORD helmmod2min; //+78 + DWORD helmmod2max; //+7C + int helmmod3code; //+80 + DWORD helmmod3param; //+84 + DWORD helmmod3min; //+88 + DWORD helmmod3max; //+8C + int shieldmod1code; //+90 + DWORD shieldmod1param;//+94 + DWORD shieldmod1min; //+98 + DWORD shieldmod1max; //+9C + int shieldmod2code; //+A0 + DWORD shieldmod2param;//+A4 + DWORD shieldmod2min; //+A8 + DWORD shieldmod2max; //+AC + int shieldmod3code; //+B0 + DWORD shieldmod3param;//+B4 + DWORD shieldmod3min; //+B8 + DWORD shieldmod3max; //+BC +}; + +struct ItemsBIN //size: 0x1A8=424 (source : fct of dll) (nblines : 134 CA 8B) Gold:20B +{ + char FlippyFile[0x20]; //+00 + char InvFile[0x20]; //+20 + char UniqueInvFile[0x20]; //+40 + char SetInvFile[0x20]; //+60 + DWORD ItemCode; //+80 + DWORD NormCode; //+84 + DWORD UberCode; //+88 + DWORD HellCode; //+8C + DWORD AlternateGfx; //+90 + DWORD pSpell; //+94 + WORD State; //+98 + WORD cState1; //+9A + WORD cState2; //+9C + WORD Stat1; //+9E + WORD Stat2; //+A0 + WORD Stat3; //+A2 + DWORD Calc1; //+A4 + DWORD Calc2; //+A8 + DWORD Calc3; //+AC + DWORD Len; //+B0 + WORD SpellDesc; //+B4 + WORD SpellDescStr; //+B6 + DWORD SpellDescCalc; //+B8 + DWORD BetterGem; //+BC + DWORD WClass; //+C0 + DWORD TwoHandedWClass; //+C4 + DWORD TMogType; //+C8 + DWORD MinAC; //+CC + DWORD MaxAC; //+D0 + DWORD GambleCost; //+D4 + DWORD Speed; //+D8 + DWORD BitField; //+DC + DWORD Cost; //+E0 + DWORD MinStack; //+E4 + DWORD MaxStack; //+E8 + DWORD SpawnStack; //+EC + DWORD GemOffset; //+F0 + WORD NameStr; //+F4 + WORD Version; //+F6 + WORD AutoPrefix; //+F8 + WORD MissileType; //+FA + BYTE Rarity; //+FC + BYTE Level; //+FD + BYTE MinDam; //+FE + BYTE MaxDam; //+FF + BYTE MinMisDam; //+100 + BYTE MaxMisDam; //+101 + BYTE TwoHandMinDam; //+102 + BYTE TwoHandMaxDam; //+103 + BYTE RangeAdder; //+104 + BYTE NotUsed1; //+105 + WORD StrBonus; //+106 + WORD DexBonus; //+108 + WORD RegStr; //+10A + WORD RegDex; //+10C + BYTE Absorbs; //+10E + BYTE InvWidth; //+10F + BYTE InvHeight; //+110 + BYTE Block; //+111 + BYTE Durability; //+112 + BYTE NoDurability; //+113 + BYTE Missile; //+114 + BYTE Component; //+115 + BYTE RArm; //+116 + BYTE LArm; //+117 + BYTE Torso; //+118 + BYTE Legs; //+119 + BYTE RSpad; //+11A + BYTE LSpad; //+11B + BYTE TwoHanded; //+11C + BYTE Usable; //+11D + WORD Type; //+11E + WORD Type2; //+120 + BYTE SubType; //+122 + BYTE NotUsed2; //+123 + WORD DropSound; //+124 + WORD UseSound; //+126 + BYTE DropSfxFrame; //+128 + BYTE Unique; //+129 + BYTE Quest; //+12A + BYTE QuestDiffCheck; //+12B + BYTE Transparent; //+12C + BYTE TransTbl; //+12D + BYTE NotUsed3; //+12E + BYTE LightRadius; //+12F + BYTE Belt; //+130 + BYTE AutoBelt; //+131 + BYTE Stackable; //+132 + BYTE Spawnable; //+133 + BYTE SpellIcon; //+134 + BYTE DurWarning; //+135 + BYTE QntWaning; //+136 + BYTE HasInv; //+137 + BYTE GemSockets; //+138 + BYTE TransmoGrify; //+139 + BYTE TMogMin; //+13A + BYTE TMogMax; //+13B + BYTE HitClass; //+13C + BYTE OneOrTwoHanded; //+13D + BYTE GemApplyType; //+13E + BYTE LevelReq; //+13F + BYTE MagicLvl; //+140 + BYTE Transform; //+141 + BYTE InvTrans; //+142 + BYTE CompactSave; //+143 + BYTE SkipName; //+144 + BYTE NotUsed4; //+145 + BYTE VendorMin[17]; //+146 + BYTE VendorMax[17]; //+157 + BYTE VendorMagicMin[17]; //+168 + BYTE VendorMagicMax[17]; //+179 + BYTE VendorMagicLvl[17]; //+18A + BYTE NotUsed5; //+19B + DWORD NightmareUpgrade; //+19C + DWORD HellUpgrade; //+1A0 + BYTE PermStoreItem; //+1A4 + BYTE Multibuy; //+1A5 + WORD zeros; //+1A6 +}; + +struct RunesBIN //size: 0x120=288 (1.10 ok) +{ + char Name[0x40]; //+00 + char RuneName[0x40]; //+40 + BYTE Complete; //+80 + BYTE Server; //+81 + WORD RuneNameID; //+82 + WORD zero; //+84 (=0x0000) + WORD Itypes[6]; //+86 + WORD Etypes[3]; //+92 + int Runes[6]; //+98 + DWORD t1code1; //+B0 + DWORD t1param1; //+B4 + DWORD t1min1; //+B8 + DWORD t1max1; //+BC + DWORD t1code2; //+C0 + DWORD t1param2; //+C4 + DWORD t1min2; //+C8 + DWORD t1max2; //+CC + DWORD t1code3; //+D0 + DWORD t1param3; //+D4 + DWORD t1min3; //+D8 + DWORD t1max3; //+DC + DWORD t1code4; //+E0 + DWORD t1param4; //+E4 + DWORD t1min4; //+E8 + DWORD t1max4; //+EC + DWORD t1code5; //+F0 + DWORD t1param5; //+F4 + DWORD t1min5; //+F8 + DWORD t1max5; //+FC + DWORD t1code6; //+100 + DWORD t1param6; //+104 + DWORD t1min6; //+108 + DWORD t1max6; //+10C + DWORD t1code7; //+110 + DWORD t1param7; //+114 + DWORD t1min7; //+118 + DWORD t1max7; //+11C +}; + +/*struct ItemStatsBIN //size: 0x234=564 +{ + BYTE uk1[0x80]; //+00 + DWORD code; //+80 // ou 0x90 + BYTE uk2[0xB3]; //+84 + BYTE itemStat137; //+137 +};*/ + + +struct CharStatsBIN //size= 0xC4=196 +{ + WCHAR nameU[0x10]; + char name[0x10]; + BYTE baseSTR; //+20 + BYTE baseDEX; + BYTE baseENE; + BYTE baseVIT; + BYTE baseStamina; + BYTE HPAdd; + BYTE percentStr; + BYTE percentDex; + BYTE percentInt; + BYTE percentVit; + WORD manaRegen; + DWORD toHitFactor; + BYTE walkVelocity;//+30 + BYTE runVelocity; + BYTE runDrain; + BYTE lifePerLevel; + BYTE staminaPerLevel; + BYTE manaPerLevel; + BYTE lifePerVitality; + BYTE staminaPerVitality; + BYTE manaPerMagic; + BYTE blockFactor; + WORD startSkill; + DWORD baseWClass; + DWORD unknown1[3]; + DWORD item1; + BYTE item1Loc; + BYTE item1Count; + WORD item1Unknown; + DWORD item2; + BYTE item2Loc; + BYTE item2Count; + WORD item2Unknown; + DWORD item3; + BYTE item3Loc; + BYTE item3Count; + WORD item3Unknown; + DWORD item4; + BYTE item4Loc; + BYTE item4Count; + WORD item4Unknown; + DWORD item5; + BYTE item5Loc; + BYTE item5Count; + WORD item5Unknown; + DWORD item6; + BYTE item6Loc; + BYTE item6Count; + WORD item6Unknown; + DWORD item7; + BYTE item7Loc; + BYTE item7Count; + WORD item7Unknown; + DWORD item8; + BYTE item8Loc; + BYTE item8Count; + WORD item8Unknown; + DWORD item9; + BYTE item9Loc; + BYTE item9Count; + WORD item9Unknown; + DWORD item10; + BYTE item10Loc; + BYTE item10Count; + WORD item10Unknown; + BYTE unknown2[0x18]; +}; +/* +struct D2CharStats +{ + wchar_t Class_t[0x10]; //+00 + char Class[0x10]; //+20 + BYTE Str; //+30 + BYTE Dex; //+31 + BYTE Int; //+32 + BYTE Vit; //+33 + BYTE Stamina; //+34 + BYTE HpAdd; //+35 + BYTE PercentStr; //+36 + BYTE PercentInt; //+37 + BYTE PercentDex; //+38 + BYTE PercentVit; //+39 + BYTE ManaRegen; //+3A + BYTE NotUsed1; //+3B + DWORD ToHitFactor; //+3C + BYTE WalkVelocity; //+40 + BYTE RunVelocity; //+41 + BYTE RunDrain; //+42 + BYTE LifePerLevel; //+43 + BYTE StamianPerLevel; //+44 + BYTE ManaPerLevel; //+45 + BYTE LifePerVitality; //+46 + BYTE StaminaPerVitality; //+47 + BYTE ManaPerMagic; //+48 + BYTE BlockFactor; //+49 + BYTE NotUsed2[2]; //+4A + DWORD BaseWClass; //+4C + BYTE StatPerLevel; //+50 + BYTE NotUsed3; //+51 + WORD StrAllSkills; //+52 + WORD StrSkillTab1; //+54 + WORD StrSkillTab2; //+56 + WORD StrSkillTab3; //+58 + WORD StrClassOnly; //+5A + DWORD Item1; //+5C + BYTE Item1Loc; //+60 + BYTE Item1Count; //+61 + BYTE NotUsed4[2]; //+62 + DWORD Item2; //+64 + BYTE Item2Loc; //+68 + BYTE Item2Count; //+69 + BYTE NotUsed5[2]; //+6A + DWORD Item3; //+6C + BYTE Item3Loc; //+70 + BYTE Item3Count; //+71 + BYTE NotUsed6[2]; //+72 + DWORD Item4; //+74 + BYTE Item4Loc; //+78 + BYTE Item4Count; //+79 + BYTE NotUsed7[2]; //+7A + DWORD Item5; //+7C + BYTE Item5Loc; //+80 + BYTE Item5Count; //+81 + BYTE NotUsed8[2]; //+82 + DWORD Item6; //+84 + BYTE Item6Loc; //+88 + BYTE Item6Count; //+89 + BYTE NotUsed9[2]; //+8A + DWORD Item7; //+8C + BYTE Item7Loc; //+90 + BYTE Item7Count; //+91 + BYTE NotUsed10[2]; //+92 + DWORD Item8; //+94 + BYTE Item8Loc; //+98 + BYTE Item8Count; //+99 + BYTE NotUsed11[2]; //+9A + DWORD Item9; //+9C + BYTE Item9Loc; //+A0 + BYTE Item9Count; //+A1 + BYTE NotUsed12[2]; //+A2 + DWORD Item10; //+A4 + BYTE Item10Loc; //+A8 + BYTE Item10Count; //+A9 + BYTE NotUsed13[2]; //+AA + WORD StartSkill; //+AC + WORD Skill1; //+AE + WORD Skill2; //+B0 + WORD Skill3; //+B2 + WORD Skill4; //+B4 + WORD Skill5; //+B6 + WORD Skill6; //+B8 + WORD Skill7; //+BA + WORD Skill8; //+BC + WORD Skill9; //+BE + WORD Skill10; //+C0 + BYTE NotUSed14[2]; //+C2 +}; + +*/ + +struct UniqueItemsBIN //size=0x14C (332) +{ + WORD uniqueId; //+00 + BYTE uk1[0x20]; //+02 + WORD uniqueNameId; //+22 + BYTE uk2[0x08]; //+24 + union { + BYTE flag; //+2C + struct { + BYTE ukf:2; + BYTE carry1:1; + }; + }; + BYTE uk3[0x11F]; //+2D +}; + + +struct SetItemsBIN //size=0x1B8 (source : fct of dll) +{ + WORD setId; //+00 + char index[0x20]; //+02 + BYTE uk1; //+04 + WORD setNameId; //+24 + BYTE uk2[0x192]; //+26 +}; + + +struct SkillDescBIN //size=0x120=288 (source : fct of dll) +{ + BYTE uk1[0x08]; //+00 + WORD strNameID; //+08 + WORD strShortID; //+0A + WORD strLongID; //+0C + WORD strAltID; //+0E + BYTE uk2[0x110]; //+10 +}; + + +struct SkillsBIN //size=0x23C (572) +{ + WORD skillID; //+00 + BYTE uk1[0x0A]; //+02 + BYTE charclass; //+0C + BYTE uk2[0x08]; //+10 + WORD itypea1; //+18 + WORD itypea2; //+1A + WORD itypea3; //+1C + WORD itypeb1; //+1E + WORD itypeb2; //+20 + WORD itypeb3; //+22 + WORD etypea1; //+24 + WORD etypea2; //+26 + WORD etypeb1; //+28 + WORD etypeb2; //+2A + BYTE uk3[0x100]; //+2C + WORD maxlvl; //+12C + BYTE uk4[0x42]; //+12E + int skpoints; //+170 + WORD reqlevel; //+174 + BYTE uk5[0x1E]; //+176 + DWORD skilldesc; //+194 (DWORD ?) + BYTE uk6[0xA4]; //+198 +}; + +/* +struct D2SkillsTXT +{ + WORD SkillID; //+000 + BYTE Mask1; //+002 + BYTE Mask2; //+003 + BYTE Unknown[8]; //+004 + BYTE CharClass; //+00C + BYTE unknown_1[0x17D]; //+00D + WORD Mana; //+18A + short LvlMana; //+18C + BYTE Attackrank; //+18E + BYTE LineOfSight; //+18F + DWORD Delay; //+190 + WORD SkillDesc; //+194 + BYTE unknown_2[0xA6]; //+196 +}; + +struct D2SkillsTXT +{ + WORD SkillID; //+000 + BYTE Mask1; //+002 + BYTE Mask2; //+003 + BYTE Unknown[8]; //+004 + BYTE CharClass; //+00C + BYTE Unknown2[3]; //+00D + BYTE anim; //+010 + BYTE monanim; //+011 + BYTE seqtrans; //+012 + BYTE seqnum; //+013 + BYTE Unknown7; //+014 + BYTE SelectProc; //+015 + BYTE seqinput; //+016 + BYTE Unknown3; //+017 + WORD itypea1; //+018 + WORD itypea2; //+01A + WORD itypea3; //+01C + WORD itypeb1; //+01E + WORD itypeb2; //+020 + WORD itypeb3; //+022 + WORD etypea1; //+024 + WORD etypea2; //+026 + WORD etypeb1; //+028 + WORD etypeb2; //+02A + WORD srvstfunc; //+02C + WORD srvdofunc; //+02E + WORD srvprgfunc1; //+030 + WORD srvprgfunc2; //+032 + WORD srvprgfunc3; //+034 + WORD Unknown8; //+036 + DWORD prgcalc1; //+038 + DWORD prgcalc2; //+03C + DWORD prgcalc3; //+040 + WORD prgdam; //+044 + WORD srvmissile; //+046 + WORD srvmissilea; //+048 + WORD srvmissileb; //+04A + WORD srvmissilec; //+04C + WORD srvoverlay; //+04E + DWORD aurafilter; //+050 + WORD aurastat1; //+054 + WORD aurastat2; //+056 + WORD aurastat3; //+058 + WORD aurastat4; //+05A + WORD aurastat5; //+05C + WORD aurastat6; //+05E + DWORD auralencalc; //+060 + DWORD aurarangecalc; //+064 + DWORD aurastatcalc1; //+068 + DWORD aurastatcalc2; //+06C + DWORD aurastatcalc3; //+070 + DWORD aurastatcalc4; //+074 + DWORD aurastatcalc5; //+078 + DWORD aurastatcalc6; //+07C + WORD aurastate; //+080 + WORD auratargetstate; //+082 + WORD auraevent1; //+084 + WORD auraevent2; //+086 + WORD auraevent3; //+088 + WORD auraeventfunc1; //+08A + WORD auraeventfunc2; //+08C + WORD auraeventfunc3; //+08E + WORD auratgtevent; //+090 + WORD auratgteventfunc; //+092 + WORD passivestate; //+094 + WORD passiveitype; //+096 + WORD passivestat1; //+098 + WORD passivestat2; //+09A + WORD passivestat3; //+09C + WORD passivestat4; //+09E + WORD passivestat5; //+0A0 + DWORD passivecalc1; //+0A4 + DWORD passivecalc2; //+0A8 + DWORD passivecalc3; //+0AC + DWORD passivecalc4; //+0B0 + DWORD passivecalc5; //+0B4 + WORD passiveevent; //+0B8 + WORD passiveeventfunc; //+0BA + WORD summon; //+0BC + BYTE pettype; //+0BE + BYTE summode; //+0BF + DWORD petmax; //+0C0 + WORD sumskill1; //+0C4 + WORD sumskill2; //+0C6 + WORD sumskill3; //+0C8 + WORD sumskill4; //+0CA + WORD sumskill5; //+0CC + DWORD sumskcalc1; //+0D0 + DWORD sumskcalc2; //+0D4 + DWORD sumskcalc3; //+0D8 + DWORD sumskcalc4; //+0DC + DWORD sumskcalc5; //+0E0 + WORD sumumod; //+0E4 + WORD sumoverlay; //+0E6 + WORD cltmissile; //+0E8 + WORD cltmissilea; //+0EA + WORD cltmissileb; //+0EC + WORD cltmissilec; //+0EE + WORD cltmissiled; //+0F0 + WORD cltstfunc; //+0F2 + WORD cltdofunc; //+0F4 + WORD cltprgfunc1; //+0F6 + WORD cltprgfunc2; //+0F8 + WORD cltprgfunc3; //+0FA + WORD stsound; //+0FC + WORD stsoundclass; //+0FE + WORD dosound; //+100 + WORD dosounda; //+102 + WORD dosoundb; //+104 + WORD castoverlay; //+106 + WORD tgtoverlay; //+108 + WORD tgtsound; //+10A + WORD prgoverlay; //+10C + WORD prgsound; //+10E + WORD cltoverlaya; //+110 + WORD cltoverlayb; //+112 + DWORD cltcalc1; //+114 + DWORD cltcalc2; //+118 + DWORD cltcalc3; //+11C + WORD ItemTarget; //+120 + WORD ItemCastSound; //+122 + WORD ItemCastOverlay; //+124 + WORD Unknown4; //+126 + DWORD perdelay; //+128 + WORD maxlvl; //+12C + WORD ResultFlags; //+12E + DWORD HitFlags; //+130 + DWORD HitClass; //+134 + DWORD calc1; //+138 + DWORD calc2; //+13C + DWORD calc3; //+140 + DWORD calc4; //+144 + DWORD Param1; //+148 + DWORD Param2; //+14C + DWORD Param3; //+150 + DWORD Param4; //+154 + DWORD Param5; //+158 + DWORD Param6; //+15C + DWORD Param7; //+160 + DWORD Param8; //+164 + WORD weapsel; //+168 + WORD ItemEffect; //+16A + BYTE ItemCltEffect; //+16C + BYTE ItemTgtDo; //+16D + BYTE ItemCheckStart; //+16E + BYTE ItemCltCheckStart; //+16F + DWORD skpoints; //+170 + WORD reqlevel; //+174 + WORD reqstr; //+176 + WORD reqdex; //+178 + WORD reqint; //+17A + WORD reqvit; //+17C + WORD reqskill1; //+17E + WORD reqskill2; //+180 + WORD reqskill3; //+182 + WORD startmana; //+184 + WORD minmana; //+186 + WORD manashift; //+188 + WORD Mana; //+18A + short LvlMana; //+18C + BYTE Attackrank; //+18E + BYTE LineOfSight; //+18F + DWORD Delay; //+190 + WORD SkillDesc; //+194 + WORD Unknown5; //+196 + DWORD ToHit; //+198 + DWORD LevToHit; //+19C + DWORD ToHitCalc; //+1A0 + BYTE HitShift; //+1A4 + WORD SrcDam; //+1A5 + BYTE Unknown6; //+1A7 + DWORD MinDam; //+1A8 + DWORD MaxDam; //+1AC + DWORD MinLevDam1; //+1B0 + DWORD MinLevDam2; //+1B4 + DWORD MinLevDam3; //+1B8 + DWORD MinLevDam4; //+1BC + DWORD MinLevDam5; //+1C0 + DWORD MaxLevDam1; //+1C4 + DWORD MaxLevDam2; //+1C8 + DWORD MaxLevDam3; //+1CC + DWORD MaxLevDam4; //+1D0 + DWORD MaxLevDam5; //+1D4 + DWORD DmgSymPerCalc; //+1D8 + DWORD EType; //+1DC + DWORD Emin; //+1E0 + DWORD Emax; //+1E4 + DWORD EMinLev1; //+1E8 + DWORD EMinLev2; //+1EC + DWORD EMinLev3; //+1F0 + DWORD EMinLev4; //+1F4 + DWORD EMinLev5; //+1F8 + DWORD EMaxLev1; //+1FC + DWORD EMaxLev2; //+200 + DWORD EMaxLev3; //+204 + DWORD EMaxLev4; //+208 + DWORD EMaxLev5; //+20C + DWORD EDmgSymPerCalc; //+210 + DWORD ELen; //+214 + DWORD ELevLen1; //+218 + DWORD ELevLen2; //+21C + DWORD ELevLen3; //+220 + DWORD ELenSymPerCalc; //+224 + WORD restrict; //+228 + WORD state1; //+22A + WORD state2; //+22C + WORD state3; //+22E + WORD aitype; //+230 + WORD aibonus; //+232 + DWORD CostMult; //+234 + DWORD CostAdd; //+238 +}; +Yohann: thx +Kingpin: /* +usemanaondo +repeat +TgtPlaceCheck +interrupt +leftskill +AttackNoMana +TargetItem +TargetAlly +TargetPet +TargetCorpse +SearchOpenXY +SearchEnemyNear +SearchEnemyXY +TargetableOnly +UseAttackRate +durability +enhanceable +noammo +InGame +scroll +general +periodic +aura +passive +Kick +InTown +prgstack +finishing +progressive +range +warp +weaponsnd +stsounddelay +stsuccessonly +lob +decquant +immediate + +Kingpin: those columns should be there also +*/ + +struct DifficultyLevelsBIN +{ + DWORD resistPenalty; //+00 + BYTE uk1[1]; //+04 +}; + +struct SuperUniqueBIN +{ +}; + +struct MonStatsBIN //size=0x1A8 (424) +{ + BYTE uk1[0x6]; //+00 + WORD monsterNameID; //+06 + BYTE uk2[0x1A0]; //+08 +}; //+1A8 + +struct ItemTypesBIN //size=0xE4 (228) (source : fct of dll) +{ + DWORD code; //+00 + BYTE uk1[0x11]; //+04 + BYTE rare; //+15 + BYTE uk2[0x09]; //+16 + BYTE staffmods; //+1F + BYTE uk3[0xC4]; //+20 +}; //+E4 + +struct AffixBIN //size=0x90 (144) (source : fct of dll) magicsuffix + magicprefix + automagic +{ + char name[0x20]; //+00 + WORD nameCode; //+20 + WORD version; //+22 + DWORD mod1code; //+24 + DWORD mod1param; //+28 + DWORD mod1min; //+2C + DWORD mod1max; //+30 + DWORD mod2code; //+34 + DWORD mod2param; //+38 + DWORD mod2min; //+3C + DWORD mod2max; //+40 + DWORD mod3code; //+44 + DWORD mod3param; //+48 + DWORD mod3min; //+4C + DWORD mod3max; //+50 + BYTE spawnable; //+54 + BYTE uk1[0x1]; //+55 + WORD transformcolor; //+56 + DWORD level; //+58 + DWORD group; //+5C + DWORD maxlevel; //+60 + BYTE rare; //+64 + BYTE levelreq; //+65 + BYTE classspecific; //+66 + BYTE classf; //+67 + BYTE classlevelreq; //+68 + BYTE uk2[0x1]; //+69 + WORD itype1; //+6A + WORD itype2; //+6C + WORD itype3; //+6E + WORD itype4; //+70 + WORD itype5; //+72 + WORD itype6; //+74 + WORD itype7; //+76 + WORD etype1; //+78 + WORD etype2; //+7A + WORD etype3; //+7C + WORD etype4; //+7E + WORD etype5; //+80 + BYTE frequency; //+82 + BYTE uk3[0x1]; //+83 + DWORD divide; //+84 + DWORD multiply; //+88 + DWORD add; //+8C +}; + +struct PropertiesBIN // size=0x2E (46) (source total : fct of dll) +{ + WORD modcode; //+00 + BYTE set1; //+02 + BYTE set2; //+03 + BYTE set3; //+04 + BYTE set4; //+05 + BYTE set5; //+06 + BYTE set6; //+07 + BYTE set7; //+08 + BYTE uk1[0x1]; //+09 + + WORD val1; //+0A + WORD val2; //+0C + WORD val3; //+0E + WORD val4; //+10 + WORD val5; //+12 + WORD val6; //+14 + WORD val7; //+16 + + BYTE func1; //+18 + BYTE func2; //+19 + BYTE func3; //+1A + BYTE func4; //+1B + BYTE func5; //+1C + BYTE func6; //+1D + BYTE func7; //+1E + BYTE uk2[0x1]; //+1F + + WORD stat1; //+20 + WORD stat2; //+22 + WORD stat3; //+24 + WORD stat4; //+26 + WORD stat5; //+28 + WORD stat6; //+2A + WORD stat7; //+2C +}; + + +struct ItemStatCostBIN // size=0x144 (324) (source total : fct of dll) maxline = 0x1FF = 511 +{ + DWORD statID; //+00 + union //+04 + { + DWORD flags; + struct + { + DWORD sendOther:1; //0x00000001 + DWORD signedf:1; //0x00000002 + DWORD damagerelated:1; //0x00000004 + DWORD itemspecific:1; //0x00000008 + DWORD direct:1; //0x00000010 + DWORD fuk1:4; //0x000001E0 + DWORD updateanimrate:1; //0x00000200 + DWORD fmin:1; //0x00000400 + DWORD fcallback:1; //0x00000800 + DWORD saved:1; //0x00001000 + DWORD cvssigned:1; //0x00002000 + DWORD fuk2:18; //0xFFFFC000 + }; + }; + BYTE sendBits; //+08 + BYTE sendParamBits; //+09 + BYTE csvbits; //+0A + BYTE csvparam; //+0B + DWORD divide; //+0C + DWORD multiply; //+10 + DWORD add; //+14 + BYTE valshift; //+18 + BYTE saveBits; //+19 + BYTE saveBits109; //+1A //are only for conversion + BYTE uk2[0x1]; //+1B + DWORD saveAdd; //+1C + DWORD saveAdd109; //+20 //are only for conversion + DWORD saveParamBits; //+24 + BYTE uk3[0x4]; //+28 + DWORD minaccr; //+2C + BYTE encode; //+30 + BYTE uk4[0x1]; //+31 + WORD maxstat; //+32 + WORD descpriority; //+34 + BYTE descfunc; //+36 + BYTE descval; //+37 + WORD descstrpos; //+38 + WORD descstrneg; //+3A + WORD descstr2; //+3C + WORD dgrp; //+3E + BYTE dgrpfunc; //+40 + BYTE dgrpval; //+41 + WORD dgrpstrpos; //+42 + WORD dgrpstrneg; //+44 + WORD dgrpstr2; //+46 + WORD itemevent1; //+48 + WORD itemevent2; //+4A + WORD itemeventfunc1; //+4C + WORD itemeventfunc2; //+4E + BYTE keepzero; //+50 + BYTE uk5[0x3]; //+51 + BYTE op; //+54 + BYTE opParam; //+55 + WORD opStat1; //+58 + WORD opStat2; //+5A + WORD opStat3; //+5C + BYTE uk6[0xE2]; //+5E + DWORD stuff; //+140 +}; + +struct InventoryBIN // size=0xF0 (240) (source total : fct of dll) +{ + DWORD invLeft; //+00 + DWORD invRight; //+04 + DWORD invTop; //+08 + DWORD invBottom; //+0C + BYTE gridX; //+10 + BYTE gridY; //+11 + BYTE uk1[2]; //+12 + DWORD gridLeft; //+14 + DWORD gridRight; //+18 + DWORD gridTop; //+1C + DWORD gridBottom; //+20 + BYTE gridBoxWidth; //+24 + BYTE gridBoxHeight; //+25 + BYTE uk2[2]; //+26 + DWORD rArmLeft; //+28 + DWORD rArmRight; //+2C + DWORD rArmTop; //+30 + DWORD rArmBottom; //+34 + BYTE rArmWidth; //+38 + BYTE rArmHeight; //+39 + BYTE uk3[2]; //+3A + DWORD torsoLeft; //+3C + DWORD torsoRight; //+40 + DWORD torsoTop; //+44 + DWORD torsoBottom; //+48 + BYTE torsoWidth; //+4C + BYTE torsoHeight; //+4D + BYTE uk4[2]; //+4E + DWORD lArmLeft; //+50 + DWORD lArmRight; //+54 + DWORD lArmTop; //+58 + DWORD lArmBottom; //+5C + BYTE lArmWidth; //+60 + BYTE lArmHeight; //+61 + BYTE uk5[2]; //+62 + DWORD headLeft; //+64 + DWORD headRight; //+68 + DWORD headTop; //+6C + DWORD headBottom; //+70 + BYTE headWidth; //+74 + BYTE headHeight; //+75 + BYTE uk6[2]; //+76 + DWORD neckLeft; //+78 + DWORD neckRight; //+7C + DWORD neckTop; //+80 + DWORD neckBottom; //+84 + BYTE neckWidth; //+88 + BYTE neckHeight; //+89 + BYTE uk7[2]; //+8A + DWORD rHandLeft; //+8C + DWORD rHandRight; //+90 + DWORD rHandTop; //+94 + DWORD rHandBottom; //+98 + BYTE rHandWidth; //+9C + BYTE rHandHeight; //+9D + BYTE uk8[2]; //+9E + DWORD lHandLeft; //+A0 + DWORD lHandRight; //+A4 + DWORD lHandTop; //+A8 + DWORD lHandBottom; //+AC + BYTE lHandWidth; //+B0 + BYTE lHandHeight; //+B1 + BYTE uk9[2]; //+B2 + DWORD beltLeft; //+B4 + DWORD beltRight; //+B8 + DWORD beltTop; //+BC + DWORD beltBottom; //+C0 + BYTE beltWidth; //+C4 + BYTE beltHeight; //+C5 + BYTE uk10[2]; //+C6 + DWORD feetLeft; //+C8 + DWORD feetRight; //+CC + DWORD feetTop; //+D0 + DWORD feetBottom; //+D4 + BYTE feetWidth; //+D8 + BYTE feetHeight; //+D9 + BYTE uk11[2]; //+DA + DWORD glovesLeft; //+DC + DWORD glovesRight; //+E0 + DWORD glovesTop; //+E4 + DWORD glovesBottom; //+E8 + BYTE glovesWidth; //+EC + BYTE glovesHeight; //+ED + BYTE uk12[2]; //+EE +}; + + +struct DataTables//01EE6A20 * 01FDA2D0 //second comments=1.11 +{ + BYTE uk1[0xA78]; //+000 + MonStatsBIN* monStats; //+A78 //1.11 and 1.10 + BYTE uk2[0x4]; //+A7C + DWORD nbMonStats; //+A80 //1.11 and 1.10 + BYTE uk3[0x108]; //+A84 + SkillDescBIN* skilldesc; //+B8C + BYTE uk4[0x4]; //+B90 + DWORD nbSkilldesc; //+B94 + SkillsBIN* skills; //+B98 + BYTE uk5[0x4]; //+B9C + DWORD nbSkills; //+BA0 + int* nbSkillsPerPlayer; //+BA4 + int maxSkillsPerPlayer; //+BA8 + WORD* playerSkills; //+BAC + BYTE uk6[0x14]; //+BB0 + CharStatsBIN* charStats; //+BC4 + DWORD nbCharStats; //+BC8 + ItemStatCostBIN* itemStatCost; //+BCC + BYTE uk7[4]; //+BD0 + DWORD nbItemStatCosts; //+BD4 + WORD* statsDescPriority; //+BD8 + DWORD nbStatsDescPriority;//+BDC + BYTE uk8[0x18]; //+BE0 + ItemTypesBIN* itemTypes; //+BF8 + DWORD nbItemTypes; //+BFC + BYTE uk9[0x18]; //+C00 + SetItemsBIN* setItems; //+C18 //1.11 and 1.10 + DWORD nbSetItems; //+C1C //1.11 and 1.10 + BYTE uk10[0x4]; //+C20 + UniqueItemsBIN* uniqueItems; //+C24 //1.11 and 1.10 + DWORD nbUniqueItems; //+C28 //1.11 and 1.10 + BYTE uk11[0x2C]; //+C2C + LevelsBIN* levels; //+C58 + DWORD nbLevels; //+C5C + BYTE uk12[0x64]; //+C60 + CubeMainBIN* cubemain; //+CC4 //14C0 by 148 for 1.11 + DWORD nbCubemain; //+CC8 //14C4 for 1.11 + DWORD nbInventory; //+CCC + InventoryBIN* inventory; //+CD0 + BYTE uk13[0x04]; //+CD4 + DWORD nbItems; //+CD8 + ItemsBIN* items; //+CDC + ItemsBIN* itemsBis; //+CE0 + BYTE uk14[0x1F8]; //+CDC + DWORD nbRunes; //+EDC + RunesBIN* runes; //+EE0 +}; + + +/* NEXT NOT TESTED IN 1.10 (1.09b) + +struct AffixTxt +{ + BYTE mName[0x21]; // +00 + WORD mVersion; // +22 + DWORD mMod1code; // +24 + DWORD mMod1param; // +28 + DWORD mMod1min; // +2c + DWORD mMod1max; // +30 + DWORD mMod2code; // +34 + DWORD mMod2param; // +38 + DWORD mMod2min; // +3c + DWORD mMod2max; // +40 + DWORD mMod3code; // +44 + DWORD mMod3param; // +48 + DWORD mMod3min; // +4c + DWORD mMod3max; // +50 + WORD mSpawnable; // +54 + WORD mTransformcolor; // +56 + DWORD mLevel; // +58 + DWORD mGroup; // +5c + DWORD mMaxlevel; // +60 + BYTE mRare; // +64 + BYTE mLevelreq; // +65 + BYTE mClassspecific; // +66 + BYTE mClass; // +67 + BYTE classlevelreq; // +68 + BYTE itype1; // +69 + BYTE itype2; // +6a + BYTE itype3; // +6b + BYTE itype4; // +6c + BYTE itype5; // +6d + BYTE itype6; // +6e + BYTE itype7; // +6f + BYTE etype1; // +70 + BYTE etype2; // +71 + BYTE etype3; // +72 + BYTE etype4; // +73 + BYTE etype5; // +74 + DWORD frequency; // +75 + DWORD mDivide; // +79 + DWORD mMultiply; // +7D + DWORD mAdd; // +81 +}; + +struct AffixTxtTable +{ + DWORD mNbAffix; // +00 = total affixes + AffixTxt* mStartTable; // +04 = beginnig ptr + AffixTxt* mSuffixTable; // +08 = suffix.txt ptr + AffixTxt* mPrefixTable; // +0c = prefix.txt ptr + AffixTxt* mAutomagicTable; // +10 = automagic.txt ptr +}; +*/ + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/Commons/d2StringTblStruct.h b/Commons/d2StringTblStruct.h new file mode 100644 index 0000000..a8c5ad7 --- /dev/null +++ b/Commons/d2StringTblStruct.h @@ -0,0 +1,43 @@ +/*================================================================= + File created by Yohann NICOLAS. + + @brief Diablo II Tbl Structures definitions. + +=================================================================*/ + +#pragma once + +#include + +#pragma pack(1) + +struct TblHeader +{ + WORD usCRC; // +00 + WORD NumElementsOffset; // +02 + DWORD HashTableSizeOffset; // +04 + BYTE VersionOffset; // +08 + DWORD IndexStart; // +09 + DWORD NumLoopsOffset; // +0D + DWORD IndexEnd; // +11 (FileLen) +}; + +struct TblNode +{ + BYTE ActiveOffset; // +00 + WORD KeyIndex; // +01 + DWORD HashValueOffset; // +03 + DWORD KeyOffset; // +07 + DWORD StringOffset; // +0B + WORD StringLength; // +0F +}; + + + + +#pragma pack() + +//#define TBLHEADERSIZE 0x15 +//#define TBLNODESIZE 0x11 + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/Commons/d2Struct.h b/Commons/d2Struct.h new file mode 100644 index 0000000..dad360c --- /dev/null +++ b/Commons/d2Struct.h @@ -0,0 +1,118 @@ +/*================================================================= + File created by Yohann NICOLAS. + + NOT TESTED IN 1.10 (1.09b) + +=================================================================*/ + +#pragma once + +#include +struct Unit; +struct Game; +struct Room; + +#pragma pack(1) +struct sWinMessage +{ + void* msg; + DWORD type; + DWORD uk1; + WORD x; + WORD y; + DWORD uk3; + DWORD uk4; + DWORD managed; + DWORD unmanaged; +}; +#pragma pack() + +/* +struct sDrawImageInfo//size = 0x48 (until 1.10) +{ + void* reserved; + void* image; + DWORD frame; + DWORD zero[0xF]; +};*/ + +struct sDrawImageInfo//size = 0x48 +{ + DWORD uk1; + DWORD uk2; + void* image; + DWORD uk3; + DWORD uk4; + void* reserved; + DWORD uk5[0xB]; + DWORD frame; +}; + + +struct saveBitField +{ + BYTE* data; + DWORD maxBits; + DWORD currentByte; + DWORD currentBit; + DWORD overflaw; +}; + +struct BINField +{ + char* fieldName; + int type; + DWORD strLength; + DWORD offset; + void* lookup; +}; + +struct ItemGenerationData //size=0x84 +{ + Unit* ptMonster; //+00 + BYTE uk1[0x04]; //+04 + Game* ptGame; //+08 + DWORD ilvl; //+0C + BYTE uk2[0x04]; //+10 + DWORD nTxtFileNo; //+14 + DWORD unknow1; //+18 + DWORD x; //+1C + DWORD y; //+20 + Room* ptRoom; //+24 + WORD unknow2; //+28 + WORD gameUnknown2; //+2A + BYTE uk3[0x04]; //+2C + DWORD quality; //+30 + BYTE uk4[0x34]; //+34 + int prefixID[3]; //+68 (-1: no prefix; 0:random prefix) + int suffixID[3]; //+74 (-1: no suffix; 0:random suffix) + union { //+80 + DWORD flags; + struct { + DWORD fuk1:5; //0x0000001F + DWORD unknow3:1; //0x00000020 + }; + }; +}; + + +/*=================================================================*/ +/* Data Structure to Update Client */ +/*=================================================================*/ +struct DataPacket +{ + BYTE mType; // +00 Packet Type + BYTE mFunc; // +02 Function to Call + BYTE mSize; // +04 Size of the Packet + DWORD mReserved; // +06 Used with items + BYTE mUnitType; // +0A Always '0' + DWORD mPlayerID; // +0C The Player ID (ptUnit + 08h) + DWORD mItemID; // +10 The Item ID + DWORD mMod1_ID; // +14 The Stat/Mod ID + DWORD mParam1; // +18 3 Paramters + DWORD mParam2; // +1C + DWORD mParam3; // +20 +}; + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/Commons/d2constants.h b/Commons/d2constants.h new file mode 100644 index 0000000..04a90ad --- /dev/null +++ b/Commons/d2constants.h @@ -0,0 +1,843 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Constants of D2 + NOT TESTED IN 1.10 (from 1.09b) + +=================================================================*/ + +#pragma once + +/*==================================================================================*/ +/* + * Constants & Enumerations. + */ +/*==================================================================================*/ + +enum D2TypeSize { D2TS_UNITSIZE = 0x011C }; +enum D2DifficultyModes { D2DM_NORMAL, D2DM_NIGHTMARE, D2DM_HELL }; +enum D2PlayerClass { D2PC_AMAZON, D2PC_SORCERESS, D2PC_NECROMANCER, D2PC_PALADIN, D2PC_BARBARIAN, D2PC_DRUID, D2PC_ASSASSIN }; + +enum D2Color +{ + WHITE=0, + RED=1, + GREEN=2, + BLUE=3, + GOLD=4, + DARK_GRAY=5, +// INVISIBLE=6, + DARK_YELLOW=7, + ORANGE=8, + YELLOW=9, + DARKEST_GREEN=0xA, + PURPLE=0xB, + DARK_GREEN=0xC, +// WHITE_BIS=0xD, +// INVISIBLE2=0xE, + LIGHT_GRAY=0xF, + GRAY=0x10, +// VERY_WIERD=0x11, + BRIGHT_WHITE=0x12, + CRYSTAL_RED=0x13, +// WIERD_YELLOW=0x14 +}; + +enum D2Lang +{ + LNG_ENG=0,// English + LNG_ESP,// Spanish + LNG_DEU,// German + LNG_FRA,// French + LNG_POR,// Portuguese + LNG_ITA,// Italian + LNG_JPN,// Japanese + LNG_KOR,// Korean + LNG_SIN,// + LNG_CHI,// Chinese + LNG_POL,// Polish + LNG_RUS,// Russian + LNG_DEF,// Default : English +}; + + +enum D2GameTypeMode +{ +// MODE_SINGLE = 0, + MODE_CLOSED = 1, + MODE_TCP, + MODE_OPEN, +}; + +enum D2CStat +{ + STATS_STRENGTH = 0, + STATS_ENERGY, + STATS_DEXTERITY, + STATS_VITALITY, + STATS_STATPTS, + STATS_NEWSKILLS, + STATS_HP, + STATS_MAXHP, + STATS_MANA, + STATS_MAXMANA, + STATS_STAMINA, + STATS_MAXSTAMINA, + STATS_LEVEL, + STATS_EXPERIENCE, + STATS_GOLD, + STATS_GOLDBANK, + STATS_ITEM_ARMOR_PERCENT,//0x10 + STATS_ITEM_MAXDAMAGE_PERCENT, + STATS_ITEM_MINDAMAGE_PERCENT, + STATS_TOHIT, + STATS_TOBLOCK, + STATS_MINDAMAGE, + STATS_MAXDAMAGE, + STATS_SECONDARY_MINDAMAGE, + STATS_SECONDARY_MAXDAMAGE, + STATS_DAMAGEPERCENT, + STATS_MANARECOVERY, + STATS_MANARECOVERYBONUS, + STATS_STAMINARECOVERYBONUS, + STATS_LASTEXP, + STATS_NEXTEXP, + STATS_ARMORCLASS, + STATS_ARMORCLASS_VS_MISSILE,//0x20 + STATS_ARMORCLASS_VS_HTH,//0x21 + STATS_NORMAL_DAMAGE_REDUCTION, + STATS_MAGIC_DAMAGE_REDUCTION, + STATS_DAMAGERESIST, + STATS_MAGICRESIST, + STATS_MAXMAGICRESIST, + STATS_FIRERESIST,//0x27 + STATS_MAXFIRERESIST, + STATS_LIGHTRESIST,//0x29 + STATS_MAXLIGHTRESIST, + STATS_COLDRESIST,//0x2B + STATS_MAXCOLDRESIST, + STATS_POISONRESIST, + STATS_MAXPOISONRESIST, + STATS_DAMAGEAURA, + STATS_FIREMINDAM,//0x30 + STATS_FIREMAXDAM, + STATS_LIGHTMINDAM, + STATS_LIGHTMAXDAM, + STATS_MAGICMINDAM, + STATS_MAGICMAXDAM, + STATS_COLDMINDAM, + STATS_COLDMAXDAM, + STATS_COLDLENGTH, + STATS_POISONMINDAM, + STATS_POISONMAXDAM, + STATS_POISONLENGTH, + STATS_LIFEDRAINMINDAM, + STATS_LIFEDRAINMAXDAM, + STATS_MANADRAINMINDAM, + STATS_MANADRAINMAXDAM, + STATS_STAMDRAINMINDAM,//0x40 + STATS_STAMDRAINMAXDAM, + STATS_STUNLENGTH, + STATS_VELOCITYPERCENT, + STATS_ATTACKRATE, + STATS_OTHER_ANIMRATE, + STATS_QUANTITY, + STATS_VALUE, + STATS_DURABILITY, + STATS_MAXDURABILITY, + STATS_HPREGEN, + STATS_ITEM_MAXDURABILITY_PERCENT, + STATS_ITEM_MAXHP_PERCENT, + STATS_ITEM_MAXMANA_PERCENT, + STATS_ITEM_ATTACKERTAKESDAMAGE, + STATS_ITEM_GOLDBONUS, + STATS_ITEM_MAGICBONUS,//0x50 + STATS_ITEM_KNOCKBACK, + STATS_ITEM_TIMEDURATION, + STATS_ITEM_ADDCLASSSKILLS, //STATS_ITEM_ADDAMASKILLPOINTS + STATS_UNSENTPARAM1, //STATS_ITEM_ADDPALSKILLPOINTS + STATS_ADDEXPERIENCE, //STATS_ITEM_ADDNECSKILLPOINTS + STATS_HEALAFTERKILL, //STATS_ITEM_ADDSORSKILLPOINTS + STATS_REDUCESPRICES, //STATS_ITEM_ADDBARSKILLPOINTS + STATS_ITEM_DOUBLEHERBDURATION, + STATS_ITEM_LIGHTRADIUS, + STATS_ITEM_LIGHTCOLOR, + STATS_ITEM_REQ_PERCENT, + STATS_LEVELREQ, //STATS_ITEM_FASTATTACKRATE + STATS_ITEM_FASTERATTACKRATE, + STATS_ITEM_LEVELREQPCT, //STATS_ITEM_FASTESTATTACKRATE, + STATS_LASTBLOCKFRAME, //STATS_ITEM_FASTMOVEVELOCITY, + STATS_ITEM_FASTERMOVEVELOCITY,//0x60 + STATS_NONCLASSKILL, //STATS_ITEM_FASTESTMOVEVELOCITY, + STATS_STATE, //STATS_ITEM_FASTGETHITRATE, + STATS_ITEM_FASTERGETHITRATE, + STATS_MONSTER_PLAYERCOUNT, //STATS_ITEM_FASTESTGETHITRATE, + STATS_SKILL_POISON_OVERRIDE_LENGTH, //STATS_ITEM_FASTBLOCKRATE, + STATS_ITEM_FASTERBLOCKRATE, + STATS_SKILL_BYPASS_UNDEAD, //STATS_ITEM_FASTESTBLOCKRATE, + STATS_SKILL_BYPASS_DEMONS, //STATS_ITEM_FASTCASTRATE, + STATS_ITEM_FASTERCASTRATE, + STATS_SKILL_BYPASS_BEASTS, //STATS_ITEM_FASTESTCASTRATE, + STATS_ITEM_SINGLESKILL, //STATS_ITEM_SINGLESKILL1, + STATS_ITEM_RESTINPEACE, //STATS_ITEM_SINGLESKILL2, + STATS_CURSE_RESISTANCE, //STATS_ITEM_SINGLESKILL3, + STATS_ITEM_POISONLENGTHRESIST, + STATS_ITEM_NORMALDAMAGE, + STATS_ITEM_HOWL,//0x70 + STATS_ITEM_STUPIDITY, + STATS_ITEM_DAMAGETOMANA, + STATS_ITEM_IGNORETARGETAC, + STATS_ITEM_FRACTIONALTARGETAC, + STATS_ITEM_PREVENTHEAL, + STATS_ITEM_HALFFREEZEDURATION, + STATS_ITEM_TOHIT_PERCENT, + STATS_ITEM_DAMAGETARGETAC, + STATS_ITEM_DEMONDAMAGE_PERCENT, + STATS_ITEM_UNDEADDAMAGE_PERCENT, + STATS_ITEM_DEMON_TOHIT, + STATS_ITEM_UNDEAD_TOHIT, + STATS_ITEM_THROWABLE, + STATS_ITEM_ELEMSKILL, //STATS_ITEM_FIRESKILL, + STATS_ITEM_ALLSKILLS, + STATS_ITEM_ATTACKERTAKESLIGHTDAMAGE,//0x80 + STATS_IRONMAIDEN_LEVEL, + STATS_LIFETAP_LEVEL, + STATS_THORNS_LEVEL, + STATS_BONEARMOR, + STATS_BONEARMORMAX, + STATS_ITEM_FREEZE, + STATS_ITEM_OPENWOUNDS, + STATS_ITEM_CRUSHINGBLOW, + STATS_ITEM_KICKDAMAGE, + STATS_ITEM_MANAAFTERKILL, + STATS_ITEM_HEALAFTERDEMONKILL, + STATS_ITEM_EXTRABLOOD, + STATS_ITEM_DEADLYSTRIKE, + STATS_ITEM_ABSORBFIRE_PERCENT, + STATS_ITEM_ABSORBFIRE, + STATS_ITEM_ABSORBLIGHT_PERCENT, + STATS_ITEM_ABSORBLIGHT, + STATS_ITEM_ABSORBMAGIC_PERCENT, + STATS_ITEM_ABSORBMAGIC, + STATS_ITEM_ABSORBCOLD_PERCENT, + STATS_ITEM_ABSORBCOLD, + STATS_ITEM_SLOW, + STATS_ITEM_AURA, //STATS_ITEM_BLESSEDAIM, + STATS_ITEM_INDESTRUCTIBLE, //STATS_ITEM_DEFIANCE, + STATS_ITEM_CANNOTBEFROZEN, + STATS_ITEM_STAMINADRAINPCT, + STATS_ITEM_REANIMATE, + STATS_ITEM_PIERCE, + STATS_ITEM_MAGICARROW, + STATS_ITEM_EXPLOSIVEARROW, + STATS_ITEM_THROW_MINDAMAGE, + STATS_ITEM_THROW_MAXDAMAGE, + STATS_SKILL_HANDOFATHENA, + STATS_SKILL_STAMINAPERCENT, + STATS_SKILL_PASSIVE_STAMINAPERCENT, + STATS_SKILL_CONCENTRATION, + STATS_SKILL_ENCHANT, + STATS_SKILL_PIERCE, + STATS_SKILL_CONVICTION, + STATS_SKILL_CHILLINGARMOR, + STATS_SKILL_FRENZY, + STATS_SKILL_DECREPIFY, + STATS_SKILL_ARMOR_PERCENT, + STATS_ALIGNMENT, + STATS_TARGET0, + STATS_TARGET1, + STATS_GOLDLOST, + STATS_CONVERSION_LEVEL, + STATS_CONVERSION_MAXHP, + STATS_UNIT_DOOVERLAY, + STATS_ATTACK_VS_MONTYPE, //STATS_ITEM_ADDDRUSKILLPOINTS, + STATS_DAMAGE_VS_MONTYPE, //STATS_ITEM_ADDASSSKILLPOINTS, + STATS_FADE, //STATS_ITEM_ADDSKILL_SINGLE4, + STATS_ARMOR_OVERRIDE_PERCENT, //STATS_ITEM_ADDSKILL_SINGLE5, + STATS_UNUSED183, //STATS_ITEM_ADDSKILL_SINGLE6, + STATS_UNUSED184, //STATS_ITEM_ADDSKILL_SINGLE7, + STATS_UNUSED185, //STATS_ITEM_ADDSKILL_SINGLE8, + STATS_UNUSED186, //STATS_ITEM_ADDSKILL_SINGLE9, + STATS_UNUSED187, //STATS_ITEM_ADDSKILL_SINGLE10, + STATS_ADDSKILL_TAB, //STATS_ITEM_ADDSKILL_TAB1, + STATS_UNUSED189, //STATS_ITEM_ADDSKILL_TAB2, + STATS_UNUSED190, //STATS_ITEM_ADDSKILL_TAB3, + STATS_UNUSED191, //STATS_ITEM_ADDSKILL_TAB4, + STATS_UNUSED192, //STATS_ITEM_ADDSKILL_TAB5, + STATS_UNUSED193, //STATS_ITEM_ADDSKILL_TAB6, + STATS_ITEM_NUMSOCKETS, + STATS_ITEM_SKILLONATTACK, //STATS_ITEM_SKILLONATTACK1, + STATS_ITEM_SKILLONKILL, //STATS_ITEM_SKILLONATTACK2, + STATS_ITEM_SKILLONDEATH, //STATS_ITEM_SKILLONATTACK3, + STATS_ITEM_SKILLONHIT, //STATS_ITEM_SKILLONHIT1, + STATS_ITEM_SKILLONLEVELUP, //STATS_ITEM_SKILLONHIT2, + STATS_UNUSED200, //STATS_ITEM_SKILLONHIT3, + STATS_ITEM_SKILLONGETHIT, //STATS_ITEM_SKILLONGETHIT1, + STATS_UNUSED202, //STATS_ITEM_SKILLONGETHIT2, + STATS_UNUSED203, //STATS_ITEM_SKILLONGETHIT3, + STATS_ITEM_CHARGED_SKILL, //STATS_ITEM_CHARGED_SKILL0, + STATS_UNUSED205, //STATS_ITEM_CHARGED_SKILL1, + STATS_UNUSED206, //STATS_ITEM_CHARGED_SKILL2, + STATS_UNUSED207, //STATS_ITEM_CHARGED_SKILL3, + STATS_UNUSED208, //STATS_ITEM_CHARGED_SKILL4, + STATS_UNUSED209, //STATS_ITEM_CHARGED_SKILL5, + STATS_UNUSED210, //STATS_ITEM_CHARGED_SKILL6, + STATS_UNUSED211, //STATS_ITEM_CHARGED_SKILL7, + STATS_UNUSED212, //STATS_ITEM_CHARGED_SKILL8, + STATS_UNUSED213, //STATS_ITEM_CHARGED_SKILL9, + STATS_ITEM_ARMOR_PERLEVEL, + STATS_ITEM_ARMORPERCENT_PERLEVEL, + STATS_ITEM_HP_PERLEVEL, + STATS_ITEM_MANA_PERLEVEL, + STATS_ITEM_MAXDAMAGE_PERLEVEL, + STATS_ITEM_MAXDAMAGE_PERCENT_PERLEVEL, + STATS_ITEM_STRENGTH_PERLEVEL, + STATS_ITEM_DEXTERITY_PERLEVEL, + STATS_ITEM_ENERGY_PERLEVEL, + STATS_ITEM_VITALITY_PERLEVEL, + STATS_ITEM_TOHIT_PERLEVEL, + STATS_ITEM_TOHITPERCENT_PERLEVEL, + STATS_ITEM_COLD_DAMAGEMAX_PERLEVEL, + STATS_ITEM_FIRE_DAMAGEMAX_PERLEVEL, + STATS_ITEM_LTNG_DAMAGEMAX_PERLEVEL, + STATS_ITEM_POIS_DAMAGEMAX_PERLEVEL, + STATS_ITEM_RESIST_COLD_PERLEVEL, + STATS_ITEM_RESIST_FIRE_PERLEVEL, + STATS_ITEM_RESIST_LTNG_PERLEVEL, + STATS_ITEM_RESIST_POIS_PERLEVEL, + STATS_ITEM_ABSORB_COLD_PERLEVEL, + STATS_ITEM_ABSORB_FIRE_PERLEVEL, + STATS_ITEM_ABSORB_LTNG_PERLEVEL, + STATS_ITEM_ABSORB_POIS_PERLEVEL, + STATS_ITEM_THORNS_PERLEVEL, + STATS_ITEM_FIND_GOLD_PERLEVEL, + STATS_ITEM_FIND_MAGIC_PERLEVEL, + STATS_ITEM_REGENSTAMINA_PERLEVEL, + STATS_ITEM_STAMINA_PERLEVEL, + STATS_ITEM_DAMAGE_DEMON_PERLEVEL, + STATS_ITEM_DAMAGE_UNDEAD_PERLEVEL, + STATS_ITEM_TOHIT_DEMON_PERLEVEL, + STATS_ITEM_TOHIT_UNDEAD_PERLEVEL, + STATS_ITEM_CRUSHINGBLOW_PERLEVEL, + STATS_ITEM_OPENWOUNDS_PERLEVEL, + STATS_ITEM_KICK_DAMAGE_PERLEVEL, + STATS_ITEM_DEADLYSTRIKE_PERLEVEL, + STATS_ITEM_FIND_GEMS_PERLEVEL, + STATS_ITEM_REPLENISH_DURABILITY, + STATS_ITEM_REPLENISH_QUANTITY, + STATS_ITEM_EXTRA_STACK, + STATS_ITEM_FIND_ITEM, + STATS_ITEM_SLASH_DAMAGE, + STATS_ITEM_SLASH_DAMAGE_PERCENT, + STATS_ITEM_CRUSH_DAMAGE, + STATS_ITEM_CRUSH_DAMAGE_PERCENT, + STATS_ITEM_THRUST_DAMAGE, + STATS_ITEM_THRUST_DAMAGE_PERCENT, + STATS_ITEM_ABSORB_SLASH, + STATS_ITEM_ABSORB_CRUSH, + STATS_ITEM_ABSORB_THRUST, + STATS_ITEM_ABSORB_SLASH_PERCENT, + STATS_ITEM_ABSORB_CRUSH_PERCENT, + STATS_ITEM_ABSORB_THRUST_PERCENT, + STATS_ITEM_ARMOR_BYTIME, + STATS_ITEM_ARMORPERCENT_BYTIME, + STATS_ITEM_HP_BYTIME, + STATS_ITEM_MANA_BYTIME, + STATS_ITEM_MAXDAMAGE_BYTIME, + STATS_ITEM_MAXDAMAGE_PERCENT_BYTIME, + STATS_ITEM_STRENGTH_BYTIME, + STATS_ITEM_DEXTERITY_BYTIME, + STATS_ITEM_ENERGY_BYTIME, + STATS_ITEM_VITALITY_BYTIME, + STATS_ITEM_TOHIT_BYTIME, + STATS_ITEM_TOHITPERCENT_BYTIME, + STATS_ITEM_COLD_DAMAGEMAX_BYTIME, + STATS_ITEM_FIRE_DAMAGEMAX_BYTIME, + STATS_ITEM_LTNG_DAMAGEMAX_BYTIME, + STATS_ITEM_POIS_DAMAGEMAX_BYTIME, + STATS_ITEM_RESIST_COLD_BYTIME, + STATS_ITEM_RESIST_FIRE_BYTIME, + STATS_ITEM_RESIST_LTNG_BYTIME, + STATS_ITEM_RESIST_POIS_BYTIME, + STATS_ITEM_ABSORB_COLD_BYTIME, + STATS_ITEM_ABSORB_FIRE_BYTIME, + STATS_ITEM_ABSORB_LTNG_BYTIME, + STATS_ITEM_ABSORB_POIS_BYTIME, + STATS_ITEM_FIND_GOLD_BYTIME, + STATS_ITEM_FIND_MAGIC_BYTIME, + STATS_ITEM_REGENSTAMINA_BYTIME, + STATS_ITEM_STAMINA_BYTIME, + STATS_ITEM_DAMAGE_DEMON_BYTIME, + STATS_ITEM_DAMAGE_UNDEAD_BYTIME, + STATS_ITEM_TOHIT_DEMON_BYTIME, + STATS_ITEM_TOHIT_UNDEAD_BYTIME, + STATS_ITEM_CRUSHINGBLOW_BYTIME, + STATS_ITEM_OPENWOUNDS_BYTIME, + STATS_ITEM_KICK_DAMAGE_BYTIME, + STATS_ITEM_DEADLYSTRIKE_BYTIME, + STATS_ITEM_FIND_GEMS_BYTIME, + STATS_ITEM_PIERCE_COLD, + STATS_ITEM_PIERCE_FIRE, + STATS_ITEM_PIERCE_LTNG, + STATS_ITEM_PIERCE_POIS, + STATS_ITEM_DAMAGE_VS_MONSTER, + STATS_ITEM_DAMAGE_PERCENT_VS_MONSTER, + STATS_ITEM_TOHIT_VS_MONSTER, + STATS_ITEM_TOHIT_PERCENT_VS_MONSTER, + STATS_ITEM_AC_VS_MONSTER, + STATS_ITEM_AC_PERCENT_VS_MONSTER, + STATS_FIRELENGTH, + STATS_BURNINGMIN, + STATS_BURNINGMAX, + STATS_PROGRESSIVE_DAMAGE, + STATS_PROGRESSIVE_STEAL, + STATS_PROGRESSIVE_OTHER, + STATS_PROGRESSIVE_FIRE, + STATS_PROGRESSIVE_COLD, + STATS_PROGRESSIVE_LIGHTNING, + STATS_ITEM_EXTRA_CHARGES, + STATS_PROGRESSIVE_TOHIT, + STATS_POISON_COUNT, + STATS_DAMAGE_FRAMERATE, + STATS_PIERCE_IDX, + STATS_PASSIVE_FIRE_MASTERY,///////////////////////// NEW FOR 1.10 + STATS_PASSIVE_LTNG_MASTERY, + STATS_PASSIVE_COLD_MASTERY, + STATS_PASSIVE_POUS_MASTERY, + STATS_PASSIVE_FIRE_PIERCE, + STATS_PASSIVE_LTNG_PIERCE, + STATS_PASSIVE_COLD_PIERCE, + STATS_PASSIVE_POIS_PIERCE, + STATS_PASSIVE_CRITICAL_STRIKE, + STATS_PASSIVE_DODGE, + STATS_PASSIVE_AVOID, + STATS_PASSIVE_EVADE, + STATS_PASSIVE_WARMTH, + STATS_PASSIVE_MASTERY_MELEE_TH, + STATS_PASSIVE_MASTERY_MELEE_DMG, + STATS_PASSIVE_MASTERY_MELEE_CRIT, + STATS_PASSIVE_MASTERY_THROW_TH, + STATS_PASSIVE_MASTERY_THROW_DMG, + STATS_PASSIVE_MASTERY_THROW_CRIT, + STATS_PASSIVE_WEAPONBLOCK, + STATS_PASSIVE_SUMMON_RESIST, + STATS_MODIFIERLIST_SKILL, + STATS_MODIFIERLIST_LEVEL, + STATS_LAST_SENT_HP_PCT, + STATS_SOURCE_UNIT_TYPE, + STATS_SOURCE_UNIT_ID, + STATS_SHORTPARAM1, + STATS_QUESTITEMDIFFICULTY, + STATS_PASSIVE_MAG_MASTERY, + STATS_PASSIVE_MAG_PIERCE +}; + +enum D2Mod +{ + ARMORCLASS = 0, + ARMORCLASS_VS_MISSILE, + ARMORCLASS_VS_HTH, + NORMAL_DAMAGE_REDUCTION, + NORMAL_DAMAGE_REDUCTION_PCT, + ARMOR_PERCENT, + MAGIC_DAMAGE_REDUCTION, + STRENGTH, + DEXTERITY, + VITALITY, + ENERGY, + MAXMANA, + MAXMANA_PERCENT, + MAXHP, + MAXHP_PERCENT, + TOHIT, + TOBLOCK, + COLDMINDAM, + COLDMAXDAM, + COLDLENGTH, + FIREMINDAM, + FIREMAXDAM, + LIGHTMINDAM, + LIGHTMAXDAM, + POISONMINDAM, + POISONMAXDAM, + POISONLENGTH, + MINDAMAGE, + MAXDAMAGE, + WEAPONDAMAGE_PERCENT, + DAMAGETOMANA, + FIRERESIST, + MAXFIRERESIST, + LIGHTRESIST, + MAXLIGHTRESIST, + COLDRESIST, + MAXCOLDRESIST, + MAGICRESIST, + MAXMAGICRESIST, + POISONRESIST, + MAXPOISONRESIST, + RESISTALL, + MAXRESISTALL, + ASBORBFIRE_PERCENT, + ASBORBFIRE, + ASBORBLIGHT_PERCENT, + ASBORBLIGHT, + ASBORBMAGIC_PERCENT, + ASBORBMAGIC, + ASBORBCOLD_PERCENT, + ASBORBCOLD, + MAXDURABILITY, + MAXDURABILITY_PERCENT, + HITPOINTS_DELTA, + ATTACKERTAKES_DAMAGE, + FASTATTACKRATE, + FASTERATTACKRATE, + FASTESTATTACKRATE, + GOLDBONUS, + MAGICBONUS, + KNOCKBACK, + REGENSTAMINA_PERCENT, + REGENMANA_PERCENT, + BASESTAMINA, + TIMEDURATION, + MANASTEAL, + LIFESTEAL, + ADDAMASKILLPOINTS, + ADDPALSKILLPOINTS, + ADDNECSKILLPOINTS, + ADDSORSKILLPOINTS, + ADDBARSKILLPOINTS, + DOUBLEHERBDURATION, + LIGHTRADIUS, + LIGHTCOLOR, + REQ_PERCENT, + FASTMOVEVELOCITY, + FASTERMOVEVELOCITY, + FASTESTMOVEVELOCITY, + FASTGETHITRATE, + FASTERGETHITRATE, + FASTESTGETHITRATE, + FASTBLOCKRATE, + FASTERBLOCKRATE, + FASTESTBLOCKRATE, + FASTCASTRATE, + FASTERCASTRATE, + FASTESTCASTRATE, + POISONLENGTHRESIST, + NORMALDAMAGE, + HOWL, + STUPIDITY, + IGNORETARGETAC, + FRACTIONALTARGETAC, + PREVENTHEAL, + HALFFREEZEDURATION, + TOHIT_PERCENT, + DAMAGETARGETAC, + DEMONDAMAGE_PERCENT, + UNDEADDAMAGE_PERCENT, + DEMON_TOHIT, + UNDEAD_TOHIT, + THROWABLE, + FIRESKILL, + ALLSKILLS, + ATTACKERTAKESLIGHT_DAMAGE, + FREEZE, + OPENWOUNDS, + CRUSHINGBLOW, + KICKDAMAGE, + MANAAFTERKILL, + HEALAFTERDEMONKILL, + EXTRABLOOD, + DEADLYSTRIKE, + SLOW, + CANNOTBEFROZEN, + STAMINADRAINPCT, + REANIMATE, + PIERCE, + MAGICARROW, + EXPLOSIVEARROW, + ADDDRUSKILLPOINTS, + ADDASSSKILLPOINTS, + ADDSKILL, + ADDTAB, + ADDSKILL_PASSIVES, + SKILL_ON_ATTACK, + SKILL_ON_HIT, + SKILL_ON_GETHIT, + GEMBONUS, + DURABILITY_OVER_TIME, + FIRE_EFFECTS, + LIGHTNING_EFFECTS, + SOCKETS, + FIRE_DAMAGE_MINMAX, + LIGHT_DAMAGE_MINMAX, + MAGIC_DAMAGE_MINMAX, + COLD_DAMAGE_MINMAXLEN, + POIS_DAMAGE_MINMAXLEN, + THROW_DAMAGE_MINMAX, + DAMAGE_MINMAX, + STATS_ITEM_ARMOR_PERLEVEL_MOD, + STATS_ITEM_ARMORPERCENT_PERLEVEL_MOD, + STATS_ITEM_HP_PERLEVEL_MOD, + STATS_ITEM_MANA_PERLEVEL_MOD, + STATS_ITEM_MAXDAMAGE_PERLEVEL_MOD, + STATS_ITEM_MAXDAMAGE_PERCENT_PERLEVEL_MOD, + STATS_ITEM_STRENGTH_PERLEVEL_MOD, + STATS_ITEM_DEXTERITY_PERLEVEL_MOD, + STATS_ITEM_ENERGY_PERLEVEL_MOD, + STATS_ITEM_VITALITY_PERLEVEL_MOD, + STATS_ITEM_TOHIT_PERLEVEL_MOD, + STATS_ITEM_TOHITPERCENT_PERLEVEL_MOD, + STATS_ITEM_COLD_DAMAGEMAX_PERLEVEL_MOD, + STATS_ITEM_FIRE_DAMAGEMAX_PERLEVEL_MOD, + STATS_ITEM_LTNG_DAMAGEMAX_PERLEVEL_MOD, + STATS_ITEM_POIS_DAMAGEMAX_PERLEVEL_MOD, + STATS_ITEM_RESIST_COLD_PERLEVEL_MOD, + STATS_ITEM_RESIST_FIRE_PERLEVEL_MOD, + STATS_ITEM_RESIST_LTNG_PERLEVEL_MOD, + STATS_ITEM_RESIST_POIS_PERLEVEL_MOD, + STATS_ITEM_ABSORB_COLD_PERLEVEL_MOD, + STATS_ITEM_ABSORB_FIRE_PERLEVEL_MOD, + STATS_ITEM_ABSORB_LTNG_PERLEVEL_MOD, + STATS_ITEM_ABSORB_POIS_PERLEVEL_MOD, + STATS_ITEM_THORNS_PERLEVEL_MOD, + STATS_ITEM_FIND_GOLD_PERLEVEL_MOD, + STATS_ITEM_FIND_MAGIC_PERLEVEL_MOD, + STATS_ITEM_REGENSTAMINA_PERLEVEL_MOD, + STATS_ITEM_STAMINA_PERLEVEL_MOD, + STATS_ITEM_DAMAGE_DEMON_PERLEVEL_MOD, + STATS_ITEM_DAMAGE_UNDEAD_PERLEVEL_MOD, + STATS_ITEM_TOHIT_DEMON_PERLEVEL_MOD, + STATS_ITEM_TOHIT_UNDEAD_PERLEVEL_MOD, + STATS_ITEM_CRUSHINGBLOW_PERLEVEL_MOD, + STATS_ITEM_OPENWOUNDS_PERLEVEL_MOD, + STATS_ITEM_KICK_DAMAGE_PERLEVEL_MOD, + STATS_ITEM_DEADLYSTRIKE_PERLEVEL_MOD, + STATS_ITEM_FIND_GEMS_PERLEVEL_MOD, + STATS_ITEM_REPLENISH_DURABILITY_MOD, + STATS_ITEM_REPLENISH_QUANTITY_MOD, + STATS_ITEM_EXTRA_STACK_MOD, + STATS_ITEM_FIND_ITEM_MOD, + STATS_ITEM_SLASH_DAMAGE_MOD, + STATS_ITEM_SLASH_DAMAGE_PERCENT_MOD, + STATS_ITEM_CRUSH_DAMAGE_MOD, + STATS_ITEM_CRUSH_DAMAGE_PERCENT_MOD, + STATS_ITEM_THRUST_DAMAGE_MOD, + STATS_ITEM_THRUST_DAMAGE_PERCENT_MOD, + STATS_ITEM_ABSORB_SLASH_MOD, + STATS_ITEM_ABSORB_CRUSH_MOD, + STATS_ITEM_ABSORB_THRUST_MOD, + STATS_ITEM_ABSORB_SLASH_PERCENT_MOD, + STATS_ITEM_ABSORB_CRUSH_PERCENT_MOD, + STATS_ITEM_ABSORB_THRUST_PERCENT_MOD, + STATS_ITEM_ARMOR_BYTIME_MOD, + STATS_ITEM_ARMORPERCENT_BYTIME_MOD, + STATS_ITEM_HP_BYTIME_MOD, + STATS_ITEM_MANA_BYTIME_MOD, + STATS_ITEM_MAXDAMAGE_BYTIME_MOD, + STATS_ITEM_MAXDAMAGE_PERCENT_BYTIME_MOD, + STATS_ITEM_STRENGTH_BYTIME_MOD, + STATS_ITEM_DEXTERITY_BYTIME_MOD, + STATS_ITEM_ENERGY_BYTIME_MOD, + STATS_ITEM_VITALITY_BYTIME_MOD, + STATS_ITEM_TOHIT_BYTIME_MOD, + STATS_ITEM_TOHITPERCENT_BYTIME_MOD, + STATS_ITEM_COLD_DAMAGEMAX_BYTIME_MOD, + STATS_ITEM_FIRE_DAMAGEMAX_BYTIME_MOD, + STATS_ITEM_LTNG_DAMAGEMAX_BYTIME_MOD, + STATS_ITEM_POIS_DAMAGEMAX_BYTIME_MOD, + STATS_ITEM_RESIST_COLD_BYTIME_MOD, + STATS_ITEM_RESIST_FIRE_BYTIME_MOD, + STATS_ITEM_RESIST_LTNG_BYTIME_MOD, + STATS_ITEM_RESIST_POIS_BYTIME_MOD, + STATS_ITEM_ABSORB_COLD_BYTIME_MOD, + STATS_ITEM_ABSORB_FIRE_BYTIME_MOD, + STATS_ITEM_ABSORB_LTNG_BYTIME_MOD, + STATS_ITEM_ABSORB_POIS_BYTIME_MOD, + STATS_ITEM_FIND_GOLD_BYTIME_MOD, + STATS_ITEM_FIND_MAGIC_BYTIME_MOD, + STATS_ITEM_REGENSTAMINA_BYTIME_MOD, + STATS_ITEM_STAMINA_BYTIME_MOD, + STATS_ITEM_DAMAGE_DEMON_BYTIME_MOD, + STATS_ITEM_DAMAGE_UNDEAD_BYTIME_MOD, + STATS_ITEM_TOHIT_DEMON_BYTIME_MOD, + STATS_ITEM_TOHIT_UNDEAD_BYTIME_MOD, + STATS_ITEM_CRUSHINGBLOW_BYTIME_MOD, + STATS_ITEM_OPENWOUNDS_BYTIME_MOD, + STATS_ITEM_KICK_DAMAGE_BYTIME_MOD, + STATS_ITEM_DEADLYSTRIKE_BYTIME_MOD, + STATS_ITEM_FIND_GEMS_BYTIME_MOD, + STATS_ITEM_PIERCE_COLD_MOD, + STATS_ITEM_PIERCE_FIRE_MOD, + STATS_ITEM_PIERCE_LTNG_MOD, + STATS_ITEM_PIERCE_POIS_MOD, + STATS_ITEM_DAMAGE_VS_MONSTER_MOD, + STATS_ITEM_DAMAGE_PERCENT_VS_MONSTER_MOD, + STATS_ITEM_TOHIT_VS_MONSTER_MOD, + STATS_ITEM_TOHIT_PERCENT_VS_MONSTER_MOD, + STATS_ITEM_AC_VS_MONSTER_MOD, + STATS_ITEM_AC_PERCENT_VS_MONSTER_MOD, + INDESTRUCTIBLE, + STATS_ITEM_CHARGED_SKILL_MOD +}; + +enum D2ItemFlags +{ + ITEMFLAG_NEWITEM = 0x00000001, + ITEMFLAG_MAGICAL = 0x00000010, + ITEMFLAG_SOCKETED = 0x00000800, + ITEMFLAG_EAR = 0x00001000, + ITEMFLAG_NEWITEM2 = 0x00002000, + ITEMFLAG_CHECKSECPRICE = 0x00010000, + ITEMFLAG_CHACKGAMBLEPRICE = 0x00020000, + ITEMFLAG_ETHERAL = 0x00400000, + ITEMFLAG_FROMPLAYER = 0x01000000 +}; + +enum D2ItemTtype +{ + TYPE_NONE0 = 0, + TYPE_NONE1, + TYPE_SHIELD, + TYPR_ARMOR, + TYPE_GOLD, + TYPE_BOW_QUIVER, + TYPE_CROSSBOW_QUIVER, + TYPE_PLAYER_BODY_PART, + TYPE_HERB, + TYPE_POTION, + TYPE_RING, + TYPE_ELIXIR, + TYPE_AMULET, + TYPE_CHARM, + TYPE_NOT_USED14, + TYPE_BOOTS, + TYPE_GLOVES, + TYPE_NOT_USED17, + TYPE_BOOK, + TYPE_BELT, + TYPE_GEM, + TYPE_TORCH, + TYPE_SCROLL, + TYPE_NOT_USED23, + TYPE_SCEPTER, + TYPE_WAND, + TYPE_STAFF, + TYPE_BOW, + TYPE_AXE, + TYPE_CLUB, + TYPE_SWORD, + TYPE_HAMMER, + TYPE_KNIFE, + TYPE_SPEAR, + TYPE_POLEARM, + TYPE_CROSSBOW, + TYPE_MACE, + TYPE_HELM, + TYPE_MISSILE_POTION, + TYPE_QUEST, + TYPE_BODY_PART, + TYPE_KEY, + TYPE_THROWING_KNIFE, + TYPE_THROWING_AXE, + TYPE_JAVELIN, + TYPE_WEAPON, + TYPE_MELEE_WEAPON, + TYPE_MISSILE_WEAPON, + TYPE_THROWN_WEAPON, + TYPE_COMBO_WEAPON, + TYPE_ANY_ARMOR, + TYPE_ANY_SHIELD, + TYPE_MISCELLANEOUS, + TYPE_SOCKET_FILLER, + TYPE_SECOND_HAND, + TYPE_STAVES_AND_RODS, + TYPE_MISSILE, + TYPE_BLUNT, + //Expansion + TYPE_JEWEL, + TYPE_CLASS_SPECIFIC, + TYPE_AMAZON_ITEM, + TYPE_BARBARIAN_ITEM, + TYPE_NECROMANCER_ITEM, + TYPE_PALADIN_ITEM, + TYPE_SORCERESS_ITEM, + TYPE_ASSASSIN_ITEM, + TYPE_DRUID_ITEM, + TYPE_HAND_TO_HAND, + TYPE_ORB, + TYPE_VOODOO_HEADS, + TYPE_AURIC_SHIELDS, + TYPE_PRIMAL_HELM, + TYPE_PELT, + TYPE_CLOAK, + TYPE_RUNE, + TYPE_CIRCLET, + TYPE_HEALING_POTION, + TYPE_MANA_POTION, + TYPE_REJUV_POTION, + TYPE_STAMINA_POTION, + TYPE_ANTIDOTE_POTION, + TYPE_THAWING_POTION, + TYPE_SMALL_CHARM, + TYPE_MEDIUM_CHARM, + TYPE_LARGE_CHARM, + TYPE_AMAZON_BOW, + TYPE_AMAZON_SPEAR, + TYPE_AMAZON_JAVELIN, + TYPE_HAND_TO_HAND2, + TYPE_MAGIC_BOW_QUIVER, + TYPE_MAGIC_CROSSBOW_QUIVER, + TYPE_CHIPPED_GEM, + TYPE_FLAWED_GEM, + TYPE_STANDARD_GEM, + TYPE_FLAWLESS_GEM, + TYPE_PERFECT_GEM, + TYPE_AMETHYST, + TYPE_DIAMOND, + TYPE_EMERALD, + TYPE_RUBY, + TYPE_SAPPHIRE, + TYPE_TOPAZ, + TYPE_SKULL +}; + +enum D2ItemQuality +{ + ITEMQUALITY_CRACKED = 1, + ITEMQUALITY_NORMAL, + ITEMQUALITY_SUPERIOR, + ITEMQUALITY_MAGIC, + ITEMQUALITY_SET, + ITEMQUALITY_RARE, + ITEMQUALITY_UNIQUE, + ITEMQUALITY_CRAFTED, + ITEMQUALITY_TEMPERED +}; + +enum D2UnitType +{ + UNIT_PLAYER = 0, + UNIT_MONSTER, + UNIT_OBJECT, + UNIT_MISSILE, + UNIT_ITEM, + UNIT_ROOMTILE +}; + +enum D2BodyLoc +{ + LOC_HEAD =1, + LOC_NECK, + LOC_TORS, + LOC_RARM, + LOC_LARM, + LOC_LRIN, + LOC_RRIN, + LOC_BELT, + LOC_FEET, + LOC_GLOV, + LOC_RALT, + LOC_LALT +}; + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/Commons/updatingConst.h b/Commons/updatingConst.h new file mode 100644 index 0000000..99a53d9 --- /dev/null +++ b/Commons/updatingConst.h @@ -0,0 +1,54 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Updating Client and Server constantes. + +=================================================================*/ + +#pragma once + +enum UpdateClientConst +{ + UC_SELECT_STASH=0x18, + UC_SHARED_GOLD, + UC_ADD_STAT, + UC_ADD_SYNERGY, + UC_TEST1, + UC_TEST2, + UC_TEST3 +}; + +enum UpdateServerConst +{ + US_UNASSIGN_STR_POINT=0x10,//Don't change these first 8 value + US_UNASSIGN_ENE_POINT, + US_UNASSIGN_DEX_POINT, + US_UNASSIGN_VIT_POINT, + US_UNASSIGN_STR_POINTS, + US_UNASSIGN_ENE_POINTS, + US_UNASSIGN_DEX_POINTS, + US_UNASSIGN_VIT_POINTS, + US_UNASSIGN_SKILLS, + US_SELECT_PREVIOUS, + US_SELECT_NEXT, + US_SELECT_SELF, + US_SELECT_SHARED, + US_SELECT_PREVIOUS_INDEX, + US_SELECT_NEXT_INDEX, + US_SELECT_PREVIOUS2, + US_SELECT_NEXT2, + US_SELECT_PREVIOUS_INDEX2, + US_SELECT_NEXT_INDEX2, + US_WORLDEVENT, + US_STARTSAVE, + US_MAXGOLD, + US_PUTGOLD, + US_TAKEGOLD, + +//For CB + US_TEST1, + US_TEST2, + US_TEST3 +}; + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/BigStash.cpp b/PlugY/BigStash.cpp new file mode 100644 index 0000000..80cbe06 --- /dev/null +++ b/PlugY/BigStash.cpp @@ -0,0 +1,104 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Use a more big stash + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "plugYFiles.h" // Install_PlugYFiles() + +bool active_bigStash = false; +bool active_bigStash_tested = false; + +const char* tradeStash_RefFile= "%s\\TradeStash"; +const BYTE gridX_BB = 10; +const BYTE gridY_BB = 10; +const DWORD gridLeft_BB = 16; +const DWORD gridRight_BB = 302; +const DWORD gridTop_BB = 82; +const DWORD gridbottom_BB = 371; + +InventoryBIN* STDCALL modifStashGrid(InventoryBIN* ptInventoryBin) +{ + active_bigStash_tested = true; + if ( onRealm || !active_bigStash) return ptInventoryBin; + + InventoryBIN* inventory=ptInventoryBin+12; + inventory->gridX = gridX_BB; + inventory->gridY = gridY_BB; + inventory->gridLeft = gridLeft_BB; + inventory->gridRight = gridRight_BB; + inventory->gridTop = gridTop_BB; + inventory->gridBottom = gridbottom_BB; + + inventory = ptInventoryBin+28; + inventory->gridX = gridX_BB; + inventory->gridY = gridY_BB; + inventory->gridLeft = gridLeft_BB + 80; + inventory->gridRight = gridRight_BB + 80; + inventory->gridTop = gridTop_BB + 60; + inventory->gridBottom = gridbottom_BB + 60; + + return ptInventoryBin; +} + + +FCT_ASM ( caller_modifStashGrid ) + POP ESI + CALL D2CompileTxtFile + PUSH EAX + CALL modifStashGrid + JMP ESI +}} + +FCT_ASM ( caller_changeTradeStash ) + CMP onRealm,0 + JNZ normalTradeStash + MOV EAX,modDataDirectory + MOV DWORD PTR SS:[ESP+0x8],EAX + MOV EAX,tradeStash_RefFile + MOV DWORD PTR SS:[ESP+0x4],EAX +normalTradeStash: + POP EAX + PUSH 0x104 + JMP EAX +}} + + +void Install_BigStash() +{ + static int isInstalled = false; + if (isInstalled) return; + + Install_PlugYFiles(); + + log_msg("Patch D2Common & D2Client for make 10x10 squares in the stash. (BigStash)\n"); + + // modification of stash grid + mem_seek R7(D2Common, C9F3, CA03, 14ED3, 5FCB5, 2A505, 1BDB5, 82CA5); + MEMC_REF4( D2CompileTxtFile, caller_modifStashGrid); + //01B64ED2 |. E8 99AEFFFF CALL D2Common.#10578 + //6FDAFCB4 |. E8 A7C3FCFF CALL D2Common.#10653 + //6FD7A504 |. E8 5743FEFF CALL D2Common.#10496 ; \#10496 + //6FD6BDB4 |. E8 97600200 CALL D2Common.#10244 ; \#10244 + //6FDD2CA4 |. E8 97C2FDFF CALL D2Common.#10849 ; \#10849 + + // modification of stash background + mem_seek R7(D2Client, 45B1C, 45B1C, 4C61C, A643C, 749BC, A9D7C, 8CC1C); + memt_byte( 0x68, 0xE8 ); // CALL caller_changeTradeStash + MEMT_REF4( 0x00000104, caller_changeTradeStash); + //6FAEC61C |. 68 04010000 PUSH 104 + //6FB5643C |. 68 04010000 PUSH 104 + //6FB249BC |. 68 04010000 PUSH 104 + //6FB59D7C |. 68 04010000 PUSH 104 + //6FB3CC1C |. 68 04010000 PUSH 104 + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/ClientSaveFile.cpp b/PlugY/ClientSaveFile.cpp new file mode 100644 index 0000000..10dd101 --- /dev/null +++ b/PlugY/ClientSaveFile.cpp @@ -0,0 +1,115 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Add an extra save file for each characters. + +=================================================================*/ +/* +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include + +#define BUFFER_SIZE 0x4000 +#define FILE_VERSION 0x3130 //"01" +#define FILE_SAVETYPE 0x544E4C43 //"CLNT" + + +BYTE * openClientSaveFile(char* name, DWORD* size) +{ + char filename[512]; + BYTE* data; + d2_assert(!name, "Bad file name (NULL)", __FILE__, __LINE__); + D2FogGetSavePath( filename, 512-5); + strncat(filename, name, 512 - strlen(filename) - 5); + strcat(filename, ".clt"); + + log_msg("Client file to read : %s\n",filename); + + FILE* file = fopen(filename, "rb"); + if (file) + { + fseek(file, 0, SEEK_END); + *size = ftell(file); + fseek(file, 0, SEEK_SET); + data = (BYTE*)D2FogMemAlloc(*size,__FILE__,__LINE__,0); + DWORD nbRead = fread(data, 1, *size, file); + fclose(file); + d2_assert(nbRead != *size , "nbRead from client save file != size", __FILE__, __LINE__); + } else { + log_msg("Can't open client save file in mode \"rb\" (is not an error if it's a new player)\n"); + *size = 6; + data = (BYTE*)D2FogMemAlloc(*size,__FILE__,__LINE__,0); + *((DWORD*)&data[0]) = FILE_SAVETYPE; //"CSTM" + *((WORD *)&data[4]) = FILE_VERSION; + } + return data; +} + +DWORD loadClientSaveFile() +{ + Unit* ptChar = D2GetClientPlayer(); + DWORD size=0; + log_msg("Load client file\n"); + if (!ptChar || !PCPlayerData) return 0; + + BYTE* data = openClientSaveFile(PCPlayerData->name,&size); + if (!data) return 0; + + DWORD curSize = 0; + + log_msg("Load client file.\n"); + if (*(DWORD*)&data[curSize] != FILE_SAVETYPE) + { + log_msg("loadClientSaveFile -> bad header\n"); + D2FogMemDeAlloc(data,__FILE__,__LINE__,0); + return 9; + } + curSize += 4; + + if (*(WORD *)&data[curSize] != FILE_VERSION) + { + log_msg("loadClientSaveFile -> bad file version\n"); + D2FogMemDeAlloc(data,__FILE__,__LINE__,0); + return 9; + } + curSize += 2; + + D2FogMemDeAlloc(data,__FILE__,__LINE__,0); + return 0; +} + + +DWORD saveClientSaveFile() +{ + DWORD curSize = 0; + BYTE data[BUFFER_SIZE]; + char szTempName[MAX_PATH]; + char szSaveName[MAX_PATH]; + FILE* customSaveFile; + Unit* ptChar = D2GetClientPlayer(); + + D2FogGetSavePath( (char*)data, BUFFER_SIZE); + sprintf( szTempName, "%s%s.cl~", data, PCPlayerData->name ); + log_msg("Client tmp file for saving : %s\n",szTempName); + customSaveFile = fopen(szTempName, "wb+"); + + *(DWORD *)&data[curSize] = FILE_SAVETYPE; + curSize += 4; + *(WORD *)&data[curSize] = FILE_VERSION; + curSize += 2; + + fwrite(data, curSize, 1, customSaveFile); + fclose(customSaveFile); + + D2FogGetSavePath( (char*)data, BUFFER_SIZE); + sprintf( szSaveName, "%s%s.clt", data, PCPlayerData->name ); + log_msg("Client save file for saving : %s\n",szSaveName); +// if (!MoveFileEx(szTempName, szSaveName, MOVEFILE_WRITE_THROUGH|MOVEFILE_REPLACE_EXISTING)) + DeleteFile(szSaveName); + if (!MoveFile(szTempName, szSaveName)) + log_box("Could not create the client save file."); + return 1; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/Commands.cpp b/PlugY/Commands.cpp new file mode 100644 index 0000000..722cfed --- /dev/null +++ b/PlugY/Commands.cpp @@ -0,0 +1,283 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Updating server. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "updateServer.h" +#include "updateClient.h" +#include "infinityStash.h" +#include "newInterfaces.h" +#include "newInterface_CubeListing.h" +#include "extraOptions.h" + +bool active_Commands=true; + +bool active_listAllCubeFormula=true; +bool active_savegame=false; + +#define MAX_CMD_SIZE 200 + +const char * CMD_RENAME="/rename"; +const char * CMD_LISTCUBEFORMULA="/listcube"; +const char * CMD_SELECTPAGE="/page"; + +const char * CMD_RELOAD="/reload"; + +const char * CMD_STARTSAVE="/save"; + +const char * CMD_MAXGOLD="/maxgold"; + +const char * CMD_DISPLAY_MANA_LIFE = "/dml"; +const char * CMD_DISPLAY_LIFE_MANA = "/dlm"; +const char * CMD_DISPLAY_LIFE = "/dl"; +const char * CMD_DISPLAY_MANA = "/dm"; + +/* +$+21C8 02020648 |. 6A 01 PUSH 1 +$+21CA 0202064A |. 52 PUSH EDX +$+21CB 0202064B |. 57 PUSH EDI +$+21CC 0202064C |. 55 PUSH EBP +$+21CD 0202064D |. 8BC3 MOV EAX,EBX +$+21CF 0202064F |. E8 2CDEFFFF CALL D2Game.0201E480 +*/ + +void gambleReload(Unit* ptChar) +{ + Unit* ptNPC = D2GetCurrentNPC(); + if (ptNPC) + { + D2TogglePage(0xC,1,0); + __asm { + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + } +// D2OpenNPCMenu(ptNPC); + D2ReloadGambleScreen(); + } +} +//6FACFFD4 |. E8 77F90000 CALL D2Client.6FADF950 + +void savePlayers(Unit* ptChar) +{ + if (active_savegame) + D2SaveGame(PCGame); +} + +void maxGold(Unit* ptChar) +{ + log_msg("maxGold\n"); + + DWORD maxGold = D2GetMaxGold(ptChar); + DWORD maxGoldBank = D2GetMaxGoldBank(ptChar); + DWORD playerGold = D2GetPlayerStat(ptChar, STATS_GOLD, 0); + DWORD playerGoldBank = D2GetPlayerStat(ptChar, STATS_GOLDBANK, 0); + if ( (playerGold < maxGold) || (playerGoldBank < maxGoldBank) ) { + D2AddPlayerStat( ptChar, STATS_GOLD, maxGold-playerGold, 0 ); + D2AddPlayerStat( ptChar, STATS_GOLDBANK, maxGoldBank-playerGoldBank, 0 ); + } else { + D2AddPlayerStat( ptChar, STATS_GOLD, 100000, 0 ); + } + if (active_sharedGold) + { + PCPY->sharedGold = 0xFFFFFFFF; + updateClient(ptChar, UC_SHARED_GOLD, PCPY->sharedGold, 0, 0); + } +} + +void putGold(Unit* ptChar, DWORD amount) +{ + if (!active_sharedGold) return; + log_msg("putGold : %d\n", amount); + + DWORD playerGold = D2GetPlayerStat(ptChar, STATS_GOLD, 0); + DWORD toAdd = 0xFFFFFFFF - PCPY->sharedGold; + if (playerGold < toAdd) + toAdd = playerGold; + if (amount && (toAdd > amount)) + toAdd = amount; + D2AddPlayerStat(ptChar, STATS_GOLD, 0-toAdd, 0); + PCPY->sharedGold += toAdd; + updateClient(ptChar, UC_SHARED_GOLD, PCPY->sharedGold, 0, 0); +} + +void takeGold(Unit* ptChar, DWORD amount) +{ + if (!active_sharedGold) return; + log_msg("takeGold : %d\n", amount); + + DWORD maxGold = D2GetMaxGold(ptChar) - D2GetPlayerStat(ptChar, STATS_GOLD, 0); +// DWORD maxGoldBank = D2GetMaxGoldBank(ptChar) - D2GetPlayerStat(ptChar, STATS_GOLDBANK, 0); + DWORD toAdd = maxGold < PCPY->sharedGold ? maxGold : PCPY->sharedGold; + if (amount && (toAdd > amount)) + toAdd = amount; + D2AddPlayerStat( ptChar, STATS_GOLD, toAdd, 0 ); + PCPY->sharedGold -= toAdd; + updateClient(ptChar, UC_SHARED_GOLD, PCPY->sharedGold, 0, 0); +} + + +void updateSharedGold(DWORD goldAmount) +{ + Unit* ptChar = D2GetClientPlayer(); + log_msg("SharedGold = %d\n",goldAmount); + PCPY->sharedGold = goldAmount; +} + +/****************************************************************************************************/ + +int STDCALL commands (char* ptText) +{ + Unit* ptChar = D2GetClientPlayer(); + + char command[MAX_CMD_SIZE]; + ZeroMemory(command,MAX_CMD_SIZE); + strncpy(command,ptText,MAX_CMD_SIZE-1); + strlwr(command); + + if (!strncmp(command,CMD_RENAME,strlen(CMD_RENAME))) + { + if (!active_multiPageStash) return 1; + char* param = &command[strlen(CMD_RENAME)]; + DWORD len = strlen(param); + if (len && (param[0] != ' ')) return 1; + + Stash* ptStash = PCPY->currentStash; + if (!ptStash) return 0; + if (len>1) + { + D2FogMemDeAlloc(ptStash->name,__FILE__,__LINE__,0); + ptStash->name = (char *)malloc(len);//D2FogMemAlloc(len,__FILE__,__LINE__,0); + strcpy(ptStash->name,¶m[1]); + } else { + D2FogMemDeAlloc(ptStash->name,__FILE__,__LINE__,0); + ptStash->name = NULL; + } + return 0; + } + + if (!strcmp(command,CMD_LISTCUBEFORMULA)) + { + if (!active_listAllCubeFormula) return 1; + listAllCubeFormula(); + return 0; + } + + if (!strncmp(command,CMD_SELECTPAGE,strlen(CMD_SELECTPAGE))) + { + if (!active_newInterfaces) return 1; + GoStatPage(atoi(&command[strlen(CMD_SELECTPAGE)])-1); + return 0; + } + + if (!strcmp(command,CMD_RELOAD)) + { + if (onRealm) return 1; + gambleReload(ptChar); + return 0; + } + + if (!strcmp(command,CMD_STARTSAVE)) + { + if (onRealm) return 1; + updateServer(US_STARTSAVE); + return 0; + } + + if (!strcmp(command,CMD_MAXGOLD)) + { + if (onRealm) return 1; + updateServer(US_MAXGOLD); + return 0; + } + + if (!strcmp(command,CMD_DISPLAY_LIFE)) + { + active_AlwaysDisplayLifeMana = !active_AlwaysDisplayLifeMana; + return 0; + } + + if (!strcmp(command,CMD_DISPLAY_MANA)) + { + active_AlwaysDisplayLifeMana = !active_AlwaysDisplayLifeMana; + return 0; + } + + if (!strcmp(command,CMD_DISPLAY_LIFE_MANA) || !strcmp(command,CMD_DISPLAY_MANA_LIFE)) + { + active_AlwaysDisplayLifeMana = !active_AlwaysDisplayLifeMana; + return 0; + } + + return 1; +} + +FCT_ASM ( caller_Commands ) + TEST EAX,EAX + JE MANAGESOUNDCHAOSDEBUG + PUSH DWORD PTR SS:[ESP+0x1C] + CALL commands + TEST EAX,EAX + JNZ MANAGESOUNDCHAOSDEBUG + ADD DWORD PTR SS:[ESP],7 +MANAGESOUNDCHAOSDEBUG: + RETN 8 +}} + +FCT_ASM ( caller_Commands_111 ) + TEST EAX,EAX + JE MANAGESOUNDCHAOSDEBUG + PUSH ESI + CALL commands + TEST EAX,EAX + JNZ MANAGESOUNDCHAOSDEBUG + ADD DWORD PTR SS:[ESP],7 +MANAGESOUNDCHAOSDEBUG: + RETN 8 +}} + +void Install_Commands() +{ + static int isInstalled = false; + if (isInstalled) return; + + Install_UpdateServer(); + + log_msg("Patch D2Client for install commands. (Commands)\n"); + + active_listAllCubeFormula = version_D2Common >= V110; + active_savegame = version_D2Common >= V111; + + // Run custom commmand + mem_seek R7(D2Client, 2C120, 2C110, 32BDD, C1EE6, 91C16, 86926, 70AE6); + memt_byte( 0x83, 0xE8 ); // CALL + MEMT_REF4( 0xC08508C4 , version_D2Client >= V111 ? caller_Commands_111 : caller_Commands); + //6FB71EE6 . 83C4 08 ADD ESP,8 + //6FB71EE7 . 85C0 TEST EAX,EAX + //6FB41C16 |. 83C4 08 ADD ESP,8 + //6FB41C19 |. 85C0 TEST EAX,EAX + //6FB36926 |. 83C4 08 ADD ESP,8 + //6FB36929 |. 85C0 TEST EAX,EAX + //6FB20AE6 |. 83C4 08 ADD ESP,8 + //6FB20AE9 |. 85C0 TEST EAX,EAX + //6FB20AE6 |. 83C4 08 ADD ESP,8 + //6FB20AE9 |. 85C0 TEST EAX,EAX + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/Common.cpp b/PlugY/Common.cpp new file mode 100644 index 0000000..0ee02f4 --- /dev/null +++ b/PlugY/Common.cpp @@ -0,0 +1,489 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Common functions. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" + +s_shifting shifting; + +bool isOnRect(DWORD x, DWORD y, DWORD x0, DWORD y0, DWORD l, DWORD h) + {return (x>=x0) && (xy0-h) && (y<=y0);} + + +void freeMessage(sWinMessage* msg) +{ + msg->managed=1; + msg->unmanaged=0; + D2FreeWinMessage(msg); +} + + +LPWSTR getString(LPWSTR eng, LPWSTR esp, LPWSTR deu, LPWSTR fra, LPWSTR por, LPWSTR ita, LPWSTR jpn, LPWSTR kor, LPWSTR sin, LPWSTR chi, LPWSTR pol, LPWSTR rus) +{ + switch(D2GetLang()) + { + case LNG_ENG: return eng; + case LNG_ESP: return esp; + case LNG_DEU: return deu; + case LNG_FRA: return fra; + case LNG_POR: return por; + case LNG_ITA: return ita; + case LNG_JPN: return jpn; + case LNG_KOR: return kor; + case LNG_SIN: return sin; + case LNG_CHI: return chi; + case LNG_POL: return pol; + case LNG_RUS: return rus; + case LNG_DEF: + default: return eng; + } +} +#define LANGUAGE(I,ENG,FRA,DEU,ITA,ESP,POL/*,CHI*/) case I : return getString(L##ENG,L##ESP,L##DEU,L##FRA,L##ENG,L##ITA,L##ENG,L##ENG,L##ENG,L##ENG,L##POL,L##ENG) + +LPWSTR getTranslatedString(int stringID) +{ + switch(stringID) + { +/* LANGUAGE2( STR_STATS_UNASSIGN_WITH_LIMIT, + "+Alt: ;,+Shift: %d \x70B9\x6570",//"+Alt: Unassign, +Shift: by %d points", +// "+Alt: \x91CD\x5206\x914D;,+Shift: %d \x70B9\x6570",//"+Alt: Unassign, +Shift: by %d points", + "+Alt: Dsallocation, +Shift: par %d points,", + "+Alt: Zurcksetzen, +Shift: um %d Punkte", + "+Alt: Rimuovi, +Shift: Assegna %d punti", + "+Alt: Quita, +Shift: por %d puntos", + "+Alt: \37325\20998\37197;,+Shift:%d \28857\25968"); +*/ + LANGUAGE( STR_STATS_UNASSIGN_WITH_LIMIT, + "+Alt: Unassign, +Shift: by %d points", + "+Alt: Dsallocation, +Shift: par %d points", + "+Alt: Zurcksetzen, +Shift: um %d Punkte", + "+Alt: Rimuovi, +Shift: Assegna %d punti", + "+Alt: Quita, +Shift: por %d puntos", + "+Alt: Odejmij, +Shift: %d punktw"); +// "+Alt: ????, +Shift: %d ??"); + + LANGUAGE( STR_STATS_UNASSIGN_WITHOUT_LIMIT, + "+Alt: Unassign, +Shift: all remaining points", + "+Alt: Dsallocation, +Shift: Tous les points restants", + "+Alt: Zurcksetzen, +Shift: Alle verbleibenden Punkte", + "+Alt: Rimuovi, +Shift: Assegna tutti i punti rimanenti", + "+Alt: Quita, +Shift: Todos los puntos restantes", + "+Alt: Odejmij, +Shift: wszystkie pozostale punkty"); +// "+Alt: ????, +Shift: ???"); + + LANGUAGE( STR_STATS_BASE_MIN, + "Base: %d (Min: %d)", + "Base: %d (Min: %d)", + "Basiswert: %d (Min: %d)", + "Base: %d (Min: %d)", + "Base: %d (Min: %d)", + "Bazowo: %d (Minimum: %d)"); +// "??: %d(??: %d)"); + + LANGUAGE( STR_SKILLS_UNASSIGN, + "Un-allocate all skills points", + "Dsalloue tous les points d'aptitudes", + "Alle Fertigkeitspunkte zurcksetzen", + "Rimuovi tutte le abilit", + "Quita todos los puntos de habilidades", + "Rozdaj od nowa wszystkie punkty umiejetnosci"); +// "????????"); + + LANGUAGE( STR_STASH_PREVIOUS_PAGE, + "Previous Page (+shift: First Page)", + "Page prcdente (+shift: Premire page)", + "Vorherige Seite (+shift: Erste Seite)", + "Pagina Precedente (+shift: Prima Pagina)", + "Pagina anterior (+shift: Primera Pagina)", + "Poprzednia Strona (+shift: Pierwsza Strona)"); +// "??? (+shift: ??)"); + + LANGUAGE( STR_STASH_NEXT_PAGE, + "Next Page (+shift: Last not empty Page)", + "Page suivante (+shift: Dernire page non vide)", + "Nchste Seite (+shift: Letzte nicht leere Seite )", + "Pagina Successiva (+shift: Ultima Pagina non vuota)", + "Pagina Siguiente (+shift: Ultima pagina non vacia)", + "Nastepna Strona (+shift: Ostatnia nie pusta Strona)"); +// "??? (+shift: ?????"); + + LANGUAGE( STR_TOGGLE_TO_PERSONAL, + "Toggle to Personal Stash", + "Voir coffre personnel", + "Wechselt zum persnlichen Goldschatz", + "Vai all'Inventario Personale", + "Ver el cofre personal", + "Przejdz do Skrzyni Osobistej"); +// "????????"); + + LANGUAGE( STR_TOGGLE_TO_SHARED, + "Toggle to Shared Stash", + "Voir coffre partag", + "Wechselt zum gemeinsamen Goldschatz", + "Vai all'Inventario Condiviso", + "Ver el cofre compartido", + "Przejdz do Skrzyni Wsplnej"); +// "????????"); + + LANGUAGE( STR_STASH_PREVIOUS_INDEX, + "Previous Index : by %d Pages (+Shift: %d)", + "Index prcdent : par %d pages (+shift: %d)", + "Vorheriger Index: in %d Seiten (+shift: %d)", + "Schermata Precedente : Indietro di %d Pagine (+Shift: %d)", + "Indice anterior : por %d paginas (+shift: %d)", + "Poprzednia Strona : po %d Stron (+Shift: %d)"); +// "???? : %d ? (+Shift:%d)"); + + LANGUAGE( STR_STASH_NEXT_INDEX, + "Next Index : by %d Pages (+shift: %d)", + "Index suivant : par %d pages (+shift: %d)", + "Nchster Index: in %d Seiten (+shift: %d)", + "Schermata Successiva : Avanti di %d Pagine (+shift: %d)", + "Indice siguiente : por %d paginas (+shift: %d)", + "Nastepna Strona : po %d Stron (+shift: %d)"); +// "???? : %d ? (+shift:%d)"); + + LANGUAGE( STR_PUT_GOLD, + "Put Gold", + "Poser de l'Or", + "Gib Gold", + "Immetti Oro", + "Poner oro", + "Zdeponuj Zloto"); +// "????"); + + LANGUAGE( STR_TAKE_GOLD, + "Take Gold", + "Prendre de l'Or", + "Nehme Gold", + "Ritira Oro", + "Tomar oro", + "Wyplac zloto"); +// "????"); + + LANGUAGE( STR_PERSONAL_PAGE_NUMBER, + "Personal Page n%u", + "Page perso n%u", + "Persnliche Seite n%u", + "Pagina Personale n%u", + "Pagina personal n%u", + "Strona Osobista n%u"); +// "????? n%u"); + + LANGUAGE( STR_SHARED_PAGE_NUMBER, + "Shared Page n%u", + "Page partage n%u", + "Gemeinsame Seite n%u", + "Pagina Condivisa n%u", + "Pagina personal n%u", + "Strona Wsplna n%u"); +// "????? n%u"); + + LANGUAGE( STR_NO_SELECTED_PAGE, + "No selected page", + "Aucune page slectionne", + "Keine ausgewhlte Seite", + "Nessuna pagina selezionata", + "Ninguna pagina seleccionada", + "Nie zaznaczono strony"); +// "????"); + + LANGUAGE( STR_SHARED_GOLD_QUANTITY, + "Shared Gold : %u", + "Or partag : %u", + "Gemeinsamen Gold : %u", + "Oro Condiviso : %u", + "Oro compartido : %u", + "Wsplne Zloto : %u"); +// "????: %u"); + + LANGUAGE( STR_PREVIOUS_PAGE, + "Previous Page", + "Page prcdente", + "Vorherige Seite", + "Pagina Precedente", + "Pagina anterior", + "Poprzednia Strona"); +// "???"); + + LANGUAGE( STR_NEXT_PAGE, + "Next Page", + "Page suivante", + "Nchste Seite", + "Pagina Successiva", + "Pagina siguiente", + "Nastepna Strona"); +// "???"); + + default : return L""; + } +} + + +/*=================================================================*/ + +const char* SNONE=""; +const char* c_shie[3]={"Shield (Not Class Specific)",SNONE,SNONE}; +const char* c_tors[3]={"Body Armor",SNONE,SNONE}; +const char* c_gold[3]={"Gold",SNONE,SNONE}; +const char* c_bowq[3]={"Arrow",SNONE,SNONE}; +const char* c_xboq[3]={"Bolt",SNONE,SNONE}; +const char* c_play[3]={"Ear",SNONE,SNONE}; +const char* c_herb[3]={"Herb",SNONE,SNONE}; +const char* c_poti[3]={"Potion",SNONE,SNONE}; +const char* c_ring[3]={"Ring",SNONE,SNONE}; +const char* c_elix[3]={"Elixir",SNONE,SNONE}; +const char* c_amul[3]={"Amulet",SNONE,SNONE}; +const char* c_char[3]={"Charm",SNONE,SNONE}; +const char* c_boot[3]={"Boot",SNONE,SNONE}; +const char* c_glov[3]={"Glove",SNONE,SNONE}; +const char* c_book[3]={"Book",SNONE,SNONE}; +const char* c_belt[3]={"Belt",SNONE,SNONE}; +const char* c_gem[3]={"Gem",SNONE,SNONE}; +const char* c_torc[3]={"Torch",SNONE,SNONE}; +const char* c_scro[3]={"Scroll",SNONE,SNONE}; +const char* c_scep[3]={"Scepter",SNONE,SNONE}; +const char* c_wand[3]={"Wand",SNONE,SNONE}; +const char* c_staf[3]={"Staff",SNONE,SNONE}; +const char* c_bow[3]={"Bow",SNONE,SNONE}; +const char* c_axe[3]={"Axe",SNONE,SNONE}; +const char* c_club[3]={"Club",SNONE,SNONE}; +const char* c_swor[3]={"Sword",SNONE,SNONE}; +const char* c_hamm[3]={"Hammer",SNONE,SNONE}; +const char* c_knif[3]={"Knife",SNONE,SNONE}; +const char* c_spea[3]={"Spear",SNONE,SNONE}; +const char* c_pole[3]={"Polearm",SNONE,SNONE}; +const char* c_xbow[3]={"Crossbow",SNONE,SNONE}; +const char* c_mace[3]={"Mace",SNONE,SNONE}; +const char* c_helm[3]={"Helm",SNONE,SNONE}; + +const char* c_tpot[3]={"Missile Potion",SNONE,SNONE}; +const char* c_ques[3]={"Quest Item",SNONE,SNONE}; +const char* c_body[3]={"Body Part",SNONE,SNONE}; +const char* c_key[3]={"Key",SNONE,SNONE}; +const char* c_tkni[3]={"Throwing Knife",SNONE,SNONE}; +const char* c_taxe[3]={"Throwing Axe",SNONE,SNONE}; +const char* c_jave[3]={"Javelin",SNONE,SNONE}; +const char* c_weap[3]={"Weapon",SNONE,SNONE}; +const char* c_mele[3]={"Melee Weapon",SNONE,SNONE}; +const char* c_miss[3]={"Missile Weapon",SNONE,SNONE}; +const char* c_thro[3]={"Throwing Weapon",SNONE,SNONE}; +const char* c_comb[3]={"Combo Weapon",SNONE,SNONE}; +const char* c_armo[3]={"Armor",SNONE,SNONE}; +const char* c_shld[3]={"Any Shield",SNONE,SNONE}; +const char* c_misc[3]={"Miscellaneous",SNONE,SNONE}; +const char* c_sock[3]={"Socket Filler",SNONE,SNONE}; +const char* c_seco[3]={"Second Hand Item",SNONE,SNONE}; +const char* c_rod[3]={"Staves And Rods",SNONE,SNONE}; +const char* c_misl[3]={"Missile",SNONE,SNONE}; +const char* c_blun[3]={"Blunt",SNONE,SNONE}; + +const char* c_jewl[3]={"Jewel",SNONE,SNONE}; +const char* c_clas[3]={"Class Specific",SNONE,SNONE}; +const char* c_amaz[3]={"Amazon Item",SNONE,SNONE}; +const char* c_barb[3]={"Barbarian Item",SNONE,SNONE}; +const char* c_necr[3]={"Necromancer Item",SNONE,SNONE}; +const char* c_pala[3]={"Paladin Item",SNONE,SNONE}; +const char* c_sorc[3]={"Sorceress Item",SNONE,SNONE}; +const char* c_assn[3]={"Assassin Item",SNONE,SNONE}; +const char* c_drui[3]={"Druid Item",SNONE,SNONE}; +const char* c_h2h[3]={"Claw",SNONE,SNONE}; +const char* c_orb[3]={"Orb",SNONE,SNONE}; +const char* c_head[3]={"Voodoo Heads",SNONE,SNONE}; +const char* c_ashd[3]={"Paladin Shield",SNONE,SNONE}; +const char* c_phlm[3]={"Barbarian Helm",SNONE,SNONE}; +const char* c_pelt[3]={"Druid Helm",SNONE,SNONE}; +const char* c_cloa[3]={"Cloak",SNONE,SNONE}; +const char* c_rune[3]={"Rune",SNONE,SNONE}; +const char* c_circ[3]={"Circlet",SNONE,SNONE}; +const char* c_hpot[3]={"Healing Potion",SNONE,SNONE}; +const char* c_mpot[3]={"Mana Potion",SNONE,SNONE}; +const char* c_rpot[3]={"Rejuvenation potion",SNONE,SNONE}; +const char* c_spot[3]={"Stamina Potion",SNONE,SNONE}; +const char* c_apot[3]={"Antidote Potion",SNONE,SNONE}; +const char* c_wpot[3]={"Thawing Potion",SNONE,SNONE}; +const char* c_scha[3]={"Small Charm",SNONE,SNONE}; +const char* c_mcha[3]={"Large Charm",SNONE,SNONE}; +const char* c_lcha[3]={"Grand Charm",SNONE,SNONE}; +const char* c_abow[3]={"Amazon Bow",SNONE,SNONE}; +const char* c_aspe[3]={"Amazon Spear",SNONE,SNONE}; +const char* c_ajav[3]={"Amazon Javelin",SNONE,SNONE}; +const char* c_h2h2[3]={"Assassin Claw",SNONE,SNONE}; +const char* c_mboq[3]={"Magic Arrow",SNONE,SNONE}; +const char* c_mxbq[3]={"Magic Bolt",SNONE,SNONE}; +const char* c_gem0[3]={"Chipped Gem",SNONE,SNONE}; +const char* c_gem1[3]={"Flawed Gem",SNONE,SNONE}; +const char* c_gem2[3]={"Normal Gem",SNONE,SNONE}; +const char* c_gem3[3]={"Flawless Gem",SNONE,SNONE}; +const char* c_gem4[3]={"Perfect Gem",SNONE,SNONE}; +const char* c_gema[3]={"Amethyst",SNONE,SNONE}; +const char* c_gemd[3]={"Diamond",SNONE,SNONE}; +const char* c_geme[3]={"Emerald",SNONE,SNONE}; +const char* c_gemr[3]={"Ruby",SNONE,SNONE}; +const char* c_gems[3]={"Sapphire",SNONE,SNONE}; +const char* c_gemt[3]={"Topaz",SNONE,SNONE}; +const char* c_gemz[3]={"Skull",SNONE,SNONE}; + +const char* getTypeString (DWORD code) +{ + DWORD lang = 0;//D2GetLang(); + if ((lang == LNG_FRA) || (lang == LNG_DEU)) lang--; + else lang = 0; + switch (code) + { + case BIN('s','h','i','e') : return c_shie[0]; + case BIN('t','o','r','s') : return c_tors[0]; + case BIN('g','o','l','d') : return c_gold[0]; + case BIN('b','o','w','q') : return c_bowq[0]; + case BIN('x','b','o','q') : return c_xboq[0]; + case BIN('p','l','a','y') : return c_play[0]; + case BIN('h','e','r','b') : return c_herb[0]; + case BIN('p','o','t','i') : return c_poti[0]; + case BIN('r','i','n','g') : return c_ring[0]; + case BIN('e','l','i','x') : return c_elix[0]; + case BIN('a','m','u','l') : return c_amul[0]; + case BIN('c','h','a','r') : return c_char[0]; + case BIN('b','o','o','t') : return c_boot[0]; + case BIN('g','l','o','v') : return c_glov[0]; + case BIN('b','o','o','k') : return c_book[0]; + case BIN('b','e','l','t') : return c_belt[0]; + case BIN('g','e','m',' ') : return c_gem[0]; + case BIN('t','o','r','c') : return c_torc[0]; + case BIN('s','c','r','o') : return c_scro[0]; + case BIN('s','c','e','p') : return c_scep[0]; + case BIN('w','a','n','d') : return c_wand[0]; + case BIN('s','t','a','f') : return c_staf[0]; + case BIN('b','o','w',' ') : return c_bow[0]; + case BIN('a','x','e',' ') : return c_axe[0]; + case BIN('c','l','u','b') : return c_club[0]; + case BIN('s','w','o','r') : return c_swor[0]; + case BIN('h','a','m','m') : return c_hamm[0]; + case BIN('k','n','i','f') : return c_knif[0]; + case BIN('s','p','e','a') : return c_spea[0]; + case BIN('p','o','l','e') : return c_pole[0]; + case BIN('x','b','o','w') : return c_xbow[0]; + case BIN('m','a','c','e') : return c_mace[0]; + case BIN('h','e','l','m') : return c_helm[0]; + case BIN('t','p','o','t') : return c_tpot[0]; + case BIN('q','u','e','s') : return c_ques[0]; + case BIN('b','o','d','y') : return c_body[0]; + case BIN('k','e','y',' ') : return c_key[0]; + case BIN('t','k','n','i') : return c_tkni[0]; + case BIN('t','a','x','e') : return c_taxe[0]; + case BIN('j','a','v','e') : return c_jave[0]; + case BIN('w','e','a','p') : return c_weap[0]; + case BIN('m','e','l','e') : return c_mele[0]; + case BIN('m','i','s','s') : return c_miss[0]; + case BIN('t','h','r','o') : return c_thro[0]; + case BIN('c','o','m','b') : return c_comb[0]; + case BIN('a','r','m','o') : return c_armo[0]; + case BIN('s','h','l','d') : return c_shld[0]; + case BIN('m','i','s','c') : return c_misc[0]; + case BIN('s','o','c','k') : return c_sock[0]; + case BIN('s','e','c','o') : return c_seco[0]; + case BIN('r','o','d',' ') : return c_rod[0]; + case BIN('m','i','s','l') : return c_misl[0]; + case BIN('b','l','u','n') : return c_blun[0]; + case BIN('j','e','w','l') : return c_jewl[0]; + case BIN('c','l','a','s') : return c_clas[0]; + case BIN('a','m','a','z') : return c_amaz[0]; + case BIN('b','a','r','b') : return c_barb[0]; + case BIN('n','e','c','r') : return c_necr[0]; + case BIN('p','a','l','a') : return c_pala[0]; + case BIN('s','o','r','c') : return c_sorc[0]; + case BIN('a','s','s','n') : return c_assn[0]; + case BIN('d','r','u','i') : return c_drui[0]; + case BIN('h','2','h',' ') : return c_h2h[0]; + case BIN('h','2','h','2') : return c_h2h2[0]; + case BIN('o','r','b',' ') : return c_orb[0]; + case BIN('h','e','a','d') : return c_head[0]; + case BIN('a','s','h','d') : return c_ashd[0]; + case BIN('p','h','l','m') : return c_phlm[0]; + case BIN('p','e','l','t') : return c_pelt[0]; + case BIN('c','l','o','a') : return c_cloa[0]; + case BIN('r','u','n','e') : return c_rune[0]; + case BIN('c','i','r','c') : return c_circ[0]; + case BIN('h','p','o','t') : return c_hpot[0]; + case BIN('m','p','o','t') : return c_mpot[0]; + case BIN('r','p','o','t') : return c_rpot[0]; + case BIN('s','p','o','t') : return c_spot[0]; + case BIN('a','p','o','t') : return c_apot[0]; + case BIN('w','p','o','t') : return c_wpot[0]; + case BIN('s','c','h','a') : return c_scha[0]; + case BIN('m','c','h','a') : return c_mcha[0]; + case BIN('l','c','h','a') : return c_lcha[0]; + case BIN('a','b','o','w') : return c_abow[0]; + case BIN('a','s','p','e') : return c_aspe[0]; + case BIN('a','j','a','v') : return c_ajav[0]; + case BIN('m','b','o','q') : return c_mboq[0]; + case BIN('m','x','b','q') : return c_mxbq[0]; + case BIN('g','e','m','0') : return c_gem0[0]; + case BIN('g','e','m','1') : return c_gem1[0]; + case BIN('g','e','m','2') : return c_gem2[0]; + case BIN('g','e','m','3') : return c_gem3[0]; + case BIN('g','e','m','4') : return c_gem4[0]; + case BIN('g','e','m','a') : return c_gema[0]; + case BIN('g','e','m','d') : return c_gemd[0]; + case BIN('g','e','m','e') : return c_geme[0]; + case BIN('g','e','m','r') : return c_gemr[0]; + case BIN('g','e','m','s') : return c_gems[0]; + case BIN('g','e','m','t') : return c_gemt[0]; + case BIN('g','e','m','z') : return c_gemz[0]; + default: return NULL; + } +} + +char* getTypeAString (WORD id, char* lpText, DWORD size) +{ + ItemTypesBIN* itemTypeData = D2GetItemTypesBIN(id); + if (!itemTypeData) + { + strncpy(lpText, "Bad Type", size); + return lpText; + } + + const char* string = getTypeString(itemTypeData->code); + if (!string) + { + struct { + DWORD code; + BYTE zero; + } code; + code.code = itemTypeData->code; + code.zero = 0; + strncpy(lpText, (char*)&code, size); + } else + strncpy(lpText, string, size); + + return lpText; +} + +LPWSTR getTypeUString (WORD id, LPWSTR lpText, DWORD size) +{ + ItemTypesBIN* itemTypeData = D2GetItemTypesBIN(id); + if (!itemTypeData) + { + mbstowcs(lpText, "Bad Type", size); + return lpText; + } + const char* string = getTypeString(itemTypeData->code); + if (!string) + { + struct { + DWORD code; + BYTE zero; + } code; + code.code = itemTypeData->code; + code.zero = 0; + mbstowcs(lpText, (char*)&code, size); + } else + mbstowcs(lpText, string, size); + + return lpText; +} +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/CommonUTF8.cpp b/PlugY/CommonUTF8.cpp new file mode 100644 index 0000000..a0cebaa --- /dev/null +++ b/PlugY/CommonUTF8.cpp @@ -0,0 +1,489 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Common functions. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" + +s_shifting shifting; + +bool isOnRect(DWORD x, DWORD y, DWORD x0, DWORD y0, DWORD l, DWORD h) + {return (x>=x0) && (xy0-h) && (y<=y0);} + + +void freeMessage(sWinMessage* msg) +{ + msg->managed=1; + msg->unmanaged=0; + D2FreeWinMessage(msg); +} + + +LPWSTR getString(LPWSTR eng, LPWSTR esp, LPWSTR deu, LPWSTR fra, LPWSTR por, LPWSTR ita, LPWSTR jpn, LPWSTR kor, LPWSTR sin, LPWSTR chi, LPWSTR pol, LPWSTR rus) +{ + switch(D2GetLang()) + { + case LNG_ENG: return eng; + case LNG_ESP: return esp; + case LNG_DEU: return deu; + case LNG_FRA: return fra; + case LNG_POR: return por; + case LNG_ITA: return ita; + case LNG_JPN: return jpn; + case LNG_KOR: return kor; + case LNG_SIN: return sin; + case LNG_CHI: return chi; + case LNG_POL: return pol; + case LNG_RUS: return rus; + case LNG_DEF: + default: return eng; + } +} +#define LANGUAGE(I,ENG,FRA,DEU,ITA,ESP,POL,CHI) case I : return getString(L##ENG,L##ESP,L##DEU,L##FRA,L##ENG,L##ITA,L##ENG,L##ENG,L##ENG,L##ENG,L##POL,L##ENG) + +LPWSTR getTranslatedString(int stringID) +{ + switch(stringID) + { +/* LANGUAGE2( STR_STATS_UNASSIGN_WITH_LIMIT, + "+Alt: ;,+Shift: %d \x70B9\x6570",//"+Alt: Unassign, +Shift: by %d points", +// "+Alt: \x91CD\x5206\x914D;,+Shift: %d \x70B9\x6570",//"+Alt: Unassign, +Shift: by %d points", + "+Alt: Désallocation, +Shift: par %d points,", + "+Alt: Zurücksetzen, +Shift: um %d Punkte", + "+Alt: Rimuovi, +Shift: Assegna %d punti", + "+Alt: Quita, +Shift: por %d puntos", + "+Alt: \37325\20998\37197;,+Shift:%d \28857\25968"); +*/ + LANGUAGE( STR_STATS_UNASSIGN_WITH_LIMIT, + "+Alt: Unassign, +Shift: by %d points", + "+Alt: Désallocation, +Shift: par %d points", + "+Alt: Zurücksetzen, +Shift: um %d Punkte", + "+Alt: Rimuovi, +Shift: Assegna %d punti", + "+Alt: Quita, +Shift: por %d puntos", + "+Alt: Odejmij, +Shift: %d punktów"); +// "+Alt: 取消加点, +Shift: %d 点数"); + + LANGUAGE( STR_STATS_UNASSIGN_WITHOUT_LIMIT, + "+Alt: Unassign, +Shift: all remaining points", + "+Alt: Désallocation, +Shift: Tous les points restants", + "+Alt: Zurücksetzen, +Shift: Alle verbleibenden Punkte", + "+Alt: Rimuovi, +Shift: Assegna tutti i punti rimanenti", + "+Alt: Quita, +Shift: Todos los puntos restantes", + "+Alt: Odejmij, +Shift: wszystkie pozostale punkty"); +// "+Alt: 取消加点, +Shift: 所有剩"); + + LANGUAGE( STR_STATS_BASE_MIN, + "Base: %d (Min: %d)", + "Base: %d (Min: %d)", + "Basiswert: %d (Min: %d)", + "Base: %d (Min: %d)", + "Base: %d (Min: %d)", + "Bazowo: %d (Minimum: %d)"); +// "基础: %d(最小: %d)"); + + LANGUAGE( STR_SKILLS_UNASSIGN, + "Un-allocate all skills points", + "Désalloue tous les points d'aptitudes", + "Alle Fertigkeitspunkte zurücksetzen", + "Rimuovi tutte le abilità", + "Quita todos los puntos de habilidades", + "Rozdaj od nowa wszystkie punkty umiejetnosci"); +// "取消所有技能加点"); + + LANGUAGE( STR_STASH_PREVIOUS_PAGE, + "Previous Page (+shift: First Page)", + "Page précédente (+shift: Première page)", + "Vorherige Seite (+shift: Erste Seite)", + "Pagina Precedente (+shift: Prima Pagina)", + "Pagina anterior (+shift: Primera Pagina)", + "Poprzednia Strona (+shift: Pierwsza Strona)"); +// "上一页 (+shift: 首页)"); + + LANGUAGE( STR_STASH_NEXT_PAGE, + "Next Page (+shift: Last not empty Page)", + "Page suivante (+shift: Dernière page non vide)", + "Nächste Seite (+shift: Letzte nicht leere Seite )", + "Pagina Successiva (+shift: Ultima Pagina non vuota)", + "Pagina Siguiente (+shift: Ultima pagina non vacia)", + "Nastepna Strona (+shift: Ostatnia nie pusta Strona)"); +// "下一页 (+shift: 最后非空页"); + + LANGUAGE( STR_TOGGLE_TO_PERSONAL, + "Toggle to Personal Stash", + "Voir coffre personnel", + "Wechselt zum persönlichen Goldschatz", + "Vai all'Inventario Personale", + "Ver el cofre personal", + "Przejdz do Skrzyni Osobistej"); +// "切换到个人储物箱"); + + LANGUAGE( STR_TOGGLE_TO_SHARED, + "Toggle to Shared Stash", + "Voir coffre partagé", + "Wechselt zum gemeinsamen Goldschatz", + "Vai all'Inventario Condiviso", + "Ver el cofre compartido", + "Przejdz do Skrzyni Wspólnej"); +// "切换到共享储物箱"); + + LANGUAGE( STR_STASH_PREVIOUS_INDEX, + "Previous Index : by %d Pages (+Shift: %d)", + "Index précédent : par %d pages (+shift: %d)", + "Vorheriger Index: in %d Seiten (+shift: %d)", + "Schermata Precedente : Indietro di %d Pagine (+Shift: %d)", + "Indice anterior : por %d paginas (+shift: %d)", + "Poprzednia Strona : po %d Stron (+Shift: %d)"); +// "向前索引 : %d 页 (+Shift:%d)"); + + LANGUAGE( STR_STASH_NEXT_INDEX, + "Next Index : by %d Pages (+shift: %d)", + "Index suivant : par %d pages (+shift: %d)", + "Nächster Index: in %d Seiten (+shift: %d)", + "Schermata Successiva : Avanti di %d Pagine (+shift: %d)", + "Indice siguiente : por %d paginas (+shift: %d)", + "Nastepna Strona : po %d Stron (+shift: %d)"); +// "向后索引 : %d 页 (+shift:%d)"); + + LANGUAGE( STR_PUT_GOLD, + "Put Gold", + "Poser de l'Or", + "Gib Gold", + "Immetti Oro", + "Poner oro", + "Zdeponuj Zloto"); +// "放入金币"); + + LANGUAGE( STR_TAKE_GOLD, + "Take Gold", + "Prendre de l'Or", + "Nehme Gold", + "Ritira Oro", + "Tomar oro", + "Wyplac zloto"); +// "取出金币"); + + LANGUAGE( STR_PERSONAL_PAGE_NUMBER, + "Personal Page n°%u", + "Page perso n°%u", + "Persönliche Seite n°%u", + "Pagina Personale n°%u", + "Pagina personal n°%u", + "Strona Osobista n°%u"); +// "个人储物箱 n°%u"); + + LANGUAGE( STR_SHARED_PAGE_NUMBER, + "Shared Page n°%u", + "Page partagée n°%u", + "Gemeinsame Seite n°%u", + "Pagina Condivisa n°%u", + "Pagina personal n°%u", + "Strona Wspólna n°%u"); +// "共享储物箱 n°%u"); + + LANGUAGE( STR_NO_SELECTED_PAGE, + "No selected page", + "Aucune page sélectionnée", + "Keine ausgewählte Seite", + "Nessuna pagina selezionata", + "Ninguna pagina seleccionada", + "Nie zaznaczono strony"); +// "未使用页"); + + LANGUAGE( STR_SHARED_GOLD_QUANTITY, + "Shared Gold : %u", + "Or partagé : %u", + "Gemeinsamen Gold : %u", + "Oro Condiviso : %u", + "Oro compartido : %u", + "Wspólne Zloto : %u"); +// "共享金币: %u"); + + LANGUAGE( STR_PREVIOUS_PAGE, + "Previous Page", + "Page précédente", + "Vorherige Seite", + "Pagina Precedente", + "Pagina anterior", + "Poprzednia Strona"); +// "上一页"); + + LANGUAGE( STR_NEXT_PAGE, + "Next Page", + "Page suivante", + "Nächste Seite", + "Pagina Successiva", + "Pagina siguiente", + "Nastepna Strona"); +// "下一页"); + + default : return L""; + } +} + + +/*=================================================================*/ + +const char* SNONE=""; +const char* c_shie[3]={"Shield (Not Class Specific)",SNONE,SNONE}; +const char* c_tors[3]={"Body Armor",SNONE,SNONE}; +const char* c_gold[3]={"Gold",SNONE,SNONE}; +const char* c_bowq[3]={"Arrow",SNONE,SNONE}; +const char* c_xboq[3]={"Bolt",SNONE,SNONE}; +const char* c_play[3]={"Ear",SNONE,SNONE}; +const char* c_herb[3]={"Herb",SNONE,SNONE}; +const char* c_poti[3]={"Potion",SNONE,SNONE}; +const char* c_ring[3]={"Ring",SNONE,SNONE}; +const char* c_elix[3]={"Elixir",SNONE,SNONE}; +const char* c_amul[3]={"Amulet",SNONE,SNONE}; +const char* c_char[3]={"Charm",SNONE,SNONE}; +const char* c_boot[3]={"Boot",SNONE,SNONE}; +const char* c_glov[3]={"Glove",SNONE,SNONE}; +const char* c_book[3]={"Book",SNONE,SNONE}; +const char* c_belt[3]={"Belt",SNONE,SNONE}; +const char* c_gem[3]={"Gem",SNONE,SNONE}; +const char* c_torc[3]={"Torch",SNONE,SNONE}; +const char* c_scro[3]={"Scroll",SNONE,SNONE}; +const char* c_scep[3]={"Scepter",SNONE,SNONE}; +const char* c_wand[3]={"Wand",SNONE,SNONE}; +const char* c_staf[3]={"Staff",SNONE,SNONE}; +const char* c_bow[3]={"Bow",SNONE,SNONE}; +const char* c_axe[3]={"Axe",SNONE,SNONE}; +const char* c_club[3]={"Club",SNONE,SNONE}; +const char* c_swor[3]={"Sword",SNONE,SNONE}; +const char* c_hamm[3]={"Hammer",SNONE,SNONE}; +const char* c_knif[3]={"Knife",SNONE,SNONE}; +const char* c_spea[3]={"Spear",SNONE,SNONE}; +const char* c_pole[3]={"Polearm",SNONE,SNONE}; +const char* c_xbow[3]={"Crossbow",SNONE,SNONE}; +const char* c_mace[3]={"Mace",SNONE,SNONE}; +const char* c_helm[3]={"Helm",SNONE,SNONE}; + +const char* c_tpot[3]={"Missile Potion",SNONE,SNONE}; +const char* c_ques[3]={"Quest Item",SNONE,SNONE}; +const char* c_body[3]={"Body Part",SNONE,SNONE}; +const char* c_key[3]={"Key",SNONE,SNONE}; +const char* c_tkni[3]={"Throwing Knife",SNONE,SNONE}; +const char* c_taxe[3]={"Throwing Axe",SNONE,SNONE}; +const char* c_jave[3]={"Javelin",SNONE,SNONE}; +const char* c_weap[3]={"Weapon",SNONE,SNONE}; +const char* c_mele[3]={"Melee Weapon",SNONE,SNONE}; +const char* c_miss[3]={"Missile Weapon",SNONE,SNONE}; +const char* c_thro[3]={"Throwing Weapon",SNONE,SNONE}; +const char* c_comb[3]={"Combo Weapon",SNONE,SNONE}; +const char* c_armo[3]={"Armor",SNONE,SNONE}; +const char* c_shld[3]={"Any Shield",SNONE,SNONE}; +const char* c_misc[3]={"Miscellaneous",SNONE,SNONE}; +const char* c_sock[3]={"Socket Filler",SNONE,SNONE}; +const char* c_seco[3]={"Second Hand Item",SNONE,SNONE}; +const char* c_rod[3]={"Staves And Rods",SNONE,SNONE}; +const char* c_misl[3]={"Missile",SNONE,SNONE}; +const char* c_blun[3]={"Blunt",SNONE,SNONE}; + +const char* c_jewl[3]={"Jewel",SNONE,SNONE}; +const char* c_clas[3]={"Class Specific",SNONE,SNONE}; +const char* c_amaz[3]={"Amazon Item",SNONE,SNONE}; +const char* c_barb[3]={"Barbarian Item",SNONE,SNONE}; +const char* c_necr[3]={"Necromancer Item",SNONE,SNONE}; +const char* c_pala[3]={"Paladin Item",SNONE,SNONE}; +const char* c_sorc[3]={"Sorceress Item",SNONE,SNONE}; +const char* c_assn[3]={"Assassin Item",SNONE,SNONE}; +const char* c_drui[3]={"Druid Item",SNONE,SNONE}; +const char* c_h2h[3]={"Claw",SNONE,SNONE}; +const char* c_orb[3]={"Orb",SNONE,SNONE}; +const char* c_head[3]={"Voodoo Heads",SNONE,SNONE}; +const char* c_ashd[3]={"Paladin Shield",SNONE,SNONE}; +const char* c_phlm[3]={"Barbarian Helm",SNONE,SNONE}; +const char* c_pelt[3]={"Druid Helm",SNONE,SNONE}; +const char* c_cloa[3]={"Cloak",SNONE,SNONE}; +const char* c_rune[3]={"Rune",SNONE,SNONE}; +const char* c_circ[3]={"Circlet",SNONE,SNONE}; +const char* c_hpot[3]={"Healing Potion",SNONE,SNONE}; +const char* c_mpot[3]={"Mana Potion",SNONE,SNONE}; +const char* c_rpot[3]={"Rejuvenation potion",SNONE,SNONE}; +const char* c_spot[3]={"Stamina Potion",SNONE,SNONE}; +const char* c_apot[3]={"Antidote Potion",SNONE,SNONE}; +const char* c_wpot[3]={"Thawing Potion",SNONE,SNONE}; +const char* c_scha[3]={"Small Charm",SNONE,SNONE}; +const char* c_mcha[3]={"Large Charm",SNONE,SNONE}; +const char* c_lcha[3]={"Grand Charm",SNONE,SNONE}; +const char* c_abow[3]={"Amazon Bow",SNONE,SNONE}; +const char* c_aspe[3]={"Amazon Spear",SNONE,SNONE}; +const char* c_ajav[3]={"Amazon Javelin",SNONE,SNONE}; +const char* c_h2h2[3]={"Assassin Claw",SNONE,SNONE}; +const char* c_mboq[3]={"Magic Arrow",SNONE,SNONE}; +const char* c_mxbq[3]={"Magic Bolt",SNONE,SNONE}; +const char* c_gem0[3]={"Chipped Gem",SNONE,SNONE}; +const char* c_gem1[3]={"Flawed Gem",SNONE,SNONE}; +const char* c_gem2[3]={"Normal Gem",SNONE,SNONE}; +const char* c_gem3[3]={"Flawless Gem",SNONE,SNONE}; +const char* c_gem4[3]={"Perfect Gem",SNONE,SNONE}; +const char* c_gema[3]={"Amethyst",SNONE,SNONE}; +const char* c_gemd[3]={"Diamond",SNONE,SNONE}; +const char* c_geme[3]={"Emerald",SNONE,SNONE}; +const char* c_gemr[3]={"Ruby",SNONE,SNONE}; +const char* c_gems[3]={"Sapphire",SNONE,SNONE}; +const char* c_gemt[3]={"Topaz",SNONE,SNONE}; +const char* c_gemz[3]={"Skull",SNONE,SNONE}; + +const char* getTypeString (DWORD code) +{ + DWORD lang = 0;//D2GetLang(); + if ((lang == LNG_FRA) || (lang == LNG_DEU)) lang--; + else lang = 0; + switch (code) + { + case BIN('s','h','i','e') : return c_shie[0]; + case BIN('t','o','r','s') : return c_tors[0]; + case BIN('g','o','l','d') : return c_gold[0]; + case BIN('b','o','w','q') : return c_bowq[0]; + case BIN('x','b','o','q') : return c_xboq[0]; + case BIN('p','l','a','y') : return c_play[0]; + case BIN('h','e','r','b') : return c_herb[0]; + case BIN('p','o','t','i') : return c_poti[0]; + case BIN('r','i','n','g') : return c_ring[0]; + case BIN('e','l','i','x') : return c_elix[0]; + case BIN('a','m','u','l') : return c_amul[0]; + case BIN('c','h','a','r') : return c_char[0]; + case BIN('b','o','o','t') : return c_boot[0]; + case BIN('g','l','o','v') : return c_glov[0]; + case BIN('b','o','o','k') : return c_book[0]; + case BIN('b','e','l','t') : return c_belt[0]; + case BIN('g','e','m',' ') : return c_gem[0]; + case BIN('t','o','r','c') : return c_torc[0]; + case BIN('s','c','r','o') : return c_scro[0]; + case BIN('s','c','e','p') : return c_scep[0]; + case BIN('w','a','n','d') : return c_wand[0]; + case BIN('s','t','a','f') : return c_staf[0]; + case BIN('b','o','w',' ') : return c_bow[0]; + case BIN('a','x','e',' ') : return c_axe[0]; + case BIN('c','l','u','b') : return c_club[0]; + case BIN('s','w','o','r') : return c_swor[0]; + case BIN('h','a','m','m') : return c_hamm[0]; + case BIN('k','n','i','f') : return c_knif[0]; + case BIN('s','p','e','a') : return c_spea[0]; + case BIN('p','o','l','e') : return c_pole[0]; + case BIN('x','b','o','w') : return c_xbow[0]; + case BIN('m','a','c','e') : return c_mace[0]; + case BIN('h','e','l','m') : return c_helm[0]; + case BIN('t','p','o','t') : return c_tpot[0]; + case BIN('q','u','e','s') : return c_ques[0]; + case BIN('b','o','d','y') : return c_body[0]; + case BIN('k','e','y',' ') : return c_key[0]; + case BIN('t','k','n','i') : return c_tkni[0]; + case BIN('t','a','x','e') : return c_taxe[0]; + case BIN('j','a','v','e') : return c_jave[0]; + case BIN('w','e','a','p') : return c_weap[0]; + case BIN('m','e','l','e') : return c_mele[0]; + case BIN('m','i','s','s') : return c_miss[0]; + case BIN('t','h','r','o') : return c_thro[0]; + case BIN('c','o','m','b') : return c_comb[0]; + case BIN('a','r','m','o') : return c_armo[0]; + case BIN('s','h','l','d') : return c_shld[0]; + case BIN('m','i','s','c') : return c_misc[0]; + case BIN('s','o','c','k') : return c_sock[0]; + case BIN('s','e','c','o') : return c_seco[0]; + case BIN('r','o','d',' ') : return c_rod[0]; + case BIN('m','i','s','l') : return c_misl[0]; + case BIN('b','l','u','n') : return c_blun[0]; + case BIN('j','e','w','l') : return c_jewl[0]; + case BIN('c','l','a','s') : return c_clas[0]; + case BIN('a','m','a','z') : return c_amaz[0]; + case BIN('b','a','r','b') : return c_barb[0]; + case BIN('n','e','c','r') : return c_necr[0]; + case BIN('p','a','l','a') : return c_pala[0]; + case BIN('s','o','r','c') : return c_sorc[0]; + case BIN('a','s','s','n') : return c_assn[0]; + case BIN('d','r','u','i') : return c_drui[0]; + case BIN('h','2','h',' ') : return c_h2h[0]; + case BIN('h','2','h','2') : return c_h2h2[0]; + case BIN('o','r','b',' ') : return c_orb[0]; + case BIN('h','e','a','d') : return c_head[0]; + case BIN('a','s','h','d') : return c_ashd[0]; + case BIN('p','h','l','m') : return c_phlm[0]; + case BIN('p','e','l','t') : return c_pelt[0]; + case BIN('c','l','o','a') : return c_cloa[0]; + case BIN('r','u','n','e') : return c_rune[0]; + case BIN('c','i','r','c') : return c_circ[0]; + case BIN('h','p','o','t') : return c_hpot[0]; + case BIN('m','p','o','t') : return c_mpot[0]; + case BIN('r','p','o','t') : return c_rpot[0]; + case BIN('s','p','o','t') : return c_spot[0]; + case BIN('a','p','o','t') : return c_apot[0]; + case BIN('w','p','o','t') : return c_wpot[0]; + case BIN('s','c','h','a') : return c_scha[0]; + case BIN('m','c','h','a') : return c_mcha[0]; + case BIN('l','c','h','a') : return c_lcha[0]; + case BIN('a','b','o','w') : return c_abow[0]; + case BIN('a','s','p','e') : return c_aspe[0]; + case BIN('a','j','a','v') : return c_ajav[0]; + case BIN('m','b','o','q') : return c_mboq[0]; + case BIN('m','x','b','q') : return c_mxbq[0]; + case BIN('g','e','m','0') : return c_gem0[0]; + case BIN('g','e','m','1') : return c_gem1[0]; + case BIN('g','e','m','2') : return c_gem2[0]; + case BIN('g','e','m','3') : return c_gem3[0]; + case BIN('g','e','m','4') : return c_gem4[0]; + case BIN('g','e','m','a') : return c_gema[0]; + case BIN('g','e','m','d') : return c_gemd[0]; + case BIN('g','e','m','e') : return c_geme[0]; + case BIN('g','e','m','r') : return c_gemr[0]; + case BIN('g','e','m','s') : return c_gems[0]; + case BIN('g','e','m','t') : return c_gemt[0]; + case BIN('g','e','m','z') : return c_gemz[0]; + default: return NULL; + } +} + +char* getTypeAString (WORD id, char* lpText, DWORD size) +{ + ItemTypesBIN* itemTypeData = D2GetItemTypesBIN(id); + if (!itemTypeData) + { + strncpy(lpText, "Bad Type", size); + return lpText; + } + + const char* string = getTypeString(itemTypeData->code); + if (!string) + { + struct { + DWORD code; + BYTE zero; + } code; + code.code = itemTypeData->code; + code.zero = 0; + strncpy(lpText, (char*)&code, size); + } else + strncpy(lpText, string, size); + + return lpText; +} + +LPWSTR getTypeUString (WORD id, LPWSTR lpText, DWORD size) +{ + ItemTypesBIN* itemTypeData = D2GetItemTypesBIN(id); + if (!itemTypeData) + { + mbstowcs(lpText, "Bad Type", size); + return lpText; + } + const char* string = getTypeString(itemTypeData->code); + if (!string) + { + struct { + DWORD code; + BYTE zero; + } code; + code.code = itemTypeData->code; + code.zero = 0; + mbstowcs(lpText, (char*)&code, size); + } else + mbstowcs(lpText, string, size); + + return lpText; +} +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/CustomLibraries.cpp b/PlugY/CustomLibraries.cpp new file mode 100644 index 0000000..2fcb57f --- /dev/null +++ b/PlugY/CustomLibraries.cpp @@ -0,0 +1,89 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Language management. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "customLibraries.h" + + +TCustomDll* customDlls=NULL; + +void TCustomDll::init() +{ + if (initFct) + initFct(); +}; + +void TCustomDll::release() +{ + if (releaseFct) + releaseFct(); +}; + +void TCustomDll::saveExtendedSaveFile(Unit* ptChar, BYTE** data, DWORD* maxSize, DWORD* curSize) +{ + if (saveExtendedSaveFileFct) + saveExtendedSaveFileFct(ptChar, data, maxSize, curSize); +}; + +int TCustomDll::loadExtendedSaveFile(Unit* ptChar, BYTE* data, DWORD maxSize, DWORD* curSize) +{ + if (loadExtendedSaveFileFct) + return loadExtendedSaveFileFct(ptChar, data, maxSize, curSize); + return 0; +}; + +int TCustomDll::initExtendedSaveFile(BYTE** data, DWORD* maxSize, DWORD* curSize) +{ + if (initExtendedSaveFileFct) + return initExtendedSaveFileFct(data, maxSize, curSize); + return 0; +}; + +void TCustomDll::saveSharedSaveFile(Unit* ptChar, BYTE** data, DWORD* maxSize, DWORD* curSize) +{ + if (saveSharedSaveFileFct) + saveSharedSaveFileFct(ptChar, data, maxSize, curSize); +}; + +int TCustomDll::loadSharedSaveFile(Unit* ptChar, BYTE data[], DWORD maxSize, DWORD* curSize) +{ + if (loadSharedSaveFileFct) + return loadSharedSaveFileFct(ptChar, data, maxSize, curSize); + return 0; +}; + +int TCustomDll::initSharedSaveFile(BYTE** data, DWORD* maxSize, DWORD* curSize) +{ + if (initSharedSaveFileFct) + return initSharedSaveFileFct(data, maxSize, curSize); + return 0; +}; + + +void TCustomDll::initialize(DWORD offsetDll) +{ + offset = offsetDll; + + initFct = GetProcAddress(module,(LPCSTR)"_Init@0"); + if (!initFct) + initFct = GetProcAddress(module,(LPCSTR)10000); + + releaseFct = GetProcAddress(module,(LPCSTR)"_Release@0"); + if (!releaseFct) + releaseFct = GetProcAddress(module,(LPCSTR)10001); + + saveExtendedSaveFileFct = (TsaveSaveFile) GetProcAddress(module,"_saveExtendedSaveFile@16"); + loadExtendedSaveFileFct = (TloadSaveFile) GetProcAddress(module,"_loadExtendedSaveFile@16"); + initExtendedSaveFileFct = (TinitSaveFile) GetProcAddress(module,"_initExtendedSaveFile@12"); + saveSharedSaveFileFct = (TsaveSaveFile) GetProcAddress(module,"_saveSharedSaveFile@16"); + loadSharedSaveFileFct = (TloadSaveFile) GetProcAddress(module,"_loadSharedSaveFile@16"); + initSharedSaveFileFct = (TinitSaveFile) GetProcAddress(module,"_initSharedSaveFile@12"); +} + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/D2functions.cpp b/PlugY/D2functions.cpp new file mode 100644 index 0000000..753de83 --- /dev/null +++ b/PlugY/D2functions.cpp @@ -0,0 +1,962 @@ +/*================================================ + File created by Yohann NICOLAS. + + This file implements some common and useful + function related to some Diablo II mechanisms. + +================================================*/ + +#include "common.h" +#include "d2functions.h" +#include "error.h" + + +#define D2S(F, I, R, N, P) T##N N; +#define D2F(F, I, R, N, P) T##N N; +#define E2S(F, A, R, N, P) T##N N; +#define E2F(F, A, R, N, P) T##N N; +#define E2C(F, A, T, N) T* pt##N; +#define F7(X, Z, A,B,C,D,E,F,G, R, N, P) T##N N; +#define A7(X, Z, A,B,C,D,E,F,G, R, N, P) T##N N; +#define C7(Z, A,B,C,D,E,F,G, T, N) T* pt##N; + +#include "../Commons/D2Funcs.h" +DataTables* SgptDataTables; +//E2F(D2Client,0, DWORD, D2isLODGame, ());//6FAAC080 +//E2F(D2Client,0, BYTE, D2GetDifficultyLevel, ());//6FAAC090 +//E2S(D2Client,0, DWORD, D2GetMouseX, ());//6FB57BC0 +//E2S(D2Client,0, DWORD, D2GetMouseY, ());//6FB57BD0 +//E2S(D2Client,0, Unit*, D2GetClientPlayer, ());//6FB283D0 +//E2F(D2Client,0, void, D2SendToServer3, (BYTE type, WORD p));//6FAAD990 +////E2F(D2Client,0, void, D2SendToServer7, (BYTE type, WORD p1, WORD p2, WORD p3));//6FAAD9E0 +////E2F(D2Client,0, void, D2SendToServer5, (BYTE type, DWORD p));//6FAADA20 +////E2F(D2Client,0, void, D2SendToServer9, (BYTE type, DWORD p1, DWORD p2));//6FAADA40 +////E2F(D2Client,0, void, D2SendToServer13,(BYTE type, DWORD p1, DWORD p2, DWORD p3));//6FAADA70 +//E2F(D2Game,0, NetClient*, D2GetClient, (Unit* ptUnit, char* lpszErrFile, DWORD ErrLine));//6FCBC2E0 +//E2F(D2Client,0, void, D2CleanStatMouseUp, ());//6FAABF60 +#undef F7 +#undef A7 +#undef C7 +#undef D2S +#undef D2F +#undef E2S +#undef E2F +#undef E2C + +#define D2S(F, I, R, N, P) typedef R (STDCALL *T##N) P; T##N N; +D2S(D2Common,10581, CharStatsBIN*, D2Common10581, (DWORD charID));//ONLY in 1.09 +D2S(D2Common,10598, ItemStatCostBIN*, D2Common10598, (DWORD itemStatCostID));//ONLY in 1.09 +D2S(D2Common,10673, ItemTypesBIN*, D2Common10673, (DWORD itemTypesID));//ONLY in 1.09 +#undef D2S + +//TD2SetPlayerStat V2SetPlayerStat; +TD2AddPlayerStat V2AddPlayerStat; +TD2GetPlayerStat V2GetPlayerStat; +//TD2GetPlayerStat20 V2GetPlayerStat20; +TD2GetPlayerBaseStat V2GetPlayerBaseStat; +TD2SetSkillBaseLevel V2SetSkillBaseLevel; +TD2SetSkillBaseLevelOnClient V2SetSkillBaseLevelOnClient; +TD2PrintStat V2PrintStat; +TD2CompileCubeInput V2CompileCubeInput; +TD2CompileCubeOutput V2CompileCubeOutput; +TD2BroadcastFunction V2BroadcastFunction; +TD2GetGameByClientID V2GetGameByClientID; +TD2SpawnMonster V2SpawnMonster; +TD2VerifIfNotCarry1 V2VerifIfNotCarry1; +TD2GameGetObject V2GameGetObject; +TD2TestPositionInRoom V2TestPositionInRoom; +TD2GetItemTypesBIN V2GetItemTypesBIN; +TD2CompileTxtFile compileTxtFile; +WORD (*getDescStrPos) (DWORD statID); +//void (*setImage) (sDrawImageInfo* data, void* image); +//void (*setFrame) (sDrawImageInfo* data, DWORD frame); +TD2SendMsgToAll V2SendMsgToAll; +TD2SetColorPopup V2SetColorPopup; +TD2LoadImage V2LoadImage; +TD2PlaySound V2PlaySound; +TD2SendToServer V2SendToServer; +TD2GetCharStatsBIN V2GetCharStatsBIN; +TD2GetItemStatCostBIN V2GetItemStatCostBIN; +TD2SendPacket V2SendPacket; +TD2LoadInventory V2LoadInventory; +TD2SaveGame V2SaveGame; + +//DWORD* ptNbStatDesc +//DWORD* ptStatDescTable; +//TD2OpenNPCMenu V2OpenNPCMenu; + +DWORD getStatDescIDFrom (DWORD statID)//FOR 1.09 +{ + DWORD* desc = ptStatDescTable; + DWORD curDesc = 0; + while (curDesc < *ptNbStatDesc) + { + if (*desc == statID) + return curDesc; + desc+=4; + curDesc++; + } + return curDesc; +} + +//FCT_ASM ( D2SetPlayerStat_9 )//(Unit* ptChar, DWORD statID, DWORD amount, DWORD index) +// PUSH DWORD PTR SS:[ESP+0xC] +// PUSH DWORD PTR SS:[ESP+0xC] +// PUSH DWORD PTR SS:[ESP+0xC] +// CALL V2SetPlayerStat +// RETN 0x10 +//}} + +FCT_ASM ( D2AddPlayerStat_9 )//(Unit* ptChar, DWORD statID, DWORD amount, DWORD index) + PUSH DWORD PTR SS:[ESP+0xC] + PUSH DWORD PTR SS:[ESP+0xC] + PUSH DWORD PTR SS:[ESP+0xC] + CALL V2AddPlayerStat + RETN 0x10 +}} + +FCT_ASM ( D2GetPlayerStat_9 )//(Unit* ptChar, DWORD statID, DWORD index) + PUSH DWORD PTR SS:[ESP+0x8] + PUSH DWORD PTR SS:[ESP+0x8] + CALL V2GetPlayerStat + RETN 0x0C +}} + +//FCT_ASM ( D2GetPlayerStat20_9 )//(Unit* ptChar, DWORD statID, DWORD index) +// PUSH DWORD PTR SS:[ESP+0x8] +// PUSH DWORD PTR SS:[ESP+0x8] +// CALL V2GetPlayerStat20 +// RETN 0x0C +//}} + +FCT_ASM ( D2GetPlayerBaseStat_9 )//(Unit* ptChar, DWORD statID, DWORD index) + PUSH DWORD PTR SS:[ESP+0x8] + PUSH DWORD PTR SS:[ESP+0x8] + CALL V2GetPlayerBaseStat + RETN 0x0C +}} + +FCT_ASM ( D2SetSkillBaseLevel_9 )//(Unit* ptChar, DWORD skillID, DWORD slvl, DWORD bRemove, char*, DWORD)); + PUSH DWORD PTR SS:[ESP+0x10] + PUSH DWORD PTR SS:[ESP+0x10] + PUSH DWORD PTR SS:[ESP+0x10] + PUSH DWORD PTR SS:[ESP+0x10] + CALL V2SetSkillBaseLevel + RETN 0x18 +}} + +FCT_ASM ( D2SetSkillBaseLevelOnClient_9 )//(void* ptClient, Unit* ptChar, DWORD skillID, DWORD newValue, DWORD zero) + POP EAX + MOV ECX,EDX + POP EDX + PUSH EAX + JMP V2SetSkillBaseLevelOnClient +}} + +FCT_ASM ( D2GetCharStatsBIN_9 ) + PUSH ECX + CALL D2Common10581 + RETN +}} + +FCT_ASM ( D2GetItemStatCostBIN_9 ) + PUSH ECX + CALL D2Common10598 + RETN +}} + +FCT_ASM ( D2GetItemTypesBIN_9 ) + PUSH ECX + CALL D2Common10673 + RETN +}} + + +DWORD FASTCALL D2PrintStat_9 (Unit* ptItem, Stats* ptStats, DWORD statID, DWORD statIndex, DWORD statValue, LPWSTR lpText) +{ + DWORD curDesc = getStatDescIDFrom(statID); + if (curDesc < *ptNbStatDesc) + return V2PrintStat(ptItem, (Stats*)curDesc, statValue, 0, 0, lpText); + return 0; +} + + +void setImage(sDrawImageInfo* data, void* image){((void**)data)[shifting.ptImage/4]=image;}//0x4 0x8 0x3C +void setFrame(sDrawImageInfo* data, DWORD frame){((DWORD*)data)[shifting.ptFrame/4]=frame;}//0x8 0x44 0x40 + +//void setImage_111(sDrawImageInfo* data, void* image){data->image=image;}//0x8 0x44 +//void setImage_1XX(sDrawImageInfo* data, void* image){((void**)data)[1]=image;}//0x4 0x8 +//void setFrame_111(sDrawImageInfo* data, DWORD frame){data->frame=frame;} +//void setFrame_1XX(sDrawImageInfo* data, DWORD frame){((DWORD*)data)[2]=frame;} + + +WORD getDescStrPos_9 (DWORD statID) +{ + DWORD* desc = &ptStatDescTable[getStatDescIDFrom(statID)*4]; + return (WORD)*(desc+2); +} +WORD getDescStrPos_10 (DWORD statID) +{ + ItemStatCostBIN* itemStatCost = D2GetItemStatCostBIN(statID); + return itemStatCost->descstrpos; +} + + +const char* S_compileTxtFile = "compileTxtFile"; +const char* S_errorReadTxtFile = "pbData"; +__declspec(naked) void* STDCALL compileTxtFile_9(DWORD unused, const char* filename, BINField* ptFields, DWORD* ptRecordCount, DWORD recordLength) +{_asm{ + SUB ESP,0x210 +// MOV EAX,DWORD PTR DS:[1BEA28C] + PUSH EBX + PUSH EBP + PUSH ESI + PUSH EDI + MOV ESI,DWORD PTR SS:[ESP+0x228] + MOV DWORD PTR SS:[ESP+0x10],0 + + MOV EDI,wsprintf + PUSH ESI + LEA EAX,DWORD PTR SS:[ESP+0x20] + PUSH EAX + CALL EDI + ADD ESP,8 + + LEA EDX,DWORD PTR SS:[ESP+0x10] + PUSH 0 + PUSH S_compileTxtFile + PUSH EDX + MOV ECX,DWORD PTR SS:[ESP+0x230] + LEA EDX,DWORD PTR SS:[ESP+0x28] + CALL D2ReadFile + TEST EAX,EAX + JNZ continue_compileTxtFile + PUSH 0 + PUSH S_compileTxtFile + PUSH S_errorReadTxtFile + CALL D2FogAssertOld + PUSH -1 + CALL exit +continue_compileTxtFile: + MOV ECX,D2CompileTxtFile + ADD ECX,0x305 + JMP ECX +}} + +__declspec(naked) void* STDCALL compileTxtFile_10(DWORD unused, const char* filename, BINField* ptFields, DWORD* ptRecordCount, DWORD recordLength) +{_asm{ + SUB ESP,0x210 +// MOV EAX,DWORD PTR DS:[1BEA28C] + PUSH EBX + PUSH EBP + MOV EBP,DWORD PTR SS:[ESP+0x220] + PUSH ESI + PUSH EDI + MOV DWORD PTR SS:[ESP+0x10],0 + + MOV EBX,wsprintf + PUSH EBP + LEA EAX,DWORD PTR SS:[ESP+0x20] + PUSH EAX + CALL EBX + ADD ESP,8 + + LEA EDX,DWORD PTR SS:[ESP+0x10] + PUSH 0 + PUSH S_compileTxtFile + PUSH EDX + MOV ECX,DWORD PTR SS:[ESP+0x230] + LEA EDX,DWORD PTR SS:[ESP+0x28] + CALL D2ReadFile + TEST EAX,EAX + JNZ continue_compileTxtFile + PUSH 0 + PUSH S_compileTxtFile + PUSH S_errorReadTxtFile + CALL D2FogAssertOld + PUSH -1 + CALL exit +continue_compileTxtFile: + MOV ECX,D2CompileTxtFile + ADD ECX,0x2ED + JMP ECX +}} + +__declspec(naked) void* STDCALL compileTxtFile_111(DWORD unused, const char* filename, BINField* ptFields, DWORD* ptRecordCount, DWORD recordLength) +{_asm{ + SUB ESP,0x20C +// MOV EAX,DWORD PTR DS:[6FDF1464] + PUSH EBX + PUSH EBP + PUSH ESI + PUSH EDI + MOV DWORD PTR SS:[ESP+0x10],0 + MOV EBX,DWORD PTR SS:[ESP+0x224] + + PUSH EBX + LEA EAX,DWORD PTR SS:[ESP+0x1C] + PUSH EAX + CALL DWORD PTR SS:[wsprintf] + MOV EDX,DWORD PTR SS:[ESP+0x228] + ADD ESP,8 + LEA EDX,DWORD PTR SS:[ESP+0x10] + PUSH EDX + PUSH EAX + LEA EAX,DWORD PTR SS:[ESP+0x20] + CALL D2ReadFile + TEST EAX,EAX + JNZ continue_compileTxtFile + PUSH __LINE__ + CALL D2GetInstructionPointer + PUSH EAX + PUSH S_errorReadTxtFile + CALL D2FogAssert + ADD ESP,0xC + PUSH -1 + CALL exit +continue_compileTxtFile: + MOV ECX,D2CompileTxtFile + ADD ECX,0x1EC + JMP ECX +}} + + +DWORD FASTCALL D2isLODGame_111(){return IsLodGame;} +BYTE FASTCALL D2GetDifficultyLevel_111(){return DifficultyLevel;} +DWORD STDCALL D2GetMouseX_111(){return MouseX;} +DWORD STDCALL D2GetMouseY_111(){return MouseY;} +Unit* STDCALL D2GetClientPlayer_111(){return ptClientChar;} + +DWORD *StatMouse1, *StatMouse2, *StatMouse3, *StatMouse4; +void FASTCALL D2CleanStatMouseUp_111(){*StatMouse1=*StatMouse2=*StatMouse3=*StatMouse4=0;} + +Unit* STDCALL D2GetRealItem_111(Unit* ptItem){return ptItem;} +/* 1.11 : sizememory : 0x104 (LoadBuySell) +6FADA7F0 |. A1 48BDBC6F MOV EAX,DWORD PTR DS:[6FBCBD48] +6FADA7F5 |. 3BC3 CMP EAX,EBX +6FADA7F7 |. 75 27 JNZ SHORT D2Client.6FADA820 +6FADA7F9 |. 68 C407B86F PUSH D2Client.6FB807C4 ; /<%s> = "DATA\GLOBAL" +6FADA7FE |. 8D4424 6C LEA EAX,DWORD PTR SS:[ESP+6C] ; | +6FADA802 |. 68 483BB86F PUSH D2Client.6FB83B48 ; |Format = "%s\ui\panel\buysellbtn" +6FADA807 |. 50 PUSH EAX ; |s +6FADA808 |. FF15 FCF0B76F CALL DWORD PTR DS:[<&USER32.wsprintfA>] ; \wsprintfA +6FADA80E |. 83C4 0C ADD ESP,0C +6FADA811 |. 53 PUSH EBX ; /Arg1 +6FADA812 |. 8D4424 6C LEA EAX,DWORD PTR SS:[ESP+6C] ; | +6FADA816 |. E8 E5B40400 CALL D2Client.6FB25D00 ; \D2Client.6FB25D00 +6FADA81B |. A3 48BDBC6F MOV DWORD PTR DS:[6FBCBD48],EAX +*/ + + +FCT_ASM ( D2SendMsgToAll_111 ) + PUSH ESI + MOV ESI,ECX + CALL V2SendMsgToAll + POP ESI + RETN +}} + +FCT_ASM ( D2SetColorPopup_111 ) + PUSH EDI + PUSH EDX + MOV EDI,ECX + CALL V2SetColorPopup + POP EDI + RETN +}} + +FCT_ASM ( D2LoadImage_111 ) + PUSH EDX + MOV EAX,ECX + CALL V2LoadImage + RETN +}} + +const char* D2FreeImage_FILE = __FILE__; +FCT_ASM ( D2FreeImage_111 ) + PUSH ESI + MOV ESI,ECX + PUSH ESI + CALL D2CMP10014 + TEST ESI,ESI + JE END_D2Free + PUSH 0 + PUSH __LINE__ + MOV EDX,D2FreeImage_FILE ; ASCII "C:\projects\D2\head\Diablo2\Source\D2Client\CORE\ARCHIVE.CPP" + MOV ECX,ESI + CALL D2FogMemDeAlloc +END_D2Free: + POP ESI + RETN +}} + + +FCT_ASM ( D2PlaySound_111 ) + PUSH EBX + PUSH DWORD PTR SS:[ESP+0x10] + PUSH DWORD PTR SS:[ESP+0x10] + PUSH DWORD PTR SS:[ESP+0x10] + PUSH EDX + MOV EBX,ECX + CALL V2PlaySound + POP EBX + RETN 0xC +}} + +FCT_ASM ( D2GetClient_111 ) + PUSH ECX + CALL D2GetPlayerData + MOV EAX,DWORD PTR DS:[EAX+0x9C] + RETN 4 +}} + + +FCT_ASM ( D2SetSkillBaseLevelOnClient_111 ) + PUSH EBX + PUSH ESI + PUSH DWORD PTR SS:[ESP+0x14] + PUSH DWORD PTR SS:[ESP+0x14] + MOV EBX, DWORD PTR SS:[ESP+0x14] + MOV EAX,ECX + MOV ESI,EDX + CALL V2SetSkillBaseLevelOnClient + POP ESI + POP EBX + RETN 0xC +}} + +FCT_ASM ( D2GetCharStatsBIN_111 ) + MOV EAX,ECX + JMP V2GetCharStatsBIN +}} + +FCT_ASM ( D2GetItemStatCostBIN_111 ) + MOV EAX,ECX + JMP V2GetItemStatCostBIN +}} + +FCT_ASM ( D2SendToServer3_111 ) + PUSH EBX + PUSH ECX + MOV BYTE PTR SS:[ESP],CL + MOV WORD PTR SS:[ESP+1],DX + MOV EBX,3 + LEA EDX,DWORD PTR SS:[ESP] + PUSH EDX + CALL D2SendToServerXX + POP ECX + POP EBX + RETN +}} + +FCT_ASM ( D2PrintStat_111 ) + PUSH ESI + MOV ESI,DWORD PTR SS:[ESP+0x14] + MOV EAX,DWORD PTR SS:[ESP+0x08] + PUSH DWORD PTR SS:[ESP+0x10] + PUSH DWORD PTR SS:[ESP+0x10] + PUSH EDX + PUSH ECX + CALL V2PrintStat + POP ESI + RETN 0x10 +}} + +FCT_ASM ( D2SendPacket_111 ) + POP EAX + PUSH EDX + PUSH EAX + MOV EAX,ECX + JMP V2SendPacket +}} + +FCT_ASM ( D2LoadInventory_111 ) + MOV EAX,DWORD PTR SS:[ESP+4] + MOV DWORD PTR SS:[ESP+4],EDX + JMP V2LoadInventory +}} + +FCT_ASM ( D2CompileCubeInput_111 ) + PUSH EBX + MOV EBX,ECX + MOV EAX,EDX + CALL V2CompileCubeInput + POP EBX + RETN 8 +}} + +FCT_ASM ( D2CompileCubeOutput_111 ) + PUSH EBX + MOV EBX,ECX + PUSH EDX + CALL V2CompileCubeOutput + POP EBX + RETN 8 +}} + +FCT_ASM ( D2BroadcastFunction_111 ) + PUSH EDI + PUSH EBX + MOV EAX,ECX + MOV EDI,EDX + MOV EBX,DWORD PTR SS:[ESP+0xC] + CALL V2BroadcastFunction + POP EBX + POP EDI + RETN 4 +}} + +FCT_ASM ( D2SpawnMonster_111 ) + PUSH DWORD PTR SS:[ESP+0x18] + PUSH DWORD PTR SS:[ESP+0x14] + PUSH DWORD PTR SS:[ESP+0x14] + PUSH DWORD PTR SS:[ESP+0x14] + PUSH ECX + MOV ECX,DWORD PTR SS:[ESP+0x18] + MOV EAX,DWORD PTR SS:[ESP+0x28] + CALL V2SpawnMonster + RETN 0x18 +}} + +FCT_ASM ( D2SpawnMonster_111b ) + PUSH DWORD PTR SS:[ESP+0x10] + PUSH DWORD PTR SS:[ESP+0x10] + PUSH DWORD PTR SS:[ESP+0x10] + PUSH EDX + PUSH ECX + MOV EAX,DWORD PTR SS:[ESP+0x18] + MOV EDX,DWORD PTR SS:[ESP+0x2C] + MOV ECX,DWORD PTR SS:[ESP+0x28]//superuniqueID + CALL V2SpawnMonster + RETN 0x18 +}} + +FCT_ASM ( D2VerifIfNotCarry1_111 ) + PUSH EBX + PUSH ECX + MOV EBX,EDX + MOV EAX,DWORD PTR SS:[ESP+0xC] + CALL V2VerifIfNotCarry1 + POP EBX + RETN 4 +}} + +FCT_ASM ( D2GameGetObject_111 ) + MOV EAX,EDX + MOV EDX,DWORD PTR SS:[ESP+4] + CALL V2GameGetObject + RETN 4 +}} + + +FCT_ASM ( D2TestPositionInRoom_111 ) + PUSH EDI + PUSH EBX + MOV EDI,DWORD PTR SS:[ESP+0xC] + MOV EAX,ECX + MOV EBX,EDX + CALL V2TestPositionInRoom + POP EBX + POP EDI + RETN 4 +}} + +FCT_ASM ( D2GetItemTypesBIN_111) + MOV EAX,ECX + JMP V2GetItemTypesBIN +}} + +//FCT_ASM ( D2OpenNPCMenu_111) +// MOV ESI,ECX +// JMP V2OpenNPCMenu +//}} +FCT_ASM ( D2SendToServer_1XX ) + PUSH DWORD PTR SS:[ESP+0x4] + PUSH DWORD PTR SS:[ESP+0x10] + PUSH 0 + CALL V2SendToServer + RETN 0xC +}} + + +FCT_ASM ( D2GetGameByClientID_1XX ) + POP EAX + POP ECX + PUSH EAX + JMP V2GetGameByClientID +}} + +FCT_ASM ( D2SaveGame_1XX ) + POP EAX + POP ECX + PUSH EAX + JMP V2SaveGame +}} + +#define SETFCTADDR(F, I, N) setFctAddr((DWORD*)&N, (HMODULE)offset_##F, (LPCSTR)I) +void setFctAddr(DWORD* addr, HMODULE module, LPCSTR index) +{ + if (index) + { + *addr = (DWORD)GetProcAddress(module,index); + if (!*addr) + { + log_msg("Bad index fct %d for %08X\n",index,module); + } + } else + *addr = NULL; +} + +bool initD2functions() +{ +// #define D2S(F, I, R, N, P) N = (F##I)GetProcAddress((HMODULE)offset_##F, (LPCSTR)I); +// #define D2F(F, I, R, N, P) N = (F##I)GetProcAddress((HMODULE)offset_##F, (LPCSTR)I); + #define D2S(F, I, R, N, P) SETFCTADDR(F, I, N); + #define D2F(F, I, R, N, P) SETFCTADDR(F, I, N); + #define E2S(F, A, R, N, P) N = (T##N)(offset_##F + 0x##A); + #define E2F(F, A, R, N, P) N = (T##N)(offset_##F + 0x##A); + #define E2C(F, A, T, N) pt##N = (T*)(offset_##F + 0x##A); + #define F7(X, Z, A,B,C,D,E,F,G, R, N, P) setFctAddr((DWORD*)&N, (HMODULE)offset_##Z, (LPCSTR)((version_##Z == V113? G : (version_##Z == V112? F : version_##Z == V111b? E : (version_##Z == V111? D : (version_##Z == V110? C : (version_##Z == V109d? B : A))))))); + #define A7(X, Z, A,B,C,D,E,F,G, R, N, P) N = (T##N)R7(Z,A,B,C,D,E,F,G); + #define C7(Z, A,B,C,D,E,F,G, T, N) pt##N = (T*)R7(Z,A,B,C,D,E,F,G); + + #include "../Commons/D2Funcs.h" + SgptDataTables = *(DataTables**) R7(D2Common, 0000, 0000, 96A20, 9B74C, 9EE8C, 9B500, 99E1C); + if (version_D2Common < V110) + { + D2S(D2Common,10581, CharStatsBIN*, D2Common10581, (DWORD charID));//ONLY in 1.09 + D2S(D2Common,10598, ItemStatCostBIN*, D2Common10598, (DWORD itemStatCostID));//ONLY in 1.09 + D2S(D2Common,10673, ItemTypesBIN*, D2Common10673, (DWORD itemTypesID));//ONLY in 1.09 + } + #undef F7 + #undef A7 + #undef C7 + #undef D2S + #undef D2F + #undef E2S + #undef E2F + #undef E2C + + + //////////////// MISC FCT //////////////// + //setImage = version_D2Common >= V111 ? setImage_111 : setImage_1XX; + //setFrame = version_D2Common >= V111 ? setFrame_111 : setFrame_1XX; + getDescStrPos = version_D2Common >= V110 ? getDescStrPos_10 : getDescStrPos_9; + compileTxtFile = version_D2Common >= V111 ? compileTxtFile_111 : version_D2Common == V110 ? compileTxtFile_10 : compileTxtFile_9; + + + //////////////// SELECT RIGHT ADDR FUNCTION //////////////// +//#define V3(V,T,F,A,B,C,D)\ +// if (version_##F == V109b) V = (T) (offset_##F + 0x##A);\ +// else if (version_##F == V109d) V = (T) (offset_##F + 0x##B);\ +// else if (version_##F == V110) V = (T) (offset_##F + 0x##C);\ +// else if (version_##F == V111) V = (T) (offset_##F + 0x##D) + + //if (version_D2Common != V111b) + //{ + //SETFCTADDR( D2Common, 10332, D2GetLevelID); + //SETFCTADDR( D2Common, 10623, D2GetDropRoom); + //SETFCTADDR( D2Common, 10461, D2InvRemoveItem); + //SETFCTADDR( D2Common, 10855, D2CanPutItemInInv); + //SETFCTADDR( D2Common, 10880, D2InvAddItem); + //SETFCTADDR( D2Common, 10402, D2InventoryGetFirstItem); + //SETFCTADDR( D2Common, 10934, D2UnitGetNextItem); + //SETFCTADDR( D2Common, 11095, D2GetRealItem); + //SETFCTADDR( D2Common, 11080, D2GetPosition); + //SETFCTADDR( D2Common, 10455, D2GetMaxGoldBank); + //SETFCTADDR( D2Common, 10172, D2GetRoom); + //SETFCTADDR( D2Common, 10218, D2InitPlayerData); + //SETFCTADDR( D2Common, 10914, D2FreePlayerData); + //SETFCTADDR( D2Common, 10562, D2GetPlayerData); + //SETFCTADDR( D2Common, 10343, D2GetMaxGold); + //SETFCTADDR( D2Common, 10500, D2GetGemsBIN); + //SETFCTADDR( D2Common, 10109, D2AddPlayerStat); + //SETFCTADDR( D2Common, 11092, D2GetPlayerStat); + //SETFCTADDR( D2Common, 10733, D2GetPlayerBaseStat); + //SETFCTADDR( D2Common, 10653, D2CompileTxtFile); + //SETFCTADDR( D2Common, 10573, D2GetItemsBIN); + //SETFCTADDR( D2Common, 10687, D2GetNbRunesBIN); + //SETFCTADDR( D2Common, 10775, D2GetRunesBIN); + //SETFCTADDR( D2Common, 10450, D2GetSuperUniqueBIN); + //SETFCTADDR( D2Common, 10927, D2GetItemQuality); + //SETFCTADDR( D2Common, 10911, D2TestFlags); + //SETFCTADDR( D2Common, 10898, D2GetItemLevel); + //SETFCTADDR( D2Common, 10820, D2ItemGetPage); + //SETFCTADDR( D2Common, 10485, D2ItemSetPage); + //SETFCTADDR( D2Common, 11017, D2CheckItemType); + //SETFCTADDR( D2Common, 10692, D2GetUniqueID); + //SETFCTADDR( D2Common, 10816, D2GetNbSocket); + //SETFCTADDR( D2Common, 10880, D2isEtheral); + //SETFCTADDR( D2Common, 10956, D2SaveItem); + //SETFCTADDR( D2Common, 10950, D2IncSkillBaseLevel); + //SETFCTADDR( D2Common, 10700, D2GetSkillLevel); + //SETFCTADDR( D2Common, 10027, D2Common10027); + //SETFCTADDR( D2Common, 10099, D2SetSkillBaseLevel); + //SETFCTADDR( D2Common, 10746, D2GetCubeMainBIN); + //SETFCTADDR( D2Common, 10639, D2GetNbCubeMainBIN); + //SETFCTADDR( D2Common, 10254, D2GetSkillCost); + //SETFCTADDR( D2Common, 10471, D2GetObjectFlags); + //SETFCTADDR( D2Common, 10572, D2SetObjectFlags); + //SETFCTADDR( D2Common, 10188, D2Common11084); + //SETFCTADDR( D2Common, 10440, D2Common10572); + //SETFCTADDR( D2Common, 10655, D2GetDifficultyLevelsBIN); + //SETFCTADDR( D2Game, 10039, D2SetNbPlayers); + //SETFCTADDR( D2Win, 10061, D2PrintLineOnTextBox); + //SETFCTADDR( D2Win, 10020, D2PrintString); + //SETFCTADDR( D2Win, 10034, D2GetPixelLen); + //SETFCTADDR( D2Win, 10141, D2SetFont); + //SETFCTADDR( D2Win, 10118, D2PrintPopup); + //SETFCTADDR( D2Win, 10147, D2CreateTextBox); + //SETFCTADDR( D2Lang, 10009, D2GetLang); + //SETFCTADDR( D2Lang, 10005, D2GetStringFromIndex); + //SETFCTADDR( D2gfx, 10000, D2GetResolution); + //SETFCTADDR( D2gfx, 10047, D2PrintImage); + //SETFCTADDR( D2gfx, 10028, D2FillArea); + //SETFCTADDR( D2Net, 10035, D2SendToServer); + ////SETFCTADDR( D2Net, 10018, D2SendToClient);//SAME IN BOTH VERSION + //SETFCTADDR( D2CMP, 10021, D2CMP10014); + //if (version_D2Common != V111) + //{ + //setImage = setImage_1XX; + //setFrame = setFrame_1XX; + //SETFCTADDR( D2Common, 10057, D2GetLevelID); + //SETFCTADDR( D2Common, 10138, D2GetDropRoom); + //SETFCTADDR( D2Common, 10243, D2InvRemoveItem); + //SETFCTADDR( D2Common, 10246, D2CanPutItemInInv); + //SETFCTADDR( D2Common, 10249, D2InvAddItem); + //SETFCTADDR( D2Common, 10277, D2InventoryGetFirstItem); + //SETFCTADDR( D2Common, 10304, D2UnitGetNextItem); + //SETFCTADDR( D2Common, 10305, D2GetRealItem); + //SETFCTADDR( D2Common, 10332, D2GetPosition); + //SETFCTADDR( D2Common, 10339, D2GetMaxGoldBank); + //SETFCTADDR( D2Common, 10342, D2GetRoom); + //SETFCTADDR( D2Common, 10420, D2InitPlayerData); + //SETFCTADDR( D2Common, 10421, D2FreePlayerData); + //SETFCTADDR( D2Common, 10424, D2GetPlayerData); + //SETFCTADDR( D2Common, 10439, D2GetMaxGold); + //SETFCTADDR( D2Common, 10616, D2GetGemsBIN); + //SETFCTADDR( D2Common, 10518, D2AddPlayerStat); + //SETFCTADDR( D2Common, 10519, D2GetPlayerStat); + //SETFCTADDR( D2Common, 10521, D2GetPlayerBaseStat); + //SETFCTADDR( D2Common, 10578, D2CompileTxtFile); + //SETFCTADDR( D2Common, 10600, D2GetItemsBIN); + //SETFCTADDR( D2Common, 10619, D2GetNbRunesBIN); + //SETFCTADDR( D2Common, 10620, D2GetRunesBIN); + //SETFCTADDR( D2Common, 10668, D2GetSuperUniqueBIN); + //SETFCTADDR( D2Common, 10695, D2GetItemQuality); + //SETFCTADDR( D2Common, 10707, D2TestFlags); + //SETFCTADDR( D2Common, 10717, D2GetItemLevel); + //SETFCTADDR( D2Common, 10719, D2ItemGetPage); + //SETFCTADDR( D2Common, 10720, D2ItemSetPage); + //SETFCTADDR( D2Common, 10731, D2CheckItemType); + //SETFCTADDR( D2Common, 10732, D2GetUniqueID); + //SETFCTADDR( D2Common, 10816, D2GetNbSocket); + //SETFCTADDR( D2Common, 11163, D2isEtheral); + //SETFCTADDR( D2Common, 10881, D2SaveItem); + //SETFCTADDR( D2Common, 10952, D2IncSkillBaseLevel); + //SETFCTADDR( D2Common, 10968, D2GetSkillLevel); + //SETFCTADDR( D2Common, 10940, D2Common10027); + //SETFCTADDR( D2Common, 10953, D2SetSkillBaseLevel); + //SETFCTADDR( D2Common, 11232, D2GetCubeMainBIN); + //SETFCTADDR( D2Common, 11233, D2GetNbCubeMainBIN); + //SETFCTADDR( D2Common, 11276, D2GetSkillCost); + //SETFCTADDR( D2Common, 10655, D2GetDifficultyLevelsBIN); + //SETFCTADDR( D2Game, 10059, D2SetNbPlayers); + //SETFCTADDR( D2Win, 10046, D2PrintLineOnTextBox); + //SETFCTADDR( D2Win, 10117, D2PrintString); + //SETFCTADDR( D2Win, 10121, D2GetPixelLen); + //SETFCTADDR( D2Win, 10127, D2SetFont); + //SETFCTADDR( D2Win, 10129, D2PrintPopup); + //SETFCTADDR( D2Win, 10017, D2CreateTextBox); + //SETFCTADDR( D2Lang, 10007, D2GetLang); + //SETFCTADDR( D2Lang, 10004, D2GetStringFromIndex); + //SETFCTADDR( D2gfx, 10005, D2GetResolution); + //SETFCTADDR( D2gfx, 10072, D2PrintImage); + //SETFCTADDR( D2gfx, 10055, D2FillArea); + //SETFCTADDR( D2Net, 10005, D2SendToServer); //(DWORD zero, void* data, DWORD size) + //SETFCTADDR( D2Net, 10006, D2SendToClient); + //SETFCTADDR( Fog, 10023, D2FogAssertOld); + //SETFCTADDR( D2CMP, 10032, D2CMP10014); + //} + //} + + //V3(ptResolutionY, DWORD*, D2Client, D50E8, D40E0, D40F0, F5C60); + //V3(ptResolutionX, DWORD*, D2Client, D50EC, D40E4, D40F4, F5C5C); + //V3(ptNegWindowStartY, DWORD*, D2Client, 125AD8, 124958, 11A74C, 11BD28); + //V3(ptWindowStartX, DWORD*, D2Client, 125AD4, 124954, 11A748, 11BD24); + //V3(ptGameTypeMode, DWORD*, D2Launch, 55818, 56088, 2CD5C, 0000); + //V3(ptClientTable, NetClient**, D2Game, F2A80, F2918, 113FB8, 111718); + //V3(ptIsLodGame, DWORD*, D2Client, 0000, 0000, 0000, FB3F4); + //V3(ptDifficultyLevel, BYTE*, D2Client, 0000, 0000, 10795C, 11BFB8); + //V3(ptMouseY, DWORD*, D2Client, 0000, 0000, 0000, 10A40C); + //V3(ptMouseX, DWORD*, D2Client, 0000, 0000, 0000, 10A410); + //V3(ptptClientChar, Unit**, D2Client, 0000, 0000, 0000, 11C4F0); + //V3(ptNbStatDesc, DWORD*, D2Client, DB918, DA828, 0000, 0000); + //V3(ptStatDescTable, DWORD*, D2Client, DAF98, D9EA8, 0000, 0000); + + //V3(D2LoadImage, TD2LoadImage, D2Client, 1000, 1000, 1000, 75D00); + //V3(D2FreeImage, TD2FreeImage, D2Client, 1150, 1150, 1140, 0000); + //V3(D2CleanStatMouseUp, TD2CleanStatMouseUp, D2Client, B920, B910, BF60, 0000); + //V3(D2isLODGame, TD2isLODGame, D2Client, BA00, B9F0, C080, 0000); + //V3(D2GetDifficultyLevel,TD2GetDifficultyLevel, D2Client, 000, 000, C090, 0000);//1.09 should be BA10 (b) BA00 (d) + //V3(D2SendToServer3, TD2SendToServer3, D2Client, D210, D200, D990, 0000); + //V3(D2SendToServer7, TD2SendToServer7, D2Client, 000, 000, D9E0, 0000); + //V3(D2SendToServer5, TD2SendToServer5, D2Client, 000, 000, DA20, 0000); + //V3(D2SendToServer9, TD2SendToServer9, D2Client, 000, 000, DA40, 0000); + //V3(D2SendToServer13, TD2SendToServer13, D2Client, 000, 000, DA70, 0000); + //V3(D2SendMsgToAll, TD2SendMsgToAll, D2Client, D640, D630, DB50, 73620); + //V3(D2PrintStatsPage, TD2PrintStatsPage, D2Client, 29800, 297F0, 2FD60, 828A0); + //V3(D2SetColorPopup, TD2SetColorPopup, D2Client, 85A60, 84DE0, 80430, 9EEB0); + //V3(D2SendToServerXX, TD2SendToServerXX, D2Client, 000, 000, 000, 73260); + //V3(D2TogglePage, TD2TogglePage, D2Client, 88940, 87CC0, 83260, A1F30); + //V3(D2LoadBuySelBtn, TD2LoadBuySelBtn, D2Client, 897B0, 88B30, 84110, 9E3B0); + //V3(D2GetClientPlayer, TD2GetClientPlayer, D2Client, 8DC40, 8CFC0, 883D0, 0000); + //V3(D2PlaySound, TD2PlaySound, D2Client, B4360, B36E0, B5820, 3ACC0); + //V3(D2GetMouseX, TD2GetMouseX, D2Client, B6670, B59F0, B7BC0, 0000); + //V3(D2GetMouseY, TD2GetMouseY, D2Client, B6680, B5A00, B7BD0, 0000); +// //V3(D2FillRect, TD2FillRect, D2Client, B9970, B8CF0, BB0F0, 0000); + + //V3(D2PrintStat, TD2PrintStat, D2Client, 4BB20, 4BB20, 521C0, B8CB0); + + //V3(D2AddClient, TD2AddClient, D2Game, 000, 000, 6C60, E3DA0); + //V3(D2SendPacket, TD2SendPacket, D2Game, C380, C650, C710, 41420); + //V3(D2GetGameByClientID, TD2GetGameByClientID, D2Game, 000, 000, 94E0, E0520); + //V3(D2BroadcastFunction, TD2BroadcastFunction, D2Game, 000, 000, B0E0, DF250); + //V3(D2SetSkillBaseLevelOnClient, TD2SetSkillBaseLevelOnClient,D2Game, D650, D920, DB50, 44D00); + //V3(D2VerifIfNotCarry1, TD2VerifIfNotCarry1, D2Game, 000, 000, 128F0, 38D90); + //V3(D2TestPositionInRoom,TD2TestPositionInRoom, D2Game, 000, 000, 22070, 01090); + //V3(D2LoadInventory, TD2LoadInventory, D2Game, 4F100, 4F500, 5B8A0, B9D70); + //V3(D2GameGetObject, TD2GameGetObject, D2Game, 7BAE0, 7BFD0, 8BB00, 97620); + //V3(D2GetClient, TD2GetClient, D2Game, 7C2C0, 7C7B0, 8C2E0, 000); + //V3(D2GetOwnerMonster, TD2GetOwnerMonster, D2Game, 000, 000, 9F320, 501C0); + //V3(D2ReadFile, TD2ReadFile, D2Common, 738A4, 739B4, 84268, 96E0);//1.11 + //V3(D2CompileCubeInput, TD2CompileCubeInput, D2Common, 000, 000, 12410, 5D7D0); + //V3(D2CompileCubeOutput, TD2CompileCubeOutput, D2Common, 000, 000, 12910, 5D210); + //V3(D2GetCharStatsBIN, TD2GetCharStatsBIN, D2Common, 000, 000, 82C80, 015D0); + //V3(D2LoadSuperuniques, TD2LoadSuperuniques, D2Common, 1F500, 1F510, 29FA0, 71EB0); + //V3(D2GetItemStatCostBIN,TD2GetItemStatCostBIN, D2Common, 000, 000, 642B0, 13F0); + //V3(D2GetItemTypesBIN, TD2GetItemTypesBIN, D2Common, 000, 000, 2B1A0, 11F0); + //V3(D2SpawnMonster, TD2SpawnMonster, D2Game, 000, 000, 3F220, 4ABE0); + //V3(D2ReloadGambleScreen,TD2ReloadGambleScreen, D2Game, 000, 000, 000, 8E480); + //V3(D2SaveGame, TD2SaveGame, D2Game, 000, 000, 89C0, E2390); + //V3(D2ClickOnStashButton,TD2ClickOnStashButton, D2Client, 000, 000, 000, A6520); + //V3(D2CreateUnit, TD2CreateUnit, D2Game, 000, 000, 000, 99760); + //V3(D2LinkPortal, TD2LinkPortal, D2Game, 000, 000, 000, 27230); + //V3(D2Game235C0, TD2Game235C0, D2Game, 000, 000, 000, D6D10); + //V3(D2OpenPandPortal, TD2OpenPandPortal, D2Game, 000, 000, 000, 9B480); + //V3(D2OpenPandFinalPortal,TD2OpenPandFinalPortal,D2Game, 000, 000, 000, 9B470); + //V3(D2MephIA, TD2MephIA, D2Game, 000, 000, 000, 84730); + //V3(D2DiabloIA, TD2DiabloIA, D2Game, 000, 000, 000, 75980); + //V3(D2BaalIA, TD2BaalIA, D2Game, 000, 000, 000, EAB20); + //V3(D2UberMephIA, TD2UberMephIA, D2Game, 000, 000, 000, 70320); + //V3(D2UberDiabloIA, TD2UberDiabloIA, D2Game, 000, 000, 000, 7F200); + //V3(D2UberBaalIA, TD2UberBaalIA, D2Game, 000, 000, 000, E92B0); + +//#undef V3 + + //V2SetPlayerStat = D2SetPlayerStat; + V2AddPlayerStat = D2AddPlayerStat; + V2GetPlayerStat = D2GetPlayerStat; + //V2GetPlayerStat20 = D2GetPlayerStat20; + V2GetPlayerBaseStat = D2GetPlayerBaseStat; + V2SetSkillBaseLevel = D2SetSkillBaseLevel; + V2SetSkillBaseLevelOnClient = D2SetSkillBaseLevelOnClient; + V2PrintStat = D2PrintStat; + V2SendMsgToAll = D2SendMsgToAll; + V2SetColorPopup = D2SetColorPopup; + V2LoadImage = D2LoadImage; + V2PlaySound = D2PlaySound; + V2GetCharStatsBIN = D2GetCharStatsBIN; + V2GetItemStatCostBIN = D2GetItemStatCostBIN; + V2SendToServer = D2SendToServer; + V2SendPacket = D2SendPacket; + V2LoadInventory = D2LoadInventory; + V2CompileCubeInput = D2CompileCubeInput; + V2CompileCubeOutput = D2CompileCubeOutput; + V2BroadcastFunction = D2BroadcastFunction; + V2GetGameByClientID = D2GetGameByClientID; + V2SpawnMonster = D2SpawnMonster; + V2VerifIfNotCarry1 = D2VerifIfNotCarry1; + V2GameGetObject = D2GameGetObject; + V2TestPositionInRoom = D2TestPositionInRoom; + V2GetItemTypesBIN = D2GetItemTypesBIN; + V2SaveGame = D2SaveGame; + //V2OpenNPCMenu = D2OpenNPCMenu; + //////////////// REDIRECT ON CUSTOM FUNCTIONS //////////////// + + if ( version_D2Client >= V111 ) + { + D2SendMsgToAll = (TD2SendMsgToAll) D2SendMsgToAll_111; + D2SetColorPopup = (TD2SetColorPopup) D2SetColorPopup_111; + D2LoadImage = (TD2LoadImage) D2LoadImage_111; + D2FreeImage = (TD2FreeImage) D2FreeImage_111; + D2PlaySound = (TD2PlaySound) D2PlaySound_111; + D2GetClient = (TD2GetClient) D2GetClient_111; + D2SendToServer3 = (TD2SendToServer3) D2SendToServer3_111; + D2SetSkillBaseLevelOnClient = (TD2SetSkillBaseLevelOnClient) D2SetSkillBaseLevelOnClient_111; + D2GetCharStatsBIN = (TD2GetCharStatsBIN) D2GetCharStatsBIN_111; + D2GetItemStatCostBIN = (TD2GetItemStatCostBIN) D2GetItemStatCostBIN_111; + D2PrintStat = (TD2PrintStat) D2PrintStat_111; + D2SendPacket = (TD2SendPacket) D2SendPacket_111; + D2LoadInventory = (TD2LoadInventory) D2LoadInventory_111; + D2CompileCubeInput = (TD2CompileCubeInput) D2CompileCubeInput_111; + D2CompileCubeOutput = (TD2CompileCubeOutput) D2CompileCubeOutput_111; + D2BroadcastFunction = (TD2BroadcastFunction) D2BroadcastFunction_111; + D2SpawnMonster = version_D2Game >= V111b ? (TD2SpawnMonster)D2SpawnMonster_111b : (TD2SpawnMonster)D2SpawnMonster_111; + D2VerifIfNotCarry1 = (TD2VerifIfNotCarry1) D2VerifIfNotCarry1_111; + D2GameGetObject = (TD2GameGetObject) D2GameGetObject_111; + D2GetItemTypesBIN = (TD2GetItemTypesBIN) D2GetItemTypesBIN_111; + D2TestPositionInRoom = (TD2TestPositionInRoom) D2TestPositionInRoom_111; + //D2OpenNPCMenu = (TD2OpenNPCMenu) D2OpenNPCMenu_111; + D2isLODGame = D2isLODGame_111; + D2GetDifficultyLevel = D2GetDifficultyLevel_111; + D2GetMouseX = D2GetMouseX_111; + D2GetMouseY = D2GetMouseY_111; + D2GetClientPlayer = D2GetClientPlayer_111; + D2GetRealItem = D2GetRealItem_111; + D2CleanStatMouseUp = D2CleanStatMouseUp_111; + StatMouse1 = (DWORD*)R7(D2Client, 0000, 0000, 0000, 11C004, 11C2F4, 11C040, 11C3DC); + StatMouse2 = (DWORD*)R7(D2Client, 0000, 0000, 0000, 11C008, 11C2F8, 11C044, 11C3E0); + StatMouse3 = (DWORD*)R7(D2Client, 0000, 0000, 0000, 11C020, 11C310, 11C05C, 11C3F8); + StatMouse4 = (DWORD*)R7(D2Client, 0000, 0000, 0000, 11C024, 11C314, 11C060, 11C3FC); + } else { + D2SendToServer = (TD2SendToServer) D2SendToServer_1XX; + D2GetGameByClientID = (TD2GetGameByClientID) D2GetGameByClientID_1XX; + D2SaveGame = (TD2SaveGame) D2SaveGame_1XX; + } + + if ( version_D2Common <= V109d ) + { + //D2SetPlayerStat = (TD2SetPlayerStat) D2SetPlayerStat_9; + D2AddPlayerStat = (TD2AddPlayerStat) D2AddPlayerStat_9; + D2GetPlayerStat = (TD2GetPlayerStat) D2GetPlayerStat_9; + //D2GetPlayerStat20 = (TD2GetPlayerStat20) D2GetPlayerStat20_9; + D2GetPlayerBaseStat = (TD2GetPlayerBaseStat) D2GetPlayerBaseStat_9; + D2SetSkillBaseLevel = (TD2SetSkillBaseLevel) D2SetSkillBaseLevel_9; + D2GetCharStatsBIN = (TD2GetCharStatsBIN) D2GetCharStatsBIN_9; + D2GetItemStatCostBIN = (TD2GetItemStatCostBIN) D2GetItemStatCostBIN_9; + D2GetItemTypesBIN = (TD2GetItemTypesBIN) D2GetItemTypesBIN_9; + } + + if ( version_D2Client <= V109d ) + D2PrintStat = (TD2PrintStat) D2PrintStat_9; + + if ( version_D2Game <= V109d ) + D2SetSkillBaseLevelOnClient = (TD2SetSkillBaseLevelOnClient) D2SetSkillBaseLevelOnClient_9; + + + //////////////// STRUCTURE MANAGEMENT //////////////// + +// shifting.ptPYPlayerData = V7(D2Common,118,118,F4,F4,F4,F4,F4); + shifting.ptPYPlayerData = *(DWORD*)((DWORD)D2InitPlayerData + V7(D2Common,5D,5D,5D,49,49,49,49)); + shifting.ptSpecificData = V7(D2Common,70,70,14,14,14,14,14); + shifting.ptGame = V7(D2Common,A4,A4,80,80,80,80,80); + shifting.ptClientGame = V7(D2Common,170,194,1A8,1A8,1A8,1A8,1A8); + shifting.ptInventory = V7(D2Common,84,84,60,60,60,60,60); + shifting.ptSkills = V7(D2Common,CC,CC,A8,A8,A8,A8,A8); + shifting.ptImage = V7(D2Common,04,04,04,08,08,3C,34); + shifting.ptFrame = V7(D2Common,08,08,08,44,44,40,00); + return true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/D2wrapper.cpp b/PlugY/D2wrapper.cpp new file mode 100644 index 0000000..7552405 --- /dev/null +++ b/PlugY/D2wrapper.cpp @@ -0,0 +1,562 @@ +/*================================================================= + File created by Yohann NICOLAS. + + @file D2wrapper.cpp + @brief Main Diablo II extra DLL handler. + + This is the sources of the D2DLL class. + +=================================================================*/ + +// Core Class Headers +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "customLibraries.h" + +/* Beginning of Custom Header */ +#include "globalVariable.h" // Install_VariableOnRealm() +#include "commands.h" // Install_Commands() +#include "othersFeatures.h" // Install_ChangeResolution() +#include "mainScreen.h" // Install_PrintPlugYVersion() Install_VersionChange() +#include "savePath.h" // Install_ChangingSavePath() +#include "bigStash.h" // Install_BigStash() +#include "skillPerLevelUp.h" // Install_SkillPerLevelUp() +#include "statPerLevelUp.h" // Install_StatPerLevelUp() +#include "statsPoints.h" // Install_StatsPoints() Install_StatsLimitShiftClick() +#include "skillsPoints.h" // Install_SkillsPoints() +#include "infinityStash.h" // Install_MultiPageStash() +#include "newInterfaces.h" // Install_NewInterfaces() +#include "worldEvent.h" // Install_WorldEvent() +#include "uberQuest.h" // Install_UberQuest() +#include "extraOptions.h" // Install_AlwaysRegenMapInSP() +#include "language.h" // Install_LanguageManagement() + + +int version_SmackW32=V113; +int version_D2Common=V113; +int version_ijl11=V113; +int version_D2Gdi=V113; +int version_D2Win=V113; +int version_D2sound=V113; +int version_D2MCPCLI=V113; +int version_D2Launch=V113; +int version_D2gfx=V113; +int version_D2Client=V113; +int version_D2Net=V113; +int version_D2Lang=V113; +int version_D2Game=V113; +int version_D2CMP=V113; +int version_Bnclient=V113; +int version_Fog=V113; +int version_Storm=V113; + + +DWORD offset_SmackW32=NULL; +DWORD offset_D2Common=NULL; +DWORD offset_ijl11=NULL; +DWORD offset_D2Gdi=NULL; +DWORD offset_D2Win=NULL; +DWORD offset_D2sound=NULL; +DWORD offset_D2Multi=NULL; +DWORD offset_D2MCPCLI=NULL; +DWORD offset_D2Launch=NULL; +DWORD offset_D2gfx=NULL; +DWORD offset_D2Game=NULL; +DWORD offset_D2Client=NULL; +DWORD offset_D2Net=NULL; +DWORD offset_D2Lang=NULL; +DWORD offset_D2CMP=NULL; +DWORD offset_Bnclient=NULL; +DWORD offset_Fog=NULL; +DWORD offset_Storm=NULL; +// manque : Game.exe D2DDraw.dll D2Direct3D.dll D2Glide.dll + +const char* S_SmackW32 = "SmackW32.dll"; +const char* S_D2Common = "D2Common.dll"; +const char* S_ijl11 = "ijl11.dll"; +const char* S_D2Gdi = "D2Gdi.dll"; +const char* S_D2Win = "D2Win.dll"; +const char* S_D2sound = "D2sound.dll"; +const char* S_D2Multi = "D2Multi.dll"; +const char* S_D2MCPCLI = "D2MCPClient.dll"; +const char* S_D2Launch = "D2Launch.dll"; +const char* S_D2gfx = "D2gfx.dll"; +const char* S_D2Game = "D2Game.dll"; +const char* S_D2Client = "D2Client.dll"; +const char* S_D2Net = "D2Net.dll"; +const char* S_D2Lang = "D2Lang.dll"; +const char* S_D2CMP = "D2CMP.dll"; +const char* S_Bnclient = "Bnclient.dll"; +const char* S_Fog = "Fog.dll"; +const char* S_Storm = "Storm.dll"; + +const char* S_CloneBattles ="CloneBattles.dll"; +const char* S_DarkAlliance ="DarkAlliance.dll"; + +DWORD loadLibrary( const char* libraryName) +{ + DWORD offset; +/* char currentpath[MAX_PATH]; + + if (!strcmp(libraryName,"D2Common.dll") || !strcmp(libraryName,"D2Game.dll") || !strcmp(libraryName,"D2Client.dll")) + { + GetCurrentDirectory(MAX_PATH,currentpath); + strncat(currentpath,"\\",MAX_PATH); + strncat(currentpath,libraryName,MAX_PATH); + log_msg("Load = %s : ",currentpath); + offset = (DWORD)LoadLibrary(currentpath); + log_msg("offset = %08X\n",offset); + if (offset) + { + log_msg("%s loaded successfully at: %08X\n", libraryName, offset); + return offset; + } + }*/ + offset = (DWORD)LoadLibrary(libraryName); + if (!offset) + { + log_msg("Failed to load library : %s\n", libraryName); + exit(-1); + } + log_msg("%s loaded successfully at: %08X\n", libraryName, offset); + + return offset; +} + +void freeLibrary( DWORD library ) +{ + if (library) + FreeLibrary((HINSTANCE__ *)library); +} + +// Change the protection scheme of a loaded +// DLL called libraryName in memory space at address addr+size to allow us to customize it. +void hookLibrary(const char* libraryName, DWORD addr) +{ + DWORD dw=0; + BYTE* offsetPESignature = addr + *(BYTE**)((BYTE*)addr + 0x3C); + DWORD sizeOfCode = *(DWORD*)(offsetPESignature + 0x1C); + BYTE* baseOfCode = addr + *(BYTE**)(offsetPESignature + 0x2C); + if( !VirtualProtect(baseOfCode, sizeOfCode, PAGE_EXECUTE_READWRITE, &dw) ) + { + log_msg("Failed to hook library : %s. (%08X,%08X)\n", libraryName ,baseOfCode, sizeOfCode); + exit(-1); + } + log_msg("%s successfully hooked. (%08X,%08X)\n", libraryName ,baseOfCode, sizeOfCode); +} + +void unhookLibrary(const char* libraryName, DWORD addr) +{ + DWORD dw=0; + BYTE* offsetPESignature = addr + *(BYTE**)((BYTE*)addr + 0x3C); + DWORD sizeOfCode = *(DWORD*)(offsetPESignature + 0x1C); + BYTE* baseOfCode = addr + *(BYTE**)(offsetPESignature + 0x2C); + if( !VirtualProtect(baseOfCode, sizeOfCode, PAGE_EXECUTE_READ, &dw) ) + log_msg("Failed to unhook library : %s. (%08X,%08X)\n", libraryName ,baseOfCode, sizeOfCode); + else + log_msg("%s successfully unhooked. (%08X,%08X)\n", libraryName ,baseOfCode, sizeOfCode); +} + + +void loadD2Libraries () +{ + log_msg("***** Load D2 Libraries *****\n"); + + offset_SmackW32 = loadLibrary( S_SmackW32); //0xD000 0x03B90000 Already Loaded - + offset_D2Common = loadLibrary( S_D2Common); //0x8D000 0x037A0000 0x7C000 + offset_ijl11 = loadLibrary( S_ijl11); //0x24000 0x60000000 Already Loaded - + offset_D2Gdi = loadLibrary( S_D2Gdi); //0x7000 0x6F830000 Already Loaded - + offset_D2Win = loadLibrary( S_D2Win); //0x19000 0x6F8A0000 Already Loaded 0x1C000 + offset_D2sound = loadLibrary( S_D2sound); //0xC000 0x6F980000 Already Loaded 0xD000 +// offset_D2Multi = loadLibrary( S_D2Multi); //0x1000 0x6F9A0000 ? +// offset_D2MCPCLI = loadLibrary( S_D2MCPCLI); //0x6000 0x6F9F0000 Already Loaded - + offset_D2Launch = loadLibrary( S_D2Launch); //0x20000 0x6FA10000 Already Loaded 0x1E000 + offset_D2gfx = loadLibrary( S_D2gfx); //0xB000 0x6FA70000 Already Loaded - + offset_D2Game = loadLibrary( S_D2Game); //0xF6000 0x6FC30000 0xCF000 + offset_D2Client = loadLibrary( S_D2Client); //0xCC000 0x6FAA0000 0xCA000 + offset_D2Net = loadLibrary( S_D2Net); //0x6000 0x6FC00000 Already Loaded - + offset_D2Lang = loadLibrary( S_D2Lang); //0x0A000 0x6FC10000 Already Loaded - + offset_D2CMP = loadLibrary( S_D2CMP); //0x18000 0x6FDF0000 Already Loaded 0x19000 + offset_Bnclient = loadLibrary( S_Bnclient); //0x15000 0x6FF00000 Already Loaded - + offset_Fog = loadLibrary( S_Fog); //0x20000 0x6FF50000 Already Loaded 0x1F000 + offset_Storm = loadLibrary( S_Storm); //0x30000 0x6FFB0000 Already Loaded - + + log_msg("\n\n"); +} + + +void freeD2Libraries() +{ + log_msg("***** Free Libraries *****\n"); + + freeLibrary( offset_SmackW32 ); + freeLibrary( offset_D2Common ); + freeLibrary( offset_ijl11 ); + freeLibrary( offset_D2Gdi ); + freeLibrary( offset_D2Win ); + freeLibrary( offset_D2sound ); +// freeLibrary( offset_D2Multi ); +// freeLibrary( offset_D2MCPCLI ); + freeLibrary( offset_D2Launch ); + freeLibrary( offset_D2gfx ); + freeLibrary( offset_D2Game ); + freeLibrary( offset_D2Client ); + freeLibrary( offset_D2Net ); + freeLibrary( offset_D2Lang ); + freeLibrary( offset_D2CMP ); + freeLibrary( offset_Bnclient ); + freeLibrary( offset_Fog ); + freeLibrary( offset_Storm ); + + log_msg("\n\n"); +} + +void hookLibraries() +{ + log_msg("***** Unprotect Libraries *****\n"); + + hookLibrary(S_D2Common, offset_D2Common); + hookLibrary(S_D2Client, offset_D2Client); + hookLibrary(S_D2Lang, offset_D2Lang); + hookLibrary(S_D2Game, offset_D2Game); + hookLibrary(S_Fog, offset_Fog); + hookLibrary(S_Storm, offset_Storm); +// hookLibrary(S_D2Win, offset_D2Win); + hookLibrary(S_D2Launch, offset_D2Launch); + hookLibrary(S_D2gfx, offset_D2gfx); +// hookLibrary(S_D2Gdi, offset_D2Gdi); + + log_msg("\n\n"); +} + +void unhookLibraries() +{ + log_msg("***** Reprotect Libraries *****\n"); + + unhookLibrary(S_D2Common, offset_D2Common); + unhookLibrary(S_D2Client, offset_D2Client); + unhookLibrary(S_D2Lang, offset_D2Lang); + unhookLibrary(S_D2Game, offset_D2Game); + unhookLibrary(S_Fog, offset_Fog); + unhookLibrary(S_Storm, offset_Storm); +// unhookLibrary(S_D2Win, offset_D2Win); + unhookLibrary(S_D2Launch, offset_D2Launch); + unhookLibrary(S_D2gfx, offset_D2gfx); +// unhookLibrary(S_D2Gdi, offset_D2Gdi); + + log_msg("\n\n"); +} + +void freeCustomLibraries() +{ + log_msg("***** Free custom libraries *****\n"); + + TCustomDll* dll=customDlls; + TCustomDll* nextDll; + while (dll) + { + dll->release(); + freeLibrary(dll->offset); + nextDll = dll->nextDll; + D2FogMemDeAlloc(dll,__FILE__,__LINE__,0); + dll = nextDll; + } +} + +void initCustomLibraries() +{ + log_msg("***** Init custom libraries *****\n"); + + TCustomDll* dll=customDlls; + while (dll) + { + dll->init(); + dll = dll->nextDll; + } +} + +void loadCustomLibraries() +{ + char* curString = NULL; + TCustomDll* nextDll; + DWORD offset_currentDll; + + log_msg("***** Custom libraries *****\n"); + + if (dllFilenames) + curString = strtok(dllFilenames,"|"); + + if (!curString) + log_msg("No custom libraries to load.\n"); + else + { + log_msg("Load custom libraries :\n"); + while (curString) + { + if (curString[0]) + { + offset_currentDll = loadLibrary(curString); + if (offset_currentDll) + { + nextDll = customDlls; + customDlls = new(TCustomDll); + customDlls->nextDll = nextDll; + customDlls->initialize(offset_currentDll); + } + } + curString=strtok(NULL,"|"); + } + } + if(dllFilenames) + D2FogMemDeAlloc(dllFilenames,__FILE__,__LINE__,0); + + log_msg("\n\n"); +} + + +/* +void getVersion(DWORD addr, DWORD addr111, int* ver, DWORD v109b, DWORD v109d, DWORD v110, DWORD v111, DWORD v111a, DWORD v111b, DWORD v112, DWORD v113, const char * filename) +{ + log_msg("version of %s\t",filename); + + if (addr==v109b) { + *ver = V109b; + log_msg("1.09b\n"); + } else if (addr==v109d) { + *ver = V109d; + log_msg("1.09d\n"); + } else if (addr==v110) { + *ver = V110; + log_msg("1.10\n"); + } else if ((addr==v111) && (addr111==v111a)) { + *ver = V111; + log_msg("1.11\n"); + } else if ((addr==v111) && (addr111==v111b)) { + *ver = V111b; + log_msg("1.11b\n"); + } else if (addr==v112) { + *ver = V112; + log_msg("1.12\n"); + } else if (addr==v113) { + *ver = V113; + log_msg("1.13\n"); + } else { + *ver = V113; + log_msg("unknow, try with 1.13\n"); + } +} +#define GET_VERSION(F,X,Y,A,B,C,D,E,G,H,I) getVersion(*(DWORD*)(offset_##F + 0x##X), *(DWORD*)(offset_##F + 0x##Y), &version_##F, 0x##A, 0x##B, 0x##C, 0x##D, 0x##E, 0x##G, 0x##H, 0x##I, S_##F) +bool initD2version() +{ + log_msg("***** Get dll versions *****\n"); + + +//GET_VERSION(SmackW32 + GET_VERSION(D2Common, 80, 108, B03A26A0, 9E3DE7CC, 0355C185, 8402CA7A, 42E6C2E5, 43028BA5, E58C71DA, 00000000); +//GET_VERSION(ijl11 + GET_VERSION(D2Gdi, 80, 108, 90CFD95A, 86CE337B, A8CCC67B, 06059D7D, 42E6C248, 43028B2F, 5D6490A2, 00000000); + GET_VERSION(D2Win, 80, 108, B595A0CD, 1995DAD2, A8F5E2FD, B6DAB75A, 42E6C266, 43028B44, 6AA01FF5, 00000000); +//GET_VERSION(D2sound +//GET_VERSION(D2MCPCLI + GET_VERSION(D2Launch, 80, 100, A66532FF, 66678CC5, 686223E5, 80B0E2C6, 42E6C275, 43028B50, 205A4C0F, 00000000); + GET_VERSION(D2gfx, 80, 110, 00949FA8, 018866A8, 401526B2, 575C8A5E, 42E6C22A, 43028B19, ACBE1B9E, 00000000); + GET_VERSION(D2Client, 80, 108, 03522F39, 6730B639, C9817825, 37EC6E13, 42E6C43F, 43028CA5, 61A3B3D5, 00000000); + GET_VERSION(D2Net, 80, 0F0, E60F4DEA, 940E178B, 890FCC0B, C293A9D5, 42E6C20D, 43028B05, 19FA9F76, 00000000); + GET_VERSION(D2Lang, 80, 0F8, 111DCCB7, 13978953, DF917353, B91BAEA2, 42E6C213, 43028B09, B7B3978E, 00000000); + GET_VERSION(D2Game, 80, 108, B0805792, 8BB2C392, 92FA18E6, 00B6F7B7, 42E6C375, 43028C0D, BD8DD8E5, 00000000); + GET_VERSION(D2CMP, 80, 0F8, BA755486, 9A77DFEE, 38F44382, 4059B13F, 42E6C203, 43028AFE, 33A9427B, 00000000); +//GET_VERSION(Bnclient + GET_VERSION(Fog, 80, 100, 6F16123B, 75990846, 7E7ED3C7, D333B997, 42E6C1F0, 43028AF2, D3BD4F1B, 00000000); + GET_VERSION(Storm, E0, 110, 3B4B41D8, 3B8AB1CE, 00004550, 9C2BECC4, 42E6C1CA, 43028AD9, E4FA2944, 00000000); + + log_msg("\n\n"); + return true; +} +*/ + +void getVersion(DWORD addr, int* ver, DWORD v109b, DWORD v109d, DWORD v110, DWORD v111, DWORD v111b, DWORD v112, DWORD v113, const char * filename) +{ + log_msg("version of %s\t",filename); + + if (addr==v109b) { + *ver = V109b; + log_msg("1.09b\n"); + } else if (addr==v109d) { + *ver = V109d; + log_msg("1.09d\n"); + } else if (addr==v110) { + *ver = V110; + log_msg("1.10\n"); + } else if (addr==v111) { + *ver = V111; + log_msg("1.11\n"); + } else if (addr==v111b) { + *ver = V111b; + log_msg("1.11b\n"); + } else if (addr==v112) { + *ver = V112; + log_msg("1.12\n"); + } else if (addr==v113) { + *ver = V113; + log_msg("1.13\n"); + } else { + *ver = V113; + log_msg("unknow, try with 1.13\n"); + } +} +#define GET_VERSION(F,X,A,B,C,D,E,G,H) getVersion(*(DWORD*)(offset_##F + 0x##X), &version_##F, 0x##A, 0x##B, 0x##C, 0x##D, 0x##E, 0x##G, 0x##H, S_##F) +bool initD2version() +{ + log_msg("***** Get dll versions *****\n"); + +//GET_VERSION(SmackW32 + GET_VERSION(D2Common, 10CA, A1E86FDC, B1E86FDC, 72D03B42, F883057E, 16746AC6, 00FE81C3, 74FE85DB); +//GET_VERSION(ijl11 + GET_VERSION(D2Gdi, 105, B4000000, 0B210E00, E4000000, 48000401, 2F000401, 00000000, B7000401); + GET_VERSION(D2Win, 1699, 88686F8C, 84686F8C, D094686F, F0030000, 001435E8, 8B088F44, 0013F5E8); +//GET_VERSION(D2sound +//GET_VERSION(D2MCPCLI + GET_VERSION(D2Launch, 109A, 81E8526F, 01E8526F, 85E8526F, 247C8B00, 00FC6583, 15FF0424, E850E045); + GET_VERSION(D2gfx, 10D, EB000000, 006FA700, 00000010, 2A000401, 19000401, 0B210E00, 00000000); + GET_VERSION(D2Client, 17F, 00000000, 14500000, 12500000, 0D814800, 0D812800, 0DA01000, 0DA03000); + GET_VERSION(D2Net, 16E1, 78B8A73C, 68B8A73C, 10244C8B, 5349E808, 5EA9E808, 105D8B72, 53B9E808); + GET_VERSION(D2Lang, 126D, FC45048B, F445048B, 02C18313, C4830000, 00C6E045, 8B48408B, 0C75FF0C); +// GET_VERSION(D2Game, 1010, D22A78A1, D22910A1, D43FB0A1, 03E8506F, 53E8506F, 89E8506F, 63E8506F); + GET_VERSION(D2Game, 1092, 18968BF1, 38968BF1, 28968BF1, F6335608, C690C5B9, 895FD713, 56535700); + GET_VERSION(D2CMP, 1359, 3C686FE0, 38686FE0, 8BF78B56, 4C880424, 07C71824, CCCCCCCC, C7000005); +//GET_VERSION(Bnclient + GET_VERSION(Fog, 102, D0000006, 10000001, 00000006, 000042E6, 00004302, 0000483C, 00004B95); + GET_VERSION(Storm, 1190, 19E85082, 59E85082, 13C103F6, 0474F685, 8B000321, 3B1074C9, 0D896404); + + log_msg("\n\n"); + return true; +} +//////////////////////////////////// EXPORTS FUNCTIONS //////////////////////////////////// + +extern "C" __declspec(dllexport) void* __stdcall Init(LPSTR IniName) +{ + if (IniName) log_msg("* PlugY is called from D2mod.dll\n\n"); + else log_msg("* PlugY is called from D2gfx.dll\n\n"); + + static int isInstalled = false; + if (isInstalled) return NULL; + isInstalled=true; + + loadD2Libraries(); + + if (!initD2version()) return NULL; + + if (!initD2functions()) return NULL; + + loadParameters(); + + if (!active_plugin) return NULL; + + loadCustomLibraries(); + + hookLibraries(); + + log_msg("***** INSTALL FUNCTIONS *****\n"); + + Install_VariableOnRealm(); + + if (active_Commands) + Install_Commands(); + + if (active_ChangeLanguage || active_LanguageManagement) + Install_LanguageManagement(); + + if (active_VersionTextChange) + Install_VersionChange(); + + if (active_PrintPlugYVersion) + Install_PrintPlugYVersion(); + + if (active_StatsPoints) + Install_StatsPoints(); + else if (active_DisplayBaseStatsValue) + Install_DisplayBaseStatsValue(); + + if (active_SkillsPoints) + Install_SkillsPoints(); + + if (active_changingSavePath) + Install_ChangingSavePath(); + + if (active_StatsShiftClickLimit) + Install_StatsLimitShiftClick(); + + if (active_RunLODs) + Install_RunLODs(); + + if (active_bigStash) + Install_BigStash(); + + if (active_SkillPerLevelUpChange) + Install_SkillPerLevelUp(); + + if (active_StatPerLevelUpChange) + Install_StatPerLevelUp(); + + if (active_multiPageStash) + Install_MultiPageStash(); + + if (active_othersFeatures) + Install_OthersFeatures(); + + if (active_newInterfaces) + Install_NewInterfaces(); + + if (active_WorldEvent) + Install_WorldEvent(); + + if (active_UberQuest) + Install_UberQuest(); + + if (active_alwaysRegenMapInSP) + Install_AlwaysRegenMapInSP(); + + if (nbPlayersCommandByDefault) + Install_SendPlayersCommand(); + + if (active_DisplayItemLevel) + Install_DisplayItemLevel(); + + if (active_AlwaysDisplayLifeMana) + Install_AlwaysDisplayLifeMana(); + + if (active_EnabledTXTFilesWithMSExcel) + Install_EnabledTXTFilesWithMSExcel(); + + if (active_LadderRunewords) + Install_LadderRunewords(); + + if (active_EnabledCowPortalWhenCowKingWasKill) + Install_EnabledCowPortalWhenCowKingWasKill(); + + log_msg("\nDLL patched sucessfully.\n\n\n"); + + unhookLibraries(); + + initCustomLibraries(); + + log_msg("***** ENTERING DIABLO II *****\n\n" ); + + active_logFile = active_logFile - 1; + + return NULL; +} + + + +extern "C" __declspec(dllexport) bool __stdcall Release() +{ + log_msg("\n***** ENDING DIABLO II *****\n\n" ); + + freeCustomLibraries(); + freeD2Libraries(); + return true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/Error.cpp b/PlugY/Error.cpp new file mode 100644 index 0000000..3e0b16e --- /dev/null +++ b/PlugY/Error.cpp @@ -0,0 +1,103 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Error Logger implementation. + +=================================================================*/ + +#include // fopen() fclose() fprintf() vfprintf() +#include // ... +#include // strlen() strcat() +#include // _getcwd() + +#include "error.h" +#include "d2functions.h" // Fog_assert() + +DWORD active_logFile = 1; + +static char log_file[MAX_PATH] = ""; +static bool log_init = false; + + +void log_initfile() +{ + if (log_init) return; + + _getcwd( log_file, MAX_PATH ); + if( log_file[strlen(log_file)] != '\\') + strcat(log_file, "\\"); + strcat(log_file, LOG_FILE); + + FILE* lLog = fopen( log_file, "w" ); + + if( lLog != NULL ) + { + fclose(lLog); + log_init = true; + } + + log_msg("<----------------------------------------------->\n" + "\n" + "\t\tA Plugin by Yohann\n" + "\t\tversion %s\n" + "\n" + "\n" + "<---------- Starting Diablo II Plugin ---------->\n\n\n" + ,PLUGY_VERSION); +} + +void log_box( const char* pFormat, ... ) +{ + char buffer[300]; + va_list lArgs; + va_start( lArgs, pFormat ); + vsprintf( buffer, pFormat, lArgs ); + va_end(lArgs); + + log_msg(buffer); + MessageBox(NULL, buffer, "PlugY, The Survival Kit", MB_OK|MB_ICONEXCLAMATION); +} + + +void log_msg( const char* pFormat, ... ) +{ + if (!active_logFile) return; + + if( !log_init ) + log_initfile(); + + if( log_init ) + { + va_list lArgs; + va_start( lArgs, pFormat ); + + FILE *lDebug = fopen( log_file, "a" ); + + if( lDebug != NULL ) + { + vfprintf( lDebug, pFormat, lArgs ); + fclose( lDebug ); + } + else + log_init = false; + + va_end(lArgs); + } +} + +void d2_assert( bool pCondition, char* pMessage, char* pLocation, int pLineNbr ) +{ + if( pCondition ) + { + log_msg("\n" + "*-----------------------*\n" + "Assertion fail at line %d of %s :\n" + "%s\n" + "*-----------------------*\n", + pLineNbr, pLocation, pMessage); + MessageBox(NULL, pMessage, "Diablo 2 Error", MB_OK|MB_ICONEXCLAMATION); + exit(1); + } +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/ExtendedSaveFile.cpp b/PlugY/ExtendedSaveFile.cpp new file mode 100644 index 0000000..ea686b8 --- /dev/null +++ b/PlugY/ExtendedSaveFile.cpp @@ -0,0 +1,166 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Add an extra save file for each characters. + +=================================================================*/ + +#include "common.h" +#include "extendedSaveFile.h" +#include "error.h" +#include "d2functions.h" +#include "infinityStash.h" +#include "customLibraries.h" + +#define BUFFER_SIZE 0x4000 +#define FILE_VERSION 0x3130 //"01" +#define FILE_EXTENDED 0x4D545343 //"CSTM" + + +BYTE * readExtendedSaveFile(char* name, DWORD* size)//WORKS +{ + char filename[512]; + BYTE* data; + d2_assert(!name, "Bad file name (NULL)", __FILE__, __LINE__); + D2FogGetSavePath( filename, 512-5); + strncat(filename, name, 512 - strlen(filename) - 5); + strcat(filename, ".d2x"); + + log_msg("Extended file to read : %s\n",filename); + + FILE* file = fopen(filename, "rb"); + if (file) + { + fseek(file, 0, SEEK_END); + *size = ftell(file); + fseek(file, 0, SEEK_SET); + data = (BYTE*)D2FogMemAlloc(*size,__FILE__,__LINE__,0); + DWORD nbRead = fread(data, 1, *size, file); + fclose(file); + d2_assert(nbRead != *size , "nbRead from extented save file != size", __FILE__, __LINE__); + } else { + log_msg("Can't open extented save file in mode \"rb\" (is not an error if it's a new player)\n"); + DWORD maxSize = 100; + data = (BYTE*)D2FogMemAlloc(maxSize,__FILE__,__LINE__,0); + *size = 14; + *((DWORD*)&data[0]) = FILE_EXTENDED; //"CSTM" + *((WORD *)&data[4]) = FILE_VERSION; + *((DWORD*)&data[6]) = 0;// not used + *((DWORD*)&data[10]) = 0;// number of stash + + TCustomDll* currentDll = customDlls; + while (currentDll) + { + currentDll->initExtendedSaveFile(&data, &maxSize, size); + currentDll=currentDll->nextDll; + } + } + return data; +} + + + + +int loadExtendedSaveFile(Unit* ptChar, BYTE data[], DWORD maxSize)//WORKS +{ + if (!ptChar || !PCPY || !data) return 0; + + log_msg("Load extended file\n"); + + DWORD curSize = 0; + + if (*(DWORD*)&data[curSize] != FILE_EXTENDED) + { + log_msg("loadExtendedSaveFile -> bad header\n"); + return 9; + } + curSize += 4; + + if (*(WORD *)&data[curSize] != FILE_VERSION) + { + log_msg("loadExtendedSaveFile -> bad file version\n"); + return 9; + } + curSize += 2; + curSize += 4; + + int ret = loadStashList(ptChar, data, maxSize, &curSize, false); + + TCustomDll* currentDll = customDlls; + while (!ret && currentDll) + { + ret = currentDll->loadExtendedSaveFile(ptChar, data, maxSize, &curSize); + currentDll=currentDll->nextDll; + } + + PCPY->selfStashIsOpened = true; + return ret; +} + + + +void writeExtendedSaveFile(char* name, BYTE* data, DWORD size) +{ + char szTempName[MAX_PATH]; + char szSaveName[MAX_PATH]; + + //Get temporary savefile name. + D2FogGetSavePath(szTempName, MAX_PATH); + strcat(szTempName, name); + strcat(szTempName, ".d2~"); + log_msg("Extended temporary file for saving : %s\n",szTempName); + + //Write data in savefile. + FILE* customSaveFile = fopen(szTempName, "wb+"); + fwrite(data, size, 1, customSaveFile); + fclose(customSaveFile); + + //Get real savefile name. + D2FogGetSavePath(szSaveName, MAX_PATH); + strcat(szSaveName, name); + strcat(szSaveName, ".d2x"); + log_msg("Extended file for saving : %s\n",szSaveName); + +// if (!MoveFileEx(szTempName, szSaveName, MOVEFILE_WRITE_THROUGH|MOVEFILE_REPLACE_EXISTING)) + DeleteFile(szSaveName); + if (!MoveFile(szTempName, szSaveName)) + log_box("Could not create the extended save file."); +} + +void backupExtendedSaveFile(char* name) +{ + char szBackupName[MAX_PATH]; + char szSaveName[MAX_PATH]; + + D2FogGetSavePath(szSaveName, MAX_PATH); + strcat(szSaveName, name); + strcat(szSaveName, ".d2x"); + + D2FogGetSavePath(szBackupName, MAX_PATH); + strcat(szBackupName, name); + strcat(szBackupName, ".d2x.backup"); + + CopyFile(szSaveName, szBackupName, true); +} + + +void saveExtendedSaveFile(Unit* ptChar, BYTE** data, DWORD* maxSize, DWORD* curSize) +{ + *(DWORD *)(*data + *curSize) = FILE_EXTENDED; //"CSTM" + *curSize += 4; + *(WORD *)(*data + *curSize) = FILE_VERSION; + *curSize += 2; + *(DWORD *)(*data + *curSize) = 0; + *curSize += 4; + + saveStashList(ptChar, PCPY->selfStash, data, maxSize, curSize); + + TCustomDll* currentDll = customDlls; + while (currentDll) + { + currentDll->saveExtendedSaveFile(ptChar, data, maxSize, curSize); + currentDll=currentDll->nextDll; + } +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/ExtraOptions.cpp b/PlugY/ExtraOptions.cpp new file mode 100644 index 0000000..e8d6cc3 --- /dev/null +++ b/PlugY/ExtraOptions.cpp @@ -0,0 +1,625 @@ +/*================================================================= + File created by Yohann NICOLAS. + + More little options. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include + +int active_RunLODs = false; +int active_alwaysRegenMapInSP = false; +DWORD nbPlayersCommandByDefault = 1; +int active_DisplayItemLevel = false; +int active_AlwaysDisplayLifeMana = false; +int active_EnabledTXTFilesWithMSExcel = false; +int active_DisplayBaseStatsValue = false; +int active_LadderRunewords = false; +int active_EnabledCowPortalWhenCowKingWasKill = false; + +/****************************************************************************************************/ + +void STDCALL displayItemlevel(LPWSTR popup, Unit* ptItem) +{ + if (onRealm && (selectModParam==MOD_NO)) return; + WCHAR text[0x50]; + swprintf(text, L"Item Level: %u\n", D2GetItemLevel(ptItem)); + D2SetColorPopup(text,WHITE); + wcscat(popup,text); +} + +FCT_ASM ( caller_displayItemlevel_113 ) + PUSH ECX + PUSH EAX + PUSH EAX + LEA EAX,DWORD PTR SS:[ESP+0x1E70] + PUSH EAX + CALL displayItemlevel + POP EAX + POP ECX + POP EDX + PUSH 0x100 + JMP EDX +}} + +FCT_ASM ( caller_displayItemlevel_111 ) + PUSH ECX + PUSH EDX + PUSH ECX + LEA EAX,DWORD PTR SS:[ESP+0x1E74] + PUSH EAX + CALL displayItemlevel + POP EDX + POP ECX + POP EAX + PUSH 0x100 + JMP EAX +}} + +FCT_ASM ( caller_displayItemlevelSet_111 ) + PUSH ECX + PUSH EDX + PUSH ECX + LEA EAX,DWORD PTR SS:[ESP+0x1958] + PUSH EAX + CALL displayItemlevel + POP EDX + POP ECX + POP EAX + PUSH 0x100 + JMP EAX +}} + + +FCT_ASM ( caller_displayItemlevel ) + PUSH ECX + PUSH EDX + PUSH ECX + LEA EAX,DWORD PTR SS:[ESP+0x5018] + PUSH EAX + CALL displayItemlevel + POP EDX + POP ECX + POP EAX + PUSH 0x100 + JMP EAX +}} + +FCT_ASM ( caller_displayItemlevelSet ) + PUSH ECX + PUSH EDX + PUSH ECX + LEA EAX,DWORD PTR SS:[ESP+0x1220] + PUSH EAX + CALL displayItemlevel + POP EDX + POP ECX + POP EAX + PUSH 0x100 + JMP EAX +}} + +FCT_ASM ( caller_displayItemlevel_9 ) + PUSH ECX + PUSH EDX + PUSH ECX + LEA EAX,DWORD PTR SS:[ESP+0x501C] + PUSH EAX + CALL displayItemlevel + POP EDX + POP ECX + POP EAX + PUSH 0x100 + JMP EAX +}} + +FCT_ASM ( caller_displayItemlevelSet_9 ) + PUSH ECX + PUSH EDX + PUSH ECX + LEA EAX,DWORD PTR SS:[ESP+0x1224] + PUSH EAX + CALL displayItemlevel + POP EDX + POP ECX + POP EAX + PUSH 0x100 + JMP EAX +}} + + +void Install_DisplayItemLevel() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Client for display item popup. (DisplayPopup)\n"); + + // print the text in the final buffer + mem_seek R7(D2Client, 3D47C, 3D47C, 438A1, ADD0A, 789DA, AE0AA, 941C0); + memt_byte( 0x68 , 0xE8); + MEMT_REF4( 0x100, version_D2Client >= V113 ? caller_displayItemlevel_113 : version_D2Client >= V111 ? caller_displayItemlevel_111 : version_D2Client == V110 ? caller_displayItemlevel : caller_displayItemlevel_9); + //6FAE38A1 . 68 00010000 PUSH 100 + //6FB5DD0A |. 68 00010000 PUSH 100 + //6FB289DA |. 68 00010000 PUSH 100 + //6FB5E0AA |. 68 00010000 PUSH 100 + //6FB441C0 |. 68 00010000 PUSH 100 + + // print the text in the final buffer (for set items) + mem_seek R7(D2Client, 3C452, 3C452, 427BE, AC773, 77773, ACEB3, 92FE3); + memt_byte( 0x68 , 0xE8); + MEMT_REF4( 0x100, version_D2Client >= V111 ? caller_displayItemlevelSet_111 : version_D2Client == V110 ? caller_displayItemlevelSet : caller_displayItemlevelSet_9); + //6FAE27BE . 68 00010000 PUSH 100 + //6FB5C773 |. 68 00010000 PUSH 100 + //6FB27773 |. 68 00010000 PUSH 100 + //6FB5CEB3 |. 68 00010000 PUSH 100 + //6FB42FE3 |. 68 00010000 PUSH 100 + + log_msg("\n"); + + isInstalled = true; +} + +/****************************************************************************************************/ + +char* msgNBPlayersString = "players %u"; +DWORD* infoEnabledSendPlayersCommand; +void SendPlayersCommand() +{ + #pragma pack(1) + struct { + BYTE displayType;//0x15 main msg; 0x14: char popup + BYTE un; + BYTE zero; + char string[0xFF]; + char null; + } data; + #pragma pack() + + if (!needToInit || onRealm) return; + needToInit=0; + + DWORD info = *infoEnabledSendPlayersCommand; + if ((info != 0) && (info != 1) && (info != 6) && (info != 8)) return; + + D2SetNbPlayers(nbPlayersCommandByDefault); + + memset(&data,0,sizeof(data)); + data.displayType=0x15; + data.un=1; + data.zero=0;//*(BYTE*)(offset_D2Client+0x112CFC); in 1.10 + data.null=NULL; + sprintf(data.string, msgNBPlayersString, nbPlayersCommandByDefault); + D2SendMsgToAll((BYTE*)&data); +} + +FCT_ASM ( caller_SendPlayersCommand ) + CALL SendPlayersCommand + JMP D2GetResolution +}} + +void Install_SendPlayersCommand() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Client for init default nb /players. (SendPlayersCommand)\n"); + + infoEnabledSendPlayersCommand = (DWORD*)R7(D2Client, 111D60, 110BC0, 107960, 11BFBC, 11C2AC, 11BFF8, 11C394); + if ( version_D2Client >= V110 ) + msgNBPlayersString = (char*)R7(D2Client, 0000, 0000, D8448, D06A8, D4748, D4680, D4E00); + + // Set nb Player to default + mem_seek R7(D2Client, 8723B, 865BB, 81B8B, A3602, 66A02, 90162, C39F2);//6FB1C7B7-6FAA0000 + MEMJ_REF4( D2GetResolution , caller_SendPlayersCommand); + //6FB2723A |. E8 7D8E0300 CALL + //6FB265BA |. E8 7D8E0300 CALL + //6FB21B8A . E8 4F9C0400 CALL + //6FB53601 |. E8 E099F6FF CALL + //6FB16A01 |. E8 AA65FAFF CALL + //6FB40161 |. E8 1ECFF7FF CALL + //6FB739F1 |. E8 B896F4FF CALL + + log_msg("\n"); + + isInstalled = true; +} + +/****************************************************************************************************/ + + +void Install_AlwaysRegenMapInSP() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Game for always regenerate maps in Single player. (AlwaysRegenMapInSP)\n"); + + // Always regenerate maps in Single player + mem_seek R7(D2Game, 517ED, 51BFA, 5DE88, 6235D, 2966D, 1E1FE, ED3BE); + memt_byte( 0x74 , 0xEB); // JMP SHORT D2Game.01FE2368 + //6FC8DE88 |. 74 09 JE SHORT D2Game.6FC8DE93 + //01FE235D |. 74 09 JE SHORT D2Game.01FE2368 + //01F9966D |. 74 09 JE SHORT D2Game.01F99678 + //6FC3E1FE |. 74 09 JE SHORT D2Game.6FC3E209 + //6FD0D3BE |. 74 09 JE SHORT D2Game.6FD0D3C9 + + log_msg("\n"); + + isInstalled = true; +} + +/****************************************************************************************************/ + +void Install_RunLODs() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2gfx for launch any number of Diablo II game in the same computer. (RunLODs)\n"); + + // execute if it's our packet else continue + mem_seek R7(D2gfx, 447C, 447C, 446A, 84CF, 84AF, 894F, 85BF); + memt_byte( 0x74, 0xEB ); // JMP SHORT D2gfx.6FA884F6 + //6FA884AF |. 74 45 JE SHORT D2gfx.6FA884F6 + //6FA8894F |. 74 45 JE SHORT D2gfx.6FA88996 + //6FA885BF |. 74 45 JE SHORT D2gfx.6FA88606 + + log_msg("\n"); + + isInstalled = true; +} + +/****************************************************************************************************/ + + +FCT_ASM (caller_AlwaysDisplayLife_113) + POP EAX + CMP onRealm,0 + JNZ normalDisplayLife + CMP active_AlwaysDisplayLifeMana,0 + JE normalDisplayLife + ADD EAX,0x28 + JMP EAX +normalDisplayLife: + CMP EDX,0x1E + JGE cont + ADD EAX,0xBC +cont: + JMP EAX +}} + +FCT_ASM (caller_AlwaysDisplayLife_111) + CMP onRealm,0 + JNZ normalDisplayLife + CMP active_AlwaysDisplayLifeMana,0 + JE normalDisplayLife + POP EAX + ADD EAX,0x25 + JMP EAX +normalDisplayLife: + MOV EAX,ptResolutionY + MOV EAX,DWORD PTR DS:[EAX] + RETN +}} + +FCT_ASM (caller_AlwaysDisplayLife) + CMP onRealm,0 + JNZ normalDisplayLife + CMP active_AlwaysDisplayLifeMana,0 + JE normalDisplayLife + POP EAX + ADD EAX,0x28 + JMP EAX +normalDisplayLife: + MOV EAX,ptResolutionY + MOV EAX,DWORD PTR DS:[EAX] + RETN +}} + + + +FCT_ASM (caller_AlwaysDisplayMana_113) + MOV EAX,DWORD PTR DS:[ptResolutionY] + MOV EAX,DWORD PTR DS:[EAX] + CMP onRealm,0 + JNZ normalDisplayMana + CMP active_AlwaysDisplayLifeMana,0 + JE normalDisplayMana + POP EAX + ADD EAX,0x3C + JMP EAX +normalDisplayMana: + RETN +}} + +FCT_ASM (caller_AlwaysDisplayMana) + CMP onRealm,0 + JNZ normalDisplayMana + CMP active_AlwaysDisplayLifeMana,0 + JE normalDisplayMana + POP EAX + MOV WORD PTR SS:[ESP+0x14],0 + ADD EAX,0x38 + JMP EAX +normalDisplayMana: + POP EAX + POP EDI + POP ESI + POP EBP + POP EBX + ADD ESP,0x25C + RETN +}} + +FCT_ASM (caller_AlwaysDisplayMana_9) + CMP onRealm,0 + JNZ normalDisplayMana + CMP active_AlwaysDisplayLifeMana,0 + JE normalDisplayMana + ADD DWORD PTR SS:[ESP],0x32 + LEA ECX,DWORD PTR SS:[ESP+0x24] + PUSH DWORD PTR SS:[ESP+0xC] + PUSH DWORD PTR SS:[ESP+0xC] + PUSH DWORD PTR SS:[ESP+0xC] + CALL D2PrintString + MOV WORD PTR SS:[ESP+0x24],0 + RETN 0xC +normalDisplayMana: + POP EAX + ADD EAX,0xC2 + JMP EAX +}} + +void Install_AlwaysDisplayLifeMana() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Client for always display life and mana. (ALwaysPrintLifeMana)\n"); + + if ( version_D2Client >= V113 ) + { + mem_seek R7(D2Client, 0000, 0000, 0000, 0000, 0000, 0000, 2764A); + memt_byte( 0x0F , 0x90); + memt_byte( 0x8C , 0xE8); + MEMT_REF4( 0x000000BC, caller_AlwaysDisplayLife_113); + //6FAD764A |. 0F8C BC000000 JL D2Client.6FAD770C + //6FAD7650 |. 83FA 6E CMP EDX,6E + //6FAD7653 |. 0F8F B3000000 JG D2Client.6FAD770C + //6FAD7659 |. A1 4CBCB86F MOV EAX,DWORD PTR DS:[6FB8BC4C] + + //6FAD7667 |. 0F8C A4000000 JL D2Client.6FAD7711 + + } else { + // Always display life. + mem_seek R7(D2Client, 58B32, 58B32, 5F102, 2D713, B5DF3, 81733, 0000); + memt_byte( 0xA1 , 0xE8); + MEMT_REF4( ptResolutionY , version_D2Client >= V111 ? caller_AlwaysDisplayLife_111 : caller_AlwaysDisplayLife); + //6FADD713 |. A1 605CBA6F MOV EAX,DWORD PTR DS:[6FBA5C60] + //6FB65DF3 |. A1 C84FBA6F MOV EAX,DWORD PTR DS:[6FBA4FC8] + //6FB31733 |. A1 E4C6B86F MOV EAX,DWORD PTR DS:[6FB8C6E4] + } + + + // Always display mana. + if ( version_D2Client >= V113 ) + { + //mem_seek R7(D2Client, 0000, 0000, 0000, 0000, 0000, 0000, 27711); + //memt_byte( 0x8B , 0x90); + //memt_byte( 0x0D , 0xE8); + //MEMT_REF4( offset_D2Client + 0x11C4B4 , caller_AlwaysDisplayMana_113); + mem_seek R7(D2Client, 0000, 0000, 0000, 0000, 0000, 0000, 2770C); + memt_byte( 0xA1 , 0xE8); + MEMT_REF4( ptResolutionY , caller_AlwaysDisplayMana_113); + //6FAD770C |> A1 4CBCB86F MOV EAX,DWORD PTR DS:[6FB8BC4C] + //6FAD7711 |> 8B0D B4C4BC6F MOV ECX,DWORD PTR DS:[6FBCC4B4] + + //6FAD7708 |. 8B5424 10 MOV EDX,DWORD PTR SS:[ESP+10] + + //6FAD77C7 |> 5F POP EDI + //6FAD77C8 |. 5E POP ESI + //6FAD77C9 |. 5D POP EBP + //6FAD77CA |. 5B POP EBX + //6FAD77CB |. 81C4 28030000 ADD ESP,328 + //6FAD77D1 \. C3 RETN + } + else if ( version_D2Client >= V110 ) + { + mem_seek R7(D2Client, 0000, 0000, 5F1E6, 2D7FB, B5EDB, 8181B, 0000); + memt_byte( 0x5F , 0xE8); + MEMT_REF4( 0x815B5D5E , caller_AlwaysDisplayMana); + memt_byte( 0xC4 , 0x90); // NOP + memt_byte( 0x5C , 0x90); // NOP + memt_byte( 0x02 , 0x90); // NOP + memt_byte( 0x00 , 0x90); // NOP + memt_byte( 0x00 , 0x90); // NOP + //6FADD7FB |. 5F POP EDI + //6FADD7FC |. 5E POP ESI + //6FADD7FD |. 5D POP EBP + //6FADD7FE |. 5B POP EBX + //6FADD7FF |. 81C4 5C020000 ADD ESP,25C + //6FB65EDB |. 5F POP EDI + //6FB65EDC |. 5E POP ESI + //6FB65EDD |. 5D POP EBP + //6FB65EDE |. 5B POP EBX + //6FB65EDF |. 81C4 5C020000 ADD ESP,25C + //6FB3181B |. 5F POP EDI + //6FB3181C |. 5E POP ESI + //6FB3181D |. 5D POP EBP + //6FB3181E |. 5B POP EBX + //6FB3181F |. 81C4 5C020000 ADD ESP,25C + //6FB31825 |. C3 RETN + } else { + mem_seek R7(D2Client, 58C09, 58C09, 0000, 0000, 0000, 0000, 0000); + memt_byte( 0xE9 , 0xE8); + MEMT_REF4( 0x000000C2 , caller_AlwaysDisplayMana_9); + //6FAF8C09 . E9 C2000000 JMP D2Client.6FAF8CD0 + } + + if (active_AlwaysDisplayLifeMana==2) + active_AlwaysDisplayLifeMana=0; + + log_msg("\n"); + + isInstalled = true; +} + +/****************************************************************************************************/ + +void Install_EnabledTXTFilesWithMSExcel() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Client for enabled the opening of files already opened by MS Excel. (EnabledTXTFilesWithMSExcel)\n"); + + mem_seek( (DWORD)D2StormMPQOpenFile + (version_Storm >= V111 ? 0x12A : 0xFF) ); + memt_byte( 0x01 , 0x03); //; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE + //6FC1C969 |. 6A 01 PUSH 1 ; |ShareMode = FILE_SHARE_READ + + log_msg("\n"); + + isInstalled = true; +} + + +/****************************************************************************************************/ + +void STDCALL printDisplayBaseStatsValue(WORD statID, sDrawImageInfo* data, DWORD x, DWORD y, DWORD p4, DWORD p5, DWORD p6) +{ + if ( onRealm || !D2isLODGame()) + { + D2PrintImage(data,x,y,p4,p5,p6); + return; + } + Unit* ptChar = D2GetClientPlayer(); + + CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass); + int minValue=1; + switch (statID) + { + case STATS_STRENGTH: minValue = charStats->baseSTR; break; + case STATS_DEXTERITY: minValue = charStats->baseDEX; break; + case STATS_VITALITY: minValue = charStats->baseVIT; break; + case STATS_ENERGY: minValue = charStats->baseENE; break; + } + int statValue = D2GetPlayerBaseStat(ptChar, statID, 0); + + if (isOnRect(D2GetMouseX(),D2GetMouseY(),x+5,y+5,32,32)) + { + WCHAR text[100]; + swprintf(text, getTranslatedString(STR_STATS_BASE_MIN), statValue, minValue); + D2SetFont(1); + D2PrintPopup(text, x+18, y-32, WHITE, 1); + } + + if ( D2GetPlayerBaseStat(ptChar, 4, 0) <= 0) + setFrame(data, 2); + D2PrintImage(data,x,y,p4,p5,p6); +} + +FCT_ASM ( caller_displayBaseStatsValue ) + POP EAX + XOR ECX,ECX + MOV CX,WORD PTR DS:[ESI+8] + PUSH ECX + PUSH EAX + JMP printDisplayBaseStatsValue +}} + +void Install_DisplayBaseStatsValue() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Client for display base stats value. (DisplayBaseStatsValue)\n"); + + // Always print stat button images. + mem_seek R7(D2Client, 29B12, 29B02, 30073, 82BBA, 8963A, 6B59A, BD1B5); + memt_byte( 0x8B, 0xEB ); // JMP SHORT D2Client.6FAD0088 + memt_byte( 0x4C, V7(D2Client, 12, 12, 13, 13, 13, 13, 13) ); + memt_byte( 0x24, 0x90 ); // NOP + memt_byte( V7(D2Client, 20, 20, 14, 1C, 1C, 1C, 1C), 0x90 ); // NOP (V109d:0x20 , V110:0x14 + //6FAD0073 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+14] + //6FB32BBA > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C] + //6FB3963A > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C] + //6FB1B59A > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C] + //6FB6D1B5 |> 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C] + + mem_seek R7(D2Client, 29B9D, 29B8D, 300FD, 82C54, 896D4, 6B637, BD23E); + MEMJ_REF4( D2PrintImage, caller_displayBaseStatsValue); + //6FB32C53 . E8 82A3F8FF CALL + //6FB396D3 . E8 D238F8FF CALL + //6FB1B636 . E8 431AFAFF CALL + //6FB6D23D |. E8 54FEF4FF |CALL + + log_msg("\n"); + + isInstalled = true; +} + + +/****************************************************************************************************/ + +RunesBIN* STDCALL compileRunesTxt(DWORD unused, const char* filename, BINField* ptFields, DWORD* ptRecordCount, DWORD recordLength) +{ + RunesBIN* ptRunesBin = (RunesBIN*)D2CompileTxtFile(unused, filename, ptFields, ptRecordCount, recordLength); + for (DWORD i=0; i < *ptRecordCount; i++) + ptRunesBin[i].Server=0; + return ptRunesBin; +} + +void Install_LadderRunewords() +{ + static int isInstalled = false; + if (isInstalled) return; + + if ( version_D2Common < V110 ) + return; + + log_msg("Patch D2Common for enabled the ladder only runewords. (LadderRunewords)\n"); + + mem_seek R7(D2Common, 0000, 0000, 1E965, 61762, 43A72, 5D492, 724B2); + MEMC_REF4( D2CompileTxtFile, compileRunesTxt); + //01B6E964 |. E8 0714FFFF CALL D2Common.#10578 ; \#10578 + //6FDB1761 |. E8 FAA8FCFF CALL D2Common.#10653 ; \#10653 + //6FD93A71 |. E8 EAADFCFF CALL D2Common.#10496 ; \#10496 + //6FDAD491 |. E8 BA49FEFF CALL D2Common.#10244 ; \#10244 + //6FDC24B1 |. E8 8ACAFEFF CALL D2Common.#10849 ; \#10849 + + log_msg("\n"); + + isInstalled = true; +} + + + +/****************************************************************************************************/ + +void Install_EnabledCowPortalWhenCowKingWasKill() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Game for enabled the opening of Cow Portal when player have already kill the cow king in that difficulty. (EnabledCowPortalWhenCowKingWasKill)\n"); + + mem_seek R7(D2Game, 5DFF7, 5E457, 6C5E7 , B1278, 5DB68, 75C68, 67508); + memt_byte( 0x85 , 0x33); // XOR EAX,EAX + //6FC8DFF7 . 85C0 TEST EAX,EAX + //6FC8E457 . 85C0 TEST EAX,EAX + //6FC9C5E7 . 85C0 TEST EAX,EAX + //02061278 |. 85C0 TEST EAX,EAX + //01FEDB68 |. 85C0 TEST EAX,EAX + //6FC95C68 |. 85C0 TEST EAX,EAX + //6FC87508 |. 85C0 TEST EAX,EAX + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/GlobalVariable.cpp b/PlugY/GlobalVariable.cpp new file mode 100644 index 0000000..a302a26 --- /dev/null +++ b/PlugY/GlobalVariable.cpp @@ -0,0 +1,152 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Updating server. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "bigStash.h" +#include +#include "uberQuest.h" +#include "worldEvent.h" + +bool onRealm=false; +bool needToInit=false; +int previouslyOnRealm = -1; + +void STDCALL BtnPress() +{ + needToInit = 1; +// if (active_WorldEvent) +// initWorldEventVariables(); + if (active_UberQuest) + resetQuestState(); + d2_assert(active_bigStash_tested && onRealm && (previouslyOnRealm==0), "Need to restart after play an open game with the Big Stash",__FILE__,__LINE__); + d2_assert(active_bigStash_tested && !onRealm && (previouslyOnRealm>0), "Need to restart after play an closed game with the Big Stash",__FILE__,__LINE__); + previouslyOnRealm = onRealm; +} + +FCT_ASM ( caller_BnetBtnPress ) + CMP active_DisableBattleNet,1 + JE disableBattleNet + MOV onRealm,1 + PUSH EAX + CALL BtnPress + POP EAX + SUB ESP,0x3FC//400 + JMP DWORD PTR SS:[ESP+0x3FC] +disableBattleNet: + POP EAX + RETN +}} + +/* +FCT_ASM ( caller_MultiPlayerBtnPress ) + CALL BtnPress + MOV EAX,1 + RETN +}} +*/ + +FCT_ASM ( caller_TCPIPBtnPress111 ) + MOV onRealm,0 + CALL BtnPress + MOV ESI,0x40 + RETN +}} + +FCT_ASM ( caller_TCPIPBtnPress ) + MOV onRealm,0 + CALL BtnPress + MOV EBP,1 + RETN +}} + +FCT_ASM ( caller_SinglePlayerBtnPress ) + MOV onRealm,0 + CALL BtnPress + MOV EDX,0x400 + RETN +}} + + +FCT_ASM ( caller_fixClientRemovingBug ) + TEST ECX,ECX + JE notFound + CMP DWORD PTR DS:[ECX],EBP + JE found +next: + MOV EAX,ECX + MOV ECX,DWORD PTR DS:[EAX+0x4A8] + TEST ECX,ECX + JE notFound + CMP DWORD PTR DS:[ECX],EBP + JNZ next +found: + ADD DWORD PTR SS:[ESP],0xB + RETN +notFound: + ADD DWORD PTR SS:[ESP],0x1D + RETN +}} + +void Install_VariableOnRealm() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Launch for set not on realm variable. (VariableonRealm)\n"); + + // click on Battle.net button + mem_seek R7(D2Launch, 8195, 81A5, 9915, 129E5, 18AA5, 17D15, 19295); + memt_byte( 0x81, 0xE8 ); // CALL + MEMT_REF4( 0x000400EC, caller_BnetBtnPress); + memt_byte( 0x00, 0x90 ); // NOP + //6FA529E5 . 81EC 00040000 SUB ESP,400 + + // click on Multiplayer button +// mem_seek R7(D2Launch, D5EC, D5CC, EFFC, 0000, 0000, 0000, 0000); +// memt_byte( 0xB8, 0xE8 ); // CALL +// MEMT_REF4( 0x00000001, caller_MultiPlayerBtnPress); + //6FA1EFFC . B8 01000000 MOV EAX,1 + + // click on TCP/IP button + mem_seek R7(D2Launch, 87B9, 87C9, 9F99, 11329, 17409, 16659, 17B8E); + if (version_D2Launch == V109b || version_D2Launch == V109d || version_D2Launch == V110) + { + memt_byte( 0xBD, 0xE8 ); // CALL + MEMT_REF4( 0x00000001, caller_TCPIPBtnPress); + } else { + memt_byte( 0xBE, 0xE8 ); // CALL + MEMT_REF4( 0x00000040, caller_TCPIPBtnPress111); + //6FA51329 . BE 40000000 MOV ESI,40 + } + + // click on SinglePlayer button + mem_seek R7(D2Launch, D1F6, D1E6, EC16, B726, 117E6, 10A56, 11F36); + memt_byte( 0xBA, 0xE8 ); // CALL + MEMT_REF4( 0x00000400, caller_SinglePlayerBtnPress); + //6FA4B726 . BA 00040000 MOV EDX,400 + + if (version_D2Game == V110) + { + log_msg("\nPatch D2Game for fixing ptClient removing bug. (VariableonRealm)\n"); + //Bug crash ptClient search fix (for Megalixir Mod). + mem_seek R7(D2Game, 0000, 0000, 2B97, 0000, 0000, 0000, 0000); + memt_byte( 0x39 ,0xE8); + MEMT_REF4( 0x8B0C7429 , caller_fixClientRemovingBug); + memt_byte( 0xC1 ,0x90); + //6FC32B97 |> 3929 CMP DWORD PTR DS:[ECX],EBP + //6FC32B99 |. 74 0C JE SHORT D2Game.6FC32BA7 + //6FC32B9B |> 8BC1 MOV EAX,ECX + } + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/INIfile.cpp b/PlugY/INIfile.cpp new file mode 100644 index 0000000..63e82a5 --- /dev/null +++ b/PlugY/INIfile.cpp @@ -0,0 +1,359 @@ +/****************************************************************************** + File modified by Yohann NICOLAS. + + NAME + INIfile.cpp + + DESCRIPTION + Memory cached INI file read/write class to replace legacy MS code + + COPYRIGHT + 1999-2004 Ultrafunk (www.ultrafunk.com) - info@ultrafunk.com + +******************************************************************************/ + +#include +#include "INIfile.h" + +#include "d2functions.h" +#include "error.h" + +/* +http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getprivateprofilestring.asp +*/ + + +/*****************************************************************************/ +// First a few support routines + +static char *strstri(char *text, char *string) +{ + char *found = NULL; + + if(text && string) + { + int len = strlen(string); + if(len) + { + while(*text) + { + if(strnicmp(string, text, len) == 0) + { + found = text; + break; + } + + text++; + } + } + } + + return found; +} + + +static BOOL chrcmp(char c, char *string) +{ + for(unsigned int i=0; i + +#define INIFILE_READ 10 +#define INIFILE_WRITE 20 +#define INIFILE_MPQREAD 30 + +#define MAX_SECTIONNAME_LENGTH 128 +#define MAX_KEYNAME_LENGTH 128 + +/*****************************************************************************/ + +class INIFile +{ +public: + INIFile(); + ~INIFile(); + + BOOL InitReadWrite(char *path, int readWrite, DWORD writeCacheSize); + BOOL close(); + int GetPrivateProfileString(const char *section, const char *key, const char *def, char *dest, DWORD size); + BOOL WritePrivateProfileString(char *section, char *key, char *string); + +private: + int m_readWrite; + char m_path[_MAX_PATH]; + HANDLE m_file; + char *m_cache; + DWORD m_cacheWritePos; + char *m_sectionStart; + char *m_sectionEnd; + char m_currentSection[MAX_SECTIONNAME_LENGTH]; +}; + + +#endif // _INIFILE_H + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/InfinityStash.cpp b/PlugY/InfinityStash.cpp new file mode 100644 index 0000000..97f80a1 --- /dev/null +++ b/PlugY/InfinityStash.cpp @@ -0,0 +1,864 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Gestion of the infinity and shared Stash. + +=================================================================*/ + + +#include "common.h" +#include "infinityStash.h" +#include "error.h" +#include "d2functions.h" +#include "updateClient.h" +#include "interface_Stash.h" + +#define STASH_TAG 0x5453 //"ST" +#define JM_TAG 0x4D4A //"JM" + +DWORD maxSelfPages = -1; +DWORD maxSharedPages = -1; +DWORD nbPagesPerIndex = 10; +DWORD nbPagesPerIndex2 = 100; +bool active_multiPageStash = false; +bool active_sharedStash = false; +bool separateHardSoftStash = false; +bool active_sharedGold=false; +char* sharedStashFilename = NULL; + +typedef int (*TchangeToSelectedStash)(Unit* ptChar, Stash* newStash, DWORD bIsClient); + +Unit* firstClassicStashItem(Unit* ptChar) +{ + Unit* ptItem = D2InventoryGetFirstItem(PCInventory); + while (ptItem) + { + if (D2ItemGetPage(D2GetRealItem(ptItem)) == 4) + return ptItem; + ptItem = D2UnitGetNextItem(ptItem); + } + return NULL; +} + +DWORD endStashList(Unit* ptChar, Stash* ptStash)//WORKS +{ + Stash* stash = ptStash; + + while (stash) + { + if (stash->ptListItem || ((stash == PCPY->currentStash) && firstClassicStashItem(ptChar))) return 0; + stash = stash->nextStash; + } + return 1; +} + +//bool isInList(Stash* list, Stash* pStash) +//{ +// Stash* ptStash = list; +// while(ptStash) +// { +// if (ptStash->id == pStash->id) return true; +// ptStash = ptStash->nextStash; +// } +// return false; +//} + + +Stash* getLastStash(Stash* ptStash)//WORKS +{ + Stash* stash = ptStash; + + if (!stash) return NULL; + while (stash->nextStash) + stash = stash->nextStash; + + return stash; +} + +Stash* newStash(DWORD id) +{ + d2_assert( id == 0xFFFFFFFF , "trop de stash", __FILE__, __LINE__); + + Stash* stash = (Stash*)malloc(sizeof(Stash));//D2AllocMem(memPool, sizeof(Stash),__FILE__,__LINE__,0); + d2_assert(!stash , "pb de gnration de stash", __FILE__, __LINE__); + ZeroMemory(stash, sizeof(Stash)); + stash->id = id; + + return stash; +} + +Stash* addStash(Unit* ptChar, bool isShared) +{ + Stash* previous; + Stash* stash; +// DWORD memPool = PCGame ? PCGame->memoryPool :0; + if (isShared) + { + previous = getLastStash(PCPY->sharedStash); + stash = newStash(PCPY->nbSharedPages++); + } else { + previous = getLastStash(PCPY->selfStash); + stash = newStash(PCPY->nbSelfPages++); + } + + stash->isShared = isShared; + stash->previousStash = previous; + if (previous) + previous->nextStash = stash; + else if (isShared) + PCPY->sharedStash = stash; + else + PCPY->selfStash = stash; + + log_msg("AddStash: stash->id=%d\tstash->isShared=%d\tstash->previous=%08X\tnbSelf=%d\tnbShared=%d\n", + stash->id,stash->isShared,stash->previousStash,PCPY->nbSelfPages,PCPY->nbSharedPages); + + return stash; +} + +Stash* getStash(Unit* ptChar, DWORD isShared, DWORD id)//WORKS +{ + Stash* ptStash = isShared ? PCPY->sharedStash : PCPY->selfStash; + + while(ptStash) + { + if (ptStash->id == id) return ptStash; + ptStash = ptStash->nextStash; + } + + return NULL; +} + + +int changeToSelectedStash_9(Unit* ptChar, Stash* newStash, DWORD bIsClient) +{ + if (!newStash) return 0; + + log_msg("changeToSelectedStash ID:%d\tshared:%d\tclient:%d\n",newStash->id,newStash->id,bIsClient); + + Stash* currentStash = PCPY->currentStash; + if (currentStash == newStash) return 0; + + d2_assert( currentStash && currentStash->ptListItem, "ERROR : currentStash isn't empty (ptListItem != NULL)",__FILE__,__LINE__); + + // collect items to remove + Inventory* ptInventory = PCInventory; + Unit* ptNextItem; + Unit* ptPrevItem = NULL; + Unit* ptItem = D2InventoryGetFirstItem(ptInventory); + while (ptItem) + { + ptNextItem = D2UnitGetNextItem(ptItem); + if (D2ItemGetPage(D2GetRealItem(ptItem)) == 4) + { + D2SetAnim(D2GetRealItem(ptItem),-1); + if (ptPrevItem) { + ptPrevItem->CurrentAnim = (DWORD)ptNextItem;//is ptPrevItem->nextNode = ptNextItem; + } else { + ptInventory->currentUsedSocket = (DWORD)ptNextItem;//is ptInventory->ptListItem = ptNextItem; + } + if (!ptNextItem) + ptInventory->Inventory2C = (DWORD)ptPrevItem; + + ptInventory->Inventory30 = ptInventory->Inventory30 - 1; + D2Common10250(__FILE__,__LINE__,ptInventory, D2GetPosX(D2GetRealItem(ptItem)), D2GetPosY(D2GetRealItem(ptItem)), 0xC, bIsClient, 4); +// ptItem = D2InvRemoveItem(PCInventory, D2GetRealItem(ptItem)); +// D2Common10250(__FILE__,__LINE__,PCInventory, D2GetPosX(ptItem), D2GetPosY(ptItem), 0xC, bIsClient, 4); + if (currentStash) + { +// ptItem = setNextItem(ptItem, PCPY->currentStash->ptListItem); + ptItem->CurrentAnim = (DWORD)currentStash->ptListItem;//is ptItem->nextNode = ptListItem + currentStash->ptListItem = ptItem; + }; + } else ptPrevItem = ptItem; + ptItem = ptNextItem; + } + + // add items of new stash + PCPY->currentStash = newStash; + ptItem = newStash->ptListItem; + while (ptItem) + { + D2InvAddItem(PCInventory, D2GetRealItem(ptItem), D2GetPosX(D2GetRealItem(ptItem)), D2GetPosY(D2GetRealItem(ptItem)), 0xC, bIsClient, 4); + D2Common10242(PCInventory, D2GetRealItem(ptItem), 1); + ptItem = D2UnitGetNextItem(ptItem); + } + newStash->ptListItem = NULL; + + return 1; +} + +int changeToSelectedStash_10(Unit* ptChar, Stash* newStash, DWORD bIsClient) +{ + if (!newStash) return 0; + + log_msg("changeToSelectedStash ID:%d\tshared:%d\tclient:%d\n",newStash->id,newStash->id,bIsClient); + + Stash* currentStash = PCPY->currentStash; + if (currentStash == newStash) return 0; + + d2_assert( currentStash && currentStash->ptListItem, "ERROR : currentStash isn't empty (ptListItem != NULL)",__FILE__,__LINE__); + + // Remove items from current page + Unit* ptNextItem; + Unit* ptItem = D2InventoryGetFirstItem(PCInventory); + while (ptItem) + { + ptNextItem = D2UnitGetNextItem(ptItem); + if (D2ItemGetPage(ptItem) == 4) + { + BYTE tmp = ptItem->ptItemData->ItemData2; + ptItem = D2InvRemoveItem(PCInventory, ptItem); + ptItem->ptItemData->ItemData2 = tmp; + if (currentStash) + { + ptItem->ptItemData->ptNextItem = currentStash->ptListItem; + currentStash->ptListItem = ptItem; + } + } + ptItem = ptNextItem; + } + + // add items of new stash + PCPY->currentStash = newStash; + ptItem = newStash->ptListItem; + while (ptItem) + { + D2InvAddItem(PCInventory, ptItem, ptItem->path->x, ptItem->path->y, 0xC, bIsClient, 4); + ptItem = D2UnitGetNextItem(ptItem); + } + newStash->ptListItem = NULL; + + return 1; +} + +TchangeToSelectedStash changeToSelectedStash; + + +DWORD loadStash(Unit* ptChar, Stash* ptStash, BYTE data[], DWORD startSize, DWORD maxSize, DWORD* retSize) +{ + DWORD curSize = startSize; + DWORD nbBytesRead; + + log_msg("loadStash\n"); + + *retSize = curSize; + if( *(WORD *)&data[curSize] != STASH_TAG )//"ST" + { + log_msg("loadStash -> Bad tag of stash of character %s : %04X\n",PCPlayerData->name,*(WORD *)&data[curSize]); + return 0x7;//Unable to enter game. Bad inventory data + } + curSize += 2; + +// if (strlen((char *)&data[curSize]) > 0xF) +// *(char *)&data[curSize+0xF] = NULL; + if (strlen((char *)&data[curSize])) + ptStash->name = (char*)malloc(strlen((char *)&data[curSize]));//D2AllocMem(PCGame->memoryPool, strlen((char *)&data[curSize]),__FILE__,__LINE__,0); + if (ptStash->name) + strcpy(ptStash->name, (char *)&data[curSize]); + curSize += strlen((char *)&data[curSize]) + 1; + + DWORD ret = D2LoadInventory(PCGame, ptChar, (saveBitField*)&data[curSize], 0x60, maxSize-curSize, 0, &nbBytesRead); + if (ret) log_msg("loadStash -> D2LoadInventory failed\n"); + log_msg("Stash loaded (%d : %s)\n", ptStash->id ,ptStash->name); + + *retSize=curSize + nbBytesRead; + return ret; +} + +DWORD loadStashList(Unit* ptChar, BYTE data[], DWORD maxSize, DWORD* curSize, bool isShared)//WORKS +{ + DWORD curStash = 0; + Stash* newStash; + + DWORD nbStash = *(DWORD*)&data[*curSize]; + *curSize += 4; + + while (curStash < nbStash) + { + newStash = addStash(ptChar, isShared); + changeToSelectedStash(ptChar, newStash, false); + DWORD ret = loadStash(ptChar, newStash, data, *curSize, 10000000, curSize); + if (ret) return ret; + curStash++; + } + + if (!isShared && !PCPY->selfStash) + { + newStash = addStash(ptChar, isShared); + PCPY->currentStash = newStash; + } + + if (isShared && !PCPY->sharedStash) + { + newStash = addStash(ptChar, isShared); + if (!PCPY->currentStash) + PCPY->currentStash = newStash; + } + + return 0; +} + +//ADDDATA(DWORD, curSize, 0); + +#define DATA (*data + *curSize) +#define ADDDATA(T) (T*)DATA; *curSize += sizeof(T) +#define SETDATA(T,V) *(T*)DATA = V; *curSize += sizeof(T) + +void saveStash(Unit* ptChar, Stash* ptStash, BYTE** data, DWORD* maxSize, DWORD* curSize) +{ + //write "ST" + SETDATA(WORD, STASH_TAG); + + //save name + if (ptStash->name) + { + int size = strlen(ptStash->name); + if (size > 15) size = 15; + strncpy((char*)DATA, ptStash->name, size); + *curSize += size; + } + SETDATA(char, NULL); + + //Write "JM" of inventory + SETDATA(WORD, JM_TAG); + + //Get position of counter of items in inventory + WORD* ptNBItem = ADDDATA(WORD); + *ptNBItem = 0; + + //Get first item + Unit* ptItem; + if ((ptStash->id == PCPY->currentStash->id) && (ptStash->isShared == PCPY->currentStash->isShared)) + ptItem = D2InventoryGetFirstItem(PCInventory); + else + ptItem = ptStash->ptListItem; + + //Write all items + while (ptItem) + { + if (D2ItemGetPage(D2GetRealItem(ptItem)) == 4) + { + int nbBytes = D2SaveItem(D2GetRealItem(ptItem), (saveBitField*)DATA, *maxSize - *curSize, 1, 1, 0); + d2_assert(!nbBytes, "!\"Character has too many items\"", __FILE__, __LINE__ ); + *curSize += nbBytes; + (*ptNBItem)++; + } + ptItem = D2UnitGetNextItem(ptItem); + } +} + + +void saveStashList(Unit* ptChar, Stash* ptStash, BYTE** data, DWORD* maxSize, DWORD* curSize) +{ + DWORD curSizeNbStash = *curSize; + *curSize += sizeof(DWORD); + + DWORD nbStash=0; + + while(ptStash) + { + if (*curSize + 0x2000 > *maxSize) + { + BYTE* oldData = *data; + *maxSize *= 2; + *data = (BYTE *)D2AllocMem(PCGame->memoryPool, *maxSize,__FILE__,__LINE__,0); + d2_assert(!*data, "Error : Memory allocation", __FILE__, __LINE__); + CopyMemory(*data, oldData, *curSize); + D2FreeMem(PCGame->memoryPool, oldData,__FILE__,__LINE__,0); + } + saveStash(ptChar, ptStash, data, maxSize, curSize); + nbStash++; + ptStash = endStashList(ptChar, ptStash->nextStash) ? NULL : ptStash->nextStash; + } + *(DWORD*)(*data + curSizeNbStash) = nbStash; +} + +/////// client +void updateSelectedStashClient(Unit* ptChar)//WORKS +{ + Stash* newStash = PCPY->currentStash; + updateClient(ptChar, UC_SELECT_STASH, newStash->id, newStash->flags, PCPY->flags); +} + +void setSelectedStashClient(DWORD stashId, DWORD stashFlags, DWORD flags)//WORKS +{ + log_msg("setSelectedStashClient ID:%d, isShared:%d, flags:%08X\n", stashId, stashFlags&1, flags); + Unit* ptChar = D2GetClientPlayer(); + Stash* newStash = getStash(ptChar, stashFlags&1, stashId); + if (!newStash) do + newStash = addStash(ptChar, stashFlags&1); + while (newStash->id < stashId); + changeToSelectedStash(ptChar, newStash, 1); + PCPY->flags = flags; +} + + +void selectStash(Unit* ptChar, Stash* newStash)//WORKS +{ + changeToSelectedStash(ptChar, newStash, 0); + updateSelectedStashClient(ptChar); +} + + + +///// public functions +void toggleToSelfStash(Unit* ptChar) +{ + Stash* selStash = PCPY->selfStash; + if (selStash && (selStash != PCPY->currentStash)) + { + PCPY->showSharedStash = false; + selectStash(ptChar, selStash); + } +} + +void toggleToSharedStash(Unit* ptChar) +{ + Stash* selStash = PCPY->sharedStash; + if (selStash && (selStash != PCPY->currentStash)) + { + PCPY->showSharedStash = true; + selectStash(ptChar, selStash); + } +} + + +void selectPreviousStash(Unit* ptChar) +{ + Stash* selStash = PCPY->currentStash->previousStash; + if (selStash && (selStash != PCPY->currentStash)) + selectStash(ptChar, selStash); +} + + +void selectPrevious2Stash(Unit* ptChar)// Select first stash +{ + Stash* selStash = PCPY->showSharedStash ? PCPY->sharedStash : PCPY->selfStash; + if (selStash && (selStash != PCPY->currentStash)) + selectStash(ptChar, selStash); +} + +void selectNextStash(Unit* ptChar) +{ + Stash* selStash = PCPY->currentStash; + if (!selStash->isShared && (selStash->id >= maxSelfPages)) return; + if (selStash->isShared && (selStash->id >= maxSharedPages)) return; + + selStash = selStash->nextStash ? selStash->nextStash : addStash(ptChar, PCPY->showSharedStash); + + if (selStash && (selStash != PCPY->currentStash)) + selectStash(ptChar, selStash); +} + + +void selectNext2Stash(Unit* ptChar)//select last stash +{ + Stash* selStash = PCPY->showSharedStash ? PCPY->sharedStash : PCPY->selfStash;//PCPY->currentStash; + Stash* lastStash = NULL; + Unit* currentStashItem = firstClassicStashItem(ptChar); + while (selStash) + { + if (selStash->ptListItem || (selStash == PCPY->currentStash) && currentStashItem) lastStash=selStash; + selStash = selStash->nextStash; + } + if (!lastStash) + lastStash = PCPY->showSharedStash ? PCPY->sharedStash : PCPY->selfStash; + if (lastStash != PCPY->currentStash) + selectStash(ptChar, lastStash); +} + +void selectPreviousIndexStash(Unit* ptChar) +{ + selectPreviousStash(ptChar); + Stash* selStash = PCPY->currentStash; + while (selStash->previousStash && ((selStash->id+1) % nbPagesPerIndex != 0)) + selStash = selStash->previousStash; + + if (selStash && (selStash != PCPY->currentStash)) + selectStash(ptChar, selStash); +} + +void selectPreviousIndex2Stash(Unit* ptChar) +{ + selectPreviousStash(ptChar); + Stash* selStash = PCPY->currentStash; + while (selStash->previousStash && ((selStash->id+1) % nbPagesPerIndex2 != 0)) + selStash = selStash->previousStash; + + if (selStash && (selStash != PCPY->currentStash)) + selectStash(ptChar, selStash); +} + +void selectNextIndexStash(Unit* ptChar) +{ + selectNextStash(ptChar); + Stash* selStash = PCPY->currentStash; + while ((selStash->id+1) % nbPagesPerIndex != 0) + { + if (!selStash->isShared && (selStash->id >= maxSelfPages)) break; + if (selStash->isShared && (selStash->id >= maxSharedPages)) break; + selStash = selStash->nextStash ? selStash->nextStash : addStash(ptChar, PCPY->showSharedStash);; + } + if (selStash && (selStash != PCPY->currentStash)) + selectStash(ptChar, selStash); +} + +void selectNextIndex2Stash(Unit* ptChar) +{ + selectNextStash(ptChar); + Stash* selStash = PCPY->currentStash; + while ((selStash->id+1) % nbPagesPerIndex2 != 0) + { + if (!selStash->isShared && (selStash->id >= maxSelfPages)) break; + if (selStash->isShared && (selStash->id >= maxSharedPages)) break; + selStash = selStash->nextStash ? selStash->nextStash : addStash(ptChar, PCPY->showSharedStash);; + } + if (selStash && (selStash != PCPY->currentStash)) + selectStash(ptChar, selStash); +} + +////////////////////////////////////////////////////////////////////// +Stash* curStash2; +DWORD currentSawStash2; + +Unit* STDCALL getNextItem(Unit* ptChar, Unit* ptItem) +{ + Unit* item = D2UnitGetNextItem(ptItem); + if (item) return item; + + if (!curStash2) + { + switch (currentSawStash2) + { + case 0: curStash2 = PCPY->selfStash; + currentSawStash2 = 1; + break; + case 1: curStash2 = PCPY->sharedStash; + currentSawStash2 = 2; + break; + default: return NULL;//case 2: + } + } else { + curStash2 = curStash2->nextStash; + } + if (curStash2) + { + item = curStash2->ptListItem; + if (item) return item; + } + return getNextItem(ptChar,item); +} + +Unit* STDCALL initGetNextItem(Unit* ptChar, Unit* ptItem) +{ + if (ptChar->nUnitType != UNIT_PLAYER) return NULL; + if (!PCPY) return NULL; + + curStash2 = NULL; + currentSawStash2 = 0; + if (ptItem) return ptItem; + return getNextItem(ptChar,ptItem); +} + +FCT_ASM ( caller_initGetNextItem ) + PUSH DWORD PTR SS:[ESP+0x20] + PUSH DWORD PTR SS:[ESP+0xC] + CALL initGetNextItem + MOV EDI,EAX + TEST EDI,EDI + RETN +}} + + +FCT_ASM ( caller_getNextItem ) + PUSH DWORD PTR SS:[ESP+4] + PUSH DWORD PTR SS:[ESP+0x10] + CALL getNextItem + RETN 4 +}} + + +DWORD STDCALL carry1Limit(Unit* ptChar, Unit* ptItemParam, DWORD itemNum, BYTE page) +{ + if (!ptChar) return 0; + Unit* ptItem = ptItemParam ? ptItemParam : D2GameGetObject(PCGame, UNIT_ITEM, itemNum); + if ((page != 4) && (D2GetItemQuality(ptItem) == 7) && ptChar) + { + int uniqueID = D2GetUniqueID(ptItem); + if ((uniqueID>=0) && (uniqueID < (int)SgptDataTables->nbUniqueItems)) + { + UniqueItemsBIN* uniqueItems = SgptDataTables->uniqueItems + uniqueID; + if (uniqueItems && (uniqueItems->carry1==1)) + { + ItemsBIN* ptItemsBin = D2GetItemsBIN(ptItem->nTxtFileNo); + Unit* ptFirstItem = D2InventoryGetFirstItem(PCInventory); + if (ptItemsBin && ptFirstItem) + return D2VerifIfNotCarry1(ptItem, ptItemsBin, ptFirstItem); + } + } + } + return 0; +} + +FCT_ASM ( caller_carry1Limit_111 ) + PUSH DWORD PTR SS:[ESP+0x08]//page + PUSH 0//EDI + PUSH DWORD PTR SS:[ESP+0x0C] + PUSH ESI//ptChar + CALL carry1Limit + TEST EAX,EAX + JNZ end_carry1Limit + JMP D2ItemSetPage +end_carry1Limit: + ADD ESP,0xC + XOR EAX,EAX + POP EDI + POP EBX + POP ESI + POP EBP + RETN 8 +}} + +FCT_ASM ( caller_carry1Limit ) + PUSH DWORD PTR SS:[ESP+0x08]//page + PUSH 0//EBP + PUSH DWORD PTR SS:[ESP+0x0C] + PUSH DWORD PTR SS:[ESP+0x28]//ptChar + CALL carry1Limit + TEST EAX,EAX + JNZ end_carry1Limit + JMP D2ItemSetPage +end_carry1Limit: + ADD ESP,0xC + POP EDI + POP ESI + POP EBP + XOR EAX,EAX + POP EBX + ADD ESP,0x24 + RETN 8 +}} + +FCT_ASM ( caller_carry1LimitSwap_112 ) + PUSH EAX + PUSH DWORD PTR SS:[ESP+0x1C] + PUSH 0 + PUSH ESI//ptChar + CALL carry1Limit + TEST EAX,EAX + JNZ end_carry1Limit + JMP D2ItemGetPage +end_carry1Limit: + ADD ESP,8 + XOR EAX,EAX + POP EDI + POP EBP + POP ESI + POP EBX + POP ECX + RETN 8 +}} + +FCT_ASM ( caller_carry1LimitSwap_111 ) + PUSH EAX + PUSH EBP + PUSH 0 + PUSH DWORD PTR SS:[ESP+0x24]//ptChar + CALL carry1Limit + TEST EAX,EAX + JNZ end_carry1Limit + JMP D2ItemGetPage +end_carry1Limit: + ADD ESP,8 + XOR EAX,EAX + POP EDI + POP EBP + POP ESI + POP EBX + POP ECX + RETN 8 +}} + +FCT_ASM ( caller_carry1LimitSwap ) + PUSH EAX + PUSH DWORD PTR SS:[ESP+0x20] + PUSH 0 + PUSH EBP//ptChar + CALL carry1Limit + TEST EAX,EAX + JNZ end_carry1Limit + JMP D2ItemGetPage +end_carry1Limit: + ADD ESP,8 + POP EDI + POP ESI + POP EBP + XOR EAX,EAX + POP EBX + ADD ESP,0x4C + RETN 8 +}} + +/* +FCT_ASM ( caller_carry1LimitWhenDrop ) + PUSH EAX + PUSH 0 + PUSH ESI//ptItem + PUSH EDI//ptChar + CALL carry1Limit + TEST EAX,EAX + POP EAX + JE END_carry1LimitWhenDrop + MOV EDX,0x806 + RETN +END_carry1LimitWhenDrop: + ADD DWORD PTR SS:[ESP],0x1F + RETN +}}*/ + +FCT_ASM ( caller_carry1LimitWhenDrop_111 ) + PUSH 0 + PUSH 0 + PUSH DWORD PTR SS:[ESP+0x10] //ptItem + PUSH ESI //ptChar + CALL carry1Limit + TEST EAX,EAX + JNZ end_carry1Limit + JMP D2CanPutItemInInv +end_carry1Limit: + XOR EAX,EAX + RETN 0x1C +}} +/* +FCT_ASM ( caller_carry1LimitWhenDrop ) + PUSH 0 + PUSH 0 + PUSH DWORD PTR SS:[ESP+0x10] //ptItem + PUSH EDI //ptChar + CALL carry1Limit + JNZ end_carry1Limit + JMP D2CanPutItemInInv +end_carry1Limit: + XOR EAX,EAX + RETN 0x1C +}}*/ + + +FCT_ASM ( caller_carry1LimitWhenDrop ) + PUSH EAX + PUSH 0 + PUSH 0 + PUSH ESI//ptItem + PUSH EDI//ptChar + CALL carry1Limit + TEST EAX,EAX + POP EAX + JNZ END_carry1LimitWhenDrop + MOV EDX,0x806 + RETN +END_carry1LimitWhenDrop: + ADD DWORD PTR SS:[ESP],0x1F + RETN +}} + +FCT_ASM ( caller_carry1OutOfStash_111 ) + PUSH EDI + CALL D2ItemGetPage + CMP AL,4 + JNZ continue_carry1OutOfStash + ADD DWORD PTR SS:[ESP],0x17C + RETN +continue_carry1OutOfStash: + MOV ESI,DWORD PTR SS:[ESP+0x10] + TEST ESI,ESI + RETN +}} + +FCT_ASM ( caller_carry1OutOfStash ) + PUSH ESI + CALL D2ItemGetPage + CMP AL,4 + JNZ continue_carry1OutOfStash + ADD DWORD PTR SS:[ESP],0x1AF + RETN +continue_carry1OutOfStash: + MOV EAX,DWORD PTR SS:[ESP+0x14] + TEST EAX,EAX + RETN +}} + + +void Install_MultiPageStash() +{ + static int isInstalled = false; + if (isInstalled) return; + + Install_PlayerCustomData(); + Install_InterfaceStash(); + + changeToSelectedStash = version_D2Common >= V110 ? changeToSelectedStash_10 : changeToSelectedStash_9; + + if ( version_D2Game >= V110 ) + { + log_msg("Patch D2Game for carry1 unique item. (MultiPageStash)\n"); + + // Cannot put 2 items carry1 in inventory + mem_seek R7(D2Game, 0000, 0000, 55050, 57CA3, 2FE63, 99B03, CF1E3); + MEMJ_REF4( D2ItemSetPage , version_D2Game >= V111 ? caller_carry1Limit_111 : caller_carry1Limit); + //6FC8504F . E8 94670900 CALL + //01FD7CA2 . E8 6329FBFF CALL + //01F9FE62 . E8 47A8FDFF CALL + //6FCB9B02 . E8 9709F7FF CALL + //6FCEF1E2 . E8 47B7F3FF CALL + + // Cannot put 2 items carry1 in inventory by swapping + mem_seek R7(D2Game, 0000, 0000, 558D9, 58968, 310E8, 9B6E8, D10C8); + MEMJ_REF4( D2ItemGetPage , version_D2Game >= V112 ? caller_carry1LimitSwap_112 : version_D2Game >= V111 ? caller_carry1LimitSwap_111 : caller_carry1LimitSwap); + //6FC858D8 . E8 175F0900 CALL + //01FD8967 . E8 8E1DFBFF CALL + //01FA10E7 . E8 9A96FDFF CALL + //6FCBB6E7 . E8 CAEDF6FF CALL + //6FCF10C7 . E8 F895F3FF CALL + + if ( version_D2Game >= V111 ) + { + // Cannot put 2 items carry1 in inventory when drop cube + mem_seek R7(D2Game, 0000, 0000, 0000, 3D935, 49FD5, 17AD5, D7B75); + MEMJ_REF4( D2CanPutItemInInv , caller_carry1LimitWhenDrop_111); + //01FBD934 |. E8 5BD3FCFF |CALL + //01FB9FD4 |. E8 3912FCFF |CALL + //6FC37AD4 |. E8 0535FFFF |CALL + //6FCF7B74 |. E8 232FF3FF |CALL + } else { + // Cannot put 2 items carry1 in inventory when drop cube + mem_seek R7(D2Game, 0000, 0000, 14341, 0000, 0000, 0000, 0000); + memt_byte( 0xBA ,0xE8); + MEMT_REF4( 0x00000806 , caller_carry1LimitWhenDrop); + //6FC44341 |. BA 06080000 |MOV EDX,806 + } + + // Verif only carry1 out of stash page when pick up an item + mem_seek R7(D2Game, 0000, 0000, 1299E, 38E3B, 43F0B, 1209B, D211B); + memt_byte( 0x8B ,0xE8); + MEMT_REF4( version_D2Game >= V111 ? 0x850C2474 : 0x85102444 , version_D2Game >= V111 ? caller_carry1OutOfStash_111 : caller_carry1OutOfStash); + memt_byte( version_D2Game >= V111 ? 0xF6 : 0xC0 ,0x90); + //6FC4299E |. 8B4424 10 |MOV EAX,DWORD PTR SS:[ESP+10] + //6FC429A2 |. 85C0 |TEST EAX,EAX + //01FB8E3B |. 8B7424 0C |MOV ESI,DWORD PTR SS:[ESP+C] + //01FB8E3F |. 85F6 |TEST ESI,ESI + //01FB3F0B |. 8B7424 0C |MOV ESI,DWORD PTR SS:[ESP+C] + //01FB3F0F |. 85F6 |TEST ESI,ESI + //6FC3209B |. 8B7424 0C |MOV ESI,DWORD PTR SS:[ESP+C] + //6FC3209F |. 85F6 |TEST ESI,ESI + //6FCF211B |. 8B7424 0C |MOV ESI,DWORD PTR SS:[ESP+C] + //6FCF211F |. 85F6 |TEST ESI,ESI + + log_msg("\n"); + } + + isInstalled = true; +} + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/Interface_Skills.cpp b/PlugY/Interface_Skills.cpp new file mode 100644 index 0000000..a3a99f0 --- /dev/null +++ b/PlugY/Interface_Skills.cpp @@ -0,0 +1,219 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Interface functions + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "updateServer.h" // Install_UpdateServer() +#include "plugYFiles.h" // Install_PlugYImagesFiles() +#include "skillsPoints.h" +#include + +int posXUnassignSkillBtn=-1; +int posYUnassignSkillBtn=-1; + +DWORD btnSkillIsDown; +DWORD getXSkillBtn() {return RX(posXUnassignSkillBtn<0? 0x243 : posXUnassignSkillBtn);} +#define getLSkillBtn() 32 +DWORD getYSkillBtn() {return RY(posYUnassignSkillBtn<0 ? 0x1B1 : posYUnassignSkillBtn);} +#define getHSkillBtn() 32 +#define isOnButtonUnassignSkill(x,y) isOnRect(x, y, getXSkillBtn(), getYSkillBtn(), getLSkillBtn(), getHSkillBtn()) + + +void STDCALL printSkillsPageBtns() +{ + if (active_SkillsPoints && !onRealm && D2isLODGame()) + { + sDrawImageInfo data; + ZeroMemory(&data,sizeof(data)); + setImage(&data, unassignSkillsBtnImages); + setFrame(&data, btnSkillIsDown); + D2PrintImage(&data, getXSkillBtn(), getYSkillBtn(), -1, 5, 0); + + if ( isOnButtonUnassignSkill(D2GetMouseX(),D2GetMouseY())) + { + LPWSTR popupText = getTranslatedString(STR_SKILLS_UNASSIGN); + D2PrintPopup(popupText, getXSkillBtn()+getLSkillBtn()/2, getYSkillBtn()-getHSkillBtn(), 0, 1); + } + } +} + +Unit* STDCALL skillsPageMouseDown(sWinMessage* msg) +{ + Unit* ptChar = D2GetClientPlayer(); + + if ( active_SkillsPoints && !onRealm && D2isLODGame() && isOnButtonUnassignSkill(D2GetMouseX(),D2GetMouseY())) + { + log_msg("push down left button unassign skill\n"); + btnSkillIsDown = 1; + D2PlaySound(4,0,0,0,0); + freeMessage(msg); + return NULL; + } + return ptChar; +} + + +void STDCALL skillsPageMouseUp() +{ + if ( active_SkillsPoints && !onRealm && D2isLODGame() && isOnButtonUnassignSkill(D2GetMouseX(),D2GetMouseY())) + { + log_msg("push up left button unassign skill\n"); + if (btnSkillIsDown) + updateServer(US_UNASSIGN_SKILLS); + } + btnSkillIsDown = 0; +} + + +FCT_ASM ( caller_printSkillsPageBtns_111 ) + CALL printSkillsPageBtns + POP EDI + POP ESI + POP EBX + RETN +}} + + +FCT_ASM ( caller_printSkillsPageBtns ) + CALL printSkillsPageBtns + POP EDI + POP ESI + POP EBP + POP EBX + ADD ESP,0x48 + RETN +}} + +FCT_ASM ( caller_DontPrintSkillPointsRemaining_111 ) + MOV AL,BYTE PTR DS:[onRealm] + TEST AL,AL + JNZ dontPrint + ADD DWORD PTR SS:[ESP],0xF2 + RETN +dontPrint: + MOV ECX,0x1083 + RETN +}} + +FCT_ASM ( caller_DontPrintSkillPointsRemaining ) + MOV AL,BYTE PTR DS:[onRealm] + TEST AL,AL + JNZ dontPrint + ADD DWORD PTR SS:[ESP],0x9D + RETN +dontPrint: + MOV ECX,0x1083 + RETN +}} + +FCT_ASM ( caller_skillsPageMouseDown_111 ) + PUSH EBP + CALL skillsPageMouseDown + RETN +}} + + +FCT_ASM ( caller_skillsPageMouseDown ) + PUSH EBX + CALL skillsPageMouseDown + RETN +}} + +FCT_ASM ( caller_skillsPageMouseUp ) + CALL skillsPageMouseUp + JMP D2FreeWinMessage +}} + +void Install_InterfaceSkills() +{ + static int isInstalled = false; + if (isInstalled) return; + + Install_UpdateServer(); + Install_PlugYImagesFiles(); + + log_msg("Patch D2Client for skills interface. (InterfaceSkills)\n"); + + // Print new buttons images + mem_seek R7(D2Client, 7AC20, 7AC20, 77073, 16190, 8A9C0, 7F320, 77F20); + memt_byte( 0x5F, 0xE9 ); // JMP caller_printBtns + if ( version_D2Client >= V111 ) { + MEMT_REF4( 0xCCC35B5E, caller_printSkillsPageBtns_111); + //6FAC6190 5F POP EDI + //6FAC6191 5E POP ESI + //6FAC6192 5B POP EBX + //6FAC6193 C3 RETN + //6FAC6194 CC INT3 + //6FB3A9C0 |> 5F POP EDI + //6FB3A9C1 |. 5E POP ESI + //6FB3A9C2 |. 5B POP EBX + //6FB3A9C3 \. C3 RETN + //6FB3A9C4 CC INT3 + //6FB2F320 |> 5F POP EDI + //6FB2F321 |. 5E POP ESI + //6FB2F322 |. 5B POP EBX + //6FB2F323 \. C3 RETN + //6FB2F324 CC INT3 + //6FB27F20 |> 5F POP EDI + //6FB27F21 |. 5E POP ESI + //6FB27F22 |. 5B POP EBX + //6FB27F23 \. C3 RETN + //6FB27F24 CC INT3 + } else { + MEMT_REF4( 0x835B5D5E, caller_printSkillsPageBtns); + memt_byte( 0xC4, 0x90 ); // NOP + memt_byte( 0x48, 0x90 ); // NOP + memt_byte( 0xC3, 0x90 ); // NOP + //6FB17073 |. 5F POP EDI + //6FB17074 |. 5E POP ESI + //6FB17075 |. 5D POP EBP + //6FB17076 |. 5B POP EBX + //6FB17077 |. 83C4 48 ADD ESP,48 + //6FB1707A \. C3 RETN + } + + if (posXUnassignSkillBtn==-1 && posYUnassignSkillBtn==-1) + { + // Don't print "Skill Points Remaining" + mem_seek R7(D2Client, 7AC30, 7AC30, 77080, 16294, 8AC74, 7ECF4, 78334); + memt_byte( 0xB9, 0xE8 ); + MEMT_REF4( 0x00001083, version_D2Client >= V111 ? caller_DontPrintSkillPointsRemaining_111 : caller_DontPrintSkillPointsRemaining); + //6FB17080 /$ B9 83100000 MOV ECX,1083 + //6FAC6294 |. B9 83100000 MOV ECX,1083 + //6FB3AC74 |. B9 83100000 MOV ECX,1083 + //6FB2ECF4 |. B9 83100000 MOV ECX,1083 + //6FB28334 |. B9 83100000 MOV ECX,1083 + } + + // Manage mouse down (Play sound) + mem_seek R7(D2Client, 7BBD1, 7BBD1, 780E4, 17BC2, 8C6E2, 808B2, 79C62); + memt_byte( 0xC7, 0xE8 ); // CALL caller_skillsPageMouseDown + MEMT_REF4( version_D2Client >= V111 ? 0x00001845 : 0x00001843, version_D2Client >= V111 ? caller_skillsPageMouseDown_111 : caller_skillsPageMouseDown); + memt_byte( 0x00, 0x90 ); // NOP + memt_byte( 0x00, 0x90 ); // NOP + //6FB180E4 > C743 18 00000000 MOV DWORD PTR DS:[EBX+18],0 + //6FAC7BC2 > C745 18 00000000 MOV DWORD PTR SS:[EBP+18],0 + //6FB3C6E2 > C745 18 00000000 MOV DWORD PTR SS:[EBP+18],0 + //6FB308B2 > C745 18 000000>MOV DWORD PTR SS:[EBP+18],0 + //6FB29C62 > C745 18 000000>MOV DWORD PTR SS:[EBP+18],0 + + // Manage mouse up + mem_seek R7(D2Client, 7BC40, 7BC40, 78466, 17558, 8C078, 80248, 795F8); + MEMJ_REF4( D2FreeWinMessage, caller_skillsPageMouseUp);//0xFFF93B0A + //6FB18465 . E8 C07D0400 CALL + //6FAC7557 .^E9 4248FFFF JMP + //6FB3C077 .^E9 16FDF7FF JMP + //6FB30247 .^E9 2CBCF8FF JMP + //6FB295F7 .^E9 8828F9FF JMP + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/Interface_Stash.cpp b/PlugY/Interface_Stash.cpp new file mode 100644 index 0000000..f59f2a9 --- /dev/null +++ b/PlugY/Interface_Stash.cpp @@ -0,0 +1,524 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Interface stats page functions + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "interface_Stash.h" +#include "d2functions.h" +#include "updateServer.h" +#include "infinityStash.h" +#include "plugYFiles.h" // Install_PlugYImagesFiles() +#include + +static struct +{ + union{ + DWORD all; + struct{ + DWORD previous:1; + DWORD next:1; + DWORD toggleToSharedStash:1; + DWORD previousIndex:1; + DWORD nextIndex:1; + DWORD putGold:1; + DWORD takeGold:1; + }; + }; +} isDownBtn; + +bool displaySharedSetItemNameInGreen = true; +int posXPreviousBtn=-1; +int posYPreviousBtn=-1; +int posXNextBtn=-1; +int posYNextBtn=-1; +int posXSharedBtn=-1; +int posYSharedBtn=-1; +int posXPreviousIndexBtn=-1; +int posYPreviousIndexBtn=-1; +int posXNextIndexBtn=-1; +int posYNextIndexBtn=-1; +int posXPutGoldBtn=-1; +int posYPutGoldBtn=-1; +int posXTakeGoldBtn=-1; +int posYTakeGoldBtn=-1; + +DWORD getXPreviousBtn() {return RX(posXPreviousBtn<0? D2GetResolution()?0x80:0xAF : posXPreviousBtn);} +#define getLPreviousBtn() 32 +DWORD getYPreviousBtn() {return RY(posYPreviousBtn<0 ? 0x40 : posYPreviousBtn);} +#define getHPreviousBtn() 32 + +DWORD getXNextBtn() {return RX(posXNextBtn<0 ? D2GetResolution()?0xA0:0xCF :posXNextBtn);}//?169:SEL_X(0x63, 0x63, 0xCF, 0xA0));} +#define getLNextBtn() 32 +DWORD getYNextBtn() {return RY(posYNextBtn<0 ? 0x40 : posYNextBtn);} +#define getHNextBtn() 32 + +DWORD getXSharedBtn() {return RX(posXSharedBtn<0 ? D2GetResolution()?0x10:0x6F :posXSharedBtn);}//17:SEL_X(0xE3, 0xE3, 0x6F, 0x10));}//0xD8 +#define getLSharedBtn() 32 +DWORD getYSharedBtn() {return RY(posYSharedBtn<0 ? 0x40 : posYSharedBtn);} +#define getHSharedBtn() 32 + +DWORD getXPreviousIndexBtn() {return RX(posXPreviousIndexBtn<0 ? D2GetResolution()?0x60:0x8F :posXPreviousIndexBtn);}//73:SEL_X(0x18, 0x60, 0x8F, 0x60));} +#define getLPreviousIndexBtn() 32 +DWORD getYPreviousIndexBtn() {return RY(posYPreviousIndexBtn<0 ? 0x40 : posYPreviousIndexBtn);} +#define getHPreviousIndexBtn() 32 + +DWORD getXNextIndexBtn() {return RX(posXNextIndexBtn<0? D2GetResolution()?0xC0:0xEF : posXNextIndexBtn);}//217:SEL_X(0x128, 0xC0, 0xEF, 0xC0));} +#define getLNextIndexBtn() 32 +DWORD getYNextIndexBtn() {return RY(posYNextIndexBtn<0 ? 0x40 : posYNextIndexBtn);} +#define getHNextIndexBtn() 32 + +DWORD getXPutGoldBtn() {return RX(posXPutGoldBtn<0? 0x1C : posXPutGoldBtn);} +#define getLPutGoldBtn() 32 +DWORD getYPutGoldBtn() {return RY(posYPutGoldBtn<0 ? 0x1A8 : posYPutGoldBtn);} +#define getHPutGoldBtn() 32 + +DWORD getXTakeGoldBtn() {return RX(posXTakeGoldBtn<0? 0x105 : posXTakeGoldBtn);} +#define getLTakeGoldBtn() 32 +DWORD getYTakeGoldBtn() {return RY(posYTakeGoldBtn<0 ? 0x1A8 : posYTakeGoldBtn);} +#define getHTakeGoldBtn() 32 + +//closeBtn x: D2C=0x113 LOD=0x110(0->0x28) y: D2C=0x41 LOD=0x40 (-0x23 -> 5) + + +#define isOnButtonNextStash(x,y) isOnRect(x, y, getXNextBtn(), getYNextBtn(), getLNextBtn(), getHNextBtn()) +#define isOnButtonPreviousStash(x,y) isOnRect(x, y, getXPreviousBtn(), getYPreviousBtn(), getLPreviousBtn(), getHPreviousBtn()) +#define isOnButtonToggleSharedStash(x,y) isOnRect(x, y, getXSharedBtn(), getYSharedBtn(), getLSharedBtn(), getHSharedBtn()) +#define isOnButtonNextIndexStash(x,y) isOnRect(x, y, getXNextIndexBtn(), getYNextIndexBtn(), getLNextIndexBtn(), getHNextIndexBtn()) +#define isOnButtonPreviousIndexStash(x,y) isOnRect(x, y, getXPreviousIndexBtn(), getYPreviousIndexBtn(), getLPreviousIndexBtn(), getHPreviousIndexBtn()) +#define isOnButtonPutGold(x,y) isOnRect(x, y, getXPutGoldBtn(), getYPutGoldBtn(), getLPutGoldBtn(), getHPutGoldBtn()) +#define isOnButtonTakeGold(x,y) isOnRect(x, y, getXTakeGoldBtn(), getYTakeGoldBtn(), getLTakeGoldBtn(), getHTakeGoldBtn()) + + + +void* STDCALL printBtns() +{ + if (onRealm || !D2isLODGame()) return D2LoadBuySelBtn(); + + Unit* ptChar = D2GetClientPlayer(); + + sDrawImageInfo data; + ZeroMemory(&data,sizeof(data)); + setImage(&data, stashBtnsImages); + + setFrame(&data, 0 + isDownBtn.previous); + D2PrintImage(&data, getXPreviousBtn(), getYPreviousBtn(), -1, 5, 0); + + setFrame(&data, 2 + isDownBtn.next); + D2PrintImage(&data, getXNextBtn(), getYNextBtn(), -1, 5, 0); + + if (active_sharedStash) + { + setFrame(&data, 4 + isDownBtn.toggleToSharedStash + (PCPY->showSharedStash?2:0) ); + D2PrintImage(&data, getXSharedBtn(), getYSharedBtn(), -1, 5, 0); + } + + setFrame(&data, 8 + isDownBtn.previousIndex); + D2PrintImage(&data, getXPreviousIndexBtn(), getYPreviousIndexBtn(), -1, 5, 0); + + setFrame(&data, 10 + isDownBtn.nextIndex); + D2PrintImage(&data, getXNextIndexBtn(), getYNextIndexBtn(), -1, 5, 0); + + if (active_sharedGold) + { + setImage(&data, sharedGoldBtnsImages); + setFrame(&data, 0 + isDownBtn.putGold); + D2PrintImage(&data, getXPutGoldBtn(), getYPutGoldBtn(), -1, 5, 0); + + setFrame(&data, 2 + isDownBtn.takeGold); + D2PrintImage(&data, getXTakeGoldBtn(), getYTakeGoldBtn(), -1, 5, 0); + } + + + LPWSTR lpText; + WCHAR text[100]; + DWORD mx = D2GetMouseX(); + DWORD my = D2GetMouseY(); + + D2SetFont(1); + + if (isOnButtonPreviousStash(mx,my)) { + lpText = getTranslatedString(STR_STASH_PREVIOUS_PAGE); + D2PrintPopup(lpText, getXPreviousBtn()+getLPreviousBtn()/2, getYPreviousBtn()-getHPreviousBtn(), WHITE, 1); + + } else if (isOnButtonNextStash(mx,my)) { + lpText = getTranslatedString(STR_STASH_NEXT_PAGE); + D2PrintPopup(lpText, getXNextBtn()+getLNextBtn()/2, getYNextBtn()-getHNextBtn(), WHITE, 1); + + } else if (active_sharedStash && isOnButtonToggleSharedStash(mx,my)) { + lpText = getTranslatedString(PCPY->showSharedStash ? STR_TOGGLE_TO_PERSONAL : STR_TOGGLE_TO_SHARED); + D2PrintPopup(lpText, getXSharedBtn()+getLSharedBtn()/2, getYSharedBtn()-getHSharedBtn(), WHITE, 1); + + } else if (isOnButtonPreviousIndexStash(mx,my)) { + swprintf(text, getTranslatedString(STR_STASH_PREVIOUS_INDEX) ,nbPagesPerIndex,nbPagesPerIndex2); + D2PrintPopup(text, getXPreviousIndexBtn()+getLPreviousIndexBtn()/2, getYPreviousIndexBtn()-getHPreviousIndexBtn(), 0, 0); + + } else if (isOnButtonNextIndexStash(mx,my)) { + swprintf(text, getTranslatedString(STR_STASH_NEXT_INDEX) ,nbPagesPerIndex,nbPagesPerIndex2); + D2PrintPopup(text, getXNextIndexBtn()+getLNextIndexBtn()/2, getYNextIndexBtn()-getHNextIndexBtn(), WHITE, 1); + + } else if (active_sharedGold && isOnButtonPutGold(mx,my)) { + lpText = getTranslatedString(STR_PUT_GOLD); + D2PrintPopup(lpText, getXPutGoldBtn()+getLPutGoldBtn()/2, getYPutGoldBtn()-getHPutGoldBtn(), WHITE, 1); + + } else if (active_sharedGold && isOnButtonTakeGold(mx,my)) { + lpText = getTranslatedString(STR_TAKE_GOLD); + D2PrintPopup(lpText, getXTakeGoldBtn()+getLTakeGoldBtn()/2, getYTakeGoldBtn()-getHTakeGoldBtn(), WHITE, 1); + } + + return D2LoadBuySelBtn(); +} + + +DWORD STDCALL manageBtnDown(sWinMessage* msg) +{ + if (onRealm || !D2isLODGame()) return 0; + + if (isOnButtonPreviousStash(msg->x,msg->y)) + isDownBtn.previous = 1; + else if (isOnButtonNextStash(msg->x,msg->y)) + isDownBtn.next = 1; + else if (active_sharedStash && isOnButtonToggleSharedStash(msg->x,msg->y)) + isDownBtn.toggleToSharedStash = 1; + else if (isOnButtonPreviousIndexStash(msg->x,msg->y)) + isDownBtn.previousIndex = 1; + else if (isOnButtonNextIndexStash(msg->x,msg->y)) + isDownBtn.nextIndex = 1; + else if (active_sharedGold && isOnButtonPutGold(msg->x,msg->y)) + isDownBtn.putGold = 1; + else if (active_sharedGold && isOnButtonTakeGold(msg->x,msg->y)) + isDownBtn.takeGold = 1; + else return 0; + + D2PlaySound(4,0,0,0,0); + freeMessage(msg); + return 1; +} + + +DWORD STDCALL manageBtnUp(sWinMessage* msg) +{ + if (onRealm || !D2isLODGame()) return 0; + + Unit* ptChar = D2GetClientPlayer(); + + if (isOnButtonPreviousStash(msg->x,msg->y)) { + log_msg("push up left button previous\n"); + if (isDownBtn.previous) + if (GetKeyState(VK_SHIFT)<0) + updateServer(US_SELECT_PREVIOUS2); + else + updateServer(US_SELECT_PREVIOUS); + + } else if (isOnButtonNextStash(msg->x,msg->y)) { + log_msg("push up left button next\n"); + if (isDownBtn.next) + if (GetKeyState(VK_SHIFT)<0) + updateServer(US_SELECT_NEXT2); + else + updateServer(US_SELECT_NEXT); + + } else if (active_sharedStash && isOnButtonToggleSharedStash(msg->x,msg->y)) { + log_msg("push up left button shared\n"); + if (isDownBtn.toggleToSharedStash) + if (PCPY->showSharedStash) + updateServer(US_SELECT_SELF); + else + updateServer(US_SELECT_SHARED); + + } else if (isOnButtonPreviousIndexStash(msg->x,msg->y)) { + log_msg("select left button previous index\n"); + if (isDownBtn.previousIndex) + if (GetKeyState(VK_SHIFT)<0) + updateServer(US_SELECT_PREVIOUS_INDEX2); + else + updateServer(US_SELECT_PREVIOUS_INDEX); + + } else if (isOnButtonNextIndexStash(msg->x,msg->y)) { + log_msg("push up left button next index\n"); + if (isDownBtn.nextIndex) + if (GetKeyState(VK_SHIFT)<0) + updateServer(US_SELECT_NEXT_INDEX2); + else + updateServer(US_SELECT_NEXT_INDEX); + + } else if (active_sharedGold && isOnButtonPutGold(msg->x,msg->y)) { + log_msg("push up left put gold\n"); + if (isDownBtn.putGold) + updateServer(US_PUTGOLD); + + } else if (active_sharedGold && isOnButtonTakeGold(msg->x,msg->y)) { + log_msg("push up left take gold\n"); + if (isDownBtn.takeGold) + updateServer(US_TAKEGOLD); + + } else return 0; + + return 1; +} + +void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color, DWORD bfalse) +{ + if (onRealm || !D2isLODGame() ) + { + D2PrintString(maxGoldText,x,y,color,bfalse); + return; + } + + Unit* ptChar = D2GetClientPlayer(); + WCHAR popupText[100]; + + if (PCPY->currentStash) + { + bool isShared = PCPY->currentStash->isShared; + DWORD currentId = PCPY->currentStash->id; + + if (PCPY->currentStash->name && PCPY->currentStash->name[0]) + mbstowcs(popupText,PCPY->currentStash->name,50);//strlen(PCPY->currentStash->name)+1 + else swprintf(popupText, getTranslatedString( isShared ? STR_SHARED_PAGE_NUMBER : STR_PERSONAL_PAGE_NUMBER), currentId+1); + D2PrintString(popupText,x,y, isShared?RED:WHITE ,bfalse); + } else { + swprintf(popupText, getTranslatedString(STR_NO_SELECTED_PAGE)); + D2PrintString(popupText,x,y, WHITE ,bfalse); + } + + //printGoldMaxPopup + DWORD mx = D2GetMouseX(); + DWORD my = D2GetMouseY(); + if ((RX(0x5E) < mx) && (mx < RX(0xF8)) && (RY(0x1C8) < my) && (my < RY(0x1B6)) ) + { + if (active_sharedGold) + { + swprintf(popupText, L"%s\n", maxGoldText); + swprintf(popupText+wcslen(popupText), getTranslatedString(STR_SHARED_GOLD_QUANTITY), PCPY->sharedGold); + DWORD x = D2GetPixelLen(maxGoldText); + DWORD x2 = D2GetPixelLen(popupText) - x; + D2PrintPopup(popupText, RX(0xA8-max(x,x2)/2), RY(0x1CA), WHITE, 0); + } else + D2PrintPopup(maxGoldText, RX(0xA8), RY(0x1CA), WHITE, 1); + } +} + + +static Stash* curStash=NULL; +static DWORD currentSawStash=0; +Unit* STDCALL getNextItemForSet(Unit* ptItem) +{ + Unit* item = ptItem?D2UnitGetNextItem(ptItem):NULL; + if (item) return item; + + if (!curStash) + { + Unit* ptChar = D2GetClientPlayer(); + switch (currentSawStash) + { + case 0: curStash = PCPY->selfStash; + currentSawStash = displaySharedSetItemNameInGreen ? 1 : 2; + break; + case 1: curStash = PCPY->sharedStash; + currentSawStash = 2; + break; + default:return NULL; + } + } else { + curStash = curStash->nextStash; + } + if (curStash) + { + item = curStash->ptListItem; + if (item) return item; + } + return getNextItemForSet(item); +} + +Unit* STDCALL initGetNextItemForSet(Inventory* ptInventory) +{ + Unit* ptChar = D2GetClientPlayer(); + if (ptChar->nUnitType != UNIT_PLAYER) return NULL; + if (!PCPY) return NULL; + + curStash = NULL; + currentSawStash = 0; + Unit* item = D2InventoryGetFirstItem(ptInventory); + if (item) return item; + return getNextItemForSet(item); +} + + +FCT_ASM( caller_manageBtnDown_111 ) + PUSH EBP + CALL manageBtnDown + TEST EAX,EAX + JE IS_NOT_ON_BUTTON + POP EDX + MOV EDX, DWORD PTR DS:[EDX+0x10] + MOV DWORD PTR DS:[EDX],1 + POP EDI + POP ESI + POP EBP + POP EBX + RETN 4 +IS_NOT_ON_BUTTON: + JMP D2ClickOnStashButton +}} + +FCT_ASM( caller_manageBtnDown ) + PUSH EDI + CALL manageBtnDown + TEST EAX,EAX + JE IS_NOT_ON_BUTTON + POP EDX + MOV EDX, DWORD PTR DS:[EDX+0xF3] + MOV DWORD PTR DS:[EDX],1 + POP EDI + POP ESI + POP EBP + POP EBX + RETN 4 +IS_NOT_ON_BUTTON: + JMP D2isLODGame +}} + +FCT_ASM( caller_manageBtnUp_111 ) + PUSH EBX + CALL manageBtnUp + MOV isDownBtn.all,0 + TEST EAX,EAX + JE IS_NOT_ON_BUTTON + POP EDX + MOV EDX, DWORD PTR DS:[EDX+0x1A] + MOV DWORD PTR DS:[EDX],0 + SUB EDX,8 + MOV DWORD PTR DS:[EDX],0 + ADD EDX,4 + MOV DWORD PTR DS:[EDX],0 + ADD EDX,0x68 + MOV DWORD PTR DS:[EDX],0 + POP EDI + POP ESI + POP EBP + POP EBX + POP ECX + RETN 4 +IS_NOT_ON_BUTTON: + JMP D2ClickOnStashButton +}} + +FCT_ASM( caller_manageBtnUp ) + PUSH EBP + CALL manageBtnUp + MOV isDownBtn.all,0 + TEST EAX,EAX + JE IS_NOT_ON_BUTTON + POP EDX + MOV EDX, DWORD PTR DS:[EDX+0xEA] + MOV DWORD PTR DS:[EDX],0 + SUB EDX,8 + MOV DWORD PTR DS:[EDX],0 + ADD EDX,4 + MOV DWORD PTR DS:[EDX],0 + ADD EDX,0x68 + MOV DWORD PTR DS:[EDX],0 + POP EDI + POP ESI + POP EBP + POP EBX + RETN 4 +IS_NOT_ON_BUTTON: + JMP D2isLODGame +}} + + +FCT_ASM ( initBtnsStates ) + MOV isDownBtn.all,0 + ADD ESP,0x104 + RETN +}} + + +void Install_InterfaceStash() +{ + static int isInstalled = false; + if (isInstalled) return; + + Install_UpdateServer(); + Install_PlugYImagesFiles(); + + log_msg("Patch D2Client for stash interface. (InterfaceStash)\n"); + + // Print button images + mem_seek R7(D2Client, 39060, 39060, 3F399, B1006, 7DF86, B3656, 99A56); + MEMC_REF4( D2LoadBuySelBtn, printBtns); + //6FADF398 |. E8 734D0400 CALL D2Client.6FB24110 + //6FB61005 |. E8 A6D3FEFF CALL D2Client.6FB4E3B0 + //6FB2DF85 |. E8 3642FEFF CALL D2Client.6FB121C0 + //6FB63655 |. E8 9682FDFF CALL D2Client.6FB3B8F0 + //6FB49A55 |. E8 96500200 CALL D2Client.6FB6EAF0 + + // print page number + mem_seek R7(D2Client, 3903C, 3903C, 3F375, B0FE3, 7DF63, B3633, 99A33); + MEMJ_REF4( D2PrintString, printPageNumber); + //6FADF374 |. E8 3FCC0800 CALL + //6FB60FE2 |. E8 99C2F5FF CALL + //6FB2DF62 |. E8 19F3F8FF CALL + //6FB63632 |. E8 299DF5FF CALL + //6FB49A32 |. E8 4739F7FF CALL + + // Manage mouse down (Play sound) + mem_seek R7(D2Client, 45091, 45091, 4BBA1, B4666, 7FDD6, B54A6, 9B8A6); + MEMC_REF4( version_D2Client >= V111 ? (DWORD)D2ClickOnStashButton : (DWORD)D2isLODGame, version_D2Client >= V111 ? caller_manageBtnDown_111 : caller_manageBtnDown); + //6FAEBBA0 > E8 DB04FCFF CALL D2Client.6FAAC080 + //6FB64665 . E8 B61EFFFF CALL D2Client.6FB56520 + //6FB2FDD5 . E8 E612FFFF CALL D2Client.6FB210C0 + //6FB654A5 . E8 9611FFFF CALL D2Client.6FB56640 + //6FB4B8A5 . E8 5614FFFF CALL D2Client.6FB3CD00 + + // Manage mouse up + mem_seek R7(D2Client, 455F9, 455F9, 4C0F9, B57B9, 7FC09, B52D9, 9B6D9); + MEMC_REF4( version_D2Client >= V111 ? (DWORD)D2ClickOnStashButton : (DWORD)D2isLODGame, version_D2Client >= V111 ? caller_manageBtnUp_111 : caller_manageBtnUp); + //6FAEC0F8 > E8 83FFFBFF CALL D2Client.6FAAC080 + //6FB657B8 > E8 630DFFFF CALL D2Client.6FB56520 + //6FB2FC08 > E8 B314FFFF CALL D2Client.6FB210C0 + //6FB652D8 > E8 6313FFFF CALL D2Client.6FB56640 + //6FB4B6D8 > E8 2316FFFF CALL D2Client.6FB3CD00 + + // init state of button on open stash page + mem_seek R7(D2Client, 45B3A, 45B3A, 4C63A, A645A, 749DA, A9D9A, 8CC3A); + memt_byte( 0x81, 0xE9 ); // CALL initBtnsStates + MEMT_REF4( 0x000104C4, initBtnsStates); + memt_byte( 0x00, 0x90 ); + //6FAE5B3A |> 81C4 04010000 ADD ESP,104 + //6FAE5B3A |> 81C4 04010000 ADD ESP,104 + //6FAEC63A |> 81C4 04010000 ADD ESP,104 + //6FB5645A |> 81C4 04010000 ADD ESP,104 + //6FB249DA |> 81C4 04010000 ADD ESP,104 + //6FB59D9A |> 81C4 04010000 ADD ESP,104 + //6FB3CC3A |> 81C4 04010000 ADD ESP,104 + + // init the search of print in green the item set name we have in stash + mem_seek R7(D2Client, 3F098, 3F098, 45997, A71F4, 71F64, A7314, 8D434); + MEMJ_REF4( D2InventoryGetFirstItem, initGetNextItemForSet); + //6FAE5996 |. E8 D5500800 CALL + //6FB571F3 |. E8 D64EF6FF CALL + //6FB21F63 |. E8 96A1F9FF CALL + //6FB57313 |. E8 8250F6FF CALL + //6FB3D433 |. E8 B8F0F7FF CALL + + // Get next item for print in green the item set name we have in stash + mem_seek R7(D2Client, 3F0FA, 3F0FA, 45A1C, A728B, 71FFB, A73AB, 8D4CB); + MEMJ_REF4( D2UnitGetNextItem, getNextItemForSet); + //6FAE5A1B E8 4A500800 CALL + //6FB5728A |. E8 0B4FF6FF |CALL + //6FB21FFA |. E8 A1A1F9FF |CALL + //6FB573AA |. E8 7550F6FF |CALL + //6FB3D4CA |. E8 99F0F7FF |CALL + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/Interface_Stats.cpp b/PlugY/Interface_Stats.cpp new file mode 100644 index 0000000..b95c7ac --- /dev/null +++ b/PlugY/Interface_Stats.cpp @@ -0,0 +1,318 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Interface functions + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "plugYFiles.h" // Install_PlugYImagesFiles() +#include "statsPoints.h" +#include "newInterfaces.h" +#include + +static struct +{ + union{ + DWORD all; + struct{ + DWORD previousPage:1; + DWORD nextPage:1; + }; + }; +} isDownBtn; + +#define getXPreviousPageBtn() RX(0x19)//0x70 +#define getLPreviousPageBtn() 32 +#define getYPreviousPageBtn() RY(0x40) +#define getHPreviousPageBtn() 32 +#define isOnPreviousPageBtn(x,y) isOnRect(x, y, getXPreviousPageBtn(), getYPreviousPageBtn(), getLPreviousPageBtn(), getHPreviousPageBtn()) + +#define getXNextPageBtn() RX(D2GetResolution()?0x43:0x8A) +#define getLNextPageBtn() 32 +#define getYNextPageBtn() RY(D2GetResolution()?0x40:0x70) +#define getHNextPageBtn() 32 +#define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn()) + + + +void STDCALL printStatsPageBtns() +{ + if (!active_newInterfaces || !D2isLODGame() ) return; + + LPWSTR lpText; + DWORD mx = D2GetMouseX(); + DWORD my = D2GetMouseY(); + + sDrawImageInfo data; + ZeroMemory(&data,sizeof(data)); + + if (printBackgroundOnMainPage && D2GetResolution()) + { + setImage(&data, statsBackgroundImages); + setFrame(&data, 1); + D2PrintImage(&data, getXPreviousPageBtn()-7, getYPreviousPageBtn()+8, -1, 5, 0); + } + + setImage(&data, D2LoadBuySelBtn()); + if (D2GetResolution()) + { + 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" + { + lpText = getTranslatedString(STR_PREVIOUS_PAGE); + D2PrintPopup(lpText, getXPreviousPageBtn()+getLPreviousPageBtn()/2, getYPreviousPageBtn()-getHPreviousPageBtn(), WHITE, 1); + } + else if ( isOnNextPageBtn(mx,my)) + { + lpText = getTranslatedString(STR_NEXT_PAGE); + D2PrintPopup(lpText, getXNextPageBtn()+getLNextPageBtn()/2, getYNextPageBtn()-getHNextPageBtn(), WHITE, 1); + } +} + +Unit* STDCALL statsPageMouseDown(sWinMessage* msg) +{ + Unit* ptChar = D2GetClientPlayer(); + + if (!active_newInterfaces || !D2isLODGame() ) return ptChar; + + if (D2GetResolution() && isOnPreviousPageBtn(msg->x,msg->y)) + { + log_msg("push down left button previous page\n"); + isDownBtn.previousPage = 1; + D2PlaySound(4,0,0,0,0); + freeMessage(msg); + return NULL; + } + 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); + freeMessage(msg); + return NULL; + } + return ptChar; +} + + +Unit* STDCALL statsPageMouseUp(sWinMessage* msg) +{ + Unit* ptChar = D2GetClientPlayer(); + + if (!active_newInterfaces || !D2isLODGame() ) return ptChar; + + if (D2GetResolution() && isOnPreviousPageBtn(msg->x,msg->y)) + { + log_msg("push up left button previous page\n"); + if (isDownBtn.previousPage) + { + GoPreviousStatPage(); + log_msg("previous page press\n"); + isDownBtn.all=0; + freeMessage(msg); + return NULL; + } + } + else if (isOnNextPageBtn(msg->x,msg->y)) + { + log_msg("push up left button next page\n"); + if (isDownBtn.nextPage) + { + GoNextStatPage(); + log_msg("next page press\n"); + isDownBtn.all=0; + freeMessage(msg); + return NULL; + } + } + + isDownBtn.all=0; + return ptChar; +} + +FCT_ASM ( caller_printStatsPageBtns_111 ) + CALL printStatsPageBtns + POP EDI + POP ESI + POP EBP + POP EBX + ADD ESP,0x370 + RETN +}} + + +FCT_ASM ( caller_printStatsPageBtns ) + CALL printStatsPageBtns + POP EDI + POP ESI + POP EBP + POP EBX + ADD ESP,0x3B0 + RETN +}} + +FCT_ASM ( caller_printStatsPageBtns_9 ) + CALL printStatsPageBtns + POP EDI + POP ESI + POP EBP + POP EBX + ADD ESP,0x374 + RETN +}} + + + +FCT_ASM ( caller_statsPageMouseDown_111 ) + PUSH DWORD PTR SS:[ESP+0x20] + CALL statsPageMouseDown + TEST EAX,EAX + JE fin_statsPageMouseDown + RETN +fin_statsPageMouseDown: + ADD ESP,4 + POP EDI + POP ESI + POP EBP + POP EBX + RETN 4 +}} + +FCT_ASM ( caller_statsPageMouseDown ) + PUSH DWORD PTR SS:[ESP+0x18] + CALL statsPageMouseDown + TEST EAX,EAX + JE fin_statsPageMouseDown + RETN +fin_statsPageMouseDown: + ADD ESP,4 + POP EDI + POP ESI + POP EBP + POP EBX + RETN 4 +}} + +FCT_ASM ( caller_statsPageMouseUp ) + PUSH EBP + CALL statsPageMouseUp + TEST EAX,EAX + JE fin_statsPageMouseUp + RETN +fin_statsPageMouseUp: + ADD ESP,4 + POP EDI + POP ESI + POP EBP + POP EBX + ADD ESP,8 + RETN 4 +}} + +FCT_ASM ( caller_statsPageMouseUp_9 ) + PUSH EBP + CALL statsPageMouseUp + TEST EAX,EAX + JE fin_statsPageMouseUp + RETN +fin_statsPageMouseUp: + ADD ESP,4 + POP EDI + POP ESI + POP EBP + POP EBX + POP ECX + RETN 4 +}} + + +void Install_InterfaceStats() +{ + static int isInstalled = false; + if (isInstalled) return; + + Install_PlugYImagesFiles(); + + log_msg("Patch D2Client for stats interface. (InterfaceStats)\n"); + + // Print new buttons images + mem_seek R7(D2Client, 2A7BE, 2A7AE, 30F86, 83636, 8A0B6, 6C016, BDC16); + memt_byte( 0x5F, 0xE9 ); // JMP + MEMT_REF4( 0x815B5D5E, version_D2Client >= V111 ? caller_printStatsPageBtns_111: version_D2Client == V110 ? caller_printStatsPageBtns : caller_printStatsPageBtns_9); + //6FAD0F86 . 5F POP EDI + //6FAD0F87 . 5E POP ESI + //6FAD0F88 . 5D POP EBP + //6FAD0F89 . 5B POP EBX + //6FAD0F8A . 81C4 B0030000 ADD ESP,3B0 + //6FAD0F90 . C3 RETN + //6FB33636 . 5F POP EDI + //6FB33637 . 5E POP ESI + //6FB33638 . 5D POP EBP + //6FB33639 . 5B POP EBX + //6FB3363A . 81C4 70030000 ADD ESP,370 + //6FB33640 . C3 RETN + //6FB3A0B6 . 5F POP EDI + //6FB3A0B7 . 5E POP ESI + //6FB3A0B8 . 5D POP EBP + //6FB3A0B9 . 5B POP EBX + //6FB3A0BA . 81C4 70030000 ADD ESP,370 + //6FB3A0C0 . C3 RETN + //6FB1C016 . 5F POP EDI + //6FB1C017 . 5E POP ESI + //6FB1C018 . 5D POP EBP + //6FB1C019 . 5B POP EBX + //6FB1C01A . 81C4 70030000 ADD ESP,370 + //6FB1C020 . C3 RETN + //6FB6DC16 |. 5F POP EDI + //6FB6DC17 |. 5E POP ESI + //6FB6DC18 |. 5D POP EBP + //6FB6DC19 |. 5B POP EBX + //6FB6DC1A |. 81C4 70030000 ADD ESP,370 + //6FB6DC20 \. C3 RETN + + if ( version_D2Client >= V111 ) + { + // Manage mouse down (Play sound) + mem_seek R7(D2Client, 2AA6D, 2AA5D, 3133D, 827C8, 89248, 6B1A8, BCDC8); + memt_byte( 0xA1, 0xE8 ); + MEMT_REF4( ptptClientChar, caller_statsPageMouseDown); + //6FB327C8 . A1 F0C4BC6F MOV EAX,DWORD PTR DS:[6FBCC4F0] + //6FB39248 . A1 E0C1BC6F MOV EAX,DWORD PTR DS:[6FBCC1E0] + //6FB1B1A8 . A1 D0C3BC6F MOV EAX,DWORD PTR DS:[6FBCC3D0] + //6FB6CDC8 . A1 FCBBBC6F MOV EAX,DWORD PTR DS:[6FBCBBFC] + + // Manage mouse up + mem_seek R7(D2Client, 2AC43, 2AC33, 3151A, 83853, 8A2D3, 6C233, BDE33); + memt_byte( 0xA1, 0xE8 ); + MEMT_REF4( ptptClientChar, caller_statsPageMouseUp); + //6FB33853 . A1 F0C4BC6F MOV EAX,DWORD PTR DS:[6FBCC4F0] + //6FB3A2D3 . A1 E0C1BC6F MOV EAX,DWORD PTR DS:[6FBCC1E0] + //6FB1C233 . A1 D0C3BC6F MOV EAX,DWORD PTR DS:[6FBCC3D0] + //6FB6DE33 . A1 FCBBBC6F MOV EAX,DWORD PTR DS:[6FBCBBFC] + } else { + // Manage mouse down (Play sound) + mem_seek R7(D2Client, 2AA6D, 2AA5D, 3133D, 827C8, 89248, 6B1A8, 0000); + MEMC_REF4( D2GetClientPlayer, caller_statsPageMouseDown); + //6FAD133C . E8 8F700500 CALL D2Client.6FB283D0 + + // Manage mouse up + mem_seek R7(D2Client, 2AC43, 2AC33, 3151A, 83853, 8A2D3, 6C233, 0000); + MEMC_REF4( D2GetClientPlayer, version_D2Client == V110 ? caller_statsPageMouseUp : caller_statsPageMouseUp_9);//0x00056EB2 + //6FAD1519 . E8 B26E0500 CALL D2Client.6FB283D0 + } + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/Language.cpp b/PlugY/Language.cpp new file mode 100644 index 0000000..b9c88e7 --- /dev/null +++ b/PlugY/Language.cpp @@ -0,0 +1,57 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Language management. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "language.h" +#include + + +bool active_ChangeLanguage = true; +DWORD selectedLanguage = LNG_ENG; + +bool active_LanguageManagement = false; +DWORD defaultLanguage = LNG_ENG; +t_availableLanguages availableLanguages; + +DWORD* ptCurrentLanguage; + +DWORD STDCALL languageManagement () +{ + if (active_ChangeLanguage) *ptCurrentLanguage = selectedLanguage; + if (active_LanguageManagement) + if ((*ptCurrentLanguage > LNG_RUS) || !((1 << *ptCurrentLanguage) & availableLanguages.all)) + *ptCurrentLanguage = defaultLanguage; + return *ptCurrentLanguage; +} + + +void Install_LanguageManagement() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Lang for language management. (LanguageManagement)\n"); + + ptCurrentLanguage = *(DWORD**)((DWORD)D2GetLang + (version_D2Lang >= V111 ? 0x51: 0x5C)); + + // Language management + mem_seek( (DWORD)D2GetLang + (version_D2Lang >= V111 ? 0x3E : 0x49));//6FC13E39-6FC10000 + memt_byte( 0xA1 , 0xE8); + MEMT_REF4( ptCurrentLanguage, languageManagement); + //6FC13E39 |. A1 EC0CC26F MOV EAX,DWORD PTR DS:[6FC20CEC] + //003D91FE |. A1 1C0A3E00 MOV EAX,DWORD PTR DS:[3E0A1C] + //003DA0AE |. A1 1C0A3E00 MOV EAX,DWORD PTR DS:[3E0A1C] + + log_msg("\n"); + + isInstalled = true; +} + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/LoadPlayerData.cpp b/PlugY/LoadPlayerData.cpp new file mode 100644 index 0000000..5636bec --- /dev/null +++ b/PlugY/LoadPlayerData.cpp @@ -0,0 +1,566 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Load Player Custom Data. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "infinityStash.h" +#include "extendedSaveFile.h" +#include "sharedSaveFile.h" + + +/************************************ LOADING ***********************************/ + +DWORD STDCALL LoadSPCustomData(Unit* ptChar) +{ + DWORD size = 0; + BYTE* data; + + log_msg("--- Start LoadSPCustomData ---\n"); + + if (!ptChar) + {log_msg("LoadSPCustomData : ptChar == NULL\n");return 0x1B;}//Unknow failure + if (ptChar->nUnitType != UNIT_PLAYER) + {log_msg("LoadSPCustomData : ptChar->nUnitType != UNIT_PLAYER\n");return 0x1B;}//Unknow failure + if (!PCPlayerData) + {log_msg("LoadSPCustomData : PCPlayerData == NULL\n");return 0x1B;}//Unknow failure + if (!PCGame) + {log_msg("LoadSPCustomData : PCGame == NULL\n");return 0x1B;}//Unknow failure + + DWORD ret=0; + if (PCGame->isLODGame) + { + log_msg("is LOD Game\n"); + data = readExtendedSaveFile(PCPlayerData->name, &size); + ret = loadExtendedSaveFile(ptChar, data, size); + D2FogMemDeAlloc(data,__FILE__,__LINE__,0); + if (!ret) + { + data = readSharedSaveFile(PCPlayerData->name, &size); + ret = loadSharedSaveFile(ptChar, data, size); + D2FogMemDeAlloc(data,__FILE__,__LINE__,0); + } + } else { + log_msg("is not LOD Game\n"); + } + + log_msg("End LoadSPCustomData.\n\n"); + return ret; +} + + +FCT_ASM (caller_LoadSPPlayerCustomData ) + MOV ESI,EAX + TEST ESI,ESI + JNZ JMP_LoadSPPlayerCustomData + PUSH DWORD PTR SS:[ESP+0x14] + CALL LoadSPCustomData + MOV ESI,EAX + TEST ESI,ESI + JNZ JMP_LoadSPPlayerCustomData + RETN +JMP_LoadSPPlayerCustomData: + ADD DWORD PTR SS:[ESP],0x17 + RETN +}} + + +/* +return value : +0:ok +1:Unable to enter game. Bad character version +2:Unable to enter game. Bad character quest data +3:Unable to enter game. Bad character waypoint data +4:Unable to enter game. Bad character stats data +5:Unable to enter game. Bad character skills data +6:Unable to enter game +7:Unable to enter game. Bad inventory data +8:Unable to enter game. Bad dead bodies +9:Unable to enter game. Bad header +0A:Unable to enter game. bad hireables +0B:Unable to enter game, bad intro data +0C:Unable to enter game. bad item +0D:Unable to enter game, bad dead body item +0E:Unable to enter game, generic bad file +0F:Game is full +10:Version do not match.... +11:Unable to enter game,Your character must kill Baal to play nightmare game +12:Unable to enter game,Your character must kill Baal in nightmare difficulty to play hell game +13:Unable to enter game, a normal character cannot join a game create an harcore character. +14:Unable to enter game, an harcore character cannot join a game create by a normal character. +15:A dead character cannot join or create any game +16:unknow failure +17:Unable to enter game. A D2 Character cannot join an expansion character +18:Expansion cannot join D2 +19:Failures to join game +1A:Unable to enter game +1B:unknow failure +*/ +enum { + TS_SAVE_PERSONAL=0, + TS_SAVE_SHARED, + TS_PUTGOLD, + TS_TAKEGOLD +}; + +#pragma pack(1) +typedef struct { + BYTE packID; + BYTE packSize; + DWORD finalSize:31; + DWORD isCustom:1; + BYTE type; + BYTE data[0xFF]; +} t_rcvMsg; +#pragma pack() + +struct s_MPSaveFile +{ + DWORD clientID; + int sizeExtended; + int curExtended; + BYTE* dataExtended; + int sizeShared; + int curShared; + BYTE* dataShared; + s_MPSaveFile* prev; + s_MPSaveFile* next; + bool completed; +}; + +static BYTE customPackID = 0x6C; +static s_MPSaveFile * receivedSaveFiles = NULL; + +void freeCurrentCF(DWORD memoryPool, s_MPSaveFile** curSF) +{ + if (*curSF == NULL) return; + D2FreeMem(memoryPool, (*curSF)->dataExtended,__FILE__,__LINE__,0); + D2FreeMem(memoryPool, (*curSF)->dataShared,__FILE__,__LINE__,0); + if ((*curSF)->next) + (*curSF)->next->prev = (*curSF)->prev; + if ((*curSF)->prev) + (*curSF)->prev->next = (*curSF)->next; + else + receivedSaveFiles = (*curSF)->next; + D2FreeMem(memoryPool, *curSF,__FILE__,__LINE__,0); + *curSF = NULL; +} + + +void sendData(BYTE* data, DWORD size, bool isShared) +{ + t_rcvMsg pack; +// d2_assert(size >= 0x40000000, "size of file > 0x40000000", __FILE__, __LINE__); + + pack.packID = customPackID; + pack.finalSize = size; + pack.isCustom = true; + pack.type = isShared ? TS_SAVE_SHARED : TS_SAVE_PERSONAL; + + DWORD sended = 0; + while (sended < size) + { + pack.packSize = (BYTE) (size - sended > 0xFE ? 0xFF : size - sended + 1); + CopyMemory(pack.data, &data[sended], pack.packSize); + log_msg("Loading Send Packet: \ttype=%X\t finalSize=%X\t packSize=%02X\t data=%08X\n", pack.type, pack.finalSize, pack.packSize, pack.data); + D2SendToServer(pack.packSize+7, 0, &pack); + sended += pack.packSize -1; + } + log_msg("\n"); +} + +static DWORD sizeExtended; +static BYTE* dataExtended; +static DWORD sizeShared; +static BYTE* dataShared; + +void FASTCALL SendSaveFiles (char* ptPath, DWORD maxsize, char* name) +{ +// DWORD size; +// BYTE* data; + + D2FogGetSavePath(ptPath,maxsize); + + log_msg("\n--- Start SendSaveFiles ---\n"); + + // Send Extended Save File + log_msg("Send Extended Save File\n"); + dataExtended = readExtendedSaveFile(name, &sizeExtended); + sendData(dataExtended, sizeExtended, false); + D2FogMemDeAlloc(dataExtended,__FILE__,__LINE__,0); + + // Send Shared Save File + log_msg("Send Shared Save File\n"); + dataShared = readSharedSaveFile(name, &sizeShared); + sendData(dataShared, sizeShared, true); + D2FogMemDeAlloc(dataShared,__FILE__,__LINE__,0); + + // Ending load + log_msg("End SendSaveFiles.\n\n"); +} + + + +DWORD STDCALL ReceiveSaveFiles (DWORD clientID, t_rcvMsg* msg) +{ + if( (msg->packID != customPackID) || !msg->isCustom) return msg->packID; + + log_msg("Loading Receive Packet: clientID=%d\t type=%X\t finalSize=%X\t packSize=%02X\t data=%08X\n", clientID, msg->type, msg->finalSize, msg->packSize, msg->data); + + bool isShared; + + switch (msg->type) + { + case TS_SAVE_PERSONAL : isShared = false;break; + case TS_SAVE_SHARED : isShared = true;break; +// case TS_PUTGOLD : putGold(ptChar, (DWORD)msg->data); return 0; +// case TS_TAKEGOLD : takeGold(ptChar, (DWORD)msg->data); return 0; + default: return 0;//return msg->packID; + } + + NetClient* ptClient = ptClientTable[clientID & 0xFF]; + + s_MPSaveFile* curSF = receivedSaveFiles; + while (curSF && (clientID != curSF->clientID) ) + curSF = curSF->next; + + if (curSF && curSF->completed) + freeCurrentCF(0 * PClientGame->memoryPool, &curSF); + + + if (!curSF) + { + curSF = (s_MPSaveFile *)D2AllocMem(0 * PClientGame->memoryPool, sizeof(s_MPSaveFile),__FILE__,__LINE__,0); + ZeroMemory(curSF, sizeof(s_MPSaveFile)); + curSF->clientID = clientID; + curSF->next = receivedSaveFiles; + if (receivedSaveFiles) receivedSaveFiles->prev = curSF; + receivedSaveFiles = curSF; + } + + log_msg("curSF = %08X\tcurSF->completed = %d\n", curSF, curSF->completed); + + + DWORD size = msg->packSize - 1; + if (isShared) + { + if (curSF->sizeShared == 0) + curSF->sizeShared = msg->finalSize; + d2_assert(curSF->sizeShared != msg->finalSize, "Size of shared file has change", __FILE__, __LINE__); + + if (!curSF->dataShared) + curSF->dataShared = (BYTE *)D2AllocMem(0 * PClientGame->memoryPool, curSF->sizeShared,__FILE__,__LINE__,0);// d2_assert(!curSF->dataShared, "Can't malloc data", __FILE__, __LINE__); + + CopyMemory(&curSF->dataShared[curSF->curShared], msg->data, size); + curSF->curShared += size; + + } else { + + if (curSF->sizeExtended == 0) + curSF->sizeExtended = msg->finalSize; + d2_assert(curSF->sizeExtended != msg->finalSize, "Size of extented file has change", __FILE__, __LINE__); + + if (!curSF->dataExtended) + curSF->dataExtended = (BYTE *)D2AllocMem( 0 * PClientGame->memoryPool, curSF->sizeExtended,__FILE__,__LINE__,0);// d2_assert(!curSF->dataExtended, "Can't malloc data", __FILE__, __LINE__); + + CopyMemory(&curSF->dataExtended[curSF->curExtended], msg->data, size); + curSF->curExtended += size; + } + + if( curSF->sizeExtended && (curSF->sizeExtended == curSF->curExtended) && curSF->sizeShared && (curSF->sizeShared == curSF->curShared) ) + { + curSF->completed = true; + log_msg("ReceiveSaveFiles completed.\n"); + } + log_msg("End Load Receive Packet\n"); + + return msg->packID+10; +} + +/* +typedef int (STDCALL * t_fct_recv)(SOCKET s, char *buf, int len, int flags); +t_fct_recv fct_recv; +int STDCALL ReceiveSaveFiles_9(DWORD clientID, SOCKET s, char *buf, int len, int flags) +{ + t_rcvMsg* msg = (t_rcvMsg*) buf; + int nb = fct_recv(s,buf,len,flags); + if ((nb<6) || (msg->packID != customPackID) || !msg->isCustom || (msg->packSize+7 != nb)) + return nb; + ReceiveSaveFiles(clientID,msg); + msg->packSize = 1; + return 7; +}*/ + +DWORD STDCALL LoadMPCustomData(Unit* ptChar) +{ + log_msg("Start LoadMPCustomData\n"); + + if (!ptChar) return NULL; + if (!ptChar) + {log_msg("LoadMPCustomData : ptChar == NULL\n");return 0x1B;}//Unknow failure + if (ptChar->nUnitType != UNIT_PLAYER) + {log_msg("LoadMPCustomData : ptChar->nUnitType != UNIT_PLAYER\n");return 0x1B;}//Unknow failure + if (!PCPlayerData) + {log_msg("LoadMPCustomData : PCPlayerData == NULL\n");return 0x1B;}//Unknow failure + + NetClient* ptClient = D2GetClient(ptChar,__FILE__,__LINE__); + + s_MPSaveFile* curSF = receivedSaveFiles; + while (curSF && (ptClient->clientID != curSF->clientID) ) + curSF = curSF->next; + + DWORD ret=0; + + if (!curSF) + { + log_msg("Server has received no data from extra save files of character %s\n", PCPlayerData->name); + ret = 0xE;//Unable to enter game, generic bad file + } + + if (!ret && !curSF->completed) + { + log_msg("Server hasn't receive all data from extra save files of character %s\n",PCPlayerData->name); + ret = 0xE;//Unable to enter game, generic bad file + } + + if (!ret && !PCGame) + { + log_msg("LoadMPCustomData : PCGame == NULL\n"); + ret = 0x1B;//Unknow failure + } + + if (PCGame->isLODGame) + { + log_msg("is LOD Game\n"); + if (!ret) + ret = loadExtendedSaveFile(ptChar, curSF->dataExtended, curSF->sizeExtended); + if (!ret) + ret = loadSharedSaveFile(ptChar, curSF->dataShared, curSF->sizeShared); + } else { + log_msg("is not LOD Game\n"); + } + + freeCurrentCF(PCGame->memoryPool, &curSF); + + log_msg("--- End LoadMPCustomData. ---\n\n"); + + return ret; +} + + + +FCT_ASM ( caller_LoadMPPlayerCustomData_111 ) + PUSH DWORD PTR SS:[EBX] + CALL LoadMPCustomData + TEST EAX,EAX + JNZ JMP_LoadMPlayerCustomData + CMP DWORD PTR DS:[EBX],0 + JNZ Continue_LoadMP + ADD DWORD PTR SS:[ESP],0x21 +Continue_LoadMP: + RETN +JMP_LoadMPlayerCustomData: + SUB DWORD PTR SS:[ESP],0x12 + RETN +}} + + +FCT_ASM ( caller_LoadMPPlayerCustomData ) + PUSH DWORD PTR SS:[EDI] + CALL LoadMPCustomData + TEST EAX,EAX + JNZ JMP_LoadMPlayerCustomData + CMP DWORD PTR DS:[EDI],0 + JNZ Continue_LoadMP + ADD DWORD PTR SS:[ESP],0x46 +Continue_LoadMP: + RETN +JMP_LoadMPlayerCustomData: + SUB DWORD PTR SS:[ESP],0xD + RETN +}} + +FCT_ASM ( caller_LoadMPPlayerCustomData_9 ) + PUSH DWORD PTR SS:[EDI] + CALL LoadMPCustomData + TEST EAX,EAX + JNZ JMP_LoadMPlayerCustomData + CMP DWORD PTR DS:[EDI],0 + JNZ Continue_LoadMP + ADD DWORD PTR SS:[ESP],0x1D +Continue_LoadMP: + RETN +JMP_LoadMPlayerCustomData: + SUB DWORD PTR SS:[ESP],0x13 + RETN +}} + + +FCT_ASM ( caller_SendSaveFiles_111 ) + POP EAX + PUSH DWORD PTR CS:[EAX+0x01] //"name" + PUSH EAX + JMP SendSaveFiles +}} + +FCT_ASM ( caller_SendSaveFiles ) + POP EAX + PUSH DWORD PTR CS:[EAX+0x0F] //"name" + PUSH EAX + JMP SendSaveFiles +}} + + + +FCT_ASM ( caller_ReceiveSaveFiles_111 ) + PUSH ECX + PUSH EDX + LEA EBX,DWORD PTR DS:[EBP+4] + PUSH EBX //Message + MOV EBX,DWORD PTR SS:[EBP] + PUSH EBX //ID client + CALL ReceiveSaveFiles + POP EDX + POP ECX + RETN +}} + + +FCT_ASM ( caller_ReceiveSaveFiles ) + PUSH ECX + PUSH EDX + LEA EDI,DWORD PTR DS:[ESI+4] + PUSH EDI //Message + MOV EDI,DWORD PTR DS:[ESI] + PUSH EDI //ID client + CALL ReceiveSaveFiles + POP EDX + POP ECX + RETN +}} + + +FCT_ASM ( caller_BugFix109b ) + MOV EAX,DWORD PTR DS:[EDI+0xBD0] + TEST EAX,EAX + JE go_to_default + MOV EAX,DWORD PTR SS:[ESP+0x20] + MOV DWORD PTR SS:[ESP+0x24],EAX + RETN +go_to_default: + SUB DWORD PTR SS:[ESP],0x4B + RETN +}} + +FCT_ASM ( caller_BugFix109d ) + MOV EAX,DWORD PTR DS:[ESI+0xAB0] + TEST EAX,EAX + JE go_to_default + MOV EAX,DWORD PTR SS:[ESP+0x20] + MOV DWORD PTR SS:[ESP+0x24],EAX + RETN +go_to_default: + SUB DWORD PTR SS:[ESP],0x4B + RETN +}} + +void Install_LoadPlayerData() +{ + static int isInstalled = false; + if (isInstalled || !active_PlayerCustomData) return; + + log_msg("Patch D2Game & D2Client for load Player's custom data. (LoadPlayerData)\n"); + + // Load SP player custom data. + mem_seek R7(D2Game, 5046F, 5086F, 5CB0F, BB8ED, 278CD, 465BD, 5638D); + memt_byte( 0x8B, 0xE8); // CALL caller_LoadSPPlayerCustomData + MEMT_REF4( 0x75F685F0 , caller_LoadSPPlayerCustomData); + memt_byte( 0x16, 0x90); // NOP + //6FC8CB0F 8BF0 MOV ESI,EAX + //6FC8CB11 85F6 TEST ESI,ESI + //6FC8CB13 75 16 JNZ SHORT D2Game.6FC8CB2B + //0203B8ED |> 8BF0 MOV ESI,EAX + //0203B8EF |. 85F6 TEST ESI,ESI + //0203B8F1 |. 75 16 JNZ SHORT D2Game.0203B909 + //01F978CD |> 8BF0 MOV ESI,EAX + //01F978CF |. 85F6 TEST ESI,ESI + //01F978D1 |. 75 16 JNZ SHORT D2Game.01F978E9 + //6FC665BD |> 8BF0 MOV ESI,EAX + //6FC665BF |. 85F6 TEST ESI,ESI + //6FC665C1 |. 75 16 JNZ SHORT D2Game.6FC665D9 + //6FC7638D |> 8BF0 MOV ESI,EAX + //6FC7638F |. 85F6 TEST ESI,ESI + //6FC76391 |. 75 16 JNZ SHORT D2Game.6FC763A9 + + // Load MP player custom data. + mem_seek R7(D2Game, 50790, 50B90, 5CC66, BB777, 27757, 46447, 56217); + memt_byte( 0x83, 0xE8); + MEMT_REF4( version_D2Game >= V111 ? 0x2174003B : version_D2Game == V110 ? 0x4674003F : 0x1D74003F, version_D2Game >= V111 ? caller_LoadMPPlayerCustomData_111 : version_D2Game == V110 ? caller_LoadMPPlayerCustomData: caller_LoadMPPlayerCustomData_9); + //6FC8CC66 . 833F 00 CMP DWORD PTR DS:[EDI],0 + //6FC8CC69 . 74 46 JE SHORT D2Game.6FC8CCB1 + //0203B777 |> 833B 00 CMP DWORD PTR DS:[EBX],0 + //0203B77A |. 74 21 JE SHORT D2Game.0203B79D + //01F97757 |> 833B 00 CMP DWORD PTR DS:[EBX],0 + //01F9775A |. 74 21 JE SHORT D2Game.01F9777D + //6FC66447 |> 833B 00 CMP DWORD PTR DS:[EBX],0 + //6FC6644A |. 74 21 JE SHORT D2Game.6FC6646D + //6FC76217 |> 833B 00 CMP DWORD PTR DS:[EBX],0 + //6FC7621A |. 74 21 JE SHORT D2Game.6FC7623D + + // Send save files to Server. + mem_seek R7(D2Client, CF42, CF32, D5A2, 733FC, 5DFDC, 7933C, 1457C); + MEMJ_REF4( D2FogGetSavePath, version_D2Game >= V111 ? caller_SendSaveFiles_111 : caller_SendSaveFiles); + //6FAAD5A1 |. E8 88D10B00 CALL + //6FB233FB |. E8 CA8AF9FF CALL + //6FB0DFDB |. E8 C6DEFAFF CALL + //6FB2933B |. E8 6A2CF9FF CALL + //6FAC457B |. E8 187AFFFF CALL + + // Receive save files from client. + mem_seek R7(D2Game, 183A, 183A, 191A, 376E9, 703D9, 624D9, CAF39); + memt_byte( 0x8B ,0xE8); + if ( version_D2Game >= V111 ) { + MEMT_REF4( 0xB60F005D, caller_ReceiveSaveFiles_111); + memt_byte( 0x45 ,0x90); + memt_byte( 0x04 ,0x90); + //01FB76E9 |. 8B5D 00 MOV EBX,DWORD PTR SS:[EBP] + //01FB76EC |. 0FB645 04 MOVZX EAX,BYTE PTR SS:[EBP+4] + //01FE03D9 |. 8B5D 00 MOV EBX,DWORD PTR SS:[EBP] + //01FE03DC |. 0FB645 04 MOVZX EAX,BYTE PTR SS:[EBP+4] + //6FC824D9 |. 8B5D 00 MOV EBX,DWORD PTR SS:[EBP] + //6FC824DC |. 0FB645 04 MOVZX EAX,BYTE PTR SS:[EBP+4] + //6FCEAF39 |. 8B5D 00 MOV EBX,DWORD PTR SS:[EBP] + //6FCEAF3C |. 0FB645 04 MOVZX EAX,BYTE PTR SS:[EBP+4] + } else { + MEMT_REF4( 0x04468A3E, caller_ReceiveSaveFiles); + //6FC3191A |. 8B3E MOV EDI,DWORD PTR DS:[ESI] + //6FC3191C |. 8A46 04 MOV AL,BYTE PTR DS:[ESI+4] + } + + if ( version_Fog <= V109d ) + { + mem_seek R7(Fog, 47DE, 45AE, 0000, 0000, 0000, 0000, 0000); + memt_byte( 0x8B ,0xE8); + MEMT_REF4( 0x891C2444, version_Fog == V109b? caller_BugFix109b : caller_BugFix109d); + memt_byte( 0x44 ,0x90); + memt_byte( 0x24 ,0x90); + memt_byte( 0x20 ,0x90); + //6FF545AE |> 8B4424 1C |MOV EAX,DWORD PTR SS:[ESP+1C] ; Case 2 of switch 6FF5454C + //6FF545B2 |. 894424 20 |MOV DWORD PTR SS:[ESP+20],EAX + } + + if ( version_D2Game == V109b || version_D2Game == V109d ) + customPackID -= 3; + else if ( version_D2Game == V110 ) + customPackID --; + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/MainScreen.cpp b/PlugY/MainScreen.cpp new file mode 100644 index 0000000..b024f23 --- /dev/null +++ b/PlugY/MainScreen.cpp @@ -0,0 +1,123 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Add "plugY v1.00" on screen. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include + +char* versionText = ""; +bool active_VersionTextChange = 0; +BYTE modVersionColor = 0; +bool active_PrintPlugYVersion = 1; +BYTE colorOfPlugYVersion = 4; + +DWORD newTextBoxData[]={4,0x237,0x243,0xC8,0x14,0,0,0,0,0,0,2};//type,x,y,l,h,?,?,?,?,?,?,?(0,257,C8,28) + +void STDCALL printPlugYVersion(void** childrens, DWORD* sgnNumChildren) +{ + char buf[20]; + void* textbox = D2CreateTextBox(newTextBoxData); + childrens[*sgnNumChildren]=textbox; + d2_assert((*sgnNumChildren)++ >= 40,"sgnNumChildren < MAX_CHILDREN", __FILE__, __LINE__); + sprintf(buf, "PlugY %s", PLUGY_VERSION); + D2PrintLineOnTextBox(textbox, buf, colorOfPlugYVersion); +} + +FCT_ASM ( caller_printPlugYVersion ) + POP ESI + PUSH DWORD PTR [ESI+2] + PUSH DWORD PTR [ESI+9] + CALL printPlugYVersion + CALL D2CreateTextBox + JMP ESI +}} + + +void Install_PrintPlugYVersion() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Launch to print PlugY version. (PrintPlugYVersion)\n"); + + // Print PlugY version. + mem_seek R7(D2Launch, 7F5D, 7F7D, 9639, 117C7, 178A7, 16AF7, 18061); + MEMJ_REF4( D2CreateTextBox, caller_printPlugYVersion); + //6FA19638 |. E8 1BED0000 CALL + //6FA517C6 |. E8 6F81FFFF CALL + //6FA578A6 |. E8 D71FFFFF CALL + //6FA56B1F |. E8 1A2EFFFF CALL + //6FA56AF6 |. E8 432EFFFF CALL + //6FA58060 |. E8 ED18FFFF CALL + + + log_msg("\n"); + + isInstalled = true; +} + +/*************************************************************************************/ + +void FASTCALL versionChange(void* screen, char* text, DWORD color) +{ + D2PrintLineOnTextBox(screen,versionText,modVersionColor); +} + +FCT_ASM ( caller_VersionChange_10 ) + MOV CL, BYTE PTR DS:[modVersionColor] + MOV BYTE PTR SS:[ESP+4], CL + MOV EDX,versionText + MOV ECX,EDI + RETN +}} + +void Install_VersionChange()// BUG WITH 2MOD if D2Mod started before PlugY ???? +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Launch to print Mod version. (VersionChange)\n"); + +//6FA18012 |. 8D5424 0C LEA EDX,DWORD PTR SS:[ESP+C] +//6FA18016 |. 8BCE MOV ECX,ESI +//6FA18018 |. 6A 00 PUSH 0 + + + // Print LoD/Mod version. + if (version_D2Launch >= V110) + { + mem_seek R7(D2Launch, 00000, 00000, 9723, 1189B, 1797B, 16BCB, 18134);//6FA19721-6FA10000 + memt_byte( 0x8D, 0xE8 ); // CALL + MEMT_REF4( 0x8B102454 , caller_VersionChange_10); + memt_byte( 0xCF, 0x90 ); // NOP + //6FA19723 |. 8D5424 10 LEA EDX,DWORD PTR SS:[ESP+10] + //6FA19727 |. 8BCF MOV ECX,EDI + //6FA5189B |. 8D5424 10 LEA EDX,DWORD PTR SS:[ESP+10] + //6FA5189F |. 8BCF MOV ECX,EDI + //6FA5797B |. 8D5424 10 LEA EDX,DWORD PTR SS:[ESP+10] + //6FA5797F |. 8BCF MOV ECX,EDI + //6FA56BCB |. 8D5424 10 LEA EDX,DWORD PTR SS:[ESP+10] + //6FA56BCF |. 8BCF MOV ECX,EDI + //6FA58134 |. 8D5424 10 LEA EDX,DWORD PTR SS:[ESP+10] + //6FA58138 |. 8BCF MOV ECX,EDI + } else { + mem_seek R7(D2Launch, 801B, 803B, 972A, 118A2, 17982, 16BD2, 1813B); + MEMJ_REF4( D2PrintLineOnTextBox, versionChange); + //6FA19729 |. E8 88EB0000 CALL + //6FA518A1 |. E8 267FFFFF CALL + //6FA57981 |. E8 781EFFFF CALL + //6FA56BD1 |. E8 EA2CFFFF CALL + //6FA5813A |. E8 8F17FFFF CALL + } + log_msg("\n"); + + isInstalled = true; +} + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/ModifMemory.cpp b/PlugY/ModifMemory.cpp new file mode 100644 index 0000000..6f75684 --- /dev/null +++ b/PlugY/ModifMemory.cpp @@ -0,0 +1,234 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Modification of code in memory functions. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "modifMemory.h" +#include "d2functions.h" + +const char* MSG_ERROR_READ_MEMORY = "Error : Read access missing to patch memory at %08X.\nPlease install a clean version of Lord of Destruction\n\n" + "You can avoid this error message by setting ActiveCkeckMemory=0 in PlugY.ini\n(WARNING: Be careful when you use it, it shouldn't be used by common user)"; +const char* MSG_CRITICAL_WRITE_MEMORY = "Error.\nWrite access missing to patch memory at %08X.\n\nPlease install a clean version of Lord of Destruction\n"; +const char* ERROR_TESTING1 = "Error : BYTE %02X wanted but %02X found to change memory at %08X\n\n"; +const char* ERROR_TESTING4 = "Error : DWORD %08X wanted but %08X found to change memory at %08X\n\n"; + + +void* currentMemoryPos = 0; + +DWORD mem_seek(DWORD newPos) +{ + currentMemoryPos = (void*)newPos; + return (DWORD)currentMemoryPos; +} + +void patchMemory1(BYTE value) +{ + if (IsBadWritePtr(currentMemoryPos,1)) + { + log_box(MSG_CRITICAL_WRITE_MEMORY, currentMemoryPos); + exit(1); + } + *(BYTE*)currentMemoryPos = value; + currentMemoryPos = (LPVOID)((DWORD)currentMemoryPos + 1); +} + +void patchMemory4(DWORD value) +{ + if (IsBadWritePtr(currentMemoryPos,4)) + { + log_box(MSG_CRITICAL_WRITE_MEMORY, currentMemoryPos); + exit(1); + } + *(DWORD*)currentMemoryPos = value; + currentMemoryPos = (LPVOID)((DWORD)currentMemoryPos + 4); +} + +BYTE getMemory1(LPVOID mempos) +{ + if (IsBadReadPtr(mempos,1)) + { + log_box(MSG_ERROR_READ_MEMORY, currentMemoryPos); + exit(1); + } + return *(BYTE*)mempos; +} + +DWORD getMemory4(LPVOID mempos) +{ + if (IsBadReadPtr(mempos,4)) + { + log_box(MSG_ERROR_READ_MEMORY, currentMemoryPos); + exit(1); + } + return *(DWORD*)mempos; +} + + +void memt_byte(BYTE old, BYTE val) +{ + BYTE current = getMemory1(currentMemoryPos); + if ( current == val) + { + log_msg("Warning : BYTE %02X is already set at memory %08X\n", val, currentMemoryPos); + currentMemoryPos = (LPVOID)((DWORD)currentMemoryPos + 1); + return; + } + if ( old != current) + { + if (active_CheckMemory) + { + log_box(ERROR_TESTING1, old, current, currentMemoryPos); + exit(1); + } else log_msg(ERROR_TESTING1, old, current, currentMemoryPos); + } + log_msg("BYTE\t%08X : %02X->%02X\n", currentMemoryPos, old, val); + patchMemory1(val); +} + +bool testIfAlreadySet(DWORD current, DWORD wanted) +{ + if (current == wanted) + { + log_msg("Warning : DWORD %08X is already set at memory %08X\n", wanted, currentMemoryPos); + currentMemoryPos = (LPVOID)((DWORD)currentMemoryPos + 4); + return true; + } + return false; +} + +void testMemory4(DWORD old, DWORD found) +{ + if (old != found) + if (active_CheckMemory) + { + log_box(ERROR_TESTING4, old, found, currentMemoryPos); + exit(1); + } else log_msg(ERROR_TESTING4, old, found, currentMemoryPos); +} + +void memt_dword(DWORD old, DWORD val) +{ + DWORD current = getMemory4(currentMemoryPos); + DWORD wanted = val; + if (testIfAlreadySet(current, wanted)) return; + testMemory4(old, current); + log_msg("DWORD\t%08X : %08X->%08X\n", currentMemoryPos, old, wanted); + patchMemory4(wanted); +} + + +void memt_ref4(DWORD old, DWORD ref) +{ + DWORD current = getMemory4(currentMemoryPos); + DWORD wanted = ref-(DWORD)currentMemoryPos-4; + if (testIfAlreadySet(current, wanted)) return; + testMemory4(old, current); + log_msg("DWORD\t%08X : %08X->%08X\n", currentMemoryPos, old, wanted); + patchMemory4(wanted); +} + +void memc_ref4(DWORD old, DWORD ref) +{ + DWORD current = getMemory4(currentMemoryPos); + DWORD wanted = ref-(DWORD)currentMemoryPos-4; + if (testIfAlreadySet(current, wanted)) return; + testMemory4(old, current + (DWORD)currentMemoryPos + 4); + log_msg("DWORD\t%08X : %08X->%08X\n", currentMemoryPos, old, wanted); + patchMemory4(wanted); +} + +void memj_ref4(DWORD old, DWORD ref) +{ + DWORD current = getMemory4(currentMemoryPos); + DWORD wanted = ref-(DWORD)currentMemoryPos-4; + if (testIfAlreadySet(current, wanted)) return; + testMemory4(old, getMemory4((LPVOID)getMemory4((LPVOID)(current + (DWORD)currentMemoryPos + 6)))); + log_msg("DWORD\t%08X : %08X->%08X\n", currentMemoryPos, old, wanted); + patchMemory4(wanted); +} + + +void memd_ref4(DWORD old, DWORD ref) +{ + DWORD current = getMemory4(currentMemoryPos); + DWORD wanted = ref-(DWORD)currentMemoryPos-4; + if (testIfAlreadySet(current, wanted)) return; + testMemory4(old, getMemory4((LPVOID)current)); + log_msg("DWORD\t%08X : %08X->%08X\n", currentMemoryPos, old, wanted); + patchMemory4(wanted); +} + +/* + +void mem_byte(BYTE val) +{ + if ( *(BYTE*)currentMemoryPos == val) + { + log_msg("Warning : BYTE at %08X is already set to %02X\n", currentMemoryPos, val); + currentMemoryPos += 1; + return; + } + log_msg("BYTE\t%08X : %02X\n", currentMemoryPos, val); + *(BYTE*)currentMemoryPos = val; + currentMemoryPos += 1; +} + +void mem_word(WORD val) +{ + if ( *(WORD*)currentMemoryPos == val) + { + log_msg("Warning : WORD at %08X is already set to %04X\n", currentMemoryPos, val); + currentMemoryPos += 2; + return; + } + log_msg("WORD\t%08X : %04X\n", currentMemoryPos, val); + *(WORD*)currentMemoryPos = val; + currentMemoryPos += 2; +} + +void memt_word(WORD old, WORD val) +{ + if ( *(WORD*)currentMemoryPos == val) + { + log_msg("Warning : WORD at %08X is already set to %04X (normal:%04X)\n", currentMemoryPos, val, old); + currentMemoryPos += 2; + return; + } + if ( *(WORD*)currentMemoryPos != old) + { + log_msg("WORD %04X found, want %04X at %08X\n", *(WORD*)currentMemoryPos, old, currentMemoryPos); + if (active_CheckMemory) + { + log_box(MSG_ERROR_MEMORY); + exit(1); + } + } + log_msg("WORD\t%08X : %04X->%04X\n", currentMemoryPos, old, val); + *(WORD*)currentMemoryPos = val; + currentMemoryPos += 2; +} + +void mem_dword(DWORD val) +{ + if ( *(DWORD*)currentMemoryPos == val) + { + log_msg("Warning : DWORD at %08X is already set to %08X\n", currentMemoryPos, val); + currentMemoryPos += 4; + return; + } + log_msg("DWORD\t%08X : %08X\n", currentMemoryPos, val); + *(DWORD*)currentMemoryPos = val; + currentMemoryPos += 4; +} +void mem_ref4(DWORD ref) +{ + log_msg("DWORD\t%08X : %08X\n", currentMemoryPos, ref-(DWORD)currentMemoryPos-4); + *(DWORD*)currentMemoryPos = ref-(DWORD)currentMemoryPos-4; + currentMemoryPos += 4; +} +*/ +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/NewInterface_CubeListing.cpp b/PlugY/NewInterface_CubeListing.cpp new file mode 100644 index 0000000..745ab9c --- /dev/null +++ b/PlugY/NewInterface_CubeListing.cpp @@ -0,0 +1,306 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Cube Listing functions + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "updateClient.h" +#include +#include // _getcwd() + + +const char* CUBEFORMULA_FILE = "cube.txt"; +const char * STRING_ERROR="***Error***"; + + +#define BUF (&buf[strlen(buf)]) + + +/* +6FC9275F |. E8 ECCCFFFF |CALL D2Game.6FC8F450 ; \D2Game.6FC8F450 + + +*/ +void printOutput(CubeOutput* output, char* buf, BYTE* nbOutputs) +{ + if (!output->outputType) + return; + if (*nbOutputs) + sprintf(BUF," + "); + *nbOutputs += 1; + + if (output->outputType == 1) { + sprintf(BUF,"Cow Portal"); + return; + } else if (output->outputType == 2) { + sprintf(BUF,"Pandemonium Portal"); + return; + } else if (output->outputType == 3) { + sprintf(BUF,"Pandemonium Final Portal"); + return; + } + + if ((output->quantityOrNbSockets>1) && !output->haveSockets) + sprintf(BUF,"%u ", output->quantityOrNbSockets); + + if (output->repair) + sprintf(BUF,"repair "); + + if (output->recharge) + sprintf(BUF,"recharge "); + + if (output->isEthereal) + sprintf(BUF,"ethereal "); + + if (output->destroysFillers) + sprintf(BUF,"destroys Fillers "); + + if (output->removeFillers) + sprintf(BUF,"remove Fillers "); + + if (output->regeneratesUnique) + sprintf(BUF,"regenerate "); + + if (output->upgradeToExceptional) + sprintf(BUF,"exceptional "); + + if (output->upgradeToElite) + sprintf(BUF,"elite "); + + + if (output->isSpecificItem) { + if (output->quality == ITEMQUALITY_UNIQUE) + { + UniqueItemsBIN* uniqueItems = SgptDataTables->uniqueItems + output->specificID-1; + LPWSTR string = D2GetStringFromIndex(uniqueItems->uniqueNameId); + wcstombs(BUF, string, wcslen(string)+1); + } else if (output->quality == ITEMQUALITY_SET) { + SetItemsBIN* setItems = SgptDataTables->setItems + output->specificID-1; + LPWSTR string = D2GetStringFromIndex(setItems->setNameId); + wcstombs(BUF, string, wcslen(string)+1); + } else { + sprintf(BUF,STRING_ERROR);return; + } + } else { + switch (output->quality) + { + case 1:sprintf(BUF,"Cracked ");break; + case 2:sprintf(BUF,"Normal ");break; + case 3:sprintf(BUF,"Superior ");break; + case 4:sprintf(BUF,"Magic ");break; + case 5:sprintf(BUF,"Set ");break; + case 6:sprintf(BUF,"Rare ");break; + case 7:sprintf(BUF,"Unique ");break; + case 8:sprintf(BUF,"Crafted ");break; + case 9:sprintf(BUF,"Tempered ");break; + } + ItemsBIN* items;LPWSTR string; + switch (output->outputType) + { + case 0xFC: + items = D2GetItemsBIN(output->ID); + string = D2GetStringFromIndex(items->NameStr); + wcstombs(BUF, string, wcslen(string)+1); + break; + case 0xFD: + getTypeAString(output->ID,BUF,50); +// WCHAR string[50]; +// getTypeString(input->ID,string,50); +// wcstombs(BUF, string, wcslen(string)+1); + break; + case 0xFE: sprintf(BUF,"Item");break; + case 0xFF: sprintf(BUF,"Item of the same type");break; + default: sprintf(BUF,STRING_ERROR);return; + } + } + if ((output->quantityOrNbSockets>1) && (output->haveSockets==1)) + sprintf(BUF," with %u sockets", output->quantityOrNbSockets); +} + + +void printInput(CubeInput* input, char* buf, BYTE* nbInputs)//maxsize) +{ + if (!input->byItemID && !input->byItemTypeID) + return; + if (*nbInputs) + sprintf(BUF," + "); + + BYTE nb = input->quantity > 0 ? input->quantity : 1; + *nbInputs += nb; + if (nb>1) + sprintf(BUF,"%u ", nb); + + if (input->isEthereal) + sprintf(BUF,"ethereal "); + + if (input->isNotEthereal) + sprintf(BUF,"not ethereal "); + + if (input->isNotRuneword) + sprintf(BUF,"not runeword "); + + if (input->isBasic) + sprintf(BUF,"basic "); + + if (input->isExceptional) + sprintf(BUF,"exceptional "); + + if (input->isElite) + sprintf(BUF,"elite "); + + if (input->isSpecificItem) { + if (input->quality == ITEMQUALITY_UNIQUE) + { + UniqueItemsBIN* uniqueItems = SgptDataTables->uniqueItems + input->specificID-1; + LPWSTR string = D2GetStringFromIndex(uniqueItems->uniqueNameId); + wcstombs(BUF, string, wcslen(string)+1); + } else if (input->quality == ITEMQUALITY_SET) { + SetItemsBIN* setItems = SgptDataTables->setItems + input->specificID-1; + LPWSTR string = D2GetStringFromIndex(setItems->setNameId); + wcstombs(BUF, string, wcslen(string)+1); + } else { + sprintf(BUF,STRING_ERROR);return; + } + } else { + switch (input->quality) + { + case 1:sprintf(BUF,"Cracked ");break; + case 2:sprintf(BUF,"Normal ");break; + case 3:sprintf(BUF,"Superior ");break; + case 4:sprintf(BUF,"Magic ");break; + case 5:sprintf(BUF,"Set ");break; + case 6:sprintf(BUF,"Rare ");break; + case 7:sprintf(BUF,"Unique ");break; + case 8:sprintf(BUF,"Crafted ");break; + case 9:sprintf(BUF,"Tempered ");break; + } + if (input->byItemTypeID) { + getTypeAString(input->ID,BUF,50); + } else if (input->ID == 0xFFFF) { + sprintf(BUF,"Item"); + } else { + ItemsBIN* items = D2GetItemsBIN(input->ID); + LPWSTR string = D2GetStringFromIndex(items->NameStr); + wcstombs(BUF, string, wcslen(string)+1); + } + } + if (input->includeUpgradedVersions && !input->isElite) + sprintf(BUF,"(or upgraded) "); + + if (input->haveNoSocket) + sprintf(BUF," with no socket"); + + if (input->haveSockets) + sprintf(BUF," with sockets"); +} + +DWORD print(CubeMainBIN* curForm, char* buf, DWORD)//maxsize) +{ + if (!buf || !curForm || !curForm->enabled) return 0; + + BYTE realNbInputs=0; + printInput(&curForm->input1, buf, &realNbInputs); + printInput(&curForm->input2, buf, &realNbInputs); + printInput(&curForm->input3, buf, &realNbInputs); + printInput(&curForm->input4, buf, &realNbInputs); + printInput(&curForm->input5, buf, &realNbInputs); + printInput(&curForm->input6, buf, &realNbInputs); + printInput(&curForm->input7, buf, &realNbInputs); + + + if (realNbInputs != curForm->numinputs) + { + sprintf(BUF," *** ERROR : numInputs(%d) != realNbInputs(%d) ***", curForm->numinputs, realNbInputs); + return 1; + } + + sprintf(BUF," => "); + BYTE realNbOutputs=0; + printOutput(&curForm->output1, buf, &realNbOutputs); + printOutput(&curForm->output2, buf, &realNbOutputs); + printOutput(&curForm->output3, buf, &realNbOutputs); + + +// if (curForm->ladder) +// sprintf(BUF," [ladder only]"); + + if (curForm->minDiff == 1) + sprintf(BUF," [Nightmare and Hell only]"); + else if (curForm->minDiff == 2) + sprintf(BUF," [Hell only]"); + + if (curForm->playerClass != 0xFF) + { + CharStatsBIN* charStats = D2GetCharStatsBIN(curForm->playerClass); + sprintf(BUF, " [%s only]", charStats->name); + } + + if ((curForm->op>0) && (curForm->op!=28)) + sprintf(BUF, " [op%d(%d,%d)]", curForm->op, curForm->param, curForm->value); + +// if (curForm->version == 100) +// sprintf(BUF, " [expansion only]"); + + return 1; +} +#undef BUF + + + +void listAllCubeFormula() +{ + char filename[MAX_PATH]; + _getcwd( filename, MAX_PATH ); + if( filename[strlen(filename)] != '\\') + strcat(filename, "\\"); + strcat(filename, CUBEFORMULA_FILE); + + FILE* file = fopen(filename, "w"); + + if (!file) return; + + log_msg("\n\n********** Print all cube formula **********\n");//SgptDataTables->nbCubemain\n" + + int nbLines = D2GetNbCubeMainBIN();//SgptDataTables->nbCubemain + log_msg("nbLines : %d\n",nbLines); + + char buf[300]; + for (int i=0; icubemain + i; + if (res) fprintf(file,"%4u: %s\n",i,buf); + if (res) fflush(file); + } + + fclose(file); + log_msg("\n********** Printing over **********\n\n"); + +/* _getcwd( filename, MAX_PATH ); + if( filename[strlen(filename)] != '\\') + strcat(filename, "\\"); + strcat(filename, "tmp.txt"); + + file = fopen(filename, "w"); + + ItemStatCostBIN* itemStatCost; + LPWSTR lpText; + for (i=0;i<=STATS_ITEM_CHARGED_SKILL_MOD;i++) + { + buf[0]='\0'; + itemStatCost = D2GetItemStatCostBIN(i); + lpText = D2GetStringFromIndex(itemStatCost->descstrpos); + wcstombs(&buf[0],lpText,100); + strcat(buf,"\t - \t"); + lpText = D2GetStringFromIndex(itemStatCost->descstrneg); + wcstombs(&buf[strlen(buf)],lpText,100); + fprintf(file,"%03d %03X \t- %s\n",i,i,buf); + } + fclose(file);*/ +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/NewInterface_Runewords.cpp b/PlugY/NewInterface_Runewords.cpp new file mode 100644 index 0000000..68da2d7 --- /dev/null +++ b/PlugY/NewInterface_Runewords.cpp @@ -0,0 +1,291 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Interface functions + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "updateServer.h" // Install_UpdateServer() +#include "plugYFiles.h" // Install_PlugYImagesFiles() +#include "statsPoints.h" +#include "newInterfaces.h" +#include + +#define NB_RUNES_PER_PAGE 25 + +#define getXCloseBtn() 360 +#define getLCloseBtn() 32 +#define getYCloseBtn() (ResolutionY - 60) +#define getHCloseBtn() 32 +#define isOnCloseBtn(x,y) isOnRect(x, y, getXCloseBtn(), getYCloseBtn(), getLCloseBtn(), getHCloseBtn()) + +#define getXNextPageBtn() 120 +#define getLNextPageBtn() 32 +#define getYNextPageBtn() (ResolutionY - 60) +#define getHNextPageBtn() 32 +#define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn()) + +#define getXPrevRunesBtn() 168 +#define getLPrevRunesBtn() 32 +#define getYPrevRunesBtn() (ResolutionY - 60) +#define getHPrevRunesBtn() 32 +#define isOnPrevRunesBtn(x,y) isOnRect(x, y, getXPrevRunesBtn(), getYPrevRunesBtn(), getLPrevRunesBtn(), getHPrevRunesBtn()) + +#define getXNextRunesBtn() 200 +#define getLNextRunesBtn() 32 +#define getYNextRunesBtn() (ResolutionY - 60) +#define getHNextRunesBtn() 32 +#define isOnNextRunesBtn(x,y) isOnRect(x, y, getXNextRunesBtn(), getYNextRunesBtn(), getLNextRunesBtn(), getHNextRunesBtn()) + +int curRunesPage=0; +int maxRunesPage=0xFFFF; + +static struct +{ + union{ + DWORD all; + struct{ + DWORD close:1; + DWORD nextPage:1; + DWORD prevRunes:1; + DWORD nextRunes:1; + }; + }; +} isDownBtn; + + +void printRuneword(RunesBIN* runesData, DWORD pos) +{ + WCHAR temp[50]; + WCHAR runesList[50]; + WCHAR typesList[50]; + LPWSTR lpText = D2GetStringFromIndex(runesData->RuneNameID); + 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) + + typesList[0]=L'\0'; + DWORD numItype=0; + while (numItype<6) + { + WORD type = runesData->Itypes[numItype]; + if (!type) break; + getTypeUString(type,temp,50); + if (numItype) wcscat(typesList,L"/"); + wcscat(typesList,temp); + numItype++; + } + nbPixel = D2GetPixelLen(typesList); + x1 = (nbPixel >= 195) ? 0 : 195-nbPixel; + D2PrintString(typesList, x1, 20 + pos*20, WHITE, 0);//MILIEU(0x70,0xA0,nbPixel) + + runesList[0]=L'\0'; + DWORD numRune=0; + int curRuneID = runesData->Runes[0]; + while ((curRuneID>0) && (numRune<6)) + { + ItemsBIN* itemsData = D2GetItemsBIN(curRuneID); + d2_assert( !itemsData , "itemsData", __FILE__, __LINE__); + GemsBIN* gemData = D2GetGemsBIN(itemsData->GemOffset); + if (gemData) { + d2_assert( !gemData , "gemData", __FILE__, __LINE__); + mbstowcs(temp, gemData->letter, 50); + if (numRune) wcscat(runesList,L" "); +// else wcscat(runesList,L""); + wcscat(runesList,temp);} + numRune++; + curRuneID = runesData->Runes[numRune]; + } +// wcscat(runesList,L""); + D2SetFont(1); + DWORD y1; + nbPixel = D2GetPixelLen(runesList); + if (nbPixel>195) + { + D2SetFont(6); + nbPixel = D2GetPixelLen(runesList); + y1=16; + x1 = nbPixel>195 ? 395-nbPixel : 204; + } else { + x1=205; + y1=18; + } + +// x1 = (nbPixel < 145) ? 155 : 300-nbPixel; + D2PrintString(runesList, x1, y1 + pos*20, WHITE, 0);//MILIEU(0xD0,0xA0,nbPixel) +} + + +#define BUFSIZE 0x80 +//6FB21FAA +void STDCALL printRunewordsPage() +{ + if (!D2isLODGame() || !D2GetResolution()) return D2PrintStatsPage(); + + LPWSTR lpText; + bDontPrintBorder = true; + + //Init data for print image + sDrawImageInfo data; + ZeroMemory(&data,sizeof(data)); + + //print background +/* setImage(&data, newStatsInterfaceImages); + setFrame(&data, 0); + D2PrintImage(&data, 0, 256, -1, 5, 0); + setFrame(&data, 1); + D2PrintImage(&data, 256,256, -1, 5, 0); + setFrame(&data, 2); + D2PrintImage(&data, 0, 512, -1, 5, 0); + setFrame(&data, 3); + D2PrintImage(&data, 256,512, -1, 5, 0); + setFrame(&data, 4); + D2PrintImage(&data, 0, 552, -1, 5, 0); + setFrame(&data, 5); + D2PrintImage(&data, 256,552, -1, 5, 0); +*/ + fillRect(0,0,400,552,0,5); + + //print button close + setImage(&data, D2LoadBuySelBtn()); + setFrame(&data, 10 + isDownBtn.close); + D2PrintImage(&data, getXCloseBtn(), getYCloseBtn(), -1, 5, 0); + + //print next page button + setFrame(&data, isDownBtn.nextPage); + D2PrintImage(&data, getXNextPageBtn(), getYNextPageBtn(), -1, 5, 0); + + //print previous runes button + setImage(&data, stashBtnsImages); + setFrame(&data, isDownBtn.prevRunes); + D2PrintImage(&data, getXPrevRunesBtn(), getYPrevRunesBtn(), -1, 5, 0); + + //print previous runes button + setFrame(&data, 2 + isDownBtn.nextRunes); + D2PrintImage(&data, getXNextRunesBtn(), getYNextRunesBtn(), -1, 5, 0); + + D2SetFont(6); + + //146;//B400 + int nbRunes = *D2GetNbRunesBIN(); + RunesBIN* runesFirst = nbRunes>1 ? D2GetRunesBIN(1)-1 : NULL; + RunesBIN* runesLast = runesFirst? runesFirst + nbRunes : NULL; +// log_msg("nbRunes(%d,%d) runesFirst(%08X, %08X) runesLast(%08X, %08X)",nbRunes,SgptDataTables->nbRunes,runesFirst, SgptDataTables->runes,runesLast,SgptDataTables->runes + SgptDataTables->nbRunes); + + int nbRunesCompleted=0; + DWORD curNbRunes=0; + for ( RunesBIN* runesData = runesFirst; runesData < runesLast; runesData++) + { + if (!runesData->Complete || runesData->Server) continue; + nbRunesCompleted++; + if ( (curRunesPage * NB_RUNES_PER_PAGE < nbRunesCompleted) && + (nbRunesCompleted <= (curRunesPage+1) * NB_RUNES_PER_PAGE) ) + printRuneword(runesData, curNbRunes++); + } + maxRunesPage = nbRunesCompleted ? (nbRunesCompleted-1) / NB_RUNES_PER_PAGE : 0; + + +//////////////////// POPUP PRINTING //////////////////// + //set MouseX & MouseY + DWORD x = D2GetMouseX(); + DWORD y = D2GetMouseY(); + + if (isOnCloseBtn(x,y)) // print popup "close" + { + D2PrintPopup(D2GetStringFromIndex(0x1030), getXCloseBtn()+getLCloseBtn()/2, getYCloseBtn()-getHCloseBtn(), WHITE, 1); + } + else if (isOnNextPageBtn(x,y)) // print popup "next page" + { + lpText = getTranslatedString(STR_NEXT_PAGE); + D2PrintPopup(lpText, getXNextPageBtn()+getLNextPageBtn()/2, getYNextPageBtn()-getHNextPageBtn(), WHITE, 1); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +DWORD STDCALL mouseRunewordsPageLeftDown(sWinMessage* msg) +{ + if (!D2isLODGame() || !D2GetResolution()) return -1; + + if (!isOnStatsPage(msg->x,msg->y)) return 1; + + if (isOnCloseBtn(msg->x,msg->y)) + { + log_msg("push down left button close\n"); + isDownBtn.close = 1; + D2PlaySound(4,0,0,0,0); + } + 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); + } + else if (isOnPrevRunesBtn(msg->x,msg->y)) + { + log_msg("push down left button prev page\n"); + isDownBtn.prevRunes = 1; + D2PlaySound(4,0,0,0,0); + } + else if (isOnNextRunesBtn(msg->x,msg->y)) + { + log_msg("push down left button next runes\n"); + isDownBtn.nextRunes = 1; + D2PlaySound(4,0,0,0,0); + } + + freeMessage(msg); + return 0; +} + + +DWORD STDCALL mouseRunewordsPageLeftUp(sWinMessage* msg) +{ + if (!D2isLODGame() || !D2GetResolution()) return -1; + + if (!isOnStatsPage(msg->x,msg->y)) return 1; + + if (isOnCloseBtn(msg->x,msg->y)) + { + log_msg("push up left button close\n"); + if (isDownBtn.close) + D2TogglePage(2,1,0); + } + else if (isOnNextPageBtn(msg->x,msg->y)) + { + log_msg("push up left button next page\n"); + if (isDownBtn.nextPage) + { + GoStatPage(GetCurrentPage()+1); + log_msg("next page press\n"); + } + } + else if (isOnPrevRunesBtn(msg->x,msg->y)) + { + log_msg("push up left button prev runes\n"); + if (isDownBtn.prevRunes) + { + if (curRunesPage) curRunesPage--; + } + } + else if (isOnNextRunesBtn(msg->x,msg->y)) + { + log_msg("push up left button next runes\n"); + if (isDownBtn.nextRunes) + { + if (curRunesPage < maxRunesPage) curRunesPage++; + } + } + + D2CleanStatMouseUp(); + freeMessage(msg); + isDownBtn.all=0; + return 0; +} + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/NewInterface_Stats.cpp b/PlugY/NewInterface_Stats.cpp new file mode 100644 index 0000000..4ffc718 --- /dev/null +++ b/PlugY/NewInterface_Stats.cpp @@ -0,0 +1,823 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Interface functions + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "updateServer.h" // Install_UpdateServer() +#include "plugYFiles.h" // Install_PlugYImagesFiles() +#include "statsPoints.h" +#include "newInterfaces.h" +#include + + +#define getXCloseBtn() 360 +#define getLCloseBtn() 32 +#define getYCloseBtn() (ResolutionY - 60) +#define getHCloseBtn() 32 +#define isOnCloseBtn(x,y) isOnRect(x, y, getXCloseBtn(), getYCloseBtn(), getLCloseBtn(), getHCloseBtn()) + +#define getXPreviousPageBtn() RX(0x19)//0x70 +#define getLPreviousPageBtn() 32 +#define getYPreviousPageBtn() RY(0x40) +#define getHPreviousPageBtn() 32 +#define isOnPreviousPageBtn(x,y) isOnRect(x, y, getXPreviousPageBtn(), getYPreviousPageBtn(), getLPreviousPageBtn(), getHPreviousPageBtn()) + +#define getXNextPageBtn() RX(D2GetResolution()?0x43:0x8A) +#define getLNextPageBtn() 32 +#define getYNextPageBtn() RY(D2GetResolution()?0x40:0x70) +#define getHNextPageBtn() 32 +#define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn()) + +/* +#define getXNextPageBtn() 120 +#define getLNextPageBtn() 32 +#define getYNextPageBtn() (ResolutionY - 60) +#define getHNextPageBtn() 32 +#define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn()) +*/ + + +#define getLAssignBtn() 32 +#define getHAssignBtn() 32 + +#define getXAssSTRBtn() 0x7D+35 +#define getYAssSTRBtn() 0x6A +#define isOnAssSTRBtn(x,y) isOnRect(x, y, getXAssSTRBtn(), getYAssSTRBtn(), getLAssignBtn(), getHAssignBtn()) + +#define getXAssDEXBtn() 0x7D+35 +#define getYAssDEXBtn() 0xA8 +#define isOnAssDEXBtn(x,y) isOnRect(x, y, getXAssDEXBtn(), getYAssDEXBtn(), getLAssignBtn(), getHAssignBtn()) + +#define getXAssVITBtn() 0x7D+35 +#define getYAssVITBtn() 0xFE +#define isOnAssVITBtn(x,y) isOnRect(x, y, getXAssVITBtn(), getYAssVITBtn(), getLAssignBtn(), getHAssignBtn()) + +#define getXAssENEBtn() 0x7D+35 +#define getYAssENEBtn() 0x13C +#define isOnAssENEBtn(x,y) isOnRect(x, y, getXAssENEBtn(), getYAssENEBtn(), getLAssignBtn(), getHAssignBtn()) + + +#define getLUnassignBtn() 32 +#define getHUnassignBtn() 32 + +#define getXUnaSTRBtn() 0x7D +#define getYUnaSTRBtn() getYAssSTRBtn() +#define isOnUnaSTRBtn(x,y) isOnRect(x, y, getXUnaSTRBtn(), getYUnaSTRBtn(), getLUnassignBtn(), getHUnassignBtn()) + +#define getXUnaDEXBtn() 0x7D +#define getYUnaDEXBtn() getYAssDEXBtn() +#define isOnUnaDEXBtn(x,y) isOnRect(x, y, getXUnaDEXBtn(), getYUnaDEXBtn(), getLUnassignBtn(), getHUnassignBtn()) + +#define getXUnaVITBtn() 0x7D +#define getYUnaVITBtn() getYAssVITBtn() +#define isOnUnaVITBtn(x,y) isOnRect(x, y, getXUnaVITBtn(), getYUnaVITBtn(), getLUnassignBtn(), getHUnassignBtn()) + +#define getXUnaENEBtn() 0x7D +#define getYUnaENEBtn() getYAssENEBtn() +#define isOnUnaENEBtn(x,y) isOnRect(x, y, getXUnaENEBtn(), getYUnaENEBtn(), getLUnassignBtn(), getHUnassignBtn()) + + + +void** ptD2RemainingStatsPointsBoxImages = (void**)0x6FBB5E50; +#define D2RemainingStatsPointsBoxImages (*ptD2RemainingStatsPointsBoxImages) + +void** ptD2AssignStatsPointsBoxImages = (void**)0x6FBB5BB8; +#define D2AssignStatsPointsBoxImages (*ptD2AssignStatsPointsBoxImages) + +void** ptD2AssignStatsPointsBtnImages = (void**)0x6FBB5BB4; +#define D2AssignStatsPointsBtnImages (*ptD2AssignStatsPointsBtnImages) + + + +static struct +{ + union{ + DWORD all; + struct{ + DWORD close:1; + DWORD AssSTR:1; + DWORD AssDEX:1; + DWORD AssVIT:1; + DWORD AssENE:1; + DWORD UnaSTR:1; + DWORD UnaDEX:1; + DWORD UnaVIT:1; + DWORD UnaENE:1; + DWORD previousPage:1; + DWORD nextPage:1; + }; + }; +} isDownBtn; + + +void print2Lines(WORD id, LPWSTR lpText, DWORD x, DWORD l, DWORD y) +{ + wcsncpy(lpText, D2GetStringFromIndex(id), 0x63); + lpText[0x64]= L'\0'; + + LPWSTR lptmp = lpText; + while (*lptmp) + { + if (*lptmp==L'\n') + { + *lptmp = L'\0'; + if (*(++lptmp)) + { + DWORD nbPixel = D2GetPixelLen(lpText); + D2PrintString(lpText, MILIEU(x,l,nbPixel), y-4, WHITE, 0); + nbPixel = D2GetPixelLen(lptmp); + D2PrintString(lptmp, MILIEU(x,l,nbPixel), y+4, WHITE, 0); + return; + } + break; + } + lptmp++; + } + DWORD nbPixel = D2GetPixelLen(lpText); + D2PrintString(lpText, MILIEU(x,l,nbPixel), y, WHITE, 0); +} + + +#define BUFSIZE 0x80 +void STDCALL printNewStatsPage() +{ + if (!D2isLODGame() || !D2GetResolution()) return D2PrintStatsPage(); + + WCHAR text[BUFSIZE]; + LPWSTR lpText; + DWORD nbPixel; + DWORD curValue,baseValue,color; + DWORD x1,y1,reset=0; + bDontPrintBorder = true; + + int curRes,maxRes; + + Unit* ptChar = D2GetClientPlayer(); + + d2_assert(!ptChar, "Printing stats page : no character selected",__FILE__,__LINE__); + d2_assert(ptChar->nUnitType != UNIT_PLAYER, "Printing stats page : bad unit type",__FILE__,__LINE__); + + //Init data for print image + sDrawImageInfo data; + ZeroMemory(&data,sizeof(data)); + + //print background +/* setImage(&data, newStatsInterfaceImages); + setFrame(&data, 0); + D2PrintImage(&data, 0, 256, -1, 5, 0); + setFrame(&data, 1); + D2PrintImage(&data, 256,256, -1, 5, 0); + setFrame(&data, 2); + D2PrintImage(&data, 0, 512, -1, 5, 0); + setFrame(&data, 3); + D2PrintImage(&data, 256,512, -1, 5, 0); + setFrame(&data, 4); + D2PrintImage(&data, 0, 552, -1, 5, 0); + setFrame(&data, 5); + D2PrintImage(&data, 256,552, -1, 5, 0); +*/ + fillRect(0,0,400,552,0,5); + + //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, 14 + isDownBtn.nextPage); + D2PrintImage(&data, getXNextPageBtn(), getYNextPageBtn(), -1, 5, 0); + + CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass); + DifficultyLevelsBIN* difficultyLevels = D2GetDifficultyLevelsBIN (D2GetDifficultyLevel()); + + //print fixed text + D2SetFont(6); + print2Lines(0xFD9, text, 0x0B, 0x29, 0x2C); //level //0x34-0xB + print2Lines(0xFDA, text, 0x41, 0x73, 0x2C); //Experience //0xB4-0x41 + print2Lines(0xFDB, text, 0xC1, 0x73, 0x2C); //Next Level //0x134-0xC1 + print2Lines(0xFDC, text, 0x0A, 0x3F, 0x61); //Strengh //0x49-0xA + print2Lines(0xFDE, text, 0x0A, 0x3F, 0xA0); //Dexterity //0x49-0xA + print2Lines(0xFE0, text, 0xAE, 0x5E, 0xCF); //Defence //0x10C-0xAE + print2Lines(0xFE2, text, 0x0A, 0x3F, 0xF5); //Vitality //0x49-0xA + print2Lines(0xFE3, text, 0xAE, 0x36, 0xF5); //Stamina //0xE4-0xAE + print2Lines(0xFE4, text, 0xAE, 0x36, 0x10D);//Life //0xE4-0xAE + print2Lines(0xFE5, text, 0x0A, 0x3F, 0x133);//Energy //0x49-0xA + print2Lines(0xFE6, text, 0xAE, 0x36, 0x133);//Mana //0xE4-0xAE + print2Lines(0xFE7, text, 0xBE, 0x4E, 0x15A);//Fire.Resistance //0x10C-0xBE + print2Lines(0xFE8, text, 0xBE, 0x4E, 0x172);//Cold.Resistance //0x10C-0xBE + print2Lines(0xFE9, text, 0xBE, 0x4E, 0x18B);//Lightning.Resistance //0x10C-0xBE + print2Lines(0xFEA, text, 0xBE, 0x4E, 0x1A3);//Poison.Resistance //0x10C-0xBE + + // print class + D2SetFont(1); + lpText = charStats->nameU; + nbPixel = D2GetPixelLen(lpText); + D2PrintString(lpText, MILIEU(0xC1,0x76,nbPixel), 0x19, WHITE, 0); + + // print name + char* string = PCPlayerData->name; + int usize = strlen(string); + if (usize>9) + D2SetFont(usize < 12?0:6); + mbstowcs(text,string,BUFSIZE); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0xD,0x94,nbPixel), 0x19, WHITE, 0); + + D2SetFont(1); + + // print level value + curValue = D2GetPlayerStat(ptChar, STATS_LEVEL, 0); + baseValue = D2GetPlayerBaseStat(ptChar, STATS_LEVEL, 0); + if (curValue != baseValue) color = curValue < baseValue ? RED : BLUE; + else color = WHITE; + swprintf(text,L"%ld",curValue); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0xD,0x29,nbPixel), 0x3B, color, 0);//ESI,EBX,EDI + +if (version_D2Client <= V110) +{ + //print Experience + curValue = D2GetPlayerStat(ptChar, STATS_EXPERIENCE, 0); + D2PrintBigNumber(text, curValue, BUFSIZE); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0x43,0x72,nbPixel), 0x3B, WHITE, 0); + + //print next level + DWORD plvl = D2GetPlayerBaseStat(ptChar, STATS_LEVEL, 0); + if (plvl < D2GetMaxLevel(ptChar->nPlayerClass)) + curValue = D2GetNextLevelXP(ptChar->nPlayerClass, plvl); + else + curValue = D2GetPlayerStat(ptChar, STATS_NEXTEXP, 0); + D2PrintBigNumber(text,curValue,BUFSIZE); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0xC3,0x72,nbPixel), 0x3B, WHITE, 0); + + //print strength + curValue = D2GetPlayerStat(ptChar, STATS_STRENGTH, 0); + baseValue = D2GetPlayerBaseStat(ptChar, STATS_STRENGTH, 0); + if (curValue != baseValue) color = curValue < baseValue ? RED : BLUE; + else color = WHITE; + swprintf(text,L"%ld",curValue); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0x4D,0x24,nbPixel), 0x63, color, 0);//ESI,EBX,EDI + + //print dexterity + curValue = D2GetPlayerStat(ptChar, STATS_DEXTERITY, 0); + baseValue = D2GetPlayerBaseStat(ptChar, STATS_DEXTERITY, 0); + if (curValue != baseValue) color = curValue < baseValue ? RED : BLUE; + else color = WHITE; + swprintf(text,L"%ld",curValue); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0x4D,0x24,nbPixel), 0xA1, color, 0);//ESI,EBX,EDI + + //print vitality + curValue = D2GetPlayerStat(ptChar, STATS_VITALITY, 0); + baseValue = D2GetPlayerBaseStat(ptChar, STATS_VITALITY, 0); + if (curValue != baseValue) color = curValue < baseValue ? RED : BLUE; + else color = WHITE; + swprintf(text,L"%ld",curValue); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0x4D,0x24,nbPixel), 0xF7, color, 0);//ESI,EBX,EDI + + //print energy + curValue = D2GetPlayerStat(ptChar, STATS_ENERGY, 0); + baseValue = D2GetPlayerBaseStat(ptChar, STATS_ENERGY, 0); + if (curValue != baseValue) color = curValue < baseValue ? RED : BLUE; + else color=0; + swprintf(text,L"%ld",curValue); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0x4D,0x24,nbPixel), 0x134, color, 0);//ESI,EBX,EDI + + + //print max stamina + curValue = D2GetPlayerStat(ptChar, STATS_MAXSTAMINA, 0) / 256; + baseValue = D2GetPlayerBaseStat(ptChar, STATS_MAXSTAMINA, 0) / 256; + if (curValue != baseValue) color = curValue < baseValue ? RED : BLUE; + else color = WHITE; + swprintf(text,L"%ld",curValue); + + if (curValue > 999) reset=1; + D2GetPixelRect(text,&x1,&y1); + if (0x24 999) reset=1; + D2GetPixelRect(text,&x1,&y1); + if (0x24 999) reset=1; + D2GetPixelRect(text,&x1,&y1); + if (0x24CurrentAnim != 0x11) && !curValue) curValue=1; + + swprintf(text,L"%ld",curValue); + + if (curValue > 999) reset=1; + D2GetPixelRect(text,&x1,&y1); + if (0x24 999) reset=1; + D2GetPixelRect(text,&x1,&y1); + if (0x24 999) reset=1; + D2GetPixelRect(text,&x1,&y1); + if (0x24 999)) + {reset = 1; D2SetFont(0);} + } + + swprintf(text,L"%ld",curValue); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0x111,0x23,nbPixel), 0xD1, color, 0);//ESI,EBX,EDI + if (reset) {D2SetFont(1); reset=0;} + + + //print fire resistance + curRes = D2GetPlayerStat(ptChar, STATS_FIRERESIST, 0) + difficultyLevels->resistPenalty; + color = D2haveFireResBonus(ptChar) ? BLUE : WHITE; + if (D2haveFireResMalus(ptChar)) color = RED; + maxRes = 75 + D2GetPlayerStat(ptChar, STATS_MAXFIRERESIST, 0); + if (maxRes>95) maxRes = 95; + if (curRes < -100) curRes=-100; + if (curRes > maxRes) curRes = maxRes; + if ((curRes == maxRes) && (color != BLUE)) color = GOLD; + else if (curRes < 0) color = RED; + + swprintf(text,L"%ld",curRes); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0x111,0x23,nbPixel), 0x15C, color, 0);//ESI,EBX,EDI + + //print lightning resistance + curRes = D2GetPlayerStat(ptChar, STATS_LIGHTRESIST, 0) + difficultyLevels->resistPenalty; + color = D2haveLightResBonus(ptChar) ? BLUE : WHITE; + if (D2haveLightResMalus(ptChar)) color = RED; + maxRes = 75 + D2GetPlayerStat(ptChar, STATS_MAXLIGHTRESIST, 0); + if (maxRes>95) maxRes = 95; + if (curRes < -100) curRes=-100; + if (curRes > maxRes) curRes = maxRes; + if ((curRes == maxRes) && (color != BLUE)) color = GOLD; + else if (curRes < 0) color = RED; + + swprintf(text,L"%ld",curRes); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0x111,0x23,nbPixel), 0x174, color, 0);//ESI,EBX,EDI + + //print cold resistance + curRes = D2GetPlayerStat(ptChar, STATS_COLDRESIST, 0) + difficultyLevels->resistPenalty; + color = D2haveColdResBonus(ptChar) ? BLUE : WHITE; + if (D2haveColdResMalus(ptChar)) color = RED; + maxRes = 75 + D2GetPlayerStat(ptChar, STATS_MAXCOLDRESIST, 0); + if (maxRes>95) maxRes = 95; + if (curRes < -100) curRes=-100; + if (curRes > maxRes) curRes = maxRes; + if ((curRes == maxRes) && (color != BLUE)) color = GOLD; + else if (curRes < 0) color = RED; + + swprintf(text,L"%ld",curRes); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0x111,0x23,nbPixel), 0x18C, color, 0);//ESI,EBX,EDI + + //print poison resistance + curRes = D2GetPlayerStat(ptChar, STATS_POISONRESIST, 0) + difficultyLevels->resistPenalty; + color = D2havePoisonResBonus(ptChar) ? BLUE : WHITE; + if (D2havePoisonResMalus(ptChar)) color = RED; + maxRes = 75 + D2GetPlayerStat(ptChar, STATS_MAXPOISONRESIST, 0); + if (maxRes>95) maxRes = 95; + if (curRes < -100) curRes=-100; + if (curRes > maxRes) curRes = maxRes; + if ((curRes == maxRes) && (color != BLUE)) color = GOLD; + else if (curRes < 0) color = RED; + + swprintf(text,L"%ld",curRes); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(0x111,0x23,nbPixel), 0x1A4, color, 0);//ESI,EBX,EDI + + +//////////////////// STAT POINTS REMAINING MANAGEMENT //////////////////// + //print Assign box of btns : Str,Dex,Ene,Vit + setImage(&data, D2AssignStatsPointsBoxImages); + setFrame(&data, 0); + D2PrintImage(&data, getXAssSTRBtn()-3, getYAssSTRBtn()+4, -1, 5, 0); + D2PrintImage(&data, getXAssDEXBtn()-3, getYAssDEXBtn()+4, -1, 5, 0); + D2PrintImage(&data, getXAssENEBtn()-3, getYAssENEBtn()+4, -1, 5, 0); + D2PrintImage(&data, getXAssVITBtn()-3, getYAssVITBtn()+4, -1, 5, 0); + + DWORD nbStatPointsRemaining = D2GetPlayerBaseStat(ptChar, 4, 0); + if (nbStatPointsRemaining) + { + //print stat point remaining box image + setImage(&data, D2RemainingStatsPointsBoxImages); + setFrame(&data, 0); + D2PrintImage(&data, 3, 0x16C, -1, 5, 0); + + //print "Stat Points Remaining" + D2SetFont(6); + lpText = D2GetStringFromIndex(0xFEB); + nbPixel = D2GetPixelLen(lpText); + D2PrintString(lpText, MILIEU(11,78,nbPixel), 0x163, RED, 0);//163 + lpText = D2GetStringFromIndex(0xFEC); + nbPixel = D2GetPixelLen(lpText); + D2PrintString(lpText, MILIEU(11,78,nbPixel), 0x16B, RED, 0); + + //print Stat Points Remaining number + D2SetFont(1); + swprintf(text, L"%i", nbStatPointsRemaining); + nbPixel = D2GetPixelLen(text); + D2PrintString(text, MILIEU(92,36,nbPixel), 0x168, WHITE, 0); + + setImage(&data, D2AssignStatsPointsBtnImages); + setFrame(&data, isDownBtn.AssSTR); + D2PrintImage(&data, getXAssSTRBtn(), getYAssSTRBtn(), -1, 5, 0); + setFrame(&data, isDownBtn.AssDEX); + D2PrintImage(&data, getXAssDEXBtn(), getYAssDEXBtn(), -1, 5, 0); + setFrame(&data, isDownBtn.AssVIT); + D2PrintImage(&data, getXAssVITBtn(), getYAssVITBtn(), -1, 5, 0); + setFrame(&data, isDownBtn.AssENE); + D2PrintImage(&data, getXAssENEBtn(), getYAssENEBtn(), -1, 5, 0); + } else { + setImage(&data, D2AssignStatsPointsBtnImages); + setFrame(&data, 2); + D2PrintImage(&data, getXAssSTRBtn(), getYAssSTRBtn(), -1, 5, 0); + D2PrintImage(&data, getXAssDEXBtn(), getYAssDEXBtn(), -1, 5, 0); + D2PrintImage(&data, getXAssVITBtn(), getYAssVITBtn(), -1, 5, 0); + D2PrintImage(&data, getXAssENEBtn(), getYAssENEBtn(), -1, 5, 0); + } + + if (active_StatsPoints && !onRealm) + { + setImage(&data, D2AssignStatsPointsBoxImages); + setFrame(&data, 0); + D2PrintImage(&data, getXUnaSTRBtn()-3, getYUnaSTRBtn()+4, -1, 5, 0); + D2PrintImage(&data, getXUnaDEXBtn()-3, getYUnaDEXBtn()+4, -1, 5, 0); + D2PrintImage(&data, getXUnaENEBtn()-3, getYUnaENEBtn()+4, -1, 5, 0); + D2PrintImage(&data, getXUnaVITBtn()-3, getYUnaVITBtn()+4, -1, 5, 0); + + setImage(&data, unassignStatsBtnImages); + if ((int)charStats->baseSTR < D2GetPlayerBaseStat(ptChar, STATS_STRENGTH, 0)) + setFrame(&data, isDownBtn.UnaSTR); + else data.frame = 2; + D2PrintImage(&data, getXUnaSTRBtn(), getYUnaSTRBtn(), -1, 5, 0); + + if ((int)charStats->baseDEX < D2GetPlayerBaseStat(ptChar, STATS_DEXTERITY, 0)) + setFrame(&data, isDownBtn.UnaDEX); + else setFrame(&data, 2); + D2PrintImage(&data, getXUnaDEXBtn(), getYUnaDEXBtn(), -1, 5, 0); + + if ((int)charStats->baseVIT < D2GetPlayerBaseStat(ptChar, STATS_VITALITY, 0)) + setFrame(&data, isDownBtn.UnaVIT); + else setFrame(&data, 2); + D2PrintImage(&data, getXUnaVITBtn(), getYUnaVITBtn(), -1, 5, 0); + + if ((int)charStats->baseENE < D2GetPlayerBaseStat(ptChar, STATS_ENERGY, 0)) + setFrame(&data, isDownBtn.UnaENE); + else setFrame(&data, 2); + D2PrintImage(&data, getXUnaENEBtn(), getYUnaENEBtn(), -1, 5, 0); + } +} + +//////////////////// POPUP PRINTING //////////////////// + //set MouseX & MouseY + DWORD x = D2GetMouseX(); + DWORD y = D2GetMouseY(); + + + if (isOnCloseBtn(x,y)) // print popup "close" + { + //lpText = D2GetStringFromIndex(0x1030); + //nbPixel = D2GetPixelLen(lpText); + //D2PrintPopup(lpText, getXCloseBtn()+getLCloseBtn()/2-nbPixel/2, getYCloseBtn()-getHCloseBtn(), WHITE, 0); + D2PrintPopup(D2GetStringFromIndex(0x1030), getXCloseBtn()+getLCloseBtn()/2, getYCloseBtn()-getHCloseBtn(), WHITE, 1); + } + else if (isOnPreviousPageBtn(x,y)) //print popup "previous page" + { + lpText = getTranslatedString(STR_PREVIOUS_PAGE); + D2PrintPopup(lpText, getXPreviousPageBtn()+getLPreviousPageBtn()/2, getYPreviousPageBtn()-getHPreviousPageBtn(), WHITE, 1); + } + else if (isOnNextPageBtn(x,y)) //print popup "next page" + { + lpText = getTranslatedString(STR_NEXT_PAGE); + D2PrintPopup(lpText, getXNextPageBtn()+getLNextPageBtn()/2, getYNextPageBtn()-getHNextPageBtn(), WHITE, 1); + } + else if (isOnRect(x, y, 0xAD, 0x137, 0x15, 0x13)) + { +if ( version_D2Client <= V110 ) +{ + DWORD avgChanceMonsterWillHitYou=53;//TODO + if (avgChanceMonsterWillHitYou<5) avgChanceMonsterWillHitYou = 5; + else if (avgChanceMonsterWillHitYou>95) avgChanceMonsterWillHitYou = 95; + + int chanceToBlock = D2GetChanceToBlock(ptChar, D2isLODGame()); + if (chanceToBlock <= 0) + { + //......TODO + chanceToBlock=0; + } + + int monsterID = D2GetLastMonsterIDFight(); + MonStatsBIN* monStats = SgptDataTables->monStats + monsterID; + d2_assert((monsterID<0) || (monsterID >= (int)SgptDataTables->nbMonStats) || !monStats, "ptStats", __FILE__, __LINE__); + LPWSTR monsterStr = D2GetStringFromIndex(monStats->monsterNameID); + if (chanceToBlock) + swprintf(text,D2GetStringFromIndex(0x2779),chanceToBlock,avgChanceMonsterWillHitYou,monsterStr,avgChanceMonsterWillHitYou); + else + swprintf(text,D2GetStringFromIndex(0x2778),monsterStr,avgChanceMonsterWillHitYou); + //D2swprintf(0x80 + D2PrintTextPopup(text,0x8B,0xA5,*(BYTE*)0x6FBB1A50,2,WHITE); +} + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +DWORD STDCALL mouseNewStatsPageLeftDown(sWinMessage* msg) +{ + if (!D2isLODGame() || !D2GetResolution()) return -1; + + if (!isOnStatsPage(msg->x,msg->y)) return 1; + + Unit* ptChar = D2GetClientPlayer(); + + if (isOnCloseBtn(msg->x,msg->y)) + { + log_msg("push down left button close\n"); + isDownBtn.close = 1; + D2PlaySound(4,0,0,0,0); + } + 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); + } + 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); + } + else if (D2GetPlayerBaseStat(ptChar, 4, 0)) + { + if (isOnAssSTRBtn(msg->x,msg->y)) + { + log_msg("push down left button assign strengh\n"); + isDownBtn.AssSTR = 1; + D2PlaySound(5,0,0,0,0); + } + else if (isOnAssDEXBtn(msg->x,msg->y)) + { + log_msg("push down left button assign dexterity\n"); + isDownBtn.AssDEX = 1; + D2PlaySound(5,0,0,0,0); + } + else if (isOnAssVITBtn(msg->x,msg->y)) + { + log_msg("push down left button assign vitality\n"); + isDownBtn.AssVIT = 1; + D2PlaySound(5,0,0,0,0); + } + else if (isOnAssENEBtn(msg->x,msg->y)) + { + log_msg("push down left button assign energy\n"); + isDownBtn.AssENE = 1; + D2PlaySound(5,0,0,0,0); + } + } + if (active_StatsPoints && !onRealm) + { + CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass); + if (isOnUnaSTRBtn(msg->x,msg->y) && ((int)charStats->baseSTR < D2GetPlayerBaseStat(ptChar, STATS_STRENGTH, 0))) + { + log_msg("push down left button unassign strengh\n"); + isDownBtn.UnaSTR = 1; + D2PlaySound(5,0,0,0,0); + } + else if (isOnUnaDEXBtn(msg->x,msg->y) && ((int)charStats->baseDEX < D2GetPlayerBaseStat(ptChar, STATS_DEXTERITY, 0))) + { + log_msg("push down left button unassign dexterity\n"); + isDownBtn.UnaDEX = 1; + D2PlaySound(5,0,0,0,0); + } + else if (isOnUnaVITBtn(msg->x,msg->y) && ((int)charStats->baseVIT < D2GetPlayerBaseStat(ptChar, STATS_VITALITY, 0))) + { + log_msg("push down left button unassign vitality\n"); + isDownBtn.UnaVIT = 1; + D2PlaySound(5,0,0,0,0); + } + else if (isOnUnaENEBtn(msg->x,msg->y) && ((int)charStats->baseENE < D2GetPlayerBaseStat(ptChar, STATS_ENERGY, 0))) + { + log_msg("push down left button unassign energy\n"); + isDownBtn.UnaENE = 1; + D2PlaySound(5,0,0,0,0); + } + } + + freeMessage(msg); + return 0; +} + + +void sendAssignStats(DWORD code, DWORD nbStatPointsRemaining) +{ + DWORD nbPoints = GetKeyState(VK_SHIFT)<0? nbStatPointsRemaining : 1; + if (active_StatsShiftClickLimit && (nbPoints>limitValueToShiftClick)) + nbPoints = limitValueToShiftClick; + while ( nbPoints>0 ) + { + DWORD nbTemp = nbPoints > 0x20 ? 0x20 : nbPoints; + D2SendToServer3(0x3A, (WORD)(code + (nbTemp-1)*256)); + nbPoints -= nbTemp; + } +} + +DWORD STDCALL mouseNewStatsPageLeftUp(sWinMessage* msg) +{ + if (!D2isLODGame() || !D2GetResolution()) return -1; + + if (!isOnStatsPage(msg->x,msg->y)) return 1; + + Unit* ptChar = D2GetClientPlayer(); + DWORD nbStatPointsRemaining = D2GetPlayerBaseStat(ptChar, 4, 0); + + if (isOnCloseBtn(msg->x,msg->y)) + { + log_msg("push up left button close\n"); + if (isDownBtn.close) + D2TogglePage(2,1,0); + } + else if (isOnPreviousPageBtn(msg->x,msg->y)) + { + log_msg("push up left button previous page\n"); + if (isDownBtn.previousPage) + { + GoStatPage(GetCurrentPage()-1); + log_msg("previous page press\n"); + } + } + else if (isOnNextPageBtn(msg->x,msg->y)) + { + log_msg("push up left button next page\n"); + if (isDownBtn.nextPage) + { + GoNextStatPage(); + log_msg("next page press\n"); + } + } + else if (nbStatPointsRemaining) + { + if (isOnAssSTRBtn(msg->x,msg->y)) + { + log_msg("push up left button assign strengh\n"); + if (isDownBtn.AssSTR) + sendAssignStats(0,nbStatPointsRemaining); + } + else if (isOnAssDEXBtn(msg->x,msg->y)) + { + log_msg("push up left button assign dexterity\n"); + if (isDownBtn.AssDEX) + sendAssignStats(2,nbStatPointsRemaining); + } + else if (isOnAssVITBtn(msg->x,msg->y)) + { + log_msg("push up left button assign vitality\n"); + if (isDownBtn.AssVIT) + sendAssignStats(3,nbStatPointsRemaining); + } + else if (isOnAssENEBtn(msg->x,msg->y)) + { + log_msg("push up left button assign energy\n"); + if (isDownBtn.AssENE) + sendAssignStats(1,nbStatPointsRemaining); + } + } + if (active_StatsPoints && !onRealm) + { + CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass); + if (isOnUnaSTRBtn(msg->x,msg->y) && ((int)charStats->baseSTR < D2GetPlayerBaseStat(ptChar, STATS_STRENGTH, 0))) + { + log_msg("push up left button unassign strengh\n"); + if (isDownBtn.UnaSTR) + if (GetKeyState(VK_SHIFT)<0) + updateServer(US_UNASSIGN_STR_POINTS); + else + updateServer(US_UNASSIGN_STR_POINT); + } + else if (isOnUnaDEXBtn(msg->x,msg->y) && ((int)charStats->baseDEX < D2GetPlayerBaseStat(ptChar, STATS_DEXTERITY, 0))) + { + log_msg("push up left button unassign dexterity\n"); + if (isDownBtn.UnaDEX) + if (GetKeyState(VK_SHIFT)<0) + updateServer(US_UNASSIGN_DEX_POINTS); + else + updateServer(US_UNASSIGN_DEX_POINT); + } + else if (isOnUnaVITBtn(msg->x,msg->y) && ((int)charStats->baseVIT < D2GetPlayerBaseStat(ptChar, STATS_VITALITY, 0))) + { + log_msg("push up left button unassign vitality\n"); + if (isDownBtn.UnaVIT) + if (GetKeyState(VK_SHIFT)<0) + updateServer(US_UNASSIGN_VIT_POINTS); + else + updateServer(US_UNASSIGN_VIT_POINT); + } + else if (isOnUnaENEBtn(msg->x,msg->y) && ((int)charStats->baseENE < D2GetPlayerBaseStat(ptChar, STATS_ENERGY, 0))) + { + log_msg("push up left button unassign energy\n"); + if (isDownBtn.UnaENE) + if (GetKeyState(VK_SHIFT)<0) + updateServer(US_UNASSIGN_ENE_POINTS); + else + updateServer(US_UNASSIGN_ENE_POINT); + } + } + + D2CleanStatMouseUp(); + freeMessage(msg); + isDownBtn.all=0; + return 0; +} + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/NewInterface_StatsPageTwo.cpp b/PlugY/NewInterface_StatsPageTwo.cpp new file mode 100644 index 0000000..acb3614 --- /dev/null +++ b/PlugY/NewInterface_StatsPageTwo.cpp @@ -0,0 +1,307 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Interface stats page 2 functions + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "updateServer.h" +#include "plugYFiles.h" +#include "statsPoints.h" +#include "newInterfaces.h" +#include + +#define getXCloseBtn() RX(0x110) +#define getLCloseBtn() 32 +#define getYCloseBtn() RY(0x40) +#define getHCloseBtn() 32 +#define isOnCloseBtn(x,y) isOnRect(x, y, getXCloseBtn(), getYCloseBtn(), getLCloseBtn(), getHCloseBtn()) + +#define getXPreviousPageBtn() RX(D2GetResolution()?0x19:0x77)//0x70 +#define getLPreviousPageBtn() 32 +#define getYPreviousPageBtn() RY(0x40) +#define getHPreviousPageBtn() 32 +#define isOnPreviousPageBtn(x,y) isOnRect(x, y, getXPreviousPageBtn(), getYPreviousPageBtn(), getLPreviousPageBtn(), getHPreviousPageBtn()) + +#define getXNextPageBtn() RX(D2GetResolution()?0x43:0xA1)//0x70 +#define getLNextPageBtn() 32 +#define getYNextPageBtn() RY(0x40) +#define getHNextPageBtn() 32 +#define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn()) + + +#define BUFSIZE 0x80 + +static struct +{ + union{ + DWORD all; + struct{ + DWORD close:1; + DWORD previousPage:1; + DWORD nextPage:1; + }; + }; +} isDownBtn; + + +struct statsInterfaceBIN +{ + WORD enabled; + WORD page; + WORD x; + WORD y; + WORD color; + WORD font; + WORD statsID; +}; + +extern int lastPage; +int nbStatsInterface; +statsInterfaceBIN* statsInterface; + +void loadStatsInterfaceDesc(DWORD mempool) +{ + log_msg("loadStatsInterfaceDesc(%d)\n",mempool); + + CREATE_TABLE_DESCRIPTION(8); + ADD_WORD_FIELD(0, "enabled"); + ADD_WORD_FIELD(2, "page"); + ADD_WORD_FIELD(4, "x"); + ADD_WORD_FIELD(6, "y"); + ADD_WORD_FIELD(8, "color"); + ADD_WORD_FIELD(10, "font"); +// ADD_LOOKUP_WORD(10, "stat", lookupItemStatCost); + ADD_WORD_FIELD(12, "statID"); + ADD_TERM_FIELD(); + BUILD_BIN(statsInterfaceBIN, statsInterface, nbStatsInterface, "PlugY\\statsinterface.txt"); + + lastPage = 0; + for (i=0; i lastPage) + lastPage = statsInterface[i].page; +} + +void freeStatsInterfaceDesc() +{ + log_msg("freeStatsInterfaceDesc()\n"); + + if (statsInterface) + { + D2FogMemDeAlloc(statsInterface,__FILE__,__LINE__,0); + statsInterface = NULL; + nbStatsInterface = 0; + } +} + +void printStat(Unit* ptChar, DWORD statID, DWORD x, DWORD y, DWORD color, LPWSTR lpText) +{ + LPWSTR text; + log_msg("printStat : %d\n", statID); + switch (statID) + { + case STATS_FIRERESIST: + case STATS_COLDRESIST: + case STATS_LIGHTRESIST: + case STATS_POISONRESIST: + text = D2GetStringFromIndex(getDescStrPos(statID)); + if (wcslen(text) > 50) return; + swprintf(lpText, L"%s +%i%%", text, D2GetPlayerStat(ptChar,statID,0)); + break; + default: + D2PrintStat(ptChar, NULL, statID, 0, D2GetPlayerStat(ptChar,statID,0), lpText);//param2=ptChar->ptStats->ptItemStats + } +// D2SetFont(1); +// if (D2GetPixelLen(lpText)>0x110) +// D2SetFont(6); + D2PrintString(lpText, x, y, color, 0); +} + +void manageStatLine(Unit* ptChar, statsInterfaceBIN* statLine, int currentPage, LPWSTR lpText) +{ + if (!statLine->enabled) + return; + + if (statLine->page != currentPage) + return; + + if (statLine->font) + D2SetFont(statLine->font); + + printStat(ptChar, statLine->statsID, RX(statLine->x), RY(statLine->y), statLine->color, lpText); +} + +void STDCALL printNewStatsPageTwo(int currentPage) +{ + if (!D2isLODGame()) return D2PrintStatsPage(); + + WCHAR text[BUFSIZE]; + LPWSTR lpText; + bDontPrintBorder = false; + + Unit* ptChar = D2GetClientPlayer(); + + d2_assert(!ptChar, "Printing stats page : no character selected",__FILE__,__LINE__); + d2_assert(ptChar->nUnitType != UNIT_PLAYER, "Printing stats page : bad unit type",__FILE__,__LINE__); + + //Init data for print image + sDrawImageInfo data; + ZeroMemory(&data,sizeof(data)); + + //print background + fillRect(RX(0),RY(480),320,432,0,5);//552 + setImage(&data, newStatsInterfaceImages); + setFrame(&data, 0); + D2PrintImage(&data, RX(0), RY(224), -1, 5, 0); + setFrame(&data, 1); + D2PrintImage(&data, RX(256),RY(224), -1, 5, 0);//256 + setFrame(&data, 2); + D2PrintImage(&data, RX(0), RY(48), -1, 5, 0);//432 + setFrame(&data, 3); + D2PrintImage(&data, RX(256),RY(48), -1, 5, 0); + + D2SetFont(1); + for (int i=0; inPlayerClass); +// DifficultyLevelsBIN* difficultyLevels = D2GetDifficultyLevelsBIN (D2GetDifficultyLevel()); + //print deadly Strike / Critical Strike + x=RX(25); + y=RY(445); + Unit* ptItem = D2GetSkillItem(ptChar); + DWORD cs = ptItem ? D2GetCriticalStrikeFromMasteries(ptChar,ptItem,0,2) : 0; + cs = cs>100?100:cs; + cs += D2GetPlayerStat(ptChar, STATS_PASSIVE_CRITICAL_STRIKE, 0)*(100-cs)/100; + cs = cs>100?100:cs; + //SkillDescBIN* skilldesc = SgptDataTables->skilldesc + 9; + LPWSTR lpCS = D2GetStringFromIndex(skilldesc->strNameID); + + lpText = D2GetStringFromIndex(getDescStrPos(STATS_ITEM_DEADLYSTRIKE)); + curValue = D2GetPlayerStat(ptChar, STATS_ITEM_DEADLYSTRIKE, 0); + + cs += curValue*(100-cs)/100; + curValue = cs>100?100:cs; + + swprintf(text,L"%i%% %s/%s",curValue,lpCS,lpText); + D2SetFont(1); + D2SetFont( D2GetPixelLen(text)>0x110 ? 6 : 1); + D2PrintString(text, x, y, WHITE, 0); +*/ + + //print background previous/next page buttons + setImage(&data, statsBackgroundImages); + setFrame(&data, D2GetResolution()?1:0); + D2PrintImage(&data, getXPreviousPageBtn()-7, getYPreviousPageBtn()+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, 14 + isDownBtn.nextPage); + D2PrintImage(&data, getXNextPageBtn(), getYNextPageBtn(), -1, 5, 0); + + +//////////////////// POPUP PRINTING //////////////////// + //set MouseX & MouseY + DWORD mx = D2GetMouseX(); + DWORD my = D2GetMouseY(); + + D2SetFont(1); + + if (isOnCloseBtn(mx,my)) // print popup "close" + { + D2PrintPopup(D2GetStringFromIndex(0x1030), getXCloseBtn()+getLCloseBtn()/2, getYCloseBtn()-getHCloseBtn(), WHITE, 1); + } + else if (isOnPreviousPageBtn(mx,my)) //print popup "previous page" + { + lpText = getTranslatedString(STR_PREVIOUS_PAGE); + D2PrintPopup(lpText, getXPreviousPageBtn()+getLPreviousPageBtn()/2, getYPreviousPageBtn()-getHPreviousPageBtn(), WHITE, 1); + } + else if (isOnNextPageBtn(mx,my)) //print popup "next page" + { + lpText = getTranslatedString(STR_NEXT_PAGE); + D2PrintPopup(lpText, getXNextPageBtn()+getLNextPageBtn()/2, getYNextPageBtn()-getHNextPageBtn(), WHITE, 1); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +DWORD STDCALL mouseNewStatsPageTwoLeftDown(sWinMessage* msg) +{ + if (!D2isLODGame()) return -1; + + DWORD x = D2GetMouseX(); + DWORD y = D2GetMouseY(); + if (!isOnStatsPage(x,y)) return 1; + + if (isOnCloseBtn(x,y)) + { + log_msg("push down left button close\n"); + isDownBtn.close = 1; + D2PlaySound(4,0,0,0,0); + } + else if (isOnPreviousPageBtn(x,y)) + { + log_msg("push down left button previous page\n"); + isDownBtn.previousPage = 1; + D2PlaySound(4,0,0,0,0); + } + else if (isOnNextPageBtn(x,y)) + { + log_msg("push down left button next page\n"); + isDownBtn.nextPage = 1; + D2PlaySound(4,0,0,0,0); + } + + freeMessage(msg); + return 0; +} + + +DWORD STDCALL mouseNewStatsPageTwoLeftUp(sWinMessage* msg) +{ + if (!D2isLODGame()) return -1; + + DWORD x = D2GetMouseX(); + DWORD y = D2GetMouseY(); + if (!isOnStatsPage(x,y)) return 1; + + if (isOnCloseBtn(x,y)) + { + log_msg("push up left button close\n"); + if (isDownBtn.close) + D2TogglePage(2,1,0); + } + else if (isOnPreviousPageBtn(x,y)) + { + log_msg("push up left button previous page\n"); + if (isDownBtn.previousPage) + GoPreviousStatPage(); + } + else if (isOnNextPageBtn(x,y)) + { + log_msg("push up left button next page\n"); + if (isDownBtn.nextPage) + GoNextStatPage(); + } + D2CleanStatMouseUp(); + freeMessage(msg); + isDownBtn.all=0; + return 0; +} + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/NewInterfaces.cpp b/PlugY/NewInterfaces.cpp new file mode 100644 index 0000000..66102ba --- /dev/null +++ b/PlugY/NewInterfaces.cpp @@ -0,0 +1,416 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Interface functions + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "globalVariable.h" +#include "updateServer.h" // Install_UpdateServer() +#include "plugYFiles.h" // Install_PlugYImagesFiles() +#include "interface_Stats.h"// Install_InterfaceStats() +#include "newInterfaces.h" +#include "newInterface_Stats.h" +#include "newInterface_StatsPageTwo.h" +#include "newInterface_Runewords.h" +#include + +bool active_newInterfaces=false; +bool selectMainPageOnOpenning=true; +bool printBackgroundOnMainPage=true; + +DWORD bDontPrintBorder=false; + +int selectedPage=0; +int lastPage=0; +int extraHiddenPage=0; + +void GoNextStatPage() +{ + selectedPage++; + if ( selectedPage > lastPage) + selectedPage = 0; +} + +void GoPreviousStatPage() +{ + selectedPage--; + if ( selectedPage < 0 ) + selectedPage = lastPage; +} + +void GoStatPage(int page) +{ + if ( (page >= 0) && (page <= lastPage + (D2GetResolution()? extraHiddenPage : 0)) ) + selectedPage = page; +} + +int GetCurrentPage() +{ + return selectedPage; +} + + +void STDCALL printCustomPage() +{ + if(onRealm) {D2PrintStatsPage();return;} + if ( (selectedPage > 0) && (selectedPage<=lastPage) ) + printNewStatsPageTwo(selectedPage); + else if (selectedPage == lastPage+1) + printRunewordsPage(); + else if (selectedPage == lastPage+2) + printNewStatsPage(); + else + D2PrintStatsPage(); +} + +DWORD STDCALL mouseCustomPageLeftDown(sWinMessage* msg) +{ + if(onRealm) return -1; + if ( (selectedPage > 0) && (selectedPage<=lastPage) ) + return mouseNewStatsPageTwoLeftDown(msg); + else if (selectedPage == lastPage+1) + return mouseRunewordsPageLeftDown(msg); + else if (selectedPage == lastPage+2) + return mouseNewStatsPageLeftDown(msg); + else + return -1; +} + +DWORD STDCALL mouseCustomPageLeftUp(sWinMessage* msg) +{ + if(onRealm) return -1; + if ( (selectedPage > 0) && (selectedPage <= lastPage) ) + return mouseNewStatsPageTwoLeftUp(msg); + else if (selectedPage == lastPage+1) + return mouseRunewordsPageLeftUp(msg); + else if (selectedPage == lastPage+2) + return mouseNewStatsPageLeftUp(msg); + else + return -1; +} + +FCT_ASM ( caller_DontPrintBorder_111 ) + MOV ECX,bDontPrintBorder + TEST ECX,ECX + JE printBorder + MOV bDontPrintBorder,0 + ADD DWORD PTR SS:[ESP],0xBC + RETN +printBorder: + MOV ECX,0x12 + RETN +}} + +FCT_ASM ( caller_DontPrintBorder ) + MOV ECX,bDontPrintBorder + TEST ECX,ECX + JE printBorder + MOV bDontPrintBorder,0 + ADD DWORD PTR SS:[ESP],0xB6 + RETN +printBorder: + MOV ECX,0x12 + RETN +}} + + +FCT_ASM ( caller_mouseCustomPageLeftDown_111 ) + PUSH EAX + PUSH ESI + CALL mouseCustomPageLeftDown + TEST EAX,EAX + POP EAX + JE end_mouseNewPageLDown + JG continue_mouseNewPageLDown + LEA ECX,DWORD PTR DS:[EAX+0x80] + RETN +continue_mouseNewPageLDown: + POP EAX + ADD EAX,0x143 + PUSH EDI + JMP EAX + RETN +end_mouseNewPageLDown: + ADD ESP,4 + POP ESI + POP EBP + POP EBX + RETN 4 +}} + +FCT_ASM ( caller_mouseCustomPageLeftDown ) + PUSH EAX + PUSH EDI + CALL mouseCustomPageLeftDown + TEST EAX,EAX + POP EAX + JE end_mouseNewPageLDown + JG continue_mouseNewPageLDown + LEA ECX,DWORD PTR DS:[EAX+0x80] + RETN +continue_mouseNewPageLDown: + ADD DWORD PTR SS:[ESP],0x152 + RETN +end_mouseNewPageLDown: + ADD ESP,4 + POP EDI + POP ESI + POP EBP + POP EBX + RETN 4 +}} + +FCT_ASM ( caller_mouseCustomPageLeftDown_9 ) + PUSH EAX + PUSH EDI + CALL mouseCustomPageLeftDown + TEST EAX,EAX + POP EAX + JE end_mouseNewPageLDown + JG continue_mouseNewPageLDown + LEA ECX,DWORD PTR DS:[EAX+0x80] + RETN +continue_mouseNewPageLDown: + ADD DWORD PTR SS:[ESP],0x149 + RETN +end_mouseNewPageLDown: + ADD ESP,4 + POP EDI + POP ESI + POP EBP + POP EBX + RETN 4 +}} + + + +FCT_ASM ( caller_mouseCustomPageLeftUp_111 ) + PUSH EBP + CALL mouseCustomPageLeftUp + TEST EAX,EAX + JE end_mouseNewPageLUp + JG continue_mouseNewPageLUp + MOV EAX,DWORD PTR DS:[ptWindowStartX] + MOV EAX,DWORD PTR DS:[EAX] + RETN +continue_mouseNewPageLUp: + ADD DWORD PTR SS:[ESP],0x2C4 + RETN +end_mouseNewPageLUp: + ADD ESP,4 + POP EDI + POP ESI + POP EBP + POP EBX + ADD ESP,8 + RETN 4 +}} + + +FCT_ASM ( caller_mouseCustomPageLeftUp ) + PUSH EBP + CALL mouseCustomPageLeftUp + TEST EAX,EAX + JE end_mouseNewPageLUp + JG continue_mouseNewPageLUp + MOV EAX,DWORD PTR DS:[ptWindowStartX] + MOV EAX,DWORD PTR DS:[EAX] + RETN +continue_mouseNewPageLUp: + ADD DWORD PTR SS:[ESP],0x1AE + RETN +end_mouseNewPageLUp: + ADD ESP,4 + POP EDI + POP ESI + POP EBP + POP EBX + ADD ESP,8 + RETN 4 +}} + + +FCT_ASM ( caller_mouseCustomPageLeftUp_9 ) + PUSH EBP + CALL mouseCustomPageLeftUp + TEST EAX,EAX + JE end_mouseNewPageLUp + JG continue_mouseNewPageLUp + MOV EAX,DWORD PTR DS:[ptWindowStartX] + MOV EAX,DWORD PTR DS:[EAX] + RETN +continue_mouseNewPageLUp: + ADD DWORD PTR SS:[ESP],0x16A + RETN +end_mouseNewPageLUp: + ADD ESP,4 + POP EDI + POP ESI + POP EBP + POP EBX + POP ECX + RETN 4 +}} + + + + + + +FCT_ASM ( caller_resetSelectedPageByToolBar ) + MOV selectedPage,0 + CMP EAX,0x26 + JNZ noJump + ADD DWORD PTR SS:[ESP],0x1F +noJump: + RETN +}} + +FCT_ASM ( caller_resetSelectedPageByKey ) + MOV selectedPage,0 + POP EAX + PUSH EBP + XOR EBP,EBP + CMP EDX,EBP + JMP EAX +}} + + +FCT_ASM ( caller_resetSelectedPage ) + TEST EAX,EAX + SETE DL + JNZ END_resetSelectedPage + CMP ESI,2 + JNZ END_resetSelectedPage + MOV selectedPage,0 +END_resetSelectedPage: + RETN +}} + +void Install_NewInterfaces() +{ + static int isInstalled = false; + if (isInstalled) return; + + Install_UpdateServer(); + Install_PlugYImagesFiles(); + Install_PlugYTxtFiles(); + Install_InterfaceStats(); + + log_msg("Patch D2Client for new custom page interface. (NewInterfaces)\n"); + if ( version_D2Client >= V110 ) + extraHiddenPage=1; + + if (selectMainPageOnOpenning) + { + if ( version_D2Client >= V111 ) + { + //Reset selectedPage variable on opening stats page + mem_seek R7(D2Client, 0000, 0000, 0000, 4B79E, 8F73E, 55E0E, 65F5E); + memt_byte( 0x83, 0xE8 ); // CALL caller_resetSelectedPage + MEMT_REF4( 0x1F7426F8, caller_resetSelectedPageByToolBar); + //6FAFB79E > 83F8 26 CMP EAX,26 + //6FAFB7A1 . 74 1F JE SHORT D2Client.6FAFB7C2 + //6FB3F73E > 83F8 26 CMP EAX,26 + //6FB3F741 . 74 1F JE SHORT D2Client.6FB3F762 + //6FB05E0E > 83F8 26 CMP EAX,26 + //6FB05E11 . 74 1F JE SHORT D2Client.6FB05E32 + //6FB15F5E > 83F8 26 CMP EAX,26 + //6FB15F61 . 74 1F JE SHORT D2Client.6FB15F82 + + mem_seek R7(D2Client, 0000, 0000, 0000, 1E55A, 6A8FA, A31DA, 3C5EA); + memt_byte( 0x55, 0xE8 ); // CALL caller_resetSelectedPage + MEMT_REF4( 0xD53BED33, caller_resetSelectedPageByKey); + //6FACE55A . 55 PUSH EBP + //6FACE55B . 33ED XOR EBP,EBP + //6FACE55D . 3BD5 CMP EDX,EBP + //6FB1A8FA . 55 PUSH EBP + //6FB1A8FB . 33ED XOR EBP,EBP + //6FB1A8FD . 3BD5 CMP EDX,EBP + //6FB531DA . 55 PUSH EBP + //6FB531DB . 33ED XOR EBP,EBP + //6FB531DD . 3BD5 CMP EDX,EBP + //6FAEC5EA . 55 PUSH EBP + //6FAEC5EB . 33ED XOR EBP,EBP + //6FAEC5ED . 3BD5 CMP EDX,EBP + + + //For Toggle fct : (not used for open the stat page) + // mem_seek R7(D2Client, 88B58, 87ED8, 83478, A1FBE, 6571E, 8EF8E, 0000);//((DWORD)D2TogglePage+0x218); + // memt_byte( 0x3B, 0xE8 ); + // MEMT_REF4( 0x393974C5, caller_resetSelectedPage_111); + // memt_byte( 0x28, 0x90 ); // NOP + //6FB51FBE |. 3BC5 CMP EAX,EBP ; Case 2 of switch 6FB51FB8 + //6FB51FC0 |. 74 39 JE SHORT D2Client.6FB51FFB + //6FB51FC2 |. 3928 CMP DWORD PTR DS:[EAX],EBP + //6FB1571E |. 3BC5 CMP EAX,EBP ; Case 2 of switch 6FB15718 + //6FB15720 |. 74 39 JE SHORT D2Client.6FB1575B + //6FB15722 |. 3928 CMP DWORD PTR DS:[EAX],EBP + //6FB3EF8E |. 3BC5 CMP EAX,EBP ; Case 2 of switch 6FB3EF88 + //6FB3EF90 |. 74 39 JE SHORT D2Client.6FB3EFCB + //6FB3EF92 |. 3928 CMP DWORD PTR DS:[EAX],EBP + } else { + //Reset selectedPage variable on opening stats page + mem_seek R7(D2Client, 88B58, 87ED8, 83478, A1FBE, 6571E, 8EF8E, 0000);//((DWORD)D2TogglePage+0x218); + memt_byte( 0x85, 0xE8 ); // CALL caller_resetSelectedPage + MEMT_REF4( 0xC2940FC0, caller_resetSelectedPage); + //6FB23478 |. 85C0 TEST EAX,EAX + //6FB2347A |. 0F94C2 SETE DL + //FOR 1.11 + } + } + + // Print custom page + mem_seek R7(D2Client, 87697, 86A17, 81FAB, A3759, 66B59, 902B9, C3B49); + MEMC_REF4( D2PrintStatsPage, printCustomPage); + //6FB21FAA . E8 B1DDFAFF CALL D2Client.6FACFD60 + //6FB53758 . E8 43F1FDFF CALL D2Client.6FB328A0 + //6FB16B58 |. E8 C3270200 CALL D2Client.6FB39320 + //6FB402B8 |. E8 C3AFFDFF CALL D2Client.6FB1B280 + //6FB73B48 |. E8 5393FFFF CALL D2Client.6FB6CEA0 + + // Don't print Border + mem_seek R7(D2Client, 58EF6, 58EF6, 5F4C6, 2D366, B5A46, 82166, 271C6); + memt_byte( 0xB9, 0xE8 ); // CALL caller_DontPrintBorder + MEMT_REF4( 0x00000012, version_D2Client >= V111 ? caller_DontPrintBorder_111 : caller_DontPrintBorder); + //6FAFF4C6 > B9 12000000 MOV ECX,12 + //6FADD366 |. B9 12000000 MOV ECX,12 + //6FB65A46 |. B9 12000000 MOV ECX,12 + //6FB32166 |. B9 12000000 MOV ECX,12 + //6FAD71C6 |. B9 12000000 MOV ECX,12 + + // Manage mouse down (Play sound) + mem_seek R7(D2Client, 2A9DC, 2A9CC, 312A5, 82736, 891B6, 6B116, BCD36); + memt_byte( 0x8D, 0xE8 ); // CALL + MEMT_REF4( 0x00008088, version_D2Client >= V111 ? caller_mouseCustomPageLeftDown_111 : version_D2Client == V110 ? caller_mouseCustomPageLeftDown : caller_mouseCustomPageLeftDown_9); + memt_byte( 0x00, 0x90 ); // NOP + //6FAD12A5 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80] + //6FB32736 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80] + //6FB391B6 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80] + //6FB1B116 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80] + //6FB6CD36 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80] + + // Manage mouse up + mem_seek R7(D2Client, 2ABBB, 2ABAB, 3148D, 836D9, 8A159, 6C0B9, BDCB9); + memt_byte( 0xA1, 0xE8 ); // CALL caller_mouseCustomPageLeftUp + MEMT_REF4( ptWindowStartX, version_D2Client >= V111 ? caller_mouseCustomPageLeftUp_111 : version_D2Client == V110 ? caller_mouseCustomPageLeftUp : caller_mouseCustomPageLeftUp_9); + //6FAD148D . A1 48A7BB6F MOV EAX,DWORD PTR DS:[6FBBA748] + //6FB336D9 . A1 24BDBC6F MOV EAX,DWORD PTR DS:[6FBCBD24] + //6FB3A159 . A1 F8BEBC6F MOV EAX,DWORD PTR DS:[6FBCBEF8] + //6FB1C0B9 . A1 28BDBC6F MOV EAX,DWORD PTR DS:[6FBCBD28] + //6FB6DCB9 . A1 A0B9BC6F MOV EAX,DWORD PTR DS:[6FBCB9A0] + + + // open page : 6FB23515 |> 892CB5 A8A6BB6>MOV DWORD PTR DS:[ESI*4+6FBBA6A8],EBP + //6FB2347D |. 8914B5 A8A6BB6F MOV DWORD PTR DS:[ESI*4+6FBBA6A8],EDX + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/OthersFeatures.cpp b/PlugY/OthersFeatures.cpp new file mode 100644 index 0000000..c9e1afe --- /dev/null +++ b/PlugY/OthersFeatures.cpp @@ -0,0 +1,131 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Others features. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" + +bool active_othersFeatures = false; + + +/* + // Remove protect on the save file .d2s + mem_seek( offset_D2Game + 0x77080);//6FC8DD5E-6FAA0000 + memt_byte( 0x74, 0xEB ); // JMP SHORT D2Game.6FC8DD6D + //6FC8DD5E 74 0D JE SHORT D2Game.6FC8DD6D +*/ + +/* +void Install_ChangeResolution() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2gfx for . (ChangeResolution)\n"); + + // execute if it's our packet else continue + mem_seek( offset_D2Client + 0x23ED);//6FAA23EC-6FAA0000 + memt_dword( 0x280, 0x400 ); + //6FAA23EC B8 80020000 MOV EAX,280 ; Case 0 of switch 6FAA23C2 + mem_seek( offset_D2Client + 0x23F7);//6FAA23F1-6FAA0000 + memt_dword( 0x1E0, 0x300 ); + //6FAA23F1 C705 F040B76F E0>MOV DWORD PTR DS:[6FB740F0],1E0 + + // change resolution + mem_seek R7(D2gfx, 4B91, 4B91, 4B61, 0000, 0000, 0000, 0000); + memt_dword( 0x280, 0x400 ); + //6FA74B5D > C74424 14 8002>MOV DWORD PTR SS:[ESP+14],280 ; Case 0 of switch 6FA74B45 + mem_seek R7(D2gfx, 4B96, 4B96, 4B66, 0000, 0000, 0000, 0000); + memt_dword( 0x1E0, 0x300 ); + //6FA74B65 . B8 E0010000 MOV EAX,1E0 + + // refresh size + mem_seek( offset_D2Gdi + 0x118F);//6F831189-6F830000 + memt_dword( 0x280, 0x400 ); + //6F831189 |> C705 7CC0836F >MOV DWORD PTR DS:[6F83C07C],280 + mem_seek( offset_D2Gdi + 0x1199);//6F831193-6F830000 + memt_dword( 0x1E0, 0x300 ); + //6F831193 |. C705 8CC4836F >MOV DWORD PTR DS:[6F83C48C],1E0 + + log_msg("\n"); + + isInstalled = true; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +DWORD SetDisabledStat(Unit* ptItem, Stats* ptStats, DWORD disabled) +{ + if (!ptItem || !ptStats) + return 0; + if (disabled) + { + if (!ptStats->isDisabled) + { + D2PreUpdateDisabledStat(ptStats); + ptStats->isDisabled = 1; + D2UpdateDisabledStat(ptItem->ptStats,ptStats,1); + return 1; + } + } else if (ptStats->isDisabled) + { + D2PreUpdateDisabledStat(ptStats); + ptStats->isDisabled = 0; + D2UpdateDisabledStat(ptItem->ptStats,ptStats,1); + } + return 0; +} + +void STDCALL Test2Fct (Unit* ptChar, Unit* ptItem) +{ + SetDisabledStat(ptItem, ptItem->ptStats->ptStatsList, 0);//(DWORD)(rand()/(RAND_MAX+1.0)*2)); +} + +FCT_ASM ( caller_Test2 ) + PUSH EDI //ptItem + PUSH ESI //ptChar + CALL Test2Fct + POP ECX + PUSH EBX + MOV EAX,DWORD PTR DS:[ESI] + XOR EBX,EBX + JMP ECX +}} + +void Install_Test2() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Game. (Test)\n"); + + // Test + mem_seek( offset_D2Game + 0x1253C);//6FC4253C-6FC30000 + memt_byte( 0x8B, 0xE8 ); // CALL caller_BnetBtnPress + MEMT_REF4( 0xDB335306, caller_Test2); + //6FC4253C |> 8B06 MOV EAX,DWORD PTR DS:[ESI] + //6FC4253E |. 53 PUSH EBX + //6FC4253F |. 33DB XOR EBX,EBX + isInstalled = true; +}*/ +/////////////////////////////////////////////////////////////////////////////////////////////// + + +void Install_OthersFeatures() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch. (OthersFeatures)\n"); + +// Install_ChangeResolution(); +// Install_Test(); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/Parameters.cpp b/PlugY/Parameters.cpp new file mode 100644 index 0000000..af78253 --- /dev/null +++ b/PlugY/Parameters.cpp @@ -0,0 +1,818 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Loading parameters from ini file. + +=================================================================*/ + +// Core Class Headers +#include +#include +#include +#include "common.h" +#include "error.h" +#include "parameters.h" // loadParameters() +#include "D2functions.h" +#include "INIfile.h" + + +#define PARAMETERS_FILENAME "PlugY.ini" +#define PARAM_FIXED_FILENAME "PlugY\\PlugYFixed.ini" +#define PARAM_DEFAULT_FILENAME "PlugY\\PlugYDefault.ini" + +#define BUFSIZE 0x400 + +#include "statsPoints.h" +#include "mainScreen.h" +#include "skillPerLevelUp.h" +#include "statPerLevelUp.h" +#include "savePath.h" +#include "bigStash.h" +#include "skillsPoints.h" +#include "infinityStash.h" +#include "othersFeatures.h" +#include "newInterfaces.h" +#include "worldEvent.h" +#include "uberQuest.h" +#include "extraOptions.h" +#include "commands.h" +#include "language.h" +extern bool displayGreenSetItemIncludeSharedStash; + + +char* modDataDirectory = "PlugY"; +bool active_plugin = true; +bool active_DisableBattleNet = true; +bool active_CheckMemory = true; +bool active_D2Mod = false; +char* dllFilenames; + +TargetMod selectModParam = MOD_NO; + + +const char* S_GENERAL = "GENERAL"; +const char* S_dllFilenames = "DllToLoad"; +const char* S_dllFilenames2 = "DllToLoad2"; +const char* S_active_plugin = "ActivePlugin"; +const char* S_active_DisableBattleNet = "DisableBattleNet"; +const char* S_active_logFile = "ActiveLogFile"; +const char* S_active_CheckMemory = "ActiveCheckMemory"; +const char* S_active_Commands = "ActiveCommands"; +const char* S_active_othersFeatures = "ActiveAllOthersFeatures"; + +const char* S_LANGUAGE = "LANGUAGE"; +const char* S_active_ChangeLanguage = "ActiveChangeLanguage"; +const char* S_selectedLanguage = "SelectedLanguage"; +const char* S_active_LanguageManagement = "ActiveLanguageManagement"; +const char* S_defaultLanguage = "DefaultLanguage"; +const char* S_availableLanguages = "AvailableLanguages"; + +const char* S_SAVEPATH = "SAVEPATH"; +const char* S_active_changingSavePath = "ActiveSavePathChange"; +const char* S_savePath = "SavePath"; + +const char* S_MAIN_SCREEN = "MAIN SCREEN"; +const char* S_active_VersionTextChange = "ActiveVersionTextChange"; +const char* S_active_VersionTextChanges = "ActiveVersionTextChanges"; +const char* S_versionText = "VersionText"; +const char* S_modVersionColor = "ColorOfVersionText"; +const char* S_active_PrintPlugYVersion = "ActivePrintPlugYVersion"; +const char* S_colorOfPlugYVersion = "ColorOfPlugYVersion"; + +const char* S_STASH = "STASH"; +const char* S_active_multiPageStash = "ActiveMultiPageStash"; +const char* S_maxSelfPages = "MaxPersonnalPages"; +const char* S_nbPagesPerIndex = "NbPagesPerIndex"; +const char* S_nbPagesPerIndex2 = "NbPagesPerIndex2"; +const char* S_active_sharedStash = "ActiveSharedStash"; +const char* S_maxSharedPages = "MaxSharedPages"; +const char* S_sharedStashFilename = "SharedStashFilename"; +const char* S_separateHardSoftStash = "SeparateHardcoreStash"; +const char* S_active_bigStash = "ActiveBigStash"; +const char* S_displaySharedSetItemNameInGreen = "DisplaySharedSetItemNameInGreen"; +const char* S_active_sharedGold = "ActiveSharedGold"; + + +const char* S_posXPreviousBtn = "PosXPreviousBtn"; +const char* S_posYPreviousBtn = "PosYPreviousBtn"; +const char* S_posXNextBtn = "PosXNextBtn"; +const char* S_posYNextBtn = "PosYNextBtn"; +const char* S_posXSharedBtn = "PosXSharedBtn"; +const char* S_posYSharedBtn = "PosYSharedBtn"; +const char* S_posXPreviousIndexBtn = "PosXPreviousIndexBtn"; +const char* S_posYPreviousIndexBtn = "PosYPreviousIndexBtn"; +const char* S_posXNextIndexBtn = "PosXNextIndexBtn"; +const char* S_posYNextIndexBtn = "PosYNextIndexBtn"; +const char* S_posXPutGoldBtn = "PosXPutGoldBtn"; +const char* S_posYPutGoldBtn = "PosYPutGoldBtn"; +const char* S_posXTakeGoldBtn = "PosXTakeGoldBtn"; +const char* S_posYTakeGoldBtn = "PosYTakeGoldBtn"; + +const char* S_STATS_POINTS = "STATS POINTS"; +const char* S_active_StatsPoints = "ActiveStatsUnassignment"; +const char* S_keyUsedForUnassignStatPoint = "KeyUsed"; +const char* S_active_StatsShiftClickLimit = "ActiveShiftClickLimit"; +const char* S_limitValueToShiftClick = "LimitValueToShiftClick"; + +const char* S_SKILL_ON_LEVEL_UP = "SKILL ON LEVEL UP"; +const char* S_active_SkillPerLevelUpChange = "ActiveSkillPerLevelUp"; +const char* S_skillPerLevelUp = "SkillPerLevelUp"; + +const char* S_STAT_ON_LEVEL_UP = "STAT ON LEVEL UP"; +const char* S_active_StatPerLevelUpChange = "ActiveStatPerLevelUp"; +const char* S_statPerLevelUp = "StatPerLevelUp"; + +const char* S_WORLD_EVENT = "WORLD EVENT"; +const char* S_active_WorldEvent = "ActiveWorldEvent"; +const char* S_showSOJSoldCounterInAllDiff = "ShowCounterInAllDifficulty"; +const char* S_itemsToSell = "ItemsToSell"; +const char* S_worldEventmonsterID = "MonsterID"; +const char* S_valueOfOwnSOJSold = "OwnSOJSoldChargeFor"; +const char* S_valueInitSOJSoldMin = "InititalSOJSoldMin"; +const char* S_valueInitSOJSoldDelta = "InititalSOJSoldMax"; +const char* S_triggerAtSolJSoldMin = "TriggerAtEachSOJSoldMin"; +const char* S_triggerAtSolJSoldDelta = "TriggerAtEachSOJSoldMax"; +const char* S_active_AutomaticSell = "ActiveAutoSell"; +const char* S_timeBeforeAutoSellMin = "TimeBeforeAutoSellMin"; +const char* S_timeBeforeAutoSellDelta = "TimeBeforeAutoSellMax"; + +const char* S_UBER_QUEST = "UBER QUEST"; +const char* S_active_UberQuest = "ActiveUberQuest"; + +const char* S_SKILLS_POINTS = "SKILLS POINTS"; +const char* S_active_SkillsPoints = "ActiveSkillsUnassignment"; +const char* S_unassignSkillsPointsOneByOne = "ActiveSkillsUnassignmentOneByOne"; +const char* S_posXUnassignSkillBtn = "PosXUnassignSkillBtn"; +const char* S_posYUnassignSkillBtn = "PosYUnassignSkillBtn"; + +const char* S_INTERFACE = "INTERFACE"; +const char* S_active_newInterfaces = "ActiveNewStatsInterface"; +const char* S_selectMainPageOnOpenning = "SelectMainPageOnOpenning"; +const char* S_printBackgroundOnMainPage = "PrintButtonsBackgroundOnMainStatsPage"; + +const char* S_EXTRA = "EXTRA"; +const char* S_active_alwaysRegenMapInSP = "AlwaysRegenMapInSP"; +const char* S_nbPlayersCommandByDefault = "NBPlayersByDefault"; +const char* S_active_DisplayItemLevel = "ActiveDisplayItemLevel"; +const char* S_active_RunLODs = "ActiveLaunchAnyNumberOfLOD"; +const char* S_active_AlwaysDisplayLifeMana = "AlwaysDisplayLifeAndManaValues"; +const char* S_active_EnabledTXTFilesWithMSExcel= "EnabledTXTFilesWhenMSExcelOpenIt"; +const char* S_active_DisplayBaseStatsValue = "ActiveDisplayBaseStatsValue"; +const char* S_active_LadderRunewords = "ActiveLadderRunewords"; +const char* S_active_EnabledCowPortalWhenCowKingWasKill = "ActiveCowPortalWhenCowKingWasKilled"; + +const char* S_DLL = "DLL:\t"; +const char* S_DEFAULT = "DEFAULT:"; +const char* S_USER = "USER:\t"; +const char* S_FIXED = "FIXED:\t"; + + +#define GET_PRIVATE_PROFILE_STRING(S,F,D)\ +if (!iniFixedFile->GetPrivateProfileString(S, F, NULL, buffer, maxSize)) \ +if (!iniFile->GetPrivateProfileString(S, F, NULL, buffer, maxSize)) \ +if (!iniDefaultFile->GetPrivateProfileString(S, F, D, buffer, maxSize)) \ + log_msg(S_DLL); \ +else log_msg(S_DEFAULT); \ +else log_msg(S_USER); \ +else log_msg(S_FIXED) + +#define GET_PRIVATE_PROFILE_STRING2(S,F,D)\ +if (!iniFile->GetPrivateProfileString(S, F, NULL, buffer, maxSize)) \ +if (!iniDefaultFile->GetPrivateProfileString(S, F, D, buffer, maxSize)) \ + log_msg(S_DLL); \ +else log_msg(S_DEFAULT); \ +else log_msg(S_USER) + + +#define GET_PRIVATE_PROFILE_STRING3(S,F,D)\ +if (!iniFile->GetPrivateProfileString(S, F, NULL, buffer, maxSize)) \ +if (!iniFixedFile->GetPrivateProfileString(S, F, NULL, buffer, maxSize)) \ +if (!iniDefaultFile->GetPrivateProfileString(S, F, D, buffer, maxSize)) \ + log_msg(S_DLL); \ +else log_msg(S_DEFAULT); \ +else log_msg(S_FIXED); \ +else log_msg(S_USER) + + +void init_ActivePlugin(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + iniFixedFile->GetPrivateProfileString(S_GENERAL, S_active_plugin, "0", buffer, maxSize); + active_plugin = atoi(buffer) != 0; + if (!active_plugin) + { + GET_PRIVATE_PROFILE_STRING2(S_GENERAL, S_active_plugin, "1"); + active_plugin = atoi(buffer) != 0; + } else log_msg(S_FIXED); + log_msg("active_plugin\t\t\t\t= %u\n", active_plugin); +} + +void init_General(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_GENERAL, S_active_DisableBattleNet, "0"); + active_DisableBattleNet = atoi(buffer) != 0; + log_msg("active_DisableBattleNet\t\t\t\t= %d\n", active_DisableBattleNet); + + GET_PRIVATE_PROFILE_STRING(S_GENERAL, S_active_logFile, "0"); + active_logFile = atoi(buffer)+1; + log_msg("active_logFile\t\t\t\t= %d\n", active_logFile-1); + + GET_PRIVATE_PROFILE_STRING(S_GENERAL, S_active_Commands, "0"); + active_Commands = atoi(buffer) != 0; + log_msg("active_Commands\t\t\t\t= %d\n", active_Commands); + + GET_PRIVATE_PROFILE_STRING(S_GENERAL, S_active_CheckMemory, "1"); + active_CheckMemory = atoi(buffer) != 0; + log_msg("active_CheckMemory\t\t\t= %d\n", active_CheckMemory); + + GET_PRIVATE_PROFILE_STRING(S_GENERAL, S_active_othersFeatures, "0"); + active_othersFeatures = atoi(buffer) != 0; + log_msg("active_othersFeatures\t\t= %u\n", active_othersFeatures); + + GET_PRIVATE_PROFILE_STRING(S_GENERAL,S_dllFilenames,""); + strcat(buffer,"|"); + char* buf = &buffer[strlen(buffer)]; + if (!iniFixedFile->GetPrivateProfileString(S_GENERAL, S_dllFilenames2, NULL, buf, maxSize)) + if (!iniFile->GetPrivateProfileString(S_GENERAL, S_dllFilenames2, NULL, buf, maxSize)) + iniDefaultFile->GetPrivateProfileString(S_GENERAL, S_dllFilenames2, NULL, buf, maxSize); + dllFilenames = (char*)D2FogMemAlloc(strlen(buffer)+1,__FILE__,__LINE__,0); + strcpy(dllFilenames,buffer); + + log_msg("dllFilenames\t\t\t\t= %s\n",dllFilenames); + + log_msg("\n"); +} + +void init_ActiveLanguage(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_LANGUAGE, S_active_ChangeLanguage, "0"); + active_ChangeLanguage = atoi(buffer) != 0; + log_msg("active_ChangeLanguage\t\t= %d\n", active_ChangeLanguage); + + if (active_ChangeLanguage) + { + GET_PRIVATE_PROFILE_STRING(S_LANGUAGE, S_selectedLanguage, "ENG"); + strupr(buffer); + switch (*(DWORD*)buffer) + { + case BIN('E','N','G',0) : selectedLanguage=LNG_ENG;break; + case BIN('E','S','P',0) : selectedLanguage=LNG_ESP;break; + case BIN('D','E','U',0) : selectedLanguage=LNG_DEU;break; + case BIN('F','R','A',0) : selectedLanguage=LNG_FRA;break; + case BIN('P','O','R',0) : selectedLanguage=LNG_POR;break; + case BIN('I','T','A',0) : selectedLanguage=LNG_ITA;break; + case BIN('J','P','N',0) : selectedLanguage=LNG_JPN;break; + case BIN('K','O','R',0) : selectedLanguage=LNG_KOR;break; + case BIN('S','I','N',0) : selectedLanguage=LNG_SIN;break; + case BIN('C','H','I',0) : selectedLanguage=LNG_CHI;break; + case BIN('P','O','L',0) : selectedLanguage=LNG_POL;break; + case BIN('R','U','S',0) : selectedLanguage=LNG_RUS;break; + default: active_ChangeLanguage = false; + log_msg("active_ChangeLanguage\t\t= %d (because bad language string : %s)\n", active_ChangeLanguage, buffer); + } + } + if (active_ChangeLanguage) + log_msg("selectedLanguage\t\t\t= %u\n", selectedLanguage); + + + GET_PRIVATE_PROFILE_STRING(S_LANGUAGE, S_active_LanguageManagement, "0"); + active_LanguageManagement = atoi(buffer) != 0; + log_msg("active_LanguageManagement\t= %d\n", active_LanguageManagement); + + if (active_LanguageManagement) + { + GET_PRIVATE_PROFILE_STRING(S_LANGUAGE, S_defaultLanguage, "ENG"); + strupr(buffer); + switch (*(DWORD*)buffer) + { + case BIN('E','N','G',0) : defaultLanguage=LNG_ENG;break; + case BIN('E','S','P',0) : defaultLanguage=LNG_ESP;break; + case BIN('D','E','U',0) : defaultLanguage=LNG_DEU;break; + case BIN('F','R','A',0) : defaultLanguage=LNG_FRA;break; + case BIN('P','O','R',0) : defaultLanguage=LNG_POR;break; + case BIN('I','T','A',0) : defaultLanguage=LNG_ITA;break; + case BIN('J','P','N',0) : defaultLanguage=LNG_JPN;break; + case BIN('K','O','R',0) : defaultLanguage=LNG_KOR;break; + case BIN('S','I','N',0) : defaultLanguage=LNG_SIN;break; + case BIN('C','H','I',0) : defaultLanguage=LNG_CHI;break; + case BIN('P','O','L',0) : defaultLanguage=LNG_POL;break; + case BIN('R','U','S',0) : defaultLanguage=LNG_RUS;break; + default: defaultLanguage=LNG_ENG; + } + log_msg("defaultLanguage\t\t\t= %d\n", defaultLanguage); + + GET_PRIVATE_PROFILE_STRING(S_LANGUAGE, S_availableLanguages, "ENG|ESP|DEU|FRA|POR|ITA|JPN|KOR|SIN|CHI|POL|RUS"); + availableLanguages.all = 0; + strupr(buffer); + char* curString = strtok(buffer,"|"); + while (curString) + { + switch (*(DWORD*)curString) + { + case BIN('E','N','G',0) : availableLanguages.eng=1;break; + case BIN('E','S','P',0) : availableLanguages.esp=1;break; + case BIN('D','E','U',0) : availableLanguages.deu=1;break; + case BIN('F','R','A',0) : availableLanguages.fra=1;break; + case BIN('P','O','R',0) : availableLanguages.por=1;break; + case BIN('I','T','A',0) : availableLanguages.ita=1;break; + case BIN('J','P','N',0) : availableLanguages.jpn=1;break; + case BIN('K','O','R',0) : availableLanguages.kor=1;break; + case BIN('S','I','N',0) : availableLanguages.sin=1;break; + case BIN('C','H','I',0) : availableLanguages.chi=1;break; + case BIN('P','O','L',0) : availableLanguages.pol=1;break; + case BIN('R','U','S',0) : availableLanguages.rus=1;break; + default:; + } + curString=strtok(NULL,"|"); + } + log_msg("availableLanguage.all\t\t= 0x%04X\n\n",availableLanguages.all); + } + log_msg("\n"); +} + + +void init_SavePath(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING3(S_SAVEPATH, S_active_changingSavePath, "0"); + active_changingSavePath = atoi(buffer) != 0; + log_msg("active_changingSavePath\t\t= %u\n", active_changingSavePath); + + if (active_changingSavePath) + { + int curSize = 0; + int start = 0; + GET_PRIVATE_PROFILE_STRING3(S_SAVEPATH, S_savePath, "Save\\"); + + while (buffer[curSize]) + curSize++; + + if ( (curSize>0) && buffer[curSize-1] != (BYTE)'\\') + { + buffer[curSize++] = (BYTE)'\\'; + buffer[curSize]='\0'; + } + while (buffer[start] == '\\') + start++; + + if (!buffer[start]) + { + active_changingSavePath = false; + log_msg("active_changingSavePath\t\t= %u (no valid savePath)\n\n", active_changingSavePath); +// log_msg("\tsavePath\t\t\t= %s\n", savePath); + return; + } + + if (buffer[start+1]!=':') + { + char buf[MAX_PATH]; + buf[0]=NULL; + D2FogGetInstallPath(buf,MAX_PATH); + savePath = (char*)D2FogMemAlloc(strlen(buf) + curSize - start + 1,__FILE__,__LINE__,0); + strcpy(savePath,buf); + strcat(savePath,&buffer[start]); + } else { + savePath = (char*)D2FogMemAlloc(curSize-start+1,__FILE__,__LINE__,0); + strcpy(savePath,&buffer[start]); + } + log_msg("savePath\t\t\t\t\t= %s\n", savePath); + } + log_msg("\n"); +} + + +void init_VersionText(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_MAIN_SCREEN, S_active_VersionTextChange, "0"); + active_VersionTextChange = atoi(buffer) != 0; + log_msg("active_VersionTextChange\t= %u\n", active_VersionTextChange); + + if (active_VersionTextChange) + { + GET_PRIVATE_PROFILE_STRING(S_MAIN_SCREEN, S_versionText, versionText); + if (!buffer[0]) + { + switch(version_D2Game) + { + case V109b: strcpy(buffer, "v 1.09b");break; + case V109d: strcpy(buffer, "v 1.09d");break; + //case V110: strcpy(buffer, "v 1.10");break; + //case V111: strcpy(buffer, "v 1.11");break; + case V111b: strcpy(buffer, "v 1.11b");break; + default: + active_VersionTextChange=0; + } + } + + versionText = (char*)D2FogMemAlloc(strlen(buffer)+1,__FILE__,__LINE__,0); + strcpy(versionText,buffer); + log_msg("versionText\t\t\t\t\t= %s\n", versionText); + + GET_PRIVATE_PROFILE_STRING(S_MAIN_SCREEN, S_modVersionColor, "0"); + modVersionColor = atoi(buffer); + log_msg("modVersionColor\t\t\t\t= %u\n", modVersionColor); + } + + GET_PRIVATE_PROFILE_STRING(S_MAIN_SCREEN, S_active_PrintPlugYVersion, "1"); + active_PrintPlugYVersion = atoi(buffer) != 0; + log_msg("active_PrintPlugYVersion\t= %u\n", active_PrintPlugYVersion); + + + if (active_PrintPlugYVersion) + { + GET_PRIVATE_PROFILE_STRING(S_MAIN_SCREEN, S_colorOfPlugYVersion, "4"); + colorOfPlugYVersion = atoi(buffer); + log_msg("colorOfPlugYVersion\t\t\t= %u\n", colorOfPlugYVersion); + } + + log_msg("\n"); +} + +void init_Stash(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_STASH, S_active_bigStash, "0"); + active_bigStash = atoi(buffer) != 0; + log_msg("active_bigStash\t\t\t\t= %u\n", active_bigStash); + + GET_PRIVATE_PROFILE_STRING(S_STASH, S_active_multiPageStash, "0"); + active_multiPageStash = atoi(buffer) != 0; + log_msg("active_multiPageStash\t\t= %u\n", active_multiPageStash); + + if (active_multiPageStash) + { + active_PlayerCustomData = true; +// log_msg("active_PlayerCustomData\t\t= %d\n", active_PlayerCustomData); + + GET_PRIVATE_PROFILE_STRING(S_STASH, S_maxSelfPages, "0"); + maxSelfPages = atoi(buffer) - 1; + log_msg("maxSelfPages\t\t\t\t= %u\n", maxSelfPages); + + GET_PRIVATE_PROFILE_STRING(S_STASH, S_nbPagesPerIndex, "10"); + nbPagesPerIndex = atoi(buffer); + if (!nbPagesPerIndex) nbPagesPerIndex=10; + log_msg("nbPagesPerIndex\t\t\t\t= %u\n", nbPagesPerIndex); + + GET_PRIVATE_PROFILE_STRING(S_STASH, S_nbPagesPerIndex2, "100"); + nbPagesPerIndex2 = atoi(buffer); + if (!nbPagesPerIndex2) nbPagesPerIndex2=100; + log_msg("nbPagesPerIndex2\t\t\t= %u\n", nbPagesPerIndex2); + + GET_PRIVATE_PROFILE_STRING(S_STASH, S_active_sharedStash, "0"); + active_sharedStash = atoi(buffer) != 0; + log_msg("active_sharedStash\t\t\t= %u\n", active_sharedStash); + + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posXPreviousBtn,"-1"); + posXPreviousBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posYPreviousBtn,"-1"); + posYPreviousBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posXNextBtn,"-1"); + posXNextBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posYNextBtn,"-1"); + posYNextBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posXSharedBtn,"-1"); + posXSharedBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posYSharedBtn,"-1"); + posYSharedBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posXPreviousIndexBtn,"-1"); + posXPreviousIndexBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posYPreviousIndexBtn,"-1"); + posYPreviousIndexBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posXNextIndexBtn,"-1"); + posXNextIndexBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posYNextIndexBtn,"-1"); + posYNextIndexBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posXPutGoldBtn,"-1"); + posXPutGoldBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posYPutGoldBtn,"-1"); + posYPutGoldBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posXTakeGoldBtn,"-1"); + posXTakeGoldBtn = atoi(buffer); + GET_PRIVATE_PROFILE_STRING(S_STASH, S_posYTakeGoldBtn,"-1"); + posYTakeGoldBtn = atoi(buffer); + + log_msg("\t Buttons Positions: %d %d %d %d %d %d %d %d %d %d\n",posXPreviousBtn,posYPreviousBtn,posXNextBtn,posYNextBtn,posXSharedBtn,posYSharedBtn,posXPreviousIndexBtn,posYPreviousIndexBtn,posXNextIndexBtn,posYNextIndexBtn); + + } + + if (active_sharedStash) + { + GET_PRIVATE_PROFILE_STRING(S_STASH, S_maxSharedPages, "0"); + maxSharedPages = atoi(buffer) - 1; + log_msg("maxSharedPages\t\t\t\t= %u\n", maxSharedPages); + + GET_PRIVATE_PROFILE_STRING(S_STASH, S_sharedStashFilename, "SharedStashSave"); + sharedStashFilename = (char*)D2FogMemAlloc(strlen(buffer)+1,__FILE__,__LINE__,0); + strcpy(sharedStashFilename, buffer); + log_msg("sharedStashFilename\t\t\t= %s\n", sharedStashFilename); + + GET_PRIVATE_PROFILE_STRING(S_STASH, S_separateHardSoftStash, "1"); + separateHardSoftStash = atoi(buffer) != 0; + log_msg("separateHardSoftStash\t\t= %u\n", separateHardSoftStash); + + GET_PRIVATE_PROFILE_STRING(S_STASH, S_displaySharedSetItemNameInGreen, "1"); + displaySharedSetItemNameInGreen = atoi(buffer) != 0; + log_msg("displaySharedSetItemNameInGreen = %u\n", displaySharedSetItemNameInGreen); + + GET_PRIVATE_PROFILE_STRING(S_STASH, S_active_sharedGold, "1"); + active_sharedGold = atoi(buffer) != 0; + log_msg("active_sharedGold\t\t\t= %u\n", active_sharedGold); + } + + log_msg("\n"); +} + +void init_StatsPoints(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_STATS_POINTS, S_active_StatsPoints, "0"); + active_StatsPoints = atoi(buffer) != 0; + log_msg("active_StatsPoints\t\t\t= %u\n", active_StatsPoints); + + if (active_StatsPoints) + { + GET_PRIVATE_PROFILE_STRING(S_STATS_POINTS, S_keyUsedForUnassignStatPoint, "18"); + keyUsedForUnassignStatPoint = atoi(buffer); + log_msg("keyUsedForUnassignStatPoint\t= %u (0x%x)\n", keyUsedForUnassignStatPoint); + } + + GET_PRIVATE_PROFILE_STRING(S_STATS_POINTS, S_active_StatsShiftClickLimit, "0"); + active_StatsShiftClickLimit = atoi(buffer) != 0; + log_msg("active_StatsShiftClickLimit\t= %u\n", active_StatsShiftClickLimit); + + if (active_StatsShiftClickLimit) + { + GET_PRIVATE_PROFILE_STRING(S_STATS_POINTS, S_limitValueToShiftClick, "5"); + limitValueToShiftClick = atoi(buffer); + log_msg("limitValueToShiftClick\t\t= %u\n", limitValueToShiftClick); + } + log_msg("\n"); +} + + +void init_StatPerLevelUp(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_STAT_ON_LEVEL_UP, S_active_StatPerLevelUpChange, "0"); + active_StatPerLevelUpChange = atoi(buffer) != 0; + log_msg("active_StatPerLevelUpChange\t= %u\n", active_StatPerLevelUpChange); + + if (active_StatPerLevelUpChange) + { + GET_PRIVATE_PROFILE_STRING(S_STAT_ON_LEVEL_UP, S_statPerLevelUp, "5"); + statPerLevelUp = atoi(buffer); + log_msg("statPerLevelUp\t\t\t\t= %u\n", statPerLevelUp); + } + log_msg("\n"); +} + +void init_SkillsPoints(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_SKILLS_POINTS, S_active_SkillsPoints, "0"); + active_SkillsPoints = atoi(buffer) != 0; + log_msg("active_SkillsPoints\t\t\t= %d\n", active_SkillsPoints); + + GET_PRIVATE_PROFILE_STRING(S_SKILLS_POINTS, S_unassignSkillsPointsOneByOne, "0"); + unassignSkillsPointsOneByOne = atoi(buffer) != 0; + log_msg("unassignSkillsPointsOneByOne\t\t\t= %d\n", unassignSkillsPointsOneByOne); + if (unassignSkillsPointsOneByOne) + { + active_SkillsPoints = true; + log_msg("active_SkillsPoints\t\t\t= %d\n", active_SkillsPoints); + } + + GET_PRIVATE_PROFILE_STRING(S_SKILLS_POINTS, S_posXUnassignSkillBtn,"-1"); + posXUnassignSkillBtn = atoi(buffer); + log_msg("posXUnassignSkillBtn\t\t\t= %d\n", posXUnassignSkillBtn); + + GET_PRIVATE_PROFILE_STRING(S_SKILLS_POINTS, S_posYUnassignSkillBtn,"-1"); + posYUnassignSkillBtn = atoi(buffer); + log_msg("posXUnassignSkillBtn\t\t\t= %d\n", posYUnassignSkillBtn); + + log_msg("\n"); +} + +void init_SkillPerLevelUp(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_SKILL_ON_LEVEL_UP, S_active_SkillPerLevelUpChange, "0"); + active_SkillPerLevelUpChange = atoi(buffer) != 0; + log_msg("active_SkillPerLevelUpChange= %u\n", active_SkillPerLevelUpChange); + + if (active_SkillPerLevelUpChange) + { + GET_PRIVATE_PROFILE_STRING(S_SKILL_ON_LEVEL_UP, S_skillPerLevelUp, "1"); + skillPerLevelUp = atoi(buffer); + log_msg("skillPerLevelUp\t\t\t\t= %u\n", skillPerLevelUp); + } + log_msg("\n"); +} + + +void init_WorldEvent(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_active_WorldEvent, "0"); + active_WorldEvent = atoi(buffer) != 0; + if (active_WorldEvent && ((version_D2Game == V109b) || (version_D2Game == V109d)) ) { + active_WorldEvent = 0; + log_msg("active_WorldEvent\t\t\t= %d (Warning : this feature is only for LoD version 1.10 or higher, so it's automatically disabled)\n", active_WorldEvent); + } else + log_msg("active_WorldEvent\t\t\t= %d\n", active_WorldEvent); + + if (active_WorldEvent) + { + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_showSOJSoldCounterInAllDiff, "0"); + showSOJSoldCounterInAllDiff = atoi(buffer); + log_msg("showSOJSoldCounterInAllDiff\t= %d\n", showSOJSoldCounterInAllDiff); + + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_itemsToSell, itemsToSell); + if (strlen(buffer)>50) buffer[50]='\0'; + itemsToSell = (char*)D2FogMemAlloc(strlen(buffer)+1,__FILE__,__LINE__,0); + strcpy(itemsToSell,buffer); + log_msg("itemsToSell\t\t\t\t\t= %s\n", itemsToSell); + + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_worldEventmonsterID, "333"); + worldEventmonsterID = atoi(buffer); + log_msg("worldEventmonsterID\t\t\t= %d\n", worldEventmonsterID); + + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_valueOfOwnSOJSold, "100"); + valueOfOwnSOJSold = atoi(buffer); + log_msg("valueOfOwnSOJSold\t\t\t= %d\n", valueOfOwnSOJSold); + + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_valueInitSOJSoldMin, "200"); + valueInitSOJSoldMin = atoi(buffer); + log_msg("valueInitSOJSoldMin\t\t\t= %d\n", valueInitSOJSoldMin); + + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_valueInitSOJSoldDelta, "3000"); + valueInitSOJSoldDelta = atoi(buffer)-valueInitSOJSoldMin+1; + log_msg("valueInitSOJSoldDelta\t\t= %d\n", valueInitSOJSoldDelta); + + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_triggerAtSolJSoldMin, "75"); + triggerAtSolJSoldMin = atoi(buffer); + log_msg("triggerAtSolJSoldMin\t\t= %d\n", triggerAtSolJSoldMin); + + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_triggerAtSolJSoldDelta, "125"); + triggerAtSolJSoldDelta = atoi(buffer)-triggerAtSolJSoldMin+1; + log_msg("triggerAtSolJSoldDelta\t\t= %d\n", triggerAtSolJSoldDelta); + + + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_active_AutomaticSell, "1"); + active_AutomaticSell = atoi(buffer) != 0; + log_msg("active_AutomaticSell\t\t= %d\n", active_AutomaticSell); + + if (active_AutomaticSell) + { + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_timeBeforeAutoSellMin, "0"); + timeBeforeAutoSellMin = atoi(buffer)*1000; + log_msg("timeBeforeAutoSellMin\t\t= %d\n", timeBeforeAutoSellMin); + + GET_PRIVATE_PROFILE_STRING(S_WORLD_EVENT, S_timeBeforeAutoSellDelta, "1200"); + timeBeforeAutoSellDelta = atoi(buffer)*1000-timeBeforeAutoSellMin+1; + log_msg("timeBeforeAutoSellDelta\t\t= %d\n", timeBeforeAutoSellDelta); + } + } + log_msg("\n"); +} + +void init_UberQuest(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_UBER_QUEST, S_active_UberQuest, "0"); + active_UberQuest = atoi(buffer) != 0; + if (active_UberQuest && ((version_D2Game == V109b) || (version_D2Game == V109d) || (version_D2Game == V110)) ) { + active_UberQuest = 0; + log_msg("active_UberQuest\t\t= %d (Warning : this feature is only for LoD version 1.11 or higher, so it's automatically disabled)\n", active_UberQuest); + } else + log_msg("active_UberQuest\t\t\t= %d\n", active_UberQuest); + log_msg("\n"); +} + + +void init_NewInterfaces(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_active_newInterfaces, "0"); + active_newInterfaces = atoi(buffer) != 0; + log_msg("active_newInterfaces\t\t= %d\n", active_newInterfaces); + + if (active_newInterfaces) + { + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_selectMainPageOnOpenning, "1"); + selectMainPageOnOpenning = atoi(buffer) != 0; + log_msg("selectMainPageOnOpenning\t= %u\n", selectMainPageOnOpenning); + + GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_printBackgroundOnMainPage, "1"); + printBackgroundOnMainPage = atoi(buffer) != 0; + log_msg("printBackgroundOnMainPage\t= %u\n", printBackgroundOnMainPage); + } + log_msg("\n"); +} + + +void init_ExtraOptions(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFile, char* buffer, DWORD maxSize) +{ + GET_PRIVATE_PROFILE_STRING(S_EXTRA, S_active_alwaysRegenMapInSP, "0"); + active_alwaysRegenMapInSP = atoi(buffer); + log_msg("active_alwaysRegenMapInSP\t= %d\n", active_alwaysRegenMapInSP); + + GET_PRIVATE_PROFILE_STRING(S_EXTRA, S_nbPlayersCommandByDefault, "0"); + nbPlayersCommandByDefault = atoi(buffer); + if (version_D2Common == V110) + {if (nbPlayersCommandByDefault > 8) nbPlayersCommandByDefault=8;} + else if (nbPlayersCommandByDefault > 64) nbPlayersCommandByDefault=64; + log_msg("nbPlayersCommandByDefault\t= %d\n", nbPlayersCommandByDefault); + + GET_PRIVATE_PROFILE_STRING(S_EXTRA, S_active_DisplayItemLevel, "0"); + active_DisplayItemLevel = atoi(buffer); + log_msg("active_DisplayItemLevel\t\t= %d\n", active_DisplayItemLevel); + + GET_PRIVATE_PROFILE_STRING(S_EXTRA, S_active_AlwaysDisplayLifeMana, "0"); + active_AlwaysDisplayLifeMana = atoi(buffer); + log_msg("active_AlwaysDisplayLifeMana= %d\n", active_AlwaysDisplayLifeMana); + + GET_PRIVATE_PROFILE_STRING(S_EXTRA, S_active_RunLODs, "0"); + active_RunLODs = atoi(buffer); + log_msg("active_RunLODs\t\t\t\t= %u\n", active_RunLODs); + + GET_PRIVATE_PROFILE_STRING(S_EXTRA, S_active_EnabledTXTFilesWithMSExcel, "0"); + active_EnabledTXTFilesWithMSExcel = atoi(buffer); + log_msg("active_EnabledTXTFilesWithMSExcel= %u\n\n", active_EnabledTXTFilesWithMSExcel); + + GET_PRIVATE_PROFILE_STRING(S_EXTRA, S_active_DisplayBaseStatsValue, "0"); + active_DisplayBaseStatsValue = atoi(buffer); + log_msg("active_DisplayBaseStatsValue= %u\n\n", active_DisplayBaseStatsValue); + + GET_PRIVATE_PROFILE_STRING(S_EXTRA, S_active_LadderRunewords, "0"); + active_LadderRunewords = atoi(buffer); + if (active_LadderRunewords && (version_D2Common == V109b || version_D2Common == V109d) ) { + active_LadderRunewords = 0; + log_msg("active_LadderRunewords\t= %d (Warning : Warning : this feature is only for LoD version 1.10 or higher, so it's automatically disabled)\n", active_WorldEvent); + } else + log_msg("active_LadderRunewords\t= %u\n\n", active_LadderRunewords); + + GET_PRIVATE_PROFILE_STRING(S_EXTRA, S_active_EnabledCowPortalWhenCowKingWasKill, "0"); + active_EnabledCowPortalWhenCowKingWasKill = atoi(buffer); + log_msg("active_EnabledCowPortalWhenCowKingWasKill= %u\n\n", active_EnabledCowPortalWhenCowKingWasKill); +} + + + +void loadParameters() +{ + char buffer[BUFSIZE]; + int loading=0; + INIFile *iniFile = new INIFile; + INIFile *iniFixedFile = new INIFile; + INIFile *iniDefaultFile = new INIFile; + + srand(time(NULL)); + + log_msg("***** PARAMETERS *****\n"); + if (iniFile->InitReadWrite(PARAMETERS_FILENAME, INIFILE_READ, 0)) + { + log_msg("Parameters file is opened.\n\n"); + loading = 1; + } + if (iniFixedFile->InitReadWrite(PARAM_FIXED_FILENAME, INIFILE_MPQREAD, 0)) + { + log_msg("Fixed Parameters file is opened.\n\n"); + loading = 1; + } + if (iniDefaultFile->InitReadWrite(PARAM_DEFAULT_FILENAME, INIFILE_MPQREAD, 0)) + { + log_msg("Default Parameters file is opened.\n\n"); + loading = 1; + } + + if(loading) + { + log_msg("Reading parameters.\n\n"); + init_ActivePlugin(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + if (active_plugin) + { + init_General(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + init_ActiveLanguage(iniFile, iniFixedFile, iniDefaultFile, buffer,BUFSIZE); + init_SavePath(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + init_VersionText(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + init_Stash(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + init_StatsPoints(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + init_StatPerLevelUp(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + init_SkillsPoints(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + init_SkillPerLevelUp(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + init_WorldEvent(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + init_UberQuest(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + init_NewInterfaces(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + init_ExtraOptions(iniFile, iniFixedFile, iniDefaultFile, buffer, BUFSIZE); + } + log_msg("Reading parameters end.\n\n\n"); + } else { + log_msg("\nCan't open parameters files: Default values used.\n\n\n"); + active_plugin = false; + } + + if (iniFile) + iniFile->close(); + if (iniFixedFile) + iniFixedFile->close(); + if (iniDefaultFile) + iniDefaultFile->close(); + + + delete iniFile; + delete iniDefaultFile; + delete iniFixedFile; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/PlayerCustomData.cpp b/PlugY/PlayerCustomData.cpp new file mode 100644 index 0000000..d001ef8 --- /dev/null +++ b/PlugY/PlayerCustomData.cpp @@ -0,0 +1,403 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Adding custom data. + Save and load infinity & shared Stash + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "updateClient.h" +#include "d2functions.h" +#include "infinityStash.h" +#include "savePlayerData.h" //Install_SavePlayerData() +#include "loadPlayerData.h" //Install_LoadPlayerData() + +bool active_PlayerCustomData = true; + + +/*********************************** UPDATING ***********************************/ + +Stash* getStashFromItem(Unit* ptChar, Unit* ptItem) +{ + Stash* curStash = PCPY->selfStash; + Unit* curItem; + while (curStash) + { + if (curStash == PCPY->currentStash) + curItem = D2InventoryGetFirstItem(PCInventory); + else curItem = curStash->ptListItem; + while (curItem) + { + if (D2GetRealItem(curItem) == ptItem) return curStash; + curItem = D2UnitGetNextItem(curItem); + } + curStash = curStash->nextStash; + } + + curStash = PCPY->sharedStash; + while (curStash) + { + if (curStash == PCPY->currentStash) + curItem = D2InventoryGetFirstItem(PCInventory); + else curItem = curStash->ptListItem; + while (curItem) + { + if (D2GetRealItem(curItem) == ptItem) return curStash; + curItem = D2UnitGetNextItem(curItem); + } + curStash = curStash->nextStash; + } + return NULL; +} + + +Unit* FASTCALL updateItem(Game* ptGame, DWORD type, DWORD itemNum, Unit* ptChar) +{ + Unit* ptItem = D2GameGetObject(ptGame, type, itemNum); + if (ptGame->isLODGame && (D2ItemGetPage(ptItem) == 4)) + { + Stash* ptStash = getStashFromItem(ptChar, ptItem); + if (!ptStash) return NULL; + selectStash(ptChar, ptStash); + } + return ptItem; +} + + +void STDCALL updateClientPlayerOnLoading(Unit* ptChar) +{ + log_msg("--- Start updateClientPlayerOnLoading ---\n"); + if (PCGame->isLODGame) + { + selectStash(ptChar, PCPY->selfStash); + log_msg("End update client on loading.\n\n"); + } + updateClient(ptChar, UC_SHARED_GOLD, PCPY->sharedGold, 0, 0); +} + +/**************************** INIT CUSTOM DATA ****************************/ + +PlayerData* FASTCALL init_PlayerCustomData(DWORD p1, DWORD size, LPCSTR file, DWORD line, DWORD p5) +{ + log_msg("init_PlayerCustomData\n"); + PlayerData* playerData = (PlayerData*)D2AllocMem(p1,size+sizeof(PYPlayerData),file,line,p5); + ZeroMemory((BYTE*)playerData + shifting.ptPYPlayerData, sizeof(PYPlayerData)); + return playerData; +} + +/**************************** FREE CUSTOM DATA ****************************/ + + +void freeStash(Stash* ptStash) +{ + if (!ptStash) return; + freeStash(ptStash->nextStash); + free(ptStash->nextStash);// D2FogMemDeAlloc(ptStash->nextStash,__FILE__,__LINE__,0); + if(ptStash->name) + { + free(ptStash->name);//D2FogMemDeAlloc(ptStash->name,__FILE__,__LINE__,0); + ptStash->name = NULL; + } + ptStash->nextStash = NULL; +} + + +void FASTCALL free_PlayerCustomData(DWORD p1, PlayerData* playerData, LPCSTR file, DWORD line, DWORD p5) +{ + log_msg("free_PlayerCustomData\n"); + PYPlayerData* ptPYPlayerData = (PYPlayerData*)((DWORD)playerData + shifting.ptPYPlayerData); + + freeStash(ptPYPlayerData->selfStash); + free(ptPYPlayerData->selfStash);//D2FogMemDeAlloc(ptPYPlayerData->selfStash,__FILE__,__LINE__,0); + ptPYPlayerData->selfStash = NULL; + + freeStash(ptPYPlayerData->sharedStash); + free(ptPYPlayerData->sharedStash);//D2FogMemDeAlloc(ptPYPlayerData->sharedStash,__FILE__,__LINE__,0); + ptPYPlayerData->sharedStash = NULL; + + D2FreeMem(p1,playerData,file,line,p5); +} + +Unit* STDCALL getNextItemToFree(Unit* ptChar, Unit* ptItem) +{ + Unit* item = D2UnitGetNextItem(ptItem); + if (item) return item; + + if (ptChar->nUnitType != UNIT_PLAYER) return NULL; + if (!PCPlayerData) return NULL; + if (!PCPY) return NULL; + + Stash* curStash = PCPY->selfStash; + while ( curStash ) + { + if (curStash->ptListItem) + { + item = curStash->ptListItem; + curStash->ptListItem = NULL; + return item;//->nUnitType == 4 ? item : NULL; + } + curStash = curStash->nextStash; + } + + curStash = PCPY->sharedStash; + while ( curStash ) + { + if (curStash->ptListItem) + { + item = curStash->ptListItem; + curStash->ptListItem = NULL; + return item->nUnitType == 4 ? item : NULL; + } + curStash = curStash->nextStash; + } + + return NULL; +} + + +/************************ INSTALL PLAYER CUSTOM DATA ****************************/ + +void FASTCALL updateItem_111(Unit* ptItem, Unit* ptChar) +{ + if (PCGame->isLODGame && (D2ItemGetPage(ptItem) == 4)) + { + Stash* ptStash = getStashFromItem(ptChar, ptItem); + if (ptStash) + selectStash(ptChar, ptStash); + } +} + +FCT_ASM ( caller_updateItem_111 ) + MOV ECX,ESI + MOV EDX,EBP + CALL updateItem_111 + POP EAX + MOV EDX,DWORD PTR SS:[ESP+0x18] + PUSH EDX + JMP EAX +}} + +FCT_ASM ( caller_updateItemB_111 ) + MOV EDX,EBP + CALL updateItem_111 + POP EAX + MOV EDX,DWORD PTR SS:[ESP+0x18] + PUSH EDX + JMP EAX +}} + +FCT_ASM ( caller_updateItem ) + PUSH EBP + PUSH DWORD PTR SS:[ESP+0x8] + CALL updateItem + RETN 4 +}} + +FCT_ASM ( caller_updateItem_9 ) + PUSH EBX + PUSH DWORD PTR SS:[ESP+0x8] + CALL updateItem + RETN 4 +}} + + +FCT_ASM ( caller_updateClientPlayerOnLoading ) + PUSH DWORD PTR SS:[ESP+0x14] + CALL updateClientPlayerOnLoading + POP ECX + POP EDI + POP ESI + POP EBP + XOR EAX,EAX + JMP ECX +}} + +FCT_ASM ( callerServer_getNextItemToFree_111 ) + PUSH DWORD PTR SS:[ESP+4] + PUSH DWORD PTR SS:[ESP+0x30] + CALL getNextItemToFree + RETN 4 +}} + +FCT_ASM ( callerServer_getNextItemToFree ) + PUSH DWORD PTR SS:[ESP+4] + PUSH DWORD PTR SS:[ESP+0x28] + CALL getNextItemToFree + RETN 4 +}} + +FCT_ASM ( callerServer_getNextItemToFree_9 ) + PUSH DWORD PTR SS:[ESP+4] + PUSH DWORD PTR SS:[ESP+0x1C] + CALL getNextItemToFree + RETN 4 +}} + + +FCT_ASM ( callerClient_getNextItemToFree_111 ) + PUSH DWORD PTR SS:[ESP+4] + PUSH EBX + CALL getNextItemToFree + RETN 4 +}} + +FCT_ASM ( callerClient_getNextItemToFree ) + PUSH DWORD PTR SS:[ESP+4] + PUSH DWORD PTR SS:[ESP+0x24] + CALL getNextItemToFree + RETN 4 +}} + +FCT_ASM ( callerClient_getNextItemToFree_9 ) + PUSH DWORD PTR SS:[ESP+4] + PUSH DWORD PTR SS:[ESP+0x28] + CALL getNextItemToFree + RETN 4 +}} + + +void Install_PlayerCustomData() +{ + static int isInstalled = false; + if (isInstalled || !active_PlayerCustomData) return; + + Install_SavePlayerData(); + Install_LoadPlayerData(); + Install_UpdateClient(); + + log_msg("Patch D2Game & D2Client & D2Common for Player's custom data. (PlayerCustomData)\n"); + + // Initialize custom data. + mem_seek( version_D2Client == V113 ? offset_D2Common + 0x309BE : version_D2Client == V112 ? offset_D2Common + 0x585EE : version_D2Client == V111b ? offset_D2Common + 0x5BFCE : version_D2Common == V111 ? offset_D2Common + 0x4ED5E :(DWORD)D2InitPlayerData + 0x62 ); + MEMJ_REF4( D2AllocMem, init_PlayerCustomData); + //01BD0381 |. E8 C03F0000 CALL + //6FD9ED5D |. E8 94A4FBFF CALL + //6FDABFCD |. E8 34D2FAFF CALL + //6FDA85ED |. E8 240CFBFF CALL + //6FD809BD |. E8 6088FDFF CALL + + if ( version_D2Game >= V111 ) + { + // update item + mem_seek R7(D2Game, 10933, 10C03, 1100D, 8BC71, C3C51, 5F2A1, 9BB91); + memt_byte( 0x8B ,0xE8); // CALL + MEMT_REF4( 0x52182454, caller_updateItem_111); + //0200BC71 |> 8B5424 18 |MOV EDX,DWORD PTR SS:[ESP+18] + //0200BC75 |. 52 |PUSH EDX ; /Arg1 + //02023C51 |> 8B5424 18 |MOV EDX,DWORD PTR SS:[ESP+18] + //02023C55 |. 52 |PUSH EDX ; /Arg1 + //6FC7F2A1 |> 8B5424 18 |MOV EDX,DWORD PTR SS:[ESP+18] + //6FC7F2A5 |. 52 |PUSH EDX ; /Arg1 + //6FCBBB91 |> 8B5424 18 |MOV EDX,DWORD PTR SS:[ESP+18] + //6FCBBB95 |. 52 |PUSH EDX + + mem_seek R7(D2Game, 1097B, 10C4B, 11058, 8BCD1, C3CB1, 5F301, 9BBF1); + memt_byte( 0x8B ,0xE8); // CALL + MEMT_REF4( 0x52182454, caller_updateItemB_111); + //0200BCD1 |> 8B5424 18 ||MOV EDX,DWORD PTR SS:[ESP+18] + //0200BCD5 |. 52 ||PUSH EDX ; /Arg1 + //02023CB1 |> 8B5424 18 ||MOV EDX,DWORD PTR SS:[ESP+18] + //02023CB5 |. 52 ||PUSH EDX ; /Arg1 + //6FC7F301 |> 8B5424 18 ||MOV EDX,DWORD PTR SS:[ESP+18] + //6FC7F305 |. 52 ||PUSH EDX ; /Arg1 + //6FCBBBF1 |> 8B5424 18 ||MOV EDX,DWORD PTR SS:[ESP+18] + //6FCBBBF5 |. 52 ||PUSH EDX + + } else { + // update item + mem_seek R7(D2Game, 10933, 10C03, 1100D, 8BC71, C3C51, 5F2A1, 0000); + MEMC_REF4( D2GameGetObject, version_D2Game == V110?caller_updateItem: caller_updateItem_9); + //6FC4100C |. E8 EFAA0700 |CALL D2Game.6FCBBB00 + mem_seek R7(D2Game, 1097B, 10C4B, 11058, 8BCD1, C3CB1, 5F301, 0000); + MEMC_REF4( D2GameGetObject, version_D2Game == V110?caller_updateItem: caller_updateItem_9); + //6FC41057 |. E8 A4AA0700 ||CALL D2Game.6FCBBB00 + } + + // Update client on loading + mem_seek R7(D2Game, 23EB, 2426, 25D4, 53482, C6A32, ED502, 4BF12);//6FC325D4-6FC30000 + memt_byte( 0x5F ,0xE8); // CALL + MEMT_REF4( 0xC0335D5E , caller_updateClientPlayerOnLoading); + //6FC325D4 |> 5F POP EDI + //6FC325D5 |. 5E POP ESI + //6FC325D6 |. 5D POP EBP + //6FC325D7 |. 33C0 XOR EAX,EAX + //01FD3482 |> 5F POP EDI + //01FD3483 |. 5E POP ESI + //01FD3484 |. 5D POP EBP + //01FD3485 |. 33C0 XOR EAX,EAX + //02026A32 |> 5F POP EDI + //02026A33 |. 5E POP ESI + //02026A34 |. 5D POP EBP + //02026A35 |. 33C0 XOR EAX,EAX + //6FD0D502 |> 5F POP EDI + //6FD0D503 |. 5E POP ESI + //6FD0D504 |. 5D POP EBP + //6FD0D505 |. 33C0 XOR EAX,EAX + //6FC6BF12 |> 5F POP EDI + //6FC6BF13 |. 5E POP ESI + //6FC6BF14 |. 5D POP EBP + //6FC6BF15 |. 33C0 XOR EAX,EAX + + // Free custom data. + mem_seek R7(D2Common, 7055C, 7065C, 80483, 4F82D, 5C9CD, 5856D, 3093D); + MEMJ_REF4( D2FreeMem, free_PlayerCustomData); + //01BD0482 |. E8 C53E0000 CALL + //6FD9F82C |. E8 E399FBFF CALL + //6FDAC9CC |. E8 3BC8FAFF CALL + //6FDA856C |. E8 E70CFBFF CALL + //6FD8093C |. E8 E788FDFF CALL + + // Free item in Stash (Server-side) + mem_seek R7(D2Game, 7D12B, 7D62B, 8D5A4, 99112, BFDB2, 94242, E1162); + MEMJ_REF4( D2UnitGetNextItem, version_D2Game >= V111 ? callerServer_getNextItemToFree_111 : version_D2Game == V110 ? callerServer_getNextItemToFree : callerServer_getNextItemToFree_9);//0x0005E204 + //6FCBD5A3 . E8 04E20500 CALL + //02019111 |. E8 5016F7FF |CALL + //0202FDB1 |. E8 30AAF4FF |CALL + //6FCB4241 |. E8 8862F7FF |CALL + //6FD01161 |. E8 6693F2FF |CALL + + // Free item in Stash (Client-side) + mem_seek R7(D2Client, 8EF8F, 8E30F, 89B32, 26404, 4C264, 1F2D4, A5C94);//6FB29B31-6FAA0000 + MEMJ_REF4( D2UnitGetNextItem, version_D2Game >= V111 ? callerClient_getNextItemToFree_111 : version_D2Game == V110 ? callerClient_getNextItemToFree : callerClient_getNextItemToFree_9);//0x00040F34 + //6FB29B31 E8 340F0400 CALL + //6FAD6403 |. E8 925DFEFF |CALL + //6FAFC263 |. E8 38FFFBFF |CALL + //6FACF2D3 |. E8 4CD1FEFF |CALL + //6FB55C93 |. E8 D068F6FF |CALL + + if ( version_D2Common >= V110 ) + { + // Test if it's already removed from inventory + mem_seek R7(D2Common, 0000, 0000, 4E689, 26E33, 42133, 6AE93, 21B23); + memt_byte( 0x0D , 0x07); + //01D2E688 75 0D JNZ SHORT D2Common.01D2E697 + //6FD76E32 |. 74 0D JE SHORT D2Common.6FD76E41 + //6FD92132 |. 74 0D JE SHORT D2Common.6FD92141 + //6FDBAE92 |. 74 0D JE SHORT D2Common.6FDBAEA1 + //6FD71B22 |. 74 0D JE SHORT D2Common.6FD71B31 + } else { + mem_seek R7(D2Game, 7D176, 7D676, 0000, 0000, 0000, 0000, 0000); + memt_byte( 0x74 , 0x90);//MOV EAX,EDI + memt_byte( 0x35 , 0x90);//NOP + //6FCAD176 |. 74 35 |JE SHORT D2Game.6FCAD1AD + + mem_seek R7(D2Client, 8F0CA, 8E44A, 0000, 0000, 0000, 0000, 0000); + memt_byte( 0x0F , 0x90);//MOV EAX,EDI + memt_byte( 0x84 , 0x90);//NOP + memt_dword( 0x000000BF , 0x90909090);//NOP + //6FB2F0CA |. 0F84 BF000000 |JE D2Client.6FB2F18F + + mem_seek R7(D2Client, 8F13C, 8E4BC, 0000, 0000, 0000, 0000, 0000); + memt_byte( 0x74 , 0x90);//MOV EAX,EDI + memt_byte( 0x6F , 0x90);//NOP + //6FB2F13C |. 74 6F |JE SHORT D2Client.6FB2F1AD + } + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/PlugY.aps b/PlugY/PlugY.aps new file mode 100644 index 0000000..ddd515b Binary files /dev/null and b/PlugY/PlugY.aps differ diff --git a/PlugY/PlugY.cpp b/PlugY/PlugY.cpp new file mode 100644 index 0000000..38c35d5 --- /dev/null +++ b/PlugY/PlugY.cpp @@ -0,0 +1,22 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Main file of this DLL + +=================================================================*/ + +#include + +BOOL WINAPI DllMain(HANDLE /*hModule*/, DWORD dwReason, LPVOID /*lpReserved*/) +{ + switch(dwReason) + { + case DLL_PROCESS_ATTACH: + break; + case DLL_PROCESS_DETACH: + break; + } + return true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/PlugY.rc b/PlugY/PlugY.rc new file mode 100644 index 0000000..fb9713a --- /dev/null +++ b/PlugY/PlugY.rc @@ -0,0 +1,111 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// French (France) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 10,0,0,0 + PRODUCTVERSION 10,0,0,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040004b0" + BEGIN + VALUE "CompanyName", "Yohann Nicolas" + VALUE "FileVersion", "10.00" + VALUE "OriginalFilename", "PlugY.dll" + VALUE "ProductName", "PlugY, The Survival Kit" + VALUE "ProductVersion", "10.00" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x400, 1200 + END +END + +#endif // French (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/PlugY/PlugY.sln b/PlugY/PlugY.sln new file mode 100644 index 0000000..8651a40 --- /dev/null +++ b/PlugY/PlugY.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlugY", "PlugY.vcproj", "{F5E47DA0-4D85-41E4-954D-29237DF8AFCB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F5E47DA0-4D85-41E4-954D-29237DF8AFCB}.Debug|Win32.ActiveCfg = Debug|Win32 + {F5E47DA0-4D85-41E4-954D-29237DF8AFCB}.Debug|Win32.Build.0 = Debug|Win32 + {F5E47DA0-4D85-41E4-954D-29237DF8AFCB}.Release|Win32.ActiveCfg = Release|Win32 + {F5E47DA0-4D85-41E4-954D-29237DF8AFCB}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PlugY/PlugY.suo b/PlugY/PlugY.suo new file mode 100644 index 0000000..f209d63 Binary files /dev/null and b/PlugY/PlugY.suo differ diff --git a/PlugY/PlugY.vcproj b/PlugY/PlugY.vcproj new file mode 100644 index 0000000..6efbfd6 --- /dev/null +++ b/PlugY/PlugY.vcproj @@ -0,0 +1,574 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PlugY/PlugY.vcproj.ATHLON64.Yohann.user b/PlugY/PlugY.vcproj.ATHLON64.Yohann.user new file mode 100644 index 0000000..b35e81c --- /dev/null +++ b/PlugY/PlugY.vcproj.ATHLON64.Yohann.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/PlugY/PlugYFiles.cpp b/PlugY/PlugYFiles.cpp new file mode 100644 index 0000000..fb02f04 --- /dev/null +++ b/PlugY/PlugYFiles.cpp @@ -0,0 +1,273 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Adding custom data. + Save and load infinity & shared Stash + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "plugYFiles.h" +#include + +//#include "newInterfaces.h" +extern bool active_SkillsPoints, active_StatsPoints, active_newInterfaces, active_multiPageStash, active_sharedGold; + +void* unassignSkillsBtnImages = NULL; +void* unassignStatsBtnImages = NULL; +void* stashBtnsImages = NULL; +void* newStatsInterfaceImages = NULL; +void* statsBackgroundImages = NULL; +void* sharedGoldBtnsImages = NULL; + + +//void* lookupItemStatCost = NULL; + + +DWORD STDCALL isModFile (char* filename) +{ + if (strstr(filename, modDataDirectory) ) + { + char fileTemp[0x104]; + log_msg("Load custom file : %s", filename); + strcpy(fileTemp,filename); + D2FogGetInstallPath(filename,0x104-strlen(filename)); + strcat(filename,fileTemp); + log_msg("-> %s\n", filename); + if ((GetFileAttributesA(filename) & 0x10) == 0) + return true; + } + return false; +} + + +FCT_ASM ( caller_isModFile ) + TEST ESI,ESI + JNZ ISNOTMODDATA + MOV EBP, DWORD PTR SS:[ESP+0x140] + PUSH EBP + CALL isModFile + TEST EAX,EAX + JE ISNOTMODDATA + MOV BL, BYTE PTR SS:[ESP+0x144] + POP EAX + POP EAX + MOV EAX,D2StormMPQOpenFile + ADD EAX,0x9A + JMP EAX +ISNOTMODDATA: + JMP DWORD PTR CS:[LeaveCriticalSection] +}} + +FCT_ASM ( caller_isModFile_111 ) + TEST EDI,EDI + JNZ ISNOTMODDATA + MOV ESI, DWORD PTR SS:[ESP+0x130] + PUSH ESI + CALL isModFile + TEST EAX,EAX + JE ISNOTMODDATA + MOV BL, BYTE PTR SS:[ESP+0x134] + POP EAX + POP EAX + MOV EAX,D2StormMPQOpenFile + ADD EAX,0xBD + MOV EBP,GetFileAttributesA + JMP EAX +ISNOTMODDATA: + JMP DWORD PTR CS:[LeaveCriticalSection] +}} + +void Install_PlugYFiles() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch Storm to found custom file. (PlugYFiles)\n"); + + // Try in Diablo II\PlugY\ if file not found + mem_seek R7(Storm, 192C6, 19296, 18677, 2CC69, 14259, 121E9, 28D89);//( (DWORD)D2Storm268 + V7(Storm, 01A8, 01A8, 01AB, 0429, 0429, 0429, 0000) ); + memt_byte( 0xFF ,0x90); // NOP + memt_byte( 0x15 ,0xE8); // CALL + MEMD_REF4( LeaveCriticalSection, version_Storm >= V111 ? caller_isModFile_111 : caller_isModFile); + //6FFC8677 |. FF15 F411FE6F CALL DWORD PTR DS:[<&KERNEL32.LeaveCriti>; \LeaveCriticalSection + //6FC1CC69 |. FF15 3832C36F CALL DWORD PTR DS:[<&KERNEL32.LeaveCriti>; \LeaveCriticalSection + //6FC04259 |. FF15 3832C36F CALL DWORD PTR DS:[<&KERNEL32.LeaveCriti>; \LeaveCriticalSection + //6FC021E9 |. FF15 4432C36F CALL DWORD PTR DS:[<&KERNEL32.LeaveCriti>; \LeaveCriticalSection + //6FC18D89 |. FF15 5832C36F CALL DWORD PTR DS:[<&KERNEL32.LeaveCriti>; \LeaveCriticalSection + + + log_msg("\n" ); + + isInstalled = true; +} +//6FFC7EF0 >/$ 8B4C24 10 MOV ECX,DWORD PTR SS:[ESP+10] + +/****************************************************************************************************/ + + +void loadImagesFile(void** images, const char* name) +{ + if(!images || !name) return; + if(!*images) + { + char buffer[MAX_PATH]; + sprintf(buffer, "%s\\%s", modDataDirectory, name); + log_msg("Images file to load : %s\n",buffer); + + *images = D2LoadImage(buffer,0); + if (!*images) + { + sprintf(buffer, "Don't find Buttons Images File : %s.dc6", name); + d2_assert(!*images, buffer, __FILE__, __LINE__); + } + } +} + +void STDCALL loadCustomImages() +{ + if ( active_SkillsPoints ) loadImagesFile(&unassignSkillsBtnImages, "UnassignSkillsBtns"); + if ( active_StatsPoints ) loadImagesFile(&unassignStatsBtnImages, "UnassignStatsBtns"); + if ( active_multiPageStash || active_newInterfaces) loadImagesFile(&stashBtnsImages, "StashBtns"); + if ( active_sharedGold) loadImagesFile(&sharedGoldBtnsImages, "SharedGoldBtns"); + if ( active_newInterfaces ) loadImagesFile(&newStatsInterfaceImages, "EmptyPage"); + if ( active_newInterfaces ) loadImagesFile(&statsBackgroundImages, "StatsBackground"); +} + +#define freeImagesFile(I) if(I) {D2FreeImage(I);I=NULL;} + +void STDCALL freeCustomImages() +{ + freeImagesFile(unassignSkillsBtnImages); + freeImagesFile(unassignStatsBtnImages); + freeImagesFile(stashBtnsImages); + freeImagesFile(sharedGoldBtnsImages); + freeImagesFile(newStatsInterfaceImages); + freeImagesFile(statsBackgroundImages); +} + +FCT_ASM ( caller_loadCustomImages ) + CALL loadCustomImages + MOV ECX,0x0C + RETN +}} + +FCT_ASM ( caller_freeCustomImages ) + CALL freeCustomImages + MOV ECX,0x0C + RETN +}} + +void Install_PlugYImagesFiles() +{ + static int isInstalled = false; + if (isInstalled) return; + + Install_PlugYFiles(); + + log_msg("Patch D2Client to load/free custom images. (PlugYImagesFiles)\n"); + + // Load custom images + mem_seek R7(D2Client, 57E21, 57E21, 5E4B1, 2E101, B67E1, 82761, 27EAE); + memt_byte( 0xB9 ,0xE8); + MEMT_REF4( 0x0000000C , caller_loadCustomImages); + //6FAFE4B1 |. B9 0C000000 MOV ECX,0C + //6FADE101 |. B9 0C000000 MOV ECX,0C + //6FB667E1 |. B9 0C000000 MOV ECX,0C + //6FB32761 |. B9 0C000000 MOV ECX,0C + //6FAD7EAE |. B9 0C000000 MOV ECX,0C + + // Free custom images + mem_seek R7(D2Client, 57FA9, 57FA9, 5E639, 2D12D, B580D, 8158D, 26F8D); + memt_byte( 0xB9 ,0xE8); + MEMT_REF4( 0x0000000C , caller_freeCustomImages); + //6FAFE639 |> B9 0C000000 MOV ECX,0C + //6FADD12D |> B9 0C000000 MOV ECX,0C + //6FB6580D |> B9 0C000000 MOV ECX,0C + //6FB3158D |> B9 0C000000 MOV ECX,0C + //6FAD6F8D |> B9 0C000000 MOV ECX,0C + + log_msg("\n" ); + + isInstalled = true; +} + + +/****************************************************************************************************/ + +void loadStatsInterfaceDesc(DWORD mempool); +void freeStatsInterfaceDesc(); + + + +void FASTCALL loadTxtFiles(DWORD mempool) +{ + loadStatsInterfaceDesc(mempool); +} + +void FASTCALL freeTxtFiles() +{ + freeStatsInterfaceDesc(); +} + +FCT_ASM ( caller_loadTxtFiles_111 ) + MOV ECX,DWORD PTR SS:[ESP+4] + CALL loadTxtFiles + JMP D2LoadSuperuniques +}} + +FCT_ASM ( caller_loadTxtFiles ) + PUSH ECX + CALL loadTxtFiles + POP ECX + JMP D2LoadSuperuniques +}} + +FCT_ASM ( caller_freeTxtFiles ) + CALL freeTxtFiles + JMP D2Fog10212 +}} + + +void Install_PlugYTxtFiles() +{ + static int isInstalled = false; + if (isInstalled) return; + + Install_PlugYFiles(); + + log_msg("Patch D2Common to load/free custom txt files. (PlugYTxtFiles)\n"); + +// lookupItemStatCost = (void*)R7(D2Common, A1D70, A1D70, AA1D8, 0000, 0000, 0000, 0000); + + // Load custom txt files + mem_seek R7(D2Common, 7F4B, 7F4B, 2F7D7, 76854, 37444, 81C44, 5D6E4); + MEMC_REF4( D2LoadSuperuniques, version_D2Common >= V111 ? caller_loadTxtFiles_111 : caller_loadTxtFiles ); + //6FD47F4A |. E8 B1750100 CALL D2Common.6FD5F500 + //6FD47F4A |. E8 C1750100 CALL D2Common.6FD5F510 + //01B6F7D6 |. E8 C5A7FFFF CALL D2Common.01B69FA0 + //6FDC6853 |. E8 58B6FFFF CALL D2Common.6FDC1EB0 ; \D2Common.6FDC1EB0 + //6FD87443 |. E8 58B6FFFF CALL D2Common.6FD82AA0 ; \D2Common.6FD82AA0 + //6FDD1C43 |. E8 58B6FFFF CALL D2Common.6FDCD2A0 ; \D2Common.6FDCD2A0 + //6FDAD6E3 |. E8 88C1FFFF CALL D2Common.6FDA9870 ; \D2Common.6FDA9870 + + // Free custom txt files + mem_seek R7(D2Common, 79EC, 79EC, 10186, 332B3, 15AB3, 44E13, 5E8B3); + MEMJ_REF4( D2Fog10212, caller_freeTxtFiles ); + //6FD479EB . E8 C8C00600 CALL + //6FD479EB . E8 C8C00600 CALL + //01B50185 |. E8 F8410700 CALL + //6FD832B2 |. E8 755FFDFF CALL + //6FD65AB2 |. E8 B537FFFF CALL + //6FD94E12 |. E8 1744FCFF CALL + //6FDAE8B2 |. E8 8FA9FAFF CALL + + log_msg("\n" ); + + isInstalled = true; +} + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/Progress.txt b/PlugY/Progress.txt new file mode 100644 index 0000000..4c5c1d5 --- /dev/null +++ b/PlugY/Progress.txt @@ -0,0 +1,52 @@ +Parameters.h et PlugY.rc => version changing + +A faire : + +A tester : + +UPDATED : +DONE D2funcs.h +DONE BigStash.cpp +DONE ClientSaveFile.cpp +DONE Commands.cpp +DONE Common.cpp +DONE CustomLibraries.cpp +DONE D2functions.cpp +DONE D2wrapper.cpp +DONE Error.cpp +DONE ExtendedSaveFile.cpp +DONE ExtraOptions.cpp +DONE GlobalVariable.cpp +DONE InfinityStash.cpp +DONE INIfile.cpp +DONE Interface_Skills.cpp +DONE Interface_Stash.cpp +DONE Interface_Stats.cpp +DONE Language.cpp +DONE LoadPlayerData.cpp +DONE MainScreen.cpp +DONE ModifMemory.cpp +DONE NewInterface_CubeListing.cpp +DONE NewInterface_Runewords.cpp +DONE NewInterface_Stats.cpp +DONE NewInterface_StatsPageTwo.cpp +DONE NewInterfaces.cpp +DONE OthersFeatures.cpp +DONE Parameters.cpp +DONE PlayerCustomData.cpp +DONE PlugY.cpp +DONE PlugY.rc +DONE PlugYFiles.cpp +DONE SavePath.cpp +DONE SavePlayerData.cpp +DONE SharedSaveFile.cpp +DONE SkillPerLevelUp.cpp +DONE SkillsPoints.cpp +DONE StatPerLevelUp.cpp +DONE StatsPoints.cpp +DONE UberQuest.cpp +DONE UpdateClient.cpp +DONE UpdateServer.cpp +DONE WorldEvent.cpp + + diff --git a/PlugY/SavePath.cpp b/PlugY/SavePath.cpp new file mode 100644 index 0000000..31d9346 --- /dev/null +++ b/PlugY/SavePath.cpp @@ -0,0 +1,202 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Changing the current save path. + +=================================================================*/ + +#include "savePath.h" +#include "common.h" +#include "error.h" +#include "d2functions.h" + +char* savePath = NULL; +bool active_changingSavePath = false; + + +FCT_ASM( changeSavePath ) + PUSH EDI + PUSH EDX + PUSH ESI + MOV EDI,DWORD PTR DS:[savePath] + XOR AL,AL + CLD + OR ECX,0xFFFFFFFF + REPNE SCAS BYTE PTR ES:[EDI] + NOT ECX + SUB EDI,ECX + XCHG EDI,ESI + CMP BYTE PTR [ESI+1],':' + JE END_CHANGESP +//RELATIVE_PATH: + MOV EDX,ECX + OR ECX,0xFFFFFFFF + REPNE SCAS BYTE PTR ES:[EDI] + DEC EDI + CMP BYTE PTR [EDI-1],'\\' + JE NEXT + MOV BYTE PTR [EDI],'\\' + INC EDI +NEXT: + MOV ECX,EDX +END_CHANGESP: + REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] + POP ESI + POP EDX + POP EDI + PUSH ESI + CALL EBP + CMP EAX,-1 + RETN +}} + +FCT_ASM( changeSavePath_111 ) + PUSH EAX + PUSH EDI + PUSH EDX + PUSH ESI + MOV EDI,DWORD PTR DS:[savePath] + XOR AL,AL + CLD + OR ECX,0xFFFFFFFF + REPNE SCAS BYTE PTR ES:[EDI] + NOT ECX + SUB EDI,ECX + XCHG EDI,ESI + CMP BYTE PTR [ESI+1],':' + JE END_CHANGESP +//RELATIVE_PATH: + MOV EDX,ECX + OR ECX,0xFFFFFFFF + REPNE SCAS BYTE PTR ES:[EDI] + DEC EDI + CMP BYTE PTR [EDI-1],'\\' + JE NEXT + MOV BYTE PTR [EDI],'\\' + INC EDI +NEXT: + MOV ECX,EDX +END_CHANGESP: + REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] + POP ESI + POP EDX + POP EDI + POP EAX + CMP EAX,-1 + JE DONOT_JMP + ADD DWORD PTR SS:[ESP],5 +DONOT_JMP: + RETN +}} + +FCT_ASM ( forCreateSavePath ) + PUSH EDI + MOV EDI,DWORD PTR DS:[savePath] + MOV ECX,EDI + CMP BYTE PTR DS:[EDI+1],':' + JNZ END_CREATESP + PUSH ESI + XOR AL,AL + CLD + OR ECX,0xFFFFFFFF + REPNE SCAS BYTE PTR ES:[EDI] + NOT ECX + SUB EDI,ECX + XCHG EDI,ESI + REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] + POP ESI +END_CREATESP: + POP EDI + MOV DWORD PTR SS:[ESP+8],ECX + JMP D2Storm503 +}} + + + +void Install_ChangingSavePath() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch Fog for change the save path. (changingSavePath)\n"); + + if (version_Fog >= V111) + { + // Appel de notre fct d'ajout d'un sous-rpertoire + mem_seek R7(Fog, 000, 000, 000, 185F6, 1C106, 1F086, 17F86); + memt_byte( 0x83 ,0xE8); // CALL changeSavePath + MEMT_REF4( 0x0575FFF8, changeSavePath_111); + //6FF685F6 . 83F8 FF CMP EAX,-1 + //6FF685F9 . 75 05 JNZ SHORT fog.6FF68600 + //6FF6C106 . 83F8 FF CMP EAX,-1 + //6FF6C109 . 75 05 JNZ SHORT fog.6FF6C110 + //6FF6F086 . 83F8 FF CMP EAX,-1 + //6FF6F089 . 75 05 JNZ SHORT Fog.6FF6F090 + //6FF67F86 . 83F8 FF CMP EAX,-1 + //6FF67F89 . 75 05 JNZ SHORT Fog.6FF67F90 + + // Pour crer le bon chemin de sauvegarde + mem_seek R7(Fog, 000, 000, 000, 18616, 1C126, 1F0A6, 17FA6); + MEMJ_REF4( D2Storm503, forCreateSavePath); + //6FF68615 . E8 A246FFFF CALL + //6FF6C125 . E8 C20BFFFF CALL + //6FF6F0A5 . E8 34DDFEFF CALL + //6FF67FA5 . E8 504EFFFF CALL + + + // Remove registry update + mem_seek R7(Fog, 000, 000, 000, 1861A, 1C12A, 1F0AA, 17FAA); + memt_byte( 0x56 ,0xEB); // JMP SHORT fog.6FF6862C + memt_byte( 0x6A ,0x10); // + memt_byte( 0x00 ,0x90); // NOP + //6FF6861A . 56 PUSH ESI + //6FF6861B . 6A 00 PUSH 0 + //6FF6861D . 68 7C7BF76F PUSH fog.6FF77B7C ; ASCII "Save Path" + //6FF68622 . 68 2876F76F PUSH fog.6FF77628 ; ASCII "Diablo II" + //6FF68627 . E8 1A47FFFF CALL + //6FF6C12A . 56 PUSH ESI + //6FF6C12B . 6A 00 PUSH 0 + //6FF6C12D . 68 BC73F76F PUSH fog.6FF773BC ; ASCII "Save Path" + //6FF6C132 . 68 C873F76F PUSH fog.6FF773C8 ; ASCII "Diablo II" + //6FF6C137 . E8 E60BFFFF CALL + //6FF6F0AA . 56 PUSH ESI + //6FF6F0AB . 6A 00 PUSH 0 + //6FF6F0AD . 68 D466F76F PUSH Fog.6FF766D4 ; ASCII "Save Path" + //6FF6F0B2 . 68 E066F76F PUSH Fog.6FF766E0 ; ASCII "Diablo II" + //6FF6F0B7 . E8 58DDFEFF CALL + //6FF67FAA . 56 PUSH ESI + //6FF67FAB . 6A 00 PUSH 0 + + } else { + + // Appel de notre fct d'ajout d'un sous-rpertoire + mem_seek( (DWORD)D2FogGetSavePath + 0x28);//6FF61928-6FF50000 + memt_byte( 0x56 ,0x90); // NOP + memt_byte( 0xFF ,0xE8); // CALL changeSavePath + MEMT_REF4( 0xFFF883D5, changeSavePath); + //6FF61928 56 PUSH ESI + //6FF61929 FFD5 CALL EBP + //6FF6192B 83F8 FF CMP EAX,-1 + + // Pour crer le bon chemin de sauvegarde + mem_seek( (DWORD)D2FogGetSavePath + 0xBD);//6FF619BC + MEMJ_REF4( D2Storm503, forCreateSavePath); + //6FF619BC . E8 5D2A0000 CALL + + // Remove registry update + mem_seek( (DWORD)D2FogGetSavePath + 0xC1);//6FF619C1-6FF50000 + memt_byte( 0x56 ,0xEB); // JMP SHORT FOG.6FF619D2 + memt_byte( 0x53 ,0x0F); //6FF619C3-6FF619D2 + //6FF619C1 56 PUSH ESI + //6FF619C2 53 PUSH EBX + //6FF619C3 68 A877F76F PUSH Fog.6FF777A8 ; ASCII "Save Path" + //6FF619C8 68 9068F76F PUSH Fog.6FF76890 ; ASCII "Diablo II" + //6FF619CD E8 AC2A0000 CALL + } + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/SavePlayerData.cpp b/PlugY/SavePlayerData.cpp new file mode 100644 index 0000000..09ba097 --- /dev/null +++ b/PlugY/SavePlayerData.cpp @@ -0,0 +1,611 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Save Player Custom Data. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "infinityStash.h" +#include "extendedSaveFile.h" +#include "sharedSaveFile.h" + + +void STDCALL SaveSPPlayerCustomData(Unit* ptChar) +{ + if (!D2isLODGame()) return;//D2Game but in SP so np + + log_msg("\n--- Start SaveSPPlayerCustomData ---\n"); + + if (PCPY->selfStashIsOpened) + { + DWORD curSizeExt = 0; + DWORD maxSizeExt = 0x4000; + BYTE* dataExt = (BYTE *)D2AllocMem(PCGame->memoryPool, maxSizeExt,__FILE__,__LINE__,0); + d2_assert(!dataExt, "Error : Memory allocation Extended SaveFile", __FILE__, __LINE__); + saveExtendedSaveFile(ptChar, &dataExt, &maxSizeExt, &curSizeExt); + writeExtendedSaveFile(PCPlayerData->name, dataExt, curSizeExt); + D2FreeMem(PCGame->memoryPool, dataExt,__FILE__,__LINE__,0); + } + + if (active_sharedStash && PCPY->sharedStashIsOpened) + { + DWORD curSizeShr = 0; + DWORD maxSizeShr = 0x4000; + BYTE* dataShr = (BYTE *)D2AllocMem(PCGame->memoryPool, maxSizeShr,__FILE__,__LINE__,0); + d2_assert(!dataShr, "Error : Memory allocation Shared SaveFile", __FILE__, __LINE__); + saveSharedSaveFile(ptChar, &dataShr, &maxSizeShr, &curSizeShr); + + NetClient* ptClient = D2GetClient(ptChar,__FILE__,__LINE__); + writeSharedSaveFile(PCPlayerData->name, dataShr, curSizeShr, ptClient->isHardCoreGame ); + D2FreeMem(PCGame->memoryPool, dataShr,__FILE__,__LINE__,0); + } + + log_msg("End saving.\n\n"); +} + + +FCT_ASM ( caller_SaveSPPlayerCustomData_111 ) + CALL D2FogGetSavePath + PUSH DWORD PTR SS:[ESP+0x2608] + CALL SaveSPPlayerCustomData + RETN +}} + +FCT_ASM ( caller_SaveSPPlayerCustomData ) + CALL D2FogGetSavePath + PUSH EDI + CALL SaveSPPlayerCustomData + RETN +}} + +FCT_ASM ( caller_SaveSPPlayerCustomData_9 ) + CALL D2FogGetSavePath + PUSH ESI + CALL SaveSPPlayerCustomData + RETN +}} + + +////////////////////////////////////////////////////////////////////////////////////////////////// + +#define TC_SAVE_PERSONAL 0 +#define TC_SAVE_SHARED 1 + +#pragma pack(1) +typedef struct { + BYTE packID; + BYTE packSize; + BYTE init; + DWORD finalSize:31; + DWORD isCustom:1; + BYTE type; + BYTE data[0xFF]; +} t_rcvMsg; +#pragma pack() + +struct s_MPSaveFile +{ + int sizeExtended; + int curExtended; + BYTE* dataExtended; + int sizeShared; + int curShared; + BYTE* dataShared; +}; +static s_MPSaveFile receivedSaveFiles; +static BYTE customPackID = 0xB2; +//static s_MPSaveFile* receivedSaveFiles = NULL; + + +struct s_dataToSend +{ + s_dataToSend* next; + int clientID; + int sizeExtended; + int curExtended; + BYTE* dataExtended; + int sizeShared; + int curShared; + BYTE* dataShared; + bool init; +}; +s_dataToSend* ptDataToSend=NULL; + +/* +void sendDataToSave(DWORD clientID, BYTE* data, DWORD size, bool isShared) +{ + t_rcvMsg pack; + d2_assert(size >= 0x40000000, "size of file > 0x40000000", __FILE__, __LINE__); + + pack.packID = customPackID; + pack.init = !isShared; + pack.finalSize = size; + pack.type = isShared ? TC_SAVE_SHARED : TC_SAVE_PERSONAL; + pack.isCustom = true; + + DWORD sended = 0; + while (sended < size) + { + pack.packSize = (BYTE) (size - sended > 0xFE ? 0xFE : size - sended); + CopyMemory(pack.data, &data[sended], pack.packSize); + log_msg("send: ID=%02X\tsize=%02X\tinit=%02X\ttotalsize=%08X\ttype=%d\n", pack.packID, pack.init, pack.packSize, pack.finalSize, pack.type); + pack.packSize++; + D2SendToClient(0, clientID, (BYTE*)&pack, pack.packSize+7); + pack.init = false; + sended += pack.packSize -1; + } + log_msg("\n"); +}*/ + +void STDCALL SendSaveFilesToSave( Unit* ptChar ) +{ +// if (!D2isLODGame()) return; + log_msg("\n--- Start SendSaveFilesToSave ---\n"); + + DWORD curSizeExt = 0; + BYTE* dataExt = NULL; + DWORD curSizeShr = 0; + BYTE* dataShr = NULL; + + if (PCPY->selfStashIsOpened) + { + DWORD maxSizeExt = 0x4000; + dataExt = (BYTE *)D2AllocMem(PCGame->memoryPool, maxSizeExt,__FILE__,__LINE__,0); + d2_assert(!dataExt, "Error : Memory allocation Extended SaveFile", __FILE__, __LINE__); + saveExtendedSaveFile(ptChar, &dataExt, &maxSizeExt, &curSizeExt); + } + + if (active_sharedStash && PCPY->sharedStashIsOpened) + { + DWORD maxSizeShr = 0x4000; + dataShr = (BYTE *)D2AllocMem(PCGame->memoryPool, maxSizeShr,__FILE__,__LINE__,0); + d2_assert(!dataShr, "Error : Memory allocation Shared SaveFile", __FILE__, __LINE__); + saveSharedSaveFile(ptChar, &dataShr, &maxSizeShr, &curSizeShr); + } + + NetClient* ptClient = D2GetClient(ptChar,__FILE__,__LINE__); + s_dataToSend* dataToSend = ptDataToSend; + while (dataToSend && (dataToSend->clientID != ptClient->clientID)) + dataToSend = dataToSend->next; + if (!dataToSend) + { + dataToSend = (s_dataToSend*) D2AllocMem(PCGame->memoryPool, sizeof(s_dataToSend), __FILE__, __LINE__, 0); + ZeroMemory(dataToSend, sizeof(s_dataToSend)); + dataToSend->next = ptDataToSend; + ptDataToSend = dataToSend; + } + + //Sending savefiles + dataToSend->clientID = ptClient->clientID; + dataToSend->init = 1; + dataToSend->sizeExtended = curSizeExt; + dataToSend->curExtended = 0; + dataToSend->dataExtended = dataExt; + dataToSend->sizeShared = curSizeShr; + dataToSend->curShared = 0; + dataToSend->dataShared = dataShr; + log_msg("clientID=%d\t init=%d\t sizeExtended=%X\t curExtended=%X\t dataExtended=%X\t sizeShared=%X\t curShared=%X\t dataShared=%08X\n", + dataToSend->clientID, dataToSend->init, dataToSend->sizeExtended, dataToSend->curExtended, dataToSend->dataExtended, dataToSend->sizeShared, dataToSend->curShared, dataToSend->dataShared); + +/* NetClient* ptClient = D2GetClient(ptChar,__FILE__,__LINE__); + if (dataExt) + { + sendDataToSave(ptClient->clientID, dataExt, curSizeExt, false); + D2FreeMem(PCGame->memoryPool, dataExt,__FILE__,__LINE__,0); + } + if (dataShr) + { + sendDataToSave(ptClient->clientID, dataShr, curSizeShr, true); + D2FreeMem(PCGame->memoryPool, dataShr,__FILE__,__LINE__,0); + } +*/ + log_msg("End SendSaveFilesToSave.\n\n"); +} + + +DWORD STDCALL ManageNextPacketToSend(NetClient* ptClient) +{ + log_msg("ManageNextPacketToSend: "); + s_dataToSend* dataToSend = ptDataToSend; + while (dataToSend && (dataToSend->clientID != ptClient->clientID)) + dataToSend = dataToSend->next; + if (!dataToSend) return 1; + + log_msg("clientID=%d\t init=%d\t sizeExtended=%X\t curExtended=%X\t dataExtended=%X\t sizeShared=%X\t curShared=%X\t dataShared=%08X\n", + dataToSend->clientID, dataToSend->init, dataToSend->sizeExtended, dataToSend->curExtended, dataToSend->dataExtended, dataToSend->sizeShared, dataToSend->curShared, dataToSend->dataShared); + + if (dataToSend->sizeExtended && dataToSend->dataExtended && (dataToSend->curExtended < dataToSend->sizeExtended)) + { + DWORD remainingData = dataToSend->sizeExtended - dataToSend->curExtended; + t_rcvMsg* msg = (t_rcvMsg*)D2AllocMem(PClientGame->memoryPool, sizeof(t_rcvMsg),__FILE__,__LINE__,0); + msg->packID = customPackID; + msg->init = dataToSend->init; + msg->finalSize = dataToSend->sizeExtended; + msg->type = TC_SAVE_PERSONAL; + msg->isCustom = true; + msg->packSize = remainingData > 0xFE ? 0xFF : (BYTE)remainingData + 1; + CopyMemory(msg->data, &dataToSend->dataExtended[dataToSend->curExtended], msg->packSize); + log_msg("Saving Send Packet: type=%X\t init=%d\t finalSize=%X\t packSize=%02X\t data=%08X\n", msg->type, msg->init, msg->finalSize, msg->packSize, msg->data); + D2SendToClient(0, dataToSend->clientID, msg, msg->packSize+7); + dataToSend->init = false; + dataToSend->curExtended += msg->packSize - 1; + D2FreeMem(PClientGame->memoryPool, msg,__FILE__,__LINE__,0); + if (dataToSend->curExtended == dataToSend->sizeExtended) + { + dataToSend->sizeExtended = 0; + dataToSend->curExtended = 0; + D2FreeMem(PClientGame->memoryPool, dataToSend->dataExtended,__FILE__,__LINE__,0); + dataToSend->dataExtended = NULL; + } + log_msg("End Send Packet\n"); + return 0;//ManageNextPacketToSend(ptClient);//return 0; + } + + if (dataToSend->sizeShared && dataToSend->dataShared && (dataToSend->curShared < dataToSend->sizeShared)) + { + DWORD remainingData = dataToSend->sizeShared - dataToSend->curShared; + t_rcvMsg* msg = (t_rcvMsg*)D2AllocMem(PClientGame->memoryPool, sizeof(t_rcvMsg),__FILE__,__LINE__,0); + msg->packID = customPackID; + msg->init = dataToSend->init; + msg->finalSize = dataToSend->sizeShared; + msg->type = TC_SAVE_SHARED; + msg->isCustom = true; + msg->packSize = remainingData > 0xFE ? 0xFF : (BYTE)remainingData + 1; + CopyMemory(msg->data, &dataToSend->dataShared[dataToSend->curShared], msg->packSize); + log_msg("Saving Send Packet: type=%X\t init=%d\t finalSize=%X\t packSize=%02X\t data=%08X\n", msg->type, msg->init, msg->finalSize, msg->packSize, msg->data); + D2SendToClient(0, dataToSend->clientID, msg, msg->packSize+7); + dataToSend->init = false; + dataToSend->curShared += msg->packSize - 1; + D2FreeMem(PClientGame->memoryPool, msg,__FILE__,__LINE__,0); + if (dataToSend->curShared == dataToSend->sizeShared) + { + dataToSend->sizeShared = 0; + dataToSend->curShared = 0; + D2FreeMem(PClientGame->memoryPool, dataToSend->dataShared,__FILE__,__LINE__,0); + dataToSend->dataShared = NULL; + } + log_msg("End Send Packet\n"); + return 0;//ManageNextPacketToSend(ptClient);//return 0; + } + + log_msg("End Send Packet\n"); + return 1; +} + + +DWORD STDCALL ReceiveSaveFilesToSave(t_rcvMsg* msg) +{ + if( (msg->packID != customPackID) || !msg->isCustom) return 0; + + log_msg("Saving Receive Packet: type=%X\t init=%d\t finalSize=%X\t packSize=%02X\t data=%08X\n", msg->type, msg->init, msg->finalSize, msg->packSize, msg->data); + + bool isShared; + + if ( msg->type == TC_SAVE_PERSONAL) + isShared = false; + else if (msg->type == TC_SAVE_SHARED) + isShared = true; + else return 0; + + + if (msg->init) + { + D2FogMemDeAlloc(receivedSaveFiles.dataExtended,__FILE__,__LINE__,0); + D2FogMemDeAlloc(receivedSaveFiles.dataShared,__FILE__,__LINE__,0); + ZeroMemory(&receivedSaveFiles, sizeof(receivedSaveFiles));//TODO + } + + log_msg("receivedSaveFiles: sizeExtended=%d\t curExtended=%d\t dataExtended=%08X\t sizeShared=%d\t curShared=%d\t dataShared=%08X\n", receivedSaveFiles.sizeExtended, receivedSaveFiles.curExtended, receivedSaveFiles.dataExtended, receivedSaveFiles.sizeShared, receivedSaveFiles.curShared, receivedSaveFiles.dataShared); + + DWORD size = msg->packSize - 1; + if (isShared) + { + if (receivedSaveFiles.sizeShared == 0) + receivedSaveFiles.sizeShared = msg->finalSize; +// d2_assert(receivedSaveFiles.sizeShared != msg->finalSize, "Size of shared file has change", __FILE__, __LINE__); + + if (!receivedSaveFiles.dataShared) + receivedSaveFiles.dataShared = (BYTE *)D2FogMemAlloc(receivedSaveFiles.sizeShared,__FILE__,__LINE__,0); + + CopyMemory(&receivedSaveFiles.dataShared[receivedSaveFiles.curShared], msg->data, size); + receivedSaveFiles.curShared += size; + + } else { + + if (receivedSaveFiles.sizeExtended == 0) + receivedSaveFiles.sizeExtended = msg->finalSize; +// d2_assert(receivedSaveFiles.sizeExtended != msg->finalSize, "Size of extented file has change", __FILE__, __LINE__); + + if (!receivedSaveFiles.dataExtended) + receivedSaveFiles.dataExtended = (BYTE *)D2FogMemAlloc(receivedSaveFiles.sizeExtended,__FILE__,__LINE__,0); + + CopyMemory(&receivedSaveFiles.dataExtended[receivedSaveFiles.curExtended], msg->data, size); + receivedSaveFiles.curExtended += size; + } + log_msg("End Save Receive Packet\n"); + return 1; +} + + +void STDCALL SaveMPPlayerCustomData(BYTE* dataD2Savefile ) +{ + log_msg("Start SaveMPPlayerCustomData.\n"); + Unit* ptChar = D2GetClientPlayer(); + if( receivedSaveFiles.sizeExtended && (receivedSaveFiles.sizeExtended == receivedSaveFiles.curExtended) && receivedSaveFiles.sizeShared && (receivedSaveFiles.sizeShared == receivedSaveFiles.curShared) ) + { + log_msg("Saving can start\n"); + if (ptChar) + { + writeExtendedSaveFile(PCPlayerData->name, receivedSaveFiles.dataExtended, receivedSaveFiles.sizeExtended); + D2FogMemDeAlloc(receivedSaveFiles.dataExtended,__FILE__,__LINE__,0); + if (active_sharedStash) + writeSharedSaveFile(PCPlayerData->name, receivedSaveFiles.dataShared, receivedSaveFiles.sizeShared, (dataD2Savefile[0x24] & 4) == 4);//6FBAB9A4-6FAA0000 + D2FogMemDeAlloc(receivedSaveFiles.dataShared,__FILE__,__LINE__,0); + ZeroMemory(&receivedSaveFiles,sizeof(receivedSaveFiles)); + } + log_msg("Receive Savefiles completed\n\n"); + } else { + if (ptChar) + { + log_box("Connection error : back up current save file then save with client data."); + backupSharedSaveFile(); + backupExtendedSaveFile(PCPlayerData->name); + SaveSPPlayerCustomData(ptChar); + } + } + log_msg("--- End SaveMPPlayerCustomData. ---\n\n"); +} + + + + + +/* +FCT_ASM ( caller_SendSaveFilesToSave_9 ) + POP ECX + PUSH EAX + PUSH ECX + PUSH EBX + CALL SendSaveFilesToSave + MOV EDX,EBX + MOV ECX,EDI + RETN +}} + +FCT_ASM ( caller_SendSaveFilesToSave ) + POP ECX + PUSH EAX + PUSH ECX + PUSH EBX + CALL SendSaveFilesToSave + MOV EDX,EBX + MOV ECX,EBP + RETN +}} +*/ + +FCT_ASM( caller_ManageNextPacketToSend ) + PUSH ESI + CALL ManageNextPacketToSend + TEST EAX,EAX + JNZ end_caller_ManageNextPacketToSend + XOR ECX,ECX + RETN +end_caller_ManageNextPacketToSend: + MOV ECX,DWORD PTR DS:[ESI+0x17C] + RETN +}} + +FCT_ASM( caller_ManageNextPacketToSend_9 ) + PUSH ESI + CALL ManageNextPacketToSend + TEST EAX,EAX + JNZ end_caller_ManageNextPacketToSend_9 + MOV DWORD PTR DS:[ESI+0x14C],5 + POP ESI + POP ESI + RETN +end_caller_ManageNextPacketToSend_9: + MOV EAX,DWORD PTR DS:[ESI+0x150] + RETN +}} + +FCT_ASM( caller_ManageNextPacketToSend_9d ) + PUSH ESI + CALL ManageNextPacketToSend + TEST EAX,EAX + JNZ end_caller_ManageNextPacketToSend_9d + MOV DWORD PTR DS:[ESI+0x170],5 + POP ESI + POP ESI + RETN +end_caller_ManageNextPacketToSend_9d: + MOV EAX,DWORD PTR DS:[ESI+0x174] + RETN +}} + + + +FCT_ASM( caller_SendSaveFilesToSave_111 ) + PUSH DWORD PTR SS:[ESP+0x2014] + CALL SendSaveFilesToSave + MOV EAX,DWORD PTR SS:[ESP+0x8] + TEST EAX,EAX + RETN +}} + +FCT_ASM( caller_SendSaveFilesToSave ) + PUSH EDI + CALL SendSaveFilesToSave + MOV EDI,DWORD PTR SS:[ESP+0x14] + TEST EDI,EDI + RETN +}} + +FCT_ASM( caller_SendSaveFilesToSave_9 ) + PUSH ESI + CALL SendSaveFilesToSave + MOV ESI,DWORD PTR SS:[ESP+0x14] + TEST ESI,ESI + RETN +}} + + +FCT_ASM ( caller_ReceivedSaveFilesToSave_111 ) + LEA EAX,DWORD PTR SS:[ESP+0x10] + PUSH EAX + CALL ReceiveSaveFilesToSave + TEST EAX,EAX + JE continue_rcvFct + ADD DWORD PTR SS:[ESP],0x3D + RETN +continue_rcvFct: + MOVZX EAX,BYTE PTR SS:[ESP+0x10] + RETN +}} + +FCT_ASM ( caller_ReceivedSaveFilesToSave ) + CMP EDX,-1 + JE continue_rcvFct + PUSH ECX + PUSH EDX + PUSH ECX + CALL ReceiveSaveFilesToSave + POP EDX + POP ECX + TEST EAX,EAX + JE continue_rcvFct + XOR EAX,EAX + ADD ESP,4 + RETN +continue_rcvFct: + POP EAX + SUB ESP,0x5F4//5F4 + JMP EAX +// JMP DWORD PTR SS:[ESP+0x5F0] +}} + +FCT_ASM ( caller_SaveMPPlayerCustomData_111 ) + PUSH EAX + PUSH ECX + PUSH EAX + CALL SaveMPPlayerCustomData + POP ECX + POP EAX + CMP ECX,0xAA55AA55 + RETN +}} + + + +FCT_ASM ( caller_SaveMPPlayerCustomData ) + PUSH ECX + PUSH ECX + CALL SaveMPPlayerCustomData + POP ECX + MOV EAX,DWORD PTR DS:[ECX] + MOV EDX,DWORD PTR DS:[ECX+4] + RETN +}} + + + +void Install_SavePlayerData() +{ + static int isInstalled = false; + if (isInstalled || !active_PlayerCustomData) return; + + log_msg("Patch D2Game & D2Client for save Player's custom data. (SavePlayerData)\n"); + + //Save single player custom data. + mem_seek R7(D2Game, 4DF04, 4E304, 5A624, B9365, 25475, 44165, 53F35); + MEMJ_REF4( D2FogGetSavePath, version_D2Game >= V111 ? caller_SaveSPPlayerCustomData_111 : version_D2Game != V109b ? caller_SaveSPPlayerCustomData : caller_SaveSPPlayerCustomData_9); + //6FC8A623 E8 3E210900 CALL + //02039364 |. E8 3B0FF5FF CALL + //01F95474 |. E8 C34EFEFF CALL + //6FC64164 |. E8 EB61FCFF CALL + //6FC73F34 |. E8 DD63FBFF CALL + + //Send SaveFiles + mem_seek R7(D2Game, 4DFFA, 4E3FA, 5A720, B92DB, 253EB, 440DB, 53EAB); + memt_byte( 0x8B ,0x90); // NOP + memt_byte( version_D2Game >= V111 ? 0x44 : version_D2Game != V109b ? 0x7C : 0x74 ,0xE8); // CALL + MEMT_REF4( version_D2Game >= V111 ? 0xC0850424 : version_D2Game != V109b ? 0xFF851024 : 0xF6851024, version_D2Game >= V111 ? caller_SendSaveFilesToSave_111 : version_D2Game != V109b ? caller_SendSaveFilesToSave : caller_SendSaveFilesToSave_9); + //6FC8A720 |. 8B7C24 10 MOV EDI,DWORD PTR SS:[ESP+10] + //6FC8A724 |. 85FF TEST EDI,EDI + //020392DB |. 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] + //020392DF |. 85C0 TEST EAX,EAX + //01F953EB |. 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] + //01F953EF |. 85C0 TEST EAX,EAX + //6FC640DB |. 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] + //6FC640DF |. 85C0 TEST EAX,EAX + //6FC73EAB |. 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] + //6FC73EAF |. 85C0 TEST EAX,EAX + + mem_seek R7(D2Game, 7993, 7A13, 7BBB, E2943, E6D83, A89D3, 2D173); + memt_byte( 0x8B ,0x90); // NOP + memt_byte( version_D2Game >= V110 ? 0x8E : 0x86 ,0xE8); // CALL + MEMT_REF4( version_D2Game >= V110 ? 0x0000017C : version_D2Game == V109d ? 0x0000174 : 0x00000150, version_D2Game >= V110 ? caller_ManageNextPacketToSend : version_D2Game == V109d ? caller_ManageNextPacketToSend_9d : caller_ManageNextPacketToSend_9); + //6FC37BBB |> 8B8E 7C010000 MOV ECX,DWORD PTR DS:[ESI+17C] + //02062943 |. 8B8E 7C010000 MOV ECX,DWORD PTR DS:[ESI+17C] + //02056D83 |. 8B8E 7C010000 MOV ECX,DWORD PTR DS:[ESI+17C] + //6FCC89D3 |. 8B8E 7C010000 MOV ECX,DWORD PTR DS:[ESI+17C] + //6FC4D173 |. 8B8E 7C010000 MOV ECX,DWORD PTR DS:[ESI+17C] + +// mem_seek R7(D2Game, 7B82, 7C05, 7DCF, 0000, 0000, 0000, 0000);//117FC, 117EC, 11DBC +// memt_byte( 0x8B ,0xE8); // CALL +// MEMT_REF4( (version_D2Game == V110) ? 0x50CD8BD3 : 0x50CF8BD3, (version_D2Game == V110) ? caller_SendSaveFilesToSave : caller_SendSaveFilesToSave_9); + //6FC37DCF |. 8BD3 |MOV EDX,EBX + //6FC37DD1 |. 8BCD |MOV ECX,EBP + //6FC37DD3 |. 50 |PUSH EAX + + if ( version_D2Game >= V111 ) + { + //Received SaveFiles + mem_seek R7(D2Client, 116F0, 116E0, 11CB0, 89246, 32076, 7BCD6, 43946); + memt_byte( 0x0F ,0xE8); + MEMT_REF4( 0x0C2444B6, caller_ReceivedSaveFilesToSave_111); + //6FB39246 |. 0FB64424 0C |MOVZX EAX,BYTE PTR SS:[ESP+C] + //6FAE2076 |. 0FB64424 0C |MOVZX EAX,BYTE PTR SS:[ESP+C] + //6FB2BCD6 |. 0FB64424 0C |MOVZX EAX,BYTE PTR SS:[ESP+C] + //6FAF3946 |. 0FB64424 0C |MOVZX EAX,BYTE PTR SS:[ESP+C] + + // Save multiplayer player custom data. + mem_seek R7(D2Client, 117FC, 117EC, 11DBC, 99AE2, BD7F2, 64A22, AC572); + memt_byte( 0x81 ,0xE8); // CALL + MEMT_REF4( 0x55AA55F9, caller_SaveMPPlayerCustomData_111); + memt_byte( 0xAA ,0x90); // CALL + //6FB49AE2 |. 81F9 55AA55AA CMP ECX,AA55AA55 + //6FB6D7F2 |. 81F9 55AA55AA CMP ECX,AA55AA55 + //6FB14A22 |. 81F9 55AA55AA CMP ECX,AA55AA55 + //6FB5C572 |. 81F9 55AA55AA CMP ECX,AA55AA55 + } else { + //Received SaveFiles + mem_seek R7(D2Client, 116F0, 116E0, 11CB0, 89246, 32076, 7BCD6, 0000); + memt_byte( 0x81 ,0x90); // NOP + memt_byte( 0xEC ,0xE8); // CALL + MEMT_REF4( 0x000005F4, caller_ReceivedSaveFilesToSave); + //6FAB1CB0 |$ 81EC F4050000 SUB ESP,5F4 + + // Save multiplayer player custom data. + mem_seek R7(D2Client, 117FC, 117EC, 11DBC, 99AE2, BD7F2, 64A22, 0000); + memt_byte( 0x8B ,0xE8); // CALL + MEMT_REF4( 0x04518B01, caller_SaveMPPlayerCustomData); + //6FAB1DBC |. 8B01 MOV EAX,DWORD PTR DS:[ECX] + //6FAB1DBE |. 8B51 04 MOV EDX,DWORD PTR DS:[ECX+4] + } + + if ( version_D2Game == V109b || version_D2Game == V109d ) + customPackID = 0xAB; + else if ( version_D2Game >= V111 ) + customPackID++; + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/SharedSaveFile.cpp b/PlugY/SharedSaveFile.cpp new file mode 100644 index 0000000..139db8a --- /dev/null +++ b/PlugY/SharedSaveFile.cpp @@ -0,0 +1,221 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Add an extra save file shared by all own characters. + +=================================================================*/ + +#include "common.h" +#include "sharedSaveFile.h" +#include "error.h" +#include "d2functions.h" +#include "infinityStash.h" +#include "customLibraries.h" + +#define FILE_SHAREDSTASH 0x00535353 //"SSS " +#define BUFFER_SIZE 0x4000 +#define FILE_VERSION 0x3230 //"02" + +//6FC8CE8A |. E8 A16BFAFF CALL D2Game.6FC33A30 +//$+C0 > 1F 00 00 00 03 00 00 06 ..... +// 28 0010 1000 +BYTE* readSharedSaveFile(char* name, DWORD* size) +{ + char filename[512]; + BYTE* data=NULL; + BYTE isHardCore=0; + FILE* file=NULL; + + if (separateHardSoftStash)//Get hardcore flag + { + D2FogGetSavePath( filename, 512-strlen(name)-5); + strcat(filename,name); + strcat(filename,".d2s"); + log_msg("Normal file to read if it's hardcore character : %s\n",filename); + file = fopen(filename, "rb"); + if (file) + { + fseek(file, 0x24, SEEK_SET); + DWORD nbRead = fread(&isHardCore, 1, 1, file); + isHardCore = (nbRead==1)? ((isHardCore & 4) == 4) : 0; + fclose(file); + file=NULL; + } + log_msg("%s is a HardCore character = %d\n",name,isHardCore); + } + + if (active_sharedStash) + { + D2FogGetSavePath( filename, 512-strlen("_LOD_HC_SharedStashSave")-5); + strcat(filename,isHardCore? "_LOD_HC_" : "_LOD_"); + strcat(filename, sharedStashFilename); + strcat(filename,".sss"); + + log_msg("Shared file to read : %s\n",filename); + + file = fopen(filename, "rb"); + } + + if (file) + { + fseek(file, 0, SEEK_END); + *size = ftell(file); + fseek(file, 0, SEEK_SET); + data = (BYTE*)D2FogMemAlloc(*size,__FILE__,__LINE__,0); + DWORD nbRead = fread(data, 1, *size, file); + fclose(file); + d2_assert(nbRead != *size , "nbRead from shared save file != size", __FILE__, __LINE__); + } else { + log_msg("Can't open shared save file in mode \"rb\" (is not an error if it's the first start of the mod)\n"); + *size = 14; + DWORD maxSize = 100; + data = (BYTE*)D2FogMemAlloc(maxSize,__FILE__,__LINE__,0); + *((DWORD *)&data[0]) = FILE_SHAREDSTASH; + *((WORD *)&data[4]) = FILE_VERSION; + *((DWORD *)&data[6]) = 0; + *((DWORD *)&data[10]) = 0;// number of stash + + TCustomDll* currentDll = customDlls; + while (currentDll) + { + currentDll->initSharedSaveFile(&data, &maxSize, size); + currentDll=currentDll->nextDll; + } + } + + return data; +} + + +int loadSharedSaveFile(Unit* ptChar, BYTE data[], DWORD maxSize) +{ + if ( !ptChar || !data) return false; + + log_msg("Load shared file\n"); + + DWORD curSize = 0; + + if (*(DWORD*)&data[curSize] != FILE_SHAREDSTASH) + { + log_msg("loadSharedSaveFile -> bad header\n"); + return 9; + } + curSize += 4; + + if (*(WORD *)&data[curSize] == 0x3130) {//"01" + curSize += 2; + PCPY->sharedGold = 0; + } else if (*(WORD *)&data[curSize] == FILE_VERSION) { + curSize += 2; + PCPY->sharedGold = *(DWORD*)&data[curSize]; + curSize += 4; + } else { + log_msg("loadSharedSaveFile -> bad file version : %04X\n", *(WORD *)&data[curSize]); + return 9; + } + + int ret = loadStashList(ptChar, data, maxSize, &curSize, true); + + TCustomDll* currentDll = customDlls; + while (!ret && currentDll) + { + ret = currentDll->loadSharedSaveFile(ptChar, data, maxSize, &curSize); + currentDll=currentDll->nextDll; + } + + PCPY->sharedStashIsOpened = true; + return ret; +} + + +void writeSharedSaveFile(char* name, BYTE* data, DWORD size, bool isHardcore) +{ + char szTempName[MAX_PATH]; + char szSaveName[MAX_PATH]; + + //Get temporary savefile name. + D2FogGetSavePath( szTempName, MAX_PATH-30); + strcat(szTempName, separateHardSoftStash && isHardcore? "_LOD_HC_" : "_LOD_"); + strcat(szTempName, sharedStashFilename); + strcat(szTempName,".ss~"); + log_msg("Shared temporary file for saving : %s\n", szTempName); + + //Write data in savefile. + FILE* customSaveFile = fopen(szTempName, "wb+"); + fwrite(data, size, 1, customSaveFile); + fclose(customSaveFile); + + //Get real savefile name. + D2FogGetSavePath( szSaveName, MAX_PATH-30); + strcat(szSaveName, separateHardSoftStash && isHardcore? "_LOD_HC_" : "_LOD_"); + strcat(szSaveName, sharedStashFilename); + strcat(szSaveName,".sss"); + log_msg("Shared file for saving : %s\n", szSaveName); + +// if (!MoveFileEx(szTempName, szSaveName, MOVEFILE_WRITE_THROUGH|MOVEFILE_REPLACE_EXISTING)) + DeleteFile(szSaveName); + if (!MoveFile(szTempName, szSaveName)) + log_box("Could not create the shared save file."); +} + +void backupSharedSaveFile() +{ + char szBackupName[MAX_PATH]; + char szSaveName[MAX_PATH]; + + D2FogGetSavePath( szSaveName, MAX_PATH-30); + strcat(szSaveName, "_LOD_"); + strcat(szSaveName, sharedStashFilename); + strcat(szSaveName,".sss"); + + D2FogGetSavePath( szBackupName, MAX_PATH-30); + strcat(szBackupName, "_LOD_"); + strcat(szBackupName, sharedStashFilename); + strcat(szBackupName,".sss.backup"); + + CopyFile(szSaveName, szBackupName, true); + + if (separateHardSoftStash) + { + D2FogGetSavePath( szSaveName, MAX_PATH-30); + strcat(szSaveName, "_LOD_HC_"); + strcat(szSaveName, sharedStashFilename); + strcat(szSaveName,".sss"); + + D2FogGetSavePath( szBackupName, MAX_PATH-30); + strcat(szBackupName, "_LOD_HC_"); + strcat(szBackupName, sharedStashFilename); + strcat(szBackupName,".sss.backup"); + + CopyFile(szSaveName, szBackupName, true); + } +} + + +void saveSharedSaveFile(Unit* ptChar, BYTE** data, DWORD* maxSize, DWORD* curSize) +{ + *(DWORD *)(*data + *curSize) = FILE_SHAREDSTASH; + *curSize += 4; + if (PCPY->sharedGold) + { + *(WORD *)(*data + *curSize) = FILE_VERSION; + *curSize += 2; + + *(DWORD *)(*data + *curSize) = PCPY->sharedGold; + *curSize += 4; + } else { + *(WORD *)(*data + *curSize) = 0x3130; + *curSize += 2; + } + saveStashList(ptChar, PCPY->sharedStash, data, maxSize, curSize); + + TCustomDll* currentDll = customDlls; + while (currentDll) + { + currentDll->saveSharedSaveFile(ptChar, data, maxSize, curSize); + currentDll=currentDll->nextDll; + } +} + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/SkillPerLevelUp.cpp b/PlugY/SkillPerLevelUp.cpp new file mode 100644 index 0000000..3bec02c --- /dev/null +++ b/PlugY/SkillPerLevelUp.cpp @@ -0,0 +1,53 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Change Skill win per level up. + +=================================================================*/ + +#include "skillPerLevelUp.h" +#include "common.h" +#include "error.h" +#include "d2functions.h" + +bool active_SkillPerLevelUpChange=0; +DWORD skillPerLevelUp=1; + + +FCT_ASM ( caller_changeSkillPerLevelUp_111 ) + MOV EAX,skillPerLevelUp + IMUL EAX,EBX + MOV DWORD PTR SS:[ESP+0xC], EAX + JMP V2AddPlayerStat +}} + + +FCT_ASM ( caller_changeSkillPerLevelUp ) + MOV EAX,skillPerLevelUp + IMUL EAX,EDI + MOV DWORD PTR SS:[ESP+0xC], EAX + JMP V2AddPlayerStat +}} + +void Install_SkillPerLevelUp() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Game for change Skill points win per level up. (SkillPerLevelUp)\n"); + + mem_seek R7(D2Game, 42261, 42651, 4ED60, D7AE5, 79695, AA455, EB1E5); + MEMJ_REF4( V2AddPlayerStat, version_D2Game >= V111 ? caller_changeSkillPerLevelUp_111 : caller_changeSkillPerLevelUp); + //6FC7ED5F |. E8 56CB0900 CALL + //02057AE4 |. E8 9F28F3FF CALL + //01FE9694 |. E8 1B0DF9FF CALL + //6FCCA454 |. E8 5F01F6FF CALL + //6FD0B1E4 |. E8 E9F2F1FF CALL + + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/SkillsPoints.cpp b/PlugY/SkillsPoints.cpp new file mode 100644 index 0000000..a310f45 --- /dev/null +++ b/PlugY/SkillsPoints.cpp @@ -0,0 +1,97 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Unassign Skill Point for futher re-assignment. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" +#include "updateServer.h" +#include "interface_Skills.h" // Install_InterfaceSkills() + +bool active_SkillsPoints=0; +bool unassignSkillsPointsOneByOne=0; + +int (*getskPoint)(SkillData* ptSkill); +int (*getCharClass)(SkillData* ptSkill); +TD2GetPlayerStat getSingleSkillValue; + +int getskPoint_109(SkillData* ptSkill) {return -1;} +int getskPoint_11X(SkillData* ptSkill) {return ptSkill->ptSkillBin->skpoints;} + +int getCharClass_109(SkillData* ptSkill) {return *(&ptSkill->ptSkillBin->charclass+8);} +int getCharClass_11X(SkillData* ptSkill) {return ptSkill->ptSkillBin->charclass;} + +int STDCALL getSingleSkillValue_109(Unit* ptChar, DWORD , DWORD skillID) +{ + DWORD stat; + DWORD ret=0; + stat = D2GetPlayerStat(ptChar, STATS_ITEM_SINGLESKILL+0, skillID); + if ((stat & 255) == skillID) ret += (stat >> 8) & 255; + stat = D2GetPlayerStat(ptChar, STATS_ITEM_SINGLESKILL+1, skillID); + if ((stat & 255) == skillID) ret += (stat >> 8) & 255; + stat = D2GetPlayerStat(ptChar, STATS_ITEM_SINGLESKILL+2, skillID); + if ((stat & 255) == skillID) ret += (stat >> 8) & 255; + return ret; +} + +void UnassignAllSkillsPoints(Unit* ptChar) +{ + DWORD skillID, keepBonus, maxSkillLevel; + int skpoints; + DWORD nbPoints = 0; + void* ptClient = D2GetClient(ptChar,__FILE__,__LINE__); + SkillData* ptSkill = PCSkills->ptFirstSkill; + while (ptSkill) + { + if (getCharClass(ptSkill) == ptChar->nPlayerClass)//ptSkill->ptSkillBin->charclass + if (ptSkill->state == -1) + { + skillID = ptSkill->ptSkillBin->skillID; + keepBonus = !getSingleSkillValue(ptChar, STATS_ITEM_SINGLESKILL, skillID); + maxSkillLevel = D2GetSkillLevel(ptChar, ptSkill, 0); + skpoints = getskPoint(ptSkill); + if (skpoints == -1 || unassignSkillsPointsOneByOne) + { + D2SetSkillBaseLevel(ptChar, skillID, 0, keepBonus, __FILE__, __LINE__); + nbPoints += maxSkillLevel; + } else { + while (maxSkillLevel--) + { + D2SetSkillBaseLevel(ptChar, skillID, maxSkillLevel, keepBonus, __FILE__, __LINE__); + nbPoints += D2GetSkillCost(ptChar, skpoints, skillID, maxSkillLevel); + } + } + D2SetSkillBaseLevelOnClient(ptClient, ptChar, skillID, 0, keepBonus); + } + ptSkill = ptSkill->ptNextSkill; + } + // Add new free skill points + D2AddPlayerStat( ptChar, STATS_NEWSKILLS, nbPoints, 0 ); +} + +void Install_SkillsPoints() +{ + static int isInstalled = false; + if (isInstalled) return; + + Install_InterfaceSkills(); + Install_UpdateServer(); + + if ( version_D2Common >= V110 ) + { + getskPoint = getskPoint_11X; + getCharClass = getCharClass_11X; + getSingleSkillValue = D2GetPlayerStat; + } else { + getskPoint = getskPoint_109; + getCharClass = getCharClass_109; + getSingleSkillValue = getSingleSkillValue_109; + } + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/StatPerLevelUp.cpp b/PlugY/StatPerLevelUp.cpp new file mode 100644 index 0000000..747429c --- /dev/null +++ b/PlugY/StatPerLevelUp.cpp @@ -0,0 +1,50 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Change Stat win per level up. + +=================================================================*/ + +#include "statPerLevelUp.h" +#include "common.h" +#include "error.h" +#include "d2functions.h" + +bool active_StatPerLevelUpChange=0; +DWORD statPerLevelUp=5; + +FCT_ASM ( caller_changeStatPerLevelUp_111 ) + MOV EAX,statPerLevelUp + IMUL EAX,EBX + MOV DWORD PTR SS:[ESP+0xC], EAX + JMP V2AddPlayerStat +}} + +FCT_ASM ( caller_changeStatPerLevelUp ) + MOV EAX,statPerLevelUp + IMUL EAX,EDI + MOV DWORD PTR SS:[ESP+0xC], EAX + JMP V2AddPlayerStat +}} + +void Install_StatPerLevelUp() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Game for change Stat points win per level up. (StatPerLevelUp)\n"); + + mem_seek R7(D2Game, 42258, 42648, 4ED55, D7ADA, 7968A, AA44A, EB1DA); + MEMJ_REF4( V2AddPlayerStat, version_D2Game >= V111 ? caller_changeStatPerLevelUp_111 : caller_changeStatPerLevelUp); + //6FC7ED54 |. E8 61CB0900 CALL + //02057AD9 |. E8 AA28F3FF CALL + //01FE9689 |. E8 260DF9FF CALL + //6FCCA449 |. E8 6A01F6FF CALL + //6FD0B1D9 |. E8 F4F2F1FF CALL + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/StatsPoints.cpp b/PlugY/StatsPoints.cpp new file mode 100644 index 0000000..f56b45b --- /dev/null +++ b/PlugY/StatsPoints.cpp @@ -0,0 +1,494 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Unassign Stats Point for futher re-assignment. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" + +#include "plugYFiles.h" // Install_PlugYImagesFiles() +#include "interface_Stats.h" // Install_InterfaceStats() +#include "updateServer.h" +#include + +bool active_StatsPoints=0; +DWORD keyUsedForUnassignStatPoint=VK_CONTROL; +bool active_StatsShiftClickLimit=1; +DWORD limitValueToShiftClick=5; + +void UnassignStr(Unit* ptChar, int nb) +{ + log_msg("Start Unassign Strengh\n"); + + int currentStr, removePtsNb; + CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass); + + currentStr = D2GetPlayerBaseStat( ptChar, STATS_STRENGTH, 0 ); + if (currentStr <= charStats->baseSTR) return; + removePtsNb = currentStr - charStats->baseSTR >= nb ? nb : currentStr - charStats->baseSTR; + if (currentStr - removePtsNb < 1) removePtsNb = currentStr - 1; + + log_msg("Start Unassign Strengh (cur %d, base %d, rem %d)\n",currentStr,charStats->baseSTR,removePtsNb); + D2AddPlayerStat( ptChar, STATS_STRENGTH, -removePtsNb ,0 ); + D2AddPlayerStat( ptChar, STATS_STATPTS, removePtsNb ,0 ); +} + +void UnassignDex(Unit* ptChar, int nb) +{ + log_msg("Start Unassign Dexterity\n"); + + int currentDex, removePtsNb; + CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass); + + currentDex = D2GetPlayerBaseStat( ptChar, STATS_DEXTERITY, 0 ); + if (currentDex <= charStats->baseDEX) return; + removePtsNb = currentDex - charStats->baseDEX >= nb ? nb : currentDex - charStats->baseDEX; + if (currentDex - removePtsNb < 1) removePtsNb = currentDex - 1; + + log_msg("Start Unassign Dexterity (cur %d, base %d, rem %d)\n",currentDex,charStats->baseDEX,removePtsNb); + D2AddPlayerStat( ptChar, STATS_DEXTERITY, -removePtsNb ,0 ); + D2AddPlayerStat( ptChar, STATS_STATPTS, removePtsNb ,0 ); +} + +void UnassignVit(Unit* ptChar, int nb) +{ + log_msg("Start Unassign Vitality\n"); + + int currentVit, removePtsNb, removeVitNb, removeStaNb; + CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass); + + currentVit = D2GetPlayerBaseStat( ptChar, STATS_VITALITY, 0 ); + if (currentVit <= charStats->baseVIT) return; + removePtsNb = currentVit - charStats->baseVIT >= nb ? nb : currentVit - charStats->baseVIT; + if (currentVit - removePtsNb < 1) removePtsNb = currentVit - 1; + removeVitNb = removePtsNb * (charStats->lifePerVitality << 6); + removeStaNb = removePtsNb * (charStats->staminaPerVitality << 6); + + log_msg("Start Unassign Vitality (cur %d, base %d, rem %d)\n",currentVit,charStats->baseVIT,removePtsNb); + D2AddPlayerStat( ptChar, STATS_VITALITY, -removePtsNb ,0 ); + D2AddPlayerStat( ptChar, STATS_MAXHP, -removeVitNb ,0 ); + D2AddPlayerStat( ptChar, STATS_MAXSTAMINA, -removeStaNb ,0 ); + D2AddPlayerStat( ptChar, STATS_STATPTS, removePtsNb ,0 ); +} + +void UnassignEne(Unit* ptChar, int nb) +{ + log_msg("Start Unassign Energy\n"); + + int currentEne, removePtsNb, removeManNb; + CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass); + + currentEne = D2GetPlayerBaseStat( ptChar, STATS_ENERGY, 0); + if (currentEne <= charStats->baseENE) return; + removePtsNb = currentEne - charStats->baseENE >= nb ? nb : currentEne - charStats->baseENE; + if (currentEne - removePtsNb < 1) removePtsNb = currentEne - 1; + removeManNb = removePtsNb * (charStats->manaPerMagic << 6); + + log_msg("Start Unassign Energy (cur %d, base %d, rem %d)\n",currentEne,charStats->baseENE,removePtsNb); + D2AddPlayerStat( ptChar, STATS_ENERGY, -removePtsNb ,0 ); + D2AddPlayerStat( ptChar, STATS_MAXMANA, -removeManNb ,0 ); + D2AddPlayerStat( ptChar, STATS_STATPTS, removePtsNb ,0 ); +} + +void UnassignStrPoint(Unit* ptChar) +{ + UnassignStr(ptChar, 1); +} + +void UnassignStrPoints(Unit* ptChar) +{ + UnassignStr(ptChar, active_StatsShiftClickLimit ? limitValueToShiftClick: 0x7FFFFFFF); +} + +void UnassignDexPoint(Unit* ptChar) +{ + UnassignDex(ptChar, 1); +} + +void UnassignDexPoints(Unit* ptChar) +{ + UnassignDex(ptChar, active_StatsShiftClickLimit ? limitValueToShiftClick: 0x7FFFFFFF); +} + +void UnassignVitPoint(Unit* ptChar) +{ + UnassignVit(ptChar, 1); +} + +void UnassignVitPoints(Unit* ptChar) +{ + UnassignVit(ptChar, active_StatsShiftClickLimit ? limitValueToShiftClick: 0x7FFFFFFF); +} + +void UnassignEnePoint(Unit* ptChar) +{ + UnassignEne(ptChar, 1); +} + +void UnassignEnePoints(Unit* ptChar) +{ + UnassignEne(ptChar, active_StatsShiftClickLimit ? limitValueToShiftClick: 0x7FFFFFFF); +} + + +////////////////////////////////// + + +void STDCALL printDisabledStatsBtn(WORD statID, sDrawImageInfo* data, DWORD x, DWORD y, DWORD p4, DWORD p5, DWORD p6) +{ + if ( onRealm || !D2isLODGame()) + { + D2PrintImage(data,x,y,p4,p5,p6); + return; + } + Unit* ptChar = D2GetClientPlayer(); + + CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass); + int minValue=1; + switch (statID) + { + case STATS_STRENGTH: minValue = charStats->baseSTR; break; + case STATS_DEXTERITY: minValue = charStats->baseDEX; break; + case STATS_VITALITY: minValue = charStats->baseVIT; break; + case STATS_ENERGY: minValue = charStats->baseENE; break; + } + int statValue = D2GetPlayerBaseStat(ptChar, statID, 0); + + if (isOnRect(D2GetMouseX(),D2GetMouseY(),x+5,y+5,32,32)) + { + WCHAR text[100]; + if (active_StatsShiftClickLimit) + swprintf(text, getTranslatedString(STR_STATS_UNASSIGN_WITH_LIMIT),limitValueToShiftClick); + else + swprintf(text, getTranslatedString(STR_STATS_UNASSIGN_WITHOUT_LIMIT)); + wcscat(text,L"\n"); + swprintf(text+wcslen(text), getTranslatedString(STR_STATS_BASE_MIN), statValue, minValue); + D2SetFont(1); + D2PrintPopup(text, x+18, y-32, WHITE, 1); + } + + if ( GetKeyState(keyUsedForUnassignStatPoint) >= 0) { + if ( D2GetPlayerBaseStat(ptChar, 4, 0) <= 0) + setFrame(data, 2); + } else { + setImage(data, unassignStatsBtnImages); + if (minValue >= statValue) + setFrame(data, 2); + } + + D2PrintImage(data,x,y,p4,p5,p6); +} + +FCT_ASM ( caller_printUnassignStatsBtn ) + POP EAX + XOR ECX,ECX + MOV CX,WORD PTR DS:[ESI+8] + PUSH ECX + PUSH EAX + JMP printDisabledStatsBtn +}} + + + +BYTE currentMsgID=0; + +WORD UnassignStats() +{ + if (onRealm || !D2isLODGame()) return 0; + return GetKeyState(keyUsedForUnassignStatPoint); +} + +FCT_ASM ( caller_UnassignStats_9 ) + PUSH EAX + CALL UnassignStats + TEST AX,AX + POP EAX + JNL NOT_CTRL + + MOV currentMsgID,0x10 + TEST AX,AX + JNL NOT_SHIFT + ADD currentMsgID,4 +NOT_SHIFT: + MOV EAX,1 + MOV ESI,EAX + RETN + +NOT_CTRL: + MOV currentMsgID,0 + TEST AX,AX + MOV EAX,1 + RETN +}} + + +FCT_ASM ( caller_UnassignStats ) + PUSH EAX + CALL UnassignStats + TEST AX,AX + POP EAX + JNL NOT_CTRL + + MOV currentMsgID,0x10 + TEST AX,AX + JNL NOT_SHIFT + ADD currentMsgID,4 +NOT_SHIFT: + MOV ESI,1 + ADD DWORD PTR SS:[ESP],0xB + RETN + +NOT_CTRL: + MOV currentMsgID,0 + TEST AX,AX + JNL END_UNASSGNSTATS + ADD DWORD PTR SS:[ESP],0x7 +END_UNASSGNSTATS: + RETN +}} + + +FCT_ASM ( caller_setValue_111 ) + ADD CL,currentMsgID + MOV WORD PTR SS:[ESP+0x19],CX + RETN +}} + +FCT_ASM ( caller_setValue ) + ADD DL,currentMsgID + JMP D2SendToServer3 +}} + + + +DWORD STDCALL pushDown (DWORD num) +{ + Unit* ptChar = D2GetClientPlayer(); + + if ( !D2isLODGame() || GetKeyState(keyUsedForUnassignStatPoint) >= 0)//GetAsyncKeyState + { + if ( D2GetPlayerBaseStat(ptChar, 4, 0) > 0) + return 1; + } else { + CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass); + switch (num) + { + case 0: if ((DWORD)charStats->baseSTR < (DWORD)D2GetPlayerBaseStat(ptChar, STATS_STRENGTH, 0)) + return 1; break; + case 1: if ((DWORD)charStats->baseDEX < (DWORD)D2GetPlayerBaseStat(ptChar, STATS_DEXTERITY, 0)) + return 1; break; + case 2: if ((DWORD)charStats->baseVIT < (DWORD)D2GetPlayerBaseStat(ptChar, STATS_VITALITY, 0)) + return 1; break; + case 3: if ((DWORD)charStats->baseENE < (DWORD)D2GetPlayerBaseStat(ptChar, STATS_ENERGY, 0)) + return 1; break; + } + } + return 0; +} + +FCT_ASM ( caller_pushDown_111 ) + PUSH EDX + PUSH EDX + CALL pushDown + POP EDX + TEST EAX,EAX + JNZ end_pushDown + SUB DWORD PTR SS:[ESP],0x22 + RETN +end_pushDown: + MOV EDI,1 + RETN +}} + +FCT_ASM ( caller_pushDown ) + PUSH EDX + PUSH EDX + CALL pushDown + POP EDX + TEST EAX,EAX + JNZ end_pushDown + SUB DWORD PTR SS:[ESP],0x22 + RETN +end_pushDown: + LEA EAX,DWORD PTR DS:[EDX*8] + RETN +}} + + +void Install_StatsPoints() +{ + static int isInstalled = false; + if (isInstalled) return; + + Install_PlugYImagesFiles(); +// Install_InterfaceStats(); + Install_UpdateServer(); + + log_msg("Patch D2Client for unassign stat points when specified key is press. (StatsPoints)\n"); +//if ( version_D2Client < V113 ) +{ + // Always print stat button images. + mem_seek R7(D2Client, 29B12, 29B02, 30073, 82BBA, 8963A, 6B59A, BD1B5); + memt_byte( 0x8B, 0xEB ); // JMP SHORT D2Client.6FAD0088 + memt_byte( 0x4C, V7(D2Client, 12, 12, 13, 13, 13, 13, 13) ); + memt_byte( 0x24, 0x90 ); // NOP + memt_byte( V7(D2Client, 20, 20, 14, 1C, 1C, 1C, 1C), 0x90 ); // NOP (V109d:0x20 , V110:0x14 + //6FAD0073 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+14] + //6FB32BBA > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C] + //6FB3963A > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C] + //6FB1B59A > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C] + //6FB6D1B5 |> 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C] + + //print our buttons + mem_seek R7(D2Client, 29B9D, 29B8D, 300FD, 82C54, 896D4, 6B637, BD23E); + MEMJ_REF4( D2PrintImage, caller_printUnassignStatsBtn); + //6FB32C53 . E8 82A3F8FF CALL + //6FB396D3 . E8 D238F8FF CALL + //6FB1B636 . E8 431AFAFF CALL + //6FB6D23D . E8 54FEF4FF CALL + + // Always manage push down. + mem_seek R7(D2Client, 2AA7B, 2AA6B, 3134D, 827D9, 89259, 6B1B9, BCDD9); + memt_byte( 0x74, 0x90 ); // NOP + memt_byte( 0x4E, 0x90 ); // NOP + //6FAD134D 74 4E JE SHORT D2Client.6FAD139D + //6FB327D9 . 74 4E JE SHORT D2Client.6FB32829 + //6FB39259 . 74 4E JE SHORT D2Client.6FB392A9 + //6FB1B1B9 74 4E JE SHORT D2Client.6FB1B209 + //6FB6CDD9 . 74 4E JE SHORT D2Client.6FB6CE29 + + if ( version_D2Client >= V111 ) + { + // On Push down. + mem_seek R7(D2Client, 2AAE6, 2AAD6, 313B8, 82844, 892C4, 6B224, BCE44); + memt_byte( 0x6B, 0xE8 ); + MEMT_REF4( 0x01BF0ED2, caller_pushDown_111); + memt_byte( 0x00, 0x6B ); // IMUL EDX,EDX,0E + memt_byte( 0x00, 0xD2 ); + memt_byte( 0x00, 0x0E ); + //6FB32844 > 6BD2 0E IMUL EDX,EDX,0E + //6FB32847 . BF 01000000 MOV EDI,1 + //6FB392C4 > 6BD2 0E IMUL EDX,EDX,0E + //6FB392C7 . BF 01000000 MOV EDI,1 + //6FB1B224 6BD2 0E IMUL EDX,EDX,0E + //6FB1B227 BF 01000000 MOV EDI,1 + //6FB6CE44 > 6BD2 0E IMUL EDX,EDX,0E + //6FB6CE47 . BF 01000000 MOV EDI,1 + + } else { + // On Push down. + mem_seek R7(D2Client, 2AAE6, 2AAD6, 313B8, 82844, 892C4, 0000, 0000); + memt_byte( 0x8D, 0xE8 ); // CALL + MEMT_REF4( 0x0000D504, caller_pushDown); + memt_byte( 0x00, 0x90 ); // NOP + memt_byte( 0x00, 0x90 ); // NOP + //6FAD13B8 8D04D5 00000000 LEA EAX,DWORD PTR DS:[EDX*8] + } + + + if ( version_D2Client >= V110 ) + { + // Always manage push up. + mem_seek R7(D2Client, 0000, 0000, 3152E, 83869, 8A2E9, 6C249, BDE49); + memt_byte( 0x74, 0x90 ); // NOP + memt_byte( version_D2Client >= V111 ? 0x65 : 0x68, 0x90 ); // NOP + //6FAD152E 74 68 JE SHORT D2Client.6FAD1598 + //6FB33869 . 74 65 JE SHORT D2Client.6FB338D0 + //6FB3A2E9 . 74 65 JE SHORT D2Client.6FB3A350 + //6FB1C249 74 65 JE SHORT D2Client.6FB1C2B0 + //6FB6DE49 . 74 65 JE SHORT D2Client.6FB6DEB0 + + // Unassign stats point when ctrl is push. + mem_seek R7(D2Client, 0000, 0000, 315D3, 8391B, 8A39B, 6C2FB, BDEFB); + memt_byte( 0x66, 0xE8 ); // CALL + MEMT_REF4( 0x077CC085, caller_UnassignStats); + //6FAD15D3 . 66:85C0 TEST AX,AX + //6FAD15D6 . 7C 07 JL SHORT D2Client.6FAD15DF + //6FB3391B . 66:85C0 TEST AX,AX + //6FB3391E . 7C 07 JL SHORT D2Client.6FB33927 + //6FB3A39B . 66:85C0 TEST AX,AX + //6FB3A39E . 7C 07 JL SHORT D2Client.6FB3A3A7 + //6FB1C2FB . 66:85C0 TEST AX,AX + //6FB1C2FE . 7C 07 JL SHORT D2Client.6FB1C307 + //6FB6DEFB . 66:85C0 TEST AX,AX + //6FB6DEFE . 7C 07 JL SHORT D2Client.6FB6DF07 + } else { + // Always manage push up. + mem_seek R7(D2Client, 2AC55, 2AC45, 0000, 0000, 0000, 0000, 0000); + memt_byte( 0x0F, 0x90 ); // NOP + memt_byte( 0x84, 0x90 ); // NOP + memt_dword( 0x000000AE, 0x90909090 ); // NOP NOP NOP NOP + //6FACAC45 . 0F84 AE000000 JE D2Client.6FACACF9 + + // Unassign stats point when ctrl is push. + mem_seek R7(D2Client, 2ACD9, 2ACC9, 0000, 0000, 0000, 0000, 0000); + memt_byte( 0xB8, 0xE8 ); // CALL + MEMT_REF4( 0x00000001, caller_UnassignStats_9); + //6FACACC9 . B8 01000000 MOV EAX,1 + } + + // Set the id for the calling function. + mem_seek R7(D2Client, 2AD02, 2ACF2, 31611, 8395E, 8A3DE, 6C33E, BDF3E); + if ( version_D2Client >= V111 ) { + memt_byte( 0x66, 0xE8 ); // CALL + MEMT_REF4( 0x15244C89, caller_setValue_111); + //6FB3395E . 66:894C24 15 MOV WORD PTR SS:[ESP+15],CX + //6FB3A3DE . 66:894C24 15 MOV WORD PTR SS:[ESP+15],CX + //6FB1C33E . 66:894C24 15 MOV WORD PTR SS:[ESP+15],CX ; | + //6FB6DF3E . 66:894C24 15 MOV WORD PTR SS:[ESP+15],CX ; | + } else { + MEMC_REF4( D2SendToServer3, caller_setValue); + //6FAD1610 . E8 7BC3FDFF CALL D2Client.6FAAD990 + } +} log_msg("\n"); + + isInstalled = true; +} + +/*********************************************************************************/ + + +FCT_ASM ( caller_LimitShift_111 ) + CMP EDI,limitValueToShiftClick + JL DontTruncTheValue + MOV EDI,limitValueToShiftClick +DontTruncTheValue: + JMP DWORD PTR DS:[GetKeyState] +}} + +FCT_ASM ( caller_LimitShift ) + CMP ESI,limitValueToShiftClick + JL DontTruncTheValue + MOV ESI,limitValueToShiftClick +DontTruncTheValue: + JMP DWORD PTR DS:[GetKeyState] +}} + +void Install_StatsLimitShiftClick() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Client for limit the assigment of stat points when shift is used. (LimitShift)\n"); + + // Limit the assigment of stat points. + mem_seek R7(D2Client, 2ACD0, 2ACC0, 315CD, 83915, 8A395, 6C2F5, BDEF5); + memt_byte( 0xFF, 0x90 ); // NOP + memt_byte( 0x15, 0xE8 ); // CALL + MEMD_REF4( GetKeyState, version_D2Client >= V111 ? caller_LimitShift_111 : caller_LimitShift); + //6FAD15CD . FF15 68E0B66F CALL DWORD PTR DS:[<&USER32.GetKeyState>] + //6FB33915 . FF15 CCF0B76F CALL DWORD PTR DS:[<&USER32.GetKeyState>] + //6FB3A395 . FF15 08F1B76F CALL DWORD PTR DS:[<&USER32.GetKeyState>] + //6FB1C2F5 . FF15 10F1B76F CALL DWORD PTR DS:[<&USER32.GetKeyState>>; \GetKeyState + //6FB6DEF5 . FF15 04F1B76F CALL DWORD PTR DS:[<&USER32.GetKeyState>>; \GetKeyState + + log_msg("\n"); + + isInstalled = true; +} + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/UberQuest.cpp b/PlugY/UberQuest.cpp new file mode 100644 index 0000000..c4fc399 --- /dev/null +++ b/PlugY/UberQuest.cpp @@ -0,0 +1,401 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Uber Quest Management. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" + +bool active_UberQuest=0; + +/* + void* ptQuest = D2GetPlayerData(ptChar)->ptQuest[ptGame->difficultyLevel]; + if (D2CheckQuestState(ptGame->game10F4[0xC],4,0xB) || + D2CheckQuestState(ptQuest,4,0xA) || + ptGame->ptIsLodGame && !D2CheckQuestState(ptQuest,0x28,0) +// !ptGame->ptIsLodGame && D2CheckQuestState(ptQuest,0x1A,0)TODO for !ptGame->ptIsLodGame... + { +// d2_assert(!ptChar,"openPandPortal : ptChar==NULL",__FILE__,__LINE__); +// ptChar->v6E = 0x14; +// ptChar->v70 = ptChar; +// D2Common10148(ptChar); +// ptChar->flag400 = 1; +// return 0; + } + Room* = ptRoom = D2GetRoom(ptChar); + if (D2GetLevelID(ptRoom) != 1) return 0; + Position pos1; + D2GetPosition(ptChar, &pos1); + void* ptPortal = NULL; + D2Game02059FE0(ptRoom,&pos1,3,0x400,&ptPortal,0x64); + if (!ptPortal) return 0; + Position pos2; + pos2.x = pos1.x; + pos2.y = pos1.y; + testing crash useless... + D2GetDropRoom(ptRoom, &pos2, &pos2,3,0x3E01,0xC01,0); +*/ + +/* +void* FASTCALL D2Game01F81090(Room* ptRoom, DWORD x, DWORD y);//0x1090 + +*/ + +#define OBJECT_PERMANENT_PORTAL 0x3C +#define LEVEL_ACT5TOWN 109 +#define LEVEL_ACT5_PANDEMONIUM1 133 +#define LEVEL_ACT5_PANDEMONIUM2 134 +#define LEVEL_ACT5_PANDEMONIUM3 135 +#define LEVEL_ACT5_PANDEMONIUM_FINAL 136 + +static struct +{ + union{ + DWORD all; + struct{ + DWORD portal1Opened:1; + DWORD portal2Opened:1; + DWORD portal3Opened:1; + DWORD portal4Opened:1; + DWORD uber1Spawned:1; + DWORD uber2Spawned:1; + DWORD uber3Spawned:1; + DWORD uber4Spawned:1; + DWORD uber5Spawned:1; + DWORD uber6Spawned:1; + }; + }; + int count1; + int count2; + int count3; + int count4; + int count5; + int count6; + Room* room1; + Room* room2; + Room* room3; + Room* room4; + Room* room5; + Room* room6; +} questState; + +void resetQuestState() +{ + ZeroMemory(&questState,sizeof(questState)); + questState.count1 = 10 + RANDOM(10); + questState.count2 = 20 + RANDOM(40); + questState.count3 = 10 + RANDOM(20); + int value = 5 + RANDOM(10); + questState.count4 = value + RANDOM(4); + questState.count5 = value + RANDOM(4); + questState.count6 = value + RANDOM(4); + log_msg("Uber Quest State : %d %d %d %d %d %d\n",questState.count1, questState.count2, questState.count3, questState.count4, questState.count5, questState.count6); +} + +DWORD openPortalOnLevel(Game* ptGame, Unit* ptChar, DWORD levelID) +{ + log_msg("openning portal to level %d\n",levelID); + Room* ptRoom = D2GetRoom(ptChar); + if ( D2GetLevelID(ptRoom) != LEVEL_ACT5TOWN ) return 0; + + //Get position in the room + Position pos; + D2GetPosition(ptChar, &pos); + if (!D2GetDropRoom(ptRoom, &pos, &pos, 3, 0x3E01, 0xC01, 0)) return 0; + ptRoom = D2TestPositionInRoom(ptRoom, pos.x, pos.y); + if (!ptRoom) return 0; + + // Create Portal + Unit* ptPortal = D2CreateUnit(UNIT_OBJECT, OBJECT_PERMANENT_PORTAL, pos.x, pos.y, ptGame, ptRoom, 1, 1, 0); + ptPortal->ptObjectData->levelID = (BYTE)levelID; + D2Common10572(ptPortal, 1); + D2LinkPortal(ptGame, ptPortal, levelID, LEVEL_ACT5TOWN); + D2SetObjectFlags(ptPortal, D2GetObjectFlags(ptPortal) | 3); + D2Common11084(ptRoom, 0); + D2Common11084(D2GetRoom(ptPortal), 0); + + return 1; +} + +DWORD FASTCALL openPandPortal(Game* ptGame, Unit* ptChar) +{ + log_msg("openPandPortal\n"); + Position pos; + D2GetPosition(ptChar, &pos); + log_msg("ptChar pos : %d %d\n",pos.x,pos.y); + + if (ptGame->difficultyLevel != D2DM_HELL) return 0; + int available[3]; + int nbAvailable=0; + if (!questState.portal1Opened) available[nbAvailable++]=LEVEL_ACT5_PANDEMONIUM1; + if (!questState.portal2Opened) available[nbAvailable++]=LEVEL_ACT5_PANDEMONIUM2; + if (!questState.portal3Opened) available[nbAvailable++]=LEVEL_ACT5_PANDEMONIUM3; + int selectedTargetLevel; + if (nbAvailable) + selectedTargetLevel = available[RANDOM(nbAvailable)]; + else selectedTargetLevel = LEVEL_ACT5_PANDEMONIUM1 + RANDOM(3); + + int ret = openPortalOnLevel(ptGame, ptChar, selectedTargetLevel); + + + if (ret) + { + if (selectedTargetLevel == LEVEL_ACT5_PANDEMONIUM1) questState.portal1Opened = 1; + else if (selectedTargetLevel == LEVEL_ACT5_PANDEMONIUM2) questState.portal2Opened = 1; + else if (selectedTargetLevel == LEVEL_ACT5_PANDEMONIUM3) questState.portal3Opened = 1; + } + log_msg("openPandPortal ending\n\n"); + return ret;//normally return ret; +} + +DWORD FASTCALL openPandFinalPortal(Game* ptGame, Unit* ptChar) +{ + log_msg("openPandFinalPortal\n"); + Position pos; + D2GetPosition(ptChar, &pos); + log_msg("ptChar pos : %d %d",pos.x,pos.y); + int ret = openPortalOnLevel(ptGame, ptChar, LEVEL_ACT5_PANDEMONIUM_FINAL); + log_msg("openPandFinalPortal ending\n"); + return ret;//normally return ret; +} + +Room* selectRoom(Game* ptGame, Room* ptCurrentRoom, DWORD level) +{ +/* Room* tab[200]; + nbRoom=0; + Room* ptRoom = ptGame->mapAct[5]->ptFirstRoom; + while (ptRoom); + if(!ptCurrentRoom->nbNearRooms) return ptCurrentRoom; + int targetRoomNum = RANDOM(ptCurrentRoom->nbNearRooms); + Room* ptRoom = ptCurrentRoom->ptNearRooms; + while (targetRoomNum--) + ptRoom = ptRoom->ptNextRoom;*/ + return ptCurrentRoom; +} + +void STDCALL spawnUber(Game* ptGame, Room* ptRoom) +{ + log_msg("Uber Quest State : %d %d %d %d %d %d\n",questState.count1, questState.count2, questState.count3, questState.count4, questState.count5, questState.count6); + switch(D2GetLevelID(ptRoom)) + { + case LEVEL_ACT5_PANDEMONIUM1: + if (!questState.uber1Spawned) + { + if (questState.count1) questState.count1--; + else { + Room* ptTargetRoom = selectRoom(ptGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + if (D2SpawnMonster(ptGame, ptTargetRoom, 0, 0, 0, -1, 707, 0)) + questState.uber1Spawned = 1; + } + } + break; + case LEVEL_ACT5_PANDEMONIUM2: + if (!questState.uber2Spawned) + { + if (questState.count2) questState.count2--; + else { + Room* ptTargetRoom = selectRoom(ptGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + if (D2SpawnMonster(ptGame, ptTargetRoom, 0, 0, 0, -1, 708, 0)) + questState.uber2Spawned = 1; + } + } + break; + case LEVEL_ACT5_PANDEMONIUM3: + if (!questState.uber3Spawned) + { + if (questState.count3) questState.count3--; + else { + Room* ptTargetRoom = selectRoom(ptGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + if (D2SpawnMonster(ptGame, ptTargetRoom, 0, 0, 0, -1, 706, 0)) + questState.uber3Spawned = 1; + } + } + break; + case LEVEL_ACT5_PANDEMONIUM_FINAL: + if (!questState.uber4Spawned) + { + if (questState.count4) questState.count4--; + else { + Room* ptTargetRoom = selectRoom(ptGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + if (D2SpawnMonster(ptGame, ptTargetRoom, 0, 0, 0, -1, 704, 0)) + questState.uber4Spawned = 1; + } + } + if (!questState.uber5Spawned) + { + if (questState.count5) questState.count5--; + else { + Room* ptTargetRoom = selectRoom(ptGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + if (D2SpawnMonster(ptGame, ptTargetRoom, 0, 0, 0, -1, 705, 0)) + questState.uber5Spawned = 1; + } + } + if (!questState.uber6Spawned) + { + if (questState.count6) questState.count6--; + else { + Room* ptTargetRoom = selectRoom(ptGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + if (D2SpawnMonster(ptGame, ptTargetRoom, 0, 0, 0, -1, 709, 0)) + questState.uber6Spawned = 1; + } + } + +// D2SpawnMonster(PCGame, ptRoom, 0, 25113, 5138, -1, 704, 0); +// D2SpawnMonster(PCGame, ptRoom, 0, 25125, 5150, -1, 705, 0); +// D2SpawnMonster(PCGame, ptRoom, 0, 25135, 5140, -1, 709, 0); + } + D2Game235C0(ptGame, ptRoom); +} + +/*DWORD STDCALL spawnUber(Path* ptPath, Unit* ptChar, Room* ptRoom, DWORD x, DWORD y) +{ + if (!D2WarpPlayer(ptPath, ptChar, ptRoom, x, y)) return 0; + + switch(D2GetLevelID(ptRoom)) + { + case LEVEL_ACT5_PANDEMONIUM1: + if (!questState.uber1Spawned) + { + Room* ptTargetRoom = selectRoom(PCGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + D2SpawnMonster(PCGame, ptTargetRoom, 0, 0, 0, -1, 707, 0); + questState.uber1Spawned = 1; + } + break; + case LEVEL_ACT5_PANDEMONIUM2: + if (!questState.uber2Spawned) + { + Room* ptTargetRoom = selectRoom(PCGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + D2SpawnMonster(PCGame, ptTargetRoom, 0, 0, 0, -1, 708, 0); + questState.uber2Spawned = 1; + } + break; + case LEVEL_ACT5_PANDEMONIUM3: + if (!questState.uber3Spawned) + { + Room* ptTargetRoom = selectRoom(PCGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + D2SpawnMonster(PCGame, ptTargetRoom, 0, 0, 0, -1, 706, 0); + questState.uber3Spawned = 1; + } + break; + case LEVEL_ACT5_PANDEMONIUM_FINAL: + if (!questState.uber4Spawned) + { + Room* ptTargetRoom = selectRoom(PCGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + D2SpawnMonster(PCGame, ptTargetRoom, 0, 0, 0, -1, 704, 0); + ptTargetRoom = selectRoom(PCGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + D2SpawnMonster(PCGame, ptTargetRoom, 0, 0, 0, -1, 705, 0); + ptTargetRoom = selectRoom(PCGame, ptRoom, LEVEL_ACT5_PANDEMONIUM1); + D2SpawnMonster(PCGame, ptTargetRoom, 0, 0, 0, -1, 709, 0); +// D2SpawnMonster(PCGame, ptRoom, 0, 25113, 5138, -1, 704, 0); +// D2SpawnMonster(PCGame, ptRoom, 0, 25125, 5150, -1, 705, 0); +// D2SpawnMonster(PCGame, ptRoom, 0, 25135, 5140, -1, 709, 0); + questState.uber4Spawned = 1; + } + } + return 1; +} +*/ +void FASTCALL uberMephIA(Game* ptGame, Unit* ptMonster, DWORD* ptData) +{ + D2MephIA(ptGame, ptMonster, ptData); +} + +void FASTCALL uberDiabloIA(Game* ptGame, Unit* ptMonster, DWORD* ptData) +{ + D2DiabloIA(ptGame, ptMonster, ptData); +} + + +void FASTCALL uberBaalIA(Game* ptGame, Unit* ptMonster, DWORD* ptData) +{ + D2BaalIA(ptGame, ptMonster, ptData); +} + +void Install_UberQuest() +{ + static int isInstalled = false; + if (isInstalled) return; + + if ( version_D2Game <= V110 ) + return; + + log_msg("Patch D2Game for active Uber Quest. (UberQuest)\n"); + + DWORD oldProtection; + + // open Red Portal + VirtualProtect((LPVOID)R7(D2Game,0,0,0,FA480,FA7B8, FA228, FA5F0), 8, PAGE_EXECUTE_READWRITE, &oldProtection); + mem_seek R7(D2Game, 0000, 0000, 0000, FA480, FA7B8, FA228, FA5F0); + MEMT_DWORD( D2OpenPandPortal , openPandPortal); + MEMT_DWORD( D2OpenPandFinalPortal , openPandFinalPortal); + //0201E357 |. FFD0 |CALL EAX + //01FA77E7 |. FFD0 |CALL EAX + //6FCF3CC7 |. FFD0 |CALL EAX + //6FC92437 |. FFD0 |CALL EAX + VirtualProtect((LPVOID)R7(D2Game,0,0,0,FA480,FA7B8, FA228, FA5F0), 8, oldProtection, &oldProtection); + + + // manage uberIA (fct table at 0209E7E8) + VirtualProtect((LPVOID)(R7(D2Game,0,0,0,10E7E8,10ECD0,10EF58,10E788) + 145*0x10), 0x30, PAGE_EXECUTE_READWRITE, &oldProtection); + mem_seek R7(D2Game, 0000, 0000, 0000, 10F100, 10F5E8, 10F870, 10F0A0); + MEMT_DWORD( D2UberBaalIA , uberBaalIA); + mem_seek R7(D2Game, 0000, 0000, 0000, 10F110, 10F5F8, 10F880, 10F0B0); + MEMT_DWORD( D2UberMephIA , uberMephIA); + mem_seek R7(D2Game, 0000, 0000, 0000, 10F120, 10F608, 10F890, 10F0C0); + MEMT_DWORD( D2UberDiabloIA , uberDiabloIA); + VirtualProtect((LPVOID)(R7(D2Game,0,0,0,10E7E8,10ECD0,10EF58,10E788) + 145*0x10), 0x30, oldProtection, &oldProtection); + //0202ADA7 |> B8 E8E70902 MOV EAX,D2Game.0209E7E8 + //01FD2BE7 |> B8 D0EC0702 MOV EAX,D2Game.0207ECD0 + //6FC3B597 |> B8 58EFD26F MOV EAX,D2Game.6FD2EF58 + //6FCBD157 |> B8 88E7D26F MOV EAX,D2Game.6FD2E788 + + // spawn Uber +// mem_seek R7(D2Game, 0000, 0000, 0000, 98DAD, 0000, 0000, 0000); +// MEMJ_REF4( D2WarpPlayer , spawnUber); + //02028DAC |. E8 491CF7FF CALL + + mem_seek R7(D2Game, 0000, 0000, 0000, E26E2, E6B52, A850B, 2CCAB); + MEMC_REF4( D2Game235C0 , spawnUber); + //020726E1 |. E8 2A46FFFF ||CALL D2Game.02066D10 + //02056B51 |. E8 6ACAF3FF ||CALL D2Game.01F935C0 + //6FCC850A |. E8 014FF6FF ||CALL D2Game.6FC2D410 + //6FC4CCAA |. E8 3134FFFF ||CALL D2Game.6FC400E0 + + log_msg("\n"); + + isInstalled = true; +} +/* +call fct to manage TP : +0201E33E |. 8B048D 78A4070>|MOV EAX,DWORD PTR DS:[ECX*4+207A478] ; D2Game.0201B480 +0201E345 |. 85C0 |TEST EAX,EAX +0201E347 |. 74 14 |JE SHORT D2Game.0201E35D +0201E349 |. 8B9424 2C01000>|MOV EDX,DWORD PTR SS:[ESP+12C] +0201E350 |. 8B8C24 2801000>|MOV ECX,DWORD PTR SS:[ESP+128] +0201E357 |. FFD0 |CALL EAX +0201E359 |. 894424 38 |MOV DWORD PTR SS:[ESP+38],EAX + +DWORD FASTCALL openPortal (Unit* ptGame, Unit* ptChar) +0201C6D0 : CowPortal +0201B480 : Pand. Portal return 0 !! +0201B470 : Pand. FInal Portal + +manage IA +0202AD8B |> 66:8B46 1E MOV AX,WORD PTR DS:[ESI+1E] +0202AD8F |. 66:85C0 TEST AX,AX +0202AD92 |. 7C 13 JL SHORT D2Game.0202ADA7 +0202AD94 |. 66:3D 9400 CMP AX,94 +0202AD98 |. 73 0D JNB SHORT D2Game.0202ADA7 +0202AD9A |. 0FBFC0 MOVSX EAX,AX +0202AD9D |. C1E0 04 SHL EAX,4 +0202ADA0 |. 05 E8E70902 ADD EAX,D2Game.0209E7E8 +0202ADA5 |. 5E POP ESI +0202ADA6 |. C3 RETN +0202ADA7 |> B8 E8E70902 MOV EAX,D2Game.0209E7E8 +0202ADAC |. 5E POP ESI +0202ADAD \. C3 RETN +*/ +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/UpdateClient.cpp b/PlugY/UpdateClient.cpp new file mode 100644 index 0000000..df230e2 --- /dev/null +++ b/PlugY/UpdateClient.cpp @@ -0,0 +1,90 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Updating client. + +=================================================================*/ + +#include "common.h" +#include "updateClient.h" +#include "error.h" +#include "d2functions.h" + +#include "infinityStash.h" +#include "commands.h" + + +void updateClient(Unit* ptChar, DWORD mFunc, DWORD p1, DWORD p2, DWORD p3) +{ + void* ptNetClient; + DataPacket packet; + + // Intialize the packet to send to client + ZeroMemory(&packet, sizeof(DataPacket)); + packet.mType = 0x9D; + packet.mFunc = (BYTE)mFunc; + packet.mSize = sizeof(DataPacket); + packet.mPlayerID = ptChar->nUnitId; + packet.mParam1 = p1; + packet.mParam2 = p2; + packet.mParam3 = p3; + + ptNetClient = D2GetClient( ptChar, __FILE__ , __LINE__); + + // Send packet to client for remove placed skills + D2SendPacket(ptNetClient, &packet, sizeof(DataPacket)); +} + + +DWORD FASTCALL handleClientUpdate(DataPacket* packet) +{ + log_msg("[CLIENT] Received custom message: %d with param: %08X , %08X , %08X\n",packet->mFunc,packet->mParam1,packet->mParam2,packet->mParam3); + switch (packet->mFunc) + { + case UC_SELECT_STASH : setSelectedStashClient(packet->mParam1,packet->mParam2,packet->mParam3); return 1; + case UC_SHARED_GOLD : updateSharedGold(packet->mParam1); return 1; + default : return 0; + } +} + + +FCT_ASM ( caller_handleClientUpdate_111 ) + LEA ECX,DWORD PTR SS:[ESP+8] + CALL handleClientUpdate + POP EDI + POP ESI + MOV ESP,EBP + POP EBP + RETN +}} + +FCT_ASM ( caller_handleClientUpdate ) + LEA ECX,DWORD PTR SS:[ESP] + CALL handleClientUpdate + ADD ESP,0x104 + RETN +}} + + +void Install_UpdateClient() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Client for received Item packet. (UpdateClient)\n"); + + // execute if it's our packet else continue + mem_seek R7(D2Client, 14236, 14226, 145B6, 9C6B6, BFE86, 66E06, AE896); + MEMT_REF4( version_D2Client >= V111 ? 0x000000CF : 0x000000D6, version_D2Client >= V111 ? caller_handleClientUpdate_111 : caller_handleClientUpdate); + //6FAB45B4 |. 0F87 D6000000 JA D2Client.6FAB4690 + //6FB4C6B4 |. 0F87 CF000000 JA D2Client.6FB4C789 + //6FB6FE84 |. 0F87 CF000000 JA D2Client.6FB6FF59 + //6FB16E04 |. 0F87 CF000000 JA D2Client.6FB16ED9 + //6FB5E894 |. 0F87 CF000000 JA D2Client.6FB5E969 + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/UpdateServer.cpp b/PlugY/UpdateServer.cpp new file mode 100644 index 0000000..07cb3f9 --- /dev/null +++ b/PlugY/UpdateServer.cpp @@ -0,0 +1,138 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Updating server. + +=================================================================*/ + +#include "common.h" +#include "updateServer.h" +#include "error.h" +#include "d2functions.h" + +#include "statsPoints.h" +#include "skillsPoints.h" +#include "infinityStash.h" +#include "commands.h" + + +int STDCALL handleServerUpdate(Unit* ptChar, WORD param) +{ + log_msg("Received custom message: %X\n", param); + switch(param & 0xFF) + { + case US_UNASSIGN_STR_POINT : UnassignStrPoint( ptChar ); return 1; + case US_UNASSIGN_ENE_POINT : UnassignEnePoint( ptChar ); return 1; + case US_UNASSIGN_DEX_POINT : UnassignDexPoint( ptChar ); return 1; + case US_UNASSIGN_VIT_POINT : UnassignVitPoint( ptChar ); return 1; + case US_UNASSIGN_STR_POINTS : UnassignStrPoints( ptChar ); return 1; + case US_UNASSIGN_ENE_POINTS : UnassignEnePoints( ptChar ); return 1; + case US_UNASSIGN_DEX_POINTS : UnassignDexPoints( ptChar ); return 1; + case US_UNASSIGN_VIT_POINTS : UnassignVitPoints( ptChar ); return 1; + case US_UNASSIGN_SKILLS : UnassignAllSkillsPoints( ptChar ); return 1; + case US_SELECT_PREVIOUS : selectPreviousStash( ptChar ); return 1; + case US_SELECT_NEXT : selectNextStash( ptChar ); return 1; + case US_SELECT_SELF : if (active_sharedStash) toggleToSelfStash( ptChar ); return 1; + case US_SELECT_SHARED : if (active_sharedStash) toggleToSharedStash( ptChar ); return 1; + case US_SELECT_PREVIOUS_INDEX : selectPreviousIndexStash( ptChar ); return 1; + case US_SELECT_NEXT_INDEX : selectNextIndexStash( ptChar ); return 1; + + case US_SELECT_PREVIOUS2 : selectPrevious2Stash( ptChar ); return 1; + case US_SELECT_NEXT2 : selectNext2Stash( ptChar ); return 1; + case US_SELECT_PREVIOUS_INDEX2: selectPreviousIndex2Stash( ptChar ); return 1; + case US_SELECT_NEXT_INDEX2 : selectNextIndex2Stash( ptChar ); return 1; + + case US_STARTSAVE : savePlayers( ptChar ); return 1; + + case US_MAXGOLD : maxGold(ptChar); return 1; + case US_PUTGOLD : putGold(ptChar, 0); return 1; + case US_TAKEGOLD : takeGold(ptChar, 0); return 1; + default : return 0; + } +} + +FCT_ASM( caller_handleServerUpdate) + PUSH EAX + PUSH EBX + CALL handleServerUpdate + TEST EAX,EAX + JNZ END_RCM + MOV EAX,ESI + AND EAX,0xFF + SHR ESI,8 + MOV EDI,EAX + RETN +END_RCM: + ADD ESP,4 + POP EDI + POP ESI + XOR EAX,EAX + POP EBX + RETN 8 +}} + + +FCT_ASM( caller_handleServerUpdate_9) + XOR EDX,EDX + MOV DX,WORD PTR DS:[EAX+1] + PUSH ECX + PUSH EDX + PUSH EDX + PUSH ECX + CALL handleServerUpdate + POP EDX + POP ECX + TEST EAX,EAX + JNZ END_RCM + RETN +END_RCM: + POP EAX + XOR EAX,EAX + RETN 8 +}} + + +void Install_UpdateServer() +{ + static int isInstalled = false; + if (isInstalled) return; + + log_msg("Patch D2Game for received button click message. (UpdateServer)\n"); + + // manage button click message from Client. + mem_seek R7(D2Game, 4A702, 4AAC2, 56EA2, 54AE3, 2C773, 975C3, CC983); + if (version_D2Game >= V111) { + memt_byte( 0xC1, 0x57 ); // PUSH EDI + memt_byte( 0xEE, 0xE8 ); // CALL caller_handleServerUpdate + MEMT_REF4( 0xF88B5708, caller_handleServerUpdate); + //01FD4AE3 . C1EE 08 SHR ESI,8 + //01FD4AE6 . 57 PUSH EDI + //01FD4AE7 . 8BF8 MOV EDI,EAX + //01F9C773 . C1EE 08 SHR ESI,8 + //01F9C776 . 57 PUSH EDI + //01F9C777 . 8BF8 MOV EDI,EAX + //6FCB75C3 . C1EE 08 SHR ESI,8 + //6FCB75C6 . 57 PUSH EDI + //6FCB75C7 . 8BF8 MOV EDI,EAX + //6FCEC983 . C1EE 08 SHR ESI,8 + //6FCEC986 . 57 PUSH EDI + //6FCEC987 . 8BF8 MOV EDI,EAX + } else if (version_D2Game == V110) { + memt_byte( 0xC1, 0xE8 ); // CALL caller_handleServerUpdate + MEMT_REF4( 0xF88B08EE, caller_handleServerUpdate); + //6FC86EA2 . C1EE 08 SHR ESI,8 + //6FC86EA5 . 8BF8 MOV EDI,EAX + } else { + memt_byte( 0x33, 0xE8 ); // CALL caller_handleServerUpdate + MEMT_REF4( 0x508B66D2, caller_handleServerUpdate_9); + memt_byte( 0x01, 0x90 ); // NOP + //6FC7A702 . 33D2 XOR EDX,EDX + //6FC7A704 . 66:8B50 01 MOV DX,WORD PTR DS:[EAX+1] + } + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/WorldEvent.cpp b/PlugY/WorldEvent.cpp new file mode 100644 index 0000000..d5df6d5 --- /dev/null +++ b/PlugY/WorldEvent.cpp @@ -0,0 +1,274 @@ +/*================================================================= + File created by Yohann NICOLAS. + + World Event Management. + +=================================================================*/ + +#include "common.h" +#include "error.h" +#include "d2functions.h" + +#pragma pack(1) +struct s_WEdata +{ + BYTE type; + BYTE fct; + BYTE id; + DWORD param; + WORD z; + BYTE uk[31]; +}; +#pragma pack() + +bool active_WorldEvent=0; + +DWORD WEactive = 0; +DWORD DCloneSpawned = 0; + +DWORD nbSOJSold = 0; +DWORD nbNeedSOJSold = 100; +DWORD nbManagedSOJSold = 0; + +DWORD nbTicksForNextSOJSold = 0; +DWORD prevTicks = 0; + +DWORD showSOJSoldCounterInAllDiff=0; +char* itemsToSell="The Stone of Jordan"; +DWORD worldEventmonsterID = 333; +DWORD valueOfOwnSOJSold=100; +DWORD valueInitSOJSoldMin=200; +DWORD valueInitSOJSoldDelta=2000; +DWORD triggerAtSolJSoldMin=75; +DWORD triggerAtSolJSoldDelta=51; +bool active_AutomaticSell=1; +DWORD timeBeforeAutoSellMin=00000; +DWORD timeBeforeAutoSellDelta=120000; +CubeInput itemNeeded; + +DWORD getTicksForNextSOJSold() +{ + return ((DWORD)(rand()/(RAND_MAX+1.0)*timeBeforeAutoSellDelta)+timeBeforeAutoSellMin);//average of +100 in 25hours max 41h40 +} + + +void FASTCALL sendDataToClient(void* ptclient, DWORD* param) +{ + D2SendPacket(ptclient, (void*)param[0], (DWORD)param[1]); +} + +void STDCALL worldEventBroadcast(Game* ptGame, DWORD activeWE, DWORD nbSOJSold) +{ + void* param[2]; + s_WEdata data; + data.type = 0x5A; + data.fct = activeWE ? 0x12 : 0x11; + data.id = 4; + data.param = nbSOJSold; + data.z = 0; + + param[0]=&data; + param[1]=(void*)sizeof(data); + + D2BroadcastFunction(ptGame,&sendDataToClient,param); +} + +Game* STDCALL WEManagement(DWORD clientID) +{ + Game* ptGame = D2GetGameByClientID(clientID); + if (!ptGame) return ptGame; + + if (active_AutomaticSell) + while (GetTickCount() - prevTicks >= nbTicksForNextSOJSold) + { + nbSOJSold++; + prevTicks = prevTicks + nbTicksForNextSOJSold; + nbTicksForNextSOJSold = getTicksForNextSOJSold(); + } + + if (nbSOJSold == nbManagedSOJSold) return ptGame; + + DWORD newWE; + if (!WEactive && (ptGame->difficultyLevel == D2DM_HELL) && (nbSOJSold >= nbNeedSOJSold)) + { + newWE = 1; + WEactive = 1; + } else newWE = 0; + + if ( showSOJSoldCounterInAllDiff || (ptGame->difficultyLevel == D2DM_HELL)) + worldEventBroadcast(ptGame, newWE, nbSOJSold); + + nbManagedSOJSold = nbSOJSold; + return ptGame; +} + + +DWORD FASTCALL spawnDClone(Game* ptGame, Room* ptRoom, DWORD p3, DWORD p4, DWORD p5, DWORD p6, DWORD monsterID, DWORD p8) +{ + if (WEactive && (ptGame->difficultyLevel == D2DM_HELL) && !DCloneSpawned) + { + DCloneSpawned=1; + D2SpawnMonster(ptGame,ptRoom,p3,p4,p5,p6,worldEventmonsterID,p8); + return 0;//no minions + } + else return D2SpawnMonster(ptGame,ptRoom,p3,p4,p5,p6,monsterID,p8); +} + +DWORD STDCALL verifIfWEItem (Unit* ptItem, DWORD flags, DWORD line, const char* filename) +{ + ItemsBIN* ptItemStats = D2GetItemsBIN(ptItem->nTxtFileNo); + ItemsBIN* ptWantedItemStats = D2GetItemsBIN(itemNeeded.ID); + + if((itemNeeded.byItemTypeID && D2CheckItemType(ptItem,itemNeeded.ID)) + || (itemNeeded.byItemID && (itemNeeded.ID == 0xFFFF)) + || (itemNeeded.byItemID && !itemNeeded.includeUpgradedVersions && ((DWORD)itemNeeded.ID == ptItem->nTxtFileNo)) + || (itemNeeded.byItemID && itemNeeded.includeUpgradedVersions) && ( + (ptItemStats->ItemCode == ptItemStats->NormCode) && (ptItemStats->ItemCode == ptWantedItemStats->NormCode) + || (ptItemStats->ItemCode == ptItemStats->UberCode) && (ptItemStats->ItemCode == ptWantedItemStats->NormCode) + || (ptItemStats->ItemCode == ptItemStats->UberCode) && (ptItemStats->ItemCode == ptWantedItemStats->UberCode) + || (ptItemStats->ItemCode == ptItemStats->HellCode) && (ptItemStats->ItemCode == ptWantedItemStats->NormCode) + || (ptItemStats->ItemCode == ptItemStats->HellCode) && (ptItemStats->ItemCode == ptWantedItemStats->UberCode) + || (ptItemStats->ItemCode == ptItemStats->HellCode) && (ptItemStats->ItemCode == ptWantedItemStats->HellCode) + )) + if(!(itemNeeded.isSpecificItem && (D2GetUniqueID(ptItem) != itemNeeded.specificID-1)) + && !(itemNeeded.haveNoSocket && (D2GetPlayerStat(ptItem, STATS_ITEM_NUMSOCKETS, 0) > 0)) + && !(itemNeeded.haveSockets && (D2GetPlayerStat(ptItem, STATS_ITEM_NUMSOCKETS, 0) == 0)) + && !(itemNeeded.isNotEthereal && D2isEtheral(ptItem)) + && !(itemNeeded.isEthereal && !D2isEtheral(ptItem)) + && !(itemNeeded.isBasic && (ptItemStats->ItemCode != ptWantedItemStats->NormCode)) + && !(itemNeeded.isExceptional && (ptItemStats->ItemCode != ptWantedItemStats->UberCode)) + && !(itemNeeded.isElite && (ptItemStats->ItemCode != ptWantedItemStats->HellCode)) + && !(itemNeeded.isNotRuneword && ptItem->ptItemData->isRuneword) ) + { + nbSOJSold += valueOfOwnSOJSold; + return 1;// Can't re-buy the item. + } + + return D2TestFlags(ptItem, flags, line, filename); +} + + +void initWorldEventVariables() +{ + char buf[50]; + memset(&itemNeeded,0,sizeof(itemNeeded)); + strncpy(buf,itemsToSell,50); + D2CompileCubeInput(&itemNeeded,buf,0,0); + + nbManagedSOJSold = 0; + DCloneSpawned = 0; + WEactive = 0; + + while (nbSOJSold >= nbNeedSOJSold) + nbNeedSOJSold += (DWORD)(rand()/(RAND_MAX+1.0)*triggerAtSolJSoldDelta+triggerAtSolJSoldMin); +} + + +FCT_ASM ( caller_WEManagement_1XX ) + POP EAX + PUSH ECX + PUSH EAX + JMP WEManagement +}} + + +FCT_ASM ( caller_spawnDClone_111 ) + PUSH DWORD PTR SS:[ESP+0x14] + PUSH EAX + PUSH DWORD PTR SS:[ESP+0x18] + PUSH DWORD PTR SS:[ESP+0x18] + PUSH DWORD PTR SS:[ESP+0x18] + PUSH ECX + MOV ECX,DWORD PTR SS:[ESP+0x1C] + CALL spawnDClone + RETN 0x14 +}} + +FCT_ASM ( caller_spawnDClone_111b ) + PUSH EDX + PUSH ECX + PUSH DWORD PTR SS:[ESP+0x1C] + PUSH DWORD PTR SS:[ESP+0x1C] + PUSH DWORD PTR SS:[ESP+0x1C] + PUSH EAX + MOV EDX,DWORD PTR SS:[ESP+0x20] + MOV ECX,DWORD PTR SS:[ESP+0x1C] + CALL spawnDClone + RETN 0x14 +}} + +FCT_ASM( caller_addClientForWE_111 ) + PUSH EAX + CALL initWorldEventVariables + POP EAX + JMP D2AddClient +}} + + +FCT_ASM( caller_addClientForWE ) + PUSH ECX + CALL initWorldEventVariables + POP ECX + JMP D2AddClient +}} + + +void Install_WorldEvent() +{ + static int isInstalled = false; + if (isInstalled) return; + + if ( version_D2Game < V110 ) + return; + + nbSOJSold = (DWORD)(rand()/(RAND_MAX+1.0)*valueInitSOJSoldDelta+valueInitSOJSoldMin); + if (active_AutomaticSell) + { + prevTicks = GetTickCount(); + nbTicksForNextSOJSold = (DWORD)(rand()/(RAND_MAX+1.0)*(timeBeforeAutoSellDelta+timeBeforeAutoSellMin)); + } + + log_msg("Patch D2Game for active World Event. (WorldEvent)\n"); + + // spawn DClone + mem_seek R7(D2Game, 0000, 0000, 3F720, 4BCB1, ECF10, 41570, 25280); + MEMC_REF4( V2SpawnMonster , version_D2Game >= V111b ? (DWORD)caller_spawnDClone_111b : version_D2Game == V111 ? (DWORD)caller_spawnDClone_111 : (DWORD)spawnDClone); + //6FC6F71F |. E8 FCFAFFFF CALL D2Game.6FC6F220 + //01FCBCB0 |. E8 2BEFFFFF CALL D2Game.01FCABE0 ; \D2Game.01FCABE0 + //0205CF0F |. E8 CCF8FFFF CALL D2Game.0205C7E0 ; \D2Game.0205C7E0 + //6FC6156F |. E8 1CF6FFFF CALL D2Game.6FC60B90 ; \D2Game.6FC60B90 + //6FC4527F |. E8 CCF6FFFF CALL D2Game.6FC44950 ; \D2Game.6FC44950 + + // verify if the item sold is a trigger of WE + mem_seek R7(D2Game, 0000, 0000, 977D0, 8E799, 92859, 84499, BFB29); + MEMJ_REF4( D2TestFlags , verifIfWEItem); + //6FCC77CF |. E8 32400500 CALL + //0200E798 |. E8 E9BDF7FF CALL + //02002858 |. E8 E57DF7FF CALL + //6FCA4498 |. E8 3B62F8FF CALL + //6FCDFB28 |. E8 77ADF4FF CALL + + // management of the WorldEvent + mem_seek R7(D2Game, 0000, 0000, 3CE0, 51F01, C5681, EBF41, 4A791); + MEMC_REF4( V2GetGameByClientID , version_D2Game >= V111 ? (DWORD)WEManagement : (DWORD)caller_WEManagement_1XX); + //6FC33CDF . E8 FC570000 CALL D2Game.6FC394E0 + //01FD1F00 |. E8 1BE60800 CALL D2Game.02060520 + //02035680 |. E8 1BF30100 CALL D2Game.020549A0 + //6FD0BF40 |. E8 1BA4FBFF CALL D2Game.6FCC6360 + //6FC6A790 |. E8 4B03FEFF CALL D2Game.6FC4AAE0 + + // add client for the WorldEvent + mem_seek R7(D2Game, 0000, 0000, 1AEF, 3786A, 7055A, 6265F, CB0BF); + MEMC_REF4( D2AddClient , version_D2Game >= V111 ? caller_addClientForWE_111 : caller_addClientForWE); + //6FC31AEE |. E8 6D510000 CALL D2Game.6FC36C60 + //01FB7869 |. E8 32C50A00 CALL D2Game.02063DA0 + //01FE0559 |. E8 B27C0700 CALL D2Game.02058210 + //6FC8265E |. E8 FD890800 CALL D2Game.6FD0B060 + //6FCEB0BE |. E8 6DE8F7FF CALL D2Game.6FC69930 + + log_msg("\n"); + + isInstalled = true; +} + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/bigStash.h b/PlugY/bigStash.h new file mode 100644 index 0000000..1f9ff67 --- /dev/null +++ b/PlugY/bigStash.h @@ -0,0 +1,19 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Use a more big stash + +=================================================================*/ + +#ifndef __BIGSTASH_HPP__INCLUDED +#define __BIGSTASH_HPP__INCLUDED + +#include + +extern bool active_bigStash; +extern bool active_bigStash_tested; + +void Install_BigStash(); + + +#endif \ No newline at end of file diff --git a/PlugY/clientSaveFile.h b/PlugY/clientSaveFile.h new file mode 100644 index 0000000..b2a0734 --- /dev/null +++ b/PlugY/clientSaveFile.h @@ -0,0 +1,16 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Add an extra save file for each characters. + +=================================================================*/ +/* +#pragma once + +#include "common.h" + +DWORD loadClientSaveFile(); +DWORD saveClientSaveFile(); + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/commands.h b/PlugY/commands.h new file mode 100644 index 0000000..20777e7 --- /dev/null +++ b/PlugY/commands.h @@ -0,0 +1,21 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Commands directly in game. + +=================================================================*/ + +#ifndef __COMMANDS_H__INCLUDED +#define __COMMANDS_H__INCLUDED + +extern bool active_Commands; + +void savePlayers(Unit* ptChar); +void maxGold(Unit* ptChar); +void putGold(Unit* ptChar, DWORD amount); +void takeGold(Unit* ptChar, DWORD amount); +void updateSharedGold(DWORD goldAmount); + +void Install_Commands(); + +#endif \ No newline at end of file diff --git a/PlugY/common.h b/PlugY/common.h new file mode 100644 index 0000000..3aaf109 --- /dev/null +++ b/PlugY/common.h @@ -0,0 +1,149 @@ +/*============================================== + File created by Yohann NICOLAS. + + this file implements some common and useful + function related to some Diablo II mechanisms. + +/*============================================*/ + +#pragma once + +#include +#include "../Commons/d2Constants.h" +#include "../Commons/d2BinFile.h" +#include "../Commons/d2Struct.h" +#include "../Commons/d2StringTblStruct.h" +#include "../Commons/D2UnitStruct.h" +#include "../Commons/updatingConst.h" + +#include "customData.h" +#include "modifMemory.h" +#include "parameters.h" +#include "globalVariable.h" + +//#ifdef MSVC +#define FASTCALL __fastcall +//#else +//#define FASTCALL __msfastcall +//#endif +#define STDCALL __stdcall +#define FCT_ASM(N) __declspec(naked) void N() {__asm{ +#define RANDOM(V) ((int)(rand()/(RAND_MAX+1.0)*(V))) +//#define RANDOM(V) (rand()%(V)) + +// Convertion to 1.09 +struct s_shifting { + DWORD ptInventory; + DWORD ptSpecificData; + DWORD ptPYPlayerData; + DWORD ptGame; + DWORD ptClientGame; + DWORD ptSkills; + DWORD ptImage; + DWORD ptFrame; +}; +extern s_shifting shifting; + +//#define PY(C) (*(PYPlayerData**)((BYTE*)(ptChar)+shifting.ptPYPlayerData)) +#define PCPlayerData (*(PlayerData**)((DWORD)(ptChar)+shifting.ptSpecificData)) //->ptPlayerData +#define PCGame (*(Game**)((DWORD)(ptChar)+shifting.ptGame)) //->ptGame +#define PClientGame (*(Game**)((DWORD)(ptClient)+shifting.ptClientGame)) //ptClient->ptGame +#define PCInventory (*(Inventory**)((DWORD)(ptChar)+shifting.ptInventory)) //->ptInventory +//#define PIItemData (*(ItemData**)((DWORD)(ptItem)+shifting.ptSpecificData)) //->ptItemData +//#define PCPY (*(PYPlayerData**)((DWORD)(ptChar)+shifting.ptPYPlayerData)) //->ptPYPlayerData +#define PCPY ((PYPlayerData*)((DWORD)PCPlayerData+shifting.ptPYPlayerData)) //->ptPYPlayerData +#define PCSkills (*(Skills**)((DWORD)(ptChar)+shifting.ptSkills)) //->ptSkills + +#define R7(Z,A,B,C,D,E,F,G) (offset_##Z + (version_##Z == V113? 0x##G : (version_##Z == V112? 0x##F : (version_##Z == V111b? 0x##E : (version_##Z == V111? 0x##D : (version_##Z == V110? 0x##C : (version_##Z == V109d? 0x##B : 0x##A))))))) +#define V7(Z,A,B,C,D,E,F,G) (version_##Z == V113? 0x##G : (version_##Z == V112? 0x##F : (version_##Z == V111b? 0x##E : (version_##Z == V111? 0x##D : (version_##Z == V110? 0x##C : (version_##Z == V109d? 0x##B : 0x##A)))))) + + +// Convert 4 char code in a DWORD code +#define BIN(A,B,C,D) ((DWORD)A) + (((DWORD)B) << 8) + (((DWORD)C) << 16) + (((DWORD)D) << 24) + + +#define RX(v) (WindowStartX+(v)) +#define RY(v) (ResolutionY+NegWindowStartY-(v)) + + +enum eFileVersion +{ + V109b=0, + V109d, + V110, + V111, + V111b, + V112, + V113 +}; + +extern int version_SmackW32; +extern int version_D2Common; +extern int version_ijl11; +extern int version_D2Gdi; +extern int version_D2Win; +extern int version_D2sound; +extern int version_D2MCPCLI; +extern int version_D2Launch; +extern int version_D2gfx; +extern int version_D2Client; +extern int version_D2Net; +extern int version_D2Lang; +extern int version_D2Game; +extern int version_D2CMP; +extern int version_Bnclient; +extern int version_Fog; +extern int version_Storm; + + +// Address in memory of external DLL +extern DWORD offset_SmackW32; +extern DWORD offset_D2Common; +extern DWORD offset_ijl11; +extern DWORD offset_D2Gdi; +extern DWORD offset_D2Win; +extern DWORD offset_D2sound; +extern DWORD offset_D2MCPCLI; +extern DWORD offset_D2Launch; +extern DWORD offset_D2gfx; +extern DWORD offset_D2Client; +extern DWORD offset_D2Net; +extern DWORD offset_D2Lang; +extern DWORD offset_D2Game; +extern DWORD offset_D2CMP; +extern DWORD offset_Bnclient; +extern DWORD offset_Fog; +extern DWORD offset_Storm; + +extern const char* S_CloneBattles; +extern const char* S_DarkAlliance; + +LPWSTR getTranslatedString(int stringID); +enum eStringList +{ + STR_STATS_UNASSIGN_WITH_LIMIT=0, + STR_STATS_UNASSIGN_WITHOUT_LIMIT, + STR_STATS_BASE_MIN, + STR_SKILLS_UNASSIGN, + STR_STASH_PREVIOUS_PAGE, + STR_STASH_NEXT_PAGE, + STR_TOGGLE_TO_PERSONAL, + STR_TOGGLE_TO_SHARED, + STR_STASH_PREVIOUS_INDEX, + STR_STASH_NEXT_INDEX, + STR_PERSONAL_PAGE_NUMBER, + STR_SHARED_PAGE_NUMBER, + STR_NO_SELECTED_PAGE, + STR_PUT_GOLD, + STR_TAKE_GOLD, + STR_SHARED_GOLD_QUANTITY, + STR_PREVIOUS_PAGE, + STR_NEXT_PAGE +}; + +bool isOnRect(DWORD x, DWORD y, DWORD x0, DWORD y0, DWORD l, DWORD h); +void freeMessage(sWinMessage* msg); +LPWSTR getTypeUString (WORD id, LPWSTR lpText, DWORD size); +char* getTypeAString (WORD id, char* lpText, DWORD size); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/customData.h b/PlugY/customData.h new file mode 100644 index 0000000..8605b01 --- /dev/null +++ b/PlugY/customData.h @@ -0,0 +1,15 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Data added to D2 base-stucture + +=================================================================*/ + +#pragma once + +#include "playerCustomData.h" + +#define CBPlayerData void +#define CBItemData void + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/customLibraries.h b/PlugY/customLibraries.h new file mode 100644 index 0000000..1879a7e --- /dev/null +++ b/PlugY/customLibraries.h @@ -0,0 +1,46 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Language management. + +=================================================================*/ + +#pragma once + +typedef int (STDCALL *TsaveSaveFile) (Unit* ptChar, BYTE** data, DWORD* maxSize, DWORD* curSize); +typedef int (STDCALL *TloadSaveFile) (Unit* ptChar, BYTE* data, DWORD maxSize, DWORD* curSize); +typedef int (STDCALL *TinitSaveFile) (BYTE** data, DWORD* maxSize, DWORD* curSize); + +class TCustomDll +{ +public: + union { + HMODULE module; + DWORD offset; + }; + TCustomDll* nextDll; + void initialize(DWORD offsetDll); + void init(); + void release(); + void saveExtendedSaveFile (Unit* ptChar, BYTE** data, DWORD* maxSize, DWORD* curSize); + int loadExtendedSaveFile (Unit* ptChar, BYTE* data, DWORD maxSize, DWORD* curSize); + int initExtendedSaveFile (BYTE** data, DWORD* maxSize, DWORD* curSize); + void saveSharedSaveFile (Unit* ptChar, BYTE** data, DWORD* maxSize, DWORD* curSize); + int loadSharedSaveFile (Unit* ptChar, BYTE* data, DWORD maxSize, DWORD* curSize); + int initSharedSaveFile (BYTE** data, DWORD* maxSize, DWORD* curSize); +// __inline TCustomDll() {ZeroMemory(this,sizeof(this));} +private: + FARPROC initFct; + FARPROC releaseFct; + TsaveSaveFile saveExtendedSaveFileFct; + TloadSaveFile loadExtendedSaveFileFct; + TinitSaveFile initExtendedSaveFileFct; + TsaveSaveFile saveSharedSaveFileFct; + TloadSaveFile loadSharedSaveFileFct; + TinitSaveFile initSharedSaveFileFct; +}; + +extern TCustomDll* customDlls; + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/d2functions.h b/PlugY/d2functions.h new file mode 100644 index 0000000..a131e87 --- /dev/null +++ b/PlugY/d2functions.h @@ -0,0 +1,75 @@ +/*================================================ + File created by Yohann NICOLAS. + + This file implements some common and useful + function related to some Diablo II mechanisms. + +================================================*/ + +#pragma once + +#include "common.h" + +#define D2S(F, I, R, N, P) typedef R (STDCALL *T##N) P; extern T##N N;//static D N = (D)(A); +#define D2F(F, I, R, N, P) typedef R (FASTCALL *T##N) P; extern T##N N;//static D N = (D)(A); +#define E2S(F, A, R, N, P) typedef R (STDCALL *T##N) P; extern T##N N; +#define E2F(F, A, R, N, P) typedef R (FASTCALL *T##N) P; extern T##N N; +#define E2C(F, A, T, N) extern T* pt##N; +#define F7(X, Z, A,B,C,D,E,F,G, R, N, P) typedef R (X##CALL *T##N) P; extern T##N N; +#define A7(X, Z, A,B,C,D,E,F,G, R, N, P) typedef R (X##CALL *T##N) P; extern T##N N; +#define C7(Z, A,B,C,D,E,F,G, T, N) extern T* pt##N; + +#include "../Commons/D2Funcs.h" +extern DataTables* SgptDataTables; +//ONLY UNTIL 1.10 : +//E2F(D2Client,0, DWORD, D2isLODGame, ()); +//E2F(D2Client,0, BYTE, D2GetDifficultyLevel, ()); +//E2S(D2Client,0, DWORD, D2GetMouseX, ()); +//E2S(D2Client,0, DWORD, D2GetMouseY, ()); +//E2S(D2Client,0, Unit*, D2GetClientPlayer, ()); +//E2F(D2Client,0, void, D2SendToServer3, (BYTE type, WORD p)); +////E2F(D2Client,0, void, D2SendToServer7, (BYTE type, WORD p1, WORD p2, WORD p3)); +////E2F(D2Client,0, void, D2SendToServer5, (BYTE type, DWORD p)); +////E2F(D2Client,0, void, D2SendToServer9, (BYTE type, DWORD p1, DWORD p2)); +////E2F(D2Client,0, void, D2SendToServer13,(BYTE type, DWORD p1, DWORD p2, DWORD p3)); +//E2F(D2Game,0, NetClient*, D2GetClient, (Unit* ptUnit, char* lpszErrFile, DWORD ErrLine)); +//E2F(D2Client,0, void, D2CleanStatMouseUp, ()); + + +#undef F7 +#undef A7 +#undef C7 +#undef D2S +#undef D2F +#undef E2S +#undef E2F +#undef E2C + +extern TD2AddPlayerStat V2AddPlayerStat; +extern TD2GetGameByClientID V2GetGameByClientID; +extern TD2SpawnMonster V2SpawnMonster; +//extern TD2SetColorPopup V2SetColorPopup; +extern WORD (*getDescStrPos) (DWORD statID); +extern void* (STDCALL *compileTxtFile)(DWORD unused, const char* filename, BINField* ptFields, DWORD* ptRecordCount, DWORD recordLength); +void setImage(sDrawImageInfo* data, void* image); +void setFrame(sDrawImageInfo* data, DWORD frame); +void __inline fillRect(DWORD x, DWORD y, DWORD Width, DWORD Height, DWORD color, DWORD transTbl){D2FillArea(x,y,x+Width,y+Height,color,transTbl);}; + +//#define SgptDataTables (*ptSgptDataTables) +#define ResolutionY (*ptResolutionY) +#define ResolutionX (*ptResolutionX) +#define NegWindowStartY (*ptNegWindowStartY) +#define WindowStartX (*ptWindowStartX) +#define GameTypeMode (*ptGameTypeMode) +#define ClientTable (*ptClientTable) + +#define IsLodGame (*ptIsLodGame) +#define DifficultyLevel (*ptDifficultyLevel) +#define MouseY (*ptMouseY) +#define MouseX (*ptMouseX) +#define ptClientChar (*ptptClientChar) +//#define CurrentNPCNum (*ptCurrentNPCNum) + +bool initD2functions(); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/error.h b/PlugY/error.h new file mode 100644 index 0000000..41da484 --- /dev/null +++ b/PlugY/error.h @@ -0,0 +1,24 @@ +/*============================================== + File created by Yohann NICOLAS. + + @file error.hpp + @brief Error logger definition. + + This file defiens various functions related to + error handling in D2External functions. + +==============================================*/ + +#ifndef __ERROR_H__INCLUDED__ +#define __ERROR_H__INCLUDED__ + +#include + +extern DWORD active_logFile; + +void log_initfile(); +void log_box( const char* pFormat, ... ); +void log_msg( const char* pFormat, ... ); +void d2_assert( bool pCondition, char* pLocation, char* pMessage, int pLineNbr ); + +#endif \ No newline at end of file diff --git a/PlugY/extendedSaveFile.h b/PlugY/extendedSaveFile.h new file mode 100644 index 0000000..dfec118 --- /dev/null +++ b/PlugY/extendedSaveFile.h @@ -0,0 +1,21 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Add an extra save file for each characters. + +=================================================================*/ + +#pragma once + +#include "common.h" +#include + +BYTE* readExtendedSaveFile(char* name, DWORD* size); +void writeExtendedSaveFile(char* name, BYTE* data, DWORD size); + +int loadExtendedSaveFile(Unit* ptChar, BYTE* data, DWORD maxSize); +void saveExtendedSaveFile(Unit* ptChar, BYTE** data, DWORD* maxSize, DWORD* curSize); + +void backupExtendedSaveFile(char* name); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/extraOptions.h b/PlugY/extraOptions.h new file mode 100644 index 0000000..6ec75c7 --- /dev/null +++ b/PlugY/extraOptions.h @@ -0,0 +1,31 @@ +/*================================================================= + File created by Yohann NICOLAS. + + More little options. + +=================================================================*/ + +#ifndef __EXTRAOPTIONS_H__INCLUDED +#define __EXTRAOPTIONS_H__INCLUDED + +extern int active_RunLODs; +extern int active_alwaysRegenMapInSP; +extern DWORD nbPlayersCommandByDefault; +extern int active_DisplayItemLevel; +extern int active_AlwaysDisplayLifeMana; +extern int active_EnabledTXTFilesWithMSExcel; +extern int active_DisplayBaseStatsValue; +extern int active_LadderRunewords; +extern int active_EnabledCowPortalWhenCowKingWasKill; + +void Install_RunLODs(); +void Install_AlwaysRegenMapInSP(); +void Install_SendPlayersCommand(); +void Install_DisplayItemLevel(); +void Install_AlwaysDisplayLifeMana(); +void Install_EnabledTXTFilesWithMSExcel(); +void Install_DisplayBaseStatsValue(); +void Install_LadderRunewords(); +void Install_EnabledCowPortalWhenCowKingWasKill(); + +#endif \ No newline at end of file diff --git a/PlugY/globalVariable.h b/PlugY/globalVariable.h new file mode 100644 index 0000000..a3152b9 --- /dev/null +++ b/PlugY/globalVariable.h @@ -0,0 +1,16 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Set global variable. + +=================================================================*/ + +#ifndef __GLOBAL_VARIABLE_H__INCLUDED +#define __GLOBAL_VARIABLE_H__INCLUDED + +extern bool onRealm; +extern bool needToInit; + +void Install_VariableOnRealm(); + +#endif \ No newline at end of file diff --git a/PlugY/infinityStash.h b/PlugY/infinityStash.h new file mode 100644 index 0000000..d19eed8 --- /dev/null +++ b/PlugY/infinityStash.h @@ -0,0 +1,46 @@ +/*================================================================= + File created by Yohann NICOLAS. + + infinity Stash gestion + +=================================================================*/ + +#pragma once + +#include "common.h" + +extern DWORD maxSelfPages; +extern DWORD maxSharedPages; +extern DWORD nbPagesPerIndex; +extern DWORD nbPagesPerIndex2; +extern bool active_multiPageStash; +extern bool active_sharedStash; +extern bool active_sharedGold; +extern bool separateHardSoftStash; +extern char* sharedStashFilename; + +extern bool displaySharedSetItemNameInGreen; +extern int posXPreviousBtn,posYPreviousBtn,posXNextBtn,posYNextBtn,posXSharedBtn,posYSharedBtn,posXPreviousIndexBtn,posYPreviousIndexBtn,posXNextIndexBtn,posYNextIndexBtn,posXPutGoldBtn,posYPutGoldBtn,posXTakeGoldBtn,posYTakeGoldBtn; + + +void toggleToSharedStash(Unit* ptChar); +void toggleToSelfStash(Unit* ptChar); +void selectPreviousStash(Unit* ptChar); +void selectNextStash(Unit* ptChar); +void selectPreviousIndexStash(Unit* ptChar); +void selectNextIndexStash(Unit* ptChar); +void selectPrevious2Stash(Unit* ptChar); +void selectNext2Stash(Unit* ptChar); +void selectPreviousIndex2Stash(Unit* ptChar); +void selectNextIndex2Stash(Unit* ptChar); + +void selectStash(Unit* ptChar, Stash* newStash); +void setSelectedStashClient(DWORD stashId, DWORD stashFlags, DWORD flags); + +Stash* addStash(Unit* ptChar, bool isShared); +DWORD loadStashList(Unit* ptChar, BYTE* data, DWORD maxSize, DWORD* curSize, bool isShared); +void saveStashList(Unit* ptChar, Stash* ptStash, BYTE** data, DWORD* maxSize, DWORD* curSize); + +void Install_MultiPageStash(); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/interface_Skills.h b/PlugY/interface_Skills.h new file mode 100644 index 0000000..60790cb --- /dev/null +++ b/PlugY/interface_Skills.h @@ -0,0 +1,13 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Interface Skills functions + +=================================================================*/ + +#ifndef __INTERFACE_SKILLS_HPP__INCLUDED +#define __INTERFACE_SKILLS_HPP__INCLUDED + +void Install_InterfaceSkills(); + +#endif \ No newline at end of file diff --git a/PlugY/interface_Stash.h b/PlugY/interface_Stash.h new file mode 100644 index 0000000..588ebb0 --- /dev/null +++ b/PlugY/interface_Stash.h @@ -0,0 +1,13 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Interface functions + +=================================================================*/ + +#ifndef __INTERFACE_STASH_HPP__INCLUDED +#define __INTERFACE_STASH_HPP__INCLUDED + +void Install_InterfaceStash(); + +#endif \ No newline at end of file diff --git a/PlugY/interface_Stats.h b/PlugY/interface_Stats.h new file mode 100644 index 0000000..e7282ad --- /dev/null +++ b/PlugY/interface_Stats.h @@ -0,0 +1,13 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Interface Stats functions + +=================================================================*/ + +#ifndef __INTERFACE_STATS_HPP__INCLUDED +#define __INTERFACE_STATS_HPP__INCLUDED + +void Install_InterfaceStats(); + +#endif \ No newline at end of file diff --git a/PlugY/language.h b/PlugY/language.h new file mode 100644 index 0000000..5dbc9e2 --- /dev/null +++ b/PlugY/language.h @@ -0,0 +1,39 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Language management. + +=================================================================*/ + +#ifndef __LANGUAGE_H__INCLUDED +#define __LANGUAGE_H__INCLUDED + +extern bool active_ChangeLanguage; +extern DWORD selectedLanguage; + +extern bool active_LanguageManagement; +extern DWORD defaultLanguage; + +union t_availableLanguages +{ + DWORD all; + struct { + DWORD eng:1; + DWORD esp:1; + DWORD deu:1; + DWORD fra:1; + DWORD por:1; + DWORD ita:1; + DWORD jpn:1; + DWORD kor:1; + DWORD sin:1; + DWORD chi:1; + DWORD pol:1; + DWORD rus:1; + }; +}; +extern t_availableLanguages availableLanguages; + +void Install_LanguageManagement(); + +#endif \ No newline at end of file diff --git a/PlugY/loadPlayerData.h b/PlugY/loadPlayerData.h new file mode 100644 index 0000000..0eb25ab --- /dev/null +++ b/PlugY/loadPlayerData.h @@ -0,0 +1,13 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Load Player Custom Data. + +=================================================================*/ + +#ifndef __LOADPLAYERDATA_H__INCLUDED +#define __LOADPLAYERDATA_H__INCLUDED + +void Install_LoadPlayerData(); + +#endif \ No newline at end of file diff --git a/PlugY/mainScreen.h b/PlugY/mainScreen.h new file mode 100644 index 0000000..8514261 --- /dev/null +++ b/PlugY/mainScreen.h @@ -0,0 +1,22 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Add "plugY v1.00" on screen. + +=================================================================*/ + +#ifndef __MAINSCREEN_H__INCLUDED +#define __MAINSCREEN_H__INCLUDED + +#include + +extern bool active_VersionTextChange; +extern char* versionText; +extern BYTE modVersionColor; +extern bool active_PrintPlugYVersion; +extern BYTE colorOfPlugYVersion; + +void Install_PrintPlugYVersion(); +void Install_VersionChange(); + +#endif \ No newline at end of file diff --git a/PlugY/modifMemory.h b/PlugY/modifMemory.h new file mode 100644 index 0000000..1ae47f1 --- /dev/null +++ b/PlugY/modifMemory.h @@ -0,0 +1,33 @@ +/*============================================== + File created by Yohann NICOLAS. + + Modification of code in memory functions. + +/*============================================*/ + +#pragma once + +extern void* currentMemoryPos; +DWORD mem_seek(DWORD newPos); + +void memt_byte(BYTE old, BYTE val); + +#define MEMT_DWORD(O, R) memt_dword((DWORD)(O), (DWORD)(R)) +void memt_dword(DWORD old, DWORD val); + +#define MEMT_REF4(O, R) memt_ref4((DWORD)(O), (DWORD)(R)) +void memt_ref4(DWORD old, DWORD ref); + +//CALL +#define MEMJ_REF4(O, R) memj_ref4((DWORD)(O), (DWORD)(R)) +void memj_ref4(DWORD old, DWORD ref); + +//CALL D2Common.6FD5F500 +#define MEMC_REF4(O, R) memc_ref4((DWORD)(O), (DWORD)(R)) +void memc_ref4(DWORD old, DWORD ref); + +//CALL DWORD PTR DS:[<&USER32.GetKeyState>] +#define MEMD_REF4(O, R) memd_ref4((DWORD)(O), (DWORD)(R)) +void memd_ref4(DWORD old, DWORD ref); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/newInterface_CubeListing.h b/PlugY/newInterface_CubeListing.h new file mode 100644 index 0000000..8ad2b10 --- /dev/null +++ b/PlugY/newInterface_CubeListing.h @@ -0,0 +1,13 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Cube Listing functions + +=================================================================*/ + +#ifndef __NEWINTERFACE_CUBELISTING_H__INCLUDED +#define __NEWINTERFACE_CUBELISTING_H__INCLUDED + +void listAllCubeFormula(); + +#endif \ No newline at end of file diff --git a/PlugY/newInterface_Runewords.h b/PlugY/newInterface_Runewords.h new file mode 100644 index 0000000..5220079 --- /dev/null +++ b/PlugY/newInterface_Runewords.h @@ -0,0 +1,15 @@ +/*================================================================= + File created by Yohann NICOLAS. + + New runeword Interface + +=================================================================*/ + +#ifndef __NEWINTERFACE_RUNEWORDS_H__INCLUDED +#define __NEWINTERFACE_RUNEWORDS_H__INCLUDED + +void STDCALL printRunewordsPage(); +DWORD STDCALL mouseRunewordsPageLeftDown(sWinMessage* msg); +DWORD STDCALL mouseRunewordsPageLeftUp(sWinMessage* msg); + +#endif \ No newline at end of file diff --git a/PlugY/newInterface_Stats.h b/PlugY/newInterface_Stats.h new file mode 100644 index 0000000..e11f242 --- /dev/null +++ b/PlugY/newInterface_Stats.h @@ -0,0 +1,15 @@ +/*================================================================= + File created by Yohann NICOLAS. + + New Stat Interface + +=================================================================*/ + +#ifndef __NEWINTERFACE_STATS_H__INCLUDED +#define __NEWINTERFACE_STATS_H__INCLUDED + +void STDCALL printNewStatsPage(); +DWORD STDCALL mouseNewStatsPageLeftDown(sWinMessage* msg); +DWORD STDCALL mouseNewStatsPageLeftUp(sWinMessage* msg); + +#endif \ No newline at end of file diff --git a/PlugY/newInterface_StatsPageTwo.h b/PlugY/newInterface_StatsPageTwo.h new file mode 100644 index 0000000..f62c0bc --- /dev/null +++ b/PlugY/newInterface_StatsPageTwo.h @@ -0,0 +1,15 @@ +/*================================================================= + File created by Yohann NICOLAS. + + New Stat Interface Page 2 + +=================================================================*/ + +#ifndef __NEWINTERFACE_STATSPAGETWO_H__INCLUDED +#define __NEWINTERFACE_STATSPAGETWO_H__INCLUDED + +void STDCALL printNewStatsPageTwo(int currentPage); +DWORD STDCALL mouseNewStatsPageTwoLeftDown(sWinMessage* msg); +DWORD STDCALL mouseNewStatsPageTwoLeftUp(sWinMessage* msg); + +#endif \ No newline at end of file diff --git a/PlugY/newInterfaces.h b/PlugY/newInterfaces.h new file mode 100644 index 0000000..8d41b4b --- /dev/null +++ b/PlugY/newInterfaces.h @@ -0,0 +1,27 @@ +/*================================================================= + File created by Yohann NICOLAS. + + New Interfaces functions + +=================================================================*/ + +#ifndef __NEW_INTERFACES_H__INCLUDED +#define __NEW_INTERFACES_H__INCLUDED + +#define MILIEU(X,L,N) (X + ((N + +BYTE* readSharedSaveFile(char* name, DWORD* size); +void writeSharedSaveFile(char* name, BYTE* data, DWORD size, bool isHardcore); + +int loadSharedSaveFile(Unit* ptChar, BYTE* data, DWORD maxSize); +void saveSharedSaveFile(Unit* ptChar, BYTE** data, DWORD* maxSize, DWORD* curSize); + +void backupSharedSaveFile(); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/skillPerLevelUp.h b/PlugY/skillPerLevelUp.h new file mode 100644 index 0000000..3c1f135 --- /dev/null +++ b/PlugY/skillPerLevelUp.h @@ -0,0 +1,17 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Change Skill win per level up. + +=================================================================*/ + +#pragma once + +#include + +extern bool active_SkillPerLevelUpChange; +extern DWORD skillPerLevelUp; + +void Install_SkillPerLevelUp(); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/skillsPoints.h b/PlugY/skillsPoints.h new file mode 100644 index 0000000..9daf4ec --- /dev/null +++ b/PlugY/skillsPoints.h @@ -0,0 +1,20 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Unassign Skill Point for futher re-assignment. + +=================================================================*/ + +#ifndef __SKILLSPOINTS_H__INCLUDED +#define __SKILLSPOINTS_H__INCLUDED + +extern bool active_SkillsPoints; +extern bool unassignSkillsPointsOneByOne; +extern int posXUnassignSkillBtn, posYUnassignSkillBtn; + +void UnassignAllSkillsPoints(Unit* ptChar); +void client_UnassignAllSkillsPoints(); + +void Install_SkillsPoints(); + +#endif \ No newline at end of file diff --git a/PlugY/statPerLevelUp.h b/PlugY/statPerLevelUp.h new file mode 100644 index 0000000..6bab6bd --- /dev/null +++ b/PlugY/statPerLevelUp.h @@ -0,0 +1,17 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Change Stat win per level up. + +=================================================================*/ + +#pragma once + +#include + +extern bool active_StatPerLevelUpChange; +extern DWORD statPerLevelUp; + +void Install_StatPerLevelUp(); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/statsPoints.h b/PlugY/statsPoints.h new file mode 100644 index 0000000..010803e --- /dev/null +++ b/PlugY/statsPoints.h @@ -0,0 +1,29 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Unassign Stats Point for futher re-assignment. + +=================================================================*/ + +#pragma once + +#include + +extern bool active_StatsPoints; +extern DWORD keyUsedForUnassignStatPoint; +extern bool active_StatsShiftClickLimit; +extern DWORD limitValueToShiftClick; + +void UnassignStrPoint(Unit* ptChar); +void UnassignStrPoints(Unit* ptChar); +void UnassignDexPoint(Unit* ptChar); +void UnassignDexPoints(Unit* ptChar); +void UnassignVitPoint(Unit* ptChar); +void UnassignVitPoints(Unit* ptChar); +void UnassignEnePoint(Unit* ptChar); +void UnassignEnePoints(Unit* ptChar); + +void Install_StatsLimitShiftClick(); +void Install_StatsPoints(); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/uberQuest.h b/PlugY/uberQuest.h new file mode 100644 index 0000000..087cb7d --- /dev/null +++ b/PlugY/uberQuest.h @@ -0,0 +1,15 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Uber Quest Management. + +=================================================================*/ + +#pragma once + +extern bool active_UberQuest; + +void Install_UberQuest(); +void resetQuestState(); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/updateClient.h b/PlugY/updateClient.h new file mode 100644 index 0000000..f99575e --- /dev/null +++ b/PlugY/updateClient.h @@ -0,0 +1,16 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Updating Client. + +=================================================================*/ + +#ifndef __UPDATECLIENT_H__INCLUDED +#define __UPDATECLIENT_H__INCLUDED + +#include "common.h" + +void Install_UpdateClient(); +void updateClient(Unit* ptChar, DWORD mFunc, DWORD p1, DWORD p2, DWORD p3); + +#endif \ No newline at end of file diff --git a/PlugY/updateServer.h b/PlugY/updateServer.h new file mode 100644 index 0000000..640ef4c --- /dev/null +++ b/PlugY/updateServer.h @@ -0,0 +1,16 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Updating Server. + +=================================================================*/ + +#pragma once + +#include "common.h" +#include "D2functions.h" + +__inline void updateServer(WORD p) {if (!onRealm) D2SendToServer3(0x3A, p);}; +void Install_UpdateServer(); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugY/worldEvent.h b/PlugY/worldEvent.h new file mode 100644 index 0000000..f71c2ce --- /dev/null +++ b/PlugY/worldEvent.h @@ -0,0 +1,27 @@ +/*================================================================= + File created by Yohann NICOLAS. + + World Event Management. + +=================================================================*/ + +#pragma once + +extern bool active_WorldEvent; +extern DWORD showSOJSoldCounterInAllDiff; +extern char* itemsToSell; +extern DWORD worldEventmonsterID; +extern DWORD valueOfOwnSOJSold; +extern DWORD valueInitSOJSoldMin; +extern DWORD valueInitSOJSoldDelta; +extern DWORD triggerAtSolJSoldMin; +extern DWORD triggerAtSolJSoldDelta; +extern bool active_AutomaticSell; +extern DWORD timeBeforeAutoSellMin; +extern DWORD timeBeforeAutoSellDelta; + +void initWorldEventVariables(); + +void Install_WorldEvent(); + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugYInstall/PlugYInstall.aps b/PlugYInstall/PlugYInstall.aps new file mode 100644 index 0000000..7cc6293 Binary files /dev/null and b/PlugYInstall/PlugYInstall.aps differ diff --git a/PlugYInstall/PlugYInstall.cpp b/PlugYInstall/PlugYInstall.cpp new file mode 100644 index 0000000..2c3c56e --- /dev/null +++ b/PlugYInstall/PlugYInstall.cpp @@ -0,0 +1,456 @@ +/*================================================================= + File created by Yohann NICOLAS. + + Patch D2gfx.dll to install PlugY. + +=================================================================*/ + +#include +#include + +const char* boxNameInstall = "Installation of PlugY, The Survival Kit Installation"; +const char* boxNameUnInstall = "Uninstall PlugY, The Survival Kit "; + +int CALL_LOAD[7] = {0x389B,0x389B,0x3870,0x8B23,0xB423,0x8F63,0xB423}; +BYTE callNewLoad[7][6]={{0xE8,0x60,0x85,0x00,0x00,0x90},// JMP 6FA7BE00-6FA738A0 ;install loadlibrary + {0xE8,0x60,0x85,0x00,0x00,0x90},// JMP 6FA7BE00-6FA738A0 ;install loadlibrary + {0xE8,0x8B,0x85,0x00,0x00,0x90},// JMP 6FA7BE00-6FA73875 ;install loadlibrary + {0xE8,0xD8,0x42,0x00,0x00,0x90},// JMP 6FA8CE00-6FA88B28 ;install loadlibrary + {0xE8,0xD8,0x19,0x00,0x00,0x90},// JMP 6FA8CE00-6FA8B428 ;install loadlibrary + {0xE8,0x98,0x3E,0x00,0x00,0x90},// JMP 6FA8CE00-6FA88F68 ;install loadlibrary + {0xE8,0xD8,0x19,0x00,0x00,0x90}};// JMP 6FA8CE00-6FA8B428 ;install loadlibrary +BYTE callOldLoad[7][6]={{0xFF,0x15,0x3C,0xC0,0xA7,0x6F}, + {0xFF,0x15,0x3C,0xC0,0xA7,0x6F}, + {0xFF,0x15,0x40,0xC0,0xA7,0x6F}, + {0xFF,0x15,0x1C,0xD1,0xA8,0x6F}, + {0xFF,0x15,0x1C,0xD1,0xA8,0x6F}, + {0xFF,0x15,0x1C,0xD1,0xA8,0x6F}, + {0xFF,0x15,0x1C,0xD1,0xA8,0x6F}}; + +int CALL_FREE[7] = {0x3A8C,0x3A8C,0x3A6D,0x8ACA,0xB3CA,0x8F0A,0xB3CA}; +BYTE callNewFree[7][6]={{0xE8,0xAF,0x83,0x00,0x00,0x90}, // JMP 6FA7BE40-6FA73A91 ;install freelibrary + {0xE8,0xAF,0x83,0x00,0x00,0x90}, // JMP 6FA7BE40-6FA73A91 ;install freelibrary + {0xE8,0xD2,0x83,0x00,0x00,0x90}, // JMP 6FA7BE44-6FA73A72 ;install freelibrary + {0xE8,0x75,0x43,0x00,0x00,0x90}, // JMP 6FA8CE44-6FA88ACF ;install freelibrary + {0xE8,0x75,0x1A,0x00,0x00,0x90}, // JMP 6FA8CE44-6FA8B3CF ;install freelibrary + {0xE8,0x35,0x3F,0x00,0x00,0x90}, // JMP 6FA8CE44-6FA88F0F ;install freelibrary + {0xE8,0x75,0x1A,0x00,0x00,0x90}};// JMP 6FA8CE44-6FA8B3CF ;install freelibrary +BYTE callOldFree[7][6]={{0xFF,0x15,0x44,0xC0,0xA7,0x6F}, // CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] + {0xFF,0x15,0x44,0xC0,0xA7,0x6F}, // CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] + {0xFF,0x15,0x48,0xC0,0xA7,0x6F}, // CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] + {0xFF,0x15,0x2C,0xD1,0xA8,0x6F}, // CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] + {0xFF,0x15,0x2C,0xD1,0xA8,0x6F}, // CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] + {0xFF,0x15,0x2C,0xD1,0xA8,0x6F}, // CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] + {0xFF,0x15,0x2C,0xD1,0xA8,0x6F}};// CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] + +int CALLER_LOADPLUGY = 0xBE00;//6FA7BE00-6FA70000 +BYTE caller_LoadPlugY[]={ +0xFF,0x74,0x24,0x04, //PUSH DWORD PTR SS:[ESP+4] +0xFF,0x15,0x40,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryA>] ; kernel32.LoadLibraryA +0x50, //PUSH EAX +0x68,0x80,0xBE,0xA7,0x6F, //PUSH d2gfx.6FA7BE80 ; ASCII "PlugY.dll" +0xFF,0x15,0x40,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryA>] ; kernel32.LoadLibraryA +0xA3,0xFC,0xEF,0xA8,0x6F, //MOV DWORD PTR DS:[6FA8EFFC],EAX +0x85,0xC0, //TEST EAX,EAX +0x74,0x18, //JE SHORT d2gfx.6FA7BE37 +0x68,0x90,0xBE,0xA7,0x6F, //PUSH d2gfx.6FA7BE10 ;Init ID +0x50, //PUSH EAX +0xFF,0x15,0x3C,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.GetProcAddress>] ; kernel32.GetProcAddress +0x85,0xC0, //TEST EAX,EAX +0x74,0x04, //JE SHORT d2gfx.6FA7BDC1 +0x6A,0x00, //PUSH 0 +0xFF,0xD0, //CALL EAX +0x58, //POP EAX +0xC2,0x04,0x00, //RETN 4 +0x59, //POP ECX +0xB9,0x80,0xBE,0xA7,0x6F, //MOV ECX,d2gfx.6FA7BE80 ; ASCII "PlugY.dll" +0x83,0x04,0x24,0x11, //ADD DWORD PTR SS:[ESP],11 +0xC2,0x04,0x00}; //RETN 4 + + +int CALLER_FREEPLUGY = 0xBE44;//6FA7BE44-6FA70000 +BYTE caller_FreePlugY[]={ +0xFF,0x74,0x24,0x04, //PUSH DWORD PTR SS:[ESP+4] +0xFF,0x15,0x48,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] ; kernel32.FreeLibrary +0x50, //PUSH EAX +0xA1,0xFC,0xEF,0xA8,0x6F, //MOV EAX,DWORD PTR DS:[6FA8EFFC] +0x85,0xC0, //TEST EAX,EAX +0x74,0x20, //JE SHORT d2gfx.6FA7BE74 +0x50, //PUSH EAX +0x68,0xA0,0xBE,0xA7,0x6F, //PUSH d2gfx.6FA7BE20 ;release +0x50, //PUSH EAX +0x33,0xC0, //XOR EAX,EAX +0xA3,0xFC,0xEF,0xA8,0x6F, //MOV DWORD PTR DS:[6FA8EFFC],EAX +0xFF,0x15,0x3C,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; kernel32.GetProcAddress +0x85,0xC0, //TEST EAX,EAX +0x74,0x02, //JE SHORT d2gfx.6FA7BDEF +0xFF,0xD0, //CALL EAX +0xFF,0x15,0x48,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.FreeLibrar>; kernel32.FreeLibrary +0x58, //POP EAX +0xC2,0x04,0x00}; //RETN 4 + + +int S_DLLNAME = 0xBE80;//6FA7BE30-6FA70000 +BYTE sDllName[]={'P','l','u','g','Y','.','d','l','l',0};// Dll filename to load. + +int S_INIT = 0xBE90;//6FA7BE10-6FA70000 +BYTE sInit[]={'_','I','n','i','t','@','4',0}; + +int S_RELEASE = 0xBEA0;//6FA7BE20-6FA70000 +BYTE sRelease[]={'_','R','e','l','e','a','s','e','@','0',0}; + +enum eFileVersion +{ + V109b=0, + V109d, + V110, + V111, + V111b, + V112, + V113c, + UNKNOW +}; + +int getVersion(FILE *dll) +{ + int ver; + //GET_VERSION(D2gfx, 80, 110, 0x00949FA8, 0x018866A8, 0x401526B2, 0x575C8A5E, 0x42E6C22A, 0x43028B19, 0xACBE1B9E, 0x00000000); + int addr; + fseek(dll,0x80,SEEK_SET); + fread(&addr,sizeof(addr),1,dll); + if (addr == 0x00949FA8) + ver = V109b; + else if (addr == 0x018866A8) + ver = V109d; + else if (addr == 0x401526B2) + ver = V110; + else if (addr == 0x575C8A5E) + { + fseek(dll,0x110,SEEK_SET); + fread(&addr,sizeof(addr),1,dll); + if (addr == 0x42E6C22A) + ver = V111; + else if (addr == 0x43028B19) + ver = V111b; + else + ver = UNKNOW; + } + else if (addr == 0xACBE1B9E) + ver = V112; + else if (addr == 0xACBE1BB6) + ver = V113c; + else + ver = UNKNOW; + return ver; +} + + +void updateData(int version) +{ + switch(version) + { + case V109b: + case V109d: + caller_LoadPlugY[6] -= 4; + caller_LoadPlugY[18] -= 4; + caller_LoadPlugY[39] -= 4; + caller_FreePlugY[6] -= 4; + caller_FreePlugY[36] -= 4; + caller_FreePlugY[48] -= 4; + break; + case V110: + break; + case V111: + case V111b: + case V112: + case V113c: + CALLER_LOADPLUGY += 0x1000; + CALLER_FREEPLUGY += 0x1000; + S_INIT += 0x1000; + S_RELEASE += 0x1000; + S_DLLNAME += 0x1000; + *(DWORD*)(&caller_LoadPlugY[6]) = 0x6FA8D11C; + *(DWORD*)(&caller_LoadPlugY[18]) = 0x6FA8D11C; + *(DWORD*)(&caller_LoadPlugY[39]) = 0x6FA8D120; + *(DWORD*)(&caller_FreePlugY[6]) = 0x6FA8D12C; + *(DWORD*)(&caller_FreePlugY[36]) = 0x6FA8D120; + *(DWORD*)(&caller_FreePlugY[48]) = 0x6FA8D12C; + caller_LoadPlugY[13] += 0x10; + caller_LoadPlugY[14]++; + caller_LoadPlugY[25]++; + caller_LoadPlugY[33] += 0x10; + caller_LoadPlugY[34]++; + caller_LoadPlugY[58] += 0x10; + caller_LoadPlugY[59]++; + caller_FreePlugY[23] += 0x10; + caller_FreePlugY[24]++; + caller_FreePlugY[14]++; + caller_FreePlugY[32]++; + break; + } +} + +////////////////////////////// EXPORTED FUNCTIONS ////////////////////////////// + +void Patch() +{ + if (MessageBox(0,"This programm will modify the D2gfx.dll file of the current directory.\n" + "Before continue, don't forgot to backup D2gfx.dll if you want\n" + "Do you want patch D2gfx.dll for the launch of PlugY ?", + boxNameInstall, MB_YESNO|MB_ICONQUESTION) == IDNO) + { + MessageBox(0,"D2gfx.dll isn't patched.\n", + boxNameInstall, MB_OK|MB_ICONASTERISK); + exit(0); + } + + FILE *dll=fopen("d2gfx.dll","rb+"); + + if(!dll) + { + MessageBox(0,"Can't open D2gfx.dll in read/write mode\n" + "If Diablo II is running you can\'t install PlugY, The Survival Kit.\n" + "Quit Diablo II and try again.", + boxNameInstall, MB_OK|MB_ICONEXCLAMATION); + exit(0); + } + + int version = getVersion(dll); + + if (version == UNKNOW) + { + MessageBox(0,"Bad version of D2gfx.dll.\n" + "You can try to uninstall any previous version of PlugY, The Survival Kit then retry.\n" + "Or re-install a clean version (between 1.09 and 1.12) of LOD.", + boxNameInstall, MB_OK|MB_ICONEXCLAMATION); + exit(0); + } + + updateData(version); + + bool error = false; + int ident = 0; + BYTE buffer[100]; + BYTE zeros[100]; + memset(zeros,0,sizeof(zeros)); + + fseek(dll,CALL_LOAD[version],SEEK_SET); + fread(buffer,6,1,dll); + if(memcmp(buffer, callOldLoad[version], 6) !=0 ) error = true; + if(memcmp(buffer, callNewLoad[version], 6) ==0 ) ident++; + + fseek(dll,CALL_FREE[version],SEEK_SET); + fread(buffer,6,1,dll); + if(memcmp(buffer, callOldFree[version], 6) !=0 ) error = true; + if(memcmp(buffer, callNewFree[version], 6) ==0 ) ident++; + + fseek(dll,CALLER_LOADPLUGY,SEEK_SET); + fread(buffer,sizeof(caller_LoadPlugY),1,dll); + if(memcmp(buffer, zeros, sizeof(caller_LoadPlugY)) !=0 ) error = true; + if(memcmp(buffer, caller_LoadPlugY, sizeof(caller_LoadPlugY)) ==0 ) ident++; + + fseek(dll,CALLER_FREEPLUGY,SEEK_SET); + fread(buffer,sizeof(caller_FreePlugY),1,dll); + if(memcmp(buffer, zeros, sizeof(caller_FreePlugY)) !=0 ) error = true; + if(memcmp(buffer, caller_FreePlugY, sizeof(caller_FreePlugY)) ==0 ) ident++; + + fseek(dll,S_INIT,SEEK_SET); + fread(buffer,sizeof(sInit),1,dll); + if(memcmp(buffer, zeros, sizeof(sInit)) !=0 ) error = true; + if(memcmp(buffer, sInit, sizeof(sInit)) ==0 ) ident++; + + fseek(dll,S_RELEASE,SEEK_SET); + fread(buffer,sizeof(sRelease),1,dll); + if(memcmp(buffer, zeros, sizeof(sRelease)) !=0 ) error = true; + if(memcmp(buffer, sRelease, sizeof(sRelease)) ==0 ) ident++; + + fseek(dll,S_DLLNAME,SEEK_SET); + fread(buffer,sizeof(sDllName),1,dll); + if(memcmp(buffer, zeros, sizeof(sDllName)) !=0 ) error = true; + if(memcmp(buffer, sDllName, sizeof(sDllName)) ==0 ) ident++; + + if (error) + { + if (ident==7) + { + MessageBox(0, "PlugY, The Survival Kit already installed.", + boxNameInstall, MB_OK|MB_ICONASTERISK); + exit(0); + } else + { + MessageBox(0,"Bad version of D2gfx.dll.\n" + "You can try to uninstall any previous version of PlugY, The Survival Kit then retry.\n" + "Or re-install a clean version (between 1.09 and 1.11b) of LOD.", + boxNameInstall, MB_OK|MB_ICONEXCLAMATION); + exit(0); + } + } + + fseek(dll,CALL_LOAD[version],SEEK_SET); + fwrite(callNewLoad[version], 6, 1, dll); + + fseek(dll,CALL_FREE[version],SEEK_SET); + fwrite(callNewFree[version], 6, 1, dll); + + fseek(dll,CALLER_LOADPLUGY,SEEK_SET); + fwrite(caller_LoadPlugY, sizeof(caller_LoadPlugY), 1, dll); + + fseek(dll,CALLER_FREEPLUGY,SEEK_SET); + fwrite(caller_FreePlugY, sizeof(caller_FreePlugY), 1, dll); + + fseek(dll,S_INIT,SEEK_SET); + fwrite(sInit, sizeof(sInit), 1, dll); + + fseek(dll,S_RELEASE,SEEK_SET); + fwrite(sRelease, sizeof(sRelease), 1, dll); + + fseek(dll,S_DLLNAME,SEEK_SET); + fwrite(sDllName, sizeof(sDllName), 1, dll); + + fclose(dll); + + MessageBox(0,"D2gfx.dll patched successfully.\n" + "PlugY, The Survival Kit installed successfully.", + boxNameInstall, MB_OK|MB_ICONASTERISK); + + exit(0); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +void Unpatch() +{ + if (MessageBox(0,"This programm will modify the D2gfx.dll file of the current directory.\n" + "Before continue, don't forgot to backup D2gfx.dll if you want\n" + "Do you want patch D2gfx.dll for remove the launch of PlugY ?", + boxNameUnInstall, MB_YESNO|MB_ICONQUESTION) == IDNO) + { + MessageBox(0,"D2gfx.dll isn't patched.\n", + boxNameUnInstall, MB_OK|MB_ICONASTERISK); + exit(0); + } + + FILE *dll=fopen("d2gfx.dll","rb+"); + + if(!dll) + { + MessageBox(0,"Can't open D2gfx.dll in read/write mode.\n" + "If Diablo II is running you can\'t install PlugY, The Survival Kit.\n" + "Quit Diablo and try again.", + boxNameUnInstall, MB_OK|MB_ICONEXCLAMATION); + exit(0); + } + + int version = getVersion(dll); + + if (version == UNKNOW) + { + MessageBox(0,"Bad version of D2gfx.dll.\n" + "You can try to uninstall any previous version of PlugY, The Survival Kit then retry.\n" + "Or re-install a clean version (between 1.09 and 1.12) of LOD.", + boxNameUnInstall, MB_OK|MB_ICONEXCLAMATION); + exit(0); + } + + updateData(version); + + bool error = false; + int ident = 0; + BYTE buffer[100]; + BYTE zeros[100]; + memset(zeros,0,sizeof(zeros)); + + fseek(dll,CALL_LOAD[version],SEEK_SET); + fread(buffer,6,1,dll); + if(memcmp(buffer, callNewLoad[version], 6) !=0 ) error = true; + if(memcmp(buffer, callOldLoad[version], 6) ==0 ) ident++; + + fseek(dll,CALL_FREE[version],SEEK_SET); + fread(buffer,6,1,dll); + if(memcmp(buffer, callNewFree[version], 6) !=0 ) error = true; + if(memcmp(buffer, callOldFree[version], 6) ==0 ) ident++; + + fseek(dll,CALLER_LOADPLUGY,SEEK_SET); + fread(buffer,sizeof(caller_LoadPlugY),1,dll); + if(memcmp(buffer, caller_LoadPlugY, sizeof(caller_LoadPlugY)) !=0 ) error = true; + if(memcmp(buffer, zeros, sizeof(caller_LoadPlugY)) ==0 ) ident++; + + fseek(dll,CALLER_FREEPLUGY,SEEK_SET); + fread(buffer,sizeof(caller_FreePlugY),1,dll); + if(memcmp(buffer, caller_FreePlugY, sizeof(caller_FreePlugY)) !=0 ) error = true; + if(memcmp(buffer, zeros, sizeof(caller_FreePlugY)) ==0 ) ident++; + + fseek(dll,S_INIT,SEEK_SET); + fread(buffer,sizeof(sInit),1,dll); + if(memcmp(buffer, sInit, sizeof(sInit)) !=0 ) error = true; + if(memcmp(buffer, zeros, sizeof(sInit)) ==0 ) ident++; + + fseek(dll,S_RELEASE,SEEK_SET); + fread(buffer,sizeof(sRelease),1,dll); + if(memcmp(buffer, sRelease, sizeof(sRelease)) !=0 ) error = true; + if(memcmp(buffer, zeros, sizeof(sRelease)) ==0 ) ident++; + + fseek(dll,S_DLLNAME,SEEK_SET); + fread(buffer,sizeof(sDllName),1,dll); + if(memcmp(buffer, sDllName, sizeof(sDllName)) !=0 ) error = true; + if(memcmp(buffer, zeros, sizeof(sDllName)) ==0 ) ident++; + + if (error) + { + if (ident==7) + { + MessageBox(0,"PlugY, The Survival Kit already uninstalled.", + boxNameUnInstall, MB_OK|MB_ICONASTERISK); + exit(0); + } else { + MessageBox(0,"Bad version of D2gfx.dll.\n" + "Unable to uninstall PlugY, The Survival Kit.", + boxNameUnInstall, MB_OK|MB_ICONEXCLAMATION); + exit(0); + } + } + + fseek(dll,CALL_LOAD[version],SEEK_SET); + fwrite(callOldLoad[version], 6, 1, dll); + + fseek(dll,CALL_FREE[version],SEEK_SET); + fwrite(callOldFree[version], 6, 1, dll); + + fseek(dll,CALLER_LOADPLUGY,SEEK_SET); + fwrite(zeros, sizeof(caller_LoadPlugY), 1, dll); + + fseek(dll,CALLER_FREEPLUGY,SEEK_SET); + fwrite(zeros, sizeof(caller_FreePlugY), 1, dll); + + fseek(dll,S_INIT,SEEK_SET); + fwrite(zeros, sizeof(sInit), 1, dll); + + fseek(dll,S_RELEASE,SEEK_SET); + fwrite(zeros, sizeof(sRelease), 1, dll); + + fseek(dll,S_DLLNAME,SEEK_SET); + fwrite(zeros, sizeof(sDllName), 1, dll); + + fclose(dll); + + MessageBox(0,"D2gfx.dll patched successfully.\n" + "PlugY, The Survival Kit uninstalled successfully.", + boxNameUnInstall, MB_OK|MB_ICONASTERISK); + exit(0); +} + +int main(int argc, char * argv[]) +{ +// if ((argc>1) && !strcmp(argv[1],"-u")) +#ifdef RESTORE + Unpatch(); +#else + if ((argc>1) && !strcmp(argv[1],"-u")) + Unpatch(); + else + Patch(); +#endif +} + + +/*================================= END OF FILE =================================*/ \ No newline at end of file diff --git a/PlugYInstall/PlugYInstall.rc b/PlugYInstall/PlugYInstall.rc new file mode 100644 index 0000000..66ed8d3 --- /dev/null +++ b/PlugYInstall/PlugYInstall.rc @@ -0,0 +1,110 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// French (France) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,4,0 + PRODUCTVERSION 1,0,4,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "FileVersion", "1.04" + VALUE "OriginalFilename", "PlugY_Install.exe" + VALUE "ProductName", "PlugY Installation" + VALUE "ProductVersion", "1.04" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x40c, 1200 + END +END + +#endif // French (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/PlugYInstall/PlugYInstall.sln b/PlugYInstall/PlugYInstall.sln new file mode 100644 index 0000000..46222c0 --- /dev/null +++ b/PlugYInstall/PlugYInstall.sln @@ -0,0 +1,22 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlugYInstall", "PlugYInstall.vcproj", "{F7666190-876A-4D43-BA04-82F8F3F986DC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Restore|Win32 = Restore|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F7666190-876A-4D43-BA04-82F8F3F986DC}.Debug|Win32.ActiveCfg = Release|Win32 + {F7666190-876A-4D43-BA04-82F8F3F986DC}.Debug|Win32.Build.0 = Release|Win32 + {F7666190-876A-4D43-BA04-82F8F3F986DC}.Release|Win32.ActiveCfg = Release|Win32 + {F7666190-876A-4D43-BA04-82F8F3F986DC}.Release|Win32.Build.0 = Release|Win32 + {F7666190-876A-4D43-BA04-82F8F3F986DC}.Restore|Win32.ActiveCfg = Restore|Win32 + {F7666190-876A-4D43-BA04-82F8F3F986DC}.Restore|Win32.Build.0 = Restore|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PlugYInstall/PlugYInstall.suo b/PlugYInstall/PlugYInstall.suo new file mode 100644 index 0000000..b7dd910 Binary files /dev/null and b/PlugYInstall/PlugYInstall.suo differ diff --git a/PlugYInstall/PlugYInstall.vcproj b/PlugYInstall/PlugYInstall.vcproj new file mode 100644 index 0000000..bca4a99 --- /dev/null +++ b/PlugYInstall/PlugYInstall.vcproj @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PlugYInstall/PlugYInstall.vcproj.ATHLON64.Yohann.user b/PlugYInstall/PlugYInstall.vcproj.ATHLON64.Yohann.user new file mode 100644 index 0000000..5cbdb0a --- /dev/null +++ b/PlugYInstall/PlugYInstall.vcproj.ATHLON64.Yohann.user @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + diff --git a/PlugYInstall/resource.h b/PlugYInstall/resource.h new file mode 100644 index 0000000..1c031f4 --- /dev/null +++ b/PlugYInstall/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by PlugYInstall.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/PlugYInstaller/PlugY.ini b/PlugYInstaller/PlugY.ini new file mode 100644 index 0000000..4268f34 --- /dev/null +++ b/PlugYInstaller/PlugY.ini @@ -0,0 +1,117 @@ +;--------------------------------------------------------------------------------------; +; ; +; "PlugY, The Survival Kit" ; +; Configuration file ; +; ; +; by Yohann Nicolas ; +; ; +; version 10.00 ; +; ; +;--------------------------------------------------------------------------------------; + +; See PlugY_The_Survival_Kit_-_Readme.txt file for more documentation. +; Voir le fichier PlugY_The_Survival_Kit_-_LisezMoi.txt pour plus d'information. +; Siehe PlugY_The_Survival_Kit_-_Liesmich.txt fr weitere Informationen + +[LAUNCHING] +Param= +Library=PlugY.dll + + +[GENERAL] +ActivePlugin=1 +DisableBattleNet=1 +ActiveLogFile=0 +DllToLoad= +DllToLoad2= +ActiveCommands=1 +ActiveCheckMemory=1 + + +[LANGUAGE] +;ENG|ESP|DEU|FRA|POR|ITA|JPN|KOR|SIN|CHI|POL|RUS +ActiveChangeLanguage=0 +SelectedLanguage=ENG + + +[SAVEPATH] +ActiveSavePathChange=0 +SavePath=Save\Mod PlugY\ + + +[MAIN SCREEN] +ActiveVersionTextChange=1 +VersionText= +ColorOfVersionText=0 + +ActivePrintPlugYVersion=1 +ColorOfPlugYVersion=4 + + +[STASH] +ActiveBigStash=1 + +ActiveMultiPageStash=1 +NbPagesPerIndex=10 +NbPagesPerIndex2=100 +MaxPersonnalPages=0 + +ActiveSharedStash=1 +SeparateHardcoreStash=1 +displaySharedSetItemNameInGreen=1 +MaxSharedPages=0 +ActiveSharedGold=1 + + +[STATS POINTS] +ActiveStatsUnassignment=1 +KeyUsed=18 + +ActiveShiftClickLimit=0 +LimitValueToShiftClick=5 + + +[SKILLS POINTS] +ActiveSkillsUnassignment=1 +ActiveSkillsUnassignmentOneForOne=0 + + +[WORLD EVENT] +ActiveWorldEvent=1 +ShowCounterInAllDifficulty=0 +ItemsToSell=The Stone of Jordan +MonsterID=333 +OwnSOJSoldChargeFor=100 +InititalSOJSoldMin=200 +InititalSOJSoldMax=3000 +TriggerAtEachSOJSoldMin=75 +TriggerAtEachSOJSoldMax=125 +ActiveAutoSell=1 +TimeBeforeAutoSellMin=0 +TimeBeforeAutoSellMax=1200 + + +[UBER QUEST] +ActiveUberQuest=1 + + +[INTERFACE] +ActiveNewStatsInterface=1 +SelectMainPageOnOpenning=1 + + +[EXTRA] +ActiveLaunchAnyNumberOfLOD=1 +AlwaysRegenMapInSP=0 +NBPlayersByDefault=0 +ActiveDisplayItemLevel=1 +AlwaysDisplayLifeAndManaValues=0 +EnabledTXTFilesWhenMSExcelOpenIt=0 +ActiveDisplayBaseStatsValue=1 +ActiveLadderRunewords=1 +ActiveCowPortalWhenCowKingWasKilled=1 + + +; More features later... :) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \ No newline at end of file diff --git a/PlugYInstaller/PlugY.nsi b/PlugYInstaller/PlugY.nsi new file mode 100644 index 0000000..d06c30e --- /dev/null +++ b/PlugYInstaller/PlugY.nsi @@ -0,0 +1,256 @@ +; File created by Yohann NICOLAS. +!include "LogicLib.nsh" +!include "MUI2.nsh" + +!define VERSION "10.00" +!define D2FILES "." +!define NAME "PlugY, The Survival Kit" +!define MOD_DIR "Mod PlugY" +!define REGKEY "SOFTWARE\${NAME}" +!define UNINSTALL_FILE "PlugY Uninstaller.exe" + +!define MUI_COMPONENTSPAGE_SMALLDESC +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_BITMAP "PlugYInstallerHeader.bmp" +!define MUI_LANGDLL_REGISTRY_ROOT HKLM +!define MUI_LANGDLL_REGISTRY_KEY "SOFTWARE\${NAME}" +!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language" +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_UNFINISHPAGE_NOAUTOCLOSE +!define MUI_FINISHPAGE_SHOWREADME "$(README_FILENAME)" +!define MUI_FINISHPAGE_RUN "PlugY.exe" +!define MUI_FINISHPAGE_RUN_NOTCHECKED +!define MUI_FINISHPAGE_NOREBOOTSUPPORT +!define MUI_ABORTWARNING +;!define MUI_UNABORTWARNING + +Name "${NAME} v${VERSION}" +OutFile "PlugY_The_Survival_Kit_v${VERSION}.exe" +InstallDirRegKey HKLM "${REGKEY}" "InstallPath" + +;-------------------------------- +; Pages +;!insertmacro MUI_PAGE_LICENSE "${NSISDIR}\Docs\Modern UI\License.txt" +!insertmacro MUI_PAGE_COMPONENTS +;Page Custom OptionsPage +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH + +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES +!insertmacro MUI_UNPAGE_FINISH + + +;-------------------------------- +; Languages +!insertmacro MUI_LANGUAGE "English" +!insertmacro MUI_LANGUAGE "French" + +LangString DESC_CORE ${LANG_ENGLISH} "Core files.$\nPlugY.dll will be installed in Diablo II directory." +LangString DESC_CORE ${LANG_FRENCH} "Fichiers ncessaires.$\nPlugY.dll sera install dans le rpertoire de Diablo II." +LangString DESC_DESKTOP_SHORTCUTS ${LANG_ENGLISH} "Add shortcut on Desktop to launch Diablo II with ${NAME}." +LangString DESC_DESKTOP_SHORTCUTS ${LANG_FRENCH} "Ajoute un raccourci pour dmarrer Diablo II avec ${NAME}." +LangString DESC_MENU_SHORTCUTS ${LANG_ENGLISH} "Add shortcuts in start menu." +LangString DESC_MENU_SHORTCUTS ${LANG_FRENCH} "Ajoute des raccourcis dans le menu dmarrer." +LangString DESC_UNINSTALLER ${LANG_ENGLISH} "Create a Windows uninstall program.$\nAdding registry keys in Windows." +LangString DESC_UNINSTALLER ${LANG_FRENCH} "Cre un programme Windows de dsinstallation.$\nAjoute des cls de registres dans Windows." +LangString DESC_PATCH_D2GFX ${LANG_ENGLISH} "D2gfx.dll patcher to run PlugY without PlugY.exe. Before use it, you MUST read the readme." +LangString DESC_PATCH_D2GFX ${LANG_FRENCH} "D2gfx.dll patcheur pour lancer PlugY sans PlugY.exe. Avant de l'utiliser, vous DEVEZ lire le LISEZ-MOI." +LangString SECTION_NAME_CORE ${LANG_ENGLISH} "${NAME} (required)" +LangString SECTION_NAME_CORE ${LANG_FRENCH} "${NAME} (ncessaire)" +LangString SECTION_NAME_DESKTOP_SHORTCUT ${LANG_ENGLISH} "Desktop Shortcut" +LangString SECTION_NAME_DESKTOP_SHORTCUT ${LANG_FRENCH} "Raccourci sur le bureau" +LangString SECTION_NAME_STARTMENU_SHORTCUTS ${LANG_ENGLISH} "Start menu Shortcuts" +LangString SECTION_NAME_STARTMENU_SHORTCUTS ${LANG_FRENCH} "Raccourcis dans le Menu dmarrer" +LangString SECTION_NAME_UNINSTALLER ${LANG_ENGLISH} "Uninstaller (add keys registers)" +LangString SECTION_NAME_UNINSTALLER ${LANG_FRENCH} "D-installeur (ajoute cls de registre)" +LangString SECTION_PATCH_D2GFX ${LANG_ENGLISH} "D2gfx.dll Patcher (advanced user only)" +LangString SECTION_PATCH_D2GFX ${LANG_FRENCH} "Patcheur de D2gfx.dll (utilisateur avanc uniquement)" + +LangString README_FILENAME ${LANG_ENGLISH} "PlugY_The_Survival_Kit_-_Readme.txt" +LangString README_FILENAME ${LANG_FRENCH} "PlugY_The_Survival_Kit_-_LisezMoi.txt" + +LangString ERROR_NO_D2_DIRECTORY_FOUND ${LANG_ENGLISH} "Error : Diablo II install directory not found.$\nPlease re-install your copy of Diablo II - Lord of Destruction." +LangString ERROR_NO_D2_DIRECTORY_FOUND ${LANG_FRENCH} "Erreur : Le rpertoire d'installation de Diablo II n'a pas t trouv.$\nVeuillez r-installer votre copie de Diablo II - Lord of Destruction." + +Var D2Path +;-------------------------------- +; Initialisation +Function .onInit + !define MUI_LANGDLL_WINDOWTITLE "${NAME} v${VERSION}" + !define MUI_LANGDLL_INFO "Select your language:$\nChoisissez votre langue:" + !insertmacro MUI_LANGDLL_DISPLAY + !undef MUI_LANGDLL_WINDOWTITLE + !undef MUI_LANGDLL_INFO + ReadRegStr $D2Path HKLM "SOFTWARE\Blizzard Entertainment\Diablo II" "InstallPath" + ${If} $D2Path == "" + MessageBox MB_OK $(ERROR_NO_D2_DIRECTORY_FOUND) + Abort + ${EndIf} + + ${If} $INSTDIR == "" + StrLen $0 $D2Path + IntOp $0 $0 - 1 + StrCpy $0 $D2Path 1 $0 + ${if} $0 == "\" + StrCpy $INSTDIR "$D2Path${MOD_DIR}\" + ${else} + StrCpy $INSTDIR "$D2Path\${MOD_DIR}\" + ${endif} + ${EndIf} +FunctionEnd + +Function Un.onInit + !insertmacro MUI_UNGETLANGUAGE + ReadRegStr $D2Path HKLM "${REGKEY}" "PlugYDllPath" +FunctionEnd + +;-------------------------------- +; Custom Page +;Function OptionsPage + ;StrCpy $INSTDIR "C:\temp\${NAME}" +; nsDialogs::Create /NOUNLOAD 1018 + ;Pop $D2Path + + ;GetFunctionAddress $D2Path OnBack + ;nsDialogs::OnBack /NOUNLOAD $D2Path + + ;${NSD_CreateButton} 0 0 100% 12u Test + ;Pop $BUTTON + ;GetFunctionAddress $D2Path OnClick + ;nsDialogs::OnClick /NOUNLOAD $BUTTON $D2Path + + ;${NSD_CreateText} 0 35 100% 12u hello + ;Pop $EDIT + ;GetFunctionAddress $D2Path OnChange + ;nsDialogs::OnChange /NOUNLOAD $EDIT $D2Path + + ;${NSD_CreateCheckbox} 0 -50 100% 8u Test + ;Pop $CHECKBOX + ;GetFunctionAddress $D2Path OnCheckbox + ;nsDialogs::OnClick /NOUNLOAD $CHECKBOX $D2Path + + ;${NSD_CreateLabel} 0 40u 75% 40u "* Type `hello there` above.$\n* Click the button.$\n* Check the checkbox.$\n* Hit the Back button." + ;Pop $D2Path + +; nsDialogs::Show +;FunctionEnd + + +InstType "Standard" +InstType "Minimal" + +Section "!$(SECTION_NAME_CORE)" Core + SectionIn 1 2 RO + SetOutPath $D2Path + File "${D2FILES}\PlugY.dll" + SetOutPath $INSTDIR + File "${D2FILES}\PlugY.exe" + File "${D2FILES}\PlugY.ini" + File "${D2FILES}\PlugY_The_Survival_Kit_-_Readme.txt" + File "${D2FILES}\PlugY_The_Survival_Kit_-_LisezMoi.txt" + File "${D2FILES}\PlugY_The_Survival_Kit_-_Liesmich.txt" + CreateDirectory "$D2Path\PlugY" + setOutPath "$D2Path\PlugY" + File "${D2FILES}\PlugY\EmptyPage.dc6" + File "${D2FILES}\PlugY\PlugYDefault.ini" + File "${D2FILES}\PlugY\PlugYFixed.ini" + File "${D2FILES}\PlugY\SharedGoldBtns.dc6" + File "${D2FILES}\PlugY\StashBtns.dc6" + File "${D2FILES}\PlugY\StatsBackground.dc6" + File "${D2FILES}\PlugY\statsinterface.txt" + File "${D2FILES}\PlugY\TradeStash.dc6" + File "${D2FILES}\PlugY\UnassignSkillsBtns.dc6" + File "${D2FILES}\PlugY\UnassignStatsBtns.dc6" +SectionEnd + +Section "$(SECTION_NAME_DESKTOP_SHORTCUT)" DesktopShortcuts + SectionIn 1 + SetOutPath $INSTDIR + CreateShortCut "$DESKTOP\${NAME}.lnk" "$INSTDIR\PlugY.exe" "" "$INSTDIR\PlugY.exe" 0 +SectionEnd + +Section $(SECTION_NAME_STARTMENU_SHORTCUTS) MenuShortcuts + SectionIn 1 + CreateDirectory "$SMPROGRAMS\${NAME}" + SetOutPath $INSTDIR + CreateShortCut "$SMPROGRAMS\${NAME}\Uninstall.lnk" "$INSTDIR\${UNINSTALL_FILE}" "" "$INSTDIR\${UNINSTALL_FILE}" 0 + CreateShortCut "$SMPROGRAMS\${NAME}\${NAME}.lnk" "$INSTDIR\PlugY.exe" "" "$INSTDIR\PlugY.exe" 0 +SectionEnd + +Section $(SECTION_NAME_UNINSTALLER) Uninstaller + SectionIn 1 + + ; Create uninstaller + setOutPath "$INSTDIR" + WriteUninstaller "${UNINSTALL_FILE}" + + ; Write the installation path into the registry + WriteRegStr HKLM "${REGKEY}" "InstallPath" "$INSTDIR" + WriteRegStr HKLM "${REGKEY}" "PlugYDllPath" "$D2Path" + + ; Write the uninstall keys for Windows + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "InstallLocation" "$$INSTDIR" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "DisplayName" "${NAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "HelpLink" "http://djaftal.chez-alice.fr/" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "DisplayVersion" "${VERSION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "UninstallString" '"$INSTDIR\${UNINSTALL_FILE}"' + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "NoRepair" 1 +SectionEnd + +Section $(SECTION_PATCH_D2GFX) PatchD2gfx + SetOutPath $D2Path + File "${D2FILES}\PatchD2gfxDll.exe" + File "${D2FILES}\RestoreD2gfxDll.exe" +SectionEnd + +;-------------------------------- +; Uninstall +Section "Uninstall" Uninstall + ; Remove registry keys + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" + DeleteRegKey HKLM "${REGKEY}" + + ; Remove shortcuts, if any + Delete "$DESKTOP\${NAME}.lnk" + Delete "$SMPROGRAMS\${NAME}\*.*" + RMDir "$SMPROGRAMS\${NAME}" + + ; Remove files and uninstaller + Delete "$D2Path\PlugY.dll" + Delete "$D2Path\PatchD2gfxDll.exe" + Delete "$D2Path\RestoreD2gfxDll.exe" + Delete "$INSTDIR\PlugY.exe" + Delete "$INSTDIR\PlugY.log" + Delete "$INSTDIR\PlugY.ini" + Delete "$INSTDIR\PlugY_The_Survival_Kit_-_Readme.txt" + Delete "$INSTDIR\PlugY_The_Survival_Kit_-_LisezMoi.txt" + Delete "$INSTDIR\PlugY_The_Survival_Kit_-_Liesmich.txt" + Delete "$INSTDIR\PlugY\EmptyPage.dc6" + Delete "$INSTDIR\PlugY\PlugYDefault.ini" + Delete "$INSTDIR\PlugY\PlugYFixed.ini" + Delete "$INSTDIR\PlugY\SharedGoldBtns.dc6" + Delete "$INSTDIR\PlugY\StashBtns.dc6" + Delete "$INSTDIR\PlugY\StatsBackground.dc6" + Delete "$INSTDIR\PlugY\statsinterface.txt" + Delete "$INSTDIR\PlugY\TradeStash.dc6" + Delete "$INSTDIR\PlugY\UnassignSkillsBtns.dc6" + Delete "$INSTDIR\PlugY\UnassignStatsBtns.dc6" + RMDir "$INSTDIR\PlugY" + Delete "$INSTDIR\${UNINSTALL_FILE}" + RMDir "$INSTDIR" +SectionEnd + + + +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT "${Core}" $(DESC_CORE) + !insertmacro MUI_DESCRIPTION_TEXT "${DesktopShortcuts}" $(DESC_DESKTOP_SHORTCUTS) + !insertmacro MUI_DESCRIPTION_TEXT "${MenuShortcuts}" $(DESC_MENU_SHORTCUTS) + !insertmacro MUI_DESCRIPTION_TEXT "${PatchD2gfx}" $(DESC_PATCH_D2GFX) + !insertmacro MUI_DESCRIPTION_TEXT "${Uninstaller}" $(DESC_UNINSTALLER) +!insertmacro MUI_FUNCTION_DESCRIPTION_END + +########################################################################################################### diff --git a/PlugYInstaller/PlugY/EmptyPage.dc6 b/PlugYInstaller/PlugY/EmptyPage.dc6 new file mode 100644 index 0000000..e0d1079 Binary files /dev/null and b/PlugYInstaller/PlugY/EmptyPage.dc6 differ diff --git a/PlugYInstaller/PlugY/PlugYDefault.ini b/PlugYInstaller/PlugY/PlugYDefault.ini new file mode 100644 index 0000000..c0a7bde --- /dev/null +++ b/PlugYInstaller/PlugY/PlugYDefault.ini @@ -0,0 +1,147 @@ +;--------------------------------------------------------------------------------------; +; ; +; "PlugY, The Survival Kit" ; +; Configuration file ; +; ; +; by Yohann Nicolas ; +; ; +; version 10.00 ; +; ; +;--------------------------------------------------------------------------------------; + +; See PlugY_The_Survival_Kit_-_Readme.txt file for more documentation. +; Voir le fichier PlugY_The_Survival_Kit_-_LisezMoi.txt pour plus d'information. +; Siehe PlugY_The_Survival_Kit_-_Liesmich.txt fr weitere Informationen + + +[GENERAL] +ActivePlugin=1 +DisableBattleNet=1 +ActiveLogFile=0 +DllToLoad= +DllToLoad2= +ActiveCommands=0 +ActiveCheckMemory=1 +ActiveAllOthersFeatures=0 + + +[LANGUAGE] +;ENG|ESP|DEU|FRA|POR|ITA|JPN|KOR|SIN|CHI|POL|RUS +ActiveChangeLanguage=0 +SelectedLanguage=ENG + +ActiveLanguageManagement=0 +DefaultLanguage=ENG +AvailableLanguages=ENG|ESP|DEU|FRA|POR|ITA|JPN|KOR|SIN|CHI|POL|RUS + + +[SAVEPATH] +ActiveSavePathChange=0 +SavePath=Save\ + + +[MAIN SCREEN] +ActiveVersionTextChange=0 +VersionText= +ColorOfVersionText=0 + +ActivePrintPlugYVersion=1 +ColorOfPlugYVersion=4 + + +[STASH] +ActiveBigStash=0 + +ActiveMultiPageStash=0 +NbPagesPerIndex=10 +NbPagesPerIndex2=100 +MaxPersonnalPages=0 + +ActiveSharedStash=0 +SeparateHardcoreStash=1 +displaySharedSetItemNameInGreen=1 +SharedStashFilename=SharedStashSave +MaxSharedPages=0 +ActiveSharedGold=1 + +PosXPreviousBtn=-1 +PosYPreviousBtn=-1 +PosXNextBtn=-1 +PosYNextBtn=-1 +PosXSharedBtn=-1 +PosYSharedBtn=-1 +PosXPreviousIndexBtn=-1 +PosYPreviousIndexBtn=-1 +PosXNextIndexBtn=-1 +PosYNextIndexBtn=-1 +PosXPutGoldBtn=-1 +PosYPutGoldBtn=-1 +PosXTakeGoldBtn=-1 +PosYTakeGoldBtn=-1 + + +[STATS POINTS] +ActiveStatsUnassignment=0 +KeyUsed=18 + +ActiveShiftClickLimit=0 +LimitValueToShiftClick=5 + + +[STAT ON LEVEL UP] +ActiveStatPerLevelUp=0 +StatPerLevelUp=5 + + +[SKILLS POINTS] +ActiveSkillsUnassignment=0 +ActiveSkillsUnassignmentOneForOne=0 +PosXUnassignSkillBtn=-1 +PosYUnassignSkillBtn=-1 + + +[SKILL ON LEVEL UP] +ActiveSkillPerLevelUp=0 +SkillPerLevelUp=1 + + +[WORLD EVENT] +ActiveWorldEvent=0 +ShowCounterInAllDifficulty=0 +ItemsToSell=The Stone of Jordan +MonsterID=333 +OwnSOJSoldChargeFor=100 +InititalSOJSoldMin=200 +InititalSOJSoldMax=3000 +TriggerAtEachSOJSoldMin=75 +TriggerAtEachSOJSoldMax=125 +ActiveAutoSell=1 +TimeBeforeAutoSellMin=0 +TimeBeforeAutoSellMax=1200 + + +[UBER QUEST] +ActiveUberQuest=0 + + +[INTERFACE] +ActiveNewStatsInterface=0 +SelectMainPageOnOpenning=1 +PrintButtonsBackgroundOnMainStatsPage=1 + + +[EXTRA] +ActiveLaunchAnyNumberOfLOD=0 +AlwaysRegenMapInSP=0 +NBPlayersByDefault=0 +ActiveDisplayItemLevel=0 +AlwaysDisplayLifeAndManaValues=0 +EnabledTXTFilesWhenMSExcelOpenIt=0 +ActiveDisplayBaseStatsValue=0 +ActiveLadderRunewords=0 +ActiveCowPortalWhenCowKingWasKilled=0 + + +; More features later... :) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \ No newline at end of file diff --git a/PlugYInstaller/PlugY/PlugYFixed.ini b/PlugYInstaller/PlugY/PlugYFixed.ini new file mode 100644 index 0000000..dcd6fe5 --- /dev/null +++ b/PlugYInstaller/PlugY/PlugYFixed.ini @@ -0,0 +1,44 @@ +;--------------------------------------------------------------------------------------; +; ; +; "PlugY, The Survival Kit" ; +; Configuration file ; +; Fixed ; +; ; +; by Yohann Nicolas ; +; ; +; version 10.00 ; +; ; +;--------------------------------------------------------------------------------------; + +; See PlugY_The_Survival_Kit_-_Readme.txt file for more documentation. +; Voir le fichier PlugY_The_Survival_Kit_-_LisezMoi.txt pour plus d'information. +; Siehe PlugY_The_Survival_Kit_-_Liesmich.txt fr weitere Informationen + +[GENERAL] + +[LANGUAGE] + +[SAVEPATH] + +[MAIN SCREEN] + +[STASH] + +[STATS POINTS] + +[STAT ON LEVEL UP] + +[SKILLS POINTS] + +[SKILL ON LEVEL UP] + +[WORLD EVENT] + +[UBER QUEST] + +[INTERFACE] + +[EXTRA] + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \ No newline at end of file diff --git a/PlugYInstaller/PlugY/SharedGoldBtns.dc6 b/PlugYInstaller/PlugY/SharedGoldBtns.dc6 new file mode 100644 index 0000000..6c200fb Binary files /dev/null and b/PlugYInstaller/PlugY/SharedGoldBtns.dc6 differ diff --git a/PlugYInstaller/PlugY/StashBtns.dc6 b/PlugYInstaller/PlugY/StashBtns.dc6 new file mode 100644 index 0000000..972cce9 Binary files /dev/null and b/PlugYInstaller/PlugY/StashBtns.dc6 differ diff --git a/PlugYInstaller/PlugY/StatsBackground.dc6 b/PlugYInstaller/PlugY/StatsBackground.dc6 new file mode 100644 index 0000000..0a38547 Binary files /dev/null and b/PlugYInstaller/PlugY/StatsBackground.dc6 differ diff --git a/PlugYInstaller/PlugY/TradeStash.dc6 b/PlugYInstaller/PlugY/TradeStash.dc6 new file mode 100644 index 0000000..82ede1b Binary files /dev/null and b/PlugYInstaller/PlugY/TradeStash.dc6 differ diff --git a/PlugYInstaller/PlugY/UnassignSkillsBtns.dc6 b/PlugYInstaller/PlugY/UnassignSkillsBtns.dc6 new file mode 100644 index 0000000..877d7d7 Binary files /dev/null and b/PlugYInstaller/PlugY/UnassignSkillsBtns.dc6 differ diff --git a/PlugYInstaller/PlugY/UnassignStatsBtns.dc6 b/PlugYInstaller/PlugY/UnassignStatsBtns.dc6 new file mode 100644 index 0000000..4c8ed79 Binary files /dev/null and b/PlugYInstaller/PlugY/UnassignStatsBtns.dc6 differ diff --git a/PlugYInstaller/PlugY/statsinterface.txt b/PlugYInstaller/PlugY/statsinterface.txt new file mode 100644 index 0000000..cedaf0b --- /dev/null +++ b/PlugYInstaller/PlugY/statsinterface.txt @@ -0,0 +1,42 @@ +*desc enabled page x y color font statID end +item_magicbonus 1 1 25 445 4 6 80 0 +item_goldbonus 1 1 25 430 4 6 79 0 +item_manaafterkill 1 1 25 415 6 138 0 +item_fastercastrate 1 1 25 400 6 105 0 +item_fasterattackrate 1 1 25 385 6 93 0 +lifedrainmindam 1 1 25 370 6 60 0 +manadrainmindam 1 1 25 355 6 62 0 +item_fastermovevelocity 1 1 25 340 6 96 0 +item_fastergethitrate 1 1 25 325 6 99 0 +item_reducedprices 1 1 25 310 6 87 0 +item_addexperience 1 1 25 295 6 85 0 +item_damagetomana 1 1 25 280 6 114 0 +manarecoverybonus 1 1 25 265 6 27 0 +hpregen 1 1 25 250 6 74 0 +item_freeze 1 1 25 235 6 134 0 +item_howl 1 1 25 220 6 112 0 +item_attackertakesdamage 1 1 25 205 6 78 0 +item_demondamage_percent 1 1 25 190 6 121 0 +item_undeaddamage_percent 1 1 25 175 6 122 0 +item_openwounds 1 1 25 160 6 135 0 +item_crushingblow 1 1 25 145 6 136 0 +item_deadlystrike 1 1 25 130 6 141 0 +item_lightradius 1 2 25 445 6 89 0 +damageresist 1 2 25 430 6 36 0 +normal_damage_reduction 1 2 25 415 6 34 0 +magic_damage_reduction 1 2 25 400 6 35 0 +magicresist 1 2 25 370 6 37 0 +fireresist 1 2 25 355 1 6 39 0 +coldresist 1 2 25 340 3 6 43 0 +lightresist 1 2 25 325 9 6 41 0 +poisonresist 1 2 25 310 2 6 45 0 +maxmagicresist 1 2 25 280 6 38 0 +maxfireresist 1 2 25 265 1 6 40 0 +maxcoldresist 1 2 25 250 3 6 44 0 +maxlightresist 1 2 25 235 9 6 42 0 +maxpoisonresist 1 2 25 220 2 6 46 0 +item_absorbmagic_percent 1 2 25 190 6 146 0 +item_absorbfire_percent 1 2 25 175 1 6 142 0 +item_absorbcold_percent 1 2 25 160 3 6 148 0 +item_absorblight_percent 1 2 25 145 9 6 144 0 +item_poisonlengthresist 1 2 25 130 2 6 110 0 diff --git a/PlugYInstaller/PlugYInstallerHeader.bmp b/PlugYInstaller/PlugYInstallerHeader.bmp new file mode 100644 index 0000000..0080c22 Binary files /dev/null and b/PlugYInstaller/PlugYInstallerHeader.bmp differ diff --git a/PlugYInstaller/PlugY_The_Survival_Kit_-_Liesmich.txt b/PlugYInstaller/PlugY_The_Survival_Kit_-_Liesmich.txt new file mode 100644 index 0000000..19e6f45 --- /dev/null +++ b/PlugYInstaller/PlugY_The_Survival_Kit_-_Liesmich.txt @@ -0,0 +1,756 @@ +;--------------------------------------------------------------------------------------; +; ; +; "PlugY, The Survival Kit" ; +; ; +; von Yohann Nicolas ; +; ; +; version 10.00 ; +; ; +;--------------------------------------------------------------------------------------; + +Official website : http://plugy.free.fr +You can make a donation if you want. + + +WARNUNG: +- Dieses Plug-In ist NUR fr LOD 1.09 zu 1.13c ! +- Dieses Plug-In ist NICHT das closed Battle.net! +- Alle Dateien knnen sich seit der letzten Version verndert haben, benutzt keine alten Dateien! +- Bitte benutzt eine neue D2gfx.dll bevor ihr das PlugY benutzt (Kann man auf http://d2mods.com downloaden) +- PlugY.ini wurde stark verndert, bitte nehmt die Neue! +- Vergesst nicht den Teil: "Kommentare zur Konfigurations-Datei" zu lesen. +- Bitte lest im PlugY-Forum: + http://phrozenkeep.planetdiablo.gamespy.com/forum/viewforum.php?f=133 + + +******** ALLE FUNKTIONEN ******** +- Disable access to Battle.net via main menu button. +- Nahezu unbegrenzter Speicherplatz im Goldschatz (bis zu 4,294,967,296 persnliche Seiten!) +- Gemeinsam genutzter Speicherplatz im Goldschatz (bis zu 4,294,967,296 gemeinsame Seiten!) +- Die Ladder-Only Runenwrter knnen fr den Singleplayer aktivert werden. +- Lokaler World Event ! (nicht 1.09) +- Lokaler Uber Quest! (nicht 1.09 und 1.10) +- Zurcksetzen von Fertigkeitspunkten +- Man kann die Skill- und Statuspunkte zurcksetzen. +- Man kann die gewhlte Sprache verndern +- Man kann einstellen das im Einzelspieler-Modus die Karte mit jedem Spiel erneuert wird +- Man kann /players X automatisch ausfhren lassen +- Es gibt eine weitere Charakter Anzeige Seite mit zustzlichen Informationen +- Anzeige des Itemlevel in der Gegenstandsinfo +- Man kann beliebig oft Diablo II auf dem gleichen Computer starten. +- Der Goldschatz hat 10x10 Felder. +- Man kann das "SAVE" Verzeichnis ndern. +- Man kann die Versionsanzeige im Hauptbildschirm anpassen. +- Diablo kann nun auf Text-Dateien laden die von Microsoft Excel geffnet sind. +- Lokalisiert in Englisch, Franzsisch, Deutsch, Italienisch, Spanisch, Polnisch. + + +v10.00 nderungen : +- Disable access to Battle.net via main menu button. +- PlugY funktioniert nun auch mit LoD 1.13c Versionen. +- Fix shortcut in start menu + + +v9.00 nderungen : +- PlugY funktioniert nun auch mit LoD 1.12 Versionen. +- Ein paar Bugs behoben. +- Eine neue Mglichkeit zum Skills neuverteilen in Mods hinzugefgt. + + +v8.00 nderungen : +- Einfachere Installation : Neuer Installer. +- Das Portal zum Cow-Level kann nun geffnet werden auch wenn der Spieler den Cow-King in der aktuellen Schwierigkeit bereits gettet hat. +- Die wirkliche Versionsnummer wird angezeigt (v 1.09d oder v 1.11b statt v 1.09 oder v 1.11) +- Die Mglichkeit hinzugefgt den Skill-Neuverteilungs-Button zu verschieben (fr Modder). +- Behoben : Absturz wenn man einem Superunique Monster in Lod v1.11 begegnet ist. +- Behoben : Verlorene Skillpunkte beim neu verteilen in Mods mit speziellen Skills. +- Multiplayer : Die Truhendaten werden jetzt korrekt gespeichert wenn es einen Disconnect oder einen Fehler whrend des Speicherns gibt. +- Die "check load memory failed" Meldung, wenn die D2gfx.dll gepachtt war, wurde entfernt. + + +v7.01b nderungen : +- Behoben : Die Ladder-only Runenwortfeatures in den LoD-Versionen 1.11 und 1.10. +- Behoben : Seltsame Zeichen in manchen Texten. + + +v7.01 nderungen : +- Die Ladder-Only Runenwrter knnen fr den Singleplayer aktivert werden. +- Fehler bei der AI des berbaals behoben +- Die Parameter in der PlugY.ini standaratmig entfernt (wie -w um im Fenster zu starten) +- Die Basiswerte der Statuspunkte werden angezeigt (ohne magische Boni) auch wenn die Statneuverteilung deaktiviert ist +- Eine eigene EXE wurde hinzugefgt um PlugY zu starten (es werden keine LoD-Dateien mehr verndert) +- Spanische und Polnische bersetzung hinzugefgt. + + +V7.00 nderungen : +- PlugY funktioniert nun auch mit LoD 1.11b Versionen. +- Den Basiswert fr jeden Stat im Mausbertext hinzugefgt. +- Behoben: Unendliche Statuspunkte bei der Neuverteilung +- Behoben: Einige Features blieben auch im Battle.net aktiviert +- Italienische bersetzung hinzugefgt. + + +v6.01b nderungen : +- Fehler mit dem Popups der Statuspunktvergabe-Buttons behoben. + + +v6.01 nderungen : +- Behoben : unique carry1 items verschwinden nicht wenn sie in LoD 1.10 gecubt werden +- Schlssel und Uber-Organe werden nicht mehr entfernt wenn man das rote Portal ausserhalb von Harrogath ffnen wollte. +- Fehler in der Versionsanzeige wegen einem Konflikt mit D2Mod behoben. + + +V6.00 nderungen : +- PlugY funktioniert nun auch mit LoD 1.11 Versionen +- Freischaltung des ber-Quests ausserhalb von der Realm (LoD 1.11 only). +- PlugY Start-Absturz behoben, wenn die LoD Installation unsauber war +- Kleine Fehler behoben, und kleine Verbesserungen eingebaut +- "/save"-Befehl hinzugefgt um das Spiel zu speichern ohne es zu verlassen (nur LoD 1.11). + + +v5.06 nderungen : +- Knpf for gemeinsamen Goldvorrat hinzugefgt. +- Gemeinsamer Goldvorrat in Multiplayer hinzugefgt. +- Befehl "/DisplayLifeMana" ersetzt durch "/dlm". +- Diverse Fehler behoben. + + +v5.05 nderungen : +- Standard Hintergrundfarbe im Status Interface gendert +- Gemeinsames Gold per Kommando hinzugefgt. +- Kommando "/DisplayLifeAndMana" ist nun "/DisplayLifeMana". +- Mglichkeit die Namen von Setgegenstnd in Grn bei Mouseover in der gemeinsamen Kiste anzuzeigen +- Multiplayer Fehler behoben, indem der gesamte Prozess neu programmiert wurde + + +v5.04 nderungen : +- Behoben : Status/Skill Punkte per Levelup bug. +- Behoben : Multiplayer bugs. +- PlugY/PlugYDefault.ini sind jetzt vollstndig. + + +v5.03 nderungen : +- Behoben : Bug der manchmal zwischen den Hardcore und Softcore gemeinsamen Truhen gewechselt hat. +- Farbnderung der Schrift in den Extra-Seiten mglich. +- Standartwerte in den Extra-Seiten gendert. +- EnabledTXTFilesWhenMSExcelOpenIt in der PlugY.ini ist nun standartmig aktiviert. + + +v5.02 nderungen : +- Behoben : Bug der das Verschwinden von Gegenstnden hervorgerufen hat. + + +v5.01 nderungen : +- Behoben : Grere bugs bei der gemeinsamen Truhe. +- Behoben : ActiveLogFile ist jetzt in der PlugY.ini standartmig deaktiviert. +- Behoben : Bug der auftrat wenn die gemeinsame Truhe deaktiviert war. + + +v5.00 nderungen : +- PlugY funktioniert jetzt mit den LoD Versionen 1.09, 1.09b, 1.09d, inklusive zustzlicher Mods ! +- PlugY kann jetzt das D2ModSystem (D2Mod.dll) laden. +- Diablo kann nun auf Text-Dateien laden die von Microsoft Excel geffnet sind. +- Das World Event Monster kann jetzt verndert werden. +- Neue Einstellungsmglichkeiten fr Modder. +- Behebt grere Bugs im Multiplayer : Fingerprints zurckgesetzt, unidentifizierte Items Bug, etc. +- Behoben : Schreibfehler in der PlugY.ini (Commands). +- Behoben : Keine weiteren Gro- und Kleinschreibungs Beschrnkung fr die Commands im Spiel. +- Behoben : Character Seiten Auswahl beim ffnen. +- Behoben : Ersetzt die Anzeige von "Kritischer Schlag"/"Ttlicher Schlag" nur mit "Ttlicher Schlag". +- Behoben : Das Erscheinen des Diablo Klones am Spielstart. +- Behoben : Andere kleine Bugs. + + +v4.04 nderungen : +- Behoben : Anzeige-bug wenn StatPerLevelUp aktiviert war. +- Behoben : Fehler bei der Speicherprozedur wenn die Festplatte voll war. +- Neues Konfigurations-System fr Modder. +- Man kann auswhlen, ob die Mana und Lebens Anzeige immer ber den Kugeln erscheint. + + +v4.03 nderungen +- Behoben: Wenn man einen "carry1" - einzigartigen Gegenstand (einzigartiger Zauber) in den Wrfel steckt +- Man kann direkt zur ersten und letzten Seite der Kiste gehen (shift + klick auf Nchste/Vorherige Seite) +- Zweiten Index hinzugefgt (shift + klick auf den Index Knopf) +- Weitere Status Informationen hinzugefgt (Jetzt 2 Seiten) +- Vorherige Seite - Button hinzugefgt auf der Hauptstatusseite (nur in 800x600) +- Button fr die zustzlichen Status Seiten an die gleiche Stelle verschoben, wie die original Buttons (nur in 800x600) +- Man kann auswhlen, ob die zuletzt angezeigte Seite erscheint, oder die Hauptseite + + +v4.02b nderungen : +- Behoben : Alle Funktionen bleiben im offenen Battle.net eingeschaltet. + + +v4.02 nderungen : +- Behoben : Das vergessene "d" in "SeparateHardcoreStash=1" in der PlugY.ini ergnzt +- Behoben : Standardmssig wird dei Sprache in der PlugY.ini nicht gendert. +- Behoben : Item Level sollte nun in allen Konfigurationen von PlugY korrekt angezeigt werden. +- Behoben : No more conflict with Battle.net (BigStash disabled on realms) +- Weitere Daten auf der zustzlichen Statusseite eingefgt. + +v4.01 nderungen : +- Behoben: NbPlayers Schalter stellte immer 8 Spieler ein. +- Zustzliche Daten auf der neuen Status Seite hinzugefgt. + +v4.00b nderungen : +- Behoben : Problem wenn MSVCR70.dll nicht gefunden wurde. + +v4.00 nderungen : +- Wechsel der ausgewhlten Sprache (in MODs, default und verfgbare Sprachen). +- - Generiere die Karte im Einzelspieler immer neu, wie im MultiSpieler. +- Man kann einstellen das im Einzelspieler-Modus die Karte mit jedem Spiel erneuert wird +- Man kann /players X automatisch ausfhren lassen +- Gemeinsame Kiste fr Softcore und Hardcore getrennt +- Installation gendert (kann nun direkt unter Linux installiert werden) +- Der World Event Gegenstand kann ausgewhlt werden +- Beliebig viele carry1 Gegenstnde (wie Annihilus) knnen in die Kiste getan werden +- Behoben : Man kann icht mehr als einen carry1 Gegenstand in andere Seiten legen ausser in die Kistenhauptseite +- Behoben : Anzeigefehler von gesockelten Gegenstnden in der Kiste +- Behoben : Leerzeichenfehler in PlugY.ini behoben +- Behoben : Diablo Clone kann nicht mehr in Normal und Albtraum erscheinen +- Behoben : Zerstrung von zustzlichen Minions wenn man Fertigkeitspukte zurcksetzt + + +v3.02 nderungen : +- Fehler im Bereich Statuspunkte pro LevelUp behoben +- Fehler behoben der verhinderte das bei abgeschalteter gemeinsamer Kiste ein Charkter nicht geladen werden konnte. +- Fehler behoben der es erlaubte Werte zu setzen, ohne das Fertigkeiten pro LevelUp aktiviert waren. + + +v3.01 nderungen : +- Man kann die Statuspunkte ndern, die man beim LevelUp bekommt. +- Problem mit fehlerhafter Menge der Fertigkeitspunkte beim zurcksetzen behoben. +- Konfigurationsparameter fr den World Event hinzugefgt +- Standardmssig wird nur inHlle der World Event Zhler gezeigt "X SOJ verkauft". + + +v3.00 nderungen : +- Lokaler World Event ! +- Zurcksetzen von Fertigkeitspunkten + + +v2.05 nderungen : +- Wichtiger Ffix : Alle Fehler die einen Start von Diablo2 verhinderten sind entfernt + + +v2.04 nderungen : +- Das zurcksetzen der Statuspunkte, sowie die Fertigkeiten pro LevelUp werden abgeschaltet, wenn man sich in ein Realm-Spiel einklinkt (wie bei der Goldkiste die Knpfe) +- Es wird eine Fehlermeldung angezeigt, anstelle eines Absturzes, wenn PlugY.dll nicht gefunden werden kann +- Einige Fehler in der Installationsroutine behoben +- Einen Fehler bezglich der verschwindenden Knpfe behoben +- Abspeicher-Problem unter Win95/98/Me behoben + + +v2.03b nderungen : +- Anzeige der PlugY Version nur im Hauptbild + + +v2.03 nderungen : +- Wichtigster Fix : Die Abspeicher-Routine gendert, damit bei einem Spiel-Absturz keine Items in der Kiste verloren gehen, und der Charakter korrupt wird. +- Kein Absturz des Host Spiels, wenn ein Charakter nicht ins Spiel kann. +- Ausgegrauter Status-Knopf bei mehr als 255 Status-Punkten gefixed. +- Die Versionsanzeige auf der Hauptseite gendert (PlugY Version jetzt rechts, und Farben sind nun mglich) +- Charaktere ohne PlugY knnen nun an Spielen teilnehmen die gehosted werden von PlugY-Spilern. + + +v2.02 nderungen : +- PlugY nutzt die D2win.dll nicht mehr zum laden. +- PlugY enthlt einen Patcher/Ent-Patcher um die D2gfx.dll so zu verndern, das PlugY gestartet wird. +- PlugY kann von SVRs D2Mod System gestartet werden. +- Die Goldkistenerweiterung wird bei Realm Spielen automatisch abgeschaltet. +- Index Button Fehler behoben. + + +v.2.01 nderungen +- Fertigkeitsfehler beim LevelUp behoben. +- Anzeigefehler im Hauptbildschirm behoben. + + +v2.00 nderungen : +- Deutsche Lokalisierung hinzugefgt. +- Die Anzahl der Fertigkeitspunkte beim erreichen des nchsten Levels ist einstellbar. +- Man kann beliebig oft das Spiel Diablo II auf einem Computer starten. +- Man kann die Statuspunkte zurcksetzen. +- Es gibt 2 Knpfe um jeweils zur vorherigen/nchsten Index-Seite zu springen. +- Es wird nur noch der aktuelle Gold-Inhalt der Kiste angezeigt, der Maximal Wert wird als Pop-Up angezeigt. +- Komplett berarbeitete Konfigurationsdatei. +- Die Ini-Datei kann in das MPQ gepackt werden (wie bereits die PlugY Grafik-Dateien) +- Die Kompatibilitt mit MODs wurde verbessert. +- Den TCP/IP Absturz korrigiert. +- Den Fehler mit Seitennummern bei Charakterwechsel behoben. +- Der Anzeige-Fehler von Set-Gegenstnden wurde behoben +- Der Fehler mir carry1 Gegenstnden wurde behoben (Uniques die nur einaml getragen werden drfen) +- Weitere kleine Verbesserungen eingebaut. + + +v1.03 nderungen : +- Franzsische Liesmich- und Ini-Datei hinzugefgt. +- Fehler in D2Classic-Spielen entfernt (es gibt dort keine Seiten-Erweiterungen, dies ist kein Fehler) +- Fehler behoben, der beim laden mit vor LOD 1.10 generierten Charakteren auftrat. + (zB: ShadowMaster Charakter oder 1.09 oder D2Classic Charakter) + + +v1.02 nderungen : +- Dateinamen gendert wegen eines Fehlers mit dem IE und ZIP-Files +- Man kann die Versions-Information im Hauptbildschirm ndern (siehe Ini-Datei). + + +v1.01 nderungen : +- Franzsische Lokalisierung hinzugefgt (Franzsisches Liesmich.txt folgt) +- Dateinamen von "PlugY, The Survival Kit.ini" in "PlugY,The_Survival_Kit" gendert. +- Installationsbeispiele im Liesmich hinzugefgt. +- Fehlerhafte Installation beim PlugY-Aufruf eingebaut. +- Den Eintrag "[GENERAL]PlugYDirectory=PlugY\" aus der Ini-Datei entfernt + (Man kann ihn weiterhin hinzufgen, sollte aber wissen, was man tut...) +- Paket von .rar auf .zip umgestellt + + +v1.00 Funktionen (es knnen alle einfach ein- und ausgeschaltet werden) : +- Man kann den "Save"-Pfad anpassen. +- Man kann jeden MOD starten, ohne die gesicherten Spielstnde verschieben zu mssen. +- Der Goldschatz kann auf 10x10 Felder erweitert werden. +- Bis zu 4,294,967,296 Seiten im Goldschatz mglich (nahezu unbegrenzter Speicherplatz) ! + Achtung : Dies ist nur fr LOD1.10 charaktere. +- Mit dem gemeinsamen Goldschatz kann man Gegenstnde an andere Charaktere bergeben + + +******** INHALT ******** +19 Dateien, 1 Ordner : +- PlugY_The_Survival_Kit_-_Readme.txt +- PlugY_The_Survival_Kit_-_LisezMoi.txt +- PlugY_The_Survival_Kit_-_Liesmich.txt +- PlugY.exe +- PlugY.dll (in Diablo II directory) +- PlugY.ini +- PlugY\PlugYFixed.ini +- PlugY\PlugYDefault.ini +- PlugY\EmptyPage.dc6 +- PlugY\SharedGoldBtns.dc6 +- PlugY\StashBtns.dc6 +- PlugY\TradeStash.dc6 +- PlugY\StatsBackground.dc6 +- PlugY\UnassignSkillsBtns.dc6 +- PlugY\UnassignStatsBtns.dc6 +- PlugY\statsinterface.txt +- PlugY Uninstaller.exe (with uninstaller option) +- PatchD2gfxDll.exe (in Diablo II directory with Patcher D2gfxDll option) +- RestoreD2gfxDll.exe (in Diablo II directory with Patcher D2gfxDll option) + + + +******** INSTALLATION ******** +- The officials sites are : +http://djaftal.chez-alice.fr/ +http://phrozenkeep.18v.biz/dload.php?action=category&cat_id=128 +http://diablo2.judgehype.com/index.php?page=telechargements + +Installation : +- Entpacke alle Dateien in dein Diablo Verzeichnis. +- Kopiere die PlugY.ini und die PlugY.exe in das Verzeichnis in dem dein Mod ist. +- Bearbeite die PlugY.ini um die gewnschten Features zu de/aktivieren (dazu weiter unten). +- Run PlugY.exe and enjoy :-) + +Beispiel : +Du hast LoD in folgendem Verzeichnis installiert : C:\Games\Diablo II\ +Der Mod und PlugY befindet sich hier : D:\D2Mod\MyMod\ +Dann mssen die Einstellungen wie folgt lauten : + C:\Games\Diablo II\PlugY.dll + C:\Games\Diablo II\PlugY\EmptyPage.dc6 + C:\Games\Diablo II\PlugY\SharedGoldBtns.dc6 + C:\Games\Diablo II\PlugY\StashBtns.dc6 + C:\Games\Diablo II\PlugY\TradeStash.dc6 + C:\Games\Diablo II\PlugY\StatsBackground.dc6 + C:\Games\Diablo II\PlugY\UnassignSkillsBtns.dc6 + C:\Games\Diablo II\PlugY\UnassignStatsBtns.dc6 + C:\Games\Diablo II\PlugY\statsinterface.txt + D:\D2Mod\MyMod\PlugY.ini + D:\D2Mod\MyMod\PlugY.exe + +Deinstallation : Einfach alle PlugY-Dateien lschen + + +Wenn Probleme auftreten beim Ausfhren der PlugY.exe benutze einfach die alte Installation (PlugY_Installer.exe). +Wenn das Spiel unter Windows 2000 nicht startet nimm auch die alte Installation. +1. Entzippe das Paket in einen temporren Ordner +2. Entzippe das Manual_Installer.zip in das selbe Verzeichnis +3. Kopiere die PlugY.dll und PlugY_Install.exe in Dein D2 Installations-Verzeichnis. +4. Kopiere das "PlugY\" Verzeichnis in Dein D2 Installations-Verzeichnis oder fge es Deiner MPQ-Datei direkt als PlugY\ hinzu (nicht unter "data\...") +5. Kopiere die PlugY.ini in das MOD-Zielverzeichnis und konfiguriere sie nach Deinen Wnschen. +6. Erzeuge eine Verknpfung : Gebe das MOD Ziel-Verzeichniss im "Ausfhren in" Feld der Eigenschaften von ->xxx Verknpfung an + + +Hinweis : Man kann ebenfalls die PlugY.dll in das Mod Verzeichnis installierne und die dc6 Dateien in das mpq. + + +******** KONFIGURATION ******** + +Wie konfiguriert man dieses Plug-In fr einen MOD: +- Kopiere die PlugY-Ini-Datei in das MOD-Zielverzeichnis. (Das Verzeichnis aus dem der MOD gestartet wird, beachte die Eigenschaften der Diablo Verknpfung). +- In den meisten Fllen passt man das "SAVE"-Verzeichnis in der Ini-Datei an. +- Fge alle zustzlichen DLLs des MODs in der Ini-Datei hinzu (siehe .ini Datei) falls vorhanden. +- Als letztes aktiviert man noch die gewnschten Funktionen, wie zB: Gemeinesamer Goldschatz, Goldschatz-Zusatzseiten, usw. +- Nun kann man den MOD auf klassische Art starten (mit oder ohne "-direct -txt", je nach MOD). + +D2Mod Konfiguration : +Ihr knnt die Version des D2Mod-System (v1.02 und Folgende) nutzen um PlugY zu starten. +- Startet PlugY_Uninstall.bat um alles zu deinstallieren +- Fgt die Zeile "PlugY=PlugY.dll" in den [D2MOD] Abschnitt der D2Mod.ini ein. + +Achtung, +- Gegenstnde im Horadrim-Wrfel werden immer im Spieler-Profil gespeichert. Wenn Ihr diese Gegenstnde weitergeben wollt, msst Ihr sie in den Goldschatz umpacken. + +Warnung : +- Editiere die Konfigurations-Datei nicht nachdem der MOD gestartet wurde. +- Prfe bei Multiplayer-Spielen, dass alle die gleiche Konfiguration haben.than Clients. +- Erinnerung : PlugY funktioniert nicht auf REALM-Servern, es kann dort zum Crash kommen + + +*** Konfiguration fr Modder *** +Es gibt 3 Dateien mit dem selben Aufbau um PlugY zu konfigurieren: +- "PlugY/PlugYFixed.ini" in einer Mpq oder im -direct Modus +Alle Einstellungen in der PlugYFixed.ini knnen nicht von Benutzern in der PlugY.ini verndert werden. +Zum An und Ausschalten (un)gewnschter Features. +Achtung: +1. ActivePlugin=0 funktioniert hier nicht (nur ActivePlugin=1) +2. Speicherpfadnderungen funktioniern hier nicht. +3. bertreibt es nicht, die meisten Einstllungen sollten vom Benutzer eingestellt werden drfen. (Anmerkung weiter unten) + +- "PlugY/PlugYDefault.ini" in einer Mpq oder im -direct Modus +Alle Einstllellungen in der PlugYDefault.ini werden als Standart benutzt. +Funktioniert wie die PlugY.ini in einer Mpq in der Version 4.03 und davor. +Alle Einstellungen die nicht in der PlugYFixed.ini stehen (und schon geladen sind) sollten hier sein. +Die meisten Einstellungen sollten hier sein. + +- "PlugY.ini" nur im Standartverzeichnis. +Fr Benutzerkonfigurationen (wie in den voherigen Versionen). +Einstellungen die nicht in der PlugYFixed.ini stehen mssen hier sein. +In den meisten Fllen ist die "PlugY.ini" die selbe wie die PlugYDefault.ini nur das der Benutzer Einstellungen vornehmen kann. + +Anmerkung: +berlege bei jeder Einstlellung ob sie wirklich ausgeschaltet sein muss. +- Die Speicherpfadeinstellungen funktionieren nicht in der Fixed.ini (Es sollte dem Benutzer berlassen sein wo er seine Speicherstnde ablegt) +- Die Skill-Neuverteilung kann sehr ntzlich sein umd neue Skills kennenzulernens. Ich habe aufgehrt manche Mods zu spielen weil ich nicht wusste welche Skills im High-Level Bereich ntzlich sein wrden und welche nicht. Es macht mehr Spass wenn man alle Skills ausprobieren kann und sich dann aussucht welche man benutzt. Also stellt es nicht in der PlugYFixed.ini ein. +- Das World Event sollte in jedem Mod in der Fixed.ini konfiguriert oder ausgeschaltet sein. +- Die Extra Character Seiten sollten auch nicht in der Fixed.ini sein + +Modder knnen mich erreichen, wenn sie Hilfe brauchen oder mehr Details ber das Konfigurations-System haben mchten. + +WARNUNG : Vergesst nicht, dass wenn Konfigurations-System missbraucht wird werden die Benutzer auf alte PlugY Versionen zurckgreifen und ich werde kein andere Mglichkeit haben als es zu deaktivieren. + + +******************** FAQ ****************** +Ich kann die PlugY.ini nicht finden ? +ffne im Explorer Extras/Ordneroptionen/Anzeige und nimm den Haken raus bei Erweiterung bekannter Dateien ausblenden +Generell sehr sinnvoll, da man so leichter Viren identifiziert (zB virus.txt.exe da wrde man sonst nur txt statt auch das exe sehen..) ! + +Wie kann ich gelegentlich im Battle.net spielen, wenn PlugY aktiviert ist ? +2 Mglichkeiten: +1) Starte PlugY_Uninstall.bat bevor Du Diablo2 startest und starte PlugY_Install.exe danach wenn Du wieder Einzelspieler spielen willst +2) Nutze die klassische Installation. (Vergiss icht die PlugY.ini im Diablo2 Verziechniss zu entfernen) + +Tips : Erzeuge eien Verknpfung und fge -skiptobnet im "Ziel" Feld mit einem Leerzeichen hinter dem Anfhnrungszeichen hinzu, um direkt ins Battle.Net zu gelangen ohne die Videos. + +Was tun wenn man "Bad Generic File" mit einem neuen Charakter bekommt ? +Dies passiert wenn man einen "schlechten" Gegenstand in der gemeinsamen Kiste hat +Eine mgliche Ursache ist das Du das SAVE Verzeichnis fr mehrere MODs benutzt, in diesem Fall musst Du das SAVE Verzeichnis in der PlugY.ini ndern. + +I sehe "sUnitItemInsertItemInvGridBase failed at 1046 in C:\projects\D2\head\Diablo2\Source\D2Client\UNIT\Item.cpp" in der D2YYMMDD.txt ? +Das sind nur Warnungen, die Ihr einfach ignorieren knnt + +Ich habe einen anderen Fehler, was kann ich tun ? +1) Lies meinen Thread und poste eine Frage im PhrozenKeep member annoucement forum. +2) Wenn dies Dir nicht weitergeholfen hat, sende mir eine email (at ynicolas@worldonline.fr) mit "PlugY bug" im Betreff und schreib auf Englisch oder Franzsisch, da ich kein Deutsch spreche +Hnge bitte folgende Dateien an: +- PlugY.ini +- PlugY.log (dazu muss active_logfile=1 in der plugY.ini aktiviert sein) +- D2XXYYZZ.txt log Log Datei von Diablo +- Beantworte die Fragen : wann,wo,wie,warum,... passiert das, und evtl mit welchem MOD ? +Danke + +Warum sind die fingerprint auf meinen Gegenstnden auf 0 zurckgesetzt? +- Anscheinend ein Bug, warnt mich bitte, falls ihr ihn habt. + + +******** Kommentare aus der Konfigurations-Datei ******** +Standardwerte bedeuten, das sie auch benutzt werden, wenn Ihr die Zeilen in der PlugY.ini lscht. +Die Werte in der PlugY.ini (die dem ZIP beiliegt) sind ein Beispiel einer Konfiguration, nicht die Standardwerte.value. + +[LAUNCHING] +Dieser Abschnitt beinhaltet Informationen fr die PlugY.exe und funktioniert nicht in der PlugYDefault.ini und PlugYFixed.ini + +Fge Parameter hinzu um LoD mit der gewnschten Einstellung zu starten +Parameter die der PlugY.exe hinzugefgt wurden werden auch an LoD weitergeleitet +Standartmig werden keine Parameter ausgefhrt +Die hufigsten Parameter sind (ohne Anfhrungszeichen) : +"-w" Starte LoD im Fenstermodus +"-direct" Die Dateien im data-Ordner werden anstatt der in den MPQ's enthaltenen verwendet +"-txt" Wandelt beim Spielstart die txt-dateien im data-Ordner in bin-dateien um +Zwischen den folgenden {} sind Beispielparameter mit Erklrung : +Param= {-direct -txt -w: these 3 commands are passed on the command line} + +Whle die Dll aus die geladen werden soll. +Das gewhlte Verzeichnis wird von LoD benutzt (wie die "Ausfhren in"-Zeile in einer Verknpfung). +Wenn keine Dll angegeben ist startet LoD ohne PlugY +Library=PlugY.dll + + +[GENERAL] +Ein- oder Ausschalten aller Funktionen. +Beispiel: +- ActivePlugin=0 (Deaktiviert, alle DLLs werden geladen ausser PlugY.dll) +- ActivePlugin=1 (Aktiviert, Standard) + +Erzeugen der Log-Datei "PlugY.log" im aktuellen Verzeichnis. +Beispiel: +- ActiveLogFile=0 (Deaktiviert, Standard, keine Informationen werden whrend des Spiels geschrieben) +- ActiveLogFile=1 (Aktiviert) + +Enable or disable BattleNet Access. +Beispiel: +- DisableBattleNet=1 (Deaktiviert Battle.net access, Standard) +- DisableBattleNet=0 (Aktiviert Battle.net access) + +Laden von weiteren DLLs, wenn PlugY genutzt wird. +Trenne jeden DLL-Namen durch das Zeichen Pipe (|) +Alle Dateien im "DllToLoad"-Feld werden immer geladen. +Beispiele um zwei DLLs fr einen MOD zu laden, und der Standard: +- DllToLoad=D2extra.dll|myDll.dll +- DllToLoad= (Keine DLL zu laden, Standard) +- DllToLoad2=D2OtherExtra.dll|myDll2.dll +- DllToLoad2= (Keine DLL zu laden, Standard) + + +Neue Kommandos in PlugY hinzugefgt, diese knnen whrend des Spiels genutzt werden +"/dlm" schaltet den Wert von AlwaysDisplayLifeandManaValues=1 auf 0 +"/page x" Gehe zu Seite X in den Extra Status Seiten. +"/save" Save the game without exit (LoD 1.11 und 1.11b einzig). +- ActiveCommands=0 (0=Aus; 1=Ein) + +Beendet D2, wenn PlugY nicht alle Features installieren konnte. +Nur Ausschalten wenn du weist was du machst. +- ActiveCheckMemory=1 + + +[LANGUAGE] +Wechselt die ausgewhlte Sprache +Ihr msst die Dateien der Sprache besitzen!!! +Alle D2/LoD Versionen beinhalten Englisch (nur Text, kein TON). +Alle mglcihen Sprachen: ENG|ESP|DEU|FRA|POR|ITA|JPN|KOR|SIN|CHI|POL|RUS +- ActiveChangeLanguage=1 {0:Ausgeschaltet; 1:Eingeschaltet} +- SelectedLanguage=ENG {FRA: Whle Franzsisch als SPrache} + +Fr Modder die die mglichen Sprachen einschrnken wollen: +- ActiveLanguageManagement=1 {0:Ausgeschaltet; 1:Eingeschaltet} +- DefaultLanguage=ENG {leer:D2 default Sprache; FRA:Franzsisch ist default Sprache} +- AvailableLanguages=ENG|FRA {ENG|ESP|DEU|FRA|POR|ITA|JPN|KOR|SIN|CHI|POL|RUS} + + +[SAVEPATH] +Hier werden alle Charaktere und der gemeinsame Goldschatz gespeichert. +Man kann feste Pfade benutzen +Beispiele: +- ActiveSavePathChange=0 (Deaktiviert, Standard, der Speicherort ist der Original-D2 Save-Ordner) +- ActiveSavePathChange=1 (Aktiviert, man muss "SavePath" ausfllen) +- SavePath=D:\Save Games\diablo II\Current Mod\ +- SavePath=Save\ (Standard) + + +[MAIN SCREEN] +Hier kann man die Versionsinfo des Hauptbildschirms ndern (Original ist : v 1.10) +Die Farbcodes sind Integer,identisch zu den D2 Farben. +Beispiele : +- ActiveVersionTextChange=0 {0:Deaktiviert; 1=Aktiviert} +- VersionText=v 1.10 {Aktuelle Mod Version (Text links unten) :Textlnge maximal 23 Zeichen} +- ColorOfVersionText=0 {0:Weiss; 1:Rot; 4:Gold; usw.} +- ActivePrintPlugYVersion=1 {0:Deaktiviert; 1=Aktiviert (Text rechts unten) ) +- ColorOfPlugYVersion=4 {0:Weiss; 1:Rot; 4:Gold; usw.} + + +[STASH] +Es gibt zwei Goldschatzkisten mit Mehrfach-Seiten : +- eine persnliche die nur der Spieler sieht ; +- eine gemeinsame die jeder Spieler sieht. +Benutzt den "Goldschatz"-Knopf um zwischen den beiden Kisten zu wechseln (unten links). +Benutze die Pfeiltasten am unteren Rand der Kiste (und die Shift Taste) um zwischen den Seiten umzuschalten +Definition: Die letzte Seite, ist die letzte Seite die einen Gegenstand enthlt +Die Mehrfach-Seiten sind deaktiviert fr Diablo2 Classic Charaktere. +Startet NIEMALS mehrere Spiele auf einem PC die den gleichen Speicherort fr den gemeinsamen Goldschatz benutzen und in Realm Spielen. + +Beispiele fr den Mehrfachseiten-Goldschatz: +- ActiveMultiPageStash=0 (Deaktiviert, Standard) +- ActiveMultiPageStash=1 (Aktiviert) +- NbPagesPerIndex=10 (Standard, Index Seiten sind :1,10,20,30,...,max) +- NbPagesPerIndex=5 (Index Seiten sind :1,5,10,15,...,max) +- NbPagesPerIndex2=100 {50: Index Seite (+shift) ist 1, 50, 100, 150,...max) + +Beispiel Konfiguration des persnlichen Goldschatz : +- MaxPersonnalPages=0 (Standard, nahezu unbegrenzte Speicherseiten in dem persnlichen Goldschatz) +- MaxPersonnalPages=1000 (Maximum von 1000 persnlichen Speicherseiten) + +Beispiel Konfiguration des gemeinsamen Goldschatz : +- ActiveSharedStash=0 (Deaktiviert, Standard) +- ActiveSharedStash=1 (Aktiviert, nur wenn auch ActiveMultiPageStash=1 ist, sonst deaktiviert) +- MaxSharedPages=0 (Standard, nahezu unbegrenzte Speicherseiten in dem gemeinsamen Goldschatz) +- MaxSharedPages=50000 (Maximum von 50000 gemeinsamen Seicherseiten) +- SeparateHardcoreStash=1 {0:Same shared stash for HC and SC; 1:Use 2 differents stashes} +- SharedStashFilename=SharedStashSave {Die Datei heisst dann: _LOD_MeinGemeinsamerGoldSchatz.sss} +- ActiveSharedGold=1 {0:Abschalten; 1:Schaltet die Kommandos frei, um Gold in der gemeinsame Kiste nutzen zu knnen (siehe Kommando-Abschnitt)} + +Grssennderung des Goldschatz auf 10x10 Felder. +Benutze PlugY\TradeStash.dc6 um das Hintergrundbild zu ndern. +Beispiel: +- ActiveBigStash=0 (Deaktiviert, Standard, original GOldkistengrsse aus der MPQ wird benutzt) +- ActiveBigStash=1 (Aktiviert) + + +[STATS POINTS] +Dies kann man nutzen, um versehentlich vergebene Status-Punkte neu zu verteilen. +Zum Beispiel wenn man 30 Punkte in Energie fr Barbaren vergeben hat!) +Auf der Charakter Status Seite, drckt die ausgewhlte Taste und klickt mit der Maus auf den "Minus"-Knopf. +Festlegen der Taste mit KeyUsed (entweder 17 oder 18). +Settings example to unassign stats points : +- ActiveStatsUnassignment=0 (Deaktiviert, Standard) +- ActiveStatsUnassignment=1 (Aktiviert, drcke die Taste beim klicken) +- KeyUsed=17 (Steuerungs-Taste (Strg oder Ctrl), Standard) +- KeyUsed=18 (Alt Taste) + + +Mit der "Shift"-Taste knnt Ihr die Status-Punkte in grsseren Stufen vergeben/zurcksetzen (maximal alles mt einem Klick). +Man kann ein Limit setzen. +Beispiel: +- ActiveShiftCkickLimit=0 (Deaktiviert, Standard) +- ActiveShiftCkickLimit=1 (Aktiviert) +- LimitValueToShiftClick=5 (Standard, es werden maximal 5 Statuspunkte auf einmal verndert) + + +[STAT ON LEVEL UP] +ndert die Anzahl der Statuspunkte beim LevelUp +Beispiel: +- ActiveStatPerLevelUp=0 {0:Deaktiviert; 1:Aktiviert} +- StatPerLevelUp=11 {0:keine Statuspunkte beim LevelUp; 11:elf Punkte beim LevelUp} + + +[SKILLS POINTS] + Kann genutzt werden um versehentlich gesetzte Fertigkeitspunkte zu korrigieren + Klickt auf den Knopf auf der Fertigkeits-Seite, um alle Punkte zurckzusetzen . +Hinweis: berprft die wahren "Kosten" fr jede Fertigkeit ( kann grsser als 1 sein in einem MOD) + Im folgenden die Standardwerte und in {} einige Beispiel Werte mit Beschreibungen: +- ActiveSkillsUnassignment=0 {0: Ausgeschaltet ; 1: Eingeschaltet } +- ActiveSkillsUnassignmentOneForOne=0 {0:Normal; 1:Force the skill unassign 1 for 1 (for mods).} +- PosXUnassignSkillBtn=-1 {-1: Default position, 50: Put the button at the position 50 in X} +- PosYUnassignSkillBtn=-1 {-1: Default position, 50: Put the button at the position 50 in Y} + + +[SKILL ON LEVEL UP] +ndert die Menge der Fertigkeitspunkte beim LevelUp. +Beispiel : +- ActiveSkillPerLevelUp=0 (Deakiviert, Standard) +- ActiveSkillPerLevelUp=1 (Aktiviert) +- SkillPerLevelUp=0 (man bekommt keinen Punkt beim LevelUp) +- SkillPerLevelUp=1 (Standard) +- SkillPerLevelUp=2 (2 Fertigkeitspunkte beim LevelUp) + + +[WORLD EVENT] +Aktiviert den lokalen World Event +World Event kann nur in Hlle und nur einmal pro Spiel aktiviert werden. +WorldEvent wird alle 75-125 verkauften SOJ aktivert +Der Verkauf eines echten SOJ erhht den Zhler um 100 +Bei Start eines D2 Spiels ist der SOJ Zhler zwischen 200-3000 +Der SOJ Zhler wird alle 10-20 Minuten um 1 erhht, auch wenn man nicht in einem Spiel ist. +When der World Event ausgelst wird, und man nicht in einem Spiel ist, verliert man ihn. +Hinweis 1: Es besteht eine Chance von 1/12 einen WE in der ersten Spielstunde zu erhalten +Hinweis 2: Von Beginn eines neuen Spiels kommt der nchste WE wird innerhalb weniger Sekunden bis 41:40 Stunden danach +Im folgenden die Standardwerte und in {} einige Beispiel Werte mit Beschreibungen: +- ActiveWorldEvent=0 {0: Ausgeschaltet ; 1: Eingeschaltet } +- ShowCounterInAllDifficulty=0 {0:Zeige die Meldung "SOJ verkauft" nur in Hlle; 1:Zeige es in allen Schwierigkeitsgraden} +- ItemsToSell=The Stone of Jordan {r01: rune EL; cap,rar,upg: Jede cap/war hat/shako rare} +- MonsterID=333 {333: DiabloKlon erscheint} +- OwnSOJSoldChargeFor=100 {100:Wenn Du einen SOJ verkaufst wird der SOJ Zhler um 100 erhht} +- InititalSOJSoldMin=200 {200:Der SOJ Zhler ist mindestens bei 200 wenn Du D2 startest} +- InititalSOJSoldMax=3000 {3000:Der SOJ Zhler ist maximal bei 3000 wenn Du D2 startest} +- TriggerAtEachSOJSoldMin=75 {75:Man muss mindestens 75 SOJ verkaufen zwischen zwei World Event} +- TriggerAtEachSOJSoldMax=125 {125:Man muss maximal 125 SOJ verkaufen zwischen zwei World Event} +- ActiveAutoSell=1 {0:Deaktiviert; 1:Aktiviert das automatische erhhen des SOJ Zhlers um 1} +- TimeBeforeAutoSellMin=0 {50:Es dauert mindestens 0 Sekunden zwischen 2 Hintergrund Verkufen} +- TimeBeforeAutoSellMin=1200 {1200:Es dauert maximal 20 Minuten (1200 Sekunden) zwischen 2 Hintergrund Verkufen} + + +[UBER QUEST] +Aktiviert den ber-Quest im Single-Player +Du musst die 3 Schlssel, danach die 3 Organe verwandeln. +Dies muss jeweils in Harrogath erfolgen +Notiz: Dieser Quest wird in einer spteren PlugY Version mehr dem Verhalten im Battle.net angepasst +Warnung: Aktuell sind die ber-Monster direkt neben dem Portal, also sei vorsichtig, wenn Du durch das Portal gehst!!! +ActiveUberQuest=0 {0:Deaktiviert; 1:Aktiviert} + + +[INTERFACE] +Fgt eine zustzliche Charakter Info Seite hinzu +Man kann auswhlen, ob die zuletzt angezeigte Seite erscheint, oder die Hauptseite +Die Eigenschaften die in den Extraseiten angezeigt werden knnen in der PlugY\statsinterface.txt verndert werden (Mit MS Excel ffnen) +Es gibt kein Seitenlimit. +Unterdrckt den Hintergrund von Schaltflchen, wenn der MOD diese bereits ndert +- ActiveNewStatsInterface=0 {0:Deaktiviert ; 1: Aktiviert} +- SelectMainPageOnOpenning=1 {0:Zuletzt ausgewhlte Seite wird angezeigt; 1: Hauptseite wird angezeigt} +- PrintButtonsBackgroundOnMainStatsPage=1 {0: Zeigt nicht den Hintergrund an ; 1: Zeigt ihn an } + + + +[EXTRA] +Man kann LOD beliebig oft auf einem Comuter starten. +Zum Beispiel knnen Modder Multiplayer-Spiele auf einem PC testen. +Warnung : +Startet keine Spiele mit dem gleichen Speicherort (SavePath), wenn Ihr den gemeinsamen Goldschatz aktiviert habt. +Benutzt nicht zweimal den gleichen Charakter zur gleichen Zeit. +- ActiveLaunchAnyNumberOfLOD=0 {0:Deaktiviert ; 1: Aktiviert} + +Im Einzelspieler Modus kann die Karte bei jedem Start automatisch erneuert werden (wie im Mehrspieler). +- AlwaysRegenMapInSP=0 {0:Deaktiviert ; 1: Aktiviert} + +Vorgabe der Spieleranzahl wie /players x) bei jedem Spielstart +- NBPlayersByDefault=0 {0:Deaktiviert ; 1:players 1 ; 8:players 8} + +Anzeige des ItemLevels im Gegenstandsinfobereich +- ActiveDisplayItemLevel=0 {0:Deaktiviert ; 1: Aktiviert} + +Dauerhafte Anzeige der Mana/Lebens- Werte oberhalb der Kugeln +- AlwaysDisplayLifeAndManaValues=0 {0:Deaktiviert ; 1: Aktiviert; 2:Ausgeschaltet, kann per Kommando eingeschaltet werden} + +Behebt den Bug der verhindert das von Microsoft Excel geffnete Text-Dateien nich geladen werden konnten. +- EnabledTXTFilesWhenMSExcelOpenIt=0 {0:Deaktivert; 1:Aktiviert} + +Die Ladder-Only Runenwrter knnen fr den Singleplayer aktivert werden. +Das wird ermglicht indem die Spalte "Server" in der runes.txt deaktiviert wird. +Benutze diese Spalte also nicht in deinem Mod wenn diese Funktion aktivert ist. +- ActiveLadderRunewords=0 {0:Deaktivert; 1:Aktiviert} + + +Weitere Funktionen folgen... :) + + +Wenn Ihr Anregungen habt, Fehler findet oder Konflikte mit MODs feststellt, schickt eine eMail an ynicolas@worldonline.fr mit "DiabloII" als Betreffzeile! +Zur Korrektur der deutschen bersetzung bitte eine eMail an ChaosEnergy@planetdiablo.com + + +******** Dank geht an: ******** +- Blizzard fr Diablo2 und Lord of Destruction. +- Kingpin, Afj666, Joel, SVR, Myrdinn fr Ihre Hilfe. +- Pralinor fo his help in the convertion to 1.12. +- ChaosEnergy fr Beta-Tests und die deutsche bersetzung. +- Char & Darque fr die Hilfe bei der englischen bersetzung. +- Shaitane, K&V, TheMasterCaster, raspa und onyx fr Tests. +- Golvmopp, Dark Spot in the Corner, Megalixir und Athara fr ihr Hilfe. +- ItalianPlayer fr Italienisch bersetzung. +- Alle Mitglieder des ProzenKeep Chat und Forum fr Ihre Informationen und das Feedback. +- PhrozenKeep fr alle Dinge die sie mit uns teilen (inklusive meinen ;) +- bersetzung : + * Englisch : Yohann, Jurica. + * Franzsisch : Yohann + * Deutch : ChaosEnergy, TheMasterCaster. + * Italienisch : ItalianPlayer + * Spanish : Acrerune + * Polnisch : Serdel + + ~~~~~~~~~~~~ \ No newline at end of file diff --git a/PlugYInstaller/PlugY_The_Survival_Kit_-_LisezMoi.txt b/PlugYInstaller/PlugY_The_Survival_Kit_-_LisezMoi.txt new file mode 100644 index 0000000..514c531 --- /dev/null +++ b/PlugYInstaller/PlugY_The_Survival_Kit_-_LisezMoi.txt @@ -0,0 +1,705 @@ +;--------------------------------------------------------------------------------------; +; ; +; "PlugY, The Survival Kit" ; +; ; +; par Yohann Nicolas ; +; ; +; version 10.00 ; +; ; +;--------------------------------------------------------------------------------------; + + +Site officiel : http://plugy.free.fr +Vous pouvez y faire un don si vous le souhaitez. + + +******** ATTENTION ******** +- Ce plugin fonctionne sur LoD version 1.09 1.13c et sur leurs mods. +- Ce plugin ne fonctionne pas sur les royaumes (Battle.net ou priv). +- Tous les fichiers ont changs depuis les versions prcdentes, donc dinstaller toutes les versions prcdentes. +- S'il vous plait, utilis le D2gfx.dll non modifi avant de rapporter une erreur. +- PlugY.ini a t modifi depuis les versions prcdentes, utiliser celui fourni dans cette archive. +- Ne pas oubliez de lire la partie nomme "COMMENTAIRES SUR LE FICHIER DE CONFIGURATION". +- Les moddeurs devraient lire la version anglaise de ce readme. +- N'oubliez pas de lire les forums : + http://forum.judgehype.com/judgehype/ModsetModding/liste_sujet-1.htm + http://phrozenkeep.planetdiablo.gamespy.com/forum/viewforum.php?f=133 (anglais) + + +******** CARACTERISTIQUES ******** +- Dsactive l'accs Battle.net +- Espace de stockage infini dans le coffre (jusqu' 4 294 967 296 pages personnelles!) +- Espace de stockage partag dans le coffre (jusqu' 4 294 967 296 pages partages aussi!) +- Active les mots runiques du ladder en dehors des royaumes. +- World Event et Uber Quest en Local pour le monojoueur et le multijoueur hors royaumes ! +- Permet d'ouvrir le portail vers le Cow Level mme quand on a tuer le Cow King dans cette difficult. +- Dsalloue les points de capacits(skills) et de statistiques prcdemment alloues. +- Change la langue du jeu. +- Rgnre toujours la carte en monojoueur comme en multijoueur. +- Excute automatiquement la comande /players X au lancement d'une partie. +- Ajoute des pages supplmentaires pour l'affichage de plus de statistiques du perso comme le %MF. +- Affiche le niveau de l'objet dans son popup. +- Permet de lancer autant de fois que l'on veut Diablo II sur le mme ordinateur. +- Le coffre contient 10x10 cases. +- Change le rpertoire de sauvegarde. +- Affiche toujours les valeurs numriques de mana et de vie au-dessus des globes correspondants. +- D2 peut charger tout les fichiers, mme ceux ouvert par Microsoft Excel (dsactiv par defaut). +- Affiche la valeur courante des caracs (sans les bonus magiques). +- Localis en franais, anglais, allemand, italien, espagnol et polonais. + + +Changements apports par la v10.00 : +- Dsactive l'accs Battle.net par le bouton du menu principal. +- PlugY fonctionne aussi la version 1.13c de LOD. +- Corrige le raccourci dans le menu dmarrer. + + +Changements apports par la v9.00 : +- PlugY fonctionne aussi la version 1.12 de LOD. +- Corrige diffrents bugs. +- Ajout d'une option pour le dassignement des skill dans les mods. + + +Changements apports par la v8.00 : +- Installation plus aise : Nouvel installeur. +- Permet d'ouvrir le portail vers le Cow Level mme quand on a tuer le Cow King dans cette difficult. +- Affiche la version courante de LoD avec la lettre de sous-version (1.11b, 1.09d) dans le menu principal. +- Ajout de la possibilit de dplacer le boutton de skills comme les boutons du stash. (pour moddeurs) +- Corrige le crash quand le joueur rencontrait un monstre superunique avec LoD 1.11. +- Corrige la perte de points de skills quand on les dsassign dans un mod qui contient des skills spciaux? +- Multiplayer : Sauvegarde les fichiers du stash (avec les donnes du client comme avec les versions d'avant 5.00) quand il y a une dconnection ou une erreur apparait durant la procdure de sauvegarde. +- Remove the "check load memory failed" message when D2gfx.dll was patched. + + +Changements apports par la v7.02 : +- Corrige la perte de points de skills quand on les dsalloue dans les mods contenant des skills spciaux. + + +Changements apports par la v7.01b : +- Corrige l'activation des mots runiques du ladder dans les versions 1.11 and 1.10 de LoD. +- Corrige les caractres tranges de quelques texts. + + +Changements apports par la v7.01 : +- Active les mots runiques du ladder en dehors des royaumes. +- Corrige le bug avec l'IA de Uber Baal. +- Retire les options de paramtres mis par defaut dans PlugY.ini (comme le mode fentr) +- Affiche la valeur courante des caracs (sans les bonus magiques) mme quand la dsallocation des caracs est dsactive. +- Ajout d'un excutable pour lancer Plugy (plus aucun fichier de LoD modifi). (RAPPEL) +- Traduction en espagnol et polonais. + + +Changements apports par la v7.00 : +- PlugY fonctionne aussi la version 1.11b de LOD. +- Ajout d'un excutable pour lancer Plugy (plus aucun fichier de LoD modifi). +- Ajout des valeurs de base des caracs sur les bouttons d'allocations. +- Corrige le bug des caracs infinie durant la dsallocation. +- Corrige les fonctions qui restais active sur Battle.net. +- Traduction en italien. + + +Changements apports par la v6.01b : +- Correction d'un bug avec l'affichage du popup sur les bouttons d'assignement des points de stats. + + +Changements apports par la v6.01 : +- Corrige le bug qui cause la disparition des items "carry1" du stash quand ils sont cubbs dans LoD 1.10 +- Cls et organes des uber ne sont plus dtruit quant on essaie d'ouvrir le portail en dehors d'Harrogath. +- Corrige le conflit avec D2Mod pour l'affichage de la version. + + +Changements apports par la v6.00 : +- PlugY fonctionne aussi la version 1.11 de LOD. +- Active la Uber Quest hors des Royaumes. (uniquement LoD 1.11). +- Corrige le crash au lancement de PlugY si l'installation de LoD n'est pas clean. +- Corrige quelques bugs mineurs et ajoute des amliorations mineurs. +- Ajoute la commande "/save" pour sauvegarder la partie sans quitter (uniquement LoD 1.11). + + +Changements apports par la v5.06 : +- Ajoute des bouttons pour le partage de l'or. +- Active l'or partag en multijoueur. +- La commande "/DisplayLifeMana" est remplace par "/dlm". +- Corrige quelques bugs. + + +Changements apports par la v5.05 : +- Corrige les couleurs par dfauts dans l'interface des stats. +- Ajoute de l'or partage via des commandes. +- La commande "/DisplayLifeAndMana" deviens "/DisplayLifeMana". +- Possiblit d'afficher ou non les nom des objets de set dans le popup quand ceux-ci sont dans le coffre partage. +- Correction des bugs du multiplayer (rcriture de ces fonctions). + + +Changements apports par la v5.04 : +- Corrige Stat/Skill points par levelup +- Corrige des bugs en Multiplayer. +- PlugY/PlugYDefault.ini complet. + + +Changements apports par la v5.03 : +- Corrige le bug qui change quelques fois les coffres partags Hardcore et Softcore. +- Ajoute de la couleur sur les nouvelles pages de stats. +- Change les valeurs par dfaut des nouvelles pages de stats. +- Mets EnabledTXTFilesWhenMSExcelOpenIt=1 dans le fichier PlugY.ini. + + +Changements apports par la v5.02 : +- Corrige la correction d'un bug prcdent qui engendre la disparition d'objets. + + +Changements apports par la v5.01 : +- Corrige les bugs importants dans la gestion du stash. +- Remets ActiveLogFile=0 par dfaut dans le fichier PlugY.ini. +- Corrige : Bug quand le stash partag est dsactiv. + + +Changements apports par la v5.00 : +- PlugY fonctionne sur les mods des versions 1.09, 1.09b, 1.09d et 1.10 de LOD. +- PlugY peut lancer D2Mod.dll. +- D2 peut ouvrir tous les fichiers mme quand ils sont dj ouverts dans Microsoft Excel. +- Le monstre du World Event peut tre chang. +- Plusieurs trucs pour les moddeurs. +- Importante Correction en Multijoueur : fingerprints 0, objets non identifi bugg, etc. +- Correction d'une erreur de syntaxe dans PlugY.ini (Commands). +- Les commandes ne sont plus dpendantes de la casse des caractres. +- Corrige le bug dans la slection automatique de la principale page de stats. +- Remplace l'affichage de "Coup critique/Coup mortel" par Coup mortel uniquement. +- Corrige la gnration de DiabloClone au dmarrage d'une nouvelle partie. +- Corrige plusieurs autres bugs. + + +Changements apports par la v4.04 : +- Corrige le bug d'affichage quand statPerLevelUp est activ +- Corrige le bug de sauvegarde quand le disque dur est plein. +- Nouveau systme de configuration pour les moddeurs. +- Affiche toujours les valeurs numriques de mana et de vie au-dessus des globes correspondants. + + +Changements apports par la v4.03 : +- Corrige le bug des objets uniques carry1 (charme unique) quand on drop le cube. +- Possibilit d'aller directement la premire ou dernire page du coffre (shift + clic sur prcdent/suivant). +- Utilisation d'un second index dans le coffre (shift + clic sur boutons d'index) +- Ajouts d'infos sur les pages de stats supplmentaires (2 pages maintenant). +- Ajoute un bouton "page prcdente" sur la principale page de stats (uniquement en 800x600). +- Dplace les boutons des pages de stats supplmentaire aux mme emplacements que ceux de la page principale (uniquement en 800x600). +- Possibilit de choisir si la page affiche quand on ouvre la page des stats est la page principale ou celle slectionne prcdemment. + + +Changements apports par la v4.02b : +- Les fonctionnalits restent actives sur Battle.net ouvert. + + +Changements apports par la v4.02 : +- Corrige le conflit avec Battle.net (BigStash dsactiv sur les royaumes) +- Corrige l'oublie du "d" de "SeparateHardcoreStash=1" de PlugY.ini +- Corrige la valeur par dfaut dans PlugY.ini, du changement de langage. +- Corrige l'activation de l'affichage de l'item level pour toutes les configurations de PlugY. +- Ajouts d'infos sur la 2me page de stats. + + +Changements apports par la v4.01 : +- Corrige le bug du MSVCR70.dll non trouv. +- Ajouts d'infos sur la 2me page de stats. + + +Changements apports par la v4.00b : +- Corrige le bug du MSVCR70.dll non trouv. + + +Changements apports par la v4.00 : +- Meilleure optimisation du code. +- Ajoute des pages supplmentaires pour l'affichage de plus de statistiques du perso comme le %MF. +- Change la langue du jeu (et pour les modders: les langues accessibles et la langue par dfaut). +- Rgnre toujours la carte en Monojoueur comme en Multijoueur. +- Excute automatiquement la commande /players X au lancement d'une partie. +- Affiche le niveau de l'objet dans son popup. +- Spare le coffre partag des persos Hardcore et Softcore. +- Change la mthode d'installation (peut tre install directement sur linux maintenant) +- Les objets qui dclenche le WorldEvent peut-tre chang. +- Plusieurs objets "carry1" (comme l'Annihilus) peuvent tre mis dans le coffre. +- Corrige : Impossibilit de mettre plusieurs mme objets "carry1" dans d'autre page que le coffre. +- Corrige : Le bug d'affiche des objets sertis dans le coffre. +- Corrige : Le bug des espaces dans PlugY.ini. +- Corrige : Diablo Clone ne peut pas apparatre en mode normal et cauchemar. +- Corrige : Dtruit les minions(par exemple les squelettes) en trop prs la dsallocation si on a un bonus +x dans cette skill. + + +Changements apports par la v3.02 : +- Corrige : le changement du nombre de points de Stats reus chaque gain de niveau. +- Corrige : Quand le coffre partag est dsactiv vous pouvez charger vos persos. +- Corrige : Vous pouvez changer les paramtres du World Event sans activer les skill reus chaque gain de niveau. + + +Changements apports par la v3.01 : +- Change le nombre de points de Stats reus chaque gain de niveau. +- Corrige les bugs qui donnent des points supplmentaires quand on dsallouent les skills. +- Ajoutent les paramtres du WorldEvent dans le fichier de configuration. +- Par dfaut, Le WorldEvent AFFICHE "X SOJ vendu" uniquement dans la difficult enfer. + + +Changements apports par la v3.00 : +- World Event en Local pour le monojoueur et le multijoueur hors royaumes ! +- Dsalloue les points de capacits(skills) prcdemment alloues. +- Nouvelle image de fond pour le coffre. +- On peut changer le nom du fichier de sauvegarde. +- L'affichage du numero de page pour le coffre partag est en rouge maintenant. + + +Changements apports par la v2.05 : +- Correction importante : Le bug qui faisais que D2 ne dmarrais est dfinitivement corrig. + +Changements apports par la v2.04 : +- La dsallocation des points de stats, les points de skills gagns chaque niveau + sont quand on se connecte un royaume automatiquement dsactivs (comme le stash). +- Ouvre un message d'erreur quand PlugY.dll n'est pas trouv. +- Corrige plusieurs bugs dans l'installation de PlugY. +- Corrige le bug d'affichage des boutons. +- Corrige la sauvegarde sous win95/98/Me. + +Changements apports par la v2.03b : +- Affiche la version de PlugY uniquement l'cran principal. + +Changements apports par la v2.03 : +- Correction importante : Les fonctions de sauvegardes sont plus scurises et dbugges. +- Le serveur ne plante plus quand un personnage refus tente de joindre la partie. +- Les boutons de dsallocation ne deviennent plus gris quand les points de stats de base dpassent 255. +- Change l'affichage des versions sur le menu principal (changement des couleurs + la version de PlugY droite). +- Les personnages sans PlugY peuvent joindre les parties avec PlugY activ. + + +******** CONTENU ******** +19 fichiers, 1 rpertoire : +- PlugY_The_Survival_Kit_-_Readme.txt +- PlugY_The_Survival_Kit_-_LisezMoi.txt +- PlugY_The_Survival_Kit_-_Liesmich.txt +- PlugY.exe +- PlugY.dll (in Diablo II directory) +- PlugY.ini +- PlugY\PlugYFixed.ini +- PlugY\PlugYDefault.ini +- PlugY\EmptyPage.dc6 +- PlugY\SharedGoldBtns.dc6 +- PlugY\StashBtns.dc6 +- PlugY\TradeStash.dc6 +- PlugY\StatsBackground.dc6 +- PlugY\UnassignSkillsBtns.dc6 +- PlugY\UnassignStatsBtns.dc6 +- PlugY\statsinterface.txt +- PlugY Uninstaller.exe (avec l'option d-installeur) +- PatchD2gfxDll.exe (dans le rpertoire de Diablo II avec l'option Patcheur D2gfxDll) +- RestoreD2gfxDll.exe (dans le rpertoire de Diablo II avec l'option Patcheur D2gfxDll) + + + +******** INSTALLATION ******** +Les sites de tlchargement officiel sont : +http://djaftal.chez-alice.fr/ +http://phrozenkeep.18v.biz/dload.php?action=category&cat_id=128 +http://diablo2.judgehype.com/index.php?page=telechargements + + +Installation normale : +- Suivre les directives de l'installeur. + +note : Vous pouvez choisir le rpertoire de "Diablo II" comme rpertoire d'installation. + +Installation dans un autre mod +- Copier PlugY.ini, PlugY.exe er PlugY folder (+son sontenu) dans le rpertoire du mod cibl. +- Editer PlugY.ini pour configurer les options (voir section plus bas). +- Lancer le jeu PlugY.exe et amusez-vous :) + +note : Vous pouvez dplacer le rpertoire "PlugY" dans celui de "Diablo II" et il sera vu par toutes les installation. + + +Exemple : +Si vous avez install Lord of Destruction ici : C:\Jeux\Diablo II\Diablo II.exe +Et que le mod cibl se trouve l : D:\D2Mod\MyMod\ +Et que un second mod se trouve l : D:\D2Mod\MyMod2\ +Alors la configuration classique est ceci : + C:\Jeux\Diablo II\PlugY.dll + D:\D2Mod\MyMod\PlugY\SharedGoldBtns.dc6 + D:\D2Mod\MyMod\PlugY\PlugYFixed.ini + D:\D2Mod\MyMod\PlugY\PlugYDefault.ini + D:\D2Mod\MyMod\PlugY\EmptyPage.dc6 + D:\D2Mod\MyMod\PlugY\SharedGoldBtns.dc6 + D:\D2Mod\MyMod\PlugY\StashBtns.dc6 + D:\D2Mod\MyMod\PlugY\TradeStash.dc6 + D:\D2Mod\MyMod\PlugY\StatsBackground.dc6 + D:\D2Mod\MyMod\PlugY\UnassignSkillsBtns.dc6 + D:\D2Mod\MyMod\PlugY\UnassignStatsBtns.dc6 + D:\D2Mod\MyMod\PlugY\statsinterface.txt + D:\D2Mod\MyMod\PlugY.ini + D:\D2Mod\MyMod\PlugY.exe + D:\D2Mod\MyMod2\PlugY\SharedGoldBtns.dc6 + D:\D2Mod\MyMod2\PlugY\PlugYFixed.ini + D:\D2Mod\MyMod2\PlugY\PlugYDefault.ini + D:\D2Mod\MyMod2\PlugY\EmptyPage.dc6 + D:\D2Mod\MyMod2\PlugY\SharedGoldBtns.dc6 + D:\D2Mod\MyMod2\PlugY\StashBtns.dc6 + D:\D2Mod\MyMod2\PlugY\TradeStash.dc6 + D:\D2Mod\MyMod2\PlugY\StatsBackground.dc6 + D:\D2Mod\MyMod2\PlugY\UnassignSkillsBtns.dc6 + D:\D2Mod\MyMod2\PlugY\UnassignStatsBtns.dc6 + D:\D2Mod\MyMod2\PlugY\statsinterface.txt + D:\D2Mod\MyMod2\PlugY.ini + D:\D2Mod\MyMod2\PlugY.exe + + +Dsinstallation : Run uninstaller ou si vous n'avez pas activ cette options, supprimer semplement tous les fichiers de PlugY. +NOTE : Vous pouvez aussi dplacer PlugY.dll dans le rpertoire du mod mais vous devez le supprimer du rpertoire de D2. +Note : Le rpertoire "PlugY" et son contenu peut tre plac dans un mpq. + +------- D2gfx Patcher : + +If you have problem when you run PlugY.exe then use PatchD2gfxDll.exe. (It happend sometimes with Windows 2000) +- Go in Diablo II directory. +- Do a backup of D2gfx.dll (in the case, you remove PlugY before restore it) +- Run PatchD2gfxDll.exe (which patches D2gfx.dll for launch PlugY, you can backup this file before) +- Create a shortcut : Enter target mod directory in "start in" field of properties->shortcut. (unless you install PlugY in Diablo II directory) +- Launch with the shorcut !! + +Before uninstall PlugY Restore your D2gfx.dll with your backup file or run RestoreD2gfxDll.exe. + + +Si vous avez des problme pour xcuter PlugY.exe alors utiliser PatchD2gfxDll.exe. (Ca arrive quelque fois avec Windows 2000) +- Aller dans le rpertoire de Diablo II. +- Fates un une sauvegarde du fichier D2gfx.dll (dans le cas, o vous supprimiez PlugY avant de le restaurer). +- Lancer PatchD2gfxDll.exe (qui patchera D2gfx.dll pour lancer PlugY) +- Crer un raccourci de Diablo II.exe, entrer le rpertoire du mod voulu dans "dmarrer dans" de proprit->raccourci. (sauf si vous avez install PlugY dans le rpertoire de Diablo II) +- Lancer Diablo II ! + + + +******************** FAQ ****************** + +=> Je ne troue pas le fichier PlugY.ini, o est-il ? +De kingpin (traduit de l'anglais): +Microsoft a dans Windows cach les extensions des fichiers connu. Ceci pour tre +sr que les nouveaux utilisateurs ne supprime pas ces fichiers par accidents. Vous +pouvez bien sr le dsactiver en ouvrant votre l'explorateur Windows, aller dans +outils->Options des dossiers->affichage, Dcocher "Masquer les extensions des +fichiers dont le type est connu". Alors, vous verrez le fichier srement le fichier ini. + + +=> Comment jouer sur Battle.net avec PlugY install ? +PlugY automatiquement dsactive tous quand on va en ferm. +Mais il est recommand de toujours retirer tous les programmes tiers quand on a va sur les royaumes. +Note : Quand bigStash est activ, vous devez redmarrer D2 pour jouer en solo/multi/ouvert aprs avoir jouer en ferm (et vice versa). +Astuce : Crer un raccourci et ajouter -skiptobnet la fin du champ "cible" pour aller directement sur Battle.net. + + +=> Que faire si j'ai une erreur comme "Bad Generic File" au chargement d'un nouveau joueur ? +Ceci peut apparatre quand vous avez de mauvais objets dans le fichier du coffre partag. +Une cause possible est l'utilisation du mme rpertoire de sauvegarde pour des mods diffrents, +il suffit alors de changer ce rpertoire dans PlugY.ini. + + +=> Je vois "sUnitItemInsertItemInvGridBase failed at 1046 in C:\projects\D2\head\Diablo2\Source\D2Client\UNIT\Item.cpp" dans D2YYMMDD.txt, que dois-je faire ? +Ceci est juste un avertissement sans consquence sur le jeu, ne vous inquiter pas. + + +=> J'ai un autre bug, que dois-je faire ? +1) Aller sur les forums de Phrozen-keep et Judgehype et lire les forums. + +2) Fates des recherche sur google, demander des amis, etc. mais ne me demander pas, je n'ai plus le temps pour faire le support de PlugY. +Si un jour, j'ai assez de temps, (comme pour la version 8.00) je lirai les forums pour connaitre les problmes les plus communs. + + + +******** CONFIGURATION ******** + +Configuration pour un mod prcis : +- Copier PlugY.ini dans le rpertoire du mod choisi (le rpertoire d'o vous le lancez le mod, voir dans proprits du raccourci). +- Dans la plupart dans cas changer le rpertoire de sauvegarde. +- Ajouter toutes les dll supplmentaires dans PlugY.ini si besoin est. +- Finalement activer ou dsactiver les options que vous souhaitez comme MultiPageStash, SharedStash, etc. +- Maintenant vous pouvez lancez le mod de manire classique. + +D2Mod configuration : +Ajouter simplement le nom de la dll dans PlugY.ini, par exemple : "DllToLoad=D2Mod.dll" + +Notes: +- Les objets dans le Cube sont toujours sauvegards dans le personnage, si vous voulez les partager vous devez les retirer du cube. + +Attention : +- Ne pas diter le fichier de configuration aprs avoir utilis le mod. +- Dans des parties Multiplayers, vrifier qu'il y a la mme configuration sur le serveur et les clients. +- Rappel : PlugY ne fonctionne pas sur les royaumes. + + +Lire le readme pour les moddeurs. + + +******** COMMENTAIRES SUR LE FICHIER DE CONFIGURATION ******** + +Toutes les valeurs par Dfaut signifie que si on supprime cette ligne, PlugY utilise cette valeur. +Les valeurs dans PlugY.ini (inclus dans le zip) est un exemple de configuration, pas les valeurs par dfaut. + +[LAUNCHING] +Cette section contient les informations de PlugY.exe et ne fonctionne pas dans les fichiers PlugYDefault.ini et PlugYFixed.ini. + +Ajoute les paramtres transmis LoD par sa ligne de commande. +Les paramtres pass PlugY.exe sont aussi transmis LoD par sa ligne de commande. +Par dfaut aucun paramters ne sont transmis. +Les paramtres les plus courant sont (sans les guillemets) : +"-w" lance la LoD en version fentre. +"-direct" utilise les fichiers du rpertoire la place des mpq. +"-txt" recompile les fichiers .txt avant d'antre dans une partie. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +Param= {-direct -txt -w: Ces 3 commandes sont passs LoD par la ligne de commande} + + +Slectionne la dll charger. +Le rpertoire courant est celui utilis par D2 (comme modifier le champ "dmarrer dans" d'un raccourci). +Si auncune dll n'est spcifi, LoD est charg sans PlugY. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +Library= {PlugY.dll: Charger PlugY.dll} + + +[GENERAL] +Active ou dsactive PlugY +Les dll des champs "DllToLoad" ne sont plus chargs quand ActivePlugin=0. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActivePlugin=0 {0:Charge aucunes fonctions; 1:Plugin activ} + +Active ou dsactive l'accs BattleNet. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- DisableBattleNet=1 {0:accs Battle.net activ; 1:accs Battle.net dsctiv} + +Enregistre le log dans le fichier "The PlugY.log" dans le rpertoire courant. +Cette fonction peut ralentir le jeu. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveLogFile=0 {0:Dsactiv, aucune information n'est crite pendant le jeu; 1:toujours activ} + +Charge les dll supplmentaires du mod pour les utiliser en mme temps que PlugY. +Sparer chaque dll par le caractre pipe (|) +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- DllToLoad= {(vide): rien charger; D2extra.dll|myDll.dll: Charge D2extra.dll et myDll.dll} +- DllToLoad2= {(vide): Mme chose que DlltoLoad} + +Active les nouvelles commandes de PlugY. +"/dlm" alterne l'tat de AlwaysDisplayLifeAndManaValues (AlwaysDisplayLifeAndManaValues>0) +"/page x" Aller la page x dans les pages de stats supplmentaires. +"/save" Sauvegarde la partie sans la quitter (uniquement LoD 1.11 et 1.11b). +- ActiveCommands=0 {0:Dsactiv; 1:Activ} + +Quitte D2, si PlugY if PlugY choue lors de l'installation de toutes les fonctions. +Dsactivez-le seulement si vous savez ce que vous faites. +- ActiveCheckMemory=1 {0:Dsactiv; 1:Activ} + +Active les fonctions cachs ou non finis. (ne pas utiliser) +- ActiveAllOthersFeatures=0 {0:Dsactiv; 1:Activ} + + +[LANGUAGE] +Change la langue du jeu. +Vous devez avoir les fichiers de langue choisi. +Toutes les versions de D2 et LOD contiennent les fichiers en anglais (sauf les voix). +Toutes les langues possibles : ENG|ESP|DEU|FRA|POR|ITA|JPN|KOR|SIN|CHI|POL|RUS +- ActiveChangeLanguage=0 {0:Dsactiv; 1:Activ} +- SelectedLanguage=ENG {FRA: Franais slectionn} + +Pour les moddeurs qui veulent limits les languages accessibles etle language par dfauts : +- ActiveLanguageManagement=0 {0:Dsactiv; 1:Activ} +- DefaultLanguage=ENG {empty:Langue par dfault de D2; FRA: Le franais est la langue par dfaut} +- AvailableLanguages=ENG|FRA {ENG|ESP|DEU|FRA|POR|ITA|JPN|KOR|SIN|CHI|POL|RUS} + + +[SAVEPATH] +Mettez dans cette variable le chemin d'accs des fichiers de sauvegarde. +Vous pouvez aussi bien utiliser un chemin absolu ou relatif. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveSavePathChange=0 {0:Dsactiv; 1=Activ, vous devez initialiser "SavePath"} +- SavePath=Save\ {Save\MyMod\ ou D:\Save Games\diablo II\Current Mod\} + + +[MAIN SCREEN] +Change le texte affich dans le menu principal (premier menu) ( la place de "v 1.10") +Les couleurs sont des entiers faisant rfrence aux couleurs dfinies de D2. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveVersionTextChange=0 {0:Dsactiv; 1=Activ} +- VersionText= {Vide: Affiche la version courante de LoD avec la lettre de sous-version (1.11b, 1.09d) ; Nom du Mod:Texte avec une longueur maximale d'environ 23 caractres (ex : v 1.11b)} +- ColorOfVersionText=0 {0:blanc; 1:rouge; 4:or; etc.} +- ActivePrintPlugYVersion=1 {0:Dsactiv; 1=Activ) +- ColorOfPlugYVersion=4 {0:blanc; 1:rouge; 4:or; etc.} + + +[STASH] +Ajuste le coffre pour avoir 10x10 cases. +Quand bigStash est activ, vou devez redmarrer D2 pour jouer en solo/multi/ouvert aprs avoir jouer en ferm (et vice versa). +Utilise PlugY\TradeStash.dc6 pour changer l'image de fond. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveBigStash=0 {0:Taille du coffre par dfaut utilis; 1:Activ, coffre utilise 10x10 cases} + +Utilisez cette fonction pour partager et garder tous vos objets. :) +Il y a 2 coffres pages multiples possibles : +- un personnel accessible uniquement par le personnage; +- un partag entre tous vos personnages. +Utilisez le bouton "Voir coffre..." pour changer de coffre. +Utilisez les boutons flchs (et le bouton shift) pour passer d'une page l'autre. +Dfinition : La dernire page est la dernire page qui contient un objet. +Ces coffres pages multiples ne fonctionne pas avec des personnages Diablo II classiques ou sur les royaumes. +Vous pouvez changez le nom du fichier partag. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveMultiPageStash=0 {0:Dsactiv; 1:Activ} +- NbPagesPerIndex=10 {10: Les pages indexes sont 1,10,20,30,...,max} +- NbPagesPerIndex2=100 {50: Les pages indexes (+shift) sont 1,50,100,150,...,max} +- MaxPersonnalPages=0 {0:Nombre de pages personnelles illimites; 1000: Maximum de 1000 pages personnelles} +- ActiveSharedStash=0 {0:Dsactiv; 1:Activ si ActiveMultiPageStash=1} +- SeparateHardcoreStash=1 {0:Mme coffre partag en HC et SC; 1:utilise 2 coffres diffrents} +- SharedStashFilename=SharedStashSave {xxx : Le nom du fichier sera _LOD_xxx.sss} +- displaySharedSetItemNameInGreen=1 {0:Dsactiv; 1:Activ, Les noms des objets de sets dans le stash sont affichs en vert sur les autres objets de sets.} +- MaxSharedPages=0 {0:Nombre de pages partages illimites; 5000: Maximum de 5000 pages partages ) +- ActiveSharedGold=1 {0:Dsactiv; 1:Activ, utiliser les commands pour y ajouter ou retirer de l'or (voir Command section)} +- PosXPreviousBtn=-1 {-1: Position par dfaut, 50: Dplace le bouton la position 50 en abscisse} +Idem pour PosYPreviousBtn, PosXNextBtn, PosYNextBtn, PosXSharedBtn, PosYSharedBtn, PosXPreviousIndexBtn, PosYPreviousIndexBtn, PosXNextIndexBtn, PosYNextIndexBtn, PosXPutGoldBtn, PosYPutGoldBtn, PosXTakeGoldBtn, PosYTakeGoldBtn. + + +[STATS POINTS] +Utiles pour rparer des erreurs dans l'allocation de points de caractristiques. +Par exemple 30 points d'nergie pour un barbare ! +Sur la page des statistiques, appuyer sur la touche slectionne et cliquer sur le bouton "moins". +Slectionner une touche en changeant la valeur de KeyUsed (devriez choisi 17 ou 18) +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveStatsUnassignment=0 {0:Dsactiv; 1:Activ, appuyer sur la touche slectionne en cliquant} +- KeyUsed=18 {17:touche Contrle slectionne; 18:touche Alt slecttionne} + +Utilisez la touche shift pour allouer/dsallouer tous les points possibles en un click. +Vous pouvez limiter le nombre de points allou/dsallou. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveShiftCkickLimit=0 {0:Dsactiv; 1:Activ} +- LimitValueToShiftClick=5 (10: Alloue ou dsalloue les points de stats 10 par 10} + + +[STAT ON LEVEL UP] +Change le nombre de points de Stats reus lors d'un gain de niveau. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveStatPerLevelUp=0 {0:Dsactiv; 1:Activ} +- StatPerLevelUp=5 {0:aucun points gagns; 11:onze points gagns} + + +[SKILLS POINTS] +Utiles pour rparer des erreurs dans l'allocation de points de skills. +Cliquer sur le bouton de la page des skills pour dsallouer tous les points de skills. +note : Prends le cot rel de chaque skills (qui peut tre plus grand que 1 dans les mods). +Attention : Il y a peux de place o mettre se boutton sans bugs. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveSkillsUnassignment=0 {0:Dsactiv; 1:Activ} +- ActiveSkillsUnassignmentOneForOne=0 {0:Normal; 1:Force la dassignation 1 for 1 (pour mod spcifique).} +- PosXUnassignSkillBtn=-1 {-1: Position par dfaut, 50: Dplace le bouton la position 50 en X} +- PosYUnassignSkillBtn=-1 {-1: Position par dfaut, 50: Dplace le bouton la position 50 en Y} + + +[SKILL ON LEVEL UP] +Change le nombre de points de skills reus lors d'un gain de niveau. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveSkillPerLevelUp=0 {0:Dsactiv; 1:Activ} +- SkillPerLevelUp=1 {0:aucun points gagns; 3:trois points gagns) + + +[WORLD EVENT] +Active le World Event en local. +Le World Event peut se dclencher uniquement en difficult enfer et seulement une fois par partie. +Si le WorldEvent se dclenche et qu'on n'est pas dans une partie, on le perd. +A partir du lancement de D2, le prochain WorldEvent peut s'enclencher entre quelques secondes et 41:40 heures aprs. +Gardez en mmoire avant d'diter ces variables que le World Event devrait toujours tre rare. +L'objet vendre peut tre chang, la valeur attendu est la mme que les entres du cube. +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveWorldEvent=0 {0:Dsactiv; 1:Activ} +- ShowCounterInAllDifficulty=0 {0:Affiche le message "SOJ vendu" seulement en mode enfer; 1:L'affiche dans tous les modes} +- ItemsToSell=The Stone of Jordan {r01: rune EL; cap,rar,upg: N'importe quel Capuchon de mailles/Capuchon de guerre/shako rare} +- MonsterID=333 {333: DiabloClone slectionn} +- OwnSOJSoldChargeFor=100 {100: Quand on vend une SOJ ,le compteur de SOJ est augment de 100} +- InititalSOJSoldMin=200 {200: Le compteur de SOJ est initialis a au moins 20 au lancement de D2} +- InititalSOJSoldMax=3000 {3000: Le compteur de SOJ est initialis a au plus 3000 au lancement de D2} +- TriggerAtEachSOJSoldMin=75 {75: Obligation d'avoir au moins 75 SOJ vendu entre 2 World Event} +- TriggerAtEachSOJSoldMax=125 {125: Obligation d'avoir au plus 125 SOJ vendu entre 2 World Event} +- ActiveActiveAutoSell=1 {0:Dsactiv; 1:Le compteur de SOJ est automatiquement incrment de 1} +- TimeBeforeAutoSellMin=0 {50: Obligation d'avoir au moins 50 secondes entre 2 auto-incrmentation} +- TimeBeforeAutoSellMin=1200 {1200: Obligation d'avoir au plus 20 minutes (1200 secondes) entre 2 auto-incrmentation} + + +[UBER QUEST] +Active la Uber Quest en local. +Fonctionne uniquement en Hell. +Vous devez cuber les 3 cls puis les 3 organs Harrogath. +Note : Cette qute sera mise jour plustard pour ressembler plus celle des royaumes. +ActiveUberQuest=0 {0:Disabled; 1:Enabled} + + +[INTERFACE] +Ajoute des pages supplmentaires pour l'affichage de plus de stats du perso. +Possibilit de choisir si la page affiche quand on ouvre la page des stats est la page principale ou celle slectionne prcdemment. +Possibilit de changer l'affichage des stats via le fichier PlugY\statsinterface.txt ( ouvrir avec MS Excel). +Il n'y a pas de limite pour le nombre de page. +Possibilit de ne pas afficher l'arrire plan des boutons ( utiliser si un mod le change dj). +- ActiveNewStatsInterface=0 {0:Dsactiv; 1:Activ} +- SelectMainPageOnOpenning=1 {0:Prcdente page slectionne affiche; 1:Page principale affiche} +- PrintButtonsBackgroundOnMainStatsPage=1 {0:N'affiche pas l'arrire plan; 1:L'affiche} + + +[EXTRA] +Vous pouvez lancer plusieurs parties Diablo II sur un seul ordinateur. +Par exemple, les moddeurs peuvent tester leurs mod avec des parties multijoueurs. +Attention : + Ne pas lancer des parties avec le mme chemin de sauvegarde quand vous utiliser le coffre partag. + Ne pas utiliser le mme personnage en mme temps bien sr ! +Ci-dessous, les valeurs par dfauts et entre {} des exemples avec leurs significations : +- ActiveLaunchAnyNumberOfLOD=0 {0:Dsactiv; 1:Activ} + +Rgnre la carte chaque nouvelle partie (comme en multijoueur). +- AlwaysRegenMapInSP=0 {0:Dsactiv; 1:Activ} + +Change le nombre de joueurs muls (comme /players x) chaque dbut de nouvelle partie. +- NBPlayersByDefault=0 {0:Dsactiv; 1:1 joueur mul (normal); 8: 8 joueurs muls (maximum)} + +Affiche toujours le niveau des items. +- ActiveDisplayItemLevel=0 {0:Dsactiv; 1:Activ} + +Affiche toujours les valeurs numriques de mana et de vie au-dessus des globes correspondants. +- AlwaysDisplayLifeAndManaValues=0 {0:Dsactiv; 1:Activ; 2:Dsactiv mais peut tre activ par commande} + +Corrige le bug qui bloque l'ouverture des fichiers .txt quand ils sont ouverts dans Microsoft Excel. +- EnabledTXTFilesWhenMSExcelOpenIt=0 {0:Dsactiv; 1:Activ} + +Affiche la valeur courante des caracs (sans les bonus magiques) quand la souris passse sur le bouton d'assignation. +- ActiveDisplayBaseStatsValue=0 {0:Dsactiv; 1:Activ} + +Active les mots runiques du ladder en dehors des royaumes. +Ceci est fait par la mise 0 de la colonne "server" du fichier runes.txt. +Donc n'utilisez pas cette colonne dans votre mod en mme temps que cette fonction ! +- ActiveLadderRunewords=0 {0:Dsactiv; 1:Activ} + +Active la capacit" d'ouvrir l portail vers le Cow Level dans la difficult o le joueur dj tuer le Cow King. +- ActiveCowPortalWhenCowKingWasKilled=0 {0:Dsactiv; 1:Activ} + + +Plus d'options dans de futures versions... :) + + +Mon mail ynicolas@worldonline.fr. +Mais je ne fais plus le support de PlugY donc n'attendez pas de l'aide de ma part si vous avez des problmes. A la place faites des recherches sur les forums. + + +PS : Dsol pour les ftes mais je n'ai pas envie de corriger ;) + +******** THANKS TO ******** +- Blizzard pour avoir fait Diablo II et Lord of Destruction. +- Kingpin, Afj666, Joel, SVR, Myrdinn pour leurs aides. +- Pralinor pour son aide dans la convertion en 1.12. +- ChaosEnergY pour ses beta tests et sa traduction en allemand. +- Char & Darque pour avoir corrig mon anglais. +- Shaitane, K&V, themastercaster, raspa et onyx pour leurs tests. +- Golvmopp, Dark Spot in the Corner, Megalixir et Athara pour leurs aides. +- ItalianPlayer pour la traduction en italien. +- Tous les membres du Chat de ProzenKeep. +- PhrozenKeep pour tout ce qu'ils partagent pour nous (y-compris le mien ;) +- Traduction : + * Anglais : Yohann, Jurica. + * Franais : Yohann + * Allemand : ChaosEnergy, TheMasterCaster. + * Italien : ItalianPlayer + * Espagnol : Acrerune + * Polonais : Serdel + ~~~~~~~~~~~~ \ No newline at end of file diff --git a/PlugYInstaller/PlugY_The_Survival_Kit_-_Readme.txt b/PlugYInstaller/PlugY_The_Survival_Kit_-_Readme.txt new file mode 100644 index 0000000..c9f3ea3 --- /dev/null +++ b/PlugYInstaller/PlugY_The_Survival_Kit_-_Readme.txt @@ -0,0 +1,789 @@ +;--------------------------------------------------------------------------------------; +; ; +; "PlugY, The Survival Kit" ; +; ; +; by Yohann Nicolas ; +; ; +; version 10.00 ; +; ; +;--------------------------------------------------------------------------------------; + +Official website : http://plugy.free.fr +You can make a donation if you want. + + +******** WARNING ******** +- This plug-in works with LoD version 1.09 to 1.13c and mods based on. +- This plug-in doesn't work on realms (Battle.net or private). +- All files may be changed since previous version, so uninstall any previous version. +- Please, use a clean D2dfx.dll before report any crash on starting LoD. +- PlugY.ini has changed since previous version, use the one in this package. +- Don't forget to read the part named "COMMENTS ON THE CONFIGURATION FILE". +- Don't forget to read the PlugY forum at : + http://phrozenkeep.planetdiablo.gamespy.com/forum/viewforum.php?f=133 + + +******** FEATURES ******** +- Disable access to Battle.net. +- Infinite storage space in the stash (up to 4,294,967,296 personal pages!) +- Shared storage space in the stash (up to 4,294,967,296 shared pages too!) +- Enabled the ladder only runewords out of realms. +- Local World Event and Uber Quest for singleplayer and multiplayer off-realm ! +- Can open Cow Level Portal even when player have kill the Cow King in that difficulty. +- Unassign assigned skills and stats points. +- Change the selected language. +- Always regenerate maps in SinglePlayer like in MultiPlayer. +- Automatically execute /players X when you launch a new game. +- Added some pages for display more characters stats like %MF. +- Display item level in its popup. +- Launch any number of Diablo II games on the same computer. +- Increase the stash to 10x10 squares. +- Change the save path directory. +- Always display Mana and Life values above the globes. +- D2 can load all files, even those opened with Microsoft Excel (disabled by default). +- Display the stats current value (without magical bonus) like Magic/gold find or maximum resistances. +- PlugY is localized in English, French, German, Italian, Spanish, Polish. + + +v10.00 changes : +- Disable access to Battle.net via main menu button. +- PlugY works for 1.13c version of LoD too. +- Fix shortcut in start menu + + +v9.00 changes : +- PlugY works for 1.12 version of LoD too. +- Fix somes bugs. +- Add option for unassign skill for mods. + + +v8.00 changes : +- Easier installation : New installer. +- Can open Cow Level Portal even when player have kill the Cow King in that difficulty. +- Display the real version of LoD in the main screen. (v 1.09d or v 1.11b instead of v 1.09 or v 1.11) +- Add the possibility to move the unassign skills button like stash buttons. (for modders) +- Fix crash when meeting a superunique monsters in Lod v1.11. +- Fix skills points lost when unasssign them in mods with special skills. +- Multiplayer : Save stash files (with client's data like version before 5.00) when a deconnection or error happend during saving process. +- Remove the "check load memory failed" message when D2gfx.dll was patched. + + +v7.01b changes : +- Fix the ladder only runewords features in versions 1.11 and 1.10 of LoD. +- Fix wierd characters in some text. + + +v7.01 changes : +- Enabled the ladder only runewords out of realms. +- Fixed Uber Baal AI. +- Remove all param options set by default in PlugY.ini (like windowed mode). +- Display the stats current value (without magical bonus) even when stats unasisgnment are disabled. +- Add an executable to launch PlugY (no more LoD's files modified) (RECALL) +- Translation into spanish and polish. + + +v7.00 changes : +- PlugY works for 1.11b version of LoD too. +- Add an executable to launch PlugY (no more LoD's files modified) +- Add base value for each stat on assign buttons overtext. +- Fix infinity stat bugs during unassignation. +- Fix features which stayed enabled on Battle.net. +- Translation into italian. + + +v6.01b changes : +- Bug fix with the display of popup on stat assignment buttons. + + +v6.01 changes : +- Major fix : unique carry1 items don't disappear when they are cubbed in LoD 1.10 +- Keys and Uber organs aren't destroyed when we try to open a Red Porpal out of Harrogath. +- Fix conflict with D2Mod for the version display. + + +v6.00 changes : +- PlugY works for 1.11 version of LoD too ! +- Enabled Uber Quest off realm (LoD 1.11 only). +- Fixed crash on PlugY launch if LoD install isn't clean +- Fixed some minor bugs and added some minor improvements. +- Added command "/save" to save the game without exit (LoD 1.11 only). + + +v5.06 changes : +- Added buttons for shared gold. +- Enabled shared gold in multiplayer. +- Command "/DisplayLifeMana" is replaced by "/dlm". +- Fixed some bugs. + + +v5.05 changes : +- Fixed bad default color in interface stats. +- Added Shared gold via commands. +- Command "/DisplayLifeAndMana" is now "/DisplayLifeMana". +- Display green set item name in popup when it's in the shared stash. +- Fixed multiplayer bugs by redoing multiplayer procedure. + + +v5.04 changes : +- Fixed : Stat/Skill points per level-up bug. +- Fixed : Multiplayer bugs. +- PlugY/PlugYDefault.ini completed. + + +v5.03 changes : +- Fixed : Bug which sometimes swaps Hardcore and Softcore shared stash. +- Added color on extra stats page. +- Changed default values on extra stats page. +- Set EnabledTXTFilesWhenMSExcelOpenIt=1 in PlugY.ini file. + + +v5.02 changes : +- Fixed : Previous bug fix which caused items to disappear. + + +v5.01 changes : +- Fixed : Major bugs in stash management. +- Fixed : Set back PlugY.ini with ActiveLogFile=0 by default. +- Fixed : bug when shared stash is disabled. + + +v5.00 changes : +- PlugY works for 1.09, 1.09b, 1.09d versions of LoD, including mods based on these releases ! +- PlugY can load D2Mod.dll. +- D2 can load all files, even those openned with Microsoft Excel. +- World Event monster can be changed. +- Some stuff for modders. +- Fixed : major bugs in Multiplayer : fingerprints reset, unidentified bugged items, etc. +- Fixed : Typo error in PlugY.ini (Commands). +- Fixed : No more case sensitive commands in game. +- Fixed : Select Main Stat page bug on opening +- Fixed : Replaced the display "Critical Strike/Deadly Strike" with Deadly Strike only. +- Fixed : The spawn of DiabloClone at starting of a new game +- Fixed : Some other small bugs. + + +v4.04 changes : +- Fixed : Display bug when statPerLevelUp enabled. +- Fixed : Bug in saving procedure when the disk is full. +- New configuration system for modders. +- Always display Mana and Life values above the globes. + + +v4.03 changes : +- Fixed : "carry 1" unique item (unique charm) when we drop the cube. +- Can go directly to first or last page of stash (shift + click on next/previous). +- Second index added (shift + click on index buttons) +- Added data to extra stats pages (2 pages now). +- Added previous page button in main stats page (only in 800x600). +- Moved buttons in extra stats pages to same place as in main stats page (only in 800x600). +- Can choose whether the main (first) page or the last selected page is displayed on opening the stats page. + + +v4.02b changes : +- Fixed : Features stay enabled in open Battle.net + + +v4.02 changes : +- Fixed : No more conflict with Battle.net (BigStash disabled on realms) +- Fixed : Missing "d" in "SeparateHardcoreStash=1" from PlugY.ini +- Fixed : By default in PlugY.ini, the language isn't changed. +- Fixed : Item level display enabled correctly for all configurations of PlugY. +- Added data in the extra stats page. + + +v4.01 changes : +- Fixed : NbPlayers always set to 8 when active. +- Added data in the extra stats page. + + +v4.00b changes : +- Fixed : MSVCR70.dll not found bug. + + +v4.00 changes : +- Better optimization of the code. +- Added some pages for displaying more characters stats like %MF. +- Change the selected language (and for mod, default and available language). +- Always regenerate maps in SinglePlayer like in MultiPlayer. +- Automatically execute /players X when you launch a new game. +- Display item level in its popup. +- Separate hardcore and softcore shared stash. +- Change installation method (can be installed directly on linux now) +- The item which triggers the World Event can be changed. +- Any number of "carry 1 item" (like annihilus) can be put in the stash. +- Fixed : Cannot put more than one "carry 1 item" in others page than stash. +- Fixed : display bug of socketed items in the stash. +- Fixed : removed space bug in PlugY.ini. +- Fixed : Diablo Clone can't spawn in normal and nightmare difficulty. +- Fixed : Destruction of extra minions after unassignment if you have +x bonus to the skill. + + +v3.02 changes : +- Fixed : Change the number of stats points gained when player gains a level. +- Fixed : When the shared stash is disabled, you can load a game with your character. +- Fixed : You can change parameters of World Event without activating skill per level up. + + +v3.01 changes : +- Change the number of stats points gained when player gains a level. +- Fixed bugs which give extra points when skills points are unassigned. +- Added parameters for the WorldEvent in configuration file. +- By default, World Event only SHOWS "X SOJ Sold" in hell difficulty. + + +v3.00 changes : +- Local World Event for singleplayer and multiplayer off-realm ! +- Unassign assigned skills points. +- New background for the stash. +- Can change the filename of the shared savefile. +- Shared stash page number display are in red now. + + +v2.05 changes : +- major fix : bugs which cause D2 not to start are finally removed. + + +v2.04 changes : +- Unassign stats points, skills on level up are disabled when you connect to realm (like stash). +- Open a error message box instead of crash when PlugY.dll isn't found by D2. +- Fixed some bugs in installation method. +- Fixed bug display of buttons. +- Fixed win95/98/Me saving. + + +v2.03b changes : +- Show PlugY version only in main screen. + + +v2.03 changes : +- Major fix : Correct and secure the saving procedure. +- No more crash of the host game when a character is unable to enter the game. +- Unassign stats points button greyed when base stat is above 255 fixed. +- Change version printing on main screen (change color & PlugY version in right corner) +- Character without PlugY can join game host with PlugY enabled. + + +v2.02 changes : +- PlugY doesn't use D2win.dll to launch PlugY anymore. +- PlugY includes a patcher/unpatcher for editing D2gfx.dll to launch PlugY. +- PlugY can be launched by D2Mod system of SVR. +- The infinite storage sytem is automatically disabled on a realm game. +- Fixed index button bugs. + + +v2.01 changes : +- Fixed skill per level up bug +- Fixed bug display of text in the main menu + + +v2.00 changes : +- Localized in German. +- Change the number of Skills points gained when player gains a level. +- Launch any number of Diablo II game on the same computers. +- You can unassign Stats points. +- Added 2 buttons for jumping to index page. +- Print the current stash instead of Gold max. (Gold max value is a current Gold field popup) +- Complety re-done the configuration file. +- Configuration file can be put in mpq (like other PlugY images files) +- Increased compatibility with mods. +- Removed the TCP/IP crash. +- Removed page number bug when you switch between characters. +- Removed set item's bug display. +- Removed the bug of "carry 1" +- Add other small improvements... :) + + +v1.03 changes : +- Added French readme and ini files. +- Removed bugs in D2Classic game (there is no multipage, it's not a bug) +- Removed the bug when loading character from previous version. + (like ShadowMaster character or 1.09 or D2Classic character) +- Removed the bugged line in the text when you click on delete character. +* must read : You can start any mods without moving SAVES files + (you need to move dll files with classic script). + + +v1.02 changes : +- Re-changed name files due to an IE bug with colon in zip file. +- Ability to change the version text print in the main menu (see ini file). + + +v1.01 changes : +- Localized for french version (wait for an french readme.txt) +- Changed filename from "PlugY, The Survival Kit.ini" to "PlugY,The_Survival_Kit". +- Added example for installation in the readme. +- Detection of bad installation on starting plugY. +- Removed from the ini default file the [GENERAL]PlugYDirectory=PlugY\ +(you can add it if you want but need to know what are you doing...) +- Released in .zip file instead of .rar + + +v1.00 features (can all be easily enabled or disabled) : +- You can change the save path directory. +- You can start any mods without moving saves files. +- You can increase the stash to 10x10 squares. +- Up to 4,294,967,296 pages in the stash (e.g. infinite storage space) ! + note : for LOD1.10 character only. +- Any of these pages can be shared by all of your characters! + + + +******** CONTENTS ******** +19 files, 1 folder : +- PlugY_The_Survival_Kit_-_Readme.txt +- PlugY_The_Survival_Kit_-_LisezMoi.txt +- PlugY_The_Survival_Kit_-_Liesmich.txt +- PlugY.exe +- PlugY.dll (in Diablo II directory) +- PlugY.ini +- PlugY\PlugYFixed.ini +- PlugY\PlugYDefault.ini +- PlugY\EmptyPage.dc6 +- PlugY\SharedGoldBtns.dc6 +- PlugY\StashBtns.dc6 +- PlugY\TradeStash.dc6 +- PlugY\StatsBackground.dc6 +- PlugY\UnassignSkillsBtns.dc6 +- PlugY\UnassignStatsBtns.dc6 +- PlugY\statsinterface.txt +- PlugY Uninstaller.exe (with uninstaller option) +- PatchD2gfxDll.exe (in Diablo II directory with Patcher D2gfxDll option) +- RestoreD2gfxDll.exe (in Diablo II directory with Patcher D2gfxDll option) + + + +******** INSTALLATION ******** +- The officials sites are : +http://djaftal.chez-alice.fr/ +http://phrozenkeep.18v.biz/dload.php?action=category&cat_id=128 +http://diablo2.judgehype.com/index.php?page=telechargements + + +Normal Installation : +- Follow directive installer. + +note : You can choice "Diablo II" directory as install directory. + +Installation in another mod: +- Copy PlugY.ini, PlugY.exe and PlugY folder (+its contents) in the targeted mod folder. +- Edit PlugY.ini to configure some features (see section below). +- Run PlugY.exe and enjoy :) + +note : you can move the "PlugY" folder in "Diablo II" and it will be see by all PlugY installation. + +Example : +You have installed Lord of Destruction here : C:\Games\Diablo II\ +And the mod to add this plug-in is here : D:\D2Mod\MyMod\ +And the second mod to add this plug-in is here : D:\D2Mod\MyMod2\ +So the new installation is : + C:\Games\Diablo II\PlugY.dll + D:\D2Mod\MyMod\PlugY\SharedGoldBtns.dc6 + D:\D2Mod\MyMod\PlugY\PlugYFixed.ini + D:\D2Mod\MyMod\PlugY\PlugYDefault.ini + D:\D2Mod\MyMod\PlugY\EmptyPage.dc6 + D:\D2Mod\MyMod\PlugY\SharedGoldBtns.dc6 + D:\D2Mod\MyMod\PlugY\StashBtns.dc6 + D:\D2Mod\MyMod\PlugY\TradeStash.dc6 + D:\D2Mod\MyMod\PlugY\StatsBackground.dc6 + D:\D2Mod\MyMod\PlugY\UnassignSkillsBtns.dc6 + D:\D2Mod\MyMod\PlugY\UnassignStatsBtns.dc6 + D:\D2Mod\MyMod\PlugY\statsinterface.txt + D:\D2Mod\MyMod\PlugY.ini + D:\D2Mod\MyMod\PlugY.exe + D:\D2Mod\MyMod2\PlugY\SharedGoldBtns.dc6 + D:\D2Mod\MyMod2\PlugY\PlugYFixed.ini + D:\D2Mod\MyMod2\PlugY\PlugYDefault.ini + D:\D2Mod\MyMod2\PlugY\EmptyPage.dc6 + D:\D2Mod\MyMod2\PlugY\SharedGoldBtns.dc6 + D:\D2Mod\MyMod2\PlugY\StashBtns.dc6 + D:\D2Mod\MyMod2\PlugY\TradeStash.dc6 + D:\D2Mod\MyMod2\PlugY\StatsBackground.dc6 + D:\D2Mod\MyMod2\PlugY\UnassignSkillsBtns.dc6 + D:\D2Mod\MyMod2\PlugY\UnassignStatsBtns.dc6 + D:\D2Mod\MyMod2\PlugY\statsinterface.txt + D:\D2Mod\MyMod2\PlugY.ini + D:\D2Mod\MyMod2\PlugY.exe + + +Uninstallation : Use the uninstaller or if you have check this option, simply remove all PlugY files ! +Note : You can also move PlugY.dll in the mod folder but you must remove any on in D2 folder. +Note : PlugY directory and its contents can be put in a mpq. + +------- D2gfx Patcher : + +If you have problem when you run PlugY.exe then use PatchD2gfxDll.exe. (It happend sometimes with Windows 2000) +- Go in Diablo II directory. +- Do a backup of D2gfx.dll (in the case, you remove PlugY before restore it) +- Run PatchD2gfxDll.exe (which patches D2gfx.dll for launch PlugY) +- Create a shortcut : Enter target mod directory in "start in" field of properties->shortcut. (unless you install PlugY in Diablo II directory) +- Launch with the shorcut !! + +Before uninstall PlugY Restore your D2gfx.dll with your backup file or run RestoreD2gfxDll.exe. + + + +******************** FAQ ****************** + +=> I can't find the PlugY.ini file, where is it ? +>From kingpin : +Microsoft has in their OS hidden known extensions. This is to make sure newbie +users do not delete those files by accident. You can, of course, turn this off by +opening up your Windows Explorer, selecting Tools->Folder Options. Then choose View and +mark "Show Hidden files and Folders". Unmark "Hide extensions for know file types". +Then you will for sure see the ini file. + + +=> How do I Play sometimes on Battle.net when PlugY is installed ? +PlugY automatically disables features on realm. +But it's always recommended to disable any third software when you go on realm. +Note : When bigStash is enabled, you must restart D2 for play in single/multi/open after playing in closed Bnet (and vice versa). +Tips : Make a shorcut and add -skiptobnet at the of the "target" field for directly go to Battle.net. + + +=> What do I do if I have an error like "Bad Generic File" on loading a new Character ? +This can appear when you have bad item in the shared stash file. +A possible cause is to use same save folder for different mod, in this case just change the save folder in PlugY.ini. +You can also move the _LOD_SharedStashSave.sss and _LOD_HC_SharedStashSave.sss to another directory. + + +=> I get "sUnitItemInsertItemInvGridBase failed at 1046 in C:\projects\D2\head\Diablo2\Source\D2Client\UNIT\Item.cpp" in D2YYMMDD.txt, what I should do ? +It's just a warning, don't worry about it, it causes no problem in game. + + +=> I have another bug, what should I do ? +1) Read my thread and post a question eventually in PhrozenKeep member annoucement forum. + +2) Search on google, ask to your friend, etc but don't ask me, I have no more time to support PlugY. +If one day, I got enough time (like for the version 8.00) I will check forums to get the more commons problems. + +Thx + + +******** CONFIGURATION ******** + +Configuration of this kit for a specified mod : +- Copy the PlugY.ini and PlugY.exe in the target mod directory (the directory where you start it, see it in the properties of the shortcut). +- In most cases, you will change the save directory in the ini file. +- Add all extra dll of the mod in PlugY.ini, if any. +- Finally, activate any specific features you want such as MultiPageStash, SharedStash, etc. +- Now, you can start the target mod using the classic method. + +D2Mod configuration : +Just add the dll name in PlugY.ini, for example : "DllToLoad=D2Mod.dll" + +Note: +- Items in the Cube are always saved on the player, if you want these items shared, you must remove them from the Cube. + +Warning : +- Be careful if you want to edit the configurations files after having played with the mod. +- In multiplayer game, verify that the server has the same configuration. +- Remember : PlugY doesn't support realms. + + + +*** Configuration for modders *** +There are 3 files with same structure to configure PlugY : +- "PlugY/PlugYFixed.ini" in mpq or via the switch -direct +All fields set parameters which can't be changed by users via PlugY.ini. +Use it for enabling(disabling) wanted(unwanted) features. +Only few thing should be found here. +Warning 1: ActivePlugin=0 doesn't work here (but ActivePlugin=1 works) +Warning 2: SavePath management doesn't work here too. +Warning 3: Don't abuse it, a lot of field should be set by users. (see note below) + +- "PlugY/PlugYDefault.ini" in mpq or via the switch -direct +Use it for changing default values of PlugY. +Works like PlugY.ini in an mpq in version 4.03 and before. +All fields which aren't in PlugYFixed.ini (and are always readed) should be here. +Most fields should be put here. + +- "PlugY.ini" in current directory only. +For users' configuration (like previous version). +Fields which are in PlugYFixed.ini shouldn't be found here. +In most cases, this file is the same as PlugYDefault.ini but it can be edited by user. + +Notes: +Think about each features if you really must disable it. +- The savepath management doesn't work in Fixed.ini (it's users' choice where they want to put their save files) +- The unassignment of skills can really be useful way to learn all your custom skills. I have stopped playing some mods just because I don't know what skill will be useful at very high level. It's more fun to try all skills and do the choosing after that. So don't put it in Fixed.ini +- The World Event should be configured or disabled in Fixed.ini in each mod. +- The extra pages in stats interfaces shouldn't be put in Fixed.ini + +Modders can contact me, if they want help or more details about this system. + +WARNING : Don't forget, if it's misused, players will use old version of PlugY, and I will have no other choice than to disable it. + + + +******** COMMENTS ON THE CONFIGURATION FILE ******** + +All Default values mean, if you remove the line, PlugY will use this value. +The values in PlugY.ini (included in the zip) are an example of configuration, not default values. + +[LAUNCHING] +This section store info for PlugY.exe and don't work in PlugYDefault.ini and PlugYFixed.ini files. + +Add params to transmit to LoD on his command line. +Params give to PlugY.exe are also transmitted to LoD on his command line. +By default no param are trasmited. +Most common switch are (without quote) : +"-w" open LoD in windowed form. +"-direct" use files in directory instead of those in mpq. +"-txt" recompile txt files before launch a game. +Following are default values, between {} are some examples values with descriptions : +Param= {-direct -txt -w: these 3 commands are passed on the command line} + + +Select the library to load. +The current directory are the one used by D2 (like set the "start in" field of a shorcut). +If no library specify, it load LoD without PlugY. +Following are default values, between {} are some examples values with descriptions : +Library= {PlugY.dll: Load PlugY.dll} + + +[GENERAL] +Enable or disable all selected features. +Dlls from field "DllToLoad" aren't loaded anymore when ActivePlugin=0. +Following are default values, between {} are some examples values with descriptions : +- ActivePlugin=0 {0:Don't load any features; 1:Plugin enabled} + +Enable or disable BattleNet Access. +Following are default values, between {} are some examples values with descriptions : +- DisableBattleNet=1 {0:Battle.net access enable; 1:Battle.net access disable} + +Create a log file "PlugY.log" in the current directory. +This feature can slow down your game. +Following are default values, between {} are some examples values with descriptions : +- ActiveLogFile=0 {0:No information is written while playing; 1:Always enabled} + +Load dll of a specific mod for used PlugY in same time. +Separate each dll file name by the character pipe (|) +Following are default values, between {} are some examples values with descriptions : +- DllToLoad= {(empty): load nothing; D2extra.dll|myDll.dll: Load both D2extra.dll and myDll.dll} +- DllToLoad2= {(empty): Same as DlltoLoad} + +Activate a new command in PlugY. In parenthesis is the condition to be able to use the command. +"/dlm" toggle the state of AlwaysDisplayLifeAndManaValues (AlwaysDisplayLifeAndManaValues>0) +"/page x" Go to the page x in the extra stats page. +"/save" Save the game without exit (LoD 1.11 and 1.11b only). +- ActiveCommands=0 {0:Disabled; 1:Enabled} + +Quit D2, if PlugY failed to installed all features. +Disable it only if you know what you do. +- ActiveCheckMemory=1 + +Activate hidden or not-finished feature. (don't use it) +- ActiveAllOthersFeatures=0 {0:Disabled; 1:Enabled} + + +[LANGUAGE] +Change the selected language. +You must have files of the selected language. +All D2/LoD versions contain the english language (except voices). +All possibles languages: ENG|ESP|DEU|FRA|POR|ITA|JPN|KOR|SIN|CHI|POL|RUS +- ActiveChangeLanguage=0 {0:Disabled; 1:Enabled} +- SelectedLanguage=ENG {FRA: Select French as language} + +For modders who want to restrict the available languages and the default language : +- ActiveLanguageManagement=0 {0:Disabled; 1:Enabled} +- DefaultLanguage=ENG {empty:D2 default language; FRA:French is the default language} +- AvailableLanguages=ENG|ESP|DEU|FRA|POR|ITA|JPN|KOR|SIN|CHI|POL|RUS {ENG|FRA} + + +[SAVEPATH] +This is where all of your characters and the shared stash is saved. +You can use absolute or relative paths. +Following are default values, between {} are some examples values with descriptions : +- ActiveSavePathChange=0 {0:Disabled; 1:Enabled, you must set "SavePath"} +- SavePath=Save\ {Save\MyMod\ or D:\Save Games\diablo II\Current Mod\} + + +[MAIN SCREEN] +Change the version text in the main menu (first menu)(instead of "v 1.10") +Color is an integer which refers to defined D2 colors. +Following are default values, between {} are some examples values with descriptions : +- ActiveVersionTextChange=0 {0:Disabled; 1:Enabled} +- VersionText= {Empty: Display the current version of LoD with the subversion letter (1.11b, 1.09d) ; Mod Name:Text with maximum length of 23 characters (ex : v 1.11b)} +- ColorOfVersionText=0 {0:white; 1:red; 4:gold; etc.} +- ActivePrintPlugYVersion=1 {0:Disabled; 1:Enabled) +- ColorOfPlugYVersion=4 {0:white; 1:red; 4:gold; etc.} + + +[STASH] +Increase the stash to 10x10 squares. +Use PlugY\TradeStash.dc6 to change the background image. +When bigStash is enabled, you must restart D2 for play in single/multi/open when you have started a game in closed Bnet previously (and vice versa). +Following are default values, between {} are some examples values with descriptions : +- ActiveBigStash=0 {0:Default stash size is used; 1: Enabled, Stash uses 10x10 squared} + +Use this for sharing and keep all of your items. :) +There are 2 multipage stashes : +- one Personal, only seen by the Player; +- one Shared between your Players in this mod. +Use the Toggle Button to switch between stash. +Use arrow buttons on bottom the stash (and shift key) for switching between the pages. +Definition : The last page is the last page with an item in it. +The multipage stashes are inactive for Diablo II Classic Character and on realm. +You can change the name of the shared filename. +Following are default values, between {} are some examples values with descriptions : +- ActiveMultiPageStash=0 {0:Disabled; 1:Enabled} +- NbPagesPerIndex=10 {10: Index page is 1,10,20,30,...,max} +- NbPagesPerIndex2=100 {100: Index page (+shift) is 1,50,100,150,...,max} +- MaxPersonnalPages=0 {0:Infinite number of personnal pages; 1000: Maximum of 1000 shared pages} +- ActiveSharedStash=0 {0:Disabled; 1:Enabled if ActiveMultiPageStash=1} +- SeparateHardcoreStash=1 {0:Same shared stash for HC and SC; 1:Use 2 differents stashes} +- SharedStashFilename=SharedStashSave {xxx: The filename will be "_LOD_xxx.sss"} +- displaySharedSetItemNameInGreen=1 {0:Disabled; 1:Enabled, set items in stash are their name displayed in green on other sets items.} +- MaxSharedPages=0 {0:Infinite number of shared pages; 5000: Maximum of 5000 shared pages} +- ActiveSharedGold=1 {0:Disabled; 1:Use command to put and take gold (see command section)} +- PosXPreviousBtn=-1 {-1: Default position, 50: Put the button at the position 50 in absiss} +Same for PosYPreviousBtn, PosXNextBtn, PosYNextBtn, PosXSharedBtn, PosYSharedBtn, PosXPreviousIndexBtn, PosYPreviousIndexBtn, PosXNextIndexBtn, PosYNextIndexBtn, PosXPutGoldBtn, PosYPutGoldBtn, PosXTakeGoldBtn, PosYTakeGoldBtn. + + +[STATS POINTS] +Use for repairing a bad stat point assignment. +For example, 30 points in energy for a barbarian! +On the character stat page, press selected key and click on minus button. +Select a key by setting KeyUsed (should choose 17 or 18). +Following are default values, between {} are some examples values with descriptions : +- ActiveStatsUnassignment=0 {0:Disabled 1:Enabled, press selected key when clicking} +- KeyUsed=18 {17:Control key selected; 18:Alt key selected} + +Use the shift buton for assigning/unassigning all possible points in one click. +You can define a limit value for points assigned/unassigned with shift. +Following are default values, between {} are some examples values with descriptions : +- ActiveShiftClickLimit=0 {0:Disabled; 1:Enabled} +- LimitValueToShiftClick=5 (10:Assign or unassign stats points, 10 by 10} + + +[STAT ON LEVEL UP] +Change the number of Stats Points you receive when your character gains a level. +Following are default values, between {} are some examples values with descriptions : +- ActiveStatPerLevelUp=0 {0:Disabled; 1:Enabled} +- StatPerLevelUp=5 {0:no points win; 11:eleven points win} + + +[SKILLS POINTS] +Use for repairing a bad skill point assignment. +Click on the button on skill page for unassigning all assigned skills points. +Note : It verifies the real cost of each skill (can be greater than 1 in mod) +Warning : There are few place where you can put this button without bugs. +Following are default values, between {} are some examples values with descriptions : +- ActiveSkillsUnassignment=0 {0:Disabled; 1:Enabled} +- ActiveSkillsUnassignmentOneForOne=0 {0:Normal; 1:Force the skill unassign 1 for 1 (for mods).} +- PosXUnassignSkillBtn=-1 {-1: Default position, 50: Put the button at the position 50 in X} +- PosYUnassignSkillBtn=-1 {-1: Default position, 50: Put the button at the position 50 in Y} + + +[SKILL ON LEVEL UP] +Change the number of Skills Points you receive when your character gains a level. +Following are default values, between {} are some examples values with descriptions : +- ActiveSkillPerLevelUp=0 {0:Disabled; 1:Enabled} +- SkillPerLevelUp=1 {0:no point gained; 3:three points gained) + + +[WORLD EVENT] +Activate the World Event in local game. +World Event only triggers in hell difficulty and only one time per game. +If the WE triggers when you aren't in the game, you lose it. +From the moment you launch D2, the next WE will trigger between few seconds to 41:40 hours after. +Keep in mind before editing it, World Event should be triggered rarely. +The item to sell can be changed, the value expected is same as the cube input field. +Following are default values, between {} are some examples values with descriptions : +- ActiveWorldEvent=0 {0:Disabled; 1:Enabled} +- ShowCounterInAllDifficulty=0 {0:Show it "SOJ Sold" message only in Hell; 1:Show it in all difficulties} +- ItemsToSell=The Stone of Jordan {r01: rune EL; cap,rar,upg: Any cap/war hat/shako rare} +- MonsterID=333 {333: DiabloClone spawned} +- OwnSOJSoldChargeFor=100 {100:When you sell a SOJ, the SOJ counter is incremented by 100} +- InititalSOJSoldMin=200 {200:The SOJ counter is set at least to 20 when you launch D2} +- InititalSOJSoldMax=3000 {3000:The SOJ counter is set at most to 300 when you launch D2} +- TriggerAtEachSOJSoldMin=75 {75:Need to have at least 75 SOJ sold between 2 World Event} +- TriggerAtEachSOJSoldMax=125 {125:Need to have at most 125 SOJ sold between 2 World Event} +- ActiveAutoSell=1 {0:Disabled; 1:SOJ counter is automatically incremented by 1} +- TimeBeforeAutoSellMin=0 {50:Need at least 50 seconds between 2 auto-increments} +- TimeBeforeAutoSellMin=1200 {1200:Need at most 20 minutes (1200 seconds) between 2 auto-increments} + + +[UBER QUEST] +Activate the Uber Quest in local. +It works only in Hell. +You must cube the 3 keys then the 3 organs in Harrogath. +Note : This quest will be updated more later to be more similar with the one on realm. +ActiveUberQuest=0 {0:Disabled; 1:Enabled} + + +[INTERFACE] +Add extra page for displaying some stats. +Can choose if the main (first) page or the last selected page is displayed on opening the stats page. +You can change the the stats displayed via the PlugY\statsinterface.txt file (open it with MS Excel). +There is no max page limit. +Can choose whether to display the background of buttons (Use when a mod already changes background). +- ActiveNewStatsInterface=0 {0:Disabled; 1:Enabled} +- SelectMainPageOnOpenning=1 {0:Last selected page displayed; 1:Main page displayed} +- PrintButtonsBackgroundOnMainStatsPage=1 {0:Don't display the background; 1:display it} + + +[EXTRA] +You can run any number of Diablo II games on one computer. +For example, modder can test multiplayer game for their mod. +To start the second game, you must start it with "game.exe" and not "Diablo II.exe". +Warning : Don't start games with the same savepath when you use the Shared Stash. + Don't use the same character in same time. +Following are default values, between {} are some examples values with descriptions : +- ActiveLaunchAnyNumberOfLOD=0 {0:Disabled; 1:Enabled} + +Regenerate the map each time you re-start a game (like in multiplayer). +- AlwaysRegenMapInSP=0 {0:Disabled; 1:Enabled} + +Set the number of players (like /players x) each time you start a game. +- NBPlayersByDefault=0 {0:Disabled; 1:Set the game to 1 player (normal); 8:Set the game to emulate 8 players (maximum)} + +Show the level of each item in their popup. +- ActiveDisplayItemLevel=0 {0:Disabled; 1:Enabled} + +Always display Mana and Life values above the globes. +- AlwaysDisplayLifeAndManaValues=0 {0:Disabled; 1:Enabled; 2:Disabled but can be enabled by command} + +Fix the bug which blocks the opening of txt files when they are opened by Miscrosoft Excel. +- EnabledTXTFilesWhenMSExcelOpenIt=0 {0:Disabled; 1:Enabled} + +Display the stats current value (without magical bonus) when mouse pass over assignment buttons. +- ActiveDisplayBaseStatsValue=0 {0:Disabled; 1:Enabled} + +Enabled the ladder only runewords out of realms. +This is done by setting to 0 the column "server" in runes.txt file. +So don't use this column in your mod with this funcion enabled ! +- ActiveLadderRunewords=0 {0:Disabled; 1:Enabled} + +Enabled the ability to open the Cow Portal in a difficulty where the player have already killed the Cow King. +- ActiveCowPortalWhenCowKingWasKilled=0 {0:Disabled; 1:Enabled} + + +More features later... :) + + +This is my email : ynicolas@worldonline.fr. +But I don't support PlugY anymore so don't hope any help from me if you have problems. Instead go on forums... + + +PS : Sorry for english faults ;) + +******** THANKS TO ******** +- Blizzard for making Diablo2 and Lord of Destruction. +- Kingpin, Afj666, Joel, SVR, Myrdinn for their great help. +- Pralinor fo his help in the convertion to 1.12. +- ChaosEnergy for testing and his translation in German. +- Char & Darque in the correction of my english. +- Shaitane, K&V, themastercaster, raspa and onyx for testing. +- Golvmopp, Dark Spot in the Corner, Megalixir and Athara for their help. +- ItalianPlayer for italian translation. +- All members of ProzenKeep chat and forums for their information and feedback. +- PhrozenKeep team for all stuff they shared for us (including mine ;) +- Translation : + * English : Yohann, Jurica. + * French : Yohann + * German : ChaosEnergy, TheMasterCaster. + * Italian : ItalianPlayer + * Spanish : Acrerune + * Polish : Serdel + ~~~~~~~~~~~~ \ No newline at end of file diff --git a/PlugYRun/PlugY.ico b/PlugYRun/PlugY.ico new file mode 100644 index 0000000..81168cc Binary files /dev/null and b/PlugYRun/PlugY.ico differ diff --git a/PlugYRun/PlugY32.ico b/PlugYRun/PlugY32.ico new file mode 100644 index 0000000..4ca5f13 Binary files /dev/null and b/PlugYRun/PlugY32.ico differ diff --git a/PlugYRun/PlugY48.bmp b/PlugYRun/PlugY48.bmp new file mode 100644 index 0000000..0d7b8f2 Binary files /dev/null and b/PlugYRun/PlugY48.bmp differ diff --git a/PlugYRun/PlugY64.bmp b/PlugYRun/PlugY64.bmp new file mode 100644 index 0000000..76c4553 Binary files /dev/null and b/PlugYRun/PlugY64.bmp differ diff --git a/PlugYRun/PlugYRun.aps b/PlugYRun/PlugYRun.aps new file mode 100644 index 0000000..c472084 Binary files /dev/null and b/PlugYRun/PlugYRun.aps differ diff --git a/PlugYRun/PlugYRun.cpp b/PlugYRun/PlugYRun.cpp new file mode 100644 index 0000000..4b0552d --- /dev/null +++ b/PlugYRun/PlugYRun.cpp @@ -0,0 +1,658 @@ +/* + File created by Yohann NICOLAS. +*/ +#include +#include +#include +//#using +//#using +//using namespace EnvDTE; +//using namespace System; +//using namespace System::Diagnostics; +//using namespace System::ComponentModel; +//using namespace System.Diagnostics; +/* +0012C458 00000000 |ModuleFileName = NULL +0012C45C 0012C908 |CommandLine = ""C:\Jeux\Diablo II\Game.exe"" +0012C460 00000000 |pProcessSecurity = NULL +0012C464 00000000 |pThreadSecurity = NULL +0012C468 00000000 |InheritHandles = FALSE +0012C46C 04000022 |CreationFlags = DEBUG_ONLY_THIS_PROCESS|NORMAL_PRIORITY_CLASS|CREATE_DEFAULT_ERROR_MODE +0012C470 00000000 |pEnvironment = NULL +0012C474 0012DF94 |CurrentDir = "C:\Jeux\Diablo II\" +0012C478 0012C6BC |pStartupInfo = 0012C6BC +0012C47C 0012C5CC \pProcessInfo = 0012C5CC +$ ==> >44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D............... +$+10 >1A 13 03 00 08 00 00 00 14 13 04 00 00 00 00 00 ......... +$+20 >01 00 00 00 0C C7 12 00 34 87 D1 77 81 00 00 00 .....4w... +$+30 >0A 00 00 00 00 00 00 00 00 00 00 00 89 F6 D4 77 ............w +$+40 >CD AB BA DC 00 00 00 00 ͫ.... + +//0xE9,0x1C,0xD1,0xA8,0x6F +*/ + +#define SUBKEY "Software\\Blizzard Entertainment\\Diablo II" +#define GAMEFILE "\\Game.exe " +#define INIFILE "\\PlugY.ini" +#define LAUNCHING "LAUNCHING" +#define LOD_VERSION "LodVersionFolder" +#define PARAM "Param" +#define LIBRARY_NAME "Library" + +BYTE loadDll[]={ +0xFF,0x74,0x24,0x04, //PUSH DWORD PTR SS:[ESP+4] +0xFF,0x15,0x40,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryA>] ; kernel32.LoadLibraryA +0x50, //PUSH EAX +0x68,0x80,0xBE,0xA7,0x6F, //PUSH d2gfx.6FA7BE80 ; ASCII "PlugY.dll" +0xFF,0x15,0x40,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryA>] ; kernel32.LoadLibraryA +0xA3,0xFC,0xEF,0xA8,0x6F, //MOV DWORD PTR DS:[6FA8EFFC],EAX +0x85,0xC0, //TEST EAX,EAX +0x74,0x2F, //JE SHORT d2gfx.6FA7BE37 +0x50, //PUSH EAX +0x68,0x90,0xBE,0xA7,0x6F, //PUSH d2gfx.6FA7BE10 ;Init String +0x50, //PUSH EAX +0xFF,0x15,0x3C,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.GetProcAddress>] ; kernel32.GetProcAddress +0x85,0xC0, //TEST EAX,EAX +0x74,0x04, //JE SHORT d2gfx.6FA7BDC1 +0x6A,0x00, //PUSH 0 +0xEB,0x13, //JMP SHORT d2gfx.6FA7BDC1 +0x68,0x10,0x27,0x00,0x00, //PUSH 2710 ;Init Ordinal(10000) +0xFF,0x74,0x24,0x04, //PUSH DWORD PTR SS:[ESP+4] +0xFF,0x15,0x3C,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.GetProcAddress>] ; kernel32.GetProcAddress +0x85,0xC0, //TEST EAX,EAX +0x74,0x02, //JE SHORT d2gfx.6FA7BDC1 +0xFF,0xD0, //CALL EAX +0x58, //POP EAX +0x58, //POP EAX +0xC2,0x04,0x00, //RETN 4 +0x59, //POP ECX +0xB9,0x80,0xBE,0xA7,0x6F, //MOV ECX,d2gfx.6FA7BE80 ; ASCII "PlugY.dll" +0x83,0x04,0x24,0x10, //ADD DWORD PTR SS:[ESP],10 +0xC2,0x04,0x00, //RETN 4 +0x00,0x00,0x00,0x00}; //HANDLE var; + + +BYTE freeDll[]={ +0xFF,0x74,0x24,0x04, //PUSH DWORD PTR SS:[ESP+4] +0xFF,0x15,0x48,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] ; kernel32.FreeLibrary +0x50, //PUSH EAX +0xA1,0xFC,0xEF,0xA8,0x6F, //MOV EAX,DWORD PTR DS:[6FA8EFFC] +0x85,0xC0, //TEST EAX,EAX +0x74,0x2D, //JE SHORT d2gfx.6FA7BE74 +0x50, //PUSH EAX +0x68,0xA0,0xBE,0xA7,0x6F, //PUSH d2gfx.6FA7BE20 ;Release String +0x50, //PUSH EAX +//0x33,0xC0, //XOR EAX,EAX +//0xA3,0xFC,0xEF,0xA8,0x6F, //MOV DWORD PTR DS:[6FA8EFFC],EAX +0xFF,0x15,0x3C,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; kernel32.GetProcAddress +0x85,0xC0, //TEST EAX,EAX +0x75,0x13, //JNZ SHORT d2gfx.6FA7BDEF +0x68,0x11,0x27,0x00,0x00, //PUSH 2711 ;Release Ordinal(10001) +0xFF,0x74,0x24,0x04, //PUSH DWORD PTR SS:[ESP+4] +0xFF,0x15,0x3C,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; kernel32.GetProcAddress +0x85,0xC0, //TEST EAX,EAX +0x74,0x02, //JE SHORT d2gfx.6FA7BDEF +0xFF,0xD0, //CALL EAX +0xFF,0x15,0x48,0xC0,0xA7,0x6F, //CALL DWORD PTR DS:[<&KERNEL32.FreeLibrar>; kernel32.FreeLibrary +0x58, //POP EAX +0xC2,0x04,0x00}; //RETN 4 + + +//LPCSTR dllName = "PlugY.dll"; +LPCSTR initFctName = "_Init@4"; +LPCSTR releaseFctName = "_Release@0"; +static bool versionXP; + +typedef int (__stdcall* tDebugActiveProcessStop)(DWORD); +tDebugActiveProcessStop debugActiveProcessStop; + + +void assertion(LPCSTR msg) +{ + MessageBox(0, msg, "PlugYRun", MB_OK|MB_ICONASTERISK); + exit(1); +} + +bool installPlugY(HANDLE h, DWORD addr, char* libraryName, int isAdd) +{ + BYTE buf[200]; + DWORD pos=0; + SIZE_T nb=0; + DWORD version; + int res; + + // Get Version and needed addresses. + res = ReadProcessMemory(h,(LPVOID)(addr+0x110),&version,4,&nb);//0x80 + if (!res || (nb!=4)) assertion("Read to get current d2gfx version in memory failed"); + + DWORD loadCallerAddr = addr; + DWORD freeCallerAddr = addr; + DWORD loadLibraryAddr = addr; + DWORD freeLibraryAddr = addr; + DWORD getProcAddressAddr = addr; +// GET_VERSION(D2gfx, 110, 000054EB, 00001000, 0000C000, 42E6C22A, 43028B19);//110 + switch (version) + { + case 0x000054EB://1.09b 0x00949FA8: + case 0x00001000://1.09d 0x018866A8: + loadCallerAddr += 0x389B; + freeCallerAddr += 0x3A8C; + loadLibraryAddr += 0xC03C; + freeLibraryAddr += 0xC044; + getProcAddressAddr += 0xC038; + break; + case 0x0000C000://1.10 0x401526B2 + loadCallerAddr += 0x3870; + freeCallerAddr += 0x3A6D; + loadLibraryAddr += 0xC040; + freeLibraryAddr += 0xC048; + getProcAddressAddr += 0xC03C; + break; + case 0x42E6C22A://1.11 0x575C8A5E + loadCallerAddr += 0x8B23; + freeCallerAddr += 0x8ACA; + loadLibraryAddr += 0xD11C; + freeLibraryAddr += 0xD12C; + getProcAddressAddr += 0xD120; + break; + case 0x43028B19://1.11b + loadCallerAddr += 0xB423; + freeCallerAddr += 0xB3CA; + loadLibraryAddr += 0xD11C; + freeLibraryAddr += 0xD12C; + getProcAddressAddr += 0xD120; + break; + case 0x0A07010B://1.12a + loadCallerAddr += 0x8F63; + freeCallerAddr += 0x8F0A; + loadLibraryAddr += 0xD11C; + freeLibraryAddr += 0xD12C; + getProcAddressAddr += 0xD120; + break; + case 0x00000000://1.13c + loadCallerAddr += 0xB423; + freeCallerAddr += 0xB3CA; + loadLibraryAddr += 0xD11C; + freeLibraryAddr += 0xD12C; + getProcAddressAddr += 0xD120; + break; + default: + assertion("Wrong version of the library D2gfx.dll"); + } + + //Verify if memory are ok. + bool alreadyInstalled = false; + res = ReadProcessMemory(h,(LPVOID)loadCallerAddr,buf,6,&nb); + if (!res || nb<6 ) assertion("Read memory failed for checking."); + if (buf[0]!=0xFF || buf[1]!=0x15 || *(DWORD*)(buf+2) != loadLibraryAddr) + if (buf[0]!=0xE8 /*|| buf[1]!=0xD8 || buf[2]!=0x19*/ || buf[3]!=0x00 || buf[4]!=0x00 || buf[5]!=0x90) + assertion("Checking library memory check failed."); + else + alreadyInstalled = true; + res = ReadProcessMemory(h,(LPVOID)freeCallerAddr,buf,6,&nb); + if (!res || nb<6 ) assertion("Read memory failed for checking."); + if (buf[0]!=0xFF || buf[1]!=0x15 || *(DWORD*)(buf+2) != freeLibraryAddr) + if (buf[0]!=0xE8 /*|| buf[1]!=0x75 || buf[2]!=0x1A*/ || buf[3]!=0x00 || buf[4]!=0x00 || buf[5]!=0x90) + if (!alreadyInstalled) + assertion("Checking library memory failed."); + + if (alreadyInstalled) + return true; + + //Alloc custom memory data. + DWORD memory = (DWORD)VirtualAllocEx(h,NULL,200,MEM_COMMIT,PAGE_EXECUTE_READWRITE); + DWORD oldProtect=-1; + if (!memory) + { +// MessageBox(0, "no memory", "RunPlugY.\n", MB_OK|MB_ICONASTERISK); + memory = addr + 0xBE00 + isAdd*0x1000; + if( !VirtualProtectEx(h,(LPVOID)memory, 200, PAGE_EXECUTE_READWRITE, &oldProtect) ) + assertion("Failed to get memory pool for PlugY loading."); + } + + //Make memory data + int len; + pos=0; + + //Dll name + DWORD dllNameAddr = memory+pos; + len = strlen(libraryName)+1; + res = WriteProcessMemory(h,(LPVOID)dllNameAddr,libraryName,len,&nb); + if (!res || (nb!=len)) assertion("Write custom data in memory failed"); + pos += pos%16 ? len + 16 - pos%16 : len; + + //init name + DWORD initNameAddr = memory+pos; + len = strlen(initFctName)+1; + res = WriteProcessMemory(h,(LPVOID)initNameAddr,initFctName,len,&nb); + if (!res || (nb!=len)) assertion("Write custom data in memory failed"); + pos += pos%16 ? len + 16 - pos%16 : len; + + //release name + DWORD releaseNameAddr = memory+pos; + len = strlen(releaseFctName)+1; + res = WriteProcessMemory(h,(LPVOID)releaseNameAddr,releaseFctName,len,&nb); + if (!res || (nb!=len)) assertion("Write custom data in memory failed"); + pos += pos%16 ? len + 16 - pos%16 : len; + + //load fct + DWORD loadDllAddr = memory+pos; + DWORD handleAddr = loadDllAddr + sizeof(loadDll) - 4; + *(DWORD*)&loadDll[6] = loadLibraryAddr; + *(DWORD*)&loadDll[12] = dllNameAddr; + *(DWORD*)&loadDll[18] = loadLibraryAddr; + *(DWORD*)&loadDll[23] = handleAddr; + *(DWORD*)&loadDll[33] = initNameAddr; + *(DWORD*)&loadDll[40] = getProcAddressAddr; + *(DWORD*)&loadDll[63] = getProcAddressAddr; + *(DWORD*)&loadDll[80] = dllNameAddr; + len = sizeof(loadDll); + res = WriteProcessMemory(h,(LPVOID)loadDllAddr,loadDll,len,&nb); + if (!res || (nb!=len)) assertion("Write custom data in memory failed"); + pos += pos%16 ? len + 16 - pos%16 : len; + + //free fct + DWORD freeDllAddr = memory+pos; + *(DWORD*)&freeDll[6] = freeLibraryAddr; + *(DWORD*)&freeDll[12] = handleAddr; + *(DWORD*)&freeDll[22] = releaseNameAddr; +// *(DWORD*)&freeDll[30] = handleAddr; + *(DWORD*)&freeDll[36-7] = getProcAddressAddr; + *(DWORD*)&freeDll[55-7] = getProcAddressAddr; + *(DWORD*)&freeDll[67-7] = freeLibraryAddr; + len = sizeof(freeDll); + res = WriteProcessMemory(h,(LPVOID)freeDllAddr,freeDll,len,&nb); + if (!res || (nb!=len)) assertion("Write custom data in memory failed"); + pos += pos%16 ? len + 16 - pos%16 : len; + + + //Patch load library + buf[0]=0x90; + buf[1]=0xE8; + *(DWORD*)(buf+2) = (DWORD)loadDllAddr - (DWORD)loadCallerAddr-6; + len = 6; + res = WriteProcessMemory(h,(LPVOID)loadCallerAddr,buf,len,&nb); + if (!res || (nb!=len)) assertion("Write load library in memory failed"); + + //Patch free library + *(DWORD*)(buf+2) = (DWORD)freeDllAddr - (DWORD)freeCallerAddr-6; + res = WriteProcessMemory(h,(LPVOID)freeCallerAddr,buf,len,&nb); + if (!res || (nb!=len)) assertion("Write free library in memory failed"); + +// sprintf(tmp,"mem = %08X (read = %d)",buf[0],nbRead); +// MessageBox(0, tmp, "RunPlugY.\n", MB_OK|MB_ICONASTERISK); +// if (oldProtect != -1) +// VirtualProtectEx(h,(LPVOID)memory, 200, oldProtect, &oldProtect); + return true; +} + + + + +//###########################################################################################// + + +/*bool copyLodVersionFiles() +{ + BYTE folder[MAX_PATH]; + if (!GetPrivateProfileString(LAUNCHING,LOD_VERSION,"",folder,MAX_PATH,INI_FILE)) + return true; + strcat(folder,"\\*"); + WIN32_FIND_DATA FindFileData; + HANDLE hFind = FindFirstFile(folder,&FindFileData); + if (hFind==INVALID_HANDLE_VALUE) + return true; + + do { +// CopyFile(); + } while (FindNextFile(hFind,&FindFileData); + + FindClose(hFind); + return true; +}*/ + + +#define BUF_SIZE 0x300 +bool isD2gfx(HANDLE hProcess, LPVOID dllAdr) +{ + SIZE_T nbRead; + BYTE buf[BUF_SIZE]; + ReadProcessMemory(hProcess,dllAdr,buf,BUF_SIZE, &nbRead); + if (nbRead < 0x40) return false; + int offsetPESignature = *(DWORD*)(buf+0x3C); + if (offsetPESignature+38 >= BUF_SIZE) return false; + DWORD baseOfCode = *(DWORD*)(buf+offsetPESignature + 0x34); + if ( ( baseOfCode != 0x6FA80000) && (baseOfCode != 0x6FA70000)) return false; + + return true; +} + +bool getWinReg(char* buf, DWORD bufsize) +{ + HKEY hKey; + DWORD type; + int res; + if (RegOpenKeyEx(HKEY_CURRENT_USER, SUBKEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { + res = RegQueryValueEx(hKey,"InstallPath",NULL,&type,(LPBYTE)buf,&bufsize); + RegCloseKey(hKey); + if (res!=ERROR_SUCCESS) return false; + } else if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, SUBKEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { + res = RegQueryValueEx(hKey,"InstallPath",NULL,&type,(LPBYTE)buf,&bufsize); + RegCloseKey(hKey); + if (res!=ERROR_SUCCESS) return false; + } else { + return false; + } + strcat(buf, GAMEFILE); + if (GetFileAttributes(buf) == INVALID_FILE_ATTRIBUTES) + return false; + return true; +} + +bool launchNormal(char* command, char* currentDirectory) +{ + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + ZeroMemory( &pi, sizeof(pi) ); + BOOL success = CreateProcess(0, command, 0, 0, false, 0, 0, currentDirectory, &si, &pi);//DEBUG_ONLY_THIS_PROCESS + return success?true:false; +} + +bool launchGame98(char* command, char* currentDirectory, char* libraryName) +{ +// MessageBox(0, "LAUNCH 98", "PlugYRun", MB_OK|MB_ICONASTERISK); + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + ZeroMemory( &pi, sizeof(pi) ); + BOOL success = CreateProcess(0, command, 0, 0, false, 0, 0, currentDirectory, &si, &pi);//DEBUG_ONLY_THIS_PROCESS + if (!success) return false; + DWORD ret; +// MessageBox(0, "LAUNCH 98 while", "PlugYRun", MB_OK|MB_ICONASTERISK); + Sleep(10); + while (true) + { + SuspendThread(pi.hThread);// == (DWORD)-1) + //MessageBox(0, "Thread not suspended", "PlugYRun", MB_OK|MB_ICONASTERISK); + + if (!GetExitCodeProcess(pi.hProcess,&ret) || (ret != STILL_ACTIVE)) + exit(0); + if (isD2gfx(pi.hProcess,(LPVOID)0x6FA80000)) + { +// MessageBox(0, "INSTALL 98", "PlugYRun", MB_OK|MB_ICONASTERISK); + installPlugY(pi.hProcess, 0x6FA80000, libraryName, 1); + ResumeThread(pi.hThread); + return true; + } + if (isD2gfx(pi.hProcess,(LPVOID)0x6FA70000)) + { +// MessageBox(0, "INSTALL 98", "PlugYRun", MB_OK|MB_ICONASTERISK); + installPlugY(pi.hProcess, 0x6FA70000, libraryName, 0); + ResumeThread(pi.hThread); + return true; + } + ResumeThread(pi.hThread); +// Sleep(10); + } + return true; +} + + +bool launchGameXP(char* command, char* currentDirectory, char* libraryName) +{ +// MessageBox(0, "LAUNCH XP", "PlugYRun", MB_OK|MB_ICONASTERISK); + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + ZeroMemory( &pi, sizeof(pi) ); + BOOL success = CreateProcess(0, command, 0, 0, false, DEBUG_PROCESS, 0, currentDirectory, &si, &pi);//DEBUG_ONLY_THIS_PROCESS + if (!success) return false; + DEBUG_EVENT DebugEvent; + DWORD status; +// MessageBox(0, "START WAITING", "PlugYRun", MB_OK|MB_ICONASTERISK); + while (WaitForDebugEvent(&DebugEvent,INFINITE)) + { + status = DBG_CONTINUE; + switch(DebugEvent.dwDebugEventCode) + { + case CREATE_THREAD_DEBUG_EVENT: + CloseHandle(DebugEvent.u.CreateThread.hThread); + break; + case CREATE_PROCESS_DEBUG_EVENT: + break; + case EXIT_PROCESS_DEBUG_EVENT: +// MessageBox(0, "EXIT", "PlugY", MB_OK|MB_ICONASTERISK); + exit(0); + case EXCEPTION_DEBUG_EVENT: + if (DebugEvent.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) + MessageBox(0, "EXCEPTION_ACCESS_VIOLATION", "PlugY", MB_OK|MB_ICONASTERISK); +// status = DBG_EXCEPTION_NOT_HANDLED; + break; + case LOAD_DLL_DEBUG_EVENT: +// if (!GetModuleBaseName(pi.hProcess,(HMODULE)DebugEvent.u.LoadDll.lpBaseOfDll,buf,100)) +// MessageBox(0, "ERROR", "PlugYRun", MB_OK|MB_ICONASTERISK); +// sprintf(buf,"%08X : %d",DebugEvent.u.LoadDll.lpBaseOfDll,GetLastError()); +// MessageBox(0, buf, "PlugYRun", MB_OK|MB_ICONASTERISK); +// if (!strcmp(buf,"d2gfx.dll")) +// if ((LPVOID)GetModuleHandle("D2gfx.dll") == DebugEvent.u.LoadDll.lpBaseOfDll)//pi.hProcess,,buf,bufSize); + if(isD2gfx(pi.hProcess, DebugEvent.u.LoadDll.lpBaseOfDll)) + { +// MessageBox(0, "INSTALL XP", "PlugYRun", MB_OK|MB_ICONASTERISK); + installPlugY(pi.hProcess, (DWORD)DebugEvent.u.LoadDll.lpBaseOfDll, libraryName, (DWORD)DebugEvent.u.LoadDll.lpBaseOfDll == 0x6FA8000); + CloseHandle(DebugEvent.u.LoadDll.hFile); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + debugActiveProcessStop(DebugEvent.dwProcessId); +// MessageBox(0, "INSTALL XP end", "PlugYRun", MB_OK|MB_ICONASTERISK); + return true; + } else + CloseHandle(DebugEvent.u.LoadDll.hFile); + break; + } + ContinueDebugEvent(DebugEvent.dwProcessId,DebugEvent.dwThreadId,status); + } + MessageBox(0, "ERROR : PlugY isn't installed", "PlugYRun", MB_OK|MB_ICONASTERISK); + return true; +} + + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + char currrentDirectory[MAX_PATH]; + char iniFileName[MAX_PATH]; + char command[MAX_PATH+50]; + +// MessageBox(NULL,"START","PlugYRun",MB_OK); + //Get Current Directory. + if (!GetCurrentDirectory(MAX_PATH-1,currrentDirectory)) + assertion("Current directory not found"); + + int len = strlen(currrentDirectory); + if (len && currrentDirectory[len-1] != '\\') + { + currrentDirectory[len+1]=NULL; + currrentDirectory[len]='\\'; + } + + //Get ini full path name. + strcpy(iniFileName,currrentDirectory); + strcat(iniFileName,INIFILE); + + //Get current directory. + strcpy(command,currrentDirectory); + strcat(command,GAMEFILE); + if (GetFileAttributes(command) == INVALID_FILE_ATTRIBUTES) + if (!getWinReg(command, MAX_PATH+50)) + return 1; + + //Add params. + strcat(command,lpCmdLine); + len = strlen(command); + GetPrivateProfileString(LAUNCHING,PARAM,"",&command[len],MAX_PATH-len,iniFileName); + + //copyLodVersionFiles(); + + char libraryName[50]; + if (!GetPrivateProfileString(LAUNCHING,LIBRARY_NAME,"",libraryName,50,iniFileName) || !libraryName[0]) + return !launchNormal(command, currrentDirectory); + +// MessageBox(NULL,command,"PlugYRun",MB_OK); + HMODULE module = GetModuleHandle("Kernel32.dll"); + if (module) + { + debugActiveProcessStop = (tDebugActiveProcessStop) GetProcAddress(module,"DebugActiveProcessStop"); + if (debugActiveProcessStop) + return !launchGameXP(command, currrentDirectory, libraryName); + } + return !launchGame98(command, currrentDirectory, libraryName); +} + + +/* else if (GetVersion() & 0x80000000) + { + versionXP=false; + } else { + versionXP=true; + }*/ +//HINSTANCE +// CreateProcessInternalA +// HMODULE HPlugY = LoadLibrary("C:\\Jeux\\Diablo II\\PlugY.dll"); +// if (!HPlugY) return 0; +// DuplicateHandle +// GetCurrentProcess(); +/* typedef void* (__stdcall* Tinit)(LPSTR IniName); + Tinit init = (Tinit)GetProcAddress(HPlugY,"_Init@4"); + if (!init) return 0; + init(0);*/ +/* +6FC2BD50 /$ 81EC 08010000 SUB ESP,108 +6FC2BD56 |. 53 PUSH EBX +6FC2BD57 |. 8A9C24 1801000>MOV BL,BYTE PTR SS:[ESP+118] +6FC2BD5E |. F6C3 10 TEST BL,10 +6FC2BD61 |. 55 PUSH EBP +6FC2BD62 |. 56 PUSH ESI +6FC2BD63 |. C707 00000000 MOV DWORD PTR DS:[EDI],0 +6FC2BD69 |. C74424 0C 0000>MOV DWORD PTR SS:[ESP+C],0 +6FC2BD71 |. BE F3030000 MOV ESI,3F3 +6FC2BD76 |. C64424 10 00 MOV BYTE PTR SS:[ESP+10],0 +6FC2BD7B |. 75 25 JNZ SHORT storm.6FC2BDA2 +6FC2BD7D |. F6C3 02 TEST BL,2 +6FC2BD80 |. 68 04010000 PUSH 104 +6FC2BD85 |. 74 0C JE SHORT storm.6FC2BD93 +6FC2BD87 |. 68 146AC36F PUSH storm.6FC36A14 ; ASCII "Software\Battle.net\" +6FC2BD8C |. 8D4424 18 LEA EAX,DWORD PTR SS:[ESP+18] +6FC2BD90 |. 50 PUSH EAX +6FC2BD91 |. EB 0A JMP SHORT storm.6FC2BD9D +6FC2BD93 |> 68 F069C36F PUSH storm.6FC369F0 ; ASCII "Software\Blizzard Entertainment\" +6FC2BD98 |. 8D4C24 18 LEA ECX,DWORD PTR SS:[ESP+18] +6FC2BD9C |. 51 PUSH ECX +6FC2BD9D |> E8 EE07FEFF CALL storm.#501 +6FC2BDA2 |> 8B9424 1801000>MOV EDX,DWORD PTR SS:[ESP+118] +6FC2BDA9 |. 68 04010000 PUSH 104 +6FC2BDAE |. 52 PUSH EDX +6FC2BDAF |. 8D4424 18 LEA EAX,DWORD PTR SS:[ESP+18] +6FC2BDB3 |. 50 PUSH EAX +6FC2BDB4 |. E8 6705FEFF CALL storm.#503 +6FC2BDB9 |. F6C3 04 TEST BL,4 +6FC2BDBC |. 8B2D 1030C36F MOV EBP,DWORD PTR DS:[<&ADVAPI32.RegQuer>; advapi32.RegQueryValueExA +6FC2BDC2 |. 75 5D JNZ SHORT storm.6FC2BE21 +6FC2BDC4 |. 8D4C24 0C LEA ECX,DWORD PTR SS:[ESP+C] +6FC2BDC8 |. 51 PUSH ECX ; /pHandle +6FC2BDC9 |. 68 19000200 PUSH 20019 ; |Access = KEY_READ +6FC2BDCE |. 6A 00 PUSH 0 ; |Reserved = 0 +6FC2BDD0 |. 8D5424 1C LEA EDX,DWORD PTR SS:[ESP+1C] ; | +6FC2BDD4 |. 52 PUSH EDX ; |Subkey +6FC2BDD5 |. 68 01000080 PUSH 80000001 ; |hKey = HKEY_CURRENT_USER +6FC2BDDA |. FF15 0830C36F CALL DWORD PTR DS:[<&ADVAPI32.RegOpenKey>; \RegOpenKeyExA +002281A4 80000001 |hKey = HKEY_CURRENT_USER +002281A8 002281C8 |Subkey = "Software\Blizzard Entertainment\Diablo II" +002281AC 00000000 |Reserved = 0 +002281B0 00020019 |Access = KEY_READ +002281B4 002281C4 \pHandle = 002281C4 + + +6FC2BDE0 |. 8BF0 MOV ESI,EAX +6FC2BDE2 |. 85F6 TEST ESI,ESI +6FC2BDE4 |. 75 3B JNZ SHORT storm.6FC2BE21 +6FC2BDE6 |. 8B8C24 2801000>MOV ECX,DWORD PTR SS:[ESP+128] +6FC2BDED |. 8B9424 2401000>MOV EDX,DWORD PTR SS:[ESP+124] +6FC2BDF4 |. 8B8424 2C01000>MOV EAX,DWORD PTR SS:[ESP+12C] +6FC2BDFB |. 57 PUSH EDI ; /pBufSize +6FC2BDFC |. 51 PUSH ECX ; |Buffer +6FC2BDFD |. 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+14] ; | +6FC2BE01 |. 52 PUSH EDX ; |pValueType +6FC2BE02 |. 8907 MOV DWORD PTR DS:[EDI],EAX ; | +6FC2BE04 |. 8B8424 2801000>MOV EAX,DWORD PTR SS:[ESP+128] ; | +6FC2BE0B |. 56 PUSH ESI ; |Reserved +6FC2BE0C |. 50 PUSH EAX ; |ValueName +6FC2BE0D |. 51 PUSH ECX ; |hKey +6FC2BE0E |. FFD5 CALL EBP ; \RegQueryValueExA +002281A0 00000124 |hKey = 124 +002281A4 6FF77B88 |ValueName = "InstallPath" +002281A8 00000000 |Reserved = NULL +002281AC 002282FC |pValueType = 002282FC +002281B0 00228320 |Buffer = 00228320 +002281B4 00228300 \pBufSize = 00228300 + + +6FC2BE10 |. 8B5424 0C MOV EDX,DWORD PTR SS:[ESP+C] +6FC2BE14 |. 52 PUSH EDX ; /hKey +6FC2BE15 |. 8BF0 MOV ESI,EAX ; | +6FC2BE17 |. FF15 1830C36F CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKe>; \RegCloseKey +002281B4 00000124 \hKey = 00000124 (window) + +6FC2BE1D |. 85F6 TEST ESI,ESI +6FC2BE1F |. 74 62 JE SHORT storm.6FC2BE83 +6FC2BE21 |> F6C3 01 TEST BL,1 +6FC2BE24 |. 75 59 JNZ SHORT storm.6FC2BE7F +6FC2BE26 |. 8D4424 0C LEA EAX,DWORD PTR SS:[ESP+C] +6FC2BE2A |. 50 PUSH EAX ; /pHandle +6FC2BE2B |. 68 19000200 PUSH 20019 ; |Access = KEY_READ +6FC2BE30 |. 6A 00 PUSH 0 ; |Reserved = 0 +6FC2BE32 |. 8D4C24 1C LEA ECX,DWORD PTR SS:[ESP+1C] ; | +6FC2BE36 |. 51 PUSH ECX ; |Subkey +6FC2BE37 |. 68 02000080 PUSH 80000002 ; |hKey = HKEY_LOCAL_MACHINE +6FC2BE3C |. FF15 0830C36F CALL DWORD PTR DS:[<&ADVAPI32.RegOpenKey>; \RegOpenKeyExA +6FC2BE42 |. 8BF0 MOV ESI,EAX +6FC2BE44 |. 85F6 TEST ESI,ESI +6FC2BE46 |. 75 4C JNZ SHORT storm.6FC2BE94 +6FC2BE48 |. 8B8424 2801000>MOV EAX,DWORD PTR SS:[ESP+128] +6FC2BE4F |. 8B8C24 2401000>MOV ECX,DWORD PTR SS:[ESP+124] +6FC2BE56 |. 8B9424 2C01000>MOV EDX,DWORD PTR SS:[ESP+12C] +6FC2BE5D |. 57 PUSH EDI +6FC2BE5E |. 50 PUSH EAX +6FC2BE5F |. 8B4424 14 MOV EAX,DWORD PTR SS:[ESP+14] +6FC2BE63 |. 51 PUSH ECX +6FC2BE64 |. 8917 MOV DWORD PTR DS:[EDI],EDX +6FC2BE66 |. 8B9424 2801000>MOV EDX,DWORD PTR SS:[ESP+128] +6FC2BE6D |. 56 PUSH ESI +6FC2BE6E |. 52 PUSH EDX +6FC2BE6F |. 50 PUSH EAX +6FC2BE70 |. FFD5 CALL EBP +6FC2BE72 |. 8B4C24 0C MOV ECX,DWORD PTR SS:[ESP+C] +6FC2BE76 |. 51 PUSH ECX ; /hKey +6FC2BE77 |. 8BF0 MOV ESI,EAX ; | +6FC2BE79 |. FF15 1830C36F CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKe>; \RegCloseKey +6FC2BE7F |> 85F6 TEST ESI,ESI +6FC2BE81 |. 75 11 JNZ SHORT storm.6FC2BE94 +6FC2BE83 |> 5E POP ESI +6FC2BE84 |. 5D POP EBP +6FC2BE85 |. B8 01000000 MOV EAX,1 +6FC2BE8A |. 5B POP EBX +6FC2BE8B |. 81C4 08010000 ADD ESP,108 +6FC2BE91 |. C2 1800 RETN 18 +6FC2BE94 |> 56 PUSH ESI ; /Error +6FC2BE95 |. FF15 2832C36F CALL DWORD PTR DS:[<&KERNEL32.SetLastErr>; \SetLastError +6FC2BE9B |. 5E POP ESI +6FC2BE9C |. 5D POP EBP +6FC2BE9D |. 33C0 XOR EAX,EAX +6FC2BE9F |. 5B POP EBX +6FC2BEA0 |. 81C4 08010000 ADD ESP,108 +6FC2BEA6 \. C2 1800 RETN 18 +*/ + +///////////////////////// END OF FILE /////////////////////// \ No newline at end of file diff --git a/PlugYRun/PlugYRun.rc b/PlugYRun/PlugYRun.rc new file mode 100644 index 0000000..289a11d --- /dev/null +++ b/PlugYRun/PlugYRun.rc @@ -0,0 +1,120 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// French (France) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,3,0 + PRODUCTVERSION 1,0,3,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "CompanyName", "Yohann NICOLAS" + VALUE "FileVersion", "1.03" + VALUE "OriginalFilename", "PlugY.exe" + VALUE "ProductName", "PlugY launcher." + VALUE "ProductVersion", "1.03" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x40c, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "PlugY.ico" +#endif // French (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/PlugYRun/PlugYRun.sln b/PlugYRun/PlugYRun.sln new file mode 100644 index 0000000..b97d16b --- /dev/null +++ b/PlugYRun/PlugYRun.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlugYRun", "PlugYRun.vcproj", "{119E844E-4DF8-409D-8B12-DC5CDDB5E37C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {119E844E-4DF8-409D-8B12-DC5CDDB5E37C}.Debug|Win32.ActiveCfg = Debug|Win32 + {119E844E-4DF8-409D-8B12-DC5CDDB5E37C}.Debug|Win32.Build.0 = Debug|Win32 + {119E844E-4DF8-409D-8B12-DC5CDDB5E37C}.Release|Win32.ActiveCfg = Release|Win32 + {119E844E-4DF8-409D-8B12-DC5CDDB5E37C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PlugYRun/PlugYRun.suo b/PlugYRun/PlugYRun.suo new file mode 100644 index 0000000..f38be8e Binary files /dev/null and b/PlugYRun/PlugYRun.suo differ diff --git a/PlugYRun/PlugYRun.vcproj b/PlugYRun/PlugYRun.vcproj new file mode 100644 index 0000000..cef86b6 --- /dev/null +++ b/PlugYRun/PlugYRun.vcproj @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PlugYRun/PlugYRun.vcproj.ATHLON64.Yohann.user b/PlugYRun/PlugYRun.vcproj.ATHLON64.Yohann.user new file mode 100644 index 0000000..19f0309 --- /dev/null +++ b/PlugYRun/PlugYRun.vcproj.ATHLON64.Yohann.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/PlugYRun/resource.h b/PlugYRun/resource.h new file mode 100644 index 0000000..44fcdf1 --- /dev/null +++ b/PlugYRun/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by PlugYRun.rc +// +#define IDI_ICON1 107 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_COMMAND_VALUE 40003 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif