class CDoCrackWnd;
void CreateDoCrackWindow();
void DestroyDoCrackWindow();
void ReadWindowINI(PCSIDLWND pWindow);
void WriteWindowINI(PCSIDLWND pWindow);
void DoCrackWndCommand(PSPAWNINFO pChar, PCHAR szLine);
void GetCrackStat(PCHAR szCrackName);
// CDoCrackWnd window class
class CDoCrackWnd : public CCustomWnd
{
public:
CListWnd *CrackList;
CButtonWnd *LoadButton;
CDoCrackWnd():CCustomWnd("DoCrackWnd")
{
CrackList = (CListWnd*)GetChildItem("DC_CrackList");
LoadButton = (CButtonWnd*)GetChildItem("DC_LoadButton");
SetWndNotification(CDoCrackWnd);
LoadList();
}
~CDoCrackWnd()
{
}
int WndNotification(CXWnd *pWnd, unsigned int Message, void *unknown)
{
CHAR szTemp[MAX_STRING]={0}, szBuffer[MAX_STRING]={0};
if (pWnd==(CXWnd*)LoadButton) {
if (Message==XWM_LCLICK) {
//WriteChatColor("CDoCrackWnd::Button01 LCLICK", USERCOLOR_DEFAULT);
this->LoadList();
} else {
//DebugSpew("Button01 message %Xh / %d",Message,Message);
}
}
if (pWnd==(CXWnd*)CrackList) {
if (Message==XWM_LCLICK) {
sprintf(szTemp,"/docrack %s on", GetListItem(szBuffer, (DWORD)(CrackList->GetCurSel()) ) );
//DebugSpewAlways("CDoCrackWnd::CrackList LCLICK Command '%s'", szTemp);
DoCommand(NULL, szTemp);
}
if (Message==XWM_RCLICK) {
sprintf(szTemp,"/docrack %s off", GetListItem(szBuffer, (DWORD)(CrackList->GetCurSel()) ) );
//DebugSpewAlways("CDoCrackWnd::CrackList LCLICK Command '%s'", szTemp);
DoCommand(NULL, szTemp);
LoadList();
}
if (Message==XWM_LMOUSEUP) {
LoadList(); //refresh status colors after crack select
}
}
return CSidlScreenWnd::WndNotification(pWnd,Message,unkno wn);
};
void LoadList()
{
char szBuffer[MAX_STRING], szSection[MAX_STRING], szCrackName[MAX_STRING];
int i, prev=0, curListIndex=0;
DWORD crack_color;
CrackList->DeleteAll();
//DebugSpewAlways("CDoCrackWnd::LoadList(): Get sections list");
GetPrivateProfileString(NULL,NULL,NULL,szBuffer,MA X_STRING,INIFileName);
for (i=0; ((szBuffer != 0) || (szBuffer[i+1] != 0)); i++) {
//DebugSpewAlways("LoadList(): cycledsectionbuffer byte %d", i);
szSection[i-prev] = szBuffer;
if ( szBuffer==0 ) {
//DebugSpewAlways("LoadList(): found section %s", szSection);
strcpy(szCrackName, szSection);
crack_color = GetCrackStatusColor(szCrackName);
//DebugSpewAlways("LoadList(): CrackList->AddString(text='%s',crack_color=0x%X)", szCrackName, crack_color);
CrackList->AddString(CXStr(szCrackName), crack_color, 0, 0);
curListIndex++;
prev=i+1;
}
}
}
PCHAR GetListItem(PCHAR szFoundName, DWORD dwIndex)
{
char szBuffer[MAX_STRING], szSection[MAX_STRING];
sprintf(szFoundName, "GetListItem_ERROR");
int i, prev=0;
DWORD curListIndex=0;
//DebugSpewAlways("CDoCrackWnd::GetListItem(%d): Get sections list", dwIndex);
GetPrivateProfileString(NULL,NULL,NULL,szBuffer,MA X_STRING,INIFileName);
for (i=0; ((szBuffer != 0) || (szBuffer[i+1] != 0)); i++) {
//DebugSpewAlways("GetListItem(): cycledsectionbuffer byte %d", i);
szSection[i-prev] = szBuffer;
if ( szBuffer==0 ) {
if ( curListIndex == dwIndex ) {
strcpy(szFoundName, szSection);
break;
}
curListIndex++;
prev=i+1;
}
}
//DebugSpewAlways("GetListItem():Return %s", szFoundName);
return szFoundName;
}
DWORD GetCrackStatusColor(PCHAR szCrackName)
{
CHAR szAddr[MAX_STRING] = {0};
CHAR szIniKey[MAX_STRING] = {0};
CHAR szCrack[MAX_STRING] = {0};
CHAR szNormal[MAX_STRING] = {0};
CHAR szBuffer[MAX_STRING] = {0};
CHAR szTextBuffer[MAX_STRING] = {0};
DWORD dwAddr;
int iChange = 0, iByte, iCrackSize;
BYTE byCrack[20];
BYTE byNormal[20];
DWORD crack_color;
while(1)
{
sprintf(szAddr,"Address%d",iChange);
GetPrivateProfileString(szCrackName,szAddr,"NULL",szBuffer,MAX_STRING,INIFileName);
if (!strcmp(szBuffer,"NULL"))
{
if ( iChange==0 )
{
sprintf(szTextBuffer,"GetCrackStatusColor(): no match for '%s'", szCrackName );
crack_color = ConColorToARGB(CONCOLOR_RED); //data error
}
break;
}
//converts string address to hex
dwAddr = strtoul(szBuffer,NULL,16);
sprintf(szIniKey,"Crack%d",iChange);
GetPrivateProfileString(szCrackName,szIniKey,"NULL",szCrack,MAX_STRING,INIFileName);
if (!strcmp(szCrack,"NULL"))
{
DebugSpewAlways("[%s] Crack error, no associated crack value set with address: 0x%x", szCrackName, dwAddr);
crack_color = ConColorToARGB(CONCOLOR_RED); //data error
break;
}
sprintf(szIniKey,"Normal%d",iChange);
GetPrivateProfileString(szCrackName,szIniKey,"NULL",szNormal,MAX_STRING,INIFileName);
if (!strcmp(szNormal,"NULL"))
{
DebugSpewAlways(szTextBuffer,"[%s] Crack error, no associated normal value set with address: 0x%x", szCrackName, dwAddr);
crack_color = ConColorToARGB(CONCOLOR_RED); //data error
break;
}
// convert crack string into actual bytes
char *pTempPos, *pCurPos = szCrack;
char *pEndCrack = szCrack + strlen(szCrack);
iByte = 0;
while (pCurPos < pEndCrack)
{
byCrack[iByte] = (unsigned char)strtol(pCurPos, &pTempPos, 16);
iByte++;
if (iByte > 20 )
{
DebugSpewAlways(szTextBuffer, "[%s] Crack Error: Crack too big.", szCrackName);
crack_color = ConColorToARGB(CONCOLOR_RED); //data error
}
pCurPos = pTempPos+1;
}
iCrackSize = iByte;
// convert normal string into actual bytes
pCurPos = szNormal;
pEndCrack = szNormal + strlen(szNormal);
iByte = 0;
while (pCurPos < pEndCrack)
{
byNormal[iByte] = (unsigned char)strtol(pCurPos, &pTempPos, 16);
iByte++;
pCurPos = pTempPos+1;
}
if (iByte != iCrackSize)
{
DebugSpewAlways("[%s] Crack error, crack mismatch crack size: %u normal size: %u", szCrackName, iCrackSize, iByte);
crack_color = ConColorToARGB(CONCOLOR_RED); //data error
}
// look for the first byte that is different in the crack from the normal
// should be the 1st byte for gods sake :)
for (iByte = 0; iByte < iCrackSize; iByte++)
{
if (byCrack[iByte] != byNormal[iByte])
break;
}
if (iByte == iCrackSize)
{
DebugSpewAlways("[%s] Crack Error: no difference between the crack and normal bytes.", szCrackName);
crack_color = ConColorToARGB(CONCOLOR_RED); //data error
}
if (*(((LPBYTE)dwAddr)+iByte) == byCrack[iByte])
{
crack_color = ConColorToARGB(CONCOLOR_GREEN); //on
}
else if (*(((LPBYTE)dwAddr)+iByte) == byNormal[iByte])
{
crack_color = ConColorToARGB(CONCOLOR_BLUE); //off
}
else
{
//problem
DebugSpewAlways("[%s] Crack warning! No match at addr: 0x%X [%X/%X]", szCrackName, dwAddr, byNormal[iByte], byCrack[iByte]);
crack_color = ConColorToARGB(CONCOLOR_YELLOW); //mismatch/warning
}
iChange++;
}
return crack_color;
}
};
CDoCrackWnd *MyWnd = 0;
// API are here just to show you where the stuff goes to tie it all together
PLUGIN_API VOID OnZoned(VOID)
{
//if you use map enabling in this callback... do it before you call LoadList!
if ( gGameState==GAMESTATE_INGAME && MyWnd ) {
MyWnd->LoadList(); //can't load UI element lists if SetGameState hasn't loaded them yet
}
}
// ***************************************
// DoCrackWnd UI stuff
// ***************************************
PLUGIN_API VOID OnCleanUI(VOID)
{
DebugSpewAlways("MQ2DoCrack::OnCleanUI()");
DestroyDoCrackWindow();
}
PLUGIN_API VOID OnReloadUI(VOID)
{
DebugSpewAlways("MQ2DoCrack::OnReloadUI()");
CreateDoCrackWindow();
}
CHAR szSettingINISection[MAX_STRING] = {0};
void ReadWindowINI(PCSIDLWND pWindow)
{
//DebugSpewAlways("MQ2DoCrack::ReadWindowINI()");
CHAR Buffer[MAX_STRING] = {0};
sprintf(szSettingINISection,"Settings",((PCHARINFO)pCharData)->Server,((PCHARINFO)pCharData)->Name);
pWindow->Location.top = GetPrivateProfileInt(szSettingINISection,"Top", 401,INIFileName);
pWindow->Location.bottom = GetPrivateProfileInt(szSettingINISection,"Bottom", 723,INIFileName);
pWindow->Location.left = GetPrivateProfileInt(szSettingINISection,"Left", 290,INIFileName);
pWindow->Location.right = GetPrivateProfileInt(szSettingINISection,"Right", 437,INIFileName);
pWindow->Locked = GetPrivateProfileInt(szSettingINISection,"Locked", 0,INIFileName);
pWindow->Fades = GetPrivateProfileInt(szSettingINISection,"Fades", 1,INIFileName);
pWindow->TimeMouseOver = GetPrivateProfileInt(szSettingINISection,"Delay", 2000,INIFileName);
pWindow->FadeDuration = GetPrivateProfileInt(szSettingINISection,"Duration", 500,INIFileName);
pWindow->Alpha = GetPrivateProfileInt(szSettingINISection,"Alpha", 255,INIFileName);
pWindow->FadeToAlpha = GetPrivateProfileInt(szSettingINISection,"FadeToAlpha", 255,INIFileName);
pWindow->BGType = GetPrivateProfileInt(szSettingINISection,"BGType", 1,INIFileName);
pWindow->BGColor.R = GetPrivateProfileInt(szSettingINISection,"BGTint.red", 255,INIFileName);
pWindow->BGColor.G = GetPrivateProfileInt(szSettingINISection,"BGTint.green", 255,INIFileName);
pWindow->BGColor.B = GetPrivateProfileInt(szSettingINISection,"BGTint.blue", 255,INIFileName);
GetPrivateProfileString(szSettingINISection,"WindowTitle","MQ2DoCrack",Buffer,MAX_STRING,INIFileName);
SetCXStr(&pWindow->WindowText,Buffer);
}
void WriteWindowINI(PCSIDLWND pWindow)
{
//DebugSpewAlways("MQ2DoCrack::WriteWindowINI()");
CHAR szTemp[MAX_STRING] = {0};
if (pWindow->Minimized)
{
WritePrivateProfileString(szSettingINISection,"Top", itoa(pWindow->OldLocation.top, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"Bottom", itoa(pWindow->OldLocation.bottom, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"Left", itoa(pWindow->OldLocation.left, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"Right", itoa(pWindow->OldLocation.right, szTemp,10),INIFileName);
}
else
{
WritePrivateProfileString(szSettingINISection,"Top", itoa(pWindow->Location.top, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"Bottom", itoa(pWindow->Location.bottom, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"Left", itoa(pWindow->Location.left, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"Right", itoa(pWindow->Location.right, szTemp,10),INIFileName);
}
WritePrivateProfileString(szSettingINISection,"Locked", itoa(pWindow->Locked, szTemp,10),INIFileName);
GetCXStr(pWindow->WindowText,szTemp);
WritePrivateProfileString(szSettingINISection,"WindowTitle", szTemp,INIFileName);
WritePrivateProfileString(szSettingINISection,"Fades", itoa(pWindow->Fades, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"Delay", itoa(pWindow->MouseOver, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"Duration", itoa(pWindow->FadeDuration, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"Alpha", itoa(pWindow->Alpha, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"FadeToAlpha", itoa(pWindow->FadeToAlpha, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"BGType", itoa(pWindow->BGType, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"BGTint.red", itoa(pWindow->BGColor.R, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"BGTint.green", itoa(pWindow->BGColor.G, szTemp,10),INIFileName);
WritePrivateProfileString(szSettingINISection,"BGTint.blue", itoa(pWindow->BGColor.B, szTemp,10),INIFileName);
}
void CreateDoCrackWindow()
{
//DebugSpewAlways("MQ2DoCrack::CreateDoCrackWindow()");
if (MyWnd) return;
if (pSidlMgr->FindScreenPieceTemplate("DoCrackWnd")) {
MyWnd = new CDoCrackWnd();
ReadWindowINI((PCSIDLWND)MyWnd);
WriteWindowINI((PCSIDLWND)MyWnd);
}
}
void DestroyDoCrackWindow()
{
//DebugSpewAlways("MQ2DoCrack::DestroyDoCrackWindow()");
if (MyWnd)
{
WriteWindowINI((PCSIDLWND)MyWnd);
delete MyWnd;
MyWnd=0;
}
}
// ************************************************** *************************
// Function: DoCrackWndCommand
// Description: How we hide/show our docrack window
// ************************************************** *************************
VOID DoCrackWndCommand(PSPAWNINFO pChar, PCHAR szLine)
{
if (!MyWnd) {
WriteChatColor("/docrackwnd: window init problem",USERCOLOR_DEFAULT);
return;
}
if (szLine[0]==0) {
WriteChatColor("/docrackwnd: show|hide|load",USERCOLOR_DEFAULT);
((CXWnd*)MyWnd)->Show(1,1);
return;
}
if ( strstr(szLine, "off") || strstr(szLine, "hide") ) {
((CXWnd*)MyWnd)->Show(0,0);
} else if ( strstr(szLine, "load") ) {
WriteChatColor("/docrackwnd: Reload Cracklist Display",USERCOLOR_DEFAULT);
MyWnd->LoadList();
((CXWnd*)MyWnd)->Show(1,1);
} else {
((CXWnd*)MyWnd)->Show(1,1);
}
}