l2-unlegits/l2ooghelper/NpcHtmlMessageDlg.cpp
2012-02-01 05:25:08 +00:00

423 lines
9.6 KiB
C++
Raw Blame History

#include "stdafx.h"
#include "Resource.h"
#include "Logger.h"
#include "NpcHtmlMessageDlg.h"
#include "L2Client.h"
extern HINSTANCE g_hInst;
NpcHtmlMessageDlg::NpcHtmlMessageDlg( void *pvL2Client )
{
m_hDlg = m_hWndParent = NULL;
m_html = NULL;
m_itemID = m_questID = 0;
m_npc = NULL;
m_pvL2Client = pvL2Client;
// childs
m_hWndHtml = m_hWndCombo = m_hWndBypassText = NULL;
}
NpcHtmlMessageDlg::~NpcHtmlMessageDlg()
{
destroyDialog();
if( m_html )
{
free( m_html );
m_html = NULL;
}
}
bool NpcHtmlMessageDlg::createDialog( HWND hWndParent )
{
m_hWndParent = hWndParent;
m_hDlg = CreateDialogParam( g_hInst, MAKEINTRESOURCE(IDD_NPCHTML), hWndParent,
NpcHtmlMessageDlgProc, (LPARAM)this );
if( m_hDlg ) return true;
// error
m_hWndParent = NULL;
return false;
}
void NpcHtmlMessageDlg::destroyDialog()
{
if( m_hDlg )
{
DestroyWindow( m_hDlg );
m_hDlg = NULL;
}
}
void NpcHtmlMessageDlg::showWindow( bool bShow )
{
if( m_hDlg )
{
if( bShow ) ShowWindow( m_hDlg, SW_SHOWNORMAL );
else ShowWindow( m_hDlg, SW_HIDE );
}
}
void NpcHtmlMessageDlg::displayNPCHTML( const TCHAR *html, L2Npc *pNpc,
unsigned int itemID, unsigned int questID )
{
if( !html ) return;
//
m_itemID = itemID;
m_questID = questID;
m_npc = pNpc;
if( m_html ) free( m_html );
m_html = _tcsdup( html );
//
NpcHtmlMessageDlg::wnd_initHtml( m_hDlg );
showWindow( true );
}
class NpcHtmlLink
{
public:
NpcHtmlLink() { text[0] = 0; bypass[0] = 0; next = NULL; }
~NpcHtmlLink() { if( next ) delete next; }
public:
wchar_t text[128];
wchar_t bypass[128];
NpcHtmlLink *next;
};
class NpcHtmlInfo
{
public:
NpcHtmlInfo()
{
html = NULL;
head = NULL;
}
~NpcHtmlInfo()
{
if( html ) free( html );
html = NULL;
if( head ) delete head;
head = NULL;
}
public:
wchar_t *html;
NpcHtmlLink *head;
};
void process_bypass( NpcHtmlInfo *info, wchar_t *tagHeader, wchar_t *tagTextStart )
{
// a action="bypass -h npc_268437990_Quest 1106_teleport_to_fantasy_isle" msg="811;Fantasy Island"
//log_error( LOG_OK, "[%S] [%S]\n", tagHeader, tagTextStart );
wchar_t bypass[128] = {0};
wchar_t *pbypass = bypass;
wchar_t text[128] = {0};
wchar_t *ptext = text;
wchar_t *w = wcschr( tagHeader, L'\"' );
if( !w ) return;
w++;
while( (*w) != L'\"' ) { (*pbypass) = (*w); pbypass++, w++; }
(*pbypass) = 0;
w = tagTextStart;
while( (*w) != L'<' ) { (*ptext) = (*w); ptext++, w++; }
(*ptext) = 0;
//
NpcHtmlLink *adding = new NpcHtmlLink();
wcscpy( adding->bypass, bypass );
wcscpy( adding->text, text );
adding->next = NULL;
//
if( !info->head ) info->head = adding;
else
{
NpcHtmlLink *cur = info->head;
while( cur->next ) cur = cur->next;
cur->next = adding;
}
}
NpcHtmlInfo *parse_NpcHtml( wchar_t *html )
{
if( !html ) return NULL;
NpcHtmlInfo *info = new NpcHtmlInfo();
//
info->html = (wchar_t *)malloc( 20480 );
if( !info->html ) { delete info; return NULL; }
info->html[0] = 0;
//
wchar_t *phtml = html;
wchar_t *pinfohtml = info->html;
wchar_t curChar = phtml[0];
wchar_t tagHeader[256] = {0};
wchar_t *ptagHeader = tagHeader;
bool in_tag = false;
//
const int maxCharsInLine = 40;
int curCharsInLine = 0;
bool break_next_space = false;
//
while( curChar )
{
curChar = (*phtml);
if( curChar == L'<' )
{
in_tag = true;
phtml++;
tagHeader[0] = (*phtml);
ptagHeader = tagHeader;
ptagHeader++;
phtml++;
}
else if( curChar == L'>' )
{
(*ptagHeader) = 0;
in_tag = false;
phtml++;
// parse passed tag
if( (_wcsicmp( tagHeader, L"br" ) == 0) || (_wcsicmp( tagHeader, L"br1" ) == 0) )
{
(*pinfohtml) = L'\r';
pinfohtml++;
(*pinfohtml) = L'\n';
pinfohtml++;
(*pinfohtml) = 0;
curCharsInLine = 0;
break_next_space = false;
}
else if( (wcsstr( tagHeader, L"a " ) == tagHeader) || (wcsstr( tagHeader, L"A " ) == tagHeader) )
{
process_bypass( info, tagHeader, phtml );
}
}
else if( (curChar == L'\r') || (curChar == L'\n') || (curChar == L' ') || (curChar == L'\t') )
{
if( break_next_space ) // insert line break
{
(*pinfohtml) = L'\r';
pinfohtml++;
(*pinfohtml) = L'\n';
pinfohtml++;
(*pinfohtml) = 0;
curCharsInLine = 0; // new line started
break_next_space = false; // we should not break at next whitespace )
}
// append space instead of \r, \n, \t
else if( curChar == L' ' )
{
if( in_tag )
{
(*ptagHeader) = L' ';
ptagHeader++;
(*ptagHeader) = 0;
}
else
{
(*pinfohtml) = L' ';
pinfohtml++;
}
}
phtml++;
}
else
{
if( !in_tag )
{
if( curChar != L'\n' && curChar != L'\r' )
{
(*pinfohtml) = curChar;
pinfohtml++;
(*pinfohtml) = 0;
//
curCharsInLine++;
if( curCharsInLine >= maxCharsInLine ) break_next_space = true;
}
}
else
{
(*ptagHeader) = curChar;
ptagHeader++;
(*ptagHeader) = 0;
}
phtml++;
}
}
//
return info;
}
struct NpcHtmlDlgSt
{
NpcHtmlMessageDlg *cls;
NpcHtmlInfo *htmlInfo;
};
INT_PTR CALLBACK NpcHtmlMessageDlg::NpcHtmlMessageDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch( uMsg )
{
case WM_INITDIALOG:
{
// get ptr to class
NpcHtmlMessageDlg *cls = (NpcHtmlMessageDlg *)lParam;
// save all info as window user data
NpcHtmlDlgSt *st = (NpcHtmlDlgSt *)malloc( sizeof(NpcHtmlDlgSt) );
st->cls = cls; // pointer to class
st->htmlInfo = NULL; // no html and links at this time
SetWindowLongPtr( hDlg, GWLP_USERDATA, (LONG_PTR)st );
// get children
cls->m_hWndHtml = GetDlgItem( hDlg, IDC_EDIT1 );
cls->m_hWndCombo = GetDlgItem( hDlg, IDC_COMBO1 );
cls->m_hWndBypassText = GetDlgItem( hDlg, IDC_EDIT2 );
} break;
case WM_COMMAND:
{
switch( LOWORD( wParam ) )
{
case IDCANCEL: NpcHtmlMessageDlg::wnd_onCancel( hDlg ); break;
case IDOK: NpcHtmlMessageDlg::wnd_onOK( hDlg ); break;
case IDC_COMBO1:
{
int code = HIWORD(wParam);
if( code == CBN_SELCHANGE ) NpcHtmlMessageDlg::wnd_onCombo1SelChange( hDlg );
} break;
}
return FALSE; // message was not processed
} break;
case WM_DESTROY: NpcHtmlMessageDlg::wnd_onDestroy( hDlg ); break;
case WM_KEYDOWN:
{
log_error( LOG_ERROR, "NpcHtmlMessageDlgProc(): WM_KEYDOWN\n" );
} break;
default: return FALSE; break;
}
return TRUE; // message was processed
}
void NpcHtmlMessageDlg::wnd_initHtml( HWND hDlg )
{
NpcHtmlDlgSt *st = (NpcHtmlDlgSt *)GetWindowLongPtr( hDlg, GWLP_USERDATA );
if( !st ) return;
// set dlg title
if( st->cls->m_npc )
{
TCHAR title[512] = {0};
wsprintf( title, TEXT("%s (%s)"), st->cls->m_npc->charName, st->cls->m_npc->charTitle );
SetWindowText( hDlg, title );
}
else SetWindowText( hDlg, TEXT("NpcHtmlMessage") );
// clear prev. html
SetWindowText( st->cls->m_hWndHtml, TEXT("no text") );
if( st->htmlInfo )
{
delete st->htmlInfo;
st->htmlInfo = NULL;
}
// parse and set html
NpcHtmlInfo *htmlInfo = parse_NpcHtml( st->cls->m_html );
st->htmlInfo = htmlInfo; // pointer to html info...
if( st->htmlInfo )
SetDlgItemText( hDlg, IDC_EDIT1, st->htmlInfo->html );
// init combobox
ComboBox_ResetContent( st->cls->m_hWndCombo );
if( st->htmlInfo )
{
NpcHtmlLink *cur = st->htmlInfo->head;
while( cur )
{
ComboBox_AddString( st->cls->m_hWndCombo, cur->text );
cur = cur->next;
}
}
// init bypass text
SetWindowText( st->cls->m_hWndBypassText, TEXT("") );
}
void NpcHtmlMessageDlg::wnd_onCancel( HWND hDlg )
{
ShowWindow( hDlg, SW_HIDE );
}
void NpcHtmlMessageDlg::wnd_onOK( HWND hDlg )
{
NpcHtmlDlgSt *st = (NpcHtmlDlgSt *)GetWindowLongPtr( hDlg, GWLP_USERDATA );
if( !st ) return;
// save selection and post message to notify window
int cur_sel = ComboBox_GetCurSel( st->cls->m_hWndCombo );
if( cur_sel == -1 ) return;
//
ShowWindow( hDlg, SW_HIDE );
//
int nPassed = 0;
NpcHtmlLink *cur = st->htmlInfo->head;
while( cur )
{
if( nPassed == cur_sel )
{
if( cur->bypass )
{
// send request bypass to server
class L2Client *pcl = (L2Client *)st->cls->m_pvL2Client;
if( wcsstr( cur->bypass, L"bypass -h " ) )
{
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> "bypass -h " <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
pcl->send_RequestBypassToServer( cur->bypass + 10 /*wcslen( L"bypass -h " )*/ );
}
else if( wcsstr( cur->bypass, L"link " ) )
{
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> "link " <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
pcl->send_RequestLinkHtml( cur->bypass + 5 /*wcslen( L"link " )*/ );
}
else
{
log_error( LOG_ERROR, "Possibly wrong bypass in HTML from server!\n[%S]\n", cur->bypass );
}
}
break;
}
else
{
cur = cur->next;
nPassed++;
}
}
}
void NpcHtmlMessageDlg::wnd_onCombo1SelChange( HWND hDlg )
{
NpcHtmlDlgSt *st = (NpcHtmlDlgSt *)GetWindowLongPtr( hDlg, GWLP_USERDATA );
if( !st ) return;
int cur_sel = ComboBox_GetCurSel( st->cls->m_hWndCombo );
if( cur_sel == -1 ) return;
//
if( !st->htmlInfo ) return;
int nPassed = 0;
NpcHtmlLink *cur = st->htmlInfo->head;
while( cur )
{
if( nPassed == cur_sel )
{
SetWindowText( st->cls->m_hWndBypassText, cur->bypass );
break;
}
else
{
cur = cur->next;
nPassed++;
}
}
}
void NpcHtmlMessageDlg::wnd_onDestroy( HWND hDlg )
{
NpcHtmlDlgSt *st = (NpcHtmlDlgSt *)GetWindowLongPtr( hDlg, GWLP_USERDATA );
if( !st ) return;
delete st->htmlInfo;
st->htmlInfo = NULL;
free( st );
SetWindowLongPtr( hDlg, GWLP_USERDATA, 0 );
}