/// <summary> /// ログを監視する /// </summary> private void WatchLog() { // ACTが起動していない? if (ActGlobals.oFormActMain == null || !ActGlobals.oFormActMain.Visible) { Thread.Sleep(1000); return; } // 有効なスペルとテロップのリストを取得する var spellArray = SpellTimerTable.EnabledTable; var telopArray = OnePointTelopTable.Default.EnabledTable; // ログを取り出す var logLines = this.LogBuffer.GetLogLines(); // テロップとマッチングする OnePointTelopController.Match( telopArray, logLines); // スペルリストとマッチングする this.MatchSpells( spellArray, logLines); // コマンドとマッチングする TextCommandController.MatchCommand( logLines); }
/// <summary> /// ログを監視する /// </summary> private void WatchLog() { var existsLog = false; // ACTが起動していない? if (ActGlobals.oFormActMain == null) { Logger.Write("act not started."); Thread.Sleep(TimeSpan.FromSeconds(3)); return; } // 全滅によるリセットを判定する var resetTask = Task.Run(() => this.ResetCountAtRestart()); if (!this.LogBuffer.IsEmpty) { // ログを取り出す var logsTask = Task.Run(() => this.LogBuffer.GetLogLines()); // 有効なスペルとテロップのリストを取得する var spellTask = Task.Run(() => TableCompiler.Instance.SpellList); var telopTask = Task.Run(() => TableCompiler.Instance.TickerList); if (logsTask.Result.Count > 0) { // テロップとマッチングする var t1 = Task.Run(() => OnePointTelopController.Match(telopTask.Result, logsTask.Result)); // スペルリストとマッチングする var t2 = Task.Run(() => this.MatchSpells(spellTask.Result, logsTask.Result)); // コマンドとマッチングする var t3 = Task.Run(() => TextCommandController.MatchCommand(logsTask.Result)); Task.WaitAll(t1, t2, t3); existsLog = true; } } resetTask.Wait(); if (!existsLog) { Thread.Sleep((int)Settings.Default.LogPollSleepInterval); } }
/// <summary> /// ログを監視する /// </summary> private void WatchLog() { // ACTが起動していない? if (ActGlobals.oFormActMain == null) { Logger.Write("act not started."); Thread.Sleep(TimeSpan.FromSeconds(3)); return; } if (this.LogBuffer.nonEmpty()) { // 有効なスペルとテロップのリストを取得する var spellArray = Task.Run(() => SpellTimerTable.EnabledTable); var telopArray = Task.Run(() => OnePointTelopTable.Default.EnabledTable); // ログを取り出す var logLines = Task.Run(() => this.LogBuffer.GetLogLines()); if (logLines.Result.Count > 0) { // テロップとマッチングする var t1 = Task.Run(() => OnePointTelopController.Match(telopArray.Result, logLines.Result)); // スペルリストとマッチングする var t2 = Task.Run(() => this.MatchSpells(spellArray.Result, logLines.Result)); // コマンドとマッチングする var t3 = Task.Run(() => TextCommandController.MatchCommand(logLines.Result)); Task.WaitAll(t1, t2, t3); return; } } Thread.Sleep(TimeSpan.FromMilliseconds(Settings.Default.LogPollSleepInterval)); }
/// <summary> /// ログ行を返す /// </summary> /// <returns>ログ行の配列</returns> public IReadOnlyList <XIVLog> GetLogLines() { if (this.logInfoQueue.IsEmpty) { return(EmptyLogLineList); } // プレイヤー情報を取得する var player = FFXIVPlugin.Instance.GetPlayer(); // プレイヤーが召喚士か? var palyerIsSummoner = false; if (player != null) { var job = player.AsJob(); if (job != null) { palyerIsSummoner = job.IsSummoner(); } } // マッチング用のログリスト var list = new List <XIVLog>(logInfoQueue.Count); var summoned = false; var doneCommand = false; var preLog = new string[3]; var preLogIndex = 0; #if DEBUG var sw = System.Diagnostics.Stopwatch.StartNew(); #endif while (logInfoQueue.TryDequeue( out LogLineEventArgs logInfo)) { var logLine = logInfo.logLine; // 直前とまったく同じ行はカットする if (preLog[0] == logLine || preLog[1] == logLine || preLog[2] == logLine) { continue; } preLog[preLogIndex++] = logLine; if (preLogIndex >= 3) { preLogIndex = 0; } // 無効なログ行をカットする if (IgnoreLogKeywords.Any(x => logLine.Contains(x))) { continue; } // ダメージ系ログをカットする if (Settings.Default.IgnoreDamageLogs && DamageLogPattern.IsMatch(logLine)) { continue; } // 詳細なログをカット if (Settings.Default.IgnoreDetailLogs && IgnoreDetailLogKeywords.Any(x => logLine.Contains(x))) { continue; } // エフェクトに付与されるツールチップ文字を除去する if (Settings.Default.RemoveTooltipSymbols) { // 4文字分のツールチップ文字を除去する int index; if ((index = logLine.IndexOf( TooltipSuffix, 0, StringComparison.Ordinal)) > -1) { logLine = logLine.Remove(index - 1, 4); } // 残ったReplacementCharを除去する logLine = logLine.Replace(TooltipReplacementChar, string.Empty); } // ペットジョブで召喚をしたか? if (!summoned && palyerIsSummoner) { summoned = isSummoned(logLine); } // コマンドとマッチングする doneCommand |= TextCommandController.MatchCommandCore(logLine); list.Add(new XIVLog(logLine)); } if (summoned) { TableCompiler.Instance.RefreshPetPlaceholder(); } if (doneCommand) { SystemSounds.Asterisk.Play(); } // ログファイルに出力する if (Settings.Default.SaveLogEnabled) { ChatLogWorker.Instance.AppendLinesAsync(list); } #if DEBUG sw.Stop(); System.Diagnostics.Debug.WriteLine($"★GetLogLines {sw.Elapsed.TotalMilliseconds:N1} ms"); #endif // 冒頭のタイムスタンプを除去して返す return(list); // 召喚したか? bool isSummoned(string logLine) { var r = false; if (logLine.Contains("You cast Summon", StringComparison.OrdinalIgnoreCase)) { r = true; } else { if (!string.IsNullOrEmpty(player.Name)) { r = logLine.Contains(player.Name + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameFI)) { r = logLine.Contains(player.NameFI + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameIF)) { r = logLine.Contains(player.NameIF + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameII)) { r = logLine.Contains(player.NameII + "の「サモン", StringComparison.OrdinalIgnoreCase); } } return(r); } }
/// <summary> /// ログ行を返す /// </summary> /// <returns>ログ行の配列</returns> public IReadOnlyList <XIVLog> GetLogLines() { if (this.XIVLogQueue.IsEmpty) { return(EmptyLogLineList); } // プレイヤー情報を取得する var player = CombatantsManager.Instance.Player; // プレイヤーが召喚士か? var palyerIsSummoner = false; if (player != null) { var job = player.JobInfo; if (job != null) { palyerIsSummoner = job.IsSummoner(); } } // マッチング用のログリスト var list = new List <XIVLog>(this.XIVLogQueue.Count); var summoned = false; var doneCommand = false; var isDefeated = false; var isCombatEnd = false; var preLog = new string[3]; var preLogIndex = 0; #if DEBUG var sw = System.Diagnostics.Stopwatch.StartNew(); #endif while (this.XIVLogQueue.TryDequeue( out XIVLog xivlog)) { var logLine = xivlog.LogLine; // 直前とまったく同じ行はカットする if (preLog[0] == logLine || preLog[1] == logLine || preLog[2] == logLine) { continue; } preLog[preLogIndex++] = logLine; if (preLogIndex >= 3) { preLogIndex = 0; } if (IsAutoIgnoreLog(logLine)) { continue; } // ツールチップシンボル, ワールド名を除去する logLine = RemoveTooltipSynbols(logLine); logLine = RemoveWorldName(logLine); xivlog.LogLine = logLine; // ペットジョブで召喚をしたか? if (!summoned && palyerIsSummoner) { summoned = isSummoned(logLine); } // 誰かが倒された? if (!isDefeated) { isDefeated = this.IsDefeated(logLine); } // 戦闘終了? if (!isCombatEnd) { isCombatEnd = this.IsCombatEnd(logLine); } // コマンドとマッチングする doneCommand |= TextCommandController.MatchCommandCore(logLine); doneCommand |= TextCommandBridge.Instance.TryExecute(logLine); list.Add(xivlog); } if (summoned) { TableCompiler.Instance.RefreshPetPlaceholder(); } if (isDefeated) { PluginMainWorker.Instance.ResetCountAtRestart(); } if (isCombatEnd) { PluginMainWorker.Instance.Wipeout(); } if (doneCommand) { CommonSounds.Instance.PlayAsterisk(); } // ログファイルに出力する if (Settings.Default.SaveLogEnabled) { ChatLogWorker.Instance.AppendLinesAsync(list); } #if DEBUG sw.Stop(); System.Diagnostics.Debug.WriteLine($"★GetLogLines {sw.Elapsed.TotalMilliseconds:N1} ms"); #endif // 冒頭のタイムスタンプを除去して返す return(list); // 召喚したか? bool isSummoned(string logLine) { var r = false; if (logLine.Contains("You cast Summon", StringComparison.OrdinalIgnoreCase)) { r = true; } else { if (!string.IsNullOrEmpty(player.Name)) { r = logLine.Contains(player.Name + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameFI)) { r = logLine.Contains(player.NameFI + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameIF)) { r = logLine.Contains(player.NameIF + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameII)) { r = logLine.Contains(player.NameII + "の「サモン", StringComparison.OrdinalIgnoreCase); } } return(r); } }
/// <summary> /// ログ行を返す /// </summary> /// <returns>ログ行の配列</returns> public IReadOnlyList <XIVLog> GetLogLines() { if (this.logInfoQueue.IsEmpty) { return(EmptyLogLineList); } // プレイヤー情報を取得する var player = FFXIVPlugin.Instance.GetPlayer(); // プレイヤーが召喚士か? var palyerIsSummoner = false; if (player != null) { var job = player.AsJob(); if (job != null) { palyerIsSummoner = job.IsSummoner(); } } // マッチング用のログリスト var list = new List <XIVLog>(logInfoQueue.Count); var partyChangedAtDQX = false; var summoned = false; var doneCommand = false; #if DEBUG var sw = System.Diagnostics.Stopwatch.StartNew(); #endif while (logInfoQueue.TryDequeue( out LogLineEventArgs logInfo)) { var logLine = logInfo.logLine; // エフェクトに付与されるツールチップ文字を除去する if (Settings.Default.RemoveTooltipSymbols) { // 4文字分のツールチップ文字を除去する int index; if ((index = logLine.IndexOf( TooltipSuffix, 0, StringComparison.Ordinal)) > -1) { logLine = logLine.Remove(index - 1, 4); } // 残ったReplacementCharを除去する logLine = logLine.Replace(TooltipReplacementChar, string.Empty); } // FFXIVでの使用? if (!Settings.Default.UseOtherThanFFXIV && !summoned && palyerIsSummoner) { summoned = isSummoned(logLine); } // パーティに変化があるか?(対DQX) if (!partyChangedAtDQX) { partyChangedAtDQX = DQXUtility.IsPartyChanged(logLine); } // コマンドとマッチングする doneCommand |= TextCommandController.MatchCommandCore(logLine); list.Add(new XIVLog(logLine)); } if (summoned) { TableCompiler.Instance.RefreshPetPlaceholder(); } if (partyChangedAtDQX) { Task.Run(() => { Thread.Sleep(TimeSpan.FromSeconds(1)); DQXUtility.RefeshKeywords(); }); } if (doneCommand) { SystemSounds.Asterisk.Play(); } // ログファイルに出力する if (Settings.Default.SaveLogEnabled) { Task.Run(() => ChatLogWorker.Instance.AppendLines(list)); } #if DEBUG sw.Stop(); System.Diagnostics.Debug.WriteLine($"★GetLogLines {sw.Elapsed.TotalMilliseconds:N1} ms"); #endif // 冒頭のタイムスタンプを除去して返す return(list); // 召喚したか? bool isSummoned(string logLine) { var r = false; if (logLine.Contains("You cast Summon", StringComparison.OrdinalIgnoreCase)) { r = true; } else { if (!string.IsNullOrEmpty(player.Name)) { r = logLine.Contains(player.Name + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameFI)) { r = logLine.Contains(player.NameFI + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameIF)) { r = logLine.Contains(player.NameIF + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameII)) { r = logLine.Contains(player.NameII + "の「サモン", StringComparison.OrdinalIgnoreCase); } } return(r); } }
public IEnumerable <XIVLog> GetLogLines() { var player = FFXIVPlugin.Instance.GetPlayer(); var palyerIsSummoner = player? .AsJob()? .IsSummoner() ?? false; var summoned = false; var doneCommand = false; var logs = this.GetLogs(); foreach (var xlvLog in logs) { // ペットジョブで召喚をしたか? if (!summoned && palyerIsSummoner) { summoned = isSummoned(xlvLog.LogLine); } // コマンドとマッチングする doneCommand |= TextCommandController.MatchCommandCore(xlvLog.LogLine); yield return(xlvLog); } if (summoned) { TableCompiler.Instance.RefreshPetPlaceholder(); } if (doneCommand) { SystemSounds.Asterisk.Play(); } // ログファイルに出力する if (Settings.Default.SaveLogEnabled) { ChatLogWorker.Instance.AppendLinesAsync(logs); } // 召喚したか? bool isSummoned(string logLine) { var r = false; if (logLine.Contains("You cast Summon", StringComparison.OrdinalIgnoreCase)) { r = true; } else { if (!string.IsNullOrEmpty(player.Name)) { r = logLine.Contains(player.Name + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameFI)) { r = logLine.Contains(player.NameFI + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameIF)) { r = logLine.Contains(player.NameIF + "の「サモン", StringComparison.OrdinalIgnoreCase); } if (!string.IsNullOrEmpty(player.NameII)) { r = logLine.Contains(player.NameII + "の「サモン", StringComparison.OrdinalIgnoreCase); } } 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 }