void CMUSHclientDoc::ResetConfigurationArrays (void) { int i; for (i = 0; i < NUMITEMS (OptionsTable); i++) m_NumericConfiguration [i]->Reset (); for (i = 0; i < NUMITEMS (AlphaOptionsTable); i++) m_AlphaConfiguration [i]->Reset (); }
void CMUSHclientDoc::DeleteConfigurationArrays (void) { int i; for (i = 0; i < NUMITEMS (OptionsTable); i++) delete m_NumericConfiguration [i]; m_NumericConfiguration.RemoveAll (); for (i = 0; i < NUMITEMS (AlphaOptionsTable); i++) delete m_AlphaConfiguration [i]; m_AlphaConfiguration.RemoveAll (); }
void CMUSHclientDoc::AllocateConfigurationArrays (void) { int i; m_NumericConfiguration.SetSize (NUMITEMS (OptionsTable)); for (i = 0; i < NUMITEMS (OptionsTable); i++) m_NumericConfiguration.SetAt (i, new CNumericConfiguration); m_AlphaConfiguration.SetSize (NUMITEMS (AlphaOptionsTable)); for (i = 0; i < NUMITEMS (AlphaOptionsTable); i++) m_AlphaConfiguration.SetAt (i, new CAlphaConfiguration); }
long CMUSHclientDoc::GetOptionItem (const int iItem) { return GetBaseOptionItem (iItem, OptionsTable, NUMITEMS (OptionsTable), (char *) this); }
CString CMUSHclientDoc::GetAlphaOptionItem (const int iItem) { return GetBaseAlphaOptionItem (iItem, AlphaOptionsTable, NUMITEMS (AlphaOptionsTable), (char *) this); } // end of CMUSHclientDoc::GetAlphaOptionItem
BSTR CMUSHclientDoc::Hash(LPCTSTR Text) { CString strResult; SHS_INFO shsInfo; shsInit (&shsInfo); shsUpdate (&shsInfo, (unsigned char *) (const char *) Text, strlen (Text)); shsFinal (&shsInfo); for (int i = 0; i < NUMITEMS (shsInfo.digest); i++) strResult += CFormat ("%08x", shsInfo.digest [i]); return strResult.AllocSysString(); } // end of CMUSHclientDoc::Hash
// returns true if archive turns out to be XML bool IsArchiveXML (CArchive& ar) { // auto-detect XML files char buf [500], // should be even number of bytes in case Unicode buf2 [500]; memset (buf, 0, sizeof (buf)); ar.GetFile ()->Read (buf, sizeof (buf) - 2); // allow for Unicode 00 00 ar.GetFile ()->SeekToBegin (); // back to start for further serialisation // look for Unicode (FF FE) if ((unsigned char) buf [0] == 0xFF && (unsigned char) buf [1] == 0xFE) WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR) &buf [2], -1, buf2, sizeof buf2, NULL, NULL); else // look for UTF-8 indicator bytes (EF BB BF) if ((unsigned char) buf [0] == 0xEF && (unsigned char) buf [1] == 0xBB && (unsigned char) buf [2] == 0xBF) strcpy (buf2, &buf [3]); // skip them else strcpy (buf2, buf); char * p = buf2; // skip leading whitespace while (isspace (*p)) p++; // can't see them squeezing much into less than 15 chars // (eg. minimum would be <macros></macros> ) if (strlen (p) < 15) return false; for (int i = 0; i < NUMITEMS (sigs); i++) if (COMPARE_MEMORY (sigs [i])) return true; return false; } // end of IsArchiveXML
// general MXP error message routine - appends a newline, and also writes to debug void CMUSHclientDoc::MXP_error (const int iLevel, const long iMessageNumber, CString strMessage) { char * sLevel [] = { " ", "E", // error "W", // warning "I", // info "A", // all }; char * p = "?"; // turn error level into a character if (iLevel >= 0 && iLevel < NUMITEMS (sLevel)) p = sLevel [iLevel]; if (iLevel == DBG_ERROR) { m_iMXPerrors++; MXP_Restore_Mode (); // an error cancels secure-once mode } // end of error // call script if required if (m_dispidOnMXP_Error != DISPID_UNKNOWN) { long nInvocationCount = 0; CString strType = "MXP Error"; CString strReason = "processing MXP error"; if (GetScriptEngine () && GetScriptEngine ()->IsLua ()) { list<double> nparams; list<string> sparams; nparams.push_back (iMessageNumber); // error number nparams.push_back (m_LineList.GetCount ()); // line sparams.push_back (p); // level (a character) sparams.push_back ((LPCTSTR) strMessage); // message bool result; GetScriptEngine ()->ExecuteLua (m_dispidOnMXP_Error, m_strOnMXP_Error, eWorldAction, strType, strReason, nparams, sparams, nInvocationCount, NULL, NULL, NULL, &result); if (result) return; } // end of Lua else { // WARNING - arguments should appear in REVERSE order to what the sub expects them! enum { eErrorMessage, eLineNumber, eMessageNumber, eErrorLevel, eArgCount, // this MUST be last }; COleVariant args [eArgCount]; DISPPARAMS params = { args, NULL, eArgCount, 0 }; args [eErrorLevel] = p; args [eMessageNumber] = iMessageNumber; args [eLineNumber] = (long) m_LineList.GetCount (); args [eErrorMessage] = strMessage; COleVariant result; ExecuteScript (m_dispidOnMXP_Error, m_strOnMXP_Error, eWorldAction, strType, strReason, params, nInvocationCount, &result); // if the function returns a non-zero result, don't display the message if (result.vt != VT_EMPTY) { result.ChangeType (VT_I4); // make a long if (result.vt == VT_I4) // conversion successful if (result.lVal) // return if non-zero return; } } // not Lua } // end of script callback wanted // tell each plugin about the error tag if (m_bPluginProcessesError) SendToAllPluginCallbacks (ON_PLUGIN_MXP_ERROR, CFormat ("%s,%ld,%ld,%s", (LPCTSTR) p, iMessageNumber, (long) m_LineList.GetCount (), (LPCTSTR) strMessage)); CString strTitle = MXP_ERROR_WINDOW; strTitle += " - "; strTitle += m_mush_name; if (iLevel > m_iMXPdebugLevel) // only show required level return; CString str = CFormat ("%s %5i: (%5i) %s%s", p, // error level iMessageNumber, // actual error number m_LineList.GetCount (), // which line (LPCTSTR) strMessage, // what message ENDLINE); AppendToTheNotepad (strTitle, str, // start new line false, // append eNotepadMXPdebug); }
long CMUSHclientDoc::SetAlphaOptionItem (const int iItem, LPCTSTR sValue, const bool bDoSpecial, const bool bInclude) { CString strValue = sValue; if (AlphaOptionsTable [iItem].iFlags & OPT_COMMAND_STACK) { if (strValue.GetLength () > 1) return eOptionOutOfRange; if (strValue.IsEmpty ()) { m_enable_command_stack = false; return eOptionOutOfRange; } if (!isprint (strValue [0]) || isspace (strValue [0])) { m_enable_command_stack = false; return eOptionOutOfRange; } } // end of command stack character if (AlphaOptionsTable [iItem].iFlags & OPT_WORLD_ID) { if (!strValue.IsEmpty ()) if (strValue.GetLength () != PLUGIN_UNIQUE_ID_LENGTH) return eOptionOutOfRange; // make sure hex characters const char * p = strValue; for ( ; *p ; p++) if (!isxdigit (*p)) return eOptionOutOfRange; strValue.MakeLower (); } // end of world id bool bChanged; long iResult = SetBaseAlphaOptionItem (iItem, AlphaOptionsTable, NUMITEMS (AlphaOptionsTable), (char *) this, strValue, bChanged); if (iResult != eOK) return iResult; if (bChanged) SetModifiedFlag (); if (bInclude) { m_AlphaConfiguration [iItem]->bInclude = true; m_AlphaConfiguration [iItem]->sValue = strValue; } // specials wanted? if (!bDoSpecial) return eOK; // any special tests here ... if (AlphaOptionsTable [iItem].iFlags & OPT_UPDATE_INPUT_FONT) ChangeInputFont (m_input_font_height, m_input_font_name, m_input_font_weight, m_input_font_charset, m_input_font_italic); if (AlphaOptionsTable [iItem].iFlags & OPT_UPDATE_OUTPUT_FONT) ChangeFont (m_font_height, m_font_name, m_font_weight, m_font_charset, m_bShowBold, m_bShowItalic, m_bShowUnderline, m_iLineSpacing); if (AlphaOptionsTable [iItem].iFlags & OPT_UPDATE_VIEWS) UpdateAllViews (NULL); return eOK; } // end of CMUSHclientDoc:SetAlphaOptionItem
long CMUSHclientDoc::SetOptionItem (const int iItem, long Value, const bool bDoSpecial, const bool bInclude) { bool bChanged; long iResult = SetBaseOptionItem (iItem, OptionsTable, NUMITEMS (OptionsTable), (char *) this, Value, bChanged); if (iResult != eOK) return iResult; if (bChanged) SetModifiedFlag (); if (bInclude) { m_NumericConfiguration [iItem]->bInclude = true; m_NumericConfiguration [iItem]->iValue = Value; } // specials wanted? if (!bDoSpecial) return eOK; // some special handling if (OptionsTable [iItem].iFlags & OPT_FIX_OUTPUT_BUFFER) if (m_pCurrentLine) // a new world might not have a line yet FixUpOutputBuffer (Value); if (OptionsTable [iItem].iFlags & OPT_FIX_INPUT_WRAP) FixInputWrap(); if (OptionsTable [iItem].iFlags & OPT_FIX_WRAP_COLUMN) { if (m_pCurrentLine) // a new world might not have a line yet { // save current line text CString strLine = CString (m_pCurrentLine->text, m_pCurrentLine->len); #ifdef USE_REALLOC m_pCurrentLine->text = (char *) realloc (m_pCurrentLine->text, MAX (m_pCurrentLine->len, Value) * sizeof (char)); #else delete [] m_pCurrentLine->text; m_pCurrentLine->text = new char [MAX (m_pCurrentLine->len, Value)]; #endif // put text back memcpy (m_pCurrentLine->text, (LPCTSTR) strLine, m_pCurrentLine->len); ASSERT (m_pCurrentLine->text); } // end of having a current line SendWindowSizes (Value); } if (OptionsTable [iItem].iFlags & OPT_FIX_SPEEDWALK_DELAY) SetSpeedWalkDelay ((short) Value); POSITION pos; if (OptionsTable [iItem].iFlags & OPT_FIX_TOOLTIP_VISIBLE) { for(pos = GetFirstViewPosition(); pos != NULL;) { CView* pView = GetNextView(pos); if (pView->IsKindOf(RUNTIME_CLASS(CMUSHView))) { CMUSHView* pmyView = (CMUSHView*)pView; if (pmyView->m_ToolTip.m_hWnd) pmyView->m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_AUTOPOP, Value - 1); // zero will be default (-1) } // end if } // end for } // end of OPT_FIX_TOOLTIP_VISIBLE if (OptionsTable [iItem].iFlags & OPT_FIX_TOOLTIP_START) { for(pos = GetFirstViewPosition (); pos != NULL;) { CView* pView = GetNextView(pos); if (pView->IsKindOf(RUNTIME_CLASS(CMUSHView))) { CMUSHView* pmyView = (CMUSHView*)pView; if (pmyView->m_ToolTip.m_hWnd) pmyView->m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_INITIAL, Value - 1); // zero will be default (-1) } // end if } // end for } // end of OPT_FIX_TOOLTIP_START if (OptionsTable [iItem].iFlags & OPT_USE_MXP) { if (m_iUseMXP == eNoMXP && m_bMXP) MXP_Off (true); else if (m_iUseMXP == eUseMXP && !m_bMXP) MXP_On (false, true); // not pueblo, manually on } if (OptionsTable [iItem].iFlags & OPT_UPDATE_INPUT_FONT) ChangeInputFont (m_input_font_height, m_input_font_name, m_input_font_weight, m_input_font_charset, m_input_font_italic); if (OptionsTable [iItem].iFlags & OPT_UPDATE_OUTPUT_FONT) ChangeFont (m_font_height, m_font_name, m_font_weight, m_font_charset, m_bShowBold, m_bShowItalic, m_bShowUnderline, m_iLineSpacing); if (OptionsTable [iItem].iFlags & OPT_UPDATE_VIEWS) UpdateAllViews (NULL); return eOK; } // end of CMUSHclientDoc::SetOptionItem
long CMUSHclientDoc::SetTriggerOption(LPCTSTR TriggerName, LPCTSTR OptionName, LPCTSTR Value) { CString strTriggerName = TriggerName; CString strValue = Value; CTrigger * trigger_item; // trim spaces from name, make lower-case CheckObjectName (strTriggerName, false); if (!GetTriggerMap ().Lookup (strTriggerName, trigger_item)) return eTriggerNotFound; CString strOptionName = OptionName; strOptionName.MakeLower(); strOptionName.TrimLeft (); strOptionName.TrimRight (); int iItem; int iResult = FindBaseOption (strOptionName, TriggerOptionsTable, iItem); bool bChanged; if (iResult == eOK) { // this is a numeric option // for boolean options, accept "y" or "n" if (TriggerOptionsTable [iItem].iMinimum == 0 && TriggerOptionsTable [iItem].iMaximum == 0) { if (strValue == "Y" || strValue == "y") Value = "1"; else if (strValue == "N" || strValue == "n") Value = "0"; } if (!IsNumber (Value, true)) return eOptionOutOfRange; long iValue = atol (Value); if (m_CurrentPlugin && (TriggerOptionsTable [iItem].iFlags & OPT_PLUGIN_CANNOT_WRITE)) return ePluginCannotSetOption; // not available to plugin if (TriggerOptionsTable [iItem].iFlags & OPT_CANNOT_WRITE) return ePluginCannotSetOption; // not available for writing at all iResult = SetBaseOptionItem (iItem, TriggerOptionsTable, NUMITEMS (TriggerOptionsTable), (char *) trigger_item, iValue, bChanged); if (bChanged) { if (!m_CurrentPlugin) // plugin mods don't really count SetModifiedFlag (TRUE); // document has changed trigger_item->nUpdateNumber = App.GetUniqueNumber (); // for concurrency checks } if (strOptionName == "sequence") SortTriggers (); return iResult; } // end of found else { // not numeric option, try alpha int iResult = FindBaseAlphaOption (strOptionName, TriggerAlphaOptionsTable, iItem); if (iResult == eOK) { // alpha option if (m_CurrentPlugin && (TriggerAlphaOptionsTable [iItem].iFlags & OPT_PLUGIN_CANNOT_WRITE)) return ePluginCannotSetOption; // not available to plugin if (TriggerAlphaOptionsTable [iItem].iFlags & OPT_CANNOT_WRITE) return ePluginCannotSetOption; // not available for writing at all // ------ preliminary validation before setting the option // cannot have null match text if (strOptionName == "match" || strOptionName == "ignore_case" || strOptionName == "multi_line") { if (strValue.IsEmpty ()) return eTriggerCannotBeEmpty; t_regexp * regexp = NULL; CString strRegexp; if (trigger_item->bRegexp) strRegexp = strValue; else strRegexp = ConvertToRegularExpression (strValue); // compile regular expression try { regexp = regcomp (strRegexp, (trigger_item->ignore_case ? PCRE_CASELESS : 0) | (trigger_item->bMultiLine ? PCRE_MULTILINE : 0) | (m_bUTF_8 ? PCRE_UTF8 : 0) ); } // end of try catch(CException* e) { e->Delete (); return eBadRegularExpression; } // end of catch delete trigger_item->regexp; // get rid of old one trigger_item->regexp = regexp; } // end of option "match" else if (strOptionName == "script") { // get trigger dispatch ID if (GetScriptEngine () && !strValue.IsEmpty ()) { DISPID dispid = DISPID_UNKNOWN; CString strMessage; dispid = GetProcedureDispid (strValue, "trigger", TriggerName, strMessage); if (dispid == DISPID_UNKNOWN) return eScriptNameNotLocated; trigger_item->dispid = dispid; // update dispatch ID } } // end of option "script" // set the option now iResult = SetBaseAlphaOptionItem (iItem, TriggerAlphaOptionsTable, NUMITEMS (TriggerAlphaOptionsTable), (char *) trigger_item, strValue, bChanged); if (bChanged) { if (!m_CurrentPlugin) // plugin mods don't really count SetModifiedFlag (TRUE); // document has changed trigger_item->nUpdateNumber = App.GetUniqueNumber (); // for concurrency checks } return iResult; } // end of found alpha option } // end of not numeric option return eUnknownOption; } // end of SetTriggerOption
VARIANT CMUSHclientDoc::GetTriggerOption(LPCTSTR TriggerName, LPCTSTR OptionName) { CString strTriggerName = TriggerName; CTrigger * trigger_item; VARIANT vaResult; VariantInit(&vaResult); vaResult.vt = VT_NULL; // trim spaces from name, make lower-case CheckObjectName (strTriggerName, false); vaResult.vt = VT_EMPTY; // see if trigger exists, if not return EMPTY if (!GetTriggerMap ().Lookup (strTriggerName, trigger_item)) return vaResult; int iItem; int iResult = FindBaseOption (OptionName, TriggerOptionsTable, iItem); if (iResult == eOK) { // numeric option if (m_CurrentPlugin && (TriggerOptionsTable [iItem].iFlags & OPT_PLUGIN_CANNOT_READ)) return vaResult; // not available to plugin long Value = GetBaseOptionItem (iItem, TriggerOptionsTable, NUMITEMS (TriggerOptionsTable), (char *) trigger_item); SetUpVariantLong (vaResult, Value); } // end of found numeric option else { // not numeric option, try alpha int iResult = FindBaseAlphaOption (OptionName, TriggerAlphaOptionsTable, iItem); if (iResult == eOK) { // alpha option if (m_CurrentPlugin && (TriggerAlphaOptionsTable [iItem].iFlags & OPT_PLUGIN_CANNOT_READ)) return vaResult; // not available to plugin CString strValue = GetBaseAlphaOptionItem (iItem, TriggerAlphaOptionsTable, NUMITEMS (TriggerAlphaOptionsTable), (char *) trigger_item); SetUpVariantString (vaResult, strValue); } // end of found } return vaResult; } // end of GetTriggerOption
CMUSHclientDoc::CMUSHclientDoc() : m_eventScriptFileChanged(FALSE, TRUE) { // constructor int i; // each document will have a unique number m_iUniqueDocumentNumber = App.GetUniqueNumber (); m_whenWorldStarted = CTime::GetCurrentTime(); QueryPerformanceCounter (&m_whenWorldStartedHighPrecision); AllocateConfigurationArrays (); m_bTrace = false; // not tracing yet // note - these initialisations merely make the hash lookup more efficient. // until v 3.21 they were the default of 20, so this should help somewhat // The number should be a prime number, hence the strange figures. m_VariableMap.InitHashTable (997); // allow for 1000 variables (at least) m_AliasMap.InitHashTable (293); // probably won't have many more than 300 aliases m_TriggerMap.InitHashTable (293); // probably won't have many more than 300 triggers m_TimerMap.InitHashTable (293); // probably won't have many more than 300 timers SetDefaults (false); // set up numeric/boolean defaults SetAlphaDefaults (false); // set up alpha defaults m_strWorldID = GetUniqueID (); // default world ID m_CurrentPlugin = NULL; // no plugin active right now m_iBackgroundMode = 0; m_iForegroundMode = 0; m_iBackgroundColour = NO_COLOUR; m_TextRectangle = CRect (0, 0, 0, 0); m_TextRectangleBorderOffset = 0; m_TextRectangleBorderColour = 0; m_TextRectangleBorderWidth = 0; m_TextRectangleOutsideFillColour = 0; m_TextRectangleOutsideFillStyle = 0; m_iCurrentActionSource = eUnknownActionSource; m_nBytesIn = 0; m_nBytesOut = 0; m_bTabCompleteFunctions = true; m_iTriggersEvaluatedCount = 0; m_iTriggersMatchedCount = 0; m_iAliasesEvaluatedCount = 0; m_iAliasesMatchedCount = 0; m_iTimersFiredCount = 0; m_iTriggersMatchedThisSessionCount = 0; m_iAliasesMatchedThisSessionCount = 0; m_iTimersFiredThisSessionCount = 0; m_bLoaded = false; m_bMapping = false; m_bRemoveMapReverses = true; m_MapFailureRegexp = NULL; m_bPluginProcessingCommand = false; m_bPluginProcessingSend = false; m_bPluginProcessingSent = false; m_iLastCommandCount = 0; m_iExecutionDepth = 0; m_iNextChatID = 0; m_tLastMessageTime = 0; m_tLastGroupMessageTime = 0; m_bOmitFromCommandHistory = false; m_bUTF_8 = false; m_bWorldClosing = false; m_bInSendToScript = true; m_bInPlaySoundFilePlugin = false; m_bInCancelSoundFilePlugin = false; m_strStatusMessage = Translate ("Ready"); m_bShowingMapperStatus = false; m_iMCCP_type = 0; m_bSupports_MCCP_2 = false; m_bNoEcho = false; m_bDebugIncomingPackets = false; m_iInputPacketCount = 0; m_iOutputPacketCount = 0; m_iUTF8ErrorCount = 0; m_lastGoTo = 1; m_bNAWS_wanted = false; m_bCHARSET_wanted = false; m_bSuppressNewline = false; m_echo_colour = SAMECOLOUR; m_bAlwaysRecordCommandHistory = false; m_bDoNotShowOutstandingLines = false; m_bDoNotTranslateIACtoIACIAC = false; m_bAutoResizeCommandWindow = false; m_bLogScriptErrors = false; m_bOmitSavedDateFromSaveFiles = false; m_iAutoResizeMinimumLines = 1; m_iAutoResizeMaximumLines = 20; m_bDoNotAddMacrosToCommandHistory = false; m_bCopySelectionToClipboard = false; m_bCarriageReturnClearsLine = false; m_bConvertGAtoNewline = false; m_bSendMXP_AFK_Response = true; m_bMudCanChangeOptions = true; // m_bShowGridLinesInListViews = true; // NB - app-wide :P m_bEnableSpamPrevention = false; m_strSpamMessage = "look"; m_iSpamLineCount = 20; m_iLastOutgoingChatPort = DEFAULT_CHAT_PORT; m_bScrollBarWanted = TRUE; m_iSocksProcessing = 0; // no socks processing wanted m_iProxyServerPort = 1080; // default socks port // deprecated options - set to zero for saving comparison (for XML testing) m_page_colour = 0; m_whisper_colour= 0; m_mail_colour = 0; m_game_colour = 0; m_chat_colour = 0; m_remove_channels1 = 0; m_remove_channels2 = 0; m_remove_pages= 0; m_remove_whispers = 0; m_remove_set= 0; m_remove_mail = 0; m_remove_game = 0; // things I found to be not initialised in version 3.43 m_timestamps = 0; m_iFlags1 = 0; m_iFlags2 = 0; m_iListMode = 0; m_iListCount = 0; m_iMXP_previousMode = eMXP_open; m_code = 0; // sound buffers for (i = 0; i < MAX_SOUND_BUFFERS; i++) m_pDirectSoundSecondaryBuffer [i] = NULL; /*--------------------------------------------------------- I want to be able to time speed walking delays (for pulling things out of the list, so I need a window that can take timer events, however a CDocument isn't a window. Thus, I'll make a hidden window for this specific purpose. I previously had speed walking tied to the CSendView window but this was pretty crappy, because you could have multiple send views, thus the timers would be all over the shop, and it was very fiddly when firing a "send" from a trigger, because a trigger is not related to a particular send view. --------------------------------------------------------- */ // create window that we can use for firing timers m_pTimerWnd = new CTimerWnd (this); m_pTimerWnd->m_hWnd = NULL; if (!m_pTimerWnd->CreateEx(0, AfxRegisterWndClass(0), _T("Document timer window"), WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL)) { TRACE0("Warning: unable to create document timer window!\n"); AfxThrowResourceException(); } ASSERT(m_pTimerWnd->m_hWnd != NULL); ASSERT(CWnd::FromHandlePermanent(m_pTimerWnd->m_hWnd) == m_pTimerWnd); for (i = 0; i < 8; i++) m_font [i] = NULL; m_input_font = NULL; m_FontHeight = 0; m_FontWidth = 0; m_InputFontHeight = 0; m_InputFontWidth = 0; m_total_lines = 0; m_newlines_received = 0; m_last_line_with_IAC_GA = 0; m_nTotalLinesSent = 0; m_nTotalLinesReceived = 0; m_phase = NONE; m_ttype_sequence = 0; m_bVariablesChanged = false; m_view_number = 0; m_LastFlushTime = CTime::GetCurrentTime(); m_bCompress = false; // no compression yet m_bCompressInitOK = false; m_CompressInput = NULL; m_CompressOutput = NULL; // initialise zlib decompression m_zCompress.next_in = Z_NULL; m_zCompress.avail_in = 0; m_zCompress.zalloc = Z_NULL; m_zCompress.zfree = Z_NULL; m_zCompress.opaque = Z_NULL; m_nTotalUncompressed = 0; m_nTotalCompressed = 0; m_iCompressionTimeTaken = 0; m_nCompressionOutputBufferSize = COMPRESS_BUFFER_LENGTH; // initial value // we will defer initialising zlib until we really have to m_pSocket = NULL; m_pChatListenSocket = NULL; // no listening socket m_logfile = NULL; m_match_width = 30; m_bSelected = true; m_bNotesInRGB = false; // notes are in palette colour right now m_iNoteStyle = NORMAL; // notes are not bold right now // MXP m_bMXP = false; // no MXP yet m_bPuebloActive = false; // no Pueblo yet either <evil grin> m_bInParagraph = false; m_bMXP_script = false; m_bPreMode = false; m_iMXP_defaultMode = eMXP_open; m_iMXP_mode = m_iMXP_defaultMode; m_cLastChar = 0; // initial styles m_iFlags = 0; m_iForeColour = WHITE; m_iBackColour = BLACK; if (m_bCustom16isDefaultColour) { m_iForeColour = 15; // use custom colour 16 m_iBackColour = 15; m_iFlags |= COLOUR_CUSTOM; } // m_normalcolour [BLACK] = RGB (192, 192, 192) | PALETTE; // black // m_normalcolour [RED] = RGB (128, 0, 64) | PALETTE; // red // m_normalcolour [GREEN] = RGB (128, 255, 128) | PALETTE; // green // m_normalcolour [YELLOW] = RGB (255, 255, 128) | PALETTE; // yellow // m_normalcolour [BLUE] = RGB ( 0, 255, 255) | PALETTE; // blue // m_normalcolour [MAGENTA] = RGB (255, 0, 128) | PALETTE; // magenta // m_normalcolour [CYAN] = RGB (128, 255, 255) | PALETTE; // cyan // m_normalcolour [WHITE] = RGB ( 0, 128, 0) | PALETTE; // white // m_boldcolour [BLACK] = RGB ( 0, 0, 0) | PALETTE; // black // m_boldcolour [RED] = RGB (255, 0, 0) | PALETTE; // red // m_boldcolour [GREEN] = RGB ( 0, 255, 0) | PALETTE; // green // m_boldcolour [YELLOW] = RGB (255, 255, 0) | PALETTE; // yellow // m_boldcolour [BLUE] = RGB ( 0, 64, 128) | PALETTE; // blue // m_boldcolour [MAGENTA] = RGB (255, 0, 255) | PALETTE; // magenta // m_boldcolour [CYAN] = RGB ( 0, 255, 255) | PALETTE; // cyan // m_boldcolour [WHITE] = RGB (255, 255, 255) | PALETTE; // white // better use ANSI colours as the default SetDefaultAnsiColours (m_normalcolour, m_boldcolour); // and some nice custom colours SetDefaultCustomColours (m_customtext, m_customback); // default custom colour names for (i = 0; i < NUMITEMS (m_strCustomColourName); i++) m_strCustomColourName [i].Format ("Custom%i", i + 1); for (i = 0; i < NUMITEMS (m_macro_type); i++) m_macro_type [i] = SEND_NOW; // printer styles for printing from the screen for (i = 0; i < 8; i++) { m_nNormalPrintStyle [i] = 0; m_nBoldPrintStyle [i] = FONT_BOLD; } m_bUseDefaultOutputFont = !App.m_strDefaultOutputFont.IsEmpty (); m_bUseDefaultColours = !App.m_strDefaultColoursFile.IsEmpty (); m_bUseDefaultTriggers = !App.m_strDefaultTriggersFile.IsEmpty (); m_bUseDefaultAliases = !App.m_strDefaultAliasesFile.IsEmpty (); m_bUseDefaultMacros = !App.m_strDefaultMacrosFile.IsEmpty (); m_bUseDefaultTimers = !App.m_strDefaultTimersFile.IsEmpty (); m_bUseDefaultInputFont = !App.m_strDefaultInputFont.IsEmpty (); setupstrings (); m_tStatusTime = CTime::GetCurrentTime(); m_tConnectTime = CTime::GetCurrentTime(); m_tLastPlayerInput = CTime::GetCurrentTime(); m_timeScriptFileMod = 0; m_tsConnectDuration = CTimeSpan (0, 0, 0, 0); m_iConnectPhase = eConnectNotConnected; gdoccount++; m_pActiveCommandView = NULL; m_pActiveOutputView = NULL; m_new_lines = 0; m_last_prefs_page = 1; App.m_bUpdateActivity = TRUE; // for looking up host names ZeroMemory (&m_sockAddr, sizeof m_sockAddr); ZeroMemory (&m_ProxyAddr, sizeof m_ProxyAddr); m_hNameLookup = NULL; m_pGetHostStruct = NULL; m_pLinePositions = NULL; m_pCurrentLine = NULL; m_total_lines = 0; // set up the dialog box headings for the finding dialogs m_DisplayFindInfo.m_strTitle = "Find in output buffer..."; m_MacrosFindInfo.m_strTitle = "Find macro..."; m_AliasesFindInfo.m_strTitle = "Find alias..."; m_TriggersFindInfo.m_strTitle = "Find trigger..."; m_TimersFindInfo.m_strTitle = "Find timer..."; m_VariablesFindInfo.m_strTitle = "Find variable..."; m_NotesFindInfo.m_strTitle = "Find in notes..."; m_RecallFindInfo.m_strTitle = "Recall..."; m_bRecallCommands = true; m_bRecallOutput = true; m_bRecallNotes = true; // set up column counts for use in the loading and saving of the column orders etc. m_MacrosFindInfo.m_iControlColumns = CPrefsP6::eColumnCount; m_AliasesFindInfo.m_iControlColumns = CPrefsP7::eColumnCount; m_TriggersFindInfo.m_iControlColumns = CPrefsP8::eColumnCount; m_TimersFindInfo.m_iControlColumns = CPrefsP16::eColumnCount; m_VariablesFindInfo.m_iControlColumns = CPrefsP18::eColumnCount; m_bDisconnectOK = true; // so we don't try to reconnect to prematurely m_iMXPerrors = 0; m_iMXPtags = 0; m_iMXPentities = 0; // scripting support EnableAutomation(); // not needed? if (!bWine) AfxOleLockApp(); // not needed? m_ScriptEngine = NULL; m_bInScriptFileChanged = false; m_pThread = NULL; m_bSyntaxErrorOnly = false; m_dispidWorldOpen = DISPID_UNKNOWN; m_dispidWorldClose = DISPID_UNKNOWN; m_dispidWorldSave = DISPID_UNKNOWN; m_dispidWorldConnect = DISPID_UNKNOWN; m_dispidWorldDisconnect = DISPID_UNKNOWN; m_dispidWorldGetFocus = DISPID_UNKNOWN; m_dispidWorldLoseFocus = DISPID_UNKNOWN; m_dispidOnMXP_Start = DISPID_UNKNOWN; m_dispidOnMXP_Stop = DISPID_UNKNOWN; m_dispidOnMXP_OpenTag = DISPID_UNKNOWN; m_dispidOnMXP_CloseTag = DISPID_UNKNOWN; m_dispidOnMXP_SetVariable = DISPID_UNKNOWN; m_dispidOnMXP_Error = DISPID_UNKNOWN; m_iScriptTimeTaken = 0; // time taken on scripts m_bPluginProcessesOpenTag = false; m_bPluginProcessesCloseTag = false; m_bPluginProcessesSetVariable = false; m_bPluginProcessesSetEntity = false; m_bPluginProcessesError = false; ZeroMemory (&m_bClient_sent_IAC_DO, sizeof m_bClient_sent_IAC_DO); ZeroMemory (&m_bClient_sent_IAC_DONT, sizeof m_bClient_sent_IAC_DONT); ZeroMemory (&m_bClient_sent_IAC_WILL, sizeof m_bClient_sent_IAC_WILL); ZeroMemory (&m_bClient_sent_IAC_WONT, sizeof m_bClient_sent_IAC_WONT); ZeroMemory (&m_bClient_got_IAC_DO, sizeof m_bClient_got_IAC_DO); ZeroMemory (&m_bClient_got_IAC_DONT, sizeof m_bClient_got_IAC_DONT); ZeroMemory (&m_bClient_got_IAC_WILL, sizeof m_bClient_got_IAC_WILL); ZeroMemory (&m_bClient_got_IAC_WONT, sizeof m_bClient_got_IAC_WONT); m_nCount_IAC_DO = 0; m_nCount_IAC_DONT = 0; m_nCount_IAC_WILL = 0; m_nCount_IAC_WONT = 0; m_nCount_IAC_SB = 0; m_iOutputWindowRedrawCount = 0; m_bTreeviewTriggers = true; m_bTreeviewAliases = true; m_bTreeviewTimers = true; // set up some default triggers for MUSHes /* The parameter are: Trigger Name Match Text Response Text Flags Colour Wildcard to copy to clipboard Sound File Name Script Name */ /* No, don't. It just confuses Diku MUD people AddTrigger ("Game_messages", "GAME:*", "", eEnabled, 0, 0, "", ""); AddTrigger ("Page_poses", "From afar,*", "", eEnabled, 1, 0, "", ""); AddTrigger ("Pages", "^\\w+ pages.*$", "", eEnabled | eTriggerRegularExpression, 1, 0, "", ""); AddTrigger ("Whisper_poses", "You sense:*", "", eEnabled, 2, 0, "", ""); AddTrigger ("Whispers", "^\\w+ whispers.*$", "", eEnabled | eTriggerRegularExpression, 2, 0, "", ""); AddTrigger ("Mail_messages", "MAIL:*", "", eEnabled, 3, 0, "", ""); AddTrigger ("Chat_channel_1", "^\\<.+?\\>.*$", "", eEnabled | eTriggerRegularExpression, 4, 0, "", ""); AddTrigger ("Chat_channel_2", "^\\[.+?\\].*$", "", eEnabled | eTriggerRegularExpression, 4, 0, "", ""); */ m_nextAcceleratorCommand = ACCELERATOR_FIRST_COMMAND; m_accelerator = NULL; } // end of CMUSHclientDoc::CMUSHclientDoc()
BSTR CMUSHclientDoc::ExportXML(short Type, LPCTSTR Name) { CString strResult; CString strName = Name; // trim spaces, force name to lower-case CheckObjectName (strName, false); char * p = NULL; try { CMemFile f; // open memory file for writing CArchive ar(&f, CArchive::store); // see if trigger exists, if not return EMPTY switch (Type) { case 0: // trigger { CTrigger * t; if (GetTriggerMap ().Lookup (strName, t)) { Save_Header_XML (ar, "triggers", false); Save_One_Trigger_XML (ar, t); Save_Footer_XML (ar, "triggers"); } // end of item existing } break; case 1: // alias { CAlias * t; if (GetAliasMap ().Lookup (strName, t)) { Save_Header_XML (ar, "aliases", false); Save_One_Alias_XML (ar, t); Save_Footer_XML (ar, "aliases"); } // end of item existing } break; case 2: // timer { CTimer * t; if (GetTimerMap ().Lookup (strName, t)) { Save_Header_XML (ar, "timers", false); Save_One_Timer_XML (ar, t); Save_Footer_XML (ar, "timers"); } // end of item existing } break; case 3: // macro { for (int i = 0; i < NUMITEMS (strMacroDescriptions); i++) { if (strMacroDescriptions [i].CompareNoCase (strName) == 0) { Save_Header_XML (ar, "macros", false); Save_One_Macro_XML (ar, i); Save_Footer_XML (ar, "macros"); } // end of item existing } // end of finding which one } break; case 4: // variable { CVariable * t; if (GetVariableMap ().Lookup (strName, t)) { Save_Header_XML (ar, "variables", false); Save_One_Variable_XML (ar, t); Save_Footer_XML (ar, "variables"); } // end of item existing } break; case 5: // keypad { for (int i = 0; i < NUMITEMS (strKeypadNames); i++) { if (strKeypadNames [i].CompareNoCase (strName) == 0) { Save_Header_XML (ar, "keypad", false); Save_One_Keypad_XML (ar, i); Save_Footer_XML (ar, "keypad"); } // end of item existing } // end of finding which one } break; } // end of switch ar.Close(); int nLength = f.GetLength (); p = (char *) f.Detach (); strResult = CString (p, nLength); free (p); // remove memory allocated in CMemFile p = NULL; } // end of try block catch (CException* e) { if (p) free (p); // remove memory allocated in CMemFile e->Delete(); strResult.Empty (); } // end of catch return strResult.AllocSysString(); } // end of CMUSHclientDoc::ExportXML
long CMUSHclientDoc::SetTimerOption(LPCTSTR TimerName, LPCTSTR OptionName, LPCTSTR Value) { CString strTimerName = TimerName; CString strValue = Value; CTimer * Timer_item; // trim spaces from name, make lower-case CheckObjectName (strTimerName, false); if (!GetTimerMap ().Lookup (strTimerName, Timer_item)) return eTimerNotFound; CString strOptionName = OptionName; strOptionName.MakeLower(); strOptionName.TrimLeft (); strOptionName.TrimRight (); int iItem; int iResult = FindBaseOption (strOptionName, TimerOptionsTable, iItem); bool bChanged; if (iResult == eOK) { // this is a numeric option // for boolean options, accept "y" or "n" if (TimerOptionsTable [iItem].iMinimum == 0 && TimerOptionsTable [iItem].iMaximum == 0) { if (strValue == "Y" || strValue == "y") Value = "1"; else if (strValue == "N" || strValue == "n") Value = "0"; } long iValue = 0; double fValue = 0; if (strOptionName == "second") fValue = atof (Value); else { if (!IsNumber (Value, true)) return eOptionOutOfRange; iValue = atol (Value); } if (m_CurrentPlugin && (TimerOptionsTable [iItem].iFlags & OPT_PLUGIN_CANNOT_WRITE)) return ePluginCannotSetOption; // not available to plugin if (TimerOptionsTable [iItem].iFlags & OPT_CANNOT_WRITE) return ePluginCannotSetOption; // not available for writing at all iResult = SetBaseOptionItem (iItem, TimerOptionsTable, NUMITEMS (TimerOptionsTable), (char *) Timer_item, iValue, bChanged); if (bChanged) { if (!m_CurrentPlugin) // plugin mods don't really count SetModifiedFlag (TRUE); // document has changed Timer_item->nUpdateNumber = App.GetUniqueNumber (); // for concurrency checks } if (iResult == eOK && Timer_item->iType == CTimer::eInterval) { // need to set "every" time, not "at" time if (strOptionName == "hour") { Timer_item->iEveryHour = iValue; ResetOneTimer (Timer_item); } // end of option "hour" else if (strOptionName == "minute") { Timer_item->iEveryMinute = iValue; ResetOneTimer (Timer_item); } // end of option "minute" else if (strOptionName == "second") { Timer_item->fEverySecond = fValue; ResetOneTimer (Timer_item); } // end of option "second" } // end of need to fiddle with hour/minute/second // need to reset if we are changing this if (strOptionName == "at_time" && bChanged) { // copy from at to every or vice-versa if (Timer_item->iType == CTimer::eInterval) { Timer_item->iEveryHour = Timer_item->iAtHour; Timer_item->iEveryMinute = Timer_item->iAtHour; Timer_item->fEverySecond = Timer_item->fAtSecond; } else { Timer_item->iAtHour = Timer_item->iEveryHour; Timer_item->iAtMinute = Timer_item->iEveryHour; Timer_item->fAtSecond = Timer_item->fEverySecond; } ResetOneTimer (Timer_item); } return iResult; } // end of found else { // not numeric option, try alpha int iResult = FindBaseAlphaOption (strOptionName, TimerAlphaOptionsTable, iItem); if (iResult == eOK) { // alpha option if (m_CurrentPlugin && (TimerAlphaOptionsTable [iItem].iFlags & OPT_PLUGIN_CANNOT_WRITE)) return ePluginCannotSetOption; // not available to plugin if (TimerAlphaOptionsTable [iItem].iFlags & OPT_CANNOT_WRITE) return ePluginCannotSetOption; // not available for writing at all // ------ preliminary validation before setting the option if (strOptionName == "script") { // get Timer dispatch ID if (GetScriptEngine () && !strValue.IsEmpty ()) { DISPID dispid = DISPID_UNKNOWN; CString strMessage; dispid = GetProcedureDispid (strValue, "Timer", TimerName, strMessage); if (dispid == DISPID_UNKNOWN) return eScriptNameNotLocated; Timer_item->dispid = dispid; // update dispatch ID } } // end of option "script" // set the option now iResult = SetBaseAlphaOptionItem (iItem, TimerAlphaOptionsTable, NUMITEMS (TimerAlphaOptionsTable), (char *) Timer_item, strValue, bChanged); if (bChanged) { if (!m_CurrentPlugin) // plugin mods don't really count SetModifiedFlag (TRUE); // document has changed Timer_item->nUpdateNumber = App.GetUniqueNumber (); // for concurrency checks } return iResult; } // end of found alpha option } // end of not numeric option return eUnknownOption; } // end of SetTimerOption
VARIANT CMUSHclientDoc::GetTimerOption(LPCTSTR TimerName, LPCTSTR OptionName) { CString strTimerName = TimerName; CTimer * Timer_item; VARIANT vaResult; VariantInit(&vaResult); vaResult.vt = VT_NULL; // trim spaces from name, make lower-case CheckObjectName (strTimerName, false); vaResult.vt = VT_EMPTY; // see if Timer exists, if not return EMPTY if (!GetTimerMap ().Lookup (strTimerName, Timer_item)) return vaResult; CString strOptionName = OptionName; strOptionName.MakeLower(); strOptionName.TrimLeft (); strOptionName.TrimRight (); int iItem; int iResult = FindBaseOption (strOptionName, TimerOptionsTable, iItem); if (iResult == eOK) { // numeric option if (m_CurrentPlugin && (TimerOptionsTable [iItem].iFlags & OPT_PLUGIN_CANNOT_READ)) return vaResult; // not available to plugin double Value; // this is a pest! if (strOptionName == "hour") { if (Timer_item->iType == CTimer::eInterval) Value = Timer_item->iEveryHour; else Value = Timer_item->iAtHour; } // end of option "hour" else if (strOptionName == "minute") { if (Timer_item->iType == CTimer::eInterval) Value = Timer_item->iEveryMinute; else Value = Timer_item->iAtMinute; } // end of option "minute" else if (strOptionName == "second") { if (Timer_item->iType == CTimer::eInterval) Value = Timer_item->fEverySecond; else Value = Timer_item->fAtSecond; } // end of option "second" else Value = GetBaseOptionItem (iItem, TimerOptionsTable, NUMITEMS (TimerOptionsTable), (char *) Timer_item); SetUpVariantDouble (vaResult, Value); } // end of found numeric option else { // not numeric option, try alpha int iResult = FindBaseAlphaOption (OptionName, TimerAlphaOptionsTable, iItem); if (iResult == eOK) { // alpha option if (m_CurrentPlugin && (TimerAlphaOptionsTable [iItem].iFlags & OPT_PLUGIN_CANNOT_READ)) return vaResult; // not available to plugin CString strValue = GetBaseAlphaOptionItem (iItem, TimerAlphaOptionsTable, NUMITEMS (TimerAlphaOptionsTable), (char *) Timer_item); SetUpVariantString (vaResult, strValue); } // end of found } return vaResult; } // end of GetTimerOption