예제 #1
0
        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();
                }
            }
        }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
 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();
         }
     }
 }
예제 #4
0
        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);
                }
            }
        }
예제 #5
0
        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);
                }
            }
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
        }