plugy/PlugY/PlayerCustomData.cpp

462 lines
16 KiB
C++
Raw Normal View History

/*=================================================================
File created by Yohann NICOLAS.
Add support 1.13d by L'Autour.
2021-01-04 07:07:29 +00:00
Add support 1.14d by haxifix.
Adding custom data.
Save and load infinity & shared Stash
=================================================================*/
#include "updateClient.h"
#include "infinityStash.h"
#include "savePlayerData.h" //Install_SavePlayerData()
#include "loadPlayerData.h" //Install_LoadPlayerData()
2017-01-23 19:34:12 +00:00
#include "common.h"
2021-01-04 07:07:29 +00:00
bool active_PlayerCustomData = false;
2017-01-23 19:34:12 +00:00
bool openSharedStashOnLoading = false;
/*********************************** UPDATING ***********************************/
Stash* getStashFromItem(Unit* ptChar, Unit* ptItem)
{
Stash* curStash = PCPY->selfStash;
Unit* curItem;
while (curStash)
{
if (curStash == PCPY->currentStash)
2021-01-04 07:07:29 +00:00
curItem = D2InventoryGetFirstItem(PCInventory);
else
curItem = curStash->ptListItem;
while (curItem)
{
if (D2GetRealItem(curItem) == ptItem) return curStash;
curItem = D2UnitGetNextItem(curItem);
}
curStash = curStash->nextStash;
}
2021-01-04 07:07:29 +00:00
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);
2021-09-01 07:40:52 +00:00
//log_msg("- updateItem PCPY->currentStash->id : %d // ptStash->id : %d\n", PCPY->currentStash?PCPY->currentStash->id:-1, ptStash?ptStash->id:-1);
if (!ptStash) return NULL;
2021-01-04 20:29:37 +00:00
selectStash(ptChar, ptStash, ptStash->id == 0);
}
return ptItem;
}
2021-01-04 07:07:29 +00:00
void FASTCALL updateItem_111(Unit* ptItem, Unit* ptChar)
{
if (PCGame->isLODGame && (D2ItemGetPage(ptItem) == 4))
{
Stash* ptStash = getStashFromItem(ptChar, ptItem);
if (ptStash)
2021-01-04 20:29:37 +00:00
selectStash(ptChar, ptStash, ptStash->id == 0);
2021-01-04 07:07:29 +00:00
}
}
void STDCALL updateClientPlayerOnLoading(Unit* ptChar)
{
log_msg("--- Start updateClientPlayerOnLoading ---\n");
if (PCGame->isLODGame)
{
2021-01-04 07:07:29 +00:00
PCPY->showSharedStash = openSharedStashOnLoading && active_sharedStash;
selectStash(ptChar, PCPY->showSharedStash ? PCPY->sharedStash : PCPY->selfStash, true);
}
updateClient(ptChar, UC_SHARED_GOLD, PCPY->sharedGold, 0, 0);
2021-01-04 07:07:29 +00:00
log_msg("End update client on loading.\n\n");
}
/**************************** 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;
2021-01-04 07:07:29 +00:00
}
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 ****************************/
2021-01-04 07:07:29 +00:00
FCT_ASM ( caller_updateItem_114 )
PUSH EDI
PUSH DWORD PTR SS:[ESP+0x8]
CALL updateItem
RETN 4
2020-10-25 13:10:17 +00:00
}}
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
}}
2021-01-04 07:07:29 +00:00
FCT_ASM ( caller_updateClientPlayerOnLoading_114 )
PUSH DWORD PTR SS:[ESP+0x14]
CALL updateClientPlayerOnLoading
POP ECX
POP EDI
POP ESI
XOR EAX,EAX
POP EBX
JMP ECX
2020-10-25 13:10:17 +00:00
}}
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
}}
2021-01-04 07:07:29 +00:00
FCT_ASM ( callerServer_getNextItemToFree_114 )
PUSH DWORD PTR SS:[ESP+4]
PUSH DWORD PTR SS:[EBP-8]
CALL getNextItemToFree
RETN 4
2020-10-25 13:10:17 +00:00
}}
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
}}
2021-01-04 07:07:29 +00:00
FCT_ASM ( callerClient_getNextItemToFree_114 )
PUSH DWORD PTR SS:[ESP+4]
PUSH DWORD PTR SS:[EBP-4]
CALL getNextItemToFree
RETN 4
2020-10-25 13:10:17 +00:00
}}
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;
2021-01-04 07:07:29 +00:00
if (isInstalled) return;
2021-01-04 07:07:29 +00:00
Install_SavePlayerData();
Install_LoadPlayerData();
Install_UpdateClient();
log_msg("Patch D2Game & D2Client & D2Common for Player's custom data. (PlayerCustomData)\n");
// Initialize custom data.
2020-10-25 13:10:17 +00:00
mem_seek(version_D2Client == V114d ? offset_D2Common + 0x221FDD : version_D2Client == V113d ? offset_D2Common + 0x170DE : version_D2Client == V113c ? offset_D2Common + 0x309BE : version_D2Client == V112 ? offset_D2Common + 0x585EE : version_D2Client == V111b ? offset_D2Common + 0x5BFCE : version_D2Common == V111 ? offset_D2Common + 0x4ED5E :(DWORD)D2InitPlayerData + 0x62 );
2021-01-04 07:07:29 +00:00
MEMJ_REF4( D2AllocMem, init_PlayerCustomData);
//01BD0381 |. E8 C03F0000 CALL <JMP.&Fog.#10045>
//6FD9ED5D |. E8 94A4FBFF CALL <JMP.&Fog.#10045>
//6FDABFCD |. E8 34D2FAFF CALL <JMP.&Fog.#10045>
//6FDA85ED |. E8 240CFBFF CALL <JMP.&Fog.#10045>
//6FD809BD |. E8 6088FDFF CALL <JMP.&Fog.#10045>
//6FD670DD |. E8 0C3EFFFF CALL <JMP.&Fog.#10045>
2021-01-04 07:07:29 +00:00
//00621FDC |. E8 4F94DEFF CALL Game.0040B430 ; \Game.0040B430
2021-01-04 07:07:29 +00:00
if ( version_D2Game >= V111 && version_D2Game <= V113d)
{
// update item
2021-01-04 07:07:29 +00:00
mem_seek R8(D2Game, 10933, 10C03, 1100D, 8BC71, C3C51, 5F2A1, 9BB91, 75C81, 0000);
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
//6FC95C81 |> 8B5424 18 |MOV EDX,DWORD PTR SS:[ESP+18]
//6FC95C85 |. 52 |PUSH EDX
2021-01-04 07:07:29 +00:00
mem_seek R8(D2Game, 1097B, 10C4B, 11058, 8BCD1, C3CB1, 5F301, 9BBF1, 75CE1, 0000);
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
//6FC95CE1 |> 8B5424 18 ||MOV EDX,DWORD PTR SS:[ESP+18]
//6FC95CE5 |. 52 ||PUSH EDX
} else {
// update item
2021-01-04 07:07:29 +00:00
mem_seek R8(D2Game, 10933, 10C03, 1100D, 8BC71, C3C51, 5F2A1, 0000, 0000, 1978F3);
MEMC_REF4( D2GameGetObject, version_D2Game >= V114a ? caller_updateItem_114 : version_D2Game >= V110 ? caller_updateItem : caller_updateItem_9);
//6FC4100C |. E8 EFAA0700 |CALL D2Game.6FCBBB00
2021-01-04 07:07:29 +00:00
//005978F2 |. E8 69B6FBFF |CALL Game.00552F60 ; \Game.00552F60
mem_seek R8(D2Game, 1097B, 10C4B, 11058, 8BCD1, C3CB1, 5F301, 0000, 0000, 197943);
MEMC_REF4( D2GameGetObject, version_D2Game >= V114a ? caller_updateItem_114 : version_D2Game >= V110 ? caller_updateItem : caller_updateItem_9);
//6FC41057 |. E8 A4AA0700 ||CALL D2Game.6FCBBB00
2021-01-04 07:07:29 +00:00
//00597942 |. E8 19B6FBFF |CALL Game.00552F60 ; \Game.00552F60 //005978F2 |. E8 69B6FBFF |CALL Game.00552F60 ; \Game.00552F60
}
// Update client on loading
2020-10-25 13:10:17 +00:00
mem_seek R8(D2Game, 23EB, 2426, 25D4, 53482, C6A32, ED502, 4BF12, E7548, 139A20);//6FC325D4-6FC30000
2021-01-04 07:07:29 +00:00
memt_byte( 0x5F ,0xE8); // CALL
MEMT_REF4( version_D2Game >= V114d ? 0x5BC0335E : 0xC0335D5E , version_D2Game >= V114d ? caller_updateClientPlayerOnLoading_114 : 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
//6FD07548 |> 5F POP EDI
//6FD07549 |. 5E POP ESI
//6FD0754A |. 5D POP EBP
//6FD0754B |. 33C0 XOR EAX,EAX
2021-01-04 07:07:29 +00:00
//00539A20 |> 5F POP EDI
//00539A21 |. 5E POP ESI
//00539A22 |. 33C0 XOR EAX,EAX
//00539A24 |. 5B POP EBX
// Free custom data.
2020-10-25 13:10:17 +00:00
mem_seek R8(D2Common, 7055C, 7065C, 80483, 4F82D, 5C9CD, 5856D, 3093D, 1705D, 2220DD);
2021-01-04 07:07:29 +00:00
MEMJ_REF4( D2FreeMem, free_PlayerCustomData);
//01BD0482 |. E8 C53E0000 CALL <JMP.&Fog.#10046>
//6FD9F82C |. E8 E399FBFF CALL <JMP.&Fog.#10046>
//6FDAC9CC |. E8 3BC8FAFF CALL <JMP.&Fog.#10046>
//6FDA856C |. E8 E70CFBFF CALL <JMP.&Fog.#10046>
//6FD8093C |. E8 E788FDFF CALL <JMP.&Fog.#10046>
//6FD6705C |. E8 CF3EFFFF CALL <JMP.&Fog.#10046>
2021-01-04 07:07:29 +00:00
//006220DC |. E8 9F93DEFF CALL Game.0040B480 ; \Game.0040B480
// Free item in Stash (Server-side)
2020-10-25 13:10:17 +00:00
mem_seek R8(D2Game, 7D12B, 7D62B, 8D5A4, 99112, BFDB2, 94242, E1162, 6F7C2, 155B34);
2021-01-04 07:07:29 +00:00
MEMJ_REF4( D2UnitGetNextItem, version_D2Game >= V114a ? callerServer_getNextItemToFree_114 : version_D2Game >= V111 ? callerServer_getNextItemToFree_111 : version_D2Game == V110 ? callerServer_getNextItemToFree : callerServer_getNextItemToFree_9);//0x0005E204
//6FCBD5A3 . E8 04E20500 CALL <JMP.&D2Common.#10304>
//02019111 |. E8 5016F7FF |CALL <JMP.&D2Common.#10934>
//0202FDB1 |. E8 30AAF4FF |CALL <JMP.&D2Common.#11140>
//6FCB4241 |. E8 8862F7FF |CALL <JMP.&D2Common.#10770>
//6FD01161 |. E8 6693F2FF |CALL <JMP.&D2Common.#10464>
//6FC8F7C1 |. E8 44AEF9FF |CALL <JMP.&D2Common.#10879>
2021-01-04 07:07:29 +00:00
//00555B33 |. E8 68840E00 |CALL Game.0063DFA0 ; \Game.0063DFA0
// Free item in Stash (Client-side)
2020-10-25 13:10:17 +00:00
mem_seek R8(D2Client, 8EF8F, 8E30F, 89B32, 26404, 4C264, 1F2D4, A5C94, 621E4, 66D02);//6FB29B31-6FAA0000
2021-01-04 07:07:29 +00:00
MEMJ_REF4( D2UnitGetNextItem, version_D2Game >= V114d ? callerClient_getNextItemToFree_114 : version_D2Game >= V111 ? callerClient_getNextItemToFree_111 : version_D2Game == V110 ? callerClient_getNextItemToFree : callerClient_getNextItemToFree_9);//0x00040F34
//6FB29B31 E8 340F0400 CALL <JMP.&D2Common.#10304>
//6FAD6403 |. E8 925DFEFF |CALL <JMP.&D2Common.#10934>
//6FAFC263 |. E8 38FFFBFF |CALL <JMP.&D2Common.#11140>
//6FACF2D3 |. E8 4CD1FEFF |CALL <JMP.&D2Common.#10770>
//6FB55C93 |. E8 D068F6FF |CALL <JMP.&D2Common.#10464>
//6FB121E3 |. E8 7AA1FAFF |CALL <JMP.&D2Common.#10879>
2021-01-04 07:07:29 +00:00
//00466D01 E8 9A721D00 |CALL Game.0063DFA0
if ( version_D2Common >= V110 )
{
// Test if it's already removed from inventory
2020-10-25 13:10:17 +00:00
mem_seek R8(D2Common, 0000, 0000, 4E689, 26E33, 42133, 6AE93, 21B23, 3B393, 23ADB5);
memt_byte( version_D2Common == V114d ? 0x0E : 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
//6FD8B392 |. 74 0D JE SHORT D2Common.6FD8B3A1
2021-01-04 07:07:29 +00:00
//0063ADB4 |. 74 0E JE SHORT Game.0063ADC4
} else {
2020-10-25 13:10:17 +00:00
mem_seek R8(D2Game, 7D176, 7D676, 0000, 0000, 0000, 0000, 0000, 0000, 0000);
memt_byte( 0x74 , 0x90);//MOV EAX,EDI
memt_byte( 0x35 , 0x90);//NOP
//6FCAD176 |. 74 35 |JE SHORT D2Game.6FCAD1AD
2020-10-25 13:10:17 +00:00
mem_seek R8(D2Client, 8F0CA, 8E44A, 0000, 0000, 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
2020-10-25 13:10:17 +00:00
mem_seek R8(D2Client, 8F13C, 8E4BC, 0000, 0000, 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 =================================*/