From 4675edca195124c58ed487845bddfdd194cb807e Mon Sep 17 00:00:00 2001 From: konelav Date: Tue, 8 Mar 2016 01:26:02 +0300 Subject: [PATCH 01/26] Log contents added option: log data "as-is" (as received from server), or log all highlighted/substituted/showed text (as it user see) --- sources/LogParamsPage.cpp | 2 ++ sources/LogParamsPage.h | 1 + sources/MainFrm.cpp | 2 ++ sources/resource.h | 4 +++- sources/smc.rc | 12 +++++++++--- sources/smcDoc.cpp | 3 ++- sources/ttcoreex/JmcObj.cpp | 13 ++++++++++--- sources/ttcoreex/Misc.cpp | 6 +++++- sources/ttcoreex/TINTINX.H | 1 + sources/ttcoreex/ttcoreex.cpp | 30 +++++++++++++++++++++++------- 10 files changed, 58 insertions(+), 16 deletions(-) diff --git a/sources/LogParamsPage.cpp b/sources/LogParamsPage.cpp index ce9ddfe..37a7e00 100644 --- a/sources/LogParamsPage.cpp +++ b/sources/LogParamsPage.cpp @@ -22,6 +22,7 @@ CLogParamsPage::CLogParamsPage() : CPropertyPage(CLogParamsPage::IDD, IDS_LOG_PA m_bRMASupport = FALSE; m_bAppendLogTitle = TRUE; m_nAppendMode = 0; + m_nLogAs = 0; m_LogType = -1; //}}AFX_DATA_INIT } @@ -39,6 +40,7 @@ void CLogParamsPage::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_RMA_SUPPORT, m_bRMASupport); DDX_Check(pDX, IDC_LOG_TITLE, m_bAppendLogTitle); DDX_Radio(pDX, IDC_OVERWRITE_LOG_MODE, m_nAppendMode); + DDX_Radio(pDX, IDC_WRITE_LOG_AS_SHOWN_BY_SERVER, m_nLogAs); DDX_Radio(pDX, IDC_LOGTYPE_TEXT, m_LogType); //}}AFX_DATA_MAP } diff --git a/sources/LogParamsPage.h b/sources/LogParamsPage.h index 4bce933..23662d7 100644 --- a/sources/LogParamsPage.h +++ b/sources/LogParamsPage.h @@ -31,6 +31,7 @@ class CLogParamsPage : public CPropertyPage BOOL m_bRMASupport; BOOL m_bAppendLogTitle; int m_nAppendMode; + int m_nLogAs; int m_logTypeHtml; int m_logTypeText; int m_logTypeAnsi; diff --git a/sources/MainFrm.cpp b/sources/MainFrm.cpp index f4c3167..b6d626b 100644 --- a/sources/MainFrm.cpp +++ b/sources/MainFrm.cpp @@ -573,6 +573,7 @@ void CMainFrame::OnOptionsOptions() pg4.m_bRMASupport = bRMASupport; pg4.m_nAppendMode = bDefaultLogMode ? 1 : 0 ; pg4.m_bAppendLogTitle = bAppendLogTitle; + pg4.m_nLogAs = bLogAsUserSeen ? 1 : 0; memcpy(&pg5.m_guidLang , &theApp.m_guidScriptLang, sizeof(GUID)); pg5.m_bAllowDebug = bAllowDebug; @@ -628,6 +629,7 @@ void CMainFrame::OnOptionsOptions() bHTML = pg4.m_LogType == 1; bRMASupport = bANSILog ? pg4.m_bRMASupport : FALSE; bDefaultLogMode = pg4.m_nAppendMode ; + bLogAsUserSeen = pg4.m_nLogAs; bAppendLogTitle = pg4.m_bAppendLogTitle; if ( memcmp(&theApp.m_guidScriptLang, &pg5.m_guidLang , sizeof(GUID) ) ) { diff --git a/sources/resource.h b/sources/resource.h index dfdc944..ecadeba 100644 --- a/sources/resource.h +++ b/sources/resource.h @@ -155,6 +155,8 @@ #define IDC_EDIT_EMUL_LOG_PATH 1118 #define IDC_BTN_STARTSTOP_EMUL_LOG 1119 #define IDC_CHK_EMULATE_RMA 1120 +#define IDC_WRITE_LOG_AS_SHOWN_BY_SERVER 1121 +#define IDC_WRITE_LOG_AS_SEEN_BY_USER 1122 #define ID_OPTIONS_SCROLLBUFFER 32771 #define ID_OPTIONS_FONT 32772 #define ID_OPTIONS_HOTKEYS 32774 @@ -223,7 +225,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 179 #define _APS_NEXT_COMMAND_VALUE 32809 -#define _APS_NEXT_CONTROL_VALUE 1121 +#define _APS_NEXT_CONTROL_VALUE 1123 #define _APS_NEXT_SYMED_VALUE 108 #endif #endif diff --git a/sources/smc.rc b/sources/smc.rc index c39a158..1a22ef6 100644 --- a/sources/smc.rc +++ b/sources/smc.rc @@ -307,7 +307,7 @@ BEGIN PUSHBUTTON "Standard",IDC_RESTORE_DEFAULT,184,42,50,14 END -IDD_LOG_PARAMS_PAGE DIALOG DISCARDABLE 0, 0, 199, 98 +IDD_LOG_PARAMS_PAGE DIALOG DISCARDABLE 0, 0, 227, 98 STYLE WS_CHILD FONT 8, "MS Sans Serif" BEGIN @@ -315,7 +315,7 @@ BEGIN BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,131,18,57,10 CONTROL "Append",IDC_APPEND_LOG_MODE,"Button",BS_AUTORADIOBUTTON, 131,28,58,10 - GROUPBOX "Default writing",IDC_STATIC,125,8,65,35,WS_GROUP + GROUPBOX "Default writing",IDC_STATIC,125,8,90,35,WS_GROUP GROUPBOX "Log format",IDC_STATIC,10,7,89,75 CONTROL "Write RMA",IDC_RMA_SUPPORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,41,64,49,10 @@ -326,7 +326,13 @@ BEGIN CONTROL "ANSI (+Esc colors)",IDC_LOGTYPE_ANSI,"Button", BS_AUTORADIOBUTTON,18,50,75,10 CONTROL "Append log title",IDC_LOG_TITLE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,125,47,65,10 + BS_AUTOCHECKBOX | WS_TABSTOP,130,57,65,10 + GROUPBOX "Log contents",IDC_STATIC,125,47,89,46 + CONTROL "As shown by Server",IDC_WRITE_LOG_AS_SHOWN_BY_SERVER, + "Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,129, + 69,78,9 + CONTROL "As seen by User",IDC_WRITE_LOG_AS_SEEN_BY_USER,"Button", + BS_AUTORADIOBUTTON,129,81,78,9 END IDD_SCRIPT_PAGE DIALOG DISCARDABLE 0, 0, 209, 98 diff --git a/sources/smcDoc.cpp b/sources/smcDoc.cpp index 269152a..b8abdcb 100644 --- a/sources/smcDoc.cpp +++ b/sources/smcDoc.cpp @@ -591,7 +591,7 @@ BOOL CSmcDoc::OnNewDocument() bANSILog = AfxGetApp()->GetProfileInt("ANSI" , "ANSILog" , 0); bDefaultLogMode = AfxGetApp()->GetProfileInt("ANSI" , "AppendMode" , 0); bHTML = AfxGetApp()->GetProfileInt("ANSI" , "HTMLLog" , 0); - + bLogAsUserSeen = AfxGetApp()->GetProfileInt("ANSI" , "LogAsUserSeen" , 0); bIACSendSingle = AfxGetApp()->GetProfileInt("Substitution" , "IACSendSingle" , 0); bIACReciveSingle = AfxGetApp()->GetProfileInt("Substitution" , "IACReciveSingle" , 0); @@ -719,6 +719,7 @@ BOOL CSmcDoc::DoProfileSave() AfxGetApp()->WriteProfileInt("ANSI" , "ANSILog" , bANSILog); AfxGetApp()->WriteProfileInt("ANSI" , "AppendMode" , bDefaultLogMode); AfxGetApp()->WriteProfileInt("ANSI" , "HTMLLog" , bHTML); + AfxGetApp()->WriteProfileInt("ANSI" , "LogAsUserSeen" , bLogAsUserSeen); ::WritePrivateProfileBinary("Colors" , "Foreground", (LPBYTE)m_ForeColors, sizeof(m_ForeColors), szGLOBAL_PROFILE); diff --git a/sources/ttcoreex/JmcObj.cpp b/sources/ttcoreex/JmcObj.cpp index 6d6e3e9..d65e94b 100644 --- a/sources/ttcoreex/JmcObj.cpp +++ b/sources/ttcoreex/JmcObj.cpp @@ -30,9 +30,16 @@ STDMETHODIMP CJmcObj::ShowMe(BSTR varText, BSTR varColor) if ( varColor ) { add_codes(W2A(varText), result, W2A(varColor)); - tintin_puts2(result); - } else - tintin_puts2(W2A(varText)); + } else { + strcpy(result, W2A(varText)); + } + + if ( bLogAsUserSeen ) { + log(processLine(result)); + log("\n"); + } + tintin_puts2(result); + return S_OK; } diff --git a/sources/ttcoreex/Misc.cpp b/sources/ttcoreex/Misc.cpp index 9e14aeb..0a0ddac 100644 --- a/sources/ttcoreex/Misc.cpp +++ b/sources/ttcoreex/Misc.cpp @@ -226,7 +226,11 @@ void showme_command(char *arg) prepare_actionalias(right,result); add_codes(result, strng, left); } - + + if (bLogAsUserSeen) { + log(processLine(strng)); + log("\n"); + } tintin_puts2(strng); } /***********************/ diff --git a/sources/ttcoreex/TINTINX.H b/sources/ttcoreex/TINTINX.H index 12f8dca..820e5c8 100644 --- a/sources/ttcoreex/TINTINX.H +++ b/sources/ttcoreex/TINTINX.H @@ -65,6 +65,7 @@ extern BOOL DLLEXPORT bDisplayCommands; extern BOOL DLLEXPORT bDisplayInput; extern BOOL DLLEXPORT bMinimizeToTray; extern BOOL DLLEXPORT bHTML; +extern BOOL DLLEXPORT bLogAsUserSeen; extern BOOL DLLEXPORT bAllowDebug; extern BOOL DLLEXPORT bIACSendSingle, bIACReciveSingle; extern int DLLEXPORT nScripterrorOutput; diff --git a/sources/ttcoreex/ttcoreex.cpp b/sources/ttcoreex/ttcoreex.cpp index 08c03bf..c04cd43 100644 --- a/sources/ttcoreex/ttcoreex.cpp +++ b/sources/ttcoreex/ttcoreex.cpp @@ -59,6 +59,7 @@ BOOL DLLEXPORT bPasswordEcho = TRUE; BOOL DLLEXPORT bConnectBeep; BOOL DLLEXPORT bAutoReconnect; BOOL DLLEXPORT bHTML; +BOOL DLLEXPORT bLogAsUserSeen; BOOL DLLEXPORT bAllowDebug = FALSE; BOOL DLLEXPORT bIACSendSingle, bIACReciveSingle; int DLLEXPORT nScripterrorOutput; // 0 - msgbox, 1- window, 2- output @@ -827,6 +828,7 @@ int read_buffer_mud(char *buffer) static void process_incoming(char* buffer) { char linebuffer[BUFFER_SIZE], *cpsource, *cpdest; + char line_to_log[BUFFER_SIZE]; int LastLineLen = 0, n; @@ -855,16 +857,22 @@ static void process_incoming(char* buffer) if(*cpsource=='\n' /*|| *cpsource=='\r'*/ || *cpsource==0x1) { *cpdest='\0'; + if ( !bLogAsUserSeen ) { + strcpy(line_to_log, linebuffer); + } + if ( bProcess ) { + do_one_line(linebuffer); + } + if ( bLogAsUserSeen ) { + strcpy(line_to_log, linebuffer); + } + //vls-begin// #logadd + #logpass // multiple output if(hLogFile.is_open() && !bLogPassedLine) { - log(processLine(linebuffer)); + log(processLine(line_to_log)); log("\n"); } - if ( bProcess ) { - do_one_line(linebuffer); - } - bLogPassedLine = FALSE; //vls-end// @@ -898,12 +906,20 @@ static void process_incoming(char* buffer) strcpy(last_line , linebuffer); } else { //vls-begin// #logadd + #logpass // multiple output + if ( !bLogAsUserSeen ) { + strcpy(line_to_log, linebuffer); + } if ( bProcess ) { - do_one_line(linebuffer); + do_one_line(linebuffer); + } + if ( bLogAsUserSeen ) { + strcpy(line_to_log, linebuffer); } + //vls-begin// #logadd + #logpass // multiple output if(hLogFile.is_open() && !bLogPassedLine) { - log(processLine(linebuffer)); + log(processLine(line_to_log)); + log("\n"); } bLogPassedLine = FALSE; From feecdc1704fc630f0f89e55fd50ecef919142433 Mon Sep 17 00:00:00 2001 From: konelav Date: Tue, 8 Mar 2016 03:06:14 +0300 Subject: [PATCH 02/26] HTML live logs added option to write "live" html logs, also moved html templeates from embedded resources to separate .template files --- sources/LogParamsPage.cpp | 5 + sources/LogParamsPage.h | 2 + sources/MainFrm.cpp | 2 + sources/html.log.template | 76 ++++++++ sources/htmltimestamps.log.template | 286 ++++++++++++++++++++++++++++ sources/resource.h | 3 +- sources/smc.rc | 13 +- sources/smcDoc.cpp | 2 + sources/ttcoreex/Logs.cpp | 64 ++++++- sources/ttcoreex/Logs.h | 5 +- sources/ttcoreex/TINTINX.H | 1 + sources/ttcoreex/ttcoreex.cpp | 1 + sources/ttcoreex/ttcoreex.rc | 1 + 13 files changed, 451 insertions(+), 10 deletions(-) create mode 100644 sources/html.log.template create mode 100644 sources/htmltimestamps.log.template diff --git a/sources/LogParamsPage.cpp b/sources/LogParamsPage.cpp index 37a7e00..c5c2eee 100644 --- a/sources/LogParamsPage.cpp +++ b/sources/LogParamsPage.cpp @@ -20,6 +20,7 @@ CLogParamsPage::CLogParamsPage() : CPropertyPage(CLogParamsPage::IDD, IDS_LOG_PA { //{{AFX_DATA_INIT(CLogParamsPage) m_bRMASupport = FALSE; + m_bHTMLTimestamps = FALSE; m_bAppendLogTitle = TRUE; m_nAppendMode = 0; m_nLogAs = 0; @@ -37,7 +38,9 @@ void CLogParamsPage::DoDataExchange(CDataExchange* pDX) //{{AFX_DATA_MAP(CLogParamsPage) DDX_Control(pDX, IDC_LOGTYPE_TEXT, m_LogTypeControl); DDX_Control(pDX, IDC_RMA_SUPPORT, m_RmaSupportControl); + DDX_Control(pDX, IDC_HTML_TIMESTAMPS, m_HtmlTimestampsControl); DDX_Check(pDX, IDC_RMA_SUPPORT, m_bRMASupport); + DDX_Check(pDX, IDC_HTML_TIMESTAMPS, m_bHTMLTimestamps); DDX_Check(pDX, IDC_LOG_TITLE, m_bAppendLogTitle); DDX_Radio(pDX, IDC_OVERWRITE_LOG_MODE, m_nAppendMode); DDX_Radio(pDX, IDC_WRITE_LOG_AS_SHOWN_BY_SERVER, m_nLogAs); @@ -63,6 +66,7 @@ void CLogParamsPage::OnChangeLogType() UpdateData(); m_RmaSupportControl.EnableWindow(m_LogType == 2); + m_HtmlTimestampsControl.EnableWindow(m_LogType == 1); } void CLogParamsPage::OnShowWindow(BOOL bShow, UINT nStatus) @@ -70,4 +74,5 @@ void CLogParamsPage::OnShowWindow(BOOL bShow, UINT nStatus) CPropertyPage::OnShowWindow(bShow, nStatus); m_RmaSupportControl.EnableWindow(m_LogType == 2); + m_HtmlTimestampsControl.EnableWindow(m_LogType == 1); } diff --git a/sources/LogParamsPage.h b/sources/LogParamsPage.h index 23662d7..42cba3f 100644 --- a/sources/LogParamsPage.h +++ b/sources/LogParamsPage.h @@ -27,8 +27,10 @@ class CLogParamsPage : public CPropertyPage CButton m_logTypeHtmlControl; CButton m_logTypeAnsiControl; CButton m_RmaSupportControl; + CButton m_HtmlTimestampsControl; CButton m_logTypeControl; BOOL m_bRMASupport; + BOOL m_bHTMLTimestamps; BOOL m_bAppendLogTitle; int m_nAppendMode; int m_nLogAs; diff --git a/sources/MainFrm.cpp b/sources/MainFrm.cpp index b6d626b..627f656 100644 --- a/sources/MainFrm.cpp +++ b/sources/MainFrm.cpp @@ -573,6 +573,7 @@ void CMainFrame::OnOptionsOptions() pg4.m_bRMASupport = bRMASupport; pg4.m_nAppendMode = bDefaultLogMode ? 1 : 0 ; pg4.m_bAppendLogTitle = bAppendLogTitle; + pg4.m_bHTMLTimestamps = bHTML ? bHTMLTimestamps : FALSE; pg4.m_nLogAs = bLogAsUserSeen ? 1 : 0; memcpy(&pg5.m_guidLang , &theApp.m_guidScriptLang, sizeof(GUID)); @@ -627,6 +628,7 @@ void CMainFrame::OnOptionsOptions() // Log settings save bANSILog = pg4.m_LogType == 2; bHTML = pg4.m_LogType == 1; + bHTMLTimestamps = bHTML ? pg4.m_bHTMLTimestamps : FALSE; bRMASupport = bANSILog ? pg4.m_bRMASupport : FALSE; bDefaultLogMode = pg4.m_nAppendMode ; bLogAsUserSeen = pg4.m_nLogAs; diff --git a/sources/html.log.template b/sources/html.log.template new file mode 100644 index 0000000..12ff953 --- /dev/null +++ b/sources/html.log.template @@ -0,0 +1,76 @@ + + + + + + %title% + + + + + +
Font:  
+
+
diff --git a/sources/htmltimestamps.log.template b/sources/htmltimestamps.log.template new file mode 100644 index 0000000..b5ff1bb --- /dev/null +++ b/sources/htmltimestamps.log.template @@ -0,0 +1,286 @@ + + + + + + %title% + + + + + +
Font:  
+
+
+
Click on the log area to start/pause/resume playing from selected point
+
+ + +
diff --git a/sources/resource.h b/sources/resource.h index ecadeba..d1093b3 100644 --- a/sources/resource.h +++ b/sources/resource.h @@ -157,6 +157,7 @@ #define IDC_CHK_EMULATE_RMA 1120 #define IDC_WRITE_LOG_AS_SHOWN_BY_SERVER 1121 #define IDC_WRITE_LOG_AS_SEEN_BY_USER 1122 +#define IDC_HTML_TIMESTAMPS 1123 #define ID_OPTIONS_SCROLLBUFFER 32771 #define ID_OPTIONS_FONT 32772 #define ID_OPTIONS_HOTKEYS 32774 @@ -225,7 +226,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 179 #define _APS_NEXT_COMMAND_VALUE 32809 -#define _APS_NEXT_CONTROL_VALUE 1123 +#define _APS_NEXT_CONTROL_VALUE 1124 #define _APS_NEXT_SYMED_VALUE 108 #endif #endif diff --git a/sources/smc.rc b/sources/smc.rc index 1a22ef6..3e4a05a 100644 --- a/sources/smc.rc +++ b/sources/smc.rc @@ -316,15 +316,15 @@ BEGIN CONTROL "Append",IDC_APPEND_LOG_MODE,"Button",BS_AUTORADIOBUTTON, 131,28,58,10 GROUPBOX "Default writing",IDC_STATIC,125,8,90,35,WS_GROUP - GROUPBOX "Log format",IDC_STATIC,10,7,89,75 + GROUPBOX "Log format",IDC_STATIC,10,7,112,86 CONTROL "Write RMA",IDC_RMA_SUPPORT,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,41,64,49,10 + WS_TABSTOP,37,72,49,10 CONTROL "Text",IDC_LOGTYPE_TEXT,"Button",BS_AUTORADIOBUTTON | WS_GROUP,18,21,30,10 CONTROL "HTML",IDC_LOGTYPE_HTML,"Button",BS_AUTORADIOBUTTON,18, 35,36,10 CONTROL "ANSI (+Esc colors)",IDC_LOGTYPE_ANSI,"Button", - BS_AUTORADIOBUTTON,18,50,75,10 + BS_AUTORADIOBUTTON,17,60,75,10 CONTROL "Append log title",IDC_LOG_TITLE,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,130,57,65,10 GROUPBOX "Log contents",IDC_STATIC,125,47,89,46 @@ -333,6 +333,8 @@ BEGIN 69,78,9 CONTROL "As seen by User",IDC_WRITE_LOG_AS_SEEN_BY_USER,"Button", BS_AUTORADIOBUTTON,129,81,78,9 + CONTROL "Timestamps",IDC_HTML_TIMESTAMPS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,37,46,52,10 END IDD_SCRIPT_PAGE DIALOG DISCARDABLE 0, 0, 209, 98 @@ -826,6 +828,11 @@ BEGIN BEGIN BOTTOMMARGIN, 104 END + + IDD_LOG_PARAMS_PAGE, DIALOG + BEGIN + RIGHTMARGIN, 199 + END END #endif // APSTUDIO_INVOKED diff --git a/sources/smcDoc.cpp b/sources/smcDoc.cpp index b8abdcb..1075e39 100644 --- a/sources/smcDoc.cpp +++ b/sources/smcDoc.cpp @@ -591,6 +591,7 @@ BOOL CSmcDoc::OnNewDocument() bANSILog = AfxGetApp()->GetProfileInt("ANSI" , "ANSILog" , 0); bDefaultLogMode = AfxGetApp()->GetProfileInt("ANSI" , "AppendMode" , 0); bHTML = AfxGetApp()->GetProfileInt("ANSI" , "HTMLLog" , 0); + bHTMLTimestamps = AfxGetApp()->GetProfileInt("ANSI" , "HTMLLogTimestamps" , 0); bLogAsUserSeen = AfxGetApp()->GetProfileInt("ANSI" , "LogAsUserSeen" , 0); bIACSendSingle = AfxGetApp()->GetProfileInt("Substitution" , "IACSendSingle" , 0); @@ -719,6 +720,7 @@ BOOL CSmcDoc::DoProfileSave() AfxGetApp()->WriteProfileInt("ANSI" , "ANSILog" , bANSILog); AfxGetApp()->WriteProfileInt("ANSI" , "AppendMode" , bDefaultLogMode); AfxGetApp()->WriteProfileInt("ANSI" , "HTMLLog" , bHTML); + AfxGetApp()->WriteProfileInt("ANSI" , "HTMLLogTimestamps" , bHTMLTimestamps); AfxGetApp()->WriteProfileInt("ANSI" , "LogAsUserSeen" , bLogAsUserSeen); diff --git a/sources/ttcoreex/Logs.cpp b/sources/ttcoreex/Logs.cpp index de2c050..c0d05d1 100644 --- a/sources/ttcoreex/Logs.cpp +++ b/sources/ttcoreex/Logs.cpp @@ -9,8 +9,10 @@ #include #include +#include #include #include +#include //vls-begin// #logadd + #logpass BOOL bLogPassedLine = FALSE; @@ -27,6 +29,7 @@ static int new_tcolor = tcolor; static int new_bcolor = bcolor; DWORD lastTicker = 0; +DWORD firstTicker = 0; GET_OUTPUTNAME_FUNC GetOutputName; @@ -87,7 +90,7 @@ void log(int wnd, string st) string loadHTMLFromResource(int name) { DWORD size; - HRSRC rc = ::FindResource(rs::hInst, MAKEINTRESOURCE(IDR_HTML_HEAD), RT_HTML); + HRSRC rc = ::FindResource(rs::hInst, MAKEINTRESOURCE(name), RT_HTML); HGLOBAL rcData = ::LoadResource(rs::hInst, rc); size = ::SizeofResource(rs::hInst, rc); @@ -96,6 +99,28 @@ string loadHTMLFromResource(int name) return html_content; } +string loadHTMLFromFile(const char *filename) +{ + char fn[MAX_PATH+2]; + string ret; + + MakeAbsolutePath(fn, filename, szBASE_DIR); + + ifstream t(filename); + if(t.fail()) { + char message[BUFFER_SIZE]; + sprintf(message,rs::rs(1262), fn); + tintin_puts2(message); + ret = loadHTMLFromResource(IDR_HTML_HEAD); + } else { + stringstream buffer; + buffer << t.rdbuf(); + ret = buffer.str(); + } + + return ret; +} + BOOL CloseMainLog(char *logName, BOOL logHTML) { if (hLogFile.is_open()) { // Close log file now opened @@ -140,6 +165,8 @@ BOOL CloseWNDLog(int wnd, char *logName) BOOL StartMainLog(char* logName, BOOL logMode, BOOL logHTML) { + lastTicker = firstTicker = 0; + if (logMode && !logHTML) hLogFile.open(logName, ios::out | ios::binary | ios::app ); else @@ -150,7 +177,11 @@ BOOL StartMainLog(char* logName, BOOL logMode, BOOL logHTML) // Do HTML Log pereference if ( logHTML ) { - string html_header = loadHTMLFromResource(IDR_HTML_HEAD); + string html_header; + if ( !bHTMLTimestamps ) + html_header = loadHTMLFromFile("html.log.template"); + else + html_header = loadHTMLFromFile("htmltimestamps.log.template"); string::size_type pos = 0; while ( ( pos = html_header.find("%title%", pos) ) != string::npos ) { @@ -318,7 +349,28 @@ void stripDefaultColorDuplicates(string &strInput) { string processHTML(string strInput) { - string strOutput = strInput; + string strOutput = ""; + + BOOL close_timestamp_tag = FALSE; + + if ( bHTMLTimestamps ) { + DWORD currTicker = 0; + + if ( firstTicker == 0 ) { + firstTicker = GetTickCount(); + lastTicker = 0; + } + + currTicker = GetTickCount() - firstTicker; + + if ( currTicker - lastTicker >= MIN_HTML_FRAMES_DELAY_MS ) { + strOutput += strprintf("
", currTicker); + lastTicker = currTicker; + close_timestamp_tag = TRUE; + } + } + + strOutput += strInput; stripRMA(strOutput); @@ -365,10 +417,12 @@ string processHTML(string strInput) // replace source escape sequence to html entity strOutput.replace(pos, posEscEnd - pos + 1, html_tags); - - pos = strOutput.find("\x1B[", pos); } + if (close_timestamp_tag == TRUE) { + strOutput += "
"; + } + return strOutput; } diff --git a/sources/ttcoreex/Logs.h b/sources/ttcoreex/Logs.h index 4b4f371..019b356 100644 --- a/sources/ttcoreex/Logs.h +++ b/sources/ttcoreex/Logs.h @@ -2,6 +2,9 @@ #include "tintin.h" #include +//decrease fps to 25Hz max. +const int MIN_HTML_FRAMES_DELAY_MS = 40; + const string HTML_TAG = "i", TAG_OPEN = "", @@ -10,7 +13,7 @@ const string CSS_LIGHT_COLOR = "l"; string html_footer( - "\n
" + "\n
" ); static const string css_colors[] = diff --git a/sources/ttcoreex/TINTINX.H b/sources/ttcoreex/TINTINX.H index 820e5c8..ddbda01 100644 --- a/sources/ttcoreex/TINTINX.H +++ b/sources/ttcoreex/TINTINX.H @@ -65,6 +65,7 @@ extern BOOL DLLEXPORT bDisplayCommands; extern BOOL DLLEXPORT bDisplayInput; extern BOOL DLLEXPORT bMinimizeToTray; extern BOOL DLLEXPORT bHTML; +extern BOOL DLLEXPORT bHTMLTimestamps; extern BOOL DLLEXPORT bLogAsUserSeen; extern BOOL DLLEXPORT bAllowDebug; extern BOOL DLLEXPORT bIACSendSingle, bIACReciveSingle; diff --git a/sources/ttcoreex/ttcoreex.cpp b/sources/ttcoreex/ttcoreex.cpp index c04cd43..1c91308 100644 --- a/sources/ttcoreex/ttcoreex.cpp +++ b/sources/ttcoreex/ttcoreex.cpp @@ -59,6 +59,7 @@ BOOL DLLEXPORT bPasswordEcho = TRUE; BOOL DLLEXPORT bConnectBeep; BOOL DLLEXPORT bAutoReconnect; BOOL DLLEXPORT bHTML; +BOOL DLLEXPORT bHTMLTimestamps; BOOL DLLEXPORT bLogAsUserSeen; BOOL DLLEXPORT bAllowDebug = FALSE; BOOL DLLEXPORT bIACSendSingle, bIACReciveSingle; diff --git a/sources/ttcoreex/ttcoreex.rc b/sources/ttcoreex/ttcoreex.rc index c612065..73222a4 100644 --- a/sources/ttcoreex/ttcoreex.rc +++ b/sources/ttcoreex/ttcoreex.rc @@ -6381,6 +6381,7 @@ BEGIN 1259 "#FORMAT: #tray " 1260 "#FORMAT: #wdock [disable|left|top|right|bottom]" 1261 "#FORMAT: #wclear " + 1262 "#Error: can't open file %s" END #endif // English (U.S.) resources From 0ed788c1eeb328c612ffc66e491fedfe3255b6a4 Mon Sep 17 00:00:00 2001 From: konelav Date: Thu, 17 Mar 2016 06:35:31 +0300 Subject: [PATCH 03/26] strcmp command Added new command: #strcmp {arg1} {arg2} {if-equal-part} [{if-not-equal-part}] --- sources/ttcoreex/Ivars.cpp | 31 +++++++++++++++++++++++++++++++ sources/ttcoreex/Tintin.h | 3 ++- sources/ttcoreex/cmds.h | 3 ++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/sources/ttcoreex/Ivars.cpp b/sources/ttcoreex/Ivars.cpp index cce2e21..d689a7f 100644 --- a/sources/ttcoreex/Ivars.cpp +++ b/sources/ttcoreex/Ivars.cpp @@ -320,3 +320,34 @@ int do_one_inside(int begin, int end) } } } + +void strcmp_command(char *arg) +{ + char arg1[BUFFER_SIZE], + arg2[BUFFER_SIZE], + if_then[BUFFER_SIZE], + if_else[BUFFER_SIZE], + temp[BUFFER_SIZE]; + + arg = get_arg_in_braces(arg, arg1, STOP_SPACES); + substitute_vars(arg1,temp); + substitute_myvars(temp,arg1); + + arg = get_arg_in_braces(arg, arg2, STOP_SPACES); + substitute_vars(arg2,temp); + substitute_myvars(temp,arg2); + + arg = get_arg_in_braces(arg, if_then, WITH_SPACES); + substitute_vars(if_then,temp); + substitute_myvars(temp,if_then); + + arg = get_arg_in_braces(arg, if_else, WITH_SPACES); + substitute_vars(if_else,temp); + substitute_myvars(temp,if_else); + + if( !strcmp(arg1, arg2) ) { + parse_input(if_then); + } else if(*if_else) { + parse_input(if_else); + } +} diff --git a/sources/ttcoreex/Tintin.h b/sources/ttcoreex/Tintin.h index 0a248b5..6cc272d 100644 --- a/sources/ttcoreex/Tintin.h +++ b/sources/ttcoreex/Tintin.h @@ -264,6 +264,7 @@ void end_command(char *command); void help_command(char *arg); void parse_high(char *arg); void if_command(char *line); +void strcmp_command(char *arg); void ignore_command(char* arg); void display_info(char* arg); void log_command(char *arg); @@ -471,7 +472,7 @@ extern void* JMCObjRet[1000]; // --END //* en:JMC functions struct. look cmds.h -const JMC_CMDS_NUM=116; +const JMC_CMDS_NUM=117; typedef struct jmc_cmd { char*alias; diff --git a/sources/ttcoreex/cmds.h b/sources/ttcoreex/cmds.h index 03f062c..45e07a0 100644 --- a/sources/ttcoreex/cmds.h +++ b/sources/ttcoreex/cmds.h @@ -116,6 +116,7 @@ jmc_cmdi jmc_cmds[JMC_CMDS_NUM]={ {"autoreconnect",&autoreconnect_command,"autoreconnect"}, {"run",&run_command,"\0"}, {"clear",&clear_command,"\0"}, - {"wclear",&wclear_command,"\0"} + {"wclear",&wclear_command,"\0"}, + {"strcmp",&strcmp_command,"\0"} }; #endif \ No newline at end of file From 49fb0cd47c59d12cbb6a27c6f32c1734a0802ceb Mon Sep 17 00:00:00 2001 From: konelav Date: Wed, 27 Apr 2016 16:52:39 +0300 Subject: [PATCH 04/26] Bulk commit New options: 1. Line wrapping 2. Rectangular selection mode 3. Selection with ansi-commands 4. Show "hidden" text, i.e. automatically highlight text when foreground and background are identical New commands: 1. #loopback - send to the client just as it sent by MUD (like MUD-emulation) 2. #broadcast - send to all client instances running on the same machine or within same local network (optional) and listening same "broadcast port" (there is new setting for port value) - access through firewall is needed for broadcasting within local network - such messages are just raw udp-datagrams and can be sent by any other application written in any language 3. #proxy [:port] [user] [password] - use SOCKS4/5 proxy for connection with appropriate authentication - default port in 1080 #proxy list [line] - use proxy-settings stated in at line (or at the next circularly incremented line), format of line is as argument for proxy command, e.g. "socks5 127.0.0.1:9150 foo bar" 4. #mccp [on|off] - allow/deny compression via MCCP1/2 (reconnection will be needed) 5. #promptend [] - set automatic low-level (telnet-level) substitution of character sequence with (possibly empty) string followed by Telnet-GA (end-of-prompt) symbol - this is very useful feature for MUDs without GA/EOR support 6. #srandom [seed] - set new random seed or init with timestamp value if seed is not stated 7. #random [minimum] [maximum] - set random number to uniformly distributed within range [minimum .. maximum-1] - default range is [0..99] - if only one value is passed, it is taken as value 8. #sync - force reading and processing all data from all incoming buffers (MUD and broadcast sockets, emulator and loopback buffers) New special variables: 1. $CLOCK - TinTin 'ticks' (0.1 seconds) 2. $CLOCKMS - milliseond-resolution timer 3. $RANDOM - 32-bit random value 4. $HOSTIP - IP-address of current MUD server 5. $HOSTPORT - Telnet port of current connection 6. $EOP - special symbol interpreted by client as end-of-prompt (0x1) 7. $EOL - special symbol end-of-line (\n) 8. $ESC - special symbol 0x1B - note that if your command delimiter is set to ';' then input like "#showme $ESC[1;33;47mTest" will be splitted into three lines: "#showme $ESC[1", "33" and "47mTest" leading to unwanted effect use curly brackets to achieve desirable behaviour: "#showme {$ESC[1;33;47mTest}" 9. $PING, $PINGPROXY - ping delay to the MUD-server/Proxy-server in ms, special values meaning: "-1" ping timeout "-2" no server specified "-3" program internal error New scripting events: 1. Prompt (jmc.RegisterHanlder('Prompt', '...')) - fired on each of the following events: 1) Telnet-GA received 2) Telnet-EOR received 3) Sequence stated with #promptend received 4) "Uncomplete line delay" timed out 5) User input (fired only if there are some data received till last Prompt event) - jmc.Event contains all data (including end-of-line characters) received from server, broadcast, loopback and emulation streams for example, prompt line itself in JScript would be: `jmc.Event.substr(jmc.Event.lastIndexOf("\n") + 1)` - jmc.DropEvent() disables testing corresponding batch of lines agains multiline actions Changes in commands: 1. #action [text|raw|ansi|smaug|sow] .... - added new optional parameter "color-type" (default is "text" which means old-fashion plain text actions) - in "raw" mode lines will be tested "as-is", with all escape-sequences - in "ansi" mode all lines will be preprocessed so they will contain only meaningfull forecolor ansi-commands at the rightmost positions note that such lines ALWAYS starts with corresponding ansi-command - in "smaug" mode all ansi-commands replaced with smaug-like codes such as "&W" for light-white, "&r" for dark-red and so on - in "sow" mode all ansi-commands replaced with sow-like codes such as "{7}" for light-white, "[1]" for dark-red and so on 2. #action [] //[i|m] .... - added new optional flags for regular expressions: i (case insesitive, taking into account current user locale) m (multiline, testing occured on each GA/EOR/long delay/user input) 3. #alias //[i] .... - added possibility to use regular expressions with aliases - there is also optional flag "i" (case insensitive) Other changes: 1. ping-delay to the server in the statusline (bottom-left corner) when proxy is used, there is also ping-delay to the proxy server 2. immidiate text drawing, without any delay for waiting "end-of-line" 3. all characters within ansi-commands in user input are ignored so those who have default command delimiter ';' can freely use escape-sequences such as "\x1b[1;33;47m" 4. special variables are now accessible from script engine just as others e.g. use jmc.GetVar("HOSTIP") to define current MUD server address 5. template for HTML-logs with timestamps is improved: - resizable log area - time changing while user manually scroll log 6. language.ini is updated for Russian help for Ukrainian translation is needed 7. redraw rate of text windows is limited to 50 Hz it is critical while drawing huge amount of text at once 8. HTML-logs now have no empty tags such as "" 9. almost completely rewritten logic of parsing commands so recursive aliases should works properly 10. error messages while connecting now is triggerable e.g. "#action {#Failed to connect.} {#scri MyConnectFailureHandler()}" 11. status bars automatically increases their widths 12. locale support for regular expressions in actions and aliases 13. self-testing procedure with following usage: - launch jmc.exe - create new profile or open unused one - execute "#killall; #read selftest; runtests" - look results in output #0 window Also, tiny modifications through all the files: 1. help files updated 2. numerous of minor bugs fixed (and added unpredictable amount of new ones) 3. a lot of possible buffer overflows now checked at runtime 4. made project compilable (though not yet runnable) under MSVC2010 (some more little fixes are needed, but they could brake compatibility with VC6) --- sources/AnsiWnd.cpp | 332 +++++++---- sources/AnsiWnd.h | 6 + sources/CharSubstPage.cpp | 3 +- sources/CommonParamsPage.cpp | 15 + sources/CommonParamsPage.h | 7 + sources/CoolDialogBar.cpp | 2 +- sources/CoolDialogBar.h | 2 +- sources/JMCActionsPage.cpp | 37 +- sources/JMCActionsPage.h | 2 + sources/MainFrm.cpp | 154 ++++- sources/MainFrm.h | 2 + sources/Tray.cpp | 4 +- sources/help/action.jht | 14 +- sources/help/alias.jht | 2 + sources/help/broadcast.jht | 6 + sources/help/clear.jht | 2 + sources/help/mccp.jht | 3 + sources/help/promptchar.jht | 6 + sources/help/proxy.jht | 16 + sources/help/random.jht | 9 + sources/help/srandom.jht | 4 + sources/help/strcmp.jht | 6 + sources/help/sync.jht | 5 + sources/help/wclear.jht | 2 + sources/help/wdock.jht | 2 +- sources/html.log.template | 2 +- sources/htmltimestamps.log.template | 30 +- sources/language.ini | 46 +- sources/recore/maketables.c | 4 +- sources/resource.h | 11 +- sources/selftest | 14 + sources/selftests/0.test | 38 ++ sources/selftests/1.test | 30 + sources/selftests/2.test | 25 + sources/selftests/3.test | 51 ++ sources/selftests/4.test | 30 + sources/selftests/5.test | 62 ++ sources/smc.cpp | 3 +- sources/smcDoc.cpp | 219 ++++--- sources/smcDoc.h | 4 + sources/smcView.cpp | 352 +++++++---- sources/smcView.h | 6 +- sources/ttcoreex/Action.cpp | 367 ++++++++++-- sources/ttcoreex/Alias.cpp | 30 +- sources/ttcoreex/Files.cpp | 99 ++- sources/ttcoreex/Highligh.cpp | 2 +- sources/ttcoreex/Ivars.cpp | 47 +- sources/ttcoreex/JmcObj.cpp | 27 +- sources/ttcoreex/Logs.cpp | 114 ++-- sources/ttcoreex/Misc.cpp | 183 +++++- sources/ttcoreex/Parse.cpp | 230 ++++++- sources/ttcoreex/Path.cpp | 4 +- sources/ttcoreex/Proxy.cpp | 564 ++++++++++++++++++ sources/ttcoreex/Scrfiles.cpp | 2 + sources/ttcoreex/Session.cpp | 4 +- sources/ttcoreex/Substitu.cpp | 26 +- sources/ttcoreex/System.cpp | 2 +- sources/ttcoreex/TINTINX.H | 19 + sources/ttcoreex/Text.cpp | 10 +- sources/ttcoreex/Tintin.h | 64 +- sources/ttcoreex/Utils.cpp | 12 +- sources/ttcoreex/Variable.cpp | 171 +++++- sources/ttcoreex/nodes.cpp | 127 +++- sources/ttcoreex/telnet.H | 7 +- sources/ttcoreex/telnet.cpp | 617 +++++++++++++++---- sources/ttcoreex/ttcoreex.cpp | 706 ++++++++++++++-------- sources/ttcoreex/ttcoreex.dsp | 8 + sources/ttcoreex/ttcoreex.h | 4 +- sources/ttcoreex/ttcoreex.rc | 25 +- sources/ttcoreex/ttcoreexCP.h | 44 ++ sources/ttcoreex/ttcoreex_i.c | 4 +- sources/ttcoreex/ttcoreex_p.c | 4 +- sources/ttcoreex/ttobjects.h | 31 +- sources/ttcoreex/variables.h | 15 +- sources/ttcoreex/zconf.h | 279 +++++++++ sources/ttcoreex/zlib.h | 893 ++++++++++++++++++++++++++++ sources/ttcoreex/zlib.lib | Bin 0 -> 34674 bytes 77 files changed, 5283 insertions(+), 1028 deletions(-) create mode 100644 sources/help/broadcast.jht create mode 100644 sources/help/clear.jht create mode 100644 sources/help/mccp.jht create mode 100644 sources/help/promptchar.jht create mode 100644 sources/help/proxy.jht create mode 100644 sources/help/random.jht create mode 100644 sources/help/srandom.jht create mode 100644 sources/help/strcmp.jht create mode 100644 sources/help/sync.jht create mode 100644 sources/help/wclear.jht create mode 100644 sources/selftest create mode 100644 sources/selftests/0.test create mode 100644 sources/selftests/1.test create mode 100644 sources/selftests/2.test create mode 100644 sources/selftests/3.test create mode 100644 sources/selftests/4.test create mode 100644 sources/selftests/5.test create mode 100644 sources/ttcoreex/Proxy.cpp create mode 100644 sources/ttcoreex/zconf.h create mode 100644 sources/ttcoreex/zlib.h create mode 100644 sources/ttcoreex/zlib.lib diff --git a/sources/AnsiWnd.cpp b/sources/AnsiWnd.cpp index 33f9cb0..aa4c1b0 100644 --- a/sources/AnsiWnd.cpp +++ b/sources/AnsiWnd.cpp @@ -56,6 +56,27 @@ BOOL CAnsiWnd::PreCreateWindow(CREATESTRUCT& cs) return CWnd::PreCreateWindow(cs); } +static int LengthWithoutANSI(const char* str) +{ + int ret = 0; + for(; *str; str++) { + if(*str == 0x1B) { + for(; *str && *str != 'm'; str++); + } else { + ret++; + } + } + return ret; +} +static int NumOfLines(int StrLength, int LineWidth) +{ + if (LineWidth <= 0) + return 0; + int ret = StrLength / LineWidth; + if ((StrLength == 0) || (StrLength % LineWidth)) + ret++; + return ret; +} void CAnsiWnd::OnPaint() { CPaintDC dc(this); // device context for painting @@ -68,27 +89,53 @@ void CAnsiWnd::OnPaint() dc.SelectClipRgn(&rgn); int ScrollIndex = GetScrollPos(SB_VERT); + int last_line = min(ScrollIndex + m_nPageSize, pDoc->m_nScrollSize - 1); - POSITION pos = m_strList.FindIndex(ScrollIndex+m_nPageSize); + POSITION pos = m_strList.FindIndex(last_line); ASSERT(pos); - rect.top = rect.bottom-pDoc->m_nYsize; - int i = 0; - dc.SetBkMode(OPAQUE); + dc.SetBkMode(OPAQUE); CFont* pOldFont = dc.SelectObject(&pDoc->m_fntText); - while ( pos && i++ <= m_nPageSize) { + int top = rect.top; + + m_LineCountsList.clear(); + for(int n_line = 0, total_lines = 0; pos && total_lines <= m_nPageSize; n_line++) { CString str = m_strList.GetPrev(pos); - if ( dc.RectVisible(&rect) ) - DrawWithANSI(&dc, rect, &str, m_nPageSize - i); + int length = LengthWithoutANSI((const char*)str); + int lines = pDoc->m_bLineWrap ? NumOfLines(length, m_nLineWidth) : 1; - rect.top -= pDoc->m_nYsize; - rect.bottom -= pDoc->m_nYsize; + m_LineCountsList.push_back(lines); + total_lines += lines; + + rect.top = rect.bottom - pDoc->m_nYsize * lines; + + if ( dc.RectVisible(&rect) ) + DrawWithANSI(&dc, rect, &str, m_nPageSize - n_line - 1); + + rect.bottom = rect.top; + + if (rect.bottom <= top) + break; } dc.SelectObject(pOldFont); } +void CAnsiWnd::ConvertCharPosition(int TextRow, int TextCol, int *LineNum, int *CharPos) +{ + int row = m_nPageSize; + *LineNum = TextRow; + *CharPos = TextCol; + for (int i = 0; i < m_LineCountsList.size(); i++) { + row -= m_LineCountsList[i]; + if (row <= TextRow) { + *LineNum = m_nPageSize - i - 1; + *CharPos = TextCol + (m_nLineWidth - 1) * (TextRow - row); + break; + } + } +} void CAnsiWnd::OnSetFocus(CWnd* pOldWnd) { @@ -116,8 +163,6 @@ int CAnsiWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) //=================================================================================================================== - ((CMainFrame*)AfxGetMainWnd())->m_editBar.GetDlgItem(IDC_EDIT)->SetFont(&pDoc->m_fntText); - CRect rect; GetClientRect(&rect); @@ -130,14 +175,18 @@ int CAnsiWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) void CAnsiWnd::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); - m_nLastPageSize = m_nPageSize; - m_nPageSize = cy/pDoc->m_nYsize; + + m_nLastPageSize = m_nPageSize; + m_nPageSize = min(cy/pDoc->m_nYsize, pDoc->m_nScrollSize); + m_nYDiff = cy - m_nPageSize*pDoc->m_nYsize; + + m_nLineWidth = cx/pDoc->m_nCharX; + if(cx % pDoc->m_nCharX) + m_nLineWidth++; + SetScrollSettings(FALSE); -//vls-begin// multiple output -// pDoc->m_nOutWindowCharsSize = max (cx/pDoc->m_nCharX, 1); - pDoc->m_nOutputWindowCharsSize[m_wndCode] = max (cx/pDoc->m_nCharX, 1); -//vls-end// + pDoc->m_nOutputWindowCharsSize[m_wndCode] = m_nLineWidth; } void CAnsiWnd::SetScrollSettings(BOOL bResetPosition ) @@ -163,6 +212,9 @@ void CAnsiWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) if ( Pos ) { Pos --; SetScrollPos(SB_VERT, Pos, TRUE); + InvalidateRect(NULL, FALSE ); + UpdateWindow(); + /* CDC* pDC = GetDC(); GetClientRect(&rect); pDC->ScrollDC(0 ,pDoc->m_nYsize, rect , NULL , NULL , NULL ); @@ -175,12 +227,16 @@ void CAnsiWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) RedrawOneLine(pDC , Pos+1); pDC->SelectObject(pOldFont); ReleaseDC(pDC); + */ } break; case SB_LINEDOWN: if ( Pos < pDoc->m_nScrollSize -1-m_nPageSize ) { Pos ++; SetScrollPos(SB_VERT, Pos, TRUE); + InvalidateRect(NULL, FALSE ); + UpdateWindow(); + /* CDC* pDC = GetDC(); GetClientRect(&rect); pDC->ScrollDC(0 ,-pDoc->m_nYsize, rect , NULL , NULL , NULL ); @@ -193,6 +249,7 @@ void CAnsiWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) RedrawOneLine(pDC , Pos+m_nPageSize); pDC->SelectObject(pOldFont); ReleaseDC(pDC); + */ } break; case SB_PAGEDOWN: @@ -292,13 +349,13 @@ void CAnsiWnd::DrawWithANSI(CDC* pDC, CRect& rect, CString* str, int nStrPos) char* src = (LPSTR)(LPCSTR)*str; - int LeftSide =0; + int LeftSide =0, TopSide =0; // Lets do different drawing code for selected/unselected mode. Doing to to // keep high speed of drawing while unselected mode if ( m_bSelected && nStrPos <= m_nEndSelectY && nStrPos >= m_nStartSelectY) { - BOOL bOldInvert = nStrPos > m_nStartSelectY; + BOOL bOldInvert = !pDoc->m_bRectangleSelection && (nStrPos > m_nStartSelectY); BOOL bNewInvert = bOldInvert; int CharCount = 0; do { @@ -308,10 +365,10 @@ void CAnsiWnd::DrawWithANSI(CDC* pDC, CRect& rect, CString* str, int nStrPos) int TextLen = 0; while (*src && *src != 0x1B ) { // check for current bold - if ( nStrPos == m_nStartSelectY && CharCount == m_nStartSelectX) { + if ( (pDoc->m_bRectangleSelection || nStrPos == m_nStartSelectY) && CharCount == m_nStartSelectX) { bNewInvert = TRUE; } - if ( nStrPos == m_nEndSelectY && CharCount == m_nEndSelectX) { + if ( (pDoc->m_bRectangleSelection || nStrPos == m_nEndSelectY) && CharCount == m_nEndSelectX + 1) { bNewInvert = FALSE; } if ( bNewInvert != bOldInvert) @@ -326,7 +383,7 @@ void CAnsiWnd::DrawWithANSI(CDC* pDC, CRect& rect, CString* str, int nStrPos) // Draw text // Skip \n from the end - while ( TextLen && (Text[TextLen-1] == '\n' /*|| Text[TextLen-1] == '\r' */) ) + while ( TextLen && (Text[TextLen-1] == '\n' ) ) TextLen--; indexF = m_nCurrentFg + (m_bAnsiBold && !pDoc->m_bDarkOnly ? 8 : 0 ); @@ -349,19 +406,36 @@ void CAnsiWnd::DrawWithANSI(CDC* pDC, CRect& rect, CString* str, int nStrPos) } else { XShift = 0; } - OutRect = rect; - OutRect.left += LeftSide; - - // if ( *src ) - // OutRect.right = OutRect.left + XShift; - OutRect.right = OutRect.left + XShift; - - - LeftSide += XShift; - // if ( XShift || !*src ) - if ( XShift ) - pDC->ExtTextOut(OutRect.left, OutRect.top, ETO_OPAQUE, &OutRect, Text, TextLen, NULL); + if ( XShift ) { + //LeftSide += XShift; + //pDC->ExtTextOut(OutRect.left, OutRect.top, ETO_OPAQUE, &OutRect, Text, TextLen, NULL); + int index = 0; + while ( pDoc->m_bLineWrap && LeftSide + XShift > rect.Width() ) { + int len = (rect.Width() - LeftSide) / pDoc->m_nCharX; + + OutRect = rect; + OutRect.left += LeftSide; + OutRect.top += TopSide; + OutRect.right = rect.right; + + pDC->ExtTextOut(OutRect.left, OutRect.top, ETO_OPAQUE, &OutRect, &(Text[index]), len, NULL); + index += len; + TextLen -= len; + + LeftSide = 0; + TopSide += myRect.Height(); + XShift -= len * pDoc->m_nCharX; + } + OutRect = rect; + OutRect.left += LeftSide; + OutRect.top += TopSide; + OutRect.right = OutRect.left + XShift; + + LeftSide += XShift; + pDC->ExtTextOut(OutRect.left, OutRect.top, ETO_OPAQUE, &OutRect, &(Text[index]), TextLen, NULL); + } + // !!!! Look for it ! Every time you draw to the end of string !!!! May be change rectangle ??? if ( bOldInvert != bNewInvert ) { @@ -394,10 +468,11 @@ void CAnsiWnd::DrawWithANSI(CDC* pDC, CRect& rect, CString* str, int nStrPos) }while ( *src ); // draw to end of the window OutRect = rect; + OutRect.top += TopSide; OutRect.left += LeftSide; indexF = m_nCurrentFg + (m_bAnsiBold && !pDoc->m_bDarkOnly ? 8 : 0 ); indexB = m_nCurrentBg; //+ (m_bAnsiBold ? 8 : 0 ); - if ( bOldInvert ) { + if (!pDoc->m_bRectangleSelection && bOldInvert ) { pDC->SetTextColor(0xFFFFFF-pDoc->m_ForeColors[indexF]); pDC->SetBkColor(0xFFFFFF-pDoc->m_BackColors[indexB]); } else { @@ -419,40 +494,54 @@ void CAnsiWnd::DrawWithANSI(CDC* pDC, CRect& rect, CString* str, int nStrPos) // Draw text // Skip \n from the end - while ( TextLen && (Text[TextLen-1] == '\n' /*|| Text[TextLen-1] == '\r' */) ) + while ( TextLen && (Text[TextLen-1] == '\n' ) ) TextLen--; indexF = m_nCurrentFg + (m_bAnsiBold && !pDoc->m_bDarkOnly ? 8 : 0 ); indexB = m_nCurrentBg; //+ (m_bAnsiBold ? 8 : 0 ); pDC->SetTextColor(pDoc->m_ForeColors[indexF]); - pDC->SetBkColor(pDoc->m_BackColors[indexB]); + if (indexB == indexF) + pDC->SetBkColor(0xFFFFFF-pDoc->m_BackColors[indexB]); + else + pDC->SetBkColor(pDoc->m_BackColors[indexB]); CRect myRect(0,0,0,0); int XShift; if ( TextLen) { pDC->DrawText(Text, TextLen, &myRect, DT_LEFT | DT_SINGLELINE | DT_NOCLIP | DT_CALCRECT | DT_NOPREFIX); XShift = myRect.Width(); - } else { XShift = 0; } - OutRect = rect; - OutRect.left += LeftSide; - OutRect.right = OutRect.left + XShift; + if ( XShift ) { + int index = 0; + while ( pDoc->m_bLineWrap && LeftSide + XShift > rect.Width() ) { + int len = (rect.Width() - LeftSide) / pDoc->m_nCharX; - LeftSide += XShift; - if ( XShift ) - pDC->ExtTextOut(OutRect.left, OutRect.top, ETO_OPAQUE, &OutRect, Text, TextLen, NULL); + OutRect = rect; + OutRect.left += LeftSide; + OutRect.top += TopSide; + OutRect.right = rect.right; + + pDC->ExtTextOut(OutRect.left, OutRect.top, ETO_OPAQUE, &OutRect, &(Text[index]), len, NULL); + index += len; + TextLen -= len; + + LeftSide = 0; + TopSide += myRect.Height(); + XShift -= len * pDoc->m_nCharX; + } + OutRect = rect; + OutRect.left += LeftSide; + OutRect.top += TopSide; + OutRect.right = OutRect.left + XShift; + + LeftSide += XShift; + pDC->ExtTextOut(OutRect.left, OutRect.top, ETO_OPAQUE, &OutRect, &(Text[index]), TextLen, NULL); + } -/* pDC->ExtTextOut(myRect.left, myRect.top, ETO_OPAQUE, &myRect, Text, TextLen, NULL); - - if ( TextLen) { - pDC->DrawText(Text, TextLen, &myRect, DT_LEFT | DT_SINGLELINE | DT_NOCLIP | DT_CALCRECT); - LeftSide += myRect.Width(); - } -*/ // Now check for ANSI colors if ( !*src++ ) // if end of string - get out break; @@ -478,10 +567,14 @@ void CAnsiWnd::DrawWithANSI(CDC* pDC, CRect& rect, CString* str, int nStrPos) }while ( *src ); OutRect = rect; OutRect.left += LeftSide; + OutRect.top += TopSide; indexF = m_nCurrentFg + (m_bAnsiBold && !pDoc->m_bDarkOnly ? 8 : 0 ); indexB = m_nCurrentBg; //+ (m_bAnsiBold ? 8 : 0 ); pDC->SetTextColor(pDoc->m_ForeColors[indexF]); - pDC->SetBkColor(pDoc->m_BackColors[indexB]); + if (indexB == indexF) + pDC->SetBkColor(0xFFFFFF-pDoc->m_BackColors[indexB]); + else + pDC->SetBkColor(pDoc->m_BackColors[indexB]); pDC->ExtTextOut(OutRect.left, OutRect.top, ETO_OPAQUE, &OutRect, "", 0, NULL); } } @@ -494,8 +587,14 @@ void CAnsiWnd::OnLButtonDown(UINT nFlags, CPoint point) SetCapture(); pDoc->m_bFrozen = TRUE; m_bSelected = TRUE; - m_nStartTrackY = m_nEndTrackY = m_nEndSelectY = m_nStartSelectY = (point.y-m_nYDiff)/pDoc->m_nYsize; - m_nStartTrackX = m_nEndTrackX = m_nStartSelectX = m_nEndSelectX = point.x/pDoc->m_nCharX; + + int col = point.x/pDoc->m_nCharX; + int row = (point.y-m_nYDiff)/pDoc->m_nYsize; + int x, y; + ConvertCharPosition(row, col, &y, &x); + + m_nStartTrackY = m_nEndTrackY = m_nEndSelectY = m_nStartSelectY = y; + m_nStartTrackX = m_nEndTrackX = m_nStartSelectX = m_nEndSelectX = x; } static char* SkipAnsi(char* ptr) @@ -533,7 +632,7 @@ void CAnsiWnd::OnLButtonUp(UINT nFlags, CPoint point) CString tmpStr = m_strList.GetAt(pos); char* ptr = (LPSTR)(LPCSTR)tmpStr; int count = 0; - if (i == m_nStartSelectY && i == m_nEndSelectY) { + if (pDoc->m_bRectangleSelection || i == m_nStartSelectY) { // Skip to StartX character while ( count < m_nStartSelectX && *ptr){ if ( *ptr == 0x1B ){ @@ -548,7 +647,7 @@ void CAnsiWnd::OnLButtonUp(UINT nFlags, CPoint point) } // characters skipped now copy nessesary info to string do { - if ( *ptr == '\n' /*|| *ptr == '\r'*/ ) { + if ( *ptr == '\n' ) { ptr++; continue; } @@ -556,7 +655,9 @@ void CAnsiWnd::OnLButtonUp(UINT nFlags, CPoint point) ptr = SkipAnsi(ptr); continue; } //* en: do not even try - if ( /*i == m_nEndSelectY &&*/ count >= m_nEndSelectX ) + if ( !(*ptr)) + break; + if ( count > m_nEndSelectX && (pDoc->m_bRectangleSelection || i == m_nEndSelectY)) break; ResultStr+= *ptr++; count++; @@ -592,45 +693,41 @@ void CAnsiWnd::OnLButtonUp(UINT nFlags, CPoint point) void CAnsiWnd::OnMouseMove(UINT nFlags, CPoint point) { - if ( m_bSelected && (m_nEndSelectY != (point.y-m_nYDiff)/pDoc->m_nYsize || m_nEndSelectX != point.x/pDoc->m_nCharX) ) { - int OldEndTrackX = m_nEndTrackX, OldEndTrackY = m_nEndTrackY; - m_nEndTrackY = (point.y-m_nYDiff)/pDoc->m_nYsize; - m_nEndTrackX = point.x/pDoc->m_nCharX; - - // int StartX = m_nStartSelectX, StartY= m_nStartSelectY, EndX = m_nEndSelectX, EndY = m_nEndSelectY; - - // Now calculate SELECT positions !!!! - if ( m_nStartTrackY <= m_nEndTrackY ){ - m_nStartSelectY = m_nStartTrackY; - m_nEndSelectY = min(m_nEndTrackY, m_nPageSize); - - if ( m_nStartSelectY == m_nEndSelectY ) { - m_nStartSelectX = min (m_nStartTrackX, m_nEndTrackX ); - m_nStartSelectX = max (0, m_nStartSelectX); - m_nEndSelectX = max(m_nStartTrackX, m_nEndTrackX ); - } - else { - m_nStartSelectX = m_nStartTrackX; - m_nEndSelectX = max(m_nEndTrackX, 0); - } - } - else { - m_nStartSelectY = max(m_nEndTrackY,0); - m_nEndSelectY = m_nStartTrackY; - - m_nStartSelectX = max(m_nEndTrackX, 0); - m_nEndSelectX = m_nStartTrackX; - } - - - CRect CliRect; - GetClientRect(&CliRect); - CliRect.top = min(OldEndTrackY, m_nEndTrackY)*pDoc->m_nYsize+m_nYDiff; - CliRect.bottom = max(OldEndTrackY, m_nEndTrackY)*pDoc->m_nYsize + pDoc->m_nYsize +m_nYDiff; + if (m_bSelected) { + int col = point.x/pDoc->m_nCharX; + int row = (point.y-m_nYDiff)/pDoc->m_nYsize; + int x, y; + ConvertCharPosition(row, col, &y, &x); + + if ( m_nEndTrackY != y || m_nEndTrackX != x ) { + int OldEndTrackX = m_nEndTrackX, OldEndTrackY = m_nEndTrackY; + m_nEndTrackY = y; + m_nEndTrackX = x; + + // Now calculate SELECT positions !!!! + m_nStartSelectY = min(m_nStartTrackY, m_nEndTrackY); + m_nEndSelectY = max(m_nStartTrackY, m_nEndTrackY); + if (pDoc->m_bRectangleSelection) { + m_nStartSelectX = min(m_nStartTrackX, m_nEndTrackX); + m_nEndSelectX = max(m_nStartTrackX, m_nEndTrackX); + } else { + if (m_nStartSelectY == m_nEndSelectY) { + m_nStartSelectX = min(m_nStartTrackX, m_nEndTrackX); + m_nEndSelectX = max(m_nStartTrackX, m_nEndTrackX); + } else if (m_nStartSelectY == m_nStartTrackY) { + m_nStartSelectX = m_nStartTrackX; + m_nEndSelectX = m_nEndTrackX; + } else { + m_nStartSelectX = m_nEndTrackX; + m_nEndSelectX = m_nStartTrackX; + } + + } - InvalidateRect(&CliRect, FALSE); - UpdateWindow(); - } + InvalidateRect(NULL, FALSE); + UpdateWindow(); + } + } CWnd::OnMouseMove(nFlags, point); } @@ -650,49 +747,40 @@ void CAnsiWnd::OnUpdate(LPARAM lHint) GetClientRect(&rect); -//vls-begin// multiple output -// ASSERT(pDoc->m_nOutputUpdateCount == pDoc->m_strOutoputTempList.GetCount()-1 ); -// -// m_strList.SetAt(m_strList.GetTailPosition(), pDoc->m_strOutoputTempList.GetHead()); -// // pDoc->m_strOutoputTempList.RemoveHead(); -// -// POSITION pos = pDoc->m_strOutoputTempList.GetHeadPosition(); -// pDoc->m_strOutoputTempList.GetNext(pos); -// -// while(pos) { -// CString str = pDoc->m_strOutoputTempList.GetNext(pos); -// m_strList.AddTail(str); -// m_strList.RemoveHead(); -// } -// rectSmall.left = 0; -// rectSmall.right = rect.right; -// rectSmall.bottom = rect.bottom; -// rectSmall.top = rect.bottom -pDoc->m_nYsize*(pDoc->m_nOutputUpdateCount+1); -// if ( pDoc->m_nOutputUpdateCount ) -// ScrollWindowEx(0, -pDoc->m_nYsize*pDoc->m_nOutputUpdateCount, NULL, &rect, NULL, /*&rectSmall*/ NULL , SW_INVALIDATE | SW_ERASE); - if (pDoc->m_strOutputTempList[m_wndCode].GetCount() > 0 && pDoc->m_nOutputUpdateCount[m_wndCode] == pDoc->m_strOutputTempList[m_wndCode].GetCount()-1) { + if (pDoc->m_strOutputTempList[m_wndCode].GetCount() > 0) { m_strList.SetAt(m_strList.GetTailPosition(), pDoc->m_strOutputTempList[m_wndCode].GetHead()); - // pDoc->m_strOutoputTempList.RemoveHead(); if ( pDoc->m_bClearOutputContents[m_wndCode] ) { for ( POSITION it = m_strList.GetHeadPosition(); it != NULL; m_strList.GetNext(it)) - m_strList.SetAt(it, ""); + m_strList.SetAt(it, ""); } POSITION pos = pDoc->m_strOutputTempList[m_wndCode].GetHeadPosition(); - pDoc->m_strOutputTempList[m_wndCode].GetNext(pos); + CString last_line = pDoc->m_strOutputTempList[m_wndCode].GetNext(pos); + + int dcnt_last_line = 0; + int cnt_last_line = 1; + if (pDoc->m_bLineWrap && m_LineCountsList.size() > 0) { + int old_len = m_LineCountsList[0]; + cnt_last_line = NumOfLines(LengthWithoutANSI((const char*)last_line), m_nLineWidth); + dcnt_last_line = cnt_last_line - old_len; + } + int new_lines = 0; while(pos) { CString str = pDoc->m_strOutputTempList[m_wndCode].GetNext(pos); m_strList.AddTail(str); m_strList.RemoveHead(); + + new_lines += pDoc->m_bLineWrap ? + NumOfLines(LengthWithoutANSI((const char*)str), m_nLineWidth) : 1; } rectSmall.left = 0; rectSmall.right = rect.right; rectSmall.bottom = rect.bottom; - rectSmall.top = rect.bottom -pDoc->m_nYsize*(pDoc->m_nOutputUpdateCount[m_wndCode]+1); + rectSmall.top = rect.bottom -pDoc->m_nYsize*(new_lines+cnt_last_line); if ( pDoc->m_nOutputUpdateCount[m_wndCode] ) - ScrollWindowEx(0, -pDoc->m_nYsize*pDoc->m_nOutputUpdateCount[m_wndCode], NULL, &rect, NULL, /*&rectSmall*/ NULL , SW_INVALIDATE | SW_ERASE); + ScrollWindowEx(0, -pDoc->m_nYsize*(new_lines + dcnt_last_line), NULL, &rect, NULL, /*&rectSmall*/ NULL , SW_INVALIDATE | SW_ERASE); if ( pDoc->m_bClearOutputContents[m_wndCode] ) InvalidateRect(NULL, FALSE); @@ -700,8 +788,6 @@ void CAnsiWnd::OnUpdate(LPARAM lHint) InvalidateRect(&rectSmall, FALSE); UpdateWindow(); } -//vls-end// - /*else */ } break; diff --git a/sources/AnsiWnd.h b/sources/AnsiWnd.h index 2e7b33f..2bb20a6 100644 --- a/sources/AnsiWnd.h +++ b/sources/AnsiWnd.h @@ -7,6 +7,8 @@ // AnsiWnd.h : header file // +#include + ///////////////////////////////////////////////////////////////////////////// // CAnsiWnd window @@ -21,6 +23,7 @@ class CAnsiWnd : public CWnd int m_nCurrentBg, m_nCurrentFg; BOOL m_bAnsiBold; CStringList m_strList; + std::vector m_LineCountsList; //vls-begin// multiple output int m_wndCode; @@ -28,6 +31,7 @@ class CAnsiWnd : public CWnd protected: int m_nPageSize, m_nLastPageSize; + int m_nLineWidth; int m_nStartSelectX, m_nStartSelectY, m_nEndSelectX, m_nEndSelectY; // Selection while grabbing screen int m_nStartTrackX, m_nStartTrackY, m_nEndTrackX, m_nEndTrackY; // Tracking positions of mouse @@ -36,6 +40,8 @@ class CAnsiWnd : public CWnd BOOL m_bSelected; + void ConvertCharPosition(int TextRow, int TextCol, int *LineNum, int *CharPos); + void SetScrollSettings(BOOL bResetPosition = TRUE); void RedrawOneLine(CDC* pDC, int LineNum); diff --git a/sources/CharSubstPage.cpp b/sources/CharSubstPage.cpp index ecf0ca5..2704b0b 100644 --- a/sources/CharSubstPage.cpp +++ b/sources/CharSubstPage.cpp @@ -180,7 +180,8 @@ void CCharSubstPage::OnAdd() return; } - for ( int i = 0 ; i < *((int*)m_charsSubst) ; i++ ) { + int i; + for ( i = 0 ; i < *((int*)m_charsSubst) ; i++ ) { if ( m_charsSubst[sizeof(int) + i*2] == m_strOldChar[0] && m_charsSubst[sizeof(int) + i*2+1] == m_strNewChar[0] ) { CString t1,t2; diff --git a/sources/CommonParamsPage.cpp b/sources/CommonParamsPage.cpp index 6202c4f..23eea08 100644 --- a/sources/CommonParamsPage.cpp +++ b/sources/CommonParamsPage.cpp @@ -35,6 +35,13 @@ CCommonParamsPage::CCommonParamsPage() : CPropertyPage(CCommonParamsPage::IDD, I m_bSplitOnBackscroll = FALSE; m_nTrigDelay = 0; m_bMinimizeToTray = FALSE; + m_wBCastUdpPort = 0; + m_bBCastLocalIP = FALSE; + m_bBCastSamePort = FALSE; + m_bLineWrap = TRUE; + m_bSelectRect = FALSE; + m_bRemoveESC = TRUE; + m_bShowHidden = TRUE; //}}AFX_DATA_INIT } @@ -65,6 +72,14 @@ void CCommonParamsPage::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_SPLIT_ONBACKSCROLL, m_bSplitOnBackscroll); DDX_Check(pDX, IDC_MINIMIZE_TO_TRAY, m_bMinimizeToTray); DDX_Text(pDX, IDC_TRIG_DELAY, m_nTrigDelay); + DDX_Text(pDX, IDC_BCAST_UDP_PORT, m_wBCastUdpPort); + DDV_MinMaxUInt(pDX, m_wBCastUdpPort, 5000, 30000); + DDX_Check(pDX, IDC_BCAST_LOCAL_IP, m_bBCastLocalIP); + DDX_Check(pDX, IDC_BCAST_SAME_PORT, m_bBCastSamePort); + DDX_Check(pDX, IDC_CHK_LINEWRAP, m_bLineWrap); + DDX_Check(pDX, IDC_CHK_SELECTRECT, m_bSelectRect); + DDX_Check(pDX, IDC_CHK_REMOVEESC, m_bRemoveESC); + DDX_Check(pDX, IDC_CHK_SHOWHIDDEN, m_bShowHidden); //}}AFX_DATA_MAP } diff --git a/sources/CommonParamsPage.h b/sources/CommonParamsPage.h index b7371ed..7a63f72 100644 --- a/sources/CommonParamsPage.h +++ b/sources/CommonParamsPage.h @@ -42,6 +42,13 @@ class CCommonParamsPage : public CPropertyPage BOOL m_bSplitOnBackscroll; BOOL m_bMinimizeToTray; int m_nTrigDelay; + UINT m_wBCastUdpPort; + BOOL m_bBCastLocalIP; + BOOL m_bBCastSamePort; + BOOL m_bLineWrap; + BOOL m_bSelectRect; + BOOL m_bRemoveESC; + BOOL m_bShowHidden; //}}AFX_DATA diff --git a/sources/CoolDialogBar.cpp b/sources/CoolDialogBar.cpp index 4e1d0f9..0be330a 100644 --- a/sources/CoolDialogBar.cpp +++ b/sources/CoolDialogBar.cpp @@ -382,7 +382,7 @@ void CCoolDialogBar::OnNcLButtonDown(UINT nHitTest, CPoint point) CControlBar::OnNcLButtonDown(nHitTest, point); } -UINT CCoolDialogBar::OnNcHitTest(CPoint point) +LRESULT CCoolDialogBar::OnNcHitTest(CPoint point) { if (IsFloating()) return CControlBar::OnNcHitTest(point); diff --git a/sources/CoolDialogBar.h b/sources/CoolDialogBar.h index 374e22a..53efb53 100644 --- a/sources/CoolDialogBar.h +++ b/sources/CoolDialogBar.h @@ -104,7 +104,7 @@ class CCoolDialogBar : public CControlBar afx_msg void OnWindowPosChanged(WINDOWPOS FAR* lpwndpos); afx_msg void OnNcPaint(); afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point); - afx_msg UINT OnNcHitTest(CPoint point); + afx_msg LRESULT OnNcHitTest(CPoint point); afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnCaptureChanged(CWnd *pWnd); diff --git a/sources/JMCActionsPage.cpp b/sources/JMCActionsPage.cpp index bf1234f..0136b6c 100644 --- a/sources/JMCActionsPage.cpp +++ b/sources/JMCActionsPage.cpp @@ -25,6 +25,7 @@ CJMCActionsPage::CJMCActionsPage() : CGroupedPage(CJMCActionsPage::IDD, IDS_ACTI m_strText = _T(""); m_strGroup = _T(""); m_nPriority = -1; + m_nInputType = -1; //}}AFX_DATA_INIT m_bNewItem = FALSE; } @@ -44,6 +45,7 @@ void CJMCActionsPage::DoDataExchange(CDataExchange* pDX) DDX_Text(pDX, IDC_TEXT, m_strText); DDX_CBString(pDX, IDC_GRP, m_strGroup); DDX_CBIndex(pDX, IDC_PRIORITY, m_nPriority); + DDX_CBIndex(pDX, IDC_ACTION_TYPE, m_nInputType); //}}AFX_DATA_MAP } @@ -58,6 +60,7 @@ BEGIN_MESSAGE_MAP(CJMCActionsPage, CPropertyPage) ON_BN_CLICKED(IDC_REMOVE, OnRemove) ON_EN_KILLFOCUS(IDC_NAME, OnKillfocusName) ON_CBN_SELCHANGE(IDC_PRIORITY, OnSelchangePriority) + ON_CBN_SELCHANGE(IDC_ACTION_TYPE, OnSelchangeInputType) ON_EN_CHANGE(IDC_NAME, OnChangeName) //}}AFX_MSG_MAP END_MESSAGE_MAP() @@ -88,7 +91,9 @@ BOOL CJMCActionsPage::OnInitDialog() m_cActionsList.InsertColumn (2 , t , LVCFMT_LEFT , 100 ); t.LoadString(IDS_TP_PRIORITY_COL); m_cActionsList.InsertColumn (3 , t , LVCFMT_LEFT , 30 ); - + t.LoadString(IDS_TP_INPUTTYPE_COL); + m_cActionsList.InsertColumn (4 , t , LVCFMT_LEFT , 70 ); + m_cActionsList.SetImageList(&m_ImageList, LVSIL_SMALL); @@ -133,18 +138,21 @@ void CJMCActionsPage::SetControls() GetDlgItem(IDC_TEXT)->EnableWindow(FALSE); GetDlgItem(IDC_REMOVE)->EnableWindow(FALSE); GetDlgItem(IDC_PRIORITY)->EnableWindow(FALSE); + GetDlgItem(IDC_ACTION_TYPE)->EnableWindow(FALSE); m_cGroup.EnableWindow (FALSE); } else { GetDlgItem(IDC_NAME)->EnableWindow(TRUE); GetDlgItem(IDC_TEXT)->EnableWindow(TRUE); GetDlgItem(IDC_REMOVE)->EnableWindow(TRUE); GetDlgItem(IDC_PRIORITY)->EnableWindow(TRUE); + GetDlgItem(IDC_ACTION_TYPE)->EnableWindow(TRUE); m_cGroup.EnableWindow (TRUE); PACTION pAct = (PACTION)m_cActionsList.GetItemData(pos); m_strName = pAct->m_strLeft.data(); m_strText = pAct->m_strRight.data(); m_cGroup.SelectGroup (pAct->m_pGroup ); m_nPriority = pAct->m_nPriority ; + m_nInputType = (int)pAct->m_InputType; } UpdateData(FALSE); } @@ -179,6 +187,12 @@ int CJMCActionsPage::AddItem(void* p) lvi.mask = LVIF_TEXT ; lvi.pszText = buff; m_cActionsList.SetItem (&lvi); + m_cActionsList.SetItemData(ind, (DWORD)p); + + lvi.iSubItem = 4; + lvi.mask = LVIF_TEXT ; + lvi.pszText = (LPSTR)act_type_to_str((int)pAct->m_InputType); + m_cActionsList.SetItem (&lvi); m_cActionsList.SetItemData(ind, (DWORD)p); return ind; @@ -295,7 +309,7 @@ void CJMCActionsPage::OnKillfocusName() return; } */ - PACTION pAct = SetAction((LPSTR)(LPCSTR)m_strName, "", 5, NULL ); + PACTION pAct = SetAction((ACTION::ActionType)m_nInputType, (LPSTR)(LPCSTR)m_strName, "", 5, NULL ); if ( !pAct ) return; int i = AddItem(pAct); @@ -336,6 +350,25 @@ void CJMCActionsPage::OnSelchangePriority() m_cActionsList.SetItem (&lvi); } +void CJMCActionsPage::OnSelchangeInputType() +{ + UpdateData(); + int pos = m_cActionsList.GetNextItem(-1, LVNI_SELECTED); + ASSERT(pos >= 0 ); + PACTION pAct = (PACTION )m_cActionsList.GetItemData(pos); + ASSERT(pAct); + pAct->m_InputType = (ACTION::ActionType)m_nInputType; + // SetAction((LPSTR)pAct->m_strLeft.data(), (LPSTR)(LPCSTR)m_strText, m_nPriority, NULL); + + LV_ITEM lvi; + ZeroMemory(&lvi , sizeof(lvi)); + lvi.iItem = pos; + lvi.iSubItem = 4; + lvi.mask = LVIF_TEXT ; + lvi.pszText = (LPSTR)act_type_to_str((int)pAct->m_InputType); + m_cActionsList.SetItem (&lvi); +} + void CJMCActionsPage::OnChangeName() { if ( m_bNewItem ) diff --git a/sources/JMCActionsPage.h b/sources/JMCActionsPage.h index 47013b5..5839c41 100644 --- a/sources/JMCActionsPage.h +++ b/sources/JMCActionsPage.h @@ -39,6 +39,7 @@ class CJMCActionsPage : public CGroupedPage CString m_strText; CString m_strGroup; int m_nPriority; + int m_nInputType; //}}AFX_DATA @@ -62,6 +63,7 @@ class CJMCActionsPage : public CGroupedPage afx_msg void OnRemove(); afx_msg void OnKillfocusName(); afx_msg void OnSelchangePriority(); + afx_msg void OnSelchangeInputType(); afx_msg void OnChangeName(); //}}AFX_MSG DECLARE_MESSAGE_MAP() diff --git a/sources/MainFrm.cpp b/sources/MainFrm.cpp index 627f656..e35f415 100644 --- a/sources/MainFrm.cpp +++ b/sources/MainFrm.cpp @@ -293,6 +293,8 @@ BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_MESSAGE(WM_USER+655, OnUpdStat5) //*/en + ON_MESSAGE(WM_USER+680, OnUpdPing) + // sysTray command ON_MESSAGE(WM_USER+701, OnTrayMessage) @@ -537,6 +539,13 @@ void CMainFrame::OnOptionsOptions() pg1.m_bSplitOnBackscroll = pDoc->m_bSplitOnBackscroll; pg1.m_bMinimizeToTray = bMinimizeToTray; pg1.m_nTrigDelay = MoreComingDelay; + pg1.m_wBCastUdpPort = wBCastUdpPort; + pg1.m_bBCastLocalIP = bBCastFilterIP; + pg1.m_bBCastSamePort = bBCastFilterPort; + pg1.m_bLineWrap = pDoc->m_bLineWrap; + pg1.m_bSelectRect = pDoc->m_bRectangleSelection; + pg1.m_bRemoveESC = pDoc->m_bRemoveESCSelection; + pg1.m_bShowHidden = pDoc->m_bShowHiddenText; // Fill subst params @@ -607,6 +616,18 @@ void CMainFrame::OnOptionsOptions() pDoc->m_bSplitOnBackscroll = pg1.m_bSplitOnBackscroll; if ( !pg1.m_bSplitOnBackscroll ) OnUnsplit(); + if( wBCastUdpPort != pg1.m_wBCastUdpPort || + bBCastFilterIP != pg1.m_bBCastLocalIP || + bBCastFilterPort != pg1.m_bBCastSamePort ) { + wBCastUdpPort = pg1.m_wBCastUdpPort; + bBCastFilterIP = pg1.m_bBCastLocalIP; + bBCastFilterPort = pg1.m_bBCastSamePort; + reopen_bcast_socket(); + } + pDoc->m_bLineWrap = pg1.m_bLineWrap; + pDoc->m_bRectangleSelection = pg1.m_bSelectRect; + pDoc->m_bRemoveESCSelection = pg1.m_bRemoveESC; + pDoc->m_bShowHiddenText = pg1.m_bShowHidden; MoreComingDelay =pg1.m_nTrigDelay; @@ -711,7 +732,15 @@ void CMainFrame::OnUpdateInfo1(CCmdUI* pUI) EnterCriticalSection(&secStatusSection); if ( m_strInfo1 != strInfo1 ) { m_strInfo1 = strInfo1; - m_wndStatusBar.GetStatusBarCtrl ().SetText(strInfo1, NUM_INDICATOR_INFO1, SBT_OWNERDRAW ); + + int Width = m_strInfo1.GetLength() * pDoc->m_nCharX; + UINT Style, ID; + int Size; + m_wndStatusBar.GetPaneInfo(NUM_INDICATOR_INFO1 , ID, Style, Size); + if ( Size < Width ) + m_wndStatusBar.SetPaneInfo(NUM_INDICATOR_INFO1, ID, Style, Width); + + m_wndStatusBar.GetStatusBarCtrl ().SetText(m_strInfo1, NUM_INDICATOR_INFO1, SBT_OWNERDRAW ); } LeaveCriticalSection(&secStatusSection); } @@ -719,9 +748,18 @@ void CMainFrame::OnUpdateInfo1(CCmdUI* pUI) void CMainFrame::OnUpdateInfo2(CCmdUI* pUI) { EnterCriticalSection(&secStatusSection); - if ( m_strInfo2 != strInfo2 ) { + if ( m_strInfo2 != strInfo2 ) + { m_strInfo2 = strInfo2; - m_wndStatusBar.GetStatusBarCtrl ().SetText(strInfo2, NUM_INDICATOR_INFO2, SBT_OWNERDRAW ); + + int Width = m_strInfo2.GetLength() * pDoc->m_nCharX; + UINT Style, ID; + int Size; + m_wndStatusBar.GetPaneInfo(NUM_INDICATOR_INFO2 , ID, Style, Size); + if ( Size < Width ) + m_wndStatusBar.SetPaneInfo(NUM_INDICATOR_INFO2, ID, Style, Width); + + m_wndStatusBar.GetStatusBarCtrl ().SetText(m_strInfo2, NUM_INDICATOR_INFO2, SBT_OWNERDRAW ); } LeaveCriticalSection(&secStatusSection); } @@ -731,7 +769,15 @@ void CMainFrame::OnUpdateInfo3(CCmdUI* pUI) EnterCriticalSection(&secStatusSection); if ( m_strInfo3 != strInfo3 ) { m_strInfo3 = strInfo3; - m_wndStatusBar.GetStatusBarCtrl ().SetText(strInfo3, NUM_INDICATOR_INFO3, SBT_OWNERDRAW ); + + int Width = m_strInfo3.GetLength() * pDoc->m_nCharX; + UINT Style, ID; + int Size; + m_wndStatusBar.GetPaneInfo(NUM_INDICATOR_INFO3 , ID, Style, Size); + if ( Size < Width ) + m_wndStatusBar.SetPaneInfo(NUM_INDICATOR_INFO3, ID, Style, Width); + + m_wndStatusBar.GetStatusBarCtrl ().SetText(m_strInfo3, NUM_INDICATOR_INFO3, SBT_OWNERDRAW ); } LeaveCriticalSection(&secStatusSection); } @@ -741,7 +787,15 @@ void CMainFrame::OnUpdateInfo4(CCmdUI* pUI) EnterCriticalSection(&secStatusSection); if ( m_strInfo4 != strInfo4 ) { m_strInfo4 = strInfo4; - m_wndStatusBar.GetStatusBarCtrl ().SetText(strInfo4, NUM_INDICATOR_INFO4, SBT_OWNERDRAW ); + + int Width = m_strInfo4.GetLength() * pDoc->m_nCharX; + UINT Style, ID; + int Size; + m_wndStatusBar.GetPaneInfo(NUM_INDICATOR_INFO4 , ID, Style, Size); + if ( Size < Width ) + m_wndStatusBar.SetPaneInfo(NUM_INDICATOR_INFO4, ID, Style, Width); + + m_wndStatusBar.GetStatusBarCtrl ().SetText(m_strInfo4, NUM_INDICATOR_INFO4, SBT_OWNERDRAW ); } LeaveCriticalSection(&secStatusSection); } @@ -751,7 +805,15 @@ void CMainFrame::OnUpdateInfo5(CCmdUI* pUI) EnterCriticalSection(&secStatusSection); if ( m_strInfo5 != strInfo5 ) { m_strInfo5 = strInfo5; - m_wndStatusBar.GetStatusBarCtrl ().SetText(strInfo5, NUM_INDICATOR_INFO5, SBT_OWNERDRAW ); + + int Width = m_strInfo5.GetLength() * pDoc->m_nCharX; + UINT Style, ID; + int Size; + m_wndStatusBar.GetPaneInfo(NUM_INDICATOR_INFO5 , ID, Style, Size); + if ( Size < Width ) + m_wndStatusBar.SetPaneInfo(NUM_INDICATOR_INFO5, ID, Style, Width); + + m_wndStatusBar.GetStatusBarCtrl ().SetText(m_strInfo5, NUM_INDICATOR_INFO5, SBT_OWNERDRAW ); } LeaveCriticalSection(&secStatusSection); } @@ -1168,7 +1230,7 @@ LONG CMainFrame::OnTabAdded( UINT wParam, LONG lParam) POSITION pos = pDoc->m_lstTabWords.GetHeadPosition (); while (pos ) { CString str = pDoc->m_lstTabWords.GetAt(pos); - if ( !strcmpi(p, str) ){ + if ( !_strcmpi(p, str) ){ pDoc->m_lstTabWords.RemoveAt (pos); break; } @@ -1191,7 +1253,7 @@ LONG CMainFrame::OnTabDeleted( UINT wParam, LONG lParam) POSITION pos = pDoc->m_lstTabWords.GetHeadPosition (); while (pos ) { CString str = pDoc->m_lstTabWords.GetAt(pos); - if ( !strcmpi(p, str) ){ + if ( !_strcmpi(p, str) ){ pDoc->m_lstTabWords.RemoveAt (pos); break; } @@ -1275,45 +1337,101 @@ LONG CMainFrame::OnCleanInput(UINT wParam, LONG lParam) LONG CMainFrame::OnUpdStat1(UINT wParam, LONG lParam) { - char bf[BUFFER_SIZE];strcpy(bf,strInfo1); + /*char bf[BUFFER_SIZE];strcpy(bf,strInfo1); strcpy(strInfo1,"?");CMainFrame::OnUpdateInfo1(NULL); - strcpy(strInfo1,bf); CMainFrame::OnUpdateInfo1(NULL); + strcpy(strInfo1,bf); + */ + CMainFrame::OnUpdateInfo1(NULL); return 1; } LONG CMainFrame::OnUpdStat2(UINT wParam, LONG lParam) { - char bf[BUFFER_SIZE];strcpy(bf,strInfo2); + /*char bf[BUFFER_SIZE];strcpy(bf,strInfo2); strcpy(strInfo2,"?");CMainFrame::OnUpdateInfo2(NULL); - strcpy(strInfo2,bf); CMainFrame::OnUpdateInfo2(NULL); + strcpy(strInfo2,bf);*/ + CMainFrame::OnUpdateInfo2(NULL); return 1; } LONG CMainFrame::OnUpdStat3(UINT wParam, LONG lParam) { - char bf[BUFFER_SIZE];strcpy(bf,strInfo3); + /*char bf[BUFFER_SIZE];strcpy(bf,strInfo3); strcpy(strInfo3,"?");CMainFrame::OnUpdateInfo3(NULL); - strcpy(strInfo3,bf); CMainFrame::OnUpdateInfo3(NULL); + strcpy(strInfo3,bf); */ + CMainFrame::OnUpdateInfo3(NULL); return 1; } LONG CMainFrame::OnUpdStat4(UINT wParam, LONG lParam) { - char bf[BUFFER_SIZE];strcpy(bf,strInfo4); + /*char bf[BUFFER_SIZE];strcpy(bf,strInfo4); strcpy(strInfo4,"?");CMainFrame::OnUpdateInfo4(NULL); - strcpy(strInfo4,bf); CMainFrame::OnUpdateInfo4(NULL); + strcpy(strInfo4,bf); */ + CMainFrame::OnUpdateInfo4(NULL); return 1; } LONG CMainFrame::OnUpdStat5(UINT wParam, LONG lParam) { - char bf[BUFFER_SIZE];strcpy(bf,strInfo5); + /*char bf[BUFFER_SIZE];strcpy(bf,strInfo5); strcpy(strInfo5,"?");CMainFrame::OnUpdateInfo5(NULL); - strcpy(strInfo5,bf); CMainFrame::OnUpdateInfo5(NULL); + strcpy(strInfo5,bf); */ + CMainFrame::OnUpdateInfo5(NULL); return 1; } +LONG CMainFrame::OnUpdPing(UINT wParam, LONG lParam) +{ + int mud_ping = (int)wParam; + int proxy_ping = (int)lParam; + static char mud_buf[64], proxy_buf[64], msg_buf[128]; + + switch(mud_ping) { + case -3: + sprintf(mud_buf, "ping error"); + break; + case -2: + sprintf(mud_buf, "no connection"); + break; + case -1: + sprintf(mud_buf, "PING TIMEOUT"); + break; + case 0: + sprintf(mud_buf, "ping <1 ms"); + break; + default: + sprintf(mud_buf, "ping %d ms", mud_ping); + break; + } + + switch(proxy_ping) { + case -3: + sprintf(proxy_buf, " (proxy: error)"); + break; + case -2: + sprintf(proxy_buf, ""); + break; + case -1: + sprintf(proxy_buf, " (proxy: TIMEOUT)"); + break; + case 0: + sprintf(proxy_buf, " (proxy: <1 ms)"); + break; + default: + sprintf(proxy_buf, " (proxy: %d ms)", proxy_ping); + break; + } + + sprintf(msg_buf, "%s%s", mud_buf, proxy_buf); + + m_wndStatusBar.SetPaneText(0, msg_buf); + + return 1; +} + + LONG CMainFrame::OnDockOutput(UINT wParam, LONG lParam) { int wnd = (int)wParam; diff --git a/sources/MainFrm.h b/sources/MainFrm.h index 27c197b..657c22e 100644 --- a/sources/MainFrm.h +++ b/sources/MainFrm.h @@ -191,6 +191,8 @@ class CMainFrame : public CFrameWnd afx_msg LONG OnUpdStat4(UINT wParam, LONG lParam); afx_msg LONG OnUpdStat5(UINT wParam, LONG lParam); + afx_msg LONG OnUpdPing(UINT wParam, LONG lParam); + afx_msg LONG OnTrayMessage(UINT wParam, LONG lParam); afx_msg void OnSysCommand(UINT wParam, LPARAM lParam); diff --git a/sources/Tray.cpp b/sources/Tray.cpp index 92a3f2a..e9a8ade 100644 --- a/sources/Tray.cpp +++ b/sources/Tray.cpp @@ -23,14 +23,14 @@ CTray::CTray(int nIconID, LPCTSTR szTip) isInSysTray = FALSE; } -CTray::add() +BOOL CTray::add() { isInSysTray = TRUE; return Shell_NotifyIcon(NIM_ADD, &iconData); } -CTray::remove() +BOOL CTray::remove() { isInSysTray = FALSE; diff --git a/sources/help/action.jht b/sources/help/action.jht index 965f006..7677a99 100644 --- a/sources/help/action.jht +++ b/sources/help/action.jht @@ -1,7 +1,19 @@ #action [] show all action containing pattern -#action [priority] [group] +#action [text|raw|ansi|smaug|sow] [priority] [group] +#action [text|raw|ansi|smaug|sow] //[i|m] [priority] [group] set reaction on pattern with priority in group + available types of testing line: + text - all color esc-sequences are removed + raw - line remains unchanged + ansi - color codes are placed in the right-most positions, background + codes are removed, colors for empty-substrings are omitted + smaug- same as ansi, esc-sequences replaced with codes such as "&w", "&R" and so on + sow - same as ansi, esc-sequences replaced with codes such as "[7]", "{1}" and so on + default type: text + possible flags: + i - case insensitive + m - multiline (pattern will be tested against eash batch of lines devided by GA, EOP, long delay or user input) #unaction delete action diff --git a/sources/help/alias.jht b/sources/help/alias.jht index 4c0c5db..de05233 100644 --- a/sources/help/alias.jht +++ b/sources/help/alias.jht @@ -2,6 +2,8 @@ show all or specified alias #alias [group] create alias name to command in group +#alias //[i] [group] + create alias with regular expression (optionally case insensitive) #unalias delete specified alias #verbatim [on|off] diff --git a/sources/help/broadcast.jht b/sources/help/broadcast.jht new file mode 100644 index 0000000..72dddc8 --- /dev/null +++ b/sources/help/broadcast.jht @@ -0,0 +1,6 @@ +#broadcast {text} + sends text to all JMC instances running on the + current machine or in current local network (depending + on user setting) and using same port number + (see "Options -> Common -> Broadcast messaging") + \ No newline at end of file diff --git a/sources/help/clear.jht b/sources/help/clear.jht new file mode 100644 index 0000000..24077b4 --- /dev/null +++ b/sources/help/clear.jht @@ -0,0 +1,2 @@ +#clear + clear main screen \ No newline at end of file diff --git a/sources/help/mccp.jht b/sources/help/mccp.jht new file mode 100644 index 0000000..5782c31 --- /dev/null +++ b/sources/help/mccp.jht @@ -0,0 +1,3 @@ +#mccp [on|off] + toggles or sets/resets compression support via MCCP protocol + for certain MUDs reconnection could be neccessary \ No newline at end of file diff --git a/sources/help/promptchar.jht b/sources/help/promptchar.jht new file mode 100644 index 0000000..30ee60c --- /dev/null +++ b/sources/help/promptchar.jht @@ -0,0 +1,6 @@ +#promptchar + show current end-of-prompt character +#promptchar disable + disables control of the end of prompt (use telnet GA and EOR options if possible) +#promptchar + set character that ends your prompt (be sure it can't be printed by your MUD in other lines) \ No newline at end of file diff --git a/sources/help/proxy.jht b/sources/help/proxy.jht new file mode 100644 index 0000000..da7f127 --- /dev/null +++ b/sources/help/proxy.jht @@ -0,0 +1,16 @@ +#proxy + show current proxy settings +#proxy disable + disable proxy (reconnection needed) +#proxy {socks4|socks5} {ip}[:{port}] [username] [password] + set proxy to ip:port (default port is 1080) + authorization use given username and password + reconnection needed +#proxy list {filename} [line] + takes proxy settings from file filename + if line not specified then next from previous + call line is taken + lines in file are numbered circular + format of lines is identical to the proxy command + arguments i.e. "socks4 127.0.0.1:9150 tor" + \ No newline at end of file diff --git a/sources/help/random.jht b/sources/help/random.jht new file mode 100644 index 0000000..dd2e6df --- /dev/null +++ b/sources/help/random.jht @@ -0,0 +1,9 @@ +#random {varibale} {min} {max} + sets value of certain variable to random + evenly distributed integer number + between min and max exclusive, [min..max) +#random {variable} {max} + interval is [0..max) +#random {variable} + interval is [0..100) + \ No newline at end of file diff --git a/sources/help/srandom.jht b/sources/help/srandom.jht new file mode 100644 index 0000000..de36f84 --- /dev/null +++ b/sources/help/srandom.jht @@ -0,0 +1,4 @@ +#srandom [seed] + sets random seed for random numbers generator + if no seed is present, then current system time is taken + \ No newline at end of file diff --git a/sources/help/strcmp.jht b/sources/help/strcmp.jht new file mode 100644 index 0000000..54c321c --- /dev/null +++ b/sources/help/strcmp.jht @@ -0,0 +1,6 @@ +#strcmp {str1} {str2} {true-expr} [false-expr] + compares str1 and str2 (including variables substitution) + if string are equal, then true-expr is evaluated + otherwise false-expr is evaluated, if present + (comparsion is case-sensitive) + \ No newline at end of file diff --git a/sources/help/sync.jht b/sources/help/sync.jht new file mode 100644 index 0000000..eb2a2fd --- /dev/null +++ b/sources/help/sync.jht @@ -0,0 +1,5 @@ +#sync + force reading and processing all data from + incoming buffers i.e. from MUD and JMC broadcasts + can be useful in triggers/loops/recursive aliases/etc. + \ No newline at end of file diff --git a/sources/help/wclear.jht b/sources/help/wclear.jht new file mode 100644 index 0000000..54091b5 --- /dev/null +++ b/sources/help/wclear.jht @@ -0,0 +1,2 @@ +#wclear {wnd} + clear output window \ No newline at end of file diff --git a/sources/help/wdock.jht b/sources/help/wdock.jht index c2f8027..67768b4 100644 --- a/sources/help/wdock.jht +++ b/sources/help/wdock.jht @@ -1,3 +1,3 @@ -#wdock {wnd} [disable] +#wdock {wnd} [disable|top|left|right|bottom] allows disabling output windows docking to frame sides and docked bars. if this window never was target of wpos then it will be in free fly. \ No newline at end of file diff --git a/sources/html.log.template b/sources/html.log.template index 12ff953..1a95837 100644 --- a/sources/html.log.template +++ b/sources/html.log.template @@ -10,7 +10,7 @@ a {text-decoration: underline; color: #88f;} a:visited {color: #88f;} a:hover {color: #f88;} i {font-style: normal;color: #ccc;} i.l {color: #fff;} - .bl{color:#555} .l.bl{color:#888} .b_bl{background-color:#555} + .bl{color:#555} .l.bl{color:#888} .b_bl{background-color:#000} .r {color:#c00} .l.r {color:#f00} .b_r {background-color:#c00} .g {color:#0c0} .l.g {color:#0f0} .b_g {background-color:#0c0} .y {color:#cc0} .l.y {color:#ff0} .b_y {background-color:#cc0} diff --git a/sources/htmltimestamps.log.template b/sources/htmltimestamps.log.template index b5ff1bb..7b0cd13 100644 --- a/sources/htmltimestamps.log.template +++ b/sources/htmltimestamps.log.template @@ -10,7 +10,7 @@ a {text-decoration: underline; color: #88f;} a:visited {color: #88f;} a:hover {color: #f88;} i {font-style: normal;color: #ccc;} i.l {color: #fff;} - .bl{color:#555} .l.bl{color:#888} .b_bl{background-color:#555} + .bl{color:#555} .l.bl{color:#888} .b_bl{background-color:#000} .r {color:#c00} .l.r {color:#f00} .b_r {background-color:#c00} .g {color:#0c0} .l.g {color:#0f0} .b_g {background-color:#0c0} .y {color:#cc0} .l.y {color:#ff0} .b_y {background-color:#cc0} @@ -94,13 +94,28 @@ var time = parseInt(match[1]); if (!isNaN(time)) this.frames.push({ - "id": els[i].id, + "el": els[i], "time_ms": time, "top": els[i].offsetTop - log_offset + line_height }); } } this.frames.sort(function(a,b) { return a.time_ms - b.time_ms; }); + if (this.frames.length > 0) { + var t0 = this.frames[0].time_ms; + for (var i = 0; i < this.frames.length; i++) + this.frames[i].time_ms -= t0; + } + }, + + checkInitialized: function() { + if (this.area == null) { + this.area = document.getElementById("log_area"); + this.speed = document.getElementById("play_speed"); + this.time = document.getElementById("log_time"); + } + if (this.frames.length == 0) + this.loadFrames(); }, duration: function() { @@ -169,6 +184,7 @@ }, setLogTimeToPosition: function() { + this.checkInitialized(); var pos = this.area.scrollTop + this.area.offsetHeight; var index = this.frameByPosition(pos); if (index < this.frames.length) @@ -231,13 +247,7 @@ }, start: function() { - if (this.area == null) { - this.area = document.getElementById("log_area"); - this.speed = document.getElementById("play_speed"); - this.time = document.getElementById("log_time"); - } - if (this.frames.length == 0) - this.loadFrames(); + this.checkInitialized(); if (this.duration() == 0) return false; @@ -283,4 +293,4 @@