private void OnLogLineRead( bool isImport, LogLineEventArgs logInfo) { if (string.IsNullOrEmpty(Config.Instance.OutputDirectory) && !Config.Instance.IsEnabledRecording && !Config.Instance.IsShowTitleCard) { return; } var xivlog = new XIVLog(isImport, logInfo); if (string.IsNullOrEmpty(xivlog.Log)) { return; } LogQueue.Enqueue(xivlog); if (!isImport) { this.OpenXIVLogAsync(logInfo.logLine); VideoCapture.Instance.DetectCapture(xivlog); } }
public void DetectCapture( XIVLog xivlog) { if (!xivlog.Log.StartsWith("00:") && !xivlog.Log.StartsWith("01:") && !xivlog.Log.StartsWith("02:") && !xivlog.Log.StartsWith("19:") && !xivlog.Log.StartsWith("21:")) { return; } // 攻略を開始した var match = ContentStartLogRegex.Match(xivlog.Log); if (match.Success) { this.contentName = match.Groups["content"]?.Value; var contentName = !string.IsNullOrEmpty(this.contentName) ? this.contentName : ActGlobals.oFormActMain.CurrentZone; if (Config.Instance.TryCountContentName != contentName || (DateTime.Now - Config.Instance.TryCountTimestamp) >= TimeSpan.FromHours(Config.Instance.TryCountResetInterval)) { this.TryCount = 0; } return; } // 攻略を終了した match = ContentEndLogRegex.Match(xivlog.Log); if (match.Success) { this.FinishRecording(); this.contentName = string.Empty; WPFHelper.Invoke(() => TitleCardView.CloseTitleCard()); return; } var isStart = StartCountdownRegex.IsMatch(xivlog.Log); if (!isStart) { isStart = FeastStartRegex.IsMatch(xivlog.Log); if (isStart) { this.inFeast = true; this.contentName = ActGlobals.oFormActMain.CurrentZone; if (Config.Instance.TryCountContentName != this.contentName || (DateTime.Now - Config.Instance.TryCountTimestamp) >= TimeSpan.FromHours(Config.Instance.TryCountResetInterval)) { this.TryCount = 0; } } } if (isStart || xivlog.Log.Contains("/xivlog rec")) { SystemSounds.Beep.Play(); this.deathCount = 0; this.StartRecording(); return; } var isCancel = xivlog.Log.EndsWith("戦闘開始カウントがキャンセルされました。"); if (isCancel) { this.TryCount--; } if (isCancel || xivlog.Log.Contains("/xivlog stop") || StopVideoKeywords.Any(x => xivlog.Log.Contains(x)) || (this.inFeast && FeastEndRegex.IsMatch(xivlog.Log))) { this.FinishRecording(); SystemSounds.Beep.Play(); return; } // Player change match = PlayerChangedLogRegex.Match(xivlog.Log); if (match.Success) { this.defeatedLog = $"19:{match.Groups["player"]?.Value} was defeated"; return; } // Player defeated if (xivlog.Log.StartsWith(this.defeatedLog)) { this.deathCount++; return; } }
private void InitTask() { this.dumpLogTask = ThreadWorker.Run( doWork, TimeSpan.FromSeconds(Config.Instance.WriteInterval).TotalMilliseconds, "XIVLog Worker", ThreadPriority.Lowest); ActGlobals.oFormActMain.OnLogLineRead -= this.OnLogLineRead; ActGlobals.oFormActMain.OnLogLineRead += this.OnLogLineRead; void doWork() { var isNeedsFlush = false; if (string.IsNullOrEmpty(Config.Instance.OutputDirectory) || LogQueue.IsEmpty) { Thread.Sleep(TimeSpan.FromSeconds(Config.Instance.WriteInterval)); return; } if ((DateTime.Now - this.lastFlushTimestamp).TotalSeconds >= Config.Instance.FlushInterval) { isNeedsFlush = true; } if (this.currentLogfileName != this.LogfileName) { if (this.writter != null) { if (this.writeBuffer.Length > 0) { this.writter.Write(this.writeBuffer.ToString()); this.writeBuffer.Clear(); } this.writter.Flush(); this.writter.Close(); this.writter.Dispose(); } if (!Directory.Exists(Config.Instance.OutputDirectory)) { Directory.CreateDirectory(Config.Instance.OutputDirectory); } this.writter = new StreamWriter( new FileStream( this.LogfileName, FileMode.Append, FileAccess.Write, FileShare.Read), new UTF8Encoding(false)); this.currentLogfileName = this.LogfileName; this.RaisePropertyChanged(nameof(this.LogfileName)); this.RaisePropertyChanged(nameof(this.LogfileNameWithoutParent)); } XIVLog.RefreshPCNameDictionary(); while (LogQueue.TryDequeue(out XIVLog xivlog)) { if (this.currentZoneName != xivlog.ZoneName) { this.currentZoneName = xivlog.ZoneName; this.wipeoutCounter = 1; this.fileNo++; isNeedsFlush = true; } if (xivlog.Log.Contains("wipeout") || xivlog.Log.Contains("の攻略を終了した。")) { this.wipeoutCounter++; this.fileNo++; isNeedsFlush = true; } this.writeBuffer.AppendLine(xivlog.ToCSVLine()); Thread.Yield(); } if (isNeedsFlush || this.isForceFlush || this.writeBuffer.Length > 5000) { this.writter.Write(this.writeBuffer.ToString()); this.writeBuffer.Clear(); if (isNeedsFlush || this.isForceFlush) { this.isForceFlush = false; this.lastFlushTimestamp = DateTime.Now; this.writter?.Flush(); } } } }
private void InitTask() { // FFXIV.Framework.config を読み込ませる lock (FFXIV.Framework.Config.ConfigBlocker) { _ = FFXIV.Framework.Config.Instance; } var config = Config.Instance; // WriteIntervalの初期値をマイグレーションする if (config.WriteInterval >= 30) { config.WriteInterval = Config.WriteIntervalDefault; } this.dumpLogTask = ThreadWorker.Run( doWork, TimeSpan.FromSeconds(config.WriteInterval).TotalMilliseconds, "XIVLog Worker", ThreadPriority.Lowest); ActGlobals.oFormActMain.OnLogLineRead -= this.OnLogLineRead; ActGlobals.oFormActMain.OnLogLineRead += this.OnLogLineRead; void doWork() { var isNeedsFlush = false; if (string.IsNullOrEmpty(config.OutputDirectory)) { Thread.Sleep(TimeSpan.FromSeconds(config.WriteInterval)); return; } if (LogQueue.IsEmpty) { if ((DateTime.Now - this.lastWroteTimestamp).TotalSeconds > 10) { this.lastWroteTimestamp = DateTime.MaxValue; isNeedsFlush = true; } else { if (!this.isForceFlush) { Thread.Sleep(TimeSpan.FromSeconds(config.WriteInterval)); return; } } } if ((DateTime.Now - this.lastFlushTimestamp).TotalSeconds >= config.FlushInterval) { isNeedsFlush = true; } if (this.currentLogfileName != this.LogfileName) { if (this.writter != null) { this.writter.Flush(); this.writter.Close(); this.writter.Dispose(); } if (!Directory.Exists(config.OutputDirectory)) { Directory.CreateDirectory(config.OutputDirectory); } this.writter = new StreamWriter( new FileStream( this.LogfileName, FileMode.Append, FileAccess.Write, FileShare.Read, 64 * 1024), new UTF8Encoding(config.WithBOM)); this.currentLogfileName = this.LogfileName; this.RaisePropertyChanged(nameof(this.LogfileName)); this.RaisePropertyChanged(nameof(this.LogfileNameWithoutParent)); } XIVLog.RefreshPCNameDictionary(); while (LogQueue.TryDequeue(out XIVLog xivlog)) { if (this.currentZoneName != xivlog.ZoneName) { this.currentZoneName = xivlog.ZoneName; this.wipeoutCounter = 1; this.fileNo++; isNeedsFlush = true; } if (StopLoggingKeywords.Any(x => xivlog.Log.Contains(x))) { this.wipeoutCounter++; this.fileNo++; isNeedsFlush = true; } // ログをParseする xivlog.Parse(); this.writter.WriteLine(xivlog.ToCSVLine()); this.lastWroteTimestamp = DateTime.Now; Thread.Yield(); } if (isNeedsFlush || this.isForceFlush) { if (isNeedsFlush || this.isForceFlush) { this.isForceFlush = false; this.lastFlushTimestamp = DateTime.Now; this.writter?.Flush(); } } } }