Example #1
0
        /// <summary>
        /// 不要になったWindowを閉じる
        /// </summary>
        /// <param name="telops">Telops</param>
        public static void GarbageWindows(
            IReadOnlyList <OnePointTelop> telops)
        {
            // 不要になったWindowを閉じる
            var removeWindowList = new List <OnePointTelopWindow>();

            foreach (var window in telopWindowList.Values)
            {
                if (!telops.Any(x => x.ID == window.DataSource.ID))
                {
                    removeWindowList.Add(window);
                }
            }

            foreach (var window in removeWindowList)
            {
                ActInvoker.Invoke(() =>
                {
                    window.DataSource.Left = window.Left;
                    window.DataSource.Top  = window.Top;
                    window.Close();
                });

                telopWindowList.Remove(window.DataSource.ID);
            }
        }
Example #2
0
        /// <summary>
        /// Panelの位置を設定する
        /// </summary>
        public void LayoutPanels()
        {
            if (this.SpellTimerPanels != null)
            {
                ActInvoker.Invoke(() =>
                {
                    foreach (var panel in this.SpellTimerPanels)
                    {
                        var setting = PanelSettings.Default.SettingsTable
                                      .Where(x => x.PanelName == panel.PanelName)
                                      .FirstOrDefault();

                        if (setting != null)
                        {
                            panel.Left = setting.Left;
                            panel.Top  = setting.Top;
                        }
                        else
                        {
                            panel.Left = 10.0d;
                            panel.Top  = 10.0d;
                        }
                    }
                });
            }
        }
Example #3
0
        /// <summary>
        /// 表示切り替えボタン(スペスペボタン)の状態を切り替える
        /// </summary>
        /// <param name="visible">
        /// 切り替える状態</param>
        public static void ChangeSwitchVisibleButton(
            bool visible)
        {
            Settings.Default.OverlayVisible = visible;
            Settings.Default.Save();

            SpellTimerCore.Default.ClosePanels();
            OnePointTelopController.CloseTelops();

            FF14PluginHelper.RefreshPlayer();
            LogBuffer.RefreshPartyList();
            LogBuffer.RefreshPetID();

            if (Settings.Default.OverlayVisible)
            {
                SpellTimerCore.Default.ActivatePanels();
                OnePointTelopController.ActivateTelops();
            }

            ActInvoker.Invoke(() =>
            {
                if (Settings.Default.OverlayVisible)
                {
                    SwitchVisibleButton.BackColor = Color.OrangeRed;
                    SwitchVisibleButton.ForeColor = Color.WhiteSmoke;
                }
                else
                {
                    SwitchVisibleButton.BackColor = SystemColors.Control;
                    SwitchVisibleButton.ForeColor = Color.Black;
                }
            });
        }
Example #4
0
        /// <summary>
        /// 表示切り替えボタン(スペスペボタン)の状態を切り替える
        /// </summary>
        /// <param name="visible">
        /// 切り替える状態</param>
        public static void ChangeSwitchVisibleButton(
            bool visible)
        {
            Settings.Default.OverlayVisible = visible;
            Settings.Default.Save();

            SpellTimerCore.Default.ClosePanels();
            OnePointTelopController.CloseTelops();

            TableCompiler.Instance.RefreshPlayerPlacceholder();
            TableCompiler.Instance.RefreshPartyPlaceholders();
            TableCompiler.Instance.RefreshPetPlaceholder();
            TableCompiler.Instance.RecompileSpells();
            TableCompiler.Instance.RecompileTickers();

            if (Settings.Default.OverlayVisible)
            {
                SpellTimerCore.Default.ActivatePanels();
                OnePointTelopController.ActivateTelops();
            }

            ActInvoker.Invoke(() =>
            {
                if (Settings.Default.OverlayVisible)
                {
                    SwitchVisibleButton.BackColor = Color.OrangeRed;
                    SwitchVisibleButton.ForeColor = Color.WhiteSmoke;
                }
                else
                {
                    SwitchVisibleButton.BackColor = SystemColors.Control;
                    SwitchVisibleButton.ForeColor = Color.Black;
                }
            });
        }
        private void ReplaceButton()
        {
            if (this.SwitchVisibleButton != null &&
                !this.SwitchVisibleButton.IsDisposed &&
                this.SwitchVisibleButton.IsHandleCreated)
            {
                var leftButton = (
                    from Control x in ActGlobals.oFormActMain.Controls
                    where
                    !x.Equals(this.SwitchVisibleButton) &&
                    (
                        x is Button ||
                        x is CheckBox
                    )
                    orderby
                    x.Left
                    select
                    x).FirstOrDefault();

                var location = leftButton != null ?
                               new Point(leftButton.Left - this.SwitchVisibleButton.Width - 1, 0) :
                               new Point(ActGlobals.oFormActMain.Width - 533, 0);

                ActInvoker.Invoke(() =>
                {
                    if (this.SwitchVisibleButton != null)
                    {
                        this.SwitchVisibleButton.Location = location;
                    }
                });
            }
        }
Example #6
0
        /// <summary>
        /// リスタートのときスペルのカウントをリセットする
        /// </summary>
        private void ResetCountAtRestart()
        {
            // 無効?
            if (!Settings.Default.ResetOnWipeOut)
            {
                return;
            }

            // 0.1秒毎に判定する
            if ((DateTime.Now - this.lastWipeOutDetectDateTime).TotalSeconds <= 0.1)
            {
                return;
            }

            this.lastWipeOutDetectDateTime = DateTime.Now;

            var combatants = FFXIVPlugin.Instance.GetPartyList();

            if (combatants == null ||
                combatants.Count < 1)
            {
                return;
            }

            // 関係者が全員死んでる?
            if (combatants.Count ==
                combatants.Count(x => x.CurrentHP <= 0))
            {
                // リセットするのは15秒に1回にする
                // 暗転中もずっとリセットし続けてしまうので
                if ((DateTime.Now - this.lastWipeOutDateTime).TotalSeconds >= 15.0)
                {
                    // インスタンススペルを消去する
                    SpellTable.Instance.RemoveInstanceSpellsAll();

                    SpellTable.ResetCount();
                    TickerTable.Instance.ResetCount();

                    this.lastWipeOutDateTime = DateTime.Now;

                    // wipeoutログを発生させる
                    LogParser.RaiseLog(DateTime.Now, CombatAnalyzer.Wipeout);

                    ActInvoker.Invoke(() =>
                    {
                        // ACT本体に戦闘終了を通知する
                        if (Settings.Default.WipeoutNotifyToACT)
                        {
                            ActGlobals.oFormActMain.ActCommands("end");
                        }
                    });
                }
            }
        }
Example #7
0
        /// <summary>
        /// 再生する
        /// </summary>
        /// <param name="source">
        /// 再生する対象</param>
        public void Play(
            string source)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(source))
                {
                    return;
                }

                if (this.EnabledYukkuri)
                {
                    this.ttsYukkuriPlugin.Speak(source);
                }
                else
                {
                    Task.Run(() =>
                    {
                        // wav?
                        if (source.EndsWith(".wav"))
                        {
                            // ファイルが存在する?
                            if (File.Exists(source))
                            {
                                ActInvoker.Invoke(() =>
                                {
                                    ActGlobals.oFormActMain.PlaySound(source);
                                });
                            }
                        }
                        else
                        {
                            ActInvoker.Invoke(() =>
                            {
                                ActGlobals.oFormActMain.TTS(source);
                            });
                        }
                    }).ContinueWith((t) =>
                    {
                        if (t != null)
                        {
                            t.Dispose();
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                ActGlobals.oFormActMain.WriteExceptionLog(
                    ex,
                    Translate.Get("SoundError"));
            }
        }
Example #8
0
 /// <summary>
 /// Panelを隠す
 /// </summary>
 public void HidePanels()
 {
     if (this.SpellTimerPanels != null)
     {
         ActInvoker.Invoke(() =>
         {
             foreach (var panel in this.SpellTimerPanels)
             {
                 panel.HideOverlay();
             }
         });
     }
 }
Example #9
0
 /// <summary>
 /// テロップをActive化する
 /// </summary>
 public static void ActivateTelops()
 {
     if (telopWindowList != null)
     {
         ActInvoker.Invoke(() =>
         {
             foreach (var telop in telopWindowList.Values)
             {
                 telop.Activate();
             }
         });
     }
 }
Example #10
0
 /// <summary>
 /// テロップを隠す
 /// </summary>
 public static void HideTelops()
 {
     if (telopWindowList != null)
     {
         ActInvoker.Invoke(() =>
         {
             foreach (var telop in telopWindowList.Values)
             {
                 telop.HideOverlay();
             }
         });
     }
 }
        /// <summary>
        /// 表示切り替えボタン(スペスペボタン)の状態を切り替える
        /// </summary>
        /// <param name="visible">
        /// 切り替える状態</param>
        public async void ChangeSwitchVisibleButton(
            bool visible)
        {
            await Task.Run(() =>
            {
                this.SwitchOverlay(visible);
            });

            ActInvoker.Invoke(() =>
            {
                this.ChangeButtonColor();
            });
        }
Example #12
0
 /// <summary>
 /// Panelをアクティブ化する
 /// </summary>
 public void ActivatePanels()
 {
     if (this.SpellTimerPanels != null)
     {
         ActInvoker.Invoke(() =>
         {
             foreach (var panel in this.SpellTimerPanels)
             {
                 panel.Activate();
             }
         });
     }
 }
Example #13
0
        /// <summary>
        /// リスタートのときスペルのカウントをリセットする
        /// </summary>
        private void ResetCountAtRestart()
        {
            // FFXIV以外での使用ならば何もしない
            if (Settings.Default.UseOtherThanFFXIV)
            {
                return;
            }

            // 無効?
            if (!Settings.Default.ResetOnWipeOut)
            {
                return;
            }

            var combatants = FFXIV.Instance.GetPartyList();

            if (combatants == null ||
                combatants.Count < 1)
            {
                return;
            }

            // 関係者が全員死んでる?
            if (combatants.Count ==
                combatants.Count(x => x.CurrentHP <= 0))
            {
                // リセットするのは15秒に1回にする
                // 暗転中もずっとリセットし続けてしまうので
                if ((DateTime.Now - this.LastWipeOutDateTime).TotalSeconds >= 15.0)
                {
                    Logger.Write("Party was wiped out. Reset spells and tickers.");

                    SpellTimerTable.ResetCount();
                    OnePointTelopTable.Default.ResetCount();

                    // ACT本体に戦闘終了を通知する
                    if (Settings.Default.WipeoutNotifyToACT)
                    {
                        ActInvoker.Invoke(() =>
                        {
                            ActGlobals.oFormActMain.ActCommands("end");
                        });
                    }

                    this.LastWipeOutDateTime = DateTime.Now;
                }
            }
        }
Example #14
0
        /// <summary>
        /// 不要なスペルタイマWindowを閉じる
        /// </summary>
        /// <param name="spells">Spell</param>
        private void GarbageSpellPanelWindows(
            IReadOnlyList <Models.SpellTimer> spells)
        {
            if (this.SpellTimerPanels != null)
            {
                var removeList = new List <SpellTimerListWindow>();
                foreach (var panel in this.SpellTimerPanels)
                {
                    // パネルの位置を保存する
                    var setting = (
                        from x in PanelSettings.Default.SettingsTable
                        where
                        x.PanelName == panel.PanelName
                        select
                        x).FirstOrDefault();

                    if (setting == null)
                    {
                        setting = PanelSettings.Default.SettingsTable.NewPanelSettingsRow();
                        PanelSettings.Default.SettingsTable.AddPanelSettingsRow(setting);
                    }

                    setting.PanelName = panel.PanelName;
                    setting.Left      = panel.Left;
                    setting.Top       = panel.Top;

                    // 毎分0秒の時保存する
                    if (DateTime.Now.Second == 0)
                    {
                        PanelSettings.Default.Save();
                    }

                    // スペルリストに存在しないパネルを閉じる
                    if (!spells.Any(x => x.Panel == panel.PanelName))
                    {
                        ActInvoker.Invoke(() => panel.Close());
                        removeList.Add(panel);
                    }
                }

                foreach (var item in removeList)
                {
                    this.SpellTimerPanels.Remove(item);
                }
            }
        }
Example #15
0
        public void Wipeout(
            bool isRaiseWipeoutLog = true)
        {
            // リセットするのは10秒に1回にする
            // 暗転中もずっとリセットし続けてしまうので
            var now = DateTime.Now;

            if ((now - this.lastWipeOutDateTime).TotalSeconds >= 10.0)
            {
                this.lastWipeOutDateTime = now;

                Task.Run(() =>
                {
                    if (Settings.Default.WipeoutNotifyToACT)
                    {
                        CommonSounds.Instance.PlayWipeout();
                    }

                    // ChatログをFlushする
                    ParsedLogWorker.Instance.Flush(true);

                    Thread.Sleep(TimeSpan.FromSeconds(1));

                    // ACT本体に戦闘終了を通知する
                    if (Settings.Default.WipeoutNotifyToACT)
                    {
                        ActInvoker.Invoke(() => ActGlobals.oFormActMain.EndCombat(true));
                    }

                    // トリガーをリセットする
                    SpellTable.ResetCount();
                    TickerTable.Instance.ResetCount();

                    // wipeoutログを発生させる
                    if (isRaiseWipeoutLog)
                    {
                        Task.Run(() =>
                        {
                            Thread.Sleep(200);
                            LogParser.RaiseLog(now, WipeoutKeywords.Wipeout);
                        });
                    }
                });
            }
        }
Example #16
0
        /// <summary>
        /// テロップを閉じる
        /// </summary>
        public static void CloseTelops()
        {
            if (telopWindowList != null)
            {
                ActInvoker.Invoke(() =>
                {
                    foreach (var telop in telopWindowList.Values)
                    {
                        telop.DataSource.Left = telop.Left;
                        telop.DataSource.Top  = telop.Top;

                        telop.Close();
                    }
                });

                OnePointTelopTable.Default.Save();

                telopWindowList.Clear();
            }
        }
Example #17
0
        /// <summary>
        /// Panelを閉じる
        /// </summary>
        public void ClosePanels()
        {
            if (this.SpellTimerPanels != null)
            {
                ActInvoker.Invoke(() =>
                {
                    // Panelの位置を保存する
                    foreach (var panel in this.SpellTimerPanels)
                    {
                        var setting = (
                            from x in PanelSettings.Default.SettingsTable
                            where
                            x.PanelName == panel.PanelName
                            select
                            x).FirstOrDefault();

                        if (setting == null)
                        {
                            setting = PanelSettings.Default.SettingsTable.NewPanelSettingsRow();
                            PanelSettings.Default.SettingsTable.AddPanelSettingsRow(setting);
                        }

                        setting.PanelName = panel.PanelName;
                        setting.Left      = panel.Left;
                        setting.Top       = panel.Top;
                    }

                    if (this.SpellTimerPanels.Count > 0)
                    {
                        PanelSettings.Default.Save();
                    }

                    foreach (var panel in this.SpellTimerPanels)
                    {
                        panel.Close();
                    }

                    this.SpellTimerPanels.Clear();
                });
            }
        }
        /// <summary>
        /// リスタートのときスペルのカウントをリセットする
        /// </summary>
        public void ResetCountAtRestart()
        {
            // 無効?
            if (!Settings.Default.ResetOnWipeOut)
            {
                return;
            }

            if ((DateTime.Now - this.lastWipeOutDetectDateTime).TotalSeconds <= 0.1)
            {
                return;
            }

            this.lastWipeOutDetectDateTime = DateTime.Now;

            var player = CombatantsManager.Instance.Player;
            var party  = CombatantsManager.Instance.GetPartyList();

            if (party == null ||
                party.Count() < 1)
            {
                if (player == null ||
                    player.ID == 0)
                {
                    return;
                }

                party = new[] { player };
            }

            // 異常なデータ?
            if (party.Count() > 1)
            {
                var first = party.First();
                if (party.Count() ==
                    party.Count(x =>
                                x.CurrentHP == first.CurrentHP &&
                                x.MaxHP == first.MaxHP))
                {
                    return;
                }

                if (!party.Any(x => x.IsPlayer))
                {
                    return;
                }
            }

            if (player != null)
            {
                switch (player.JobInfo.Role)
                {
                case Roles.Crafter:
                case Roles.Gatherer:
                    return;
                }
            }

            // 関係者が全員死んでる?
            if (party.Count() ==
                party.Count(x =>
                            x.CurrentHP <= 0 &&
                            x.MaxHP > 0))
            {
                // リセットするのは10秒に1回にする
                // 暗転中もずっとリセットし続けてしまうので
                var now = DateTime.Now;
                if ((now - this.lastWipeOutDateTime).TotalSeconds >= 10.0)
                {
                    this.lastWipeOutDateTime = now;

                    Task.Run(() =>
                    {
                        Thread.Sleep(TimeSpan.FromSeconds(1));

                        // ACT本体に戦闘終了を通知する
                        if (Settings.Default.WipeoutNotifyToACT)
                        {
                            ActInvoker.Invoke(() => ActGlobals.oFormActMain.EndCombat(true));
                            CommonSounds.Instance.PlayWipeout();
                        }

                        // トリガーをリセットする
                        SpellTable.ResetCount();
                        TickerTable.Instance.ResetCount();

                        // wipeoutログを発生させる
                        Task.Run(() =>
                        {
                            Thread.Sleep(200);
                            LogParser.RaiseLog(now, ConstantKeywords.Wipeout);
                        });
                    });
                }
            }
        }
Example #19
0
        /// <summary>
        /// ログとマッチングする
        /// </summary>
        /// <param name="logLines">ログ行</param>
        public static void Match(
            string[] logLines)
        {
            var telops = OnePointTelopTable.Default.EnabledTable;

            // 不要になったWindowを閉じる
            var removeWindowList = new List <OnePointTelopWindow>();

            foreach (var window in telopWindowList.Values)
            {
                if (!telops.Any(x => x.ID == window.DataSource.ID))
                {
                    removeWindowList.Add(window);
                }
            }

            foreach (var window in removeWindowList)
            {
                ActInvoker.Invoke(() =>
                {
                    window.DataSource.Left = window.Left;
                    window.DataSource.Top  = window.Top;
                    window.Close();
                });

                telopWindowList.Remove(window.DataSource.ID);
            }

            foreach (var telop in telops.AsParallel())
            {
                var regex       = telop.Regex;
                var regexToHide = telop.RegexToHide;
                var isForceHide = false;

                foreach (var log in logLines)
                {
                    // 通常マッチ
                    if (regex == null)
                    {
                        var keyword = LogBuffer.MakeKeyword(telop.Keyword);
                        if (!string.IsNullOrWhiteSpace(keyword))
                        {
                            if (log.ToUpper().Contains(
                                    keyword.ToUpper()))
                            {
                                if (!telop.AddMessageEnabled)
                                {
                                    telop.MessageReplaced = telop.Message;
                                }
                                else
                                {
                                    telop.MessageReplaced += string.IsNullOrWhiteSpace(telop.MessageReplaced) ?
                                                             telop.Message :
                                                             Environment.NewLine + telop.Message;
                                }

                                telop.MatchDateTime = DateTime.Now;
                                telop.Delayed       = false;
                                telop.MatchedLog    = log;

                                SoundController.Default.Play(telop.MatchSound);
                                SoundController.Default.Play(telop.MatchTextToSpeak);

                                continue;
                            }
                        }
                    }

                    // 正規表現マッチ
                    if (regex != null)
                    {
                        if (regex.IsMatch(log))
                        {
                            if (!telop.AddMessageEnabled)
                            {
                                telop.MessageReplaced = regex.Replace(log, telop.Message);
                            }
                            else
                            {
                                telop.MessageReplaced += string.IsNullOrWhiteSpace(telop.MessageReplaced) ?
                                                         regex.Replace(log, telop.Message) :
                                                         Environment.NewLine + regex.Replace(log, telop.Message);
                            }

                            telop.MatchDateTime = DateTime.Now;
                            telop.Delayed       = false;
                            telop.MatchedLog    = log;

                            SoundController.Default.Play(telop.MatchSound);
                            if (!string.IsNullOrWhiteSpace(telop.MatchTextToSpeak))
                            {
                                var tts = regex.Replace(log, telop.MatchTextToSpeak);
                                SoundController.Default.Play(tts);
                            }

                            continue;
                        }
                    }

                    // 通常マッチ(強制非表示)
                    if (regexToHide == null)
                    {
                        var keyword = LogBuffer.MakeKeyword(telop.KeywordToHide);
                        if (!string.IsNullOrWhiteSpace(keyword))
                        {
                            if (log.ToUpper().Contains(
                                    keyword.ToUpper()))
                            {
                                isForceHide = true;
                                continue;
                            }
                        }
                    }

                    // 正規表現マッチ(強制非表示)
                    if (regexToHide != null)
                    {
                        if (regexToHide.IsMatch(log))
                        {
                            isForceHide = true;
                            continue;
                        }
                    }
                }   // end loop logLines

                // ディレイ時間が経過した?
                if (!telop.Delayed &&
                    telop.MatchDateTime > DateTime.MinValue &&
                    telop.Delay > 0)
                {
                    var delayed = telop.MatchDateTime.AddSeconds(telop.Delay);
                    if (DateTime.Now >= delayed)
                    {
                        telop.Delayed = true;
                        SoundController.Default.Play(telop.DelaySound);
                        var tts = regex != null && !string.IsNullOrWhiteSpace(telop.DelayTextToSpeak) ?
                                  regex.Replace(telop.MatchedLog, telop.DelayTextToSpeak) :
                                  telop.DelayTextToSpeak;
                        SoundController.Default.Play(tts);
                    }
                }

                var w = telopWindowList.ContainsKey(telop.ID) ? telopWindowList[telop.ID] : null;
                if (w == null)
                {
                    w = new OnePointTelopWindow()
                    {
                        Title      = "OnePointTelop - " + telop.Title,
                        DataSource = telop
                    };

                    if (Settings.Default.ClickThroughEnabled)
                    {
                        w.ToTransparentWindow();
                    }

                    w.Opacity = 0;
                    w.Show();

                    telopWindowList.Add(telop.ID, w);
                }

                // telopの位置を保存する
                if (DateTime.Now.Second == 0)
                {
                    telop.Left = w.Left;
                    telop.Top  = w.Top;
                    OnePointTelopTable.Default.Save();
                }

                if (Settings.Default.OverlayVisible &&
                    Settings.Default.TelopAlwaysVisible)
                {
                    // ドラッグ中じゃない?
                    if (!w.IsDragging)
                    {
                        w.Refresh();
                        w.ShowOverlay();
                    }

                    continue;
                }

                if (telop.MatchDateTime > DateTime.MinValue)
                {
                    var start = telop.MatchDateTime.AddSeconds(telop.Delay);
                    var end   = telop.MatchDateTime.AddSeconds(telop.Delay + telop.DisplayTime);

                    if (start <= DateTime.Now && DateTime.Now <= end)
                    {
                        w.Refresh();
                        w.ShowOverlay();
                    }
                    else
                    {
                        w.HideOverlay();

                        if (DateTime.Now > end)
                        {
                            telop.MatchDateTime   = DateTime.MinValue;
                            telop.MessageReplaced = string.Empty;
                        }
                    }

                    if (isForceHide)
                    {
                        w.HideOverlay();
                        telop.MatchDateTime   = DateTime.MinValue;
                        telop.MessageReplaced = string.Empty;
                    }
                }
                else
                {
                    w.HideOverlay();
                    telop.MessageReplaced = string.Empty;
                }
            }   // end loop telops
        }
Example #20
0
        /// <summary>
        /// Commandとマッチングする
        /// </summary>
        /// <param name="logLines">
        /// ログ行</param>
        public static void MatchCommand(
            IReadOnlyList <string> logLines)
        {
            var commandDone = false;

            foreach (var log in logLines)
            {
                // 正規表現の前にキーワードがなければ抜けてしまう
                if (!log.ToLower().Contains("/spespe"))
                {
                    continue;
                }

                var match = regexCommand.Match(log);
                if (!match.Success)
                {
                    continue;
                }

                var command     = match.Groups["command"].ToString().ToLower();
                var target      = match.Groups["target"].ToString().ToLower();
                var windowname  = match.Groups["windowname"].ToString().Replace(@"""", string.Empty);
                var valueAsText = match.Groups["value"].ToString();
                var value       = false;
                if (!bool.TryParse(valueAsText, out value))
                {
                    value = false;
                }

                switch (command)
                {
                case "analyze":
                    switch (target)
                    {
                    case "on":
                        SpecialSpellTimerPlugin.ConfigPanel.CombatAnalyzerEnabled = true;
                        commandDone = true;
                        break;

                    case "off":
                        SpecialSpellTimerPlugin.ConfigPanel.CombatAnalyzerEnabled = false;
                        commandDone = true;
                        break;
                    }

                    break;

                case "refresh":
                    switch (target)
                    {
                    case "spells":
                        SpellTimerCore.Default.ClosePanels();
                        commandDone = true;
                        break;

                    case "telops":
                        OnePointTelopController.CloseTelops();
                        commandDone = true;
                        break;

                    case "me":
                        FF14PluginHelper.RefreshPlayer();
                        commandDone = true;
                        break;

                    case "pt":
                        LogBuffer.RefreshPartyList();
                        commandDone = true;
                        break;

                    case "pet":
                        LogBuffer.RefreshPetID();
                        commandDone = true;
                        break;
                    }

                    break;

                case "changeenabled":
                    var changed = false;
                    switch (target)
                    {
                    case "spells":
                        foreach (var spell in SpellTimerTable.Table)
                        {
                            if (spell.Panel.Trim().ToLower() == windowname.Trim().ToLower() ||
                                spell.SpellTitle.Trim().ToLower() == windowname.Trim().ToLower() ||
                                windowname.Trim().ToLower() == "all")
                            {
                                changed       = true;
                                spell.Enabled = value;
                            }
                        }

                        if (changed)
                        {
                            ActInvoker.Invoke(() =>
                            {
                                SpecialSpellTimerPlugin.ConfigPanel.LoadSpellTimerTable();
                            });

                            commandDone = true;
                        }

                        break;

                    case "telops":
                        foreach (var telop in OnePointTelopTable.Default.Table)
                        {
                            if (telop.Title.Trim().ToLower() == windowname.Trim().ToLower() ||
                                windowname.Trim().ToLower() == "all")
                            {
                                changed       = true;
                                telop.Enabled = value;
                            }
                        }

                        if (changed)
                        {
                            ActInvoker.Invoke(() =>
                            {
                                SpecialSpellTimerPlugin.ConfigPanel.LoadTelopTable();
                            });

                            commandDone = true;
                        }

                        break;
                    }

                    break;

                case "set":
                    switch (target)
                    {
                    case "placeholder":
                        if (windowname.Trim().ToLower() != "all" &&
                            windowname.Trim() != string.Empty &&
                            valueAsText.Trim() != string.Empty)
                        {
                            LogBuffer.SetCustomPlaceholder(windowname.Trim(), valueAsText.Trim());

                            commandDone = true;
                        }

                        break;
                    }

                    break;

                case "clear":
                    switch (target)
                    {
                    case "placeholder":
                        if (windowname.Trim().ToLower() == "all")
                        {
                            LogBuffer.ClearCustomPlaceholderAll();

                            commandDone = true;
                        }
                        else if (windowname.Trim() != string.Empty)
                        {
                            LogBuffer.ClearCustomPlaceholder(windowname.Trim());

                            commandDone = true;
                        }

                        break;
                    }

                    break;

                case "on":
                    SpecialSpellTimerPlugin.ChangeSwitchVisibleButton(true);
                    commandDone = true;
                    break;

                case "off":
                    SpecialSpellTimerPlugin.ChangeSwitchVisibleButton(false);
                    commandDone = true;
                    break;
                }
            }   // loop end logLines

            // コマンドを実行したらシステム音を鳴らす
            if (commandDone)
            {
                SystemSounds.Asterisk.Play();
            }
        }   // method end
        /// <summary>
        /// Load
        /// </summary>
        /// <param name="sender">イベント発生元</param>
        /// <param name="e">イベント引数</param>
        private void ConfigPanel_Load(object sender, EventArgs e)
        {
            this.LoadSpellTimerTable();

            this.DetailGroupBox.Visible      = false;
            this.DetailPanelGroupBox.Visible = false;

            // コンボボックスにアイテムを装填する
            this.MatchSoundComboBox.DataSource    = SoundController.Instance.EnumlateWave();
            this.MatchSoundComboBox.ValueMember   = "FullPath";
            this.MatchSoundComboBox.DisplayMember = "Name";

            this.OverSoundComboBox.DataSource    = SoundController.Instance.EnumlateWave();
            this.OverSoundComboBox.ValueMember   = "FullPath";
            this.OverSoundComboBox.DisplayMember = "Name";

            this.BeforeSoundComboBox.DataSource    = SoundController.Instance.EnumlateWave();
            this.BeforeSoundComboBox.ValueMember   = "FullPath";
            this.BeforeSoundComboBox.DisplayMember = "Name";

            this.TimeupSoundComboBox.DataSource    = SoundController.Instance.EnumlateWave();
            this.TimeupSoundComboBox.ValueMember   = "FullPath";
            this.TimeupSoundComboBox.DisplayMember = "Name";

            // イベントを設定する
            this.SpellTimerTreeView.AfterSelect += this.SpellTimerTreeView_AfterSelect;
            this.AddButton.Click    += this.AddButton_Click;
            this.UpdateButton.Click += this.UpdateButton_Click;
            this.DeleteButton.Click += this.DeleteButton_Click;

            this.Play1Button.Click += (s1, e1) =>
            {
                SoundController.Instance.Play((string)this.MatchSoundComboBox.SelectedValue ?? string.Empty);
            };

            this.Play2Button.Click += (s1, e1) =>
            {
                SoundController.Instance.Play((string)this.OverSoundComboBox.SelectedValue ?? string.Empty);
            };

            this.Play3Button.Click += (s1, e1) =>
            {
                SoundController.Instance.Play((string)this.TimeupSoundComboBox.SelectedValue ?? string.Empty);
            };

            this.Play4Button.Click += (s1, e1) =>
            {
                SoundController.Instance.Play((string)this.BeforeSoundComboBox.SelectedValue ?? string.Empty);
            };

            this.Speak1Button.Click += (s1, e1) =>
            {
                SoundController.Instance.Play(this.MatchTextToSpeakTextBox.Text);
            };

            this.Speak2Button.Click += (s1, e1) =>
            {
                SoundController.Instance.Play(this.OverTextToSpeakTextBox.Text);
            };

            this.Speak3Button.Click += (s1, e1) =>
            {
                SoundController.Instance.Play(this.TimeupTextToSpeakTextBox.Text);
            };

            this.Speak4Button.Click += (s1, e1) =>
            {
                SoundController.Instance.Play(this.BeforeTextToSpeakTextBox.Text);
            };

            this.SpellTimerTreeView.AfterCheck += (s1, e1) =>
            {
                var source = e1.Node.Tag as Spell;
                if (source != null)
                {
                    source.Enabled    = e1.Node.Checked;
                    source.UpdateDone = false;
                }
                else
                {
                    foreach (TreeNode node in e1.Node.Nodes)
                    {
                        var sourceChild = node.Tag as Spell;
                        if (sourceChild != null)
                        {
                            sourceChild.Enabled = e1.Node.Checked;
                        }

                        node.Checked = e1.Node.Checked;
                    }
                }

                // キャッシュを無効にする
                TableCompiler.Instance.RecompileSpells();

                // スペルの有効・無効が変化した際に、標準のスペルタイマーに反映する
                SpellsController.Instance.ApplyToNormalSpellTimer();
            };

            this.SelectJobButton.Click += async(s1, e1) =>
            {
                var src = this.DetailGroupBox.Tag as Spell;
                if (src != null)
                {
                    using (var f = new SelectJobForm())
                    {
                        f.JobFilter = src.JobFilter;
                        if (await Task.Run(() => f.ShowDialog(this.ParentForm)) ==
                            DialogResult.OK)
                        {
                            src.JobFilter = f.JobFilter;

                            // ジョブ限定ボタンの色を変える(未設定:黒、設定有:青)
                            this.SelectJobButton.ForeColor = src.JobFilter != string.Empty ? Color.Blue : Button.DefaultForeColor;
                        }
                    }
                }
            };

            this.SelectZoneButton.Click += async(s1, e1) =>
            {
                var src = this.DetailGroupBox.Tag as Spell;
                if (src != null)
                {
                    using (var f = new SelectZoneForm())
                    {
                        f.ZoneFilter = src.ZoneFilter;
                        if (await Task.Run(() => f.ShowDialog(this.ParentForm)) ==
                            DialogResult.OK)
                        {
                            src.ZoneFilter = f.ZoneFilter;

                            // ゾーン限定ボタンの色を変える(未設定:黒、設定有:青)
                            this.SelectZoneButton.ForeColor = src.ZoneFilter != string.Empty ? Color.Blue : Button.DefaultForeColor;
                        }
                    }
                }
            };

            this.SetConditionButton.Click += async(s1, e1) =>
            {
                var src = this.DetailGroupBox.Tag as Spell;
                if (src != null)
                {
                    using (var f = new SetConditionForm())
                    {
                        f.TimersMustRunning  = src.TimersMustRunningForStart;
                        f.TimersMustStopping = src.TimersMustStoppingForStart;

                        if (await Task.Run(() => f.ShowDialog(this.ParentForm)) ==
                            DialogResult.OK)
                        {
                            src.TimersMustRunningForStart  = f.TimersMustRunning;
                            src.TimersMustStoppingForStart = f.TimersMustStopping;

                            // 条件設定ボタンの色を変える(未設定:黒、設定有:青)
                            this.SetConditionButton.ForeColor =
                                (src.TimersMustRunningForStart.Length != 0 || src.TimersMustStoppingForStart.Length != 0) ?
                                Color.Blue :
                                Button.DefaultForeColor;
                        }
                    }
                }
            };

            // アイコン選択ボタンの挙動を設定する
            this.SelectIconButton.Click += async(s1, e1) =>
            {
                var selectedIcon = (string)this.SelectIconButton.Tag;
                var spell        = this.DetailGroupBox.Tag as Spell;

                var result = await SelectIconForm.ShowDialogAsync(
                    selectedIcon,
                    this,
                    spell);

                if (result.Result)
                {
                    ActInvoker.Invoke(() =>
                    {
                        this.SelectIconButton.Tag = result.Icon;
                        this.SelectIconButton.BackgroundImageLayout = ImageLayout.Zoom;

                        this.SelectIconButton.BackgroundImage           = null;
                        this.SelectIconButton.FlatAppearance.BorderSize = 1;
                        var icon = IconController.Instance.GetIconFile(result.Icon);
                        if (icon != null &&
                            File.Exists(icon.FullPath))
                        {
                            this.SelectIconButton.BackgroundImage = System.Drawing.Image.FromFile(
                                icon.FullPath);
                            this.SelectIconButton.FlatAppearance.BorderSize = 0;
                        }

                        this.SpellVisualSetting.SpellIcon = result.Icon;
                        this.SpellVisualSetting.RefreshSampleImage();
                    });
                }
            };

            this.SpellIconSizeUpDown.ValueChanged += (s1, e1) =>
            {
                this.SpellVisualSetting.SpellIconSize = (int)this.SpellIconSizeUpDown.Value;
                this.SpellVisualSetting.RefreshSampleImage();
            };

            this.HideSpellNameCheckBox.CheckedChanged += (s1, e1) =>
            {
                this.SpellVisualSetting.HideSpellName = this.HideSpellNameCheckBox.Checked;
                this.SpellVisualSetting.RefreshSampleImage();
            };

            this.OverlapRecastTimeCheckBox.CheckedChanged += (s1, e1) =>
            {
                this.SpellVisualSetting.OverlapRecastTime = this.OverlapRecastTimeCheckBox.Checked;
                this.SpellVisualSetting.RefreshSampleImage();
            };

            // スペルの一時表示チェックボックス
            this.TemporarilyDisplaySpellCheckBox.CheckedChanged += (s1, e1) =>
            {
                var src = this.DetailGroupBox.Tag as Spell;
                if (src == null)
                {
                    return;
                }

                src.IsTemporaryDisplay = this.TemporarilyDisplaySpellCheckBox.Checked;
                src.UpdateDone         = false;

                TableCompiler.Instance.RecompileSpells();
            };

            // スペルパネル単位のエクスポート
            this.ExportBySpellPanelButton.Click += this.ExportBySpellPanelButton_Click;

            // オプションのロードメソッドを呼ぶ
            this.LoadOption();
            this.LoadDQXOption();

            // ワンポイントテロップのロードメソッドを呼ぶ
            this.LoadOnePointTelop();

            // 戦闘アナライザのロードメソッドを呼ぶ
            this.LoadCombatAnalyzer();
        }
Example #22
0
        /// <summary>
        /// リスタートのときスペルのカウントをリセットする
        /// </summary>
        public void ResetCountAtRestart()
        {
            // 無効?
            if (!Settings.Default.ResetOnWipeOut)
            {
                return;
            }

            if ((DateTime.Now - this.lastWipeOutDetectDateTime).TotalSeconds <= 0.1)
            {
                return;
            }

            this.lastWipeOutDetectDateTime = DateTime.Now;

            var party = default(IEnumerable <Combatant>);

            party = FFXIVPlugin.Instance.GetPartyList();

            if (party == null ||
                party.Count() < 1)
            {
                return;
            }

            // 異常なデータ?
            if (party.Count() > 1)
            {
                var first = party.First();
                if (party.Count() ==
                    party.Count(x =>
                                x.CurrentHP == first.CurrentHP &&
                                x.MaxHP == first.MaxHP))
                {
                    return;
                }

                if (!party.Any(x => x.IsPlayer))
                {
                    return;
                }

                if (party.Any(x => x.IsNPC()))
                {
                    return;
                }
            }

            var player = FFXIVPlugin.Instance.GetPlayer();

            if (player != null)
            {
                switch (player.AsJob().Role)
                {
                case Roles.Crafter:
                case Roles.Gatherer:
                    return;
                }
            }

            // 関係者が全員死んでる?
            if (party.Count() ==
                party.Count(x =>
                            x.CurrentHP <= 0 &&
                            x.MaxHP > 0))
            {
                // リセットするのは15秒に1回にする
                // 暗転中もずっとリセットし続けてしまうので
                if ((DateTime.Now - this.lastWipeOutDateTime).TotalSeconds >= 15.0)
                {
                    this.lastWipeOutDateTime = DateTime.Now;

                    // インスタンススペルを消去する
                    SpellTable.ResetCount();
                    TickerTable.Instance.ResetCount();

                    // wipeoutログを発生させる
                    LogParser.RaiseLog(DateTime.Now, ConstantKeywords.Wipeout);

                    ActInvoker.Invoke(() =>
                    {
                        // ACT本体に戦闘終了を通知する
                        if (Settings.Default.WipeoutNotifyToACT)
                        {
                            ActGlobals.oFormActMain.ActCommands("end");
                        }
                    });
                }
            }
        }
        /// <summary>
        /// ログ1行とマッチングする
        /// </summary>
        /// <param name="logLine">ログ行</param>
        /// <returns>
        /// コマンドを実行したか?</returns>
        public static bool MatchCommandCore(
            string logLine)
        {
            var r = false;

            // 正規表現の前にキーワードがなければ抜けてしまう
            if (!logLine.ToLower().Contains("/spespe"))
            {
                return(r);
            }

            var match = regexCommand.Match(logLine);

            if (!match.Success)
            {
                return(r);
            }

            var command     = match.Groups["command"].ToString().ToLower();
            var target      = match.Groups["target"].ToString().ToLower();
            var windowname  = match.Groups["windowname"].ToString().Replace(@"""", string.Empty);
            var valueAsText = match.Groups["value"].ToString();
            var value       = false;

            if (!bool.TryParse(valueAsText, out value))
            {
                value = false;
            }

            switch (command)
            {
            case "analyze":
                switch (target)
                {
                case "on":
                    PluginCore.Instance.ConfigPanel.CombatAnalyzerEnabled = true;
                    r = true;
                    break;

                case "off":
                    PluginCore.Instance.ConfigPanel.CombatAnalyzerEnabled = false;
                    r = true;
                    break;
                }

                break;

            case "refresh":
                switch (target)
                {
                case "spells":
                    SpellsController.Instance.ClosePanels();
                    r = true;
                    break;

                case "telops":
                    TickersController.Instance.CloseTelops();
                    r = true;
                    break;

                case "pt":
                    TableCompiler.Instance.RefreshPlayerPlacceholder();
                    TableCompiler.Instance.RefreshPartyPlaceholders();
                    TableCompiler.Instance.RecompileSpells();
                    TableCompiler.Instance.RecompileTickers();
                    r = true;
                    break;

                case "pet":
                    TableCompiler.Instance.RefreshPetPlaceholder();
                    TableCompiler.Instance.RecompileSpells();
                    TableCompiler.Instance.RecompileTickers();
                    r = true;
                    break;
                }

                break;

            case "changeenabled":
                var changed = false;
                switch (target)
                {
                case "spells":
                    foreach (var spell in SpellTimerTable.Instance.Table)
                    {
                        if (spell.Panel.Trim().ToLower() == windowname.Trim().ToLower() ||
                            spell.SpellTitle.Trim().ToLower() == windowname.Trim().ToLower() ||
                            windowname.Trim().ToLower() == "all")
                        {
                            changed       = true;
                            spell.Enabled = value;
                        }
                    }

                    if (changed)
                    {
                        ActInvoker.Invoke(() =>
                        {
                            PluginCore.Instance.ConfigPanel.LoadSpellTimerTable();
                        });

                        r = true;
                    }

                    break;

                case "telops":
                    foreach (var telop in OnePointTelopTable.Instance.Table)
                    {
                        if (telop.Title.Trim().ToLower() == windowname.Trim().ToLower() ||
                            windowname.Trim().ToLower() == "all")
                        {
                            changed       = true;
                            telop.Enabled = value;
                        }
                    }

                    if (changed)
                    {
                        ActInvoker.Invoke(() =>
                        {
                            PluginCore.Instance.ConfigPanel.LoadTelopTable();
                        });

                        r = true;
                    }

                    break;
                }

                break;

            case "set":
                switch (target)
                {
                case "placeholder":
                    if (windowname.Trim().ToLower() != "all" &&
                        windowname.Trim() != string.Empty &&
                        valueAsText.Trim() != string.Empty)
                    {
                        TableCompiler.Instance.SetCustomPlaceholder(windowname.Trim(), valueAsText.Trim());

                        r = true;
                    }

                    break;
                }

                break;

            case "clear":
                switch (target)
                {
                case "placeholder":
                    if (windowname.Trim().ToLower() == "all")
                    {
                        TableCompiler.Instance.ClearCustomPlaceholderAll();

                        r = true;
                    }
                    else if (windowname.Trim() != string.Empty)
                    {
                        TableCompiler.Instance.ClearCustomPlaceholder(windowname.Trim());

                        r = true;
                    }

                    break;
                }

                break;

            case "on":
                PluginCore.Instance.ChangeSwitchVisibleButton(true);
                r = true;
                break;

            case "off":
                PluginCore.Instance.ChangeSwitchVisibleButton(false);
                r = true;
                break;
            }

            return(r);
        }
        /// <summary>
        /// Windowを更新する
        /// </summary>
        private void RefreshWindow()
        {
#if DEBUG
            var sw1 = Stopwatch.StartNew();
#endif
            // 有効なSpellリストを取得する
            var spellArray = SpellTimerTable.EnabledTable;

            // 不要なWindowを閉じる
            if (this.SpellTimerPanels != null)
            {
                var removeList = new List <SpellTimerListWindow>();
                foreach (var panel in this.SpellTimerPanels)
                {
                    // パネルの位置を保存する
                    var setting = (
                        from x in PanelSettings.Default.SettingsTable
                        where
                        x.PanelName == panel.PanelName
                        select
                        x).FirstOrDefault();

                    if (setting == null)
                    {
                        setting = PanelSettings.Default.SettingsTable.NewPanelSettingsRow();
                        PanelSettings.Default.SettingsTable.AddPanelSettingsRow(setting);
                    }

                    setting.PanelName = panel.PanelName;
                    setting.Left      = panel.Left;
                    setting.Top       = panel.Top;

                    // 毎分0秒の時保存する
                    if (DateTime.Now.Second == 0)
                    {
                        PanelSettings.Default.Save();
                    }

                    // スペルリストに存在しないパネルを閉じる
                    if (!spellArray.Any(x => x.Panel == panel.PanelName))
                    {
                        ActInvoker.Invoke(() => panel.Close());
                        removeList.Add(panel);
                    }
                }

                foreach (var item in removeList)
                {
                    this.SpellTimerPanels.Remove(item);
                }
            }

#if DEBUG
            sw1.Stop();
            Debug.WriteLine("Refresh ClosePanels ->" + sw1.ElapsedMilliseconds.ToString("N0") + "ms");
#endif

            // ACTが起動していない?
            if (ActGlobals.oFormActMain == null ||
                !ActGlobals.oFormActMain.Visible)
            {
                this.HidePanels();
                this.RefreshInterval = 1000;
                return;
            }

            if ((DateTime.Now - this.LastFFXIVProcessDateTime).TotalSeconds >= 5.0d)
            {
                // FF14が起動していない?
                if (FF14PluginHelper.GetFFXIVProcess == null)
                {
                    this.RefreshInterval = 1000;

                    if (!Settings.Default.OverlayForceVisible)
                    {
                        this.ClosePanels();
                        OnePointTelopController.CloseTelops();
                        return;
                    }
                }

                this.LastFFXIVProcessDateTime = DateTime.Now;
            }

            // タイマの間隔を標準に戻す
            this.RefreshInterval = Settings.Default.RefreshInterval;

            // ログを取り出す
#if DEBUG
            var sw2 = Stopwatch.StartNew();
#endif
            var logLines = this.LogBuffer.GetLogLines();
#if DEBUG
            sw2.Stop();
            Debug.WriteLine("Refresh GetLog ->" + sw2.ElapsedMilliseconds.ToString("N0") + "ms");
#endif

            // テロップとマッチングする
#if DEBUG
            var sw3 = Stopwatch.StartNew();
#endif
            OnePointTelopController.Match(
                logLines);
#if DEBUG
            sw3.Stop();
            Debug.WriteLine("Refresh MatchTelop ->" + sw3.ElapsedMilliseconds.ToString("N0") + "ms");
#endif

            // スペルリストとマッチングする
#if DEBUG
            var sw4 = Stopwatch.StartNew();
#endif
            this.MatchSpells(
                spellArray,
                logLines);
#if DEBUG
            sw4.Stop();
            Debug.WriteLine("Refresh MatchSpell ->" + sw4.ElapsedMilliseconds.ToString("N0") + "ms");
#endif

            // コマンドとマッチングする
            TextCommandController.MatchCommand(
                logLines);

            // オーバーレイが非表示?
            if (!Settings.Default.OverlayVisible)
            {
                this.HidePanels();
                OnePointTelopController.HideTelops();
                return;
            }

            // Windowを表示する
#if DEBUG
            var sw5 = Stopwatch.StartNew();
#endif
            var panelNames = spellArray.Select(x => x.Panel.Trim()).Distinct();
            foreach (var name in panelNames)
            {
                var w = this.SpellTimerPanels.Where(x => x.PanelName == name).FirstOrDefault();
                if (w == null)
                {
                    w = new SpellTimerListWindow()
                    {
                        Title     = "SpecialSpellTimer - " + name,
                        PanelName = name,
                    };

                    this.SpellTimerPanels.Add(w);

                    // クリックスルー?
                    if (Settings.Default.ClickThroughEnabled)
                    {
                        w.ToTransparentWindow();
                    }

                    w.Show();
                }

                w.SpellTimers = (
                    from x in spellArray
                    where
                    x.Panel.Trim() == name
                    select
                    x).ToArray();

                // ドラッグ中じゃない?
                if (!w.IsDragging)
                {
                    w.RefreshSpellTimer();
                }
            }

#if DEBUG
            sw5.Stop();
            Debug.WriteLine("Refresh RefreshSpell ->" + sw5.ElapsedMilliseconds.ToString("N0") + "ms");
#endif
        }