VARIANT CMUSHclientDoc::GetTriggerWildcard(LPCTSTR TriggerName, LPCTSTR WildcardName) { 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; if (WildcardName [0] != 0 && trigger_item->regexp) { CString strResult = trigger_item->regexp->GetWildcard (WildcardName).c_str (); SetUpVariantString (vaResult, strResult); } return vaResult; } // end of CMUSHclientDoc::GetTriggerWildcard
long CMUSHclientDoc::EnableTrigger(LPCTSTR TriggerName, BOOL Enabled) { CString strTriggerName = TriggerName; CTrigger * trigger_item; // trim spaces from name, make lower-case CheckObjectName (strTriggerName, false); if (!GetTriggerMap ().Lookup (strTriggerName, trigger_item)) return eTriggerNotFound; if (trigger_item->bEnabled && Enabled) return eOK; // already enabled, document hasn't changed if (!trigger_item->bEnabled && !Enabled) return eOK; // already not enabled, document hasn't changed trigger_item->bEnabled = Enabled != 0; // set enabled flag trigger_item->nUpdateNumber = App.GetUniqueNumber (); // for concurrency checks if (!m_CurrentPlugin) // plugin mods don't really count SetModifiedFlag (TRUE); // document has changed return eOK; } // end of CMUSHclientDoc::EnableTrigger
long CMUSHclientDoc::DeleteTrigger(LPCTSTR TriggerName) { CString strTriggerName = TriggerName; CTrigger * trigger_item; // trim spaces from name, make lower-case CheckObjectName (strTriggerName, false); if (!GetTriggerMap ().Lookup (strTriggerName, trigger_item)) return eTriggerNotFound; // can't if executing a script if (trigger_item->bExecutingScript) return eItemInUse; bool bTemporary = trigger_item->bTemporary; // the trigger seems to exist - delete its pointer delete trigger_item; // now delete its entry if (!GetTriggerMap ().RemoveKey (strTriggerName)) return eTriggerNotFound; SortTriggers (); if (!m_CurrentPlugin && !bTemporary) // plugin mods don't really count SetModifiedFlag (TRUE); // document has changed return eOK; } // end of CMUSHclientDoc::DeleteTrigger
long CMUSHclientDoc::IsTrigger(LPCTSTR TriggerName) { CString strTriggerName = TriggerName; CTrigger * trigger_item; // trim spaces from name, make lower-case CheckObjectName (strTriggerName, false); if (!GetTriggerMap ().Lookup (strTriggerName, trigger_item)) return eTriggerNotFound; return eOK; } // end of CMUSHclientDoc::IsTrigger
long CMUSHclientDoc::GetTrigger(LPCTSTR TriggerName, VARIANT FAR* MatchText, VARIANT FAR* ResponseText, VARIANT FAR* Flags, VARIANT FAR* Colour, VARIANT FAR* Wildcard, VARIANT FAR* SoundFileName, VARIANT FAR* ScriptName) { CString strTriggerName = TriggerName; CTrigger * trigger_item; // trim spaces from name, make lower-case CheckObjectName (strTriggerName, false); if (!GetTriggerMap ().Lookup (strTriggerName, trigger_item)) return eTriggerNotFound; SetUpVariantString (*MatchText, trigger_item->trigger); SetUpVariantString (*ResponseText, trigger_item->contents); SetUpVariantString (*ScriptName, trigger_item->strProcedure); SetUpVariantString (*SoundFileName, trigger_item->sound_to_play); SetUpVariantShort (*Colour, trigger_item->colour); if (trigger_item->colour == SAMECOLOUR) SetUpVariantShort (*Colour, -1); short iFlags = 0; if (trigger_item->ignore_case) iFlags |= eIgnoreCase; if (trigger_item->bOmitFromOutput) iFlags |= eOmitFromOutput; if (trigger_item->bKeepEvaluating) iFlags |= eKeepEvaluating; if (trigger_item->omit_from_log) iFlags |= eOmitFromOutput; if (trigger_item->bEnabled) iFlags |= eEnabled; if (trigger_item->bRegexp) iFlags |= eTriggerRegularExpression; if (trigger_item->bLowercaseWildcard) iFlags |= eLowercaseWildcard; if (trigger_item->bOneShot) iFlags |= eTriggerOneShot; SetUpVariantShort (*Flags, iFlags); SetUpVariantShort (*Wildcard, trigger_item->iClipboardArg); return eOK; } // end of CMUSHclientDoc::GetTrigger
long CMUSHclientDoc::GetTimer(LPCTSTR TimerName, VARIANT FAR* Hour, VARIANT FAR* Minute, VARIANT FAR* Second, VARIANT FAR* ResponseText, VARIANT FAR* Flags, VARIANT FAR* ScriptName) { CString strTimerName = TimerName; CTimer * timer_item; // trim spaces from name, make lower-case CheckObjectName (strTimerName, false); if (!GetTimerMap ().Lookup (strTimerName, timer_item)) return eTimerNotFound; if (timer_item->iType == CTimer::eAtTime) { SetUpVariantShort (*Hour, timer_item->iAtHour); SetUpVariantShort (*Minute, timer_item->iAtMinute); SetUpVariantDouble (*Second, timer_item->fAtSecond); } else { SetUpVariantShort (*Hour, timer_item->iEveryHour); SetUpVariantShort (*Minute, timer_item->iEveryMinute); SetUpVariantDouble (*Second, timer_item->fEverySecond); } SetUpVariantString (*ResponseText, timer_item->strContents); SetUpVariantString (*ScriptName, timer_item->strProcedure); short iFlags = 0; if (timer_item->bEnabled) iFlags |= eEnabled; if (timer_item->bOneShot) iFlags |= eOneShot; if (timer_item->iSendTo == eSendToSpeedwalk) iFlags |= eTimerSpeedWalk; if (timer_item->iSendTo == eSendToOutput) iFlags |= eTimerNote; if (timer_item->bActiveWhenClosed) iFlags |= eActiveWhenClosed; SetUpVariantShort (*Flags, iFlags); return eOK; } // end of CMUSHclientDoc::GetTimer
long CMUSHclientDoc::ResetTimer(LPCTSTR TimerName) { CString strTimerName = TimerName; CTimer * Timer_item; // trim spaces from name, make lower-case CheckObjectName (strTimerName, false); if (!GetTimerMap ().Lookup (strTimerName, Timer_item)) return eTimerNotFound; ResetOneTimer (Timer_item); return eOK; } // end of CMUSHclientDoc::ResetTimers
long CMUSHclientDoc::AddTriggerEx(LPCTSTR TriggerName, LPCTSTR MatchText, LPCTSTR ResponseText, long Flags, short Colour, short Wildcard, LPCTSTR SoundFileName, LPCTSTR ScriptName, short SendTo, short Sequence) { CString strTriggerName = TriggerName; CTrigger * trigger_item; DISPID dispid = DISPID_UNKNOWN; long nStatus; bool bReplace = false; // allow blank names, assign one :) if (strTriggerName.IsEmpty ()) strTriggerName.Format ("*trigger%s", (LPCTSTR) App.GetUniqueString ()); else // return if bad name if (nStatus = CheckObjectName (strTriggerName)) return nStatus; // if it already exists, error if (GetTriggerMap ().Lookup (strTriggerName, trigger_item)) if (Flags & eReplace) bReplace = true; else return eTriggerAlreadyExists; // cannot have null match text if (strlen (MatchText) == 0) return eTriggerCannotBeEmpty; // check sequence if (Sequence < 0 || Sequence > 10000) return eTriggerSequenceOutOfRange; // check send to if (SendTo < 0 || SendTo >= eSendToLast) return eTriggerSendToInvalid; // must have a label for 'send to label' if (SendTo == eSendToVariable) if (CheckObjectName (strTriggerName)) return eTriggerLabelNotSpecified; // get trigger dispatch ID if (GetScriptEngine () && strlen (ScriptName) != 0) { CString strMessage; dispid = GetProcedureDispid (ScriptName, "trigger", TriggerName, strMessage); if (dispid == DISPID_UNKNOWN) return eScriptNameNotLocated; } t_regexp * regexp = NULL; CString strRegexp; if (Flags & eTriggerRegularExpression) strRegexp = MatchText; else strRegexp = ConvertToRegularExpression (MatchText); // compile regular expression try { regexp = regcomp (strRegexp, (Flags & eIgnoreCase ? PCRE_CASELESS : 0) | (m_bUTF_8 ? PCRE_UTF8 : 0)); } // end of try catch(CException* e) { e->Delete (); return eBadRegularExpression; } // end of catch // trigger replacement wanted if (bReplace) { // the trigger seems to exist - delete its pointer delete trigger_item; // now delete its entry GetTriggerMap ().RemoveKey (strTriggerName); } // create new trigger item and insert in trigger map GetTriggerMap ().SetAt (strTriggerName, trigger_item = new CTrigger); if ((Flags & eTemporary) == 0) if (!m_CurrentPlugin) // plugin mods don't really count SetModifiedFlag (TRUE); trigger_item->nUpdateNumber = App.GetUniqueNumber (); // for concurrency checks trigger_item->strInternalName = strTriggerName; // for deleting one-shot triggers trigger_item->trigger = MatchText; trigger_item->contents = ResponseText; trigger_item->colour = Colour; trigger_item->ignore_case = (Flags & eIgnoreCase) != 0; trigger_item->bOmitFromOutput = (Flags & eOmitFromOutput) != 0; trigger_item->bKeepEvaluating = (Flags & eKeepEvaluating) != 0; trigger_item->omit_from_log = (Flags & eOmitFromLog) != 0; trigger_item->bEnabled = (Flags & eEnabled) != 0; trigger_item->bRegexp = (Flags & eTriggerRegularExpression) != 0; trigger_item->bExpandVariables = (Flags & eExpandVariables) != 0; trigger_item->bTemporary = (Flags & eTemporary) != 0; trigger_item->bLowercaseWildcard = (Flags & eLowercaseWildcard) != 0; trigger_item->bOneShot = (Flags & eTriggerOneShot) != 0; trigger_item->strProcedure = ScriptName; trigger_item->strLabel = TriggerName; trigger_item->iClipboardArg = Wildcard; trigger_item->sound_to_play = SoundFileName; trigger_item->dispid = dispid; trigger_item->regexp = regexp; trigger_item->iSendTo = SendTo; trigger_item->iSequence = Sequence; trigger_item->strVariable = TriggerName; // kludge if (Colour < 0 || Colour >= MAX_CUSTOM) trigger_item->colour = SAMECOLOUR; if (Wildcard < 0 || Wildcard > 10) trigger_item->iClipboardArg = 0; SortTriggers (); return eOK; } // end of CMUSHclientDoc::AddTriggerEx
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::GetTimerInfo(LPCTSTR TimerName, short InfoType) { 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; switch (InfoType) { case 1: if (timer_item->iType == CTimer::eAtTime) SetUpVariantShort (vaResult, timer_item->iAtHour); else SetUpVariantShort (vaResult, timer_item->iEveryHour); break; case 2: if (timer_item->iType == CTimer::eAtTime) SetUpVariantShort (vaResult, timer_item->iAtMinute); else SetUpVariantShort (vaResult, timer_item->iEveryMinute); break; case 3: if (timer_item->iType == CTimer::eAtTime) SetUpVariantDouble (vaResult, timer_item->fAtSecond); else SetUpVariantDouble (vaResult, timer_item->fEverySecond); break; case 4: SetUpVariantString (vaResult, timer_item->strContents); break; case 5: SetUpVariantString (vaResult, timer_item->strProcedure); break; case 6: SetUpVariantBool (vaResult, timer_item->bEnabled); break; case 7: SetUpVariantBool (vaResult, timer_item->bOneShot); break; case 8: SetUpVariantBool (vaResult, timer_item->iType == CTimer::eAtTime); break; case 9: SetUpVariantLong (vaResult, timer_item->nInvocationCount); break; case 10: SetUpVariantLong (vaResult, timer_item->nMatched); break; case 11: if (timer_item->tWhenFired.GetTime ()) // only if non-zero, otherwise return empty SetUpVariantDate (vaResult, COleDateTime (timer_item->tWhenFired.GetTime ())); break; case 12: if (timer_item->tFireTime.GetTime ()) // only if non-zero, otherwise return empty SetUpVariantDate (vaResult, COleDateTime (timer_item->tFireTime.GetTime ())); break; case 13: { CmcDateTime tDue = CmcDateTime (timer_item->tFireTime.GetTime ()); CmcDateTime tNow = CmcDateTime::GetTimeNow (); if (tDue < tNow) SetUpVariantDouble (vaResult, 0); // due immediately else { CmcDateTimeSpan ts = tDue - tNow; SetUpVariantDouble (vaResult, ts.GetTotalSeconds ()); // how many seconds to go } } break; case 14: SetUpVariantBool (vaResult, timer_item->bTemporary); break; case 15: SetUpVariantBool (vaResult, timer_item->iSendTo == eSendToSpeedwalk); break; case 16: SetUpVariantBool (vaResult, timer_item->iSendTo == eSendToOutput); break; case 17: SetUpVariantBool (vaResult, timer_item->bActiveWhenClosed); break; case 18: SetUpVariantBool (vaResult, timer_item->bIncluded); break; case 19: SetUpVariantString (vaResult, timer_item->strGroup); break; case 20: SetUpVariantLong (vaResult, timer_item->iSendTo); break; case 21: SetUpVariantLong (vaResult, timer_item->iUserOption); break; case 22: SetUpVariantString (vaResult, timer_item->strLabel); break; case 23: SetUpVariantBool (vaResult, timer_item->bOmitFromOutput); break; case 24: SetUpVariantBool (vaResult, timer_item->bOmitFromLog); break; case 25: SetUpVariantBool (vaResult, timer_item->bExecutingScript); break; case 26: SetUpVariantBool (vaResult, timer_item->dispid != DISPID_UNKNOWN); break; default: vaResult.vt = VT_NULL; break; } // end of switch return vaResult; } // end of CMUSHclientDoc::GetTimerInfo
VARIANT CMUSHclientDoc::GetTriggerInfo(LPCTSTR TriggerName, short InfoType) { 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; switch (InfoType) { case 1: SetUpVariantString (vaResult, trigger_item->trigger); break; case 2: SetUpVariantString (vaResult, trigger_item->contents); break; case 3: SetUpVariantString (vaResult, trigger_item->sound_to_play); break; case 4: SetUpVariantString (vaResult, trigger_item->strProcedure); break; case 5: SetUpVariantBool (vaResult, trigger_item->omit_from_log); break; case 6: SetUpVariantBool (vaResult, trigger_item->bOmitFromOutput); break; case 7: SetUpVariantBool (vaResult, trigger_item->bKeepEvaluating); break; case 8: SetUpVariantBool (vaResult, trigger_item->bEnabled); break; case 9: SetUpVariantBool (vaResult, trigger_item->bRegexp); break; case 10: SetUpVariantBool (vaResult, trigger_item->ignore_case); break; case 11: SetUpVariantBool (vaResult, trigger_item->bRepeat); break; case 12: SetUpVariantBool (vaResult, trigger_item->bSoundIfInactive); break; case 13: SetUpVariantBool (vaResult, trigger_item->bExpandVariables); break; case 14: SetUpVariantShort (vaResult, trigger_item->iClipboardArg); break; case 15: SetUpVariantShort (vaResult, trigger_item->iSendTo); break; case 16: SetUpVariantShort (vaResult, trigger_item->iSequence); break; case 17: SetUpVariantShort (vaResult, trigger_item->iMatch); break; case 18: SetUpVariantShort (vaResult, trigger_item->iStyle); break; case 19: SetUpVariantShort (vaResult, trigger_item->colour); break; case 20: SetUpVariantLong (vaResult, trigger_item->nInvocationCount); break; case 21: SetUpVariantLong (vaResult, trigger_item->nMatched); break; case 22: if (trigger_item->tWhenMatched.GetTime ()) // only if non-zero, otherwise return empty SetUpVariantDate (vaResult, COleDateTime (trigger_item->tWhenMatched.GetTime ())); break; case 23: SetUpVariantBool (vaResult, trigger_item->bTemporary); break; case 24: SetUpVariantBool (vaResult, trigger_item->bIncluded); break; case 25: SetUpVariantBool (vaResult, trigger_item->bLowercaseWildcard); break; case 26: SetUpVariantString (vaResult, trigger_item->strGroup); break; case 27: SetUpVariantString (vaResult, trigger_item->strVariable); break; case 28: SetUpVariantLong (vaResult, trigger_item->iUserOption); break; case 29: SetUpVariantLong (vaResult, trigger_item->iOtherForeground); break; case 30: SetUpVariantLong (vaResult, trigger_item->iOtherBackground); break; case 31: // number of matches to regexp if (trigger_item->regexp) SetUpVariantLong (vaResult, trigger_item->regexp->m_iCount); else SetUpVariantLong (vaResult, 0); break; case 32: // last matching string if (trigger_item->regexp) SetUpVariantString (vaResult, trigger_item->regexp->m_sTarget.c_str ()); else SetUpVariantString (vaResult, ""); break; case 33: SetUpVariantBool (vaResult, trigger_item->bExecutingScript); break; case 34: SetUpVariantBool (vaResult, trigger_item->dispid != DISPID_UNKNOWN); break; case 35: if (trigger_item->regexp && trigger_item->regexp->m_program == NULL) SetUpVariantLong (vaResult, trigger_item->regexp->m_iExecutionError); else SetUpVariantLong (vaResult, 0); break; case 36: SetUpVariantBool (vaResult, trigger_item->bOneShot); break; case 37: if (trigger_item->regexp && App.m_iCounterFrequency) { double elapsed_time; elapsed_time = ((double) trigger_item->regexp->iTimeTaken) / ((double) App.m_iCounterFrequency); SetUpVariantDouble (vaResult, elapsed_time); } break; case 38: if (trigger_item->regexp) SetUpVariantLong (vaResult, trigger_item->regexp->m_iMatchAttempts); break; #ifdef PANE case 38: SetUpVariantString (vaResult, trigger_item->strPane); break; #endif // PANE case 101: SetUpVariantString (vaResult, trigger_item->wildcards [1].c_str ()); break; case 102: SetUpVariantString (vaResult, trigger_item->wildcards [2].c_str ()); break; case 103: SetUpVariantString (vaResult, trigger_item->wildcards [3].c_str ()); break; case 104: SetUpVariantString (vaResult, trigger_item->wildcards [4].c_str ()); break; case 105: SetUpVariantString (vaResult, trigger_item->wildcards [5].c_str ()); break; case 106: SetUpVariantString (vaResult, trigger_item->wildcards [6].c_str ()); break; case 107: SetUpVariantString (vaResult, trigger_item->wildcards [7].c_str ()); break; case 108: SetUpVariantString (vaResult, trigger_item->wildcards [8].c_str ()); break; case 109: SetUpVariantString (vaResult, trigger_item->wildcards [9].c_str ()); break; case 110: SetUpVariantString (vaResult, trigger_item->wildcards [0].c_str ()); break; default: vaResult.vt = VT_NULL; break; } // end of switch return vaResult; } // end of CMUSHclientDoc::GetTriggerInfo
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
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
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
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::AddTimer(LPCTSTR TimerName, short Hour, short Minute, double Second, LPCTSTR ResponseText, long Flags, LPCTSTR ScriptName) { CString strTimerName = TimerName; CTimer * timer_item; DISPID dispid = DISPID_UNKNOWN; long nStatus; bool bReplace = false; if (strTimerName.IsEmpty ()) strTimerName.Format ("*timer%s", (LPCTSTR) App.GetUniqueString ()); else // return if bad name if (nStatus = CheckObjectName (strTimerName)) return nStatus; // if it already exists, error if (GetTimerMap ().Lookup (strTimerName, timer_item)) if (Flags & eReplace) bReplace = true; else return eTimerAlreadyExists; if (Hour < 0 || Hour > 23) return eTimeInvalid; if (Minute < 0 || Minute > 59) return eTimeInvalid; if (Second < 0.0 || Second > 59.9999) return eTimeInvalid; // can't have a zero time for "every" timers if (((Hour == 0) && (Minute == 0) && (Second == 0.0)) && !(Flags & eAtTime)) return eTimeInvalid; // get timer dispatch ID if (GetScriptEngine () && strlen (ScriptName) != 0) { CString strMessage; dispid = GetProcedureDispid (ScriptName, "timer", TimerName, strMessage); if (dispid == DISPID_UNKNOWN) return eScriptNameNotLocated; } // timer replacement wanted if (bReplace) { // the timer seems to exist - delete its pointer delete timer_item; // now delete its entry GetTimerMap ().RemoveKey (strTimerName); } // create new timer item and insert in timer map GetTimerMap ().SetAt (strTimerName, timer_item = new CTimer); if ((Flags & eTemporary) == 0) if (!m_CurrentPlugin) // plugin mods don't really count SetModifiedFlag (TRUE); timer_item->nUpdateNumber = App.GetUniqueNumber (); // for concurrency checks if (Flags & eAtTime) { timer_item->iAtHour = Hour; timer_item->iAtMinute = Minute; timer_item->fAtSecond = Second; timer_item->iType = CTimer::eAtTime; } else { timer_item->iEveryHour = Hour; timer_item->iEveryMinute = Minute; timer_item->fEverySecond = Second; timer_item->iType = CTimer::eInterval; } timer_item->strContents = ResponseText; timer_item->bEnabled = (Flags & eEnabled) != 0; timer_item->bOneShot = (Flags & eOneShot) != 0; timer_item->bTemporary = (Flags & eTemporary) != 0; timer_item->bActiveWhenClosed = (Flags & eActiveWhenClosed) != 0; timer_item->strProcedure = ScriptName; timer_item->strLabel = TimerName; timer_item->dispid = dispid; if (Flags & eTimerSpeedWalk) timer_item->iSendTo = eSendToSpeedwalk; else if (Flags & eTimerNote) timer_item->iSendTo = eSendToOutput; ResetOneTimer (timer_item); SortTimers (); return eOK; } // end of CMUSHclientDoc::AddTimer
// here for <!ELEMENT blah> void CMUSHclientDoc::MXP_Element (CString strName, CString strTag) { static CArgumentList ArgumentList; // get arguments to !ELEMENT definition if (BuildArgumentList (ArgumentList, strTag)) { DELETE_LIST (ArgumentList); return; } CElement * pElement; bool bDelete = GetKeyword (ArgumentList, "delete"); strName.MakeLower (); // case-insensitive? // see if we know of this atom CAtomicElement * element_item; if (App.m_ElementMap.Lookup (strName, element_item)) { MXP_error (DBG_ERROR, errMXP_CannotRedefineElement, TFormat ("Cannot redefine built-in MXP element: <%s>" , (LPCTSTR) strName)); return; } // if element already defined, delete old one if (m_CustomElementMap.Lookup (strName, pElement)) { if (!bDelete) MXP_error (DBG_WARNING, wrnMXP_ReplacingElement, TFormat ("Replacing previously-defined MXP element: <%s>", (LPCTSTR) strName)); DELETE_LIST (pElement->ElementItemList); DELETE_LIST (pElement->AttributeList); delete pElement; } // end of existing element if (bDelete) return; // all done! // add new element to map m_CustomElementMap.SetAt (strName, pElement = new CElement); pElement->strName = strName; // get keywords first, so we won't mistake them for arguments // (eg. so OPEN doesn't become an argument) // look for keyword OPEN pElement->bOpen = GetKeyword (ArgumentList, "open"); // look for keyword EMPTY pElement->bCommand = GetKeyword (ArgumentList, "empty"); CString strArgument; // get definition ( <COLOR &col;> ) strArgument = GetArgument (ArgumentList, "", 1, false); // get definition // add atomic items here -------------------------- CString strAtom; const char * p = strArgument; const char * pStart; while (*p) { // check opening < if (*p != '<') { MXP_error (DBG_ERROR, errMXP_NoTagInDefinition, TFormat ("No opening \"<\" in MXP element definition \"%s\"", (LPCTSTR) strArgument)); return; } p++; // skip < pStart = p; // remember start of tag // skip <, look for > for (; *p && *p != '>'; p++) // look for closing tag { if (*p == '<') { MXP_error (DBG_ERROR, errMXP_UnexpectedDefinitionSymbol, TFormat ("Unexpected \"<\" in MXP element definition \"%s\"", (LPCTSTR) strArgument)); return; } if (*p == '\'' || *p == '\"') // quoted string? { char c = *p; // remember opening quote for (p++; *p && *p != c; p++) // look for closing quote ; // just keep looking if (*p != c) { MXP_error (DBG_ERROR, errMXP_NoClosingDefinitionQuote, TFormat ("No closing quote in MXP element definition \"%s\"", (LPCTSTR) strArgument)); return; } } // end of quoted string } // end of search for closing tag // check closing > if (*p != '>') { MXP_error (DBG_ERROR, errMXP_NoClosingDefinitionTag, TFormat ("No closing \">\" in MXP element definition \"%s\"", (LPCTSTR) strArgument)); return; } strAtom = CString (pStart, p - pStart); // build tag, excluding < and > CString strAtomName; if (GetWord (strAtomName, strAtom)) { MXP_error (DBG_ERROR, errMXP_NoDefinitionTag, TFormat ("No element name in MXP element definition \"<%s>\"", (LPCTSTR) CString (pStart, p - pStart))); return; } if (strAtomName == "/") { GetWord (strAtomName, strAtom); // try to get next word strAtomName.MakeLower (); // case insensitive? MXP_error (DBG_ERROR, errMXP_DefinitionCannotCloseElement, TFormat ("Element definitions cannot close other elements: </%s>" , (LPCTSTR) strAtomName)); return; } if (strAtomName == "!") { GetWord (strAtomName, strAtom); // try to get next word strAtomName.MakeLower (); // case insensitive? MXP_error (DBG_ERROR, errMXP_DefinitionCannotDefineElement, TFormat ("Element definitions cannot define other elements: <!%s>" , (LPCTSTR) strAtomName)); return; } strAtomName.MakeLower (); // case insensitive? // see if we know of this atom CAtomicElement * element_item; if (!App.m_ElementMap.Lookup (strAtomName, element_item)) { MXP_error (DBG_ERROR, errMXP_NoInbuiltDefinitionTag, TFormat ("Unknown MXP element: <%s>" , (LPCTSTR) strAtomName)); return; } // yes? add to list CElementItem * pElementItem = new CElementItem; if (BuildArgumentList (pElementItem->ArgumentList, strAtom)) // add arguments { // bad arguments DELETE_LIST (pElementItem->ArgumentList); delete pElementItem; return; } pElement->ElementItemList.AddTail (pElementItem ); pElementItem->pAtomicElement = element_item; // which atomic element p++; // skip > } // end of processing each atomic item // end of add atomic items -------------------------- // get attributes (COLOR=RED NAME=FRED) if (BuildArgumentList (pElement->AttributeList, GetArgument (ArgumentList, "att", 2, false))) { // bad arguments DELETE_LIST (pElement->AttributeList); return; } // get tag (TAG=22) strArgument = GetArgument (ArgumentList, "tag", 3, true); // get tag number if (IsNumeric (strArgument)) { int i = atoi (strArgument); if (i >= 20 && i <= 99) pElement->iTag = i; } // get tag (FLAG=roomname) strArgument = GetArgument (ArgumentList, "flag", 4, true); // get flag name if (!strArgument.IsEmpty ()) { /* // I won't check names right now ... if (strArgument == "roomname" || strArgument == "roomdesc" || strArgument == "roomexit" || strArgument == "roomnum" || strArgument == "prompt") pElement->strFlag = strArgument; else */ if (strArgument.Left (4) == "set ") pElement->strFlag = strArgument.Mid (4); // what variable to set else pElement->strFlag = strArgument; pElement->strFlag.TrimLeft (); pElement->strFlag.TrimRight (); // make things a bit easier - let spaces through but change to underscores pElement->strFlag.Replace (" ", "_"); // check variable name is OK if (CheckObjectName (pElement->strFlag) != eOK) { MXP_error (DBG_ERROR, errMXP_BadVariableName, TFormat ("Bad variable name \"%s\" - for MXP FLAG definition", (LPCTSTR) pElement->strFlag)); pElement->strFlag.Empty (); } } // end of having a flag DELETE_LIST (ArgumentList); } // end of CMUSHclientDoc::MXP_Element