Moderator: MacroQuest Developers
Ah. Well, let me know, so we can update the mouse parser code as well. My method is brute force, because that's all we had at the timeLax wrote:Nah I mean there's a function in the CSidlWnd virtual function table to call that stores to the ini, and one that reads from the ini..
Code: Select all
CHAR szChatINISection[MAX_STRING] = {0};
void LoadChatFromINI(PCSIDLWND pWindow)
{
sprintf(szChatINISection,"%s.%s",(*EQADDR_CHAR_INFO)->Server,(*EQADDR_CHAR_INFO)->Name);
pWindow->Location.top = GetPrivateProfileInt(szChatINISection,"ChatTop", 10,gszINIFilename);
pWindow->Location.bottom = GetPrivateProfileInt(szChatINISection,"ChatBottom",210,gszINIFilename);
pWindow->Location.left = GetPrivateProfileInt(szChatINISection,"ChatLeft", 10,gszINIFilename);
pWindow->Location.right = GetPrivateProfileInt(szChatINISection,"ChatRight", 410,gszINIFilename);
}
void SaveChatToINI(PCSIDLWND pWindow)
{
CHAR szTemp[MAX_STRING] = {0};
WritePrivateProfileString(szChatINISection,"ChatTop", itoa(pWindow->Location.top, szTemp,10),gszINIFilename);
WritePrivateProfileString(szChatINISection,"ChatBottom",itoa(pWindow->Location.bottom, szTemp,10),gszINIFilename);
WritePrivateProfileString(szChatINISection,"ChatLeft", itoa(pWindow->Location.left, szTemp,10),gszINIFilename);
WritePrivateProfileString(szChatINISection,"ChatRight", itoa(pWindow->Location.right, szTemp,10),gszINIFilename);
}
void MakeChatWindow()
{
...
// should be ok now, set style etc
BitOff(MQChatWnd->Wnd.WindowStyle,CWS_CLOSE);
for (int n = 0 ; n < 0x20 ; n++)
{
if (pChatManager->ChannelMap[n]==0 || pChatManager->ChannelMap[n]==MQChatWnd)
pChatManager->ChannelMap[n]=pChatManager->ChatWnd[0];
}
LoadChatFromINI(&MQChatWnd->Wnd);
SetCXSTRText(MQChatWnd->Wnd.WindowText,"MQ");
}
VOID FreeChatWindow()
{
if (!MQChatWnd) return;
SaveChatToINI(&MQChatWnd->Wnd);
PEQCHATMGR pChatManager= *(PEQCHATMGR*)EQADDR_CHATMANAGER;
for (int n = 0 ; n < 0x20 ; n++)
{
if (pChatManager->ChannelMap[n]==0 || pChatManager->ChannelMap[n]==MQChatWnd)
pChatManager->ChannelMap[n]=pChatManager->ChatWnd[0];
}
DWORD destructor=(DWORD)MQChatWnd->Wnd.pvfTable->vector_deleting_destructor;
__asm {
push ecx;
mov ecx, MQChatWnd;
push 1;
call [destructor];
pop ecx;
};
MQChatWnd = NULL;
}Code: Select all
class CDisplay
{
public:
VOID Trampoline_CleanGameUI(VOID);
VOID Detour_CleanGameUI(VOID)
{
FreeChatWindow();
Trampoline_CleanGameUI();
}
};Code: Select all
DWORD destructor=MQChatWnd->Wnd.pvfTable->vector_deleting_destructor;
__asm {
push ecx;
mov ecx, MQChatWnd;
push 1;
call [destructor];
pop ecx;
};
Code: Select all
BitOff(MQChatWnd->Wnd.WindowStyle,CWS_CLOSE);
for (int n = 0 ; n < 0x2b ; n++)
{
if (pChatManager->ChannelMap[n]==0 || pChatManager->ChannelMap[n]==MQChatWnd)
pChatManager->ChannelMap[n]=pChatManager->ChatWnd[0];
}
Code: Select all
MQChatWnd->Wnd.WindowStyle=CWS_TITLE|CWS_MINIMIZE|CWS_BORDER|CWS_RESIZEALL;
Code: Select all
/*0x090*/ DWORD ChannelMap[0x2a]; // channel map
Code: Select all
/*0x090*/ struct _EQCHATWINDOW* ChannelMap[0x2a]; // channel map
Code: Select all
typedef struct _EQCHATMGR
{
/*0x000*/ struct _EQCHATWINDOW* ChatWnd[0x20];
/*0x080*/ DWORD NumWindows;
/*0x084*/ DWORD ActiveWindow; // CChatManager::GetActiveChatWindow
/*0x088*/ DWORD LockedWindow; // CChatManager::GetActiveChatWindow
/*0x08c*/ DWORD Unknown0x08c;
/*0x090*/ struct _EQCHATWINDOW* ChannelMap[0x20]; // channel map
/*0x110*/ BYTE Unknown0x110;
/*0x138*/ DWORD Unknown0x138;
Do we need to pad between 110 and 138 to keep the menus correct?Lax wrote:Ok, the problem was in the struct. oops. it had 0x2a available chat channels and threw off the struct.
First part of the struct fixed:The channel map integrity check should use < 0x20 instead of 0x2bCode: Select all
typedef struct _EQCHATMGR { .. /*0x110*/ BYTE Unknown0x110; /*0x138*/ DWORD Unknown0x138;