예제 #1
0
        internal void BuildTotalStats(GenerateStatsOptions options)
        {
            lock (HealingGroups)
            {
                try
                {
                    FireNewStatsEvent(options);
                    Reset();

                    Selected = options.Npcs;
                    Title    = options.Name;

                    Selected.ForEach(fight => RaidTotals.Ranges.Add(new TimeSegment(fight.BeginTankingTime, fight.LastTankingTime)));

                    if (RaidTotals.Ranges.TimeSegments.Count > 0)
                    {
                        // calculate totals first since it can modify the ranges
                        RaidTotals.TotalSeconds = RaidTotals.Ranges.GetTotal();

                        RaidTotals.Ranges.TimeSegments.ForEach(segment =>
                        {
                            var updatedHeals = new List <ActionBlock>();
                            var healedByHealerTimeSegments = new Dictionary <string, Dictionary <string, TimeSegment> >();
                            var healedBySpellTimeSegments  = new Dictionary <string, Dictionary <string, TimeSegment> >();
                            var healerHealedTimeSegments   = new Dictionary <string, Dictionary <string, TimeSegment> >();
                            var healerSpellTimeSegments    = new Dictionary <string, Dictionary <string, TimeSegment> >();
                            DataManager.Instance.GetHealsDuring(segment.BeginTime, segment.EndTime).ForEach(heal =>
                            {
                                var updatedHeal = new ActionBlock()
                                {
                                    BeginTime = heal.BeginTime
                                };
                                foreach (var record in heal.Actions.Cast <HealRecord>())
                                {
                                    if (PlayerManager.Instance.IsPossiblePlayerName(record.Healed) || PlayerManager.Instance.IsPetOrPlayer(record.Healed))
                                    {
                                        bool valid = true;
                                        SpellData spellData;
                                        if (record.SubType != null && (spellData = DataManager.Instance.GetSpellByName(record.SubType)) != null)
                                        {
                                            if (spellData.Target == (byte)SpellTarget.TARGETAE || spellData.Target == (byte)SpellTarget.NEARBYPLAYERSAE ||
                                                spellData.Target == (byte)SpellTarget.TARGETRINGAE)
                                            {
                                                valid = MainWindow.IsAoEHealingEnabled;
                                            }
                                        }

                                        if (valid)
                                        {
                                            updatedHeal.Actions.Add(record);
                                            // store substats and substats2 which is based on the player that was healed
                                            var key = Helpers.CreateRecordKey(record.Type, record.SubType);
                                            StatsUtil.UpdateTimeSegments(null, healedByHealerTimeSegments, record.Healer, record.Healed, heal.BeginTime);
                                            StatsUtil.UpdateTimeSegments(null, healedBySpellTimeSegments, key, record.Healed, heal.BeginTime);
                                            StatsUtil.UpdateTimeSegments(null, healerHealedTimeSegments, record.Healed, record.Healer, heal.BeginTime);
                                            StatsUtil.UpdateTimeSegments(null, healerSpellTimeSegments, key, record.Healer, heal.BeginTime);
                                        }
                                    }
                                }

                                if (updatedHeal.Actions.Count > 0)
                                {
                                    updatedHeals.Add(updatedHeal);
                                }
                            });

                            Parallel.ForEach(healedByHealerTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealedByHealerTimeRanges, kv));
                            Parallel.ForEach(healedBySpellTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealedBySpellTimeRanges, kv));
                            Parallel.ForEach(healerHealedTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealerHealedTimeRanges, kv));
                            Parallel.ForEach(healerSpellTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealerSpellTimeRanges, kv));

                            if (updatedHeals.Count > 0)
                            {
                                HealingGroups.Add(updatedHeals);
                            }
                        });

                        ComputeHealingStats(options);
                    }
                    else if (Selected == null || Selected.Count == 0)
                    {
                        FireNoDataEvent(options, "NONPC");
                    }
                    else
                    {
                        FireNoDataEvent(options, "NODATA");
                    }
                }
#pragma warning disable CA1031 // Do not catch general exception types
                catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
                {
                    if (ex is ArgumentNullException || ex is NullReferenceException || ex is ArgumentOutOfRangeException || ex is ArgumentException || ex is OutOfMemoryException)
                    {
                        LOG.Error(ex);
                    }
                }
            }
        }
예제 #2
0
        internal void BuildTotalStats(GenerateStatsOptions options)
        {
            lock (HealingGroups)
            {
                try
                {
                    FireNewStatsEvent(options);
                    Reset();

                    Selected = options.Npcs.OrderBy(sel => sel.Id).ToList();
                    Title    = options.Name;

                    Selected.ForEach(fight => RaidTotals.Ranges.Add(new TimeSegment(fight.BeginTankingTime, fight.LastTankingTime)));

                    if (RaidTotals.Ranges.TimeSegments.Count > 0)
                    {
                        // calculate totals first since it can modify the ranges
                        RaidTotals.TotalSeconds = RaidTotals.MaxTime = RaidTotals.Ranges.GetTotal();

                        RaidTotals.Ranges.TimeSegments.ForEach(segment =>
                        {
                            var updatedHeals = new List <ActionBlock>();
                            var healedByHealerTimeSegments = new Dictionary <string, Dictionary <string, TimeSegment> >();
                            var healedBySpellTimeSegments  = new Dictionary <string, Dictionary <string, TimeSegment> >();
                            var healerHealedTimeSegments   = new Dictionary <string, Dictionary <string, TimeSegment> >();
                            var healerSpellTimeSegments    = new Dictionary <string, Dictionary <string, TimeSegment> >();

                            double currentTime = double.NaN;
                            Dictionary <string, HashSet <string> > currentSpellCounts = new Dictionary <string, HashSet <string> >();
                            Dictionary <double, Dictionary <string, HashSet <string> > > previousSpellCounts = new Dictionary <double, Dictionary <string, HashSet <string> > >();
                            Dictionary <string, byte> ignoreRecords = new Dictionary <string, byte>();
                            List <ActionBlock> filtered             = new List <ActionBlock>();
                            DataManager.Instance.GetHealsDuring(segment.BeginTime, segment.EndTime).ForEach(heal =>
                            {
                                // copy
                                var newBlock = new ActionBlock {
                                    BeginTime = heal.BeginTime
                                };
                                filtered.Add(newBlock);

                                if (currentSpellCounts.Count > 0)
                                {
                                    previousSpellCounts[currentTime] = currentSpellCounts;
                                }

                                currentTime        = heal.BeginTime;
                                currentSpellCounts = new Dictionary <string, HashSet <string> >();

                                foreach (var timeKey in previousSpellCounts.Keys.ToList())
                                {
                                    if (previousSpellCounts.ContainsKey(timeKey))
                                    {
                                        if (currentTime != double.NaN && (currentTime - timeKey) > 7)
                                        {
                                            previousSpellCounts.Remove(timeKey);
                                        }
                                    }
                                }

                                foreach (var record in heal.Actions.Cast <HealRecord>())
                                {
                                    if (PlayerManager.Instance.IsPetOrPlayer(record.Healed) || PlayerManager.Instance.IsPossiblePlayerName(record.Healed))
                                    {
                                        // if AOEHealing is disabled then filter out AEs
                                        if (!MainWindow.IsAoEHealingEnabled)
                                        {
                                            SpellData spellData;
                                            if (record.SubType != null && (spellData = DataManager.Instance.GetHealingSpellByName(record.SubType)) != null)
                                            {
                                                if (spellData.Target == (byte)SpellTarget.TARGETAE || spellData.Target == (byte)SpellTarget.NEARBYPLAYERSAE ||
                                                    spellData.Target == (byte)SpellTarget.TARGETRINGAE || spellData.Target == (byte)SpellTarget.CASTERPBPLAYERS)
                                                {
                                                    // just skip these entirely if AOEs are turned off
                                                    continue;
                                                }
                                                else if ((spellData.Target == (byte)SpellTarget.CASTERGROUP || spellData.Target == (byte)SpellTarget.TARGETGROUP) && spellData.Mgb)
                                                {
                                                    // need to count group AEs and if more than 6 are seen we need to ignore those
                                                    // casts since they're from MGB and count as an AE
                                                    var key = record.Healer + "|" + record.SubType;
                                                    if (!currentSpellCounts.TryGetValue(key, out HashSet <string> value))
                                                    {
                                                        value = new HashSet <string>();
                                                        currentSpellCounts[key] = value;
                                                    }

                                                    value.Add(record.Healed);

                                                    HashSet <string> totals = new HashSet <string>();
                                                    List <double> temp      = new List <double>();
                                                    foreach (var timeKey in previousSpellCounts.Keys)
                                                    {
                                                        if (previousSpellCounts[timeKey].ContainsKey(key))
                                                        {
                                                            foreach (var item in previousSpellCounts[timeKey][key])
                                                            {
                                                                totals.Add(item);
                                                            }
                                                            temp.Add(timeKey);
                                                        }
                                                    }

                                                    foreach (var item in currentSpellCounts[key])
                                                    {
                                                        totals.Add(item);
                                                    }

                                                    if (totals.Count > 6)
                                                    {
                                                        ignoreRecords[heal.BeginTime + "|" + key] = 1;
                                                        temp.ForEach(timeKey =>
                                                        {
                                                            ignoreRecords[timeKey + "|" + key] = 1;
                                                        });
                                                    }
                                                }
                                            }
                                        }

                                        newBlock.Actions.Add(record);
                                    }
                                }
                            });

                            filtered.ForEach(heal =>
                            {
                                var updatedHeal = new ActionBlock()
                                {
                                    BeginTime = heal.BeginTime
                                };
                                foreach (var record in heal.Actions.Cast <HealRecord>())
                                {
                                    var ignoreKey = heal.BeginTime + "|" + record.Healer + "|" + record.SubType;
                                    if (!ignoreRecords.ContainsKey(ignoreKey))
                                    {
                                        updatedHeal.Actions.Add(record);
                                        // store substats and substats2 which is based on the player that was healed
                                        var key = Helpers.CreateRecordKey(record.Type, record.SubType);
                                        StatsUtil.UpdateTimeSegments(null, healedByHealerTimeSegments, record.Healer, record.Healed, heal.BeginTime);
                                        StatsUtil.UpdateTimeSegments(null, healedBySpellTimeSegments, key, record.Healed, heal.BeginTime);
                                        StatsUtil.UpdateTimeSegments(null, healerHealedTimeSegments, record.Healed, record.Healer, heal.BeginTime);
                                        StatsUtil.UpdateTimeSegments(null, healerSpellTimeSegments, key, record.Healer, heal.BeginTime);
                                    }
                                }

                                if (updatedHeal.Actions.Count > 0)
                                {
                                    updatedHeals.Add(updatedHeal);
                                }
                            });

                            Parallel.ForEach(healedByHealerTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealedByHealerTimeRanges, kv));
                            Parallel.ForEach(healedBySpellTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealedBySpellTimeRanges, kv));
                            Parallel.ForEach(healerHealedTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealerHealedTimeRanges, kv));
                            Parallel.ForEach(healerSpellTimeSegments, kv => StatsUtil.AddSubTimeEntry(HealerSpellTimeRanges, kv));

                            if (updatedHeals.Count > 0)
                            {
                                HealingGroups.Add(updatedHeals);
                            }
                        });

                        ComputeHealingStats(options);
                    }
                    else if (Selected == null || Selected.Count == 0)
                    {
                        FireNoDataEvent(options, "NONPC");
                    }
                    else
                    {
                        FireNoDataEvent(options, "NODATA");
                    }
                }
                catch (Exception ex)
                {
                    LOG.Error(ex);
                }
            }
        }