Esempio n. 1
0
        /// <summary>
        /// ACT標準のスペルタイマーの設定を追加・更新する
        /// </summary>
        /// <param name="spellTimer">元になるスペルタイマー</param>
        /// <param name="useRecastTime">リキャスト時間にRecastの値を使うか。falseの場合はCompleteScheduledTimeから計算される</param>
        public void UpdateNormalSpellTimer(Models.Spell spellTimer, bool useRecastTime)
        {
            if (!Settings.Default.EnabledNotifyNormalSpellTimer)
            {
                return;
            }

            var prefix       = Settings.Default.NotifyNormalSpellTimerPrefix;
            var spellName    = prefix + "spell_" + spellTimer.SpellTitle;
            var categoryName = prefix + spellTimer.Panel.PanelName;
            var recastTime   = useRecastTime ? spellTimer.RecastTime : (spellTimer.CompleteScheduledTime - DateTime.Now).TotalSeconds;

            var timerData = new TimerData(spellName, categoryName);

            timerData.TimerValue      = (int)recastTime;
            timerData.RemoveValue     = (int)-Settings.Default.TimeOfHideSpell;
            timerData.WarningValue    = 0;
            timerData.OnlyMasterTicks = true;
            timerData.Tooltip         = spellTimer.SpellTitleReplaced;

            timerData.Panel1Display = false;
            timerData.Panel2Display = false;

            // disable warning sound
            timerData.WarningSoundData = "none";

            // initialize other parameters
            timerData.RestrictToMe       = false;
            timerData.AbsoluteTiming     = false;
            timerData.RestrictToCategory = false;

            ActGlobals.oFormSpellTimers.AddEditTimerDef(timerData);
        }
Esempio n. 2
0
        /// <summary>
        /// ACT標準のスペルタイマーに通知する
        /// </summary>
        /// <param name="spellTimer">通知先に対応するスペルタイマー</param>
        public void NotifyNormalSpellTimer(Models.Spell spellTimer)
        {
            if (!Settings.Default.EnabledNotifyNormalSpellTimer)
            {
                return;
            }

            var prefix    = Settings.Default.NotifyNormalSpellTimerPrefix;
            var spellName = prefix + "spell_" + spellTimer.SpellTitle;

            ActGlobals.oFormSpellTimers.NotifySpell("attacker", spellName, false, "victim", false);
        }
Esempio n. 3
0
        /// <summary>
        /// 1ログ1スペルに対して判定する
        /// </summary>
        /// <param name="spell">スペル</param>
        /// <param name="logLine">ログ</param>
        public void MatchCore(
            Models.Spell spell,
            string logLine)
        {
            var regex        = spell.Regex;
            var notifyNeeded = false;
            var matched      = false;

            if (!spell.IsInstance)
            {
                // マッチング計測開始
                spell.StartMatching();

                // 開始条件を確認する
                if (ConditionUtility.CheckConditionsForSpell(spell))
                {
                    // 正規表現が無効?
                    if (!spell.RegexEnabled ||
                        regex == null)
                    {
                        var keyword = spell.KeywordReplaced;
                        if (string.IsNullOrWhiteSpace(keyword))
                        {
                            return;
                        }

                        // キーワードが含まれるか?
                        if (logLine.Contains(keyword, StringComparison.OrdinalIgnoreCase))
                        {
                            matched = true;
                            var targetSpell = spell;

                            // ヒットしたログを格納する
                            targetSpell.MatchedLog = logLine;

                            // スペル名(表示テキスト)を置換する
                            var replacedTitle = ConditionUtility.GetReplacedTitle(targetSpell);

                            // PC名を置換する
                            replacedTitle = FFXIVPlugin.Instance.ReplacePartyMemberName(
                                replacedTitle,
                                Settings.Default.PCNameInitialOnDisplayStyle);

                            targetSpell.SpellTitleReplaced = replacedTitle;
                            targetSpell.UpdateDone         = false;
                            targetSpell.OverDone           = false;
                            targetSpell.BeforeDone         = false;
                            targetSpell.TimeupDone         = false;

                            var now = DateTime.Now;

                            // ホットバーからリキャスト時間の読込みを試みる
                            double d = 0d;
                            if (!this.TryGetHotbarRecast(targetSpell, out d))
                            {
                                d = targetSpell.RecastTime;
                            }

                            targetSpell.CompleteScheduledTime = now.AddSeconds(d);

                            targetSpell.MatchDateTime = now;

                            // マッチング計測終了
                            spell.EndMatching();

                            // マッチ時点のサウンドを再生する
                            targetSpell.Play(targetSpell.MatchSound, targetSpell.MatchAdvancedConfig);
                            targetSpell.Play(targetSpell.MatchTextToSpeak, targetSpell.MatchAdvancedConfig);

                            notifyNeeded = true;

                            // 遅延サウンドタイマを開始する
                            targetSpell.StartOverSoundTimer();
                            targetSpell.StartBeforeSoundTimer();
                            targetSpell.StartTimeupSoundTimer();
                        }
                    }
                    else
                    {
                        // 正規表現でマッチングする
                        var match = regex.Match(logLine);
                        if (match.Success)
                        {
                            matched = true;
#if DEBUG
                            if (logLine.Contains("MARK"))
                            {
                                Debug.WriteLine("MARK");
                            }
#endif
                            var targetSpell = default(Spell);

                            void setTitle()
                            {
                                targetSpell = spell;

                                // ヒットしたログを格納する
                                targetSpell.MatchedLog = logLine;

                                // スペル名(表示テキスト)を置換する
                                var replacedTitle = match.Result(ConditionUtility.GetReplacedTitle(targetSpell));

                                // PC名を置換する
                                replacedTitle = FFXIVPlugin.Instance.ReplacePartyMemberName(
                                    replacedTitle,
                                    Settings.Default.PCNameInitialOnDisplayStyle);

                                // インスタンス化する?
                                if (targetSpell.ToInstance)
                                {
                                    // 同じタイトルのインスタンススペルを探す
                                    // 存在すればそれを使用して、なければ新しいインスタンスを生成する
                                    targetSpell = SpellTable.Instance.GetOrAddInstance(
                                        replacedTitle,
                                        targetSpell);
                                }
                                else
                                {
                                    targetSpell.SpellTitleReplaced = replacedTitle;
                                }
                            }

                            // スペルタイトルを編集する
                            setTitle();

                            targetSpell.UpdateDone = false;
                            targetSpell.OverDone   = false;
                            targetSpell.BeforeDone = false;
                            targetSpell.TimeupDone = false;

                            var now = DateTime.Now;

                            // 効果時間を決定する
                            // グループ "duration" をキャプチャーしていた場合は効果時間を置換する
                            // 最大値9999を超えていた場合は無視する
                            var duration = targetSpell.RecastTime;

                            var d = 0d;
                            var durationAsText = match.Groups["duration"].Value;
                            if (double.TryParse(durationAsText, out d) &&
                                d < 9999)
                            {
                                duration = d;
                            }
                            else
                            {
                                // ホットバーからリキャスト時間の読込を試みる
                                if (this.TryGetHotbarRecast(targetSpell, out d))
                                {
                                    duration = d;
                                }
                            }

                            targetSpell.CompleteScheduledTime = now.AddSeconds(duration);

                            // スペル対象を保存する
                            // グループ "target" をキャプチャーしていた場合はその文字列を保存する
                            var targetName = match.Groups["target"].Value;
                            if (!string.IsNullOrWhiteSpace(targetName))
                            {
                                targetSpell.TargetName = targetName;
                            }

                            // マッチ日時を格納する
                            targetSpell.MatchDateTime = now;

                            // マッチング計測終了
                            spell.EndMatching();

                            // マッチ時点のサウンドを再生する
                            targetSpell.Play(targetSpell.MatchSound, targetSpell.MatchAdvancedConfig);

                            if (!string.IsNullOrWhiteSpace(targetSpell.MatchTextToSpeak))
                            {
                                var tts = match.Result(targetSpell.MatchTextToSpeak);
                                targetSpell.Play(tts, targetSpell.MatchAdvancedConfig);
                            }

                            notifyNeeded = true;

                            // 遅延サウンドタイマを開始する
                            targetSpell.StartOverSoundTimer();
                            targetSpell.StartBeforeSoundTimer();
                            targetSpell.StartTimeupSoundTimer();
                        }
                    }
                }
            }

            // 延長をマッチングする
            if (spell.MatchDateTime > DateTime.MinValue)
            {
                var keywords      = new string[] { spell.KeywordForExtendReplaced1, spell.KeywordForExtendReplaced2 };
                var regexes       = new Regex[] { spell.RegexForExtend1, spell.RegexForExtend2 };
                var timeToExtends = new double[] { spell.RecastTimeExtending1, spell.RecastTimeExtending2 };

                for (int i = 0; i < 2; i++)
                {
                    var keywordToExtend = keywords[i];
                    var regexToExtend   = regexes[i];
                    var timeToExtend    = timeToExtends[i];

                    // マッチングする
                    var exntended = false;

                    if (!spell.RegexEnabled ||
                        regexToExtend == null)
                    {
                        if (!string.IsNullOrWhiteSpace(keywordToExtend))
                        {
                            exntended = logLine.Contains(keywordToExtend, StringComparison.OrdinalIgnoreCase);
                        }
                    }
                    else
                    {
                        var match = regexToExtend.Match(logLine);
                        exntended = match.Success;

                        if (exntended)
                        {
                            // targetをキャプチャーしている?
                            if (!string.IsNullOrWhiteSpace(spell.TargetName))
                            {
                                var targetName = match.Groups["target"].Value;
                                if (!string.IsNullOrWhiteSpace(targetName))
                                {
                                    // targetが当初のマッチングと一致するか確認する
                                    if (spell.TargetName != targetName)
                                    {
                                        exntended = false;
                                    }
                                }
                            }
                        }
                    }

                    if (!exntended)
                    {
                        continue;
                    }

                    var now = DateTime.Now;

                    // リキャストタイムを延長する
                    var newSchedule = spell.CompleteScheduledTime.AddSeconds(timeToExtend);
                    spell.BeforeDone = false;
                    spell.UpdateDone = false;

                    if (spell.ExtendBeyondOriginalRecastTime)
                    {
                        if (spell.UpperLimitOfExtension > 0)
                        {
                            var newDuration = (newSchedule - now).TotalSeconds;
                            if (newDuration > (double)spell.UpperLimitOfExtension)
                            {
                                newSchedule = newSchedule.AddSeconds(
                                    (newDuration - (double)spell.UpperLimitOfExtension) * -1);
                            }
                        }
                    }
                    else
                    {
                        var newDuration = (newSchedule - now).TotalSeconds;
                        if (newDuration > (double)spell.RecastTime)
                        {
                            newSchedule = newSchedule.AddSeconds(
                                (newDuration - (double)spell.RecastTime) * -1);
                        }
                    }

                    spell.CompleteScheduledTime = newSchedule;
                    spell.MatchDateTime         = now;

                    notifyNeeded = true;

                    // 遅延サウンドタイマを開始(更新)する
                    spell.StartOverSoundTimer();
                    spell.StartBeforeSoundTimer();
                    spell.StartTimeupSoundTimer();
                }
            }
            // end if 延長マッチング

            // ホットバー情報を更新する
            if (!matched)
            {
                var now = DateTime.Now;

                if (spell.CompleteScheduledTime > now)
                {
                    double d;
                    if (this.TryGetHotbarRecast(spell, out d))
                    {
                        // ホットバー情報と0.6秒以上乖離したら補正する
                        var newSchedule = now.AddSeconds(d);

                        if (Math.Abs((newSchedule - spell.CompleteScheduledTime).TotalSeconds)
                            >= 0.6d)
                        {
                            spell.CompleteScheduledTime = newSchedule;
                            spell.BeforeDone            = false;
                            spell.UpdateDone            = false;

                            notifyNeeded = true;

                            spell.StartOverSoundTimer();
                            spell.StartBeforeSoundTimer();
                            spell.StartTimeupSoundTimer();
                        }
                    }
                }
            }

            // ACT標準のSpellTimerに変更を通知する
            if (notifyNeeded)
            {
                this.UpdateNormalSpellTimer(spell, false);
                this.NotifyNormalSpellTimer(spell);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// 1ログ1スペルに対して判定する
        /// </summary>
        /// <param name="spell">スペル</param>
        /// <param name="logLine">ログ</param>
        public void MatchCore(
            Models.Spell spell,
            string logLine)
        {
            var regex        = spell.Regex;
            var notifyNeeded = false;

            if (!spell.IsInstance)
            {
                // マッチング計測開始
                spell.StartMatching();

                // 開始条件を確認する
                if (ConditionUtility.CheckConditionsForSpell(spell))
                {
                    // 正規表現が無効?
                    if (!spell.RegexEnabled ||
                        regex == null)
                    {
                        var keyword = spell.KeywordReplaced;
                        if (string.IsNullOrWhiteSpace(keyword))
                        {
                            return;
                        }

                        // キーワードが含まれるか?
                        if (logLine.Contains(keyword, StringComparison.OrdinalIgnoreCase))
                        {
                            var targetSpell = spell;

                            // ヒットしたログを格納する
                            targetSpell.MatchedLog = logLine;

                            // スペル名(表示テキスト)を置換する
                            var replacedTitle = ConditionUtility.GetReplacedTitle(targetSpell);

                            // PC名を置換する
                            replacedTitle = FFXIVPlugin.Instance.ReplacePartyMemberName(replacedTitle);

                            targetSpell.SpellTitleReplaced = replacedTitle;
                            targetSpell.UpdateDone         = false;
                            targetSpell.OverDone           = false;
                            targetSpell.BeforeDone         = false;
                            targetSpell.TimeupDone         = false;

                            var now = DateTime.Now;
                            targetSpell.CompleteScheduledTime = now.AddSeconds(targetSpell.RecastTime);
                            targetSpell.MatchDateTime         = now;

                            // マッチング計測終了
                            spell.EndMatching();

                            // マッチ時点のサウンドを再生する
                            this.Play(targetSpell.MatchSound);
                            this.Play(targetSpell.MatchTextToSpeak);

                            // DISCORDに通知する?
                            if (targetSpell.NotifyToDiscord)
                            {
                                DiscordBridge.Instance.SendMessageDelegate?.Invoke(
                                    $"{replacedTitle} {targetSpell.RecastTime:N0}");
                            }

                            notifyNeeded = true;

                            // 遅延サウンドタイマを開始する
                            targetSpell.StartOverSoundTimer();
                            targetSpell.StartBeforeSoundTimer();
                            targetSpell.StartTimeupSoundTimer();
                        }
                    }
                    else
                    {
                        // 正規表現でマッチングする
                        var match = regex.Match(logLine);
                        if (match.Success)
                        {
                            var targetSpell = spell;

                            // ヒットしたログを格納する
                            targetSpell.MatchedLog = logLine;

                            // スペル名(表示テキスト)を置換する
                            var replacedTitle = match.Result(ConditionUtility.GetReplacedTitle(targetSpell));

                            // PC名を置換する
                            replacedTitle = FFXIVPlugin.Instance.ReplacePartyMemberName(replacedTitle);

                            // インスタンス化する?
                            if (spell.ToInstance)
                            {
                                // 同じタイトルのインスタンススペルを探す
                                // 存在すればそれを使用して、なければ新しいインスタンスを生成する
                                targetSpell = SpellTable.Instance.GetOrAddInstance(
                                    replacedTitle,
                                    spell);

                                // インスタンスのガーベージタイマをスタートする
                                targetSpell.StartGarbageInstanceTimer();
                            }

                            targetSpell.SpellTitleReplaced = replacedTitle;
                            targetSpell.UpdateDone         = false;
                            targetSpell.OverDone           = false;
                            targetSpell.BeforeDone         = false;
                            targetSpell.TimeupDone         = false;

                            var now = DateTime.Now;

                            // 効果時間を決定する
                            // グループ "duration" をキャプチャーしていた場合は効果時間を置換する
                            var    durationAsText = match.Groups["duration"].Value;
                            double duration;
                            if (!double.TryParse(durationAsText, out duration))
                            {
                                duration = targetSpell.RecastTime;
                            }

                            targetSpell.CompleteScheduledTime = now.AddSeconds(duration);

                            // スペル対象を保存する
                            // グループ "target" をキャプチャーしていた場合はその文字列を保存する
                            var targetName = match.Groups["target"].Value;
                            if (!string.IsNullOrWhiteSpace(targetName))
                            {
                                targetSpell.TargetName = targetName;
                            }

                            // マッチ日時を格納する
                            targetSpell.MatchDateTime = now;

                            // マッチング計測終了
                            spell.EndMatching();

                            // マッチ時点のサウンドを再生する
                            this.Play(targetSpell.MatchSound);

                            if (!string.IsNullOrWhiteSpace(targetSpell.MatchTextToSpeak))
                            {
                                var tts = match.Result(targetSpell.MatchTextToSpeak);
                                this.Play(tts);
                            }

                            // DISCORDに通知する?
                            if (targetSpell.NotifyToDiscord)
                            {
                                DiscordBridge.Instance.SendMessageDelegate?.Invoke(
                                    $"{replacedTitle} {targetSpell.RecastTime:N0}");
                            }

                            notifyNeeded = true;

                            // 遅延サウンドタイマを開始する
                            targetSpell.StartOverSoundTimer();
                            targetSpell.StartBeforeSoundTimer();
                            targetSpell.StartTimeupSoundTimer();
                        }
                    }
                }
            }

            // 延長をマッチングする
            if (spell.MatchDateTime > DateTime.MinValue)
            {
                var keywords      = new string[] { spell.KeywordForExtendReplaced1, spell.KeywordForExtendReplaced2 };
                var regexes       = new Regex[] { spell.RegexForExtend1, spell.RegexForExtend2 };
                var timeToExtends = new double[] { spell.RecastTimeExtending1, spell.RecastTimeExtending2 };

                for (int i = 0; i < 2; i++)
                {
                    var keywordToExtend = keywords[i];
                    var regexToExtend   = regexes[i];
                    var timeToExtend    = timeToExtends[i];

                    // マッチングする
                    var matched = false;

                    if (!spell.RegexEnabled ||
                        regexToExtend == null)
                    {
                        if (!string.IsNullOrWhiteSpace(keywordToExtend))
                        {
                            matched = logLine.Contains(keywordToExtend, StringComparison.OrdinalIgnoreCase);
                        }
                    }
                    else
                    {
                        var match = regexToExtend.Match(logLine);
                        matched = match.Success;

                        if (matched)
                        {
                            // targetをキャプチャーしている?
                            if (!string.IsNullOrWhiteSpace(spell.TargetName))
                            {
                                var targetName = match.Groups["target"].Value;
                                if (!string.IsNullOrWhiteSpace(targetName))
                                {
                                    // targetが当初のマッチングと一致するか確認する
                                    if (spell.TargetName != targetName)
                                    {
                                        matched = false;
                                    }
                                }
                            }
                        }
                    }

                    if (!matched)
                    {
                        continue;
                    }

                    var now = DateTime.Now;

                    // リキャストタイムを延長する
                    var newSchedule = spell.CompleteScheduledTime.AddSeconds(timeToExtend);
                    spell.BeforeDone = false;
                    spell.UpdateDone = false;

                    if (spell.ExtendBeyondOriginalRecastTime)
                    {
                        if (spell.UpperLimitOfExtension > 0)
                        {
                            var newDuration = (newSchedule - now).TotalSeconds;
                            if (newDuration > (double)spell.UpperLimitOfExtension)
                            {
                                newSchedule = newSchedule.AddSeconds(
                                    (newDuration - (double)spell.UpperLimitOfExtension) * -1);
                            }
                        }
                    }
                    else
                    {
                        var newDuration = (newSchedule - now).TotalSeconds;
                        if (newDuration > (double)spell.RecastTime)
                        {
                            newSchedule = newSchedule.AddSeconds(
                                (newDuration - (double)spell.RecastTime) * -1);
                        }
                    }

                    spell.CompleteScheduledTime = newSchedule;
                    spell.MatchDateTime         = now;

                    notifyNeeded = true;

                    // 遅延サウンドタイマを開始(更新)する
                    spell.StartOverSoundTimer();
                    spell.StartBeforeSoundTimer();
                    spell.StartTimeupSoundTimer();
                }
            }
            // end if 延長マッチング

            // ACT標準のSpellTimerに変更を通知する
            if (notifyNeeded)
            {
                this.UpdateNormalSpellTimer(spell, false);
                this.NotifyNormalSpellTimer(spell);
            }
        }