private void NpcDamageManager_EventsPlayerAttackProcessed(object sender, DamageProcessedEvent e) { lock (StatsLock) { var activeFights = DataManager.Instance.GetActiveFights(); // reset if stats if first time or first new damage is received if (Stats == null || (activeFights.Count == 1 && activeFights[0].DamageBlocks.Count == 1 && activeFights[0].DamageBlocks[0].Actions.Count == 1 && CurrentDamageSelectionMode == 0)) { Stats = new OverlayDamageStats { BeginTime = e.BeginTime, RaidStats = new PlayerStats() }; } Stats.ActiveFights = activeFights; var timeout = CurrentDamageSelectionMode == 0 ? DataManager.FIGHTTIMEOUT : CurrentDamageSelectionMode; DamageStatsManager.Instance.ComputeOverlayDamageStats(e.Record, e.BeginTime, timeout, Stats); if (UpdateTimer != null && !UpdateTimer.IsEnabled) { UpdateTimer.Start(); } } }
private void HandleDamageProcessed(object sender, DamageProcessedEvent processed) { if (LastFightProcessTime != processed.BeginTime) { DataManager.Instance.CheckExpireFights(processed.BeginTime); } if (IsValidAttack(processed.Record, out bool defender)) { if (!double.IsNaN(LastFightProcessTime)) { var seconds = processed.BeginTime - LastFightProcessTime; if (seconds >= GROUP_TIMEOUT) { CurrentGroupID++; } } string origTimeString = processed.OrigTimeString.Substring(4, 15); Fight fight = Get(processed.Record, processed.BeginTime, origTimeString, defender); if (defender) { Helpers.AddAction(fight.DamageBlocks, processed.Record, processed.BeginTime); AddPlayerTime(fight, processed.Record, processed.Record.Attacker, processed.BeginTime); fight.Total += processed.Record.Total; fight.BeginDamageTime = double.IsNaN(fight.BeginDamageTime) ? processed.BeginTime : fight.BeginDamageTime; fight.LastDamageTime = processed.BeginTime; fight.DamageHits++; } else { Helpers.AddAction(fight.TankingBlocks, processed.Record, processed.BeginTime); AddPlayerTime(fight, processed.Record, processed.Record.Defender, processed.BeginTime); fight.BeginTankingTime = double.IsNaN(fight.BeginTankingTime) ? processed.BeginTime : fight.BeginTankingTime; fight.LastTankingTime = processed.BeginTime; fight.TankHits++; } fight.LastTime = processed.BeginTime; LastFightProcessTime = processed.BeginTime; var ttl = fight.LastTime - fight.BeginTime + 1; fight.TooltipText = string.Format(CultureInfo.CurrentCulture, "#Hits To Players: {0}, #Hits From Players: {1}, Time Alive: {2}s", fight.TankHits, fight.DamageHits, ttl); DataManager.Instance.UpdateIfNewFightMap(fight.CorrectMapKey, fight); if (defender) { EventsPlayerAttackProcessed?.Invoke(processed.Record, processed); } } }
private void NpcDamageManager_EventsPlayerAttackProcessed(object sender, DamageProcessedEvent e) { lock (StatsLock) { Stats = DamageStatsManager.Instance.ComputeOverlayDamageStats(e.Record, e.BeginTime, Stats); if (UpdateTimer != null && !UpdateTimer.IsEnabled) { UpdateTimer.Start(); } } }
private void HandleDamageProcessed(object sender, DamageProcessedEvent processed) { if (IsValidAttack(processed.Record, processed.BeginTime, out bool defender)) { if (!double.IsNaN(LastUpdateTime)) { var seconds = processed.BeginTime - LastUpdateTime; if (seconds >= GROUP_TIMEOUT) { CurrentGroupID++; } } string origTimeString = processed.OrigTimeString.Substring(4, 15); Fight fight = Get(processed.Record, processed.BeginTime, origTimeString, defender); if (defender) { Helpers.AddAction(fight.DamageBlocks, processed.Record, processed.BeginTime); fight.Total += processed.Record.Total; } else { Helpers.AddAction(fight.TankingBlocks, processed.Record, processed.BeginTime); } fight.LastTime = processed.BeginTime; LastUpdateTime = processed.BeginTime; DataManager.Instance.UpdateIfNewFightMap(fight.CorrectMapKey, fight); if (defender) { EventsPlayerAttackProcessed?.Invoke(processed.Record, processed); } } }
public static void Process(LineData lineData) { string line = lineData.Line; try { var actionPart = line.Substring(LineParsing.ACTIONINDEX); var timeString = line.Substring(1, 24); var currentTime = DateUtil.ParseDate(timeString); // handle Slain queue if (!double.IsNaN(SlainTime) && currentTime > SlainTime) { SlainQueue.ForEach(slain => { if (!DataManager.Instance.RemoveActiveFight(slain) && char.IsUpper(slain[0])) { DataManager.Instance.RemoveActiveFight(char.ToLower(slain[0], CultureInfo.CurrentCulture) + slain.Substring(1)); } }); SlainQueue.Clear(); SlainTime = double.NaN; } int index; if (line.Length >= 40 && line.IndexOf(" damage", LineParsing.ACTIONINDEX + 13, StringComparison.Ordinal) > -1) { DamageRecord record = ParseDamage(actionPart); if (record != null) { DamageProcessedEvent e = new DamageProcessedEvent() { Record = record, OrigTimeString = timeString, BeginTime = currentTime }; EventsDamageProcessed?.Invoke(record, e); if (record.Type == Labels.DD) { if (SpecialCodes.Keys.FirstOrDefault(special => !string.IsNullOrEmpty(record.SubType) && record.SubType.Contains(special)) is string key && !string.IsNullOrEmpty(key)) { DataManager.Instance.AddSpecial(new SpecialSpell() { Code = SpecialCodes[key], Player = record.Attacker, BeginTime = currentTime }); } } } } else if (line.Length >= 49 && (index = line.IndexOf(", but miss", LineParsing.ACTIONINDEX + 22, StringComparison.Ordinal)) > -1) { DamageRecord record = ParseMiss(actionPart, index); if (record != null) { DamageProcessedEvent e = new DamageProcessedEvent() { Record = record, OrigTimeString = timeString, BeginTime = currentTime }; EventsDamageProcessed?.Invoke(record, e); } } else if (line.Length > 35 && line.EndsWith(" died.", StringComparison.Ordinal)) { var test = line.Substring(LineParsing.ACTIONINDEX, line.Length - LineParsing.ACTIONINDEX - 6); if (!SlainQueue.Contains(test) && DataManager.Instance.GetFight(test) != null) { SlainQueue.Add(test); SlainTime = currentTime; } if (test == "You") { test = ConfigUtil.PlayerName; DataManager.Instance.ClearActiveAdps(); } var death = new DeathRecord() { Killed = string.Intern(test), Killer = "" }; DataManager.Instance.AddDeathRecord(death, currentTime); } else if (line.Length > 30 && line.Length < 102 && (index = line.IndexOf(" slain ", LineParsing.ACTIONINDEX, StringComparison.Ordinal)) > -1) { HandleSlain(actionPart, currentTime, index - LineParsing.ACTIONINDEX); } } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) #pragma warning restore CA1031 // Do not catch general exception types { if (e is ArgumentNullException || e is NullReferenceException || e is ArgumentOutOfRangeException || e is ArgumentException) { LOG.Error(e); } } }
public static void Process(LineData lineData) { string line = lineData.Line; try { var actionPart = line.Substring(LineParsing.ACTIONINDEX); var timeString = line.Substring(1, 24); var currentTime = DateUtil.ParseDate(timeString); // handle Slain queue if (!double.IsNaN(SlainTime) && currentTime > SlainTime) { SlainQueue.ForEach(slain => { if (!DataManager.Instance.RemoveActiveFight(slain) && char.IsUpper(slain[0])) { DataManager.Instance.RemoveActiveFight(char.ToLower(slain[0], CultureInfo.CurrentCulture) + slain.Substring(1)); } }); SlainQueue.Clear(); SlainTime = double.NaN; } int index; if (line.Length >= 40 && line.IndexOf(" damage", LineParsing.ACTIONINDEX + 13, StringComparison.Ordinal) > -1) { DamageRecord record = ParseDamage(actionPart); if (record != null) { DamageProcessedEvent e = new DamageProcessedEvent() { Record = record, OrigTimeString = timeString, BeginTime = currentTime }; EventsDamageProcessed?.Invoke(record, e); if (record.Type == Labels.DD) { if (SpecialCodes.Keys.FirstOrDefault(special => !string.IsNullOrEmpty(record.SubType) && record.SubType.Contains(special)) is string key && !string.IsNullOrEmpty(key)) { DataManager.Instance.AddSpecial(new SpecialSpell() { Code = SpecialCodes[key], Player = record.Attacker, BeginTime = currentTime }); } } } } else if (line.Length >= 49 && (index = line.IndexOf(", but miss", LineParsing.ACTIONINDEX + 22, StringComparison.Ordinal)) > -1) { DamageRecord record = ParseMiss(actionPart, index); if (record != null) { DamageProcessedEvent e = new DamageProcessedEvent() { Record = record, OrigTimeString = timeString, BeginTime = currentTime }; EventsDamageProcessed?.Invoke(record, e); } } else if (line.Length > 30 && line.Length < 102 && (index = line.IndexOf(" slain ", LineParsing.ACTIONINDEX, StringComparison.Ordinal)) > -1) { HandleSlain(actionPart, currentTime, index - LineParsing.ACTIONINDEX); } else if (line.Length >= 40 && line.Length < 110 && (index = line.IndexOf(" resisted your ", LineParsing.ACTIONINDEX, StringComparison.Ordinal)) > -1) { var optionalIndex = index - LineParsing.ACTIONINDEX; // [Mon Feb 11 20:00:28 2019] An inferno flare resisted your Frostreave Strike III! string defender = actionPart.Substring(0, optionalIndex); string spell = actionPart.Substring(optionalIndex + 15, actionPart.Length - optionalIndex - 15 - 1); DataManager.Instance.AddResistRecord(new ResistRecord() { Spell = spell }, currentTime); } } catch (ArgumentNullException ne) { LOG.Error(ne); } catch (NullReferenceException nr) { LOG.Error(nr); } catch (ArgumentOutOfRangeException aor) { LOG.Error(aor); } catch (ArgumentException ae) { LOG.Error(ae); } }
private void HandleDamageProcessed(object sender, DamageProcessedEvent processed) { if (LastFightProcessTime != processed.BeginTime) { DataManager.Instance.CheckExpireFights(processed.BeginTime); ValidCombo.Clear(); if (processed.BeginTime - LastFightProcessTime > RECENTSPELLTIME) { RecentSpellCache.Clear(); } } // cache recent player spells to help determine who the caster was var isAttackerPlayer = PlayerManager.Instance.IsPetOrPlayer(processed.Record.Attacker) || processed.Record.Attacker == Labels.RS; if (isAttackerPlayer && (processed.Record.Type == Labels.DD || processed.Record.Type == Labels.DOT || processed.Record.Type == Labels.PROC)) { RecentSpellCache[processed.Record.SubType] = true; } string comboKey = processed.Record.Attacker + "=" + processed.Record.Defender; if (ValidCombo.TryGetValue(comboKey, out bool defender) || IsValidAttack(processed.Record, isAttackerPlayer, out defender)) { ValidCombo[comboKey] = defender; bool isNonTankingFight = false; string origTimeString = processed.OrigTimeString.Substring(4, 15); // fix for unknown spells having a good name to work from if (processed.Record.AttackerIsSpell && defender) { processed.Record.Attacker = Labels.UNK; } Fight fight = Get(processed.Record, processed.BeginTime, origTimeString, defender); if (defender) { Helpers.AddAction(fight.DamageBlocks, processed.Record, processed.BeginTime); AddPlayerTime(fight, processed.Record, processed.Record.Attacker, processed.BeginTime); fight.BeginDamageTime = double.IsNaN(fight.BeginDamageTime) ? processed.BeginTime : fight.BeginDamageTime; fight.LastDamageTime = processed.BeginTime; if (StatsUtil.IsHitType(processed.Record.Type)) { fight.DamageHits++; fight.Total += processed.Record.Total; isNonTankingFight = fight.DamageHits == 1; var attacker = processed.Record.AttackerOwner ?? processed.Record.Attacker; if (fight.PlayerTotals.TryGetValue(attacker, out FightTotalDamage total)) { total.Damage += (processed.Record.Type == Labels.BANE) ? 0 : processed.Record.Total; total.DamageWithBane += processed.Record.Total; total.Name = processed.Record.Attacker; total.PetOwner = total.PetOwner ?? processed.Record.AttackerOwner; total.UpdateTime = processed.BeginTime; } else { fight.PlayerTotals[attacker] = new FightTotalDamage { Damage = (processed.Record.Type == Labels.BANE) ? 0 : processed.Record.Total, DamageWithBane = processed.Record.Total, Name = processed.Record.Attacker, PetOwner = processed.Record.AttackerOwner, UpdateTime = processed.BeginTime, BeginTime = processed.BeginTime }; } SpellDamageStats stats = null; var spellKey = processed.Record.Attacker + "++" + processed.Record.SubType; if (processed.Record.Type == Labels.DD) { if (!fight.DDDamage.TryGetValue(spellKey, out stats)) { stats = new SpellDamageStats { Caster = processed.Record.Attacker, Spell = processed.Record.SubType }; fight.DDDamage[spellKey] = stats; } } else if (processed.Record.Type == Labels.DOT) { if (!fight.DoTDamage.TryGetValue(spellKey, out stats)) { stats = new SpellDamageStats { Caster = processed.Record.Attacker, Spell = processed.Record.SubType }; fight.DoTDamage[spellKey] = stats; } } if (stats != null) { stats.Count += 1; stats.Max = Math.Max(processed.Record.Total, stats.Max); stats.Total += processed.Record.Total; } // only a pet can 'hit' with a Flurry since players only crush/slash/punch/pierce with main hand weapons if (processed.Record.AttackerOwner == null && processed.Record.Type == Labels.MELEE && processed.Record.SubType == "Hits" && LineModifiersParser.IsFlurry(processed.Record.ModifiersMask)) { PlayerManager.Instance.AddVerifiedPet(processed.Record.Attacker); } } } else { Helpers.AddAction(fight.TankingBlocks, processed.Record, processed.BeginTime); AddPlayerTime(fight, processed.Record, processed.Record.Defender, processed.BeginTime); fight.BeginTankingTime = double.IsNaN(fight.BeginTankingTime) ? processed.BeginTime : fight.BeginTankingTime; fight.LastTankingTime = processed.BeginTime; if (StatsUtil.IsHitType(processed.Record.Type)) { fight.TankHits++; } } fight.LastTime = processed.BeginTime; LastFightProcessTime = processed.BeginTime; var ttl = fight.LastTime - fight.BeginTime + 1; fight.TooltipText = string.Format(CultureInfo.CurrentCulture, "#Hits To Players: {0}, #Hits From Players: {1}, Time Alive: {2}s", fight.TankHits, fight.DamageHits, ttl); DataManager.Instance.UpdateIfNewFightMap(fight.CorrectMapKey, fight, isNonTankingFight); } }
private static bool CreateDamageRecord(LineData lineData, string[] split, int stop, string attacker, string defender, uint damage, string type, string subType, SpellResist resist = SpellResist.UNDEFINED, bool attackerIsSpell = false) { bool success = false; if (damage != uint.MaxValue && !string.IsNullOrEmpty(type) && !string.IsNullOrEmpty(subType) && !InIgnoreList(defender)) { // Needed to replace 'You' and 'you', etc defender = PlayerManager.Instance.ReplacePlayer(defender, defender); if (string.IsNullOrEmpty(attacker)) { attacker = subType; } else if (attacker.EndsWith("'s corpse", StringComparison.Ordinal)) { attacker = attacker.Substring(0, attacker.Length - 9); } else { // Needed to replace 'You' and 'you', etc attacker = PlayerManager.Instance.ReplacePlayer(attacker, attacker); } if (resist != SpellResist.UNDEFINED && ConfigUtil.PlayerName == attacker && defender != attacker) { DataManager.Instance.UpdateNpcSpellResistStats(defender, resist); } // check for pets HasOwner(attacker, out string attackerOwner); HasOwner(defender, out string defenderOwner); DamageRecord record = new DamageRecord { Attacker = string.Intern(FixName(attacker)), Defender = string.Intern(FixName(defender)), Type = string.Intern(type), SubType = string.Intern(subType), Total = damage, AttackerOwner = attackerOwner != null?string.Intern(attackerOwner) : null, DefenderOwner = defenderOwner != null?string.Intern(defenderOwner) : null, ModifiersMask = -1, AttackerIsSpell = attackerIsSpell }; var currentTime = DateUtil.ParseLogDate(lineData.Line, out string timeString); if (split.Length > stop + 1) { // improve this later so maybe the string doesn't have to be re-joined string modifiers = string.Join(" ", split, stop + 1, split.Length - stop - 1); record.ModifiersMask = LineModifiersParser.Parse(record.Attacker, modifiers.Substring(1, modifiers.Length - 2), currentTime); } if (!double.IsNaN(currentTime)) { // handle old style crits for eqemu if (LastCrit != null && LastCrit.Attacker == record.Attacker && LastCrit.LineData.LineNumber == (lineData.LineNumber - 1)) { var critTime = DateUtil.ParseLogDate(LastCrit.LineData.Line, out string _); if (!double.IsNaN(critTime) && (currentTime - critTime) <= 1) { record.ModifiersMask = (record.ModifiersMask == -1) ? LineModifiersParser.CRIT : record.ModifiersMask | LineModifiersParser.CRIT; } LastCrit = null; } CheckSlainQueue(currentTime); DamageProcessedEvent e = new DamageProcessedEvent() { Record = record, OrigTimeString = timeString, BeginTime = currentTime }; EventsDamageProcessed?.Invoke(record, e); success = true; if (record.Type == Labels.DD && SpecialCodes.Keys.FirstOrDefault(special => !string.IsNullOrEmpty(record.SubType) && record.SubType.Contains(special)) is string key && !string.IsNullOrEmpty(key)) { DataManager.Instance.AddSpecial(new SpecialSpell() { Code = SpecialCodes[key], Player = record.Attacker, BeginTime = currentTime }); } } } return(success); }