EQLib_Hooks.cpp
Code: Select all
// ***************************************************************************
// Function: ItemDisplay::Detour
// Description: Our Item display hook
// ***************************************************************************
class ItemDisplay
{
public:
VOID Trampoline(PITEMINFO *pitem,bool unknown);
VOID Detour(PITEMINFO *pitem,bool unknown)
{
PEQITEMWINDOW This;
__asm mov [This], ecx;
PITEMINFO item=*pitem;
DebugSpew("ItemDisplay(%s,%d)",&item->Name[0],unknown);
Trampoline(pitem,unknown);
char out[MAX_STRING];
sprintf(&out[0],"<c \"#00FFFF\">Item Lore: %s</c><BR>",&item->LoreName[0]);
AppendCXStr(&This->ItemInfo,&out[0]);
}
};
// ***************************************************************************
// Function: HookItemDisplay
// Description: Hook item display
// ***************************************************************************
DETOUR_TRAMPOLINE_EMPTY(VOID ItemDisplay::Trampoline(PITEMINFO*,bool));
VOID HookItemDisplay(BOOL Patch)
{
void (ItemDisplay::*pfDetour)(PITEMINFO*,bool) = ItemDisplay::Detour;
void (ItemDisplay::*pfTrampoline)(PITEMINFO*,bool) = ItemDisplay::Trampoline;
DebugSpewAlways("HookItemDisplay - %satching",(Patch)?"P":"Unp");
if (Patch) {
MAKE_OURDETOUR(DETOUR_ITEMDISPLAY, EQADDR_ITEMDISPLAYSETITEM);
DetourFunctionWithEmptyTrampoline(*(PBYTE*)&pfTrampoline,
(PBYTE)EQADDR_ITEMDISPLAYSETITEM,
*(PBYTE*)&pfDetour);
} else {
DetourRemove(*(PBYTE*)&pfTrampoline,
*(PBYTE*)&pfDetour);
}
}
Code: Select all
// EQLib_Utilites.cpp
extern VOID AppendCXStr(PCXSTR *cxstr, PCHAR text);
extern VOID SetCXStr(PCXSTR *cxstr, PCHAR text);
.
.
.
// EQLib_Hooks.cpp
extern VOID HookItemDisplay(BOOL Patch);
.
.
.
extern DWORD EQADDR_ITEMDISPLAYSETITEM;
extern DWORD EQADDR_CXSTRAPPEND;
extern DWORD EQADDR_CXSTRSET;
.
.
.
#define DETOUR_ITEMDISPLAY 12
#define NDETOURS 13
Code: Select all
HookDInput(TRUE);
HookCommands(TRUE);
HookMapfile(TRUE);
HookDisplay(TRUE);
HookGameEvents(TRUE);
[color=red]HookItemDisplay(TRUE);[/color]
.
.
.
HookGameEvents(FALSE);
HookDisplay(FALSE);
HookMapfile(FALSE);
HookCommands(FALSE);
HookDInput(FALSE);
HookChat(FALSE);
[color=red] HookItemDisplay(FALSE);[/color]
HookMemChecker(FALSE);
Code: Select all
DWORD EQADDR_CXSTRAPPEND=0;
DWORD EQADDR_CXSTRSET=0;
DWORD EQADDR_ITEMDISPLAYSETITEM=0;
.
.
.
GetPrivateProfileString("Function Locations","ItemDisplaySetItem","0",szBuffer,MAX_STRING,ClientINI); EQADDR_ITEMDISPLAYSETITEM = (DWORD)strtoul(szBuffer,NULL,16);
GetPrivateProfileString("Function Locations","CXStrAppend","0",szBuffer,MAX_STRING,ClientINI); EQADDR_CXSTRAPPEND = (DWORD)strtoul(szBuffer,NULL,16);
GetPrivateProfileString("Function Locations","CXStrSet","0",szBuffer,MAX_STRING,ClientINI); EQADDR_CXSTRSET = (DWORD)strtoul(szBuffer,NULL,16);
Code: Select all
// YES THIS NEEDS TO BE PCXSTR *
VOID AppendCXStr(PCXSTR *cxstr, PCHAR text)
{
__asm
{
push eax;
push ecx;
mov ecx, cxstr;
push text;
call [EQADDR_CXSTRAPPEND];
pop ecx;
pop eax;
}
}
// YES THIS NEEDS TO BE PCXSTR *
VOID SetCXStr(PCXSTR *cxstr, PCHAR text)
{
__asm
{
push eax;
push ecx;
mov ecx, cxstr;
push text;
call [EQADDR_CXSTRSET];
pop ecx;
pop eax;
}
}
Code: Select all
[Function Locations]
ItemDisplaySetItem=004EED30
CXStrAppend=00538380
CXStrSet=005374B0
Code: Select all
// Lax 10-29-2003
// Actual size 0x16C
typedef struct _EQITEMWINDOW
{
/*0x000*/ struct _CSIDLWND Wnd;
/*0x138*/ BYTE Unknown0x138[0x4];
/*0x13c*/ struct _CSIDLWND *DisplayWnd;
/*0x140*/ BYTE Unknown0x140[0x8];
/*0x148*/ BYTE Unknown0x148;
/*0x149*/ BYTE Unknown0x149[0x3];
/*0x14C*/ PCXSTR ItemInfo;
/*0x150*/ PVOID Unknown0x150; // PCXSTR "item display" ?? _CSIDLWND ??
/*0x154*/ DWORD Unknown0x154; // possibly PCXSTR of information as on charms
/*0x158*/ BYTE Unknown0x158;
/*0x15C*/ PVOID TextureAnim;
/*0x160*/ PVOID TextureAnim2;
/*0x164*/ DWORD Unknown0x164[2];
/*0x16C*/
} EQITEMWINDOW, *PEQITEMWINDOW;
The SetCXStr function can be used to replace plaz's workaround for setting CXStr text :)
