/// <summary> /// キャストログを格納する /// </summary> /// <param name="logInfo">ログ情報</param> private void StoreCastStartsUsingLog( XIVLog xivLog) { var match = ConstantKeywords.StartsUsingRegex.Match(xivLog.LogLine); if (!match.Success) { return; } var log = new CombatLog() { TimeStamp = xivLog.DetectTime, Raw = xivLog.LogLine, Actor = match.Groups["actor"].ToString(), Activity = $"starts using {match.Groups["skill"].ToString()}", Skill = match.Groups["skill"].ToString(), LogType = LogTypes.CastStart }; log.Text = log.Skill; log.SyncKeyword = log.RawWithoutTimestamp.Substring(6); if (this.ToStoreActor(log.Actor)) { this.StoreLog(log, xivLog); } }
/// <summary> /// セリフを格納する /// </summary> /// <param name="logInfo">ログ情報</param> private void StoreDialog( XIVLog xivLog) { var match = ConstantKeywords.DialogRegex.Match(xivLog.LogLine); if (!match.Success) { return; } var dialog = match.Groups["dialog"].ToString(); var isSystem = xivLog.LogLine.Contains(":0839"); var log = new CombatLog() { TimeStamp = xivLog.DetectTime, Raw = xivLog.LogLine, Actor = string.Empty, Activity = isSystem ? "System" : "Dialog", LogType = LogTypes.Dialog }; log.Text = null; log.SyncKeyword = log.RawWithoutTimestamp.Substring(8); this.StoreLog(log, xivLog); }
/// <summary> /// 戦闘(分析)を開始する /// </summary> /// <param name="logLine"> /// 対象のログ行</param> private void StartCombat( XIVLog xivLog = null) { lock (this.CurrentCombatLogList) { if (!this.inCombat) { if (!this.isImporting) { this.CurrentCombatLogList.Clear(); this.ActorHPRate.Clear(); this.partyNames = null; this.combatants = null; this.no = 1; } Logger.Write("Start Combat"); // 自分の座標をダンプする LogBuffer.DumpPosition(true); } this.inCombat = true; } this.StoreStartCombat(xivLog); }
/// <summary> /// Addedのログを格納する /// </summary> /// <param name="logInfo">ログ情報</param> private void StoreAddedLog( XIVLog xivLog) { var match = ConstantKeywords.AddedRegex.Match(xivLog.LogLine); if (!match.Success) { return; } var log = new CombatLog() { TimeStamp = xivLog.DetectTime, Raw = xivLog.LogLine, Actor = match.Groups["actor"].ToString(), Activity = $"Added", LogType = LogTypes.Added, }; log.Text = $"Add {log.Actor}"; log.SyncKeyword = log.RawWithoutTimestamp.Substring(0, log.RawWithoutTimestamp.IndexOf('.')); if (this.ToStoreActor(log.Actor)) { this.StoreLog(log, xivLog); } }
/// <summary> /// マーカーログを格納する /// </summary> /// <param name="logInfo">ログ情報</param> private void StoreMarkerLog( XIVLog xivLog) { var log = default(CombatLog); var match = ConstantKeywords.MarkerRegex.Match(xivLog.LogLine); if (match.Success) { // ログなしマーカ var id = match.Groups["id"].ToString(); var target = match.Groups["target"].ToString(); var targetJobName = this.ToNameToJob(target); log = new CombatLog() { TimeStamp = xivLog.DetectTime, Raw = xivLog.LogLine .Replace(id, PCIDPlaceholder) .Replace(target, targetJobName), Activity = $"Marker:{match.Groups["type"].ToString()}", LogType = LogTypes.Marker }; } else { // マーキング match = ConstantKeywords.MarkingRegex.Match(xivLog.LogLine); if (!match.Success) { return; } var target = match.Groups["target"].ToString(); var targetJobName = this.ToNameToJob(target); log = new CombatLog() { TimeStamp = xivLog.DetectTime, Raw = xivLog.LogLine .Replace(target, targetJobName), Activity = $"Marking", LogType = LogTypes.Marker }; } if (log != null) { log.Text = log.Activity; log.SyncKeyword = log.RawWithoutTimestamp; if (this.ToStoreActor(log.Actor)) { this.StoreLog(log, xivLog); } } }
/// <summary> /// 記録用ログを格納する /// </summary> /// <param name="logInfo">ログ情報</param> private void StoreRecordLog( XIVLog xivLog) { var log = new CombatLog() { TimeStamp = xivLog.DetectTime, Raw = xivLog.LogLine, LogType = LogTypes.Unknown }; this.StoreLog(log, xivLog); }
/// <summary> /// ログを格納する /// </summary> /// <param name="log">ログ</param> /// <param name="logLine">ログイベント引数</param> private void StoreLog( CombatLog log, XIVLog xivLog) { var zone = xivLog.ZoneName; zone = string.IsNullOrEmpty(zone) ? "UNKNOWN" : zone; lock (this.CurrentCombatLogList) { // IDを発番する log.ID = this.id; this.id++; // 今回の分析の連番を付与する log.No = this.no; this.no++; // 経過秒を求める var origin = this.CurrentCombatLogList.FirstOrDefault(x => x.IsOrigin); if (origin != null) { var ts = log.TimeStamp - origin.TimeStamp; if (ts.TotalMinutes <= 60 && ts.TotalMinutes >= -60) { log.TimeStampElapted = ts; } } // アクター別の残HP率をセットする if (this.ActorHPRate.ContainsKey(log.Actor)) { log.HPRate = this.ActorHPRate[log.Actor]; } if (!this.CurrentCombatLogList.Any() && log.RawWithoutTimestamp != ConstantKeywords.ImportLog) { log.IsOrigin = true; } // ゾーンを保存する log.Zone = zone; this.CurrentCombatLogList.Add(log); } }
private async void OnLogLineReadAsync(bool isImport, LogLineEventArgs logInfo) { var xivlog = new XIVLog(logInfo); if (string.IsNullOrEmpty(xivlog.Log)) { return; } // 戦利品追加 if (xivlog.Log.IndexOf(STRINGSTOCK.KEY_WORD_SEARCH.GetStringValue()) > -1) { try { xivlog.Log.OutputLog(); //// ロット権利者の検索 await JustCallingAsync(xivlog.Log); } catch (InvalidOperationException error) { //MessageBox.Show(error.Message, // "エラー", // MessageBoxButtons.OK, // MessageBoxIcon.Error); } } // ロット終了 if (xivlog.Log.IndexOf(STRINGSTOCK.KEY_WORD_DICE.GetStringValue()) > -1 && xivlog.Log.IndexOf(STRINGSTOCK.KEY_WORD_LOT.GetStringValue()) > -1) { try { xivlog.Log.OutputLog(); await JustCallingLotAsync(xivlog.Log); } catch (Exception e) { //MessageBox.Show(e.Message, // "エラー", // MessageBoxButtons.OK, // MessageBoxIcon.Error); } } }
/// <summary> /// 戦闘(分析)を終了する /// </summary> /// <param name="logLine"> /// 対象のログ行</param> private void EndCombat( XIVLog xivLog = null) { lock (this.CurrentCombatLogList) { if (this.inCombat) { this.inCombat = false; if (xivLog != null) { this.StoreEndCombat(xivLog); } this.AutoSaveToSpreadsheetAsync(); ChatLogWorker.Instance?.Write(true); Logger.Write("End Combat"); } } }
/// <summary> /// Effectログを格納する /// </summary> /// <param name="logInfo">ログ情報</param> private void StoreEffectLog( XIVLog xivLog) { var match = ConstantKeywords.EffectRegex.Match(xivLog.LogLine); if (!match.Success) { return; } var victim = match.Groups["victim"].ToString(); var victimJobName = this.ToNameToJob(victim); var effect = match.Groups["effect"].ToString(); var actor = match.Groups["actor"].ToString(); var duration = match.Groups["duration"].ToString(); var log = new CombatLog() { TimeStamp = xivLog.DetectTime, Raw = xivLog.LogLine .Replace(victim, victimJobName), Actor = actor, Activity = $"effect {effect}", LogType = LogTypes.Effect }; log.Text = log.Activity; log.SyncKeyword = log.RawWithoutTimestamp; if (victim != actor) { if (this.ToStoreActor(log.Actor)) { this.StoreLog(log, xivLog); } } }
/// <summary> /// 戦闘開始を格納する /// </summary> /// <param name="logInfo">ログ情報</param> private void StoreStartCombat( XIVLog xivLog) { var match = ConstantKeywords.CombatStartRegex.Match(xivLog.LogLine); if (!match.Success) { return; } var discription = match.Groups["discription"].ToString(); var log = new CombatLog() { TimeStamp = xivLog.DetectTime, Raw = xivLog.LogLine, Actor = string.Empty, Activity = LogTypes.CombatStart.ToString(), LogType = LogTypes.CombatStart }; this.StoreLog(log, xivLog); }
/// <summary> /// HP率のログを格納する /// </summary> /// <param name="logInfo">ログ情報</param> private void StoreHPRateLog( XIVLog xivLog) { var match = ConstantKeywords.HPRateRegex.Match(xivLog.LogLine); if (!match.Success) { return; } var actor = match.Groups["actor"].ToString(); if (this.ToStoreActor(actor)) { decimal hprate; if (!decimal.TryParse(match.Groups["hprate"].ToString(), out hprate)) { hprate = 0m; } this.ActorHPRate[actor] = hprate; } }
/// <summary> /// ネットワークログを格納する /// </summary> /// <param name="logInfo">ログ情報</param> /// <param name="keywordType">キーワードのタイプ</param> private void StoreNewwork( XIVLog xivLog, KewordTypes keywordType) { var log = default(CombatLog); var targetLogLine = xivLog.LogLine.Substring(15); var match = keywordType == KewordTypes.NetworkAbility ? ConstantKeywords.NetworkAbility.Match(targetLogLine) : ConstantKeywords.NetworkAOEAbility.Match(targetLogLine); if (match.Success) { var actorID = match.Groups["id"].ToString(); var victimID = match.Groups["victim_id"].ToString(); var actor = match.Groups["actor"].ToString(); var action = match.Groups["skill"].ToString(); var victim = match.Groups["victim"].ToString(); var victimJobName = this.ToNameToJob(victim); if (IgnoreNewworkActions.Any(x => string.Equals(x, action, StringComparison.OrdinalIgnoreCase))) { return; } var raw = xivLog.LogLine.Substring(0, 15) + match.Value; raw = raw .Replace(actorID, ActorIDPlaceholder) .Replace(victimID, PCIDPlaceholder); if (!string.IsNullOrEmpty(victim)) { raw = raw.Replace(victim, victimJobName); } log = new CombatLog() { TimeStamp = xivLog.DetectTime, Raw = raw, Actor = actor, Skill = action, Activity = keywordType == KewordTypes.NetworkAbility ? $"{action} Sign" : $"{action} Sign-AOE", LogType = keywordType == KewordTypes.NetworkAbility ? LogTypes.NetworkAbility : LogTypes.NetworkAOEAbility, }; if (!this.ToStoreActor(log.Actor)) { return; } } if (log != null) { if (this.CurrentCombatLogList.Any(x => Math.Abs((x.TimeStamp - log.TimeStamp).TotalSeconds) <= 1.0 && x.RawWithoutTimestamp == log.RawWithoutTimestamp)) { return; } log.Text = log.Activity; log.SyncKeyword = log.RawWithoutTimestamp; this.StoreLog(log, xivLog); } }
/// <summary> /// ログ行を分析する /// </summary> /// <param name="xivLog">ログ行</param> private void AnalyzeLogLine( XIVLog xivLog) { if (xivLog == null) { return; } // ログを分類する var category = analyzeLogLine(xivLog.LogLine, ConstantKeywords.Keywords); switch (category) { case KewordTypes.Record: if (this.inCombat) { this.StoreRecordLog(xivLog); } break; case KewordTypes.Pet: break; case KewordTypes.Cast: if (this.inCombat) { this.StoreCastLog(xivLog); } break; case KewordTypes.CastStartsUsing: /* * starts using は準備動作とかぶるので無視する * if (this.inCombat) * { * this.StoreCastStartsUsingLog(log); * } */ break; case KewordTypes.Action: if (this.inCombat) { this.StoreActionLog(xivLog); } break; case KewordTypes.Effect: if (this.inCombat) { this.StoreEffectLog(xivLog); } break; case KewordTypes.Marker: if (this.inCombat) { this.StoreMarkerLog(xivLog); } break; case KewordTypes.HPRate: if (this.inCombat) { this.StoreHPRateLog(xivLog); } break; case KewordTypes.Added: if (this.inCombat) { this.StoreAddedLog(xivLog); } break; case KewordTypes.NetworkAbility: case KewordTypes.NetworkAOEAbility: if (this.inCombat) { this.StoreNewwork(xivLog, category); } break; case KewordTypes.Dialogue: if (this.inCombat) { this.StoreDialog(xivLog); } break; case KewordTypes.Start: this.StartCombat(xivLog); break; case KewordTypes.End: case KewordTypes.AnalyzeEnd: this.EndCombat(xivLog); break; default: break; } KewordTypes analyzeLogLine(string log, IList <AnalyzeKeyword> keywords) { var key = ( from x in keywords where log.ContainsIgnoreCase(x.Keyword) select x).FirstOrDefault(); return(key != null ? key.Category : KewordTypes.Unknown); } }