Moderator: MacroQuest Developers
Code: Select all
#define CWS_VSCROLL 0x1
#define CWS_HSCROLL 0x2
#define CWS_TITLE 0x4
#define CWS_CLOSE 0x8
#define CWS_MINIMIZE 0x20
#define CWS_BORDER 0x40
#define CWS_RESIZEALL 0x200
#define CWS_TRANSPARENT 0x400
#define CWS_NOMOVE 0x8000
typedef struct _EQCHATMGR
{
/*0x000*/ struct _EQCHATWINDOW* ChatWnd[0x2a];
/*0x080*/ DWORD NumWindows;
/*0x084*/ DWORD ActiveWindow; // CChatManager::GetActiveChatWindow
/*0x088*/ DWORD LockedWindow; // CChatManager::GetActiveChatWindow
/*0x08c*/ DWORD Unknown0x08c;
/*0x090*/ DWORD ChannelMap[0x2a]; // channel map
/*0x138*/ DWORD Unknown0x138;
/*0x13c*/ DWORD Unknown0x13c;
/*0x140*/ DWORD Unknown0x140;
/*0x144*/ LPVOID ChatMenu;
/*0x148*/ DWORD Unknown0x148;
/*0x14c*/ DWORD Unknown0x14c;
/*0x150*/ DWORD Unknown0x150;
/*0x154*/ DWORD Unknown0x154;
/*0x158*/ LPVOID MeleeMenu;
/*0x15c*/ DWORD Unknown0x15c;
/*0x160*/ LPVOID SpellMenu;
/*0x164*/ DWORD Unknown0x164;
/*0x168*/ DWORD Unknown0x168;
/*0x16c*/ LPVOID ChannelMenu;
/*0x170*/ LPVOID ChatMenu2;
/*0x174*/ LPVOID FilterMenu;
/*0x178*/ DWORD Unknown0x178;
/*0x17c*/ DWORD Unknown0x17c;
/*0x180*/ DWORD Unknown0x180;
/*0x184*/ LPVOID HitsModeMenu;
/*0x188*/ LPVOID MeleeMenu2;
/*0x18c*/ LPVOID HitsModeMenu2;
/*0x190*/ DWORD Unknown0x190;
/*0x194*/ LPVOID HitsModeMenu3;
/*0x198*/ DWORD Unknown0x198;
/*0x19c*/ LPVOID HitsModeMenu4;
/*0x1a0*/ DWORD Unknown0x1a0;
/*0x1a4*/ LPVOID HitsModeMenu5;
/*0x1a8*/ DWORD Unknown0x1a8;
/*0x1ac*/ LPVOID HitsModeMenu6;
/*0x1b0*/ DWORD Unknown0x1b0;
/*0x1b4*/ DWORD Unknown0x1b4; // CChatManager__UpdateTellMenus
/*0x1b8*/ DWORD Unknown0x1b8;
/*0x1bc*/ DWORD Unknown0x1bc; // CChatManager__UpdateTellMenus
/*0x1c0*/ DWORD Unknown0x1c0;
/*0x1c4*/ DWORD Unknown0x1c4; // CChatManager__UpdateTellMenus // raid
/*0x1c8*/ DWORD Unknown0x1c8;
/*0x1cc*/ DWORD Unknown0x1cc; // CChatManager__UpdateTellMenus
/*0x1d0*/ DWORD Unknown0x1d0; // CChatManager__UpdateTellMenus
/*0x1d4*/ DWORD Unknown0x1d4; // CChatManager__UpdateTellMenus
/*0x1d8*/ DWORD Unknown0x1d8;
/*0x1dc*/ DWORD Unknown0x1dc;
/*0x1e0*/ DWORD Unknown0x1e0;
/*0x1e4*/ BYTE Unknown0x1e4[0x1c];
/*0x200*/ DWORD Unknown0x200;
/*0x204*/ DWORD Unknown0x204;
/*0x208*/
} EQCHATMGR, *PEQCHATMGR;
// Actual size 0x248 10-9-2003
typedef struct _EQCHATWINDOW
{
/*0x000*/ struct _CSIDLWND Wnd;
/*0x138*/ DWORD Unknown0x138;
/*0x13c*/ LPVOID ChatManager; // --> 0x13c
/*0x140*/ struct _CSIDLWND* InputWnd;
/*0x144*/ struct _CSIDLWND* OutputWnd;
/*0x148*/ DWORD Unknown0x140;
/*0x14c*/ DWORD Unknown0x144;
/*0x150*/ BYTE Unknown0x148;
/*0x151*/ BYTE Unknown0x149[0x3f];
/*0x18c*/ DWORD Unknown0x188;
/*0x190*/ DWORD Unknown0x18c;
/*0x194*/ struct _CXSTR *CommandHistory[0x28]; // ->0x198
/*0x238*/ DWORD Unknown0x230; // CChatWindow::HistoryBack/forward .. maybe total or current history lines
/*0x23c*/ DWORD Unknown0x234; // CChatWindow::HistoryBack/forward .. maybe total or current history lines
/*0x240*/ DWORD FontSize; //
/*0x244*/ DWORD Unknown0x23C;
/*0x248*/
} EQCHATWINDOW, *PEQCHATWINDOW;
Code: Select all
extern VOID SetCXSTRText(PCXSTR pCXStr, PCHAR Text);
extern VOID Chat(PCHAR Text, DWORD Color);
extern DWORD *EQADDR_CHATMANAGER;
extern DWORD EQADDR_CCHATMANAGERGETRGBAFROMINDEX;
extern DWORD EQADDR_CXSTRCONSTRUCTOR;
extern DWORD EQADDR_CXSTRFREE;
extern DWORD EQADDR_APPENDSTML;
extern DWORD EQADDR_CCHATMANAGERCREATECHATWINDOW;
Code: Select all
GetPrivateProfileString("Class Locations","ClassChatManager","0",szBuffer,MAX_STRING,ClientINI); EQADDR_CHATMANAGER = (PDWORD)strtoul(szBuffer,NULL,16);
GetPrivateProfileString("Function Locations","CXStrConstructor","0",szBuffer,MAX_STRING,ClientINI); EQADDR_CXSTRCONSTRUCTOR = (DWORD)strtoul(szBuffer,NULL,16);
GetPrivateProfileString("Function Locations","CXStrFree","0",szBuffer,MAX_STRING,ClientINI); EQADDR_CXSTRFREE = (DWORD)strtoul(szBuffer,NULL,16);
GetPrivateProfileString("Function Locations","CStmlWndAppend","0",szBuffer,MAX_STRING,ClientINI); EQADDR_APPENDSTML = (DWORD)strtoul(szBuffer,NULL,16);
GetPrivateProfileString("Function Locations","CChatManagerCreateChatWindow","0",szBuffer,MAX_STRING,ClientINI); EQADDR_CCHATMANAGERCREATECHATWINDOW = (DWORD)strtoul(szBuffer,NULL,16);
GetPrivateProfileString("Function Locations","CChatManagerGetRGBAFromIndex","0",szBuffer,MAX_STRING,ClientINI); EQADDR_CCHATMANAGERGETRGBAFROMINDEX = (DWORD)strtoul(szBuffer,NULL,16);
Code: Select all
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x510
#define DIRECTINPUT_VERSION 0x800
#if !defined(CINTERFACE)
#error /DCINTERFACE
#endif
#define DBG_SPEW
#include <stdio.h>
#include <stdlib.h>
#include "dinput.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <winsock.h>
#include "MQ.h"
#include "EQLib.h"
DWORD EQADDR_CCHATMANAGERGETRGBAFROMINDEX=0;
DWORD EQADDR_CXSTRCONSTRUCTOR=0;
DWORD EQADDR_CXSTRFREE=0;
DWORD EQADDR_APPENDSTML=0;
DWORD EQADDR_CCHATMANAGERCREATECHATWINDOW=0;
DWORD *EQADDR_CHATMANAGER=(DWORD*)0;
PEQCHATWINDOW MQChatWnd=0;
void CChatWindow__AddOutputText(PEQCHATWINDOW pWnd, const char *Text, int RGBA=0)
{
if (!pWnd || !Text)
return;
char out[MAX_STRING];
DWORD saddr =(DWORD)&out[0];
if (RGBA)
sprintf(&out[0],"<c \"#%08X\">%s</c><br>",RGBA,Text);
else
sprintf(&out[0],"%s<br>",Text);
PCXSTR stri=0;
DWORD outwnd=(DWORD)pWnd->OutputWnd;
__asm{
push ecx;
push eax;
push saddr;
lea ecx, [stri];
call [EQADDR_CXSTRCONSTRUCTOR];
pop eax;
pop ecx;
};
__asm{
push eax;
push ecx;
push esi;
push edx;
push [stri];
push [stri];
mov ecx, outwnd;
call [EQADDR_APPENDSTML];
pop edx;
pop esi;
pop ecx;
pop eax;
};
__asm{
push eax;
push ecx;
push [stri];
mov ecx, [stri];
call [EQADDR_CXSTRFREE];
pop ecx;
pop eax;
};
// set vertical scroll
DWORD VSMax=pWnd->OutputWnd->VScrollMax;
DWORD SetVScrollPos=(DWORD)pWnd->OutputWnd->pvfTable->SetVScrollPos;
__asm
{
push eax;
push ecx;
push VSMax;
mov ecx, outwnd;
call [SetVScrollPos];
pop ecx;
pop eax;
};
}
void MakeChatWindow()
{
// find where this window would go
PEQCHATMGR pChatManager= *(PEQCHATMGR*)EQADDR_CHATMANAGER;
for (int i = 0 ; i < 0x20 ; i++)
{
if (!pChatManager->ChatWnd[i])
goto chatwndfound;
}
// cant!
return;
chatwndfound:
__asm{
push eax;
push ecx;
mov ecx, pChatManager;
call [EQADDR_CCHATMANAGERCREATECHATWINDOW];
pop ecx;
pop eax;
};
if (!pChatManager->ChatWnd[i])
{
DebugSpewAlways("New chat window not where we think it should be...");
return;
}
MQChatWnd=pChatManager->ChatWnd[i];
// now remove it from the chat manager! =)
pChatManager->ChatWnd[i]=0;
pChatManager->NumWindows--;
pChatManager->ActiveWindow=0;
// should be ok now, set style etc
MQChatWnd->Wnd.WindowStyle=CWS_TITLE|CWS_MINIMIZE|CWS_BORDER|CWS_RESIZEALL;
SetCXSTRText(MQChatWnd->Wnd.WindowText,"MQ");
}
void Chat(const char *Text, int Color)
{
PEQCHATMGR pChatManager= *(PEQCHATMGR*)EQADDR_CHATMANAGER;
if (!MQChatWnd)
MakeChatWindow();
if (!MQChatWnd)
return;
CChatWindow__AddOutputText(MQChatWnd,Text,Color);
}
Code: Select all
VOID WriteChatColor(PCHAR Line, DWORD Color) {
if (!gbInGame) return;
if (gFilterMacro != FILTERMACRO_NONE) {
PEQCHATMGR pChatManager=*(PEQCHATMGR*)EQADDR_CHATMANAGER;
__asm
{
push eax;
push ecx;
mov ecx, pChatManager;
push Color;
call [EQADDR_CCHATMANAGERGETRGBAFROMINDEX];
mov [Color], eax;
pop ecx;
pop eax;
};
char out[MAX_STRING];
int i = 0;
int o = 0;
while(Line[i]!=0)
{
switch(Line[i])
{
case '&':
out[o++]='A';
out[o++]='M';
out[o++]='P';
out[o++]=';';
break;
case '%':
out[o++]='P';
out[o++]='C';
out[o++]='T';
out[o++]=';';
break;
case '<':
out[o++]='L';
out[o++]='T';
out[o++]=';';
break;
case '>':
out[o++]='G';
out[o++]='T';
out[o++]=';';
break;
case '"':
out[o++]='Q';
out[o++]='U';
out[o++]='O';
out[o++]='T';
out[o++]=';';
break;
default:
out[o++]=Line[i];
break;
}
i++;
}
Chat(Line,Color);
}
else if (gTelnetServer && gTelnetConnection) {
TelnetServer_Write(Line);
}
};
Code: Select all
[Function Locations]
CXStrConstructor=005372F0
CXStrFree=5372F0
CStmlWndAppend=55BEA0
CChatManagerCreateChatWindow=4D2024
CChatManagerGetRGBAFromIndex=4D008A
[Class Locations]
ClassChatManager=00777418