Example #1
0
 internal S_DESPAWN_NPC(SDespawnNpc message)
 {
     PacketProcessor.Instance.AbnormalityTracker.Update(message);
     NotifyProcessor.Instance.DespawnNpc(message);
     DataExporter.AutomatedExport(message, PacketProcessor.Instance.AbnormalityStorage);
     RichPresence.Instance.DespawnNpc(message);
 }
Example #2
0
 internal S_DESPAWN_NPC(SDespawnNpc message)
 {
     PacketProcessor.Instance.AbnormalityTracker.Update(message);
     NotifyProcessor.Instance.DespawnNpc(message);
     DataExporter.AutomatedExport(message, PacketProcessor.Instance.AbnormalityStorage);
     RichPresence.Instance.DespawnNpc(message);
     PacketProcessor.Instance.InvokeGeneralDataDisplayChanged(false, message.Npc);
 }
Example #3
0
        public void HasReset(SDespawnNpc message)
        {
            var entity = GetActorEntity(message.Npc);

            if (entity == null)
            {
                return;
            }
            _hasReset.Add(entity);
        }
Example #4
0
        public static void AutomatedExport(SDespawnNpc despawnNpc, AbnormalityStorage abnormality)
        {
            if (!despawnNpc.Dead)
            {
                return;
            }

            var entity = (NpcEntity)DamageTracker.Instance.GetEntity(despawnNpc.Npc);

            AutomatedExport(entity, abnormality);
        }
Example #5
0
 internal void DespawnNpc(SDespawnNpc message)
 {
     HudManager.Instance.RemoveBoss(message);
     if (_lastBosses.ContainsKey(message.Npc))
     {
         _lastBosses.Remove(message.Npc);
     }
     if (message.Npc == _lastBossMeterUser)
     {
         _lastBossMeterUser   = null;
         _lastBossHpMeterUser = 0;
     }
 }
Example #6
0
        public void StopAggro(SDespawnNpc aggro)
        {
            var time   = aggro.Time.Ticks;
            var entity = EntityTracker.GetOrNull(aggro.Npc) as NpcEntity;

            if (entity == null)
            {
                return;                 // Strange, but seems there are not only NPC or something wrong with trackers
            }
            if (AbnormalityStorage.Last(entity) != null)
            {
                AbnormalityStorage.AggroEnd(AbnormalityStorage.Last(entity), entity, time);
                AbnormalityStorage.LastAggro[entity] = null;
            }
        }
Example #7
0
        private static void ToTeraDpsApi(EncounterBase teradpsData, SDespawnNpc despawnNpc)
        {
            if (
                //string.IsNullOrEmpty(BasicTeraData.Instance.WindowData.TeraDpsToken)
                //|| string.IsNullOrEmpty(BasicTeraData.Instance.WindowData.TeraDpsUser)
                //||
                !BasicTeraData.Instance.WindowData.SiteExport)
            {
                return;
            }

            var entity = DamageTracker.Instance.GetEntity(despawnNpc.Npc);

            /*
             * Validation, without that, the server cpu will be burning \o
             */
            var areaId = int.Parse(teradpsData.areaId);

            if (
                areaId != 886 &&
                //areaId != 467 &&
                //areaId != 767 &&
                //areaId != 768 &&
                //areaId != 470 &&
                areaId != 468
                //areaId != 770 &&
                //areaId != 769 &&
                //areaId != 916 &&
                //areaId != 969 &&
                //areaId != 970 &&
                //areaId != 950
                )
            {
                return;
            }

            //if (int.Parse(teradpsData.partyDps) < 2000000 && areaId != 468)
            //{
            //    return;
            //}

            var json = JsonConvert.SerializeObject(teradpsData,
                                                   new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            });

            SendTeraDpsIo((NpcEntity)entity, json, 3);
        }
Example #8
0
        public static void Export(SDespawnNpc despawnNpc, AbnormalityStorage abnormality)
        {
            var stats = GenerateStats(despawnNpc, abnormality);

            if (stats == null)
            {
                return;
            }
            var sendThread = new Thread(() => {
                ToTeraDpsApi(stats.BaseStats, despawnNpc);
                ExcelExport.ExcelSave(stats);
                ToAnonymousStatistics(stats.BaseStats);
            });

            sendThread.Start();
        }
Example #9
0
        public void DespawnNpc(SDespawnNpc message)
        {
            NpcEntity boss = _bosses.Find(entity => entity.Id == message.NPC);

            if (boss == null)
            {
                return;
            }

            _bosses.Remove(boss);
            _bossHps.Remove(boss.Id);
            if (_bosses.Count == 0)
            {
                _fightStarted = null;
            }

            UpdatePresence();
        }
Example #10
0
        public static void Export(SDespawnNpc despawnNpc, AbnormalityStorage abnormality)
        {
            if (!despawnNpc.Dead) return;

            var entity = (NpcEntity)DamageTracker.Instance.GetEntity(despawnNpc.Npc);
            if (entity==null) return;// killing mob spawned by missed packet
            var stats = GenerateStats(entity, abnormality);
            if (stats == null)
            {
                return;
            }
            var sendThread = new Thread(() =>
            {
                ToTeraDpsApi(stats.BaseStats, entity);
                ExcelExport.ExcelSave(stats, NetworkController.Instance.EntityTracker.MeterUser.Name);
                ToAnonymousStatistics(stats.BaseStats);
            });
            sendThread.Start();
        }
Example #11
0
 internal void DespawnNpc(SDespawnNpc message)
 {
     HudManager.Instance.RemoveBoss(message);
     if (_lastBosses.ContainsKey(message.Npc))
     {
         _lastBosses.Remove(message.Npc);
     }
     if (message.Npc == _lastBossMeterUser)
     {
         _lastBossMeterUser   = null;
         _lastBossHpMeterUser = 0;
     }
     if (!_lastBosses.Any(x => x.Value > 0))
     {
         if (BasicTeraData.Instance.EventsData.MissingAbnormalities?.Keys != null)
         {
             foreach (var e in BasicTeraData.Instance.EventsData.MissingAbnormalities.Keys)
             {
                 e.NextChecks = new Dictionary <EntityId, DateTime>();
             }
         }
     }
 }
Example #12
0
        public static void Export(SDespawnNpc despawnNpc, AbnormalityStorage abnormality)
        {
            if (!despawnNpc.Dead)
            {
                return;
            }

            var entity = (NpcEntity)DamageTracker.Instance.GetEntity(despawnNpc.Npc);

            var stats = GenerateStats(entity, abnormality);

            if (stats == null)
            {
                return;
            }
            var sendThread = new Thread(() =>
            {
                ToTeraDpsApi(stats.BaseStats, despawnNpc);
                ExcelExport.ExcelSave(stats, NetworkController.Instance.EntityTracker.MeterUser.Name);
                ToAnonymousStatistics(stats.BaseStats);
            });

            sendThread.Start();
        }
 public void DeleteAbnormality(SDespawnNpc message)
 {
     DeleteAbnormality(message.Npc, message.Time.Ticks);
 }
Example #14
0
 public void Update(SDespawnNpc message)
 {
     StopAggro(message);
     DeleteAbnormality(message);
 }
Example #15
0
        private static ExtendedStats GenerateStats(SDespawnNpc despawnNpc, AbnormalityStorage abnormals)
        {
            if (!despawnNpc.Dead)
            {
                return(null);
            }

            var entity = DamageTracker.Instance.GetEntity(despawnNpc.Npc);

            if (!entity.IsBoss || !DamageTracker.Instance.EntitiesStats.ContainsKey(entity))
            {
                return(null);
            }

            bool timedEncounter = false;

            //Nightmare desolarus
            if (entity.NpcE.Info.HuntingZoneId == 759 && entity.NpcE.Info.TemplateId == 1003)
            {
                timedEncounter = true;
            }

            var firstTick = DamageTracker.Instance.EntitiesStats[entity].FirstHit;
            var lastTick  = DamageTracker.Instance.EntitiesStats[entity].LastHit;
            var interTick = lastTick - firstTick;
            var interval  = interTick / TimeSpan.TicksPerSecond;

            if (interval == 0)
            {
                return(null);
            }
            var totaldamage = DamageTracker.Instance.TotalDamage(entity, timedEncounter);
            var partyDps    = TimeSpan.TicksPerSecond * totaldamage / interTick;

            var teradpsData   = new EncounterBase();
            var extendedStats = new ExtendedStats();
            var stats         = DamageTracker.Instance.GetPlayerStats();
            var _abnormals    = abnormals.Clone(entity.NpcE, firstTick, lastTick);

            extendedStats.Entity      = entity.NpcE;
            extendedStats.BaseStats   = teradpsData;
            extendedStats.FirstTick   = firstTick;
            extendedStats.LastTick    = lastTick;
            teradpsData.areaId        = entity.NpcE.Info.HuntingZoneId + "";
            teradpsData.bossId        = entity.NpcE.Info.TemplateId + "";
            teradpsData.fightDuration = interval + "";
            teradpsData.partyDps      = partyDps + "";
            extendedStats.Debuffs     = _abnormals.Get(entity.NpcE);

            foreach (var debuff in extendedStats.Debuffs)
            {
                long percentage = (debuff.Value.Duration(firstTick, lastTick) * 100 / interTick);
                if (percentage == 0)
                {
                    continue;
                }
                teradpsData.debuffUptime.Add(new KeyValuePair <string, string>(
                                                 debuff.Key.Id + "", percentage + ""
                                                 ));
            }

            foreach (var user in stats)
            {
                var teradpsUser = new Members();
                var damage      = user.Dealt.Damage(entity, timedEncounter);
                teradpsUser.playerTotalDamage = damage + "";

                if (damage <= 0)
                {
                    continue;
                }

                var buffs = _abnormals.Get(user.Player);
                teradpsUser.playerClass           = user.Class.ToString();
                teradpsUser.playerName            = user.Name;
                teradpsUser.playerServer          = BasicTeraData.Instance.Servers.GetServerName(user.Player.ServerId);
                teradpsUser.playerAverageCritRate = user.Dealt.CritRate(entity, timedEncounter) + "";
                teradpsUser.healCrit  = user.IsHealer ? user.Dealt.CritRateHeal(entity, timedEncounter) + "" : null;
                teradpsUser.playerDps = TimeSpan.TicksPerSecond * damage / interTick + "";
                teradpsUser.playerTotalDamagePercentage = user.Dealt.DamageFraction(entity, totaldamage, timedEncounter) + "";

                var death = buffs.Death;
                teradpsUser.playerDeaths        = death.Count(firstTick, lastTick) + "";
                teradpsUser.playerDeathDuration = death.Duration(firstTick, lastTick) / TimeSpan.TicksPerSecond + "";

                var aggro = buffs.Aggro(entity.NpcE);
                teradpsUser.aggro = 100 * aggro.Duration(firstTick, lastTick) / interTick + "";

                foreach (var buff in buffs.Times)
                {
                    long percentage = (buff.Value.Duration(firstTick, lastTick) * 100 / interTick);
                    if (percentage == 0)
                    {
                        continue;
                    }
                    teradpsUser.buffUptime.Add(new KeyValuePair <string, string>(
                                                   buff.Key.Id + "", percentage + ""
                                                   ));
                }
                var serverPlayerName = $"{teradpsUser.playerServer}_{teradpsUser.playerName}";
                extendedStats.PlayerSkills.Add(serverPlayerName, timedEncounter ? user.Dealt.GetSkillsByTime(entity) : user.Dealt.GetSkills(entity));
                extendedStats.PlayerBuffs.Add(serverPlayerName, buffs);
                var notimedskills = NoTimedSkills(extendedStats.PlayerSkills[serverPlayerName]);

                foreach (var skill in notimedskills)
                {
                    var skillLog    = new SkillLog();
                    var skilldamage = skill.Value.Damage;

                    skillLog.skillAverageCrit   = skill.Value.DmgAverageCrit + "";
                    skillLog.skillAverageWhite  = skill.Value.DmgAverageHit + "";
                    skillLog.skillCritRate      = skill.Value.CritRateDmg + "";
                    skillLog.skillDamagePercent = skill.Value.DamagePercentage(entity, timedEncounter) + "";
                    skillLog.skillHighestCrit   = skill.Value.DmgBiggestCrit + "";
                    skillLog.skillHits          = skill.Value.HitsDmg + "";
                    skillLog.skillId            = BasicTeraData.Instance.SkillDatabase.GetSkillByPetName(skill.Key.NpcInfo?.Name, user.Player.RaceGenderClass)?.Id.ToString() ?? skill.Key.SkillId.ElementAt(0).ToString();
                    skillLog.skillLowestCrit    = skill.Value.DmgLowestCrit + "";
                    skillLog.skillTotalDamage   = skilldamage + "";

                    if (skilldamage == 0)
                    {
                        continue;
                    }
                    teradpsUser.skillLog.Add(skillLog);
                }
                teradpsData.members.Add(teradpsUser);
            }
            return(extendedStats);
        }
Example #16
0
        public static void ToTeraDpsApi(SDespawnNpc despawnNpc, DamageTracker damageTracker, EntityTracker entityTracker, TeraData teraData)
        {
            if (!despawnNpc.Dead)
            {
                return;
            }
            var entity = entityTracker.GetOrPlaceholder(despawnNpc.Npc) as NpcEntity;

            if (!(entity?.Info.Boss ?? false))
            {
                return;
            }

            if (!SettingsHelper.Instance.Settings.ExcelExport &&
                (string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsToken) ||
                 string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsUser) ||
                 !SettingsHelper.Instance.Settings.SiteExport)
                )
            {
                return;
            }


            var  abnormals      = damageTracker.Abnormals;
            bool timedEncounter = false;

            //Nightmare desolarus
            if (entity.Info.HuntingZoneId == 759 && entity.Info.TemplateId == 1003)
            {
                timedEncounter = true;
            }

            var firstHit  = damageTracker.StatsByUser.SelectMany(x => x.SkillLog).Where(x => x.Target == entity).Min(x => x.Time as DateTime?) ?? new DateTime(0);
            var lastHit   = damageTracker.StatsByUser.SelectMany(x => x.SkillLog).Where(x => x.Target == entity).Max(x => x.Time as DateTime?) ?? new DateTime(0);
            var firstTick = firstHit.Ticks;
            var lastTick  = lastHit.Ticks;
            var interval  = lastTick - firstTick;
            var seconds   = interval / TimeSpan.TicksPerSecond;

            if (seconds == 0)
            {
                return;
            }
            long totaldamage;

            if (timedEncounter)
            {
                totaldamage =
                    damageTracker.StatsByUser.SelectMany(x => x.SkillLog)
                    .Where(x => x.Time >= firstHit && x.Time <= lastHit)
                    .Sum(x => x.Damage);
            }
            else
            {
                totaldamage =
                    damageTracker.StatsByUser.SelectMany(x => x.SkillLog)
                    .Where(x => x.Target == entity)
                    .Sum(x => x.Damage);
            }

            var partyDps    = TimeSpan.TicksPerSecond * totaldamage / interval;
            var teradpsData = new EncounterBase
            {
                areaId        = entity.Info.HuntingZoneId + "",
                bossId        = entity.Info.TemplateId + "",
                fightDuration = seconds + "",
                partyDps      = partyDps + ""
            };

            foreach (var debuff in abnormals.Get(entity))
            {
                long percentage = debuff.Value.Duration(firstTick, lastTick) * 100 / interval;
                if (percentage == 0)
                {
                    continue;
                }
                teradpsData.debuffUptime.Add(new KeyValuePair <string, string>(
                                                 debuff.Key.Id + "", percentage + ""
                                                 ));
            }

            foreach (var user in damageTracker.StatsByUser)
            {
                var filteredSkillog = timedEncounter
                    ? user.SkillLog.Where(x => x.Time >= firstHit && x.Time <= lastHit).ToList()
                    : user.SkillLog.Where(x => x.Target == entity).ToList();

                long damage = filteredSkillog.Sum(x => x.Damage);
                if (damage <= 0)
                {
                    continue;
                }

                var teradpsUser = new Members();

                teradpsUser.playerTotalDamage = damage + "";
                var buffs = abnormals.Get(user.Player);
                teradpsUser.playerClass           = user.Class.ToString();
                teradpsUser.playerName            = user.Name;
                teradpsUser.playerServer          = SettingsHelper.Instance.BasicTeraData.Servers.GetServerName(user.Player.ServerId);
                teradpsUser.playerAverageCritRate = Math.Round(100 * (double)filteredSkillog.Count(x => x.IsCritical && x.Damage > 0) / filteredSkillog.Count(x => x.Damage > 0), 1) + "";
                teradpsUser.healCrit  = user.Player.IsHealer ? Math.Round(100 * (double)filteredSkillog.Count(x => x.IsCritical && x.Heal > 0) / filteredSkillog.Count(x => x.Heal > 0), 1) + "" : null;
                teradpsUser.playerDps = TimeSpan.TicksPerSecond * damage / interval + "";
                teradpsUser.playerTotalDamagePercentage = damage * 100 / totaldamage + "";

                var death = buffs.Death;
                teradpsUser.playerDeaths        = death.Count(firstTick, lastTick) + "";
                teradpsUser.playerDeathDuration = death.Duration(firstTick, lastTick) / TimeSpan.TicksPerSecond + "";

                var aggro = buffs.Aggro(entity);
                teradpsUser.aggro = 100 * aggro.Duration(firstTick, lastTick) / interval + "";

                foreach (var buff in buffs.Times)
                {
                    long percentage = (buff.Value.Duration(firstTick, lastTick) * 100 / interval);
                    if (percentage == 0)
                    {
                        continue;
                    }
                    teradpsUser.buffUptime.Add(new KeyValuePair <string, string>(
                                                   buff.Key.Id + "", percentage + ""
                                                   ));
                }

                var aggregated = new List <AggregatedSkillResult>();
                var collection = new ThreadSafeObservableCollection <SkillResult>();
                foreach (var skill in filteredSkillog)
                {
                    collection.Add(skill);
                    if (aggregated.All(asr => !skill.IsSameSkillAs(asr)))
                    {
                        aggregated.Add(new AggregatedSkillResult(skill.SkillShortName, skill.IsHeal, AggregationType.Name, collection));
                    }
                }
                foreach (var skill in aggregated)
                {
                    var skillLog    = new SkillLog();
                    var skilldamage = skill.Damage;
                    if (skilldamage == 0)
                    {
                        continue;
                    }

                    skillLog.skillAverageCrit   = skill.AverageCrit + "";
                    skillLog.skillAverageWhite  = skill.AverageWhite + "";
                    skillLog.skillCritRate      = Math.Round(skill.CritRate * 100, 1) + "";
                    skillLog.skillDamagePercent = Math.Round(skill.DamagePercent * 100, 1) + "";
                    skillLog.skillHighestCrit   = skill.HighestCrit + "";
                    skillLog.skillHits          = skill.Hits + "";
                    skillLog.skillId            = teraData.SkillDatabase.GetSkillByPetName(skill.NpcInfo?.Name, user.Player.RaceGenderClass)?.Id.ToString() ?? skill.SkillId.ToString();
                    skillLog.skillLowestCrit    = skill.LowestCrit + "";
                    skillLog.skillTotalDamage   = skilldamage + "";

                    teradpsUser.skillLog.Add(skillLog);
                }
                teradpsData.members.Add(teradpsUser);
            }

            if (SettingsHelper.Instance.Settings.ExcelExport)
            {
                Task.Run(() => ExcelExport.ExcelSave(teradpsData, teraData));
            }
            if (string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsToken) || string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsUser) || !SettingsHelper.Instance.Settings.SiteExport)
            {
                return;
            }

            /*
             * Validation, without that, the server cpu will be burning \o
             */
            var areaId = int.Parse(teradpsData.areaId);

            if (
                areaId != 886 &&
                areaId != 467 &&
                areaId != 767 &&
                areaId != 768 &&
                areaId != 470 &&
                areaId != 468
                )
            {
                return;
            }

            if (int.Parse(teradpsData.partyDps) < 2000000 && areaId != 468)
            {
                return;
            }
            string json = JsonConvert.SerializeObject(teradpsData, new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            });

            Task.Run(() => Send(entity, json, 3));
        }
Example #17
0
 internal S_DESPAWN_NPC(SDespawnNpc message)
 {
     NetworkController.Instance.AbnormalityTracker.Update(message);
     NotifyProcessor.Instance.DespawnNpc(message);
     DataExporter.AutomatedExport(message, NetworkController.Instance.AbnormalityStorage);
 }
Example #18
0
        public static void ToTeraDpsApi(SDespawnNpc despawnNpc, AbnormalityStorage abnormals)
        {
            if (!BasicTeraData.Instance.WindowData.Excel &&
                (string.IsNullOrEmpty(BasicTeraData.Instance.WindowData.TeraDpsToken) || string.IsNullOrEmpty(BasicTeraData.Instance.WindowData.TeraDpsUser)))
            {
                return;
            }

            if (!despawnNpc.Dead)
            {
                return;
            }

            var entity = DamageTracker.Instance.GetEntity(despawnNpc.Npc);

            if (!entity.IsBoss)
            {
                return;
            }

            bool timedEncounter = false;

            //Nightmare desolarus
            if (entity.NpcE.Info.HuntingZoneId == 759 && entity.NpcE.Info.TemplateId == 1003)
            {
                timedEncounter = true;
            }

            var interval = DamageTracker.Instance.Interval(entity);

            if (interval == 0)
            {
                return;
            }
            var stats       = DamageTracker.Instance.GetPlayerStats();
            var firstHit    = DamageTracker.Instance.FirstHit(entity);
            var lastHit     = DamageTracker.Instance.LastHit(entity);
            var entities    = DamageTracker.Instance.GetEntityStats();
            var totaldamage = DamageTracker.Instance.TotalDamage(entity, timedEncounter);
            var partyDps    = DamageTracker.Instance.PartyDps(entity, timedEncounter);

            var teradpsData = new EncounterBase();

            teradpsData.areaId        = entity.NpcE.Info.HuntingZoneId + "";
            teradpsData.bossId        = entity.NpcE.Info.TemplateId + "";
            teradpsData.fightDuration = interval + "";
            teradpsData.partyDps      = partyDps + "";

            foreach (var debuff in abnormals.Get(entity.NpcE))
            {
                long percentage = (debuff.Value.Duration(firstHit, lastHit) * 100 / interval);
                if (percentage == 0)
                {
                    continue;
                }
                teradpsData.debuffUptime.Add(new KeyValuePair <string, string>(
                                                 debuff.Key.Id + "", percentage + ""
                                                 ));
            }

            foreach (var user in stats)
            {
                var teradpsUser = new Members();
                var damage      = user.Dealt.Damage(entity, timedEncounter);
                teradpsUser.playerTotalDamage = damage + "";

                if (damage <= 0)
                {
                    continue;
                }

                var buffs = abnormals.Get(user.Player);
                teradpsUser.playerClass                 = user.Class.ToString();
                teradpsUser.playerName                  = user.Name;
                teradpsUser.playerServer                = BasicTeraData.Instance.Servers.GetServerName(user.Player.ServerId);
                teradpsUser.playerAverageCritRate       = user.Dealt.CritRate(entity, timedEncounter) + "";
                teradpsUser.playerDps                   = user.Dealt.GlobalDps(entity, timedEncounter, interval) + "";
                teradpsUser.playerTotalDamagePercentage = user.Dealt.DamageFraction(entity, totaldamage, timedEncounter) + "";

                var death = buffs.Death;
                teradpsUser.playerDeaths        = death.Count(firstHit, lastHit) + "";
                teradpsUser.playerDeathDuration = death.Duration(firstHit, lastHit) + "";

                foreach (var buff in buffs.Times)
                {
                    long percentage = (buff.Value.Duration(user.Dealt.GetFirstHit(entity), user.Dealt.GetLastHit(entity)) * 100 / interval);
                    if (percentage == 0)
                    {
                        continue;
                    }
                    teradpsUser.buffUptime.Add(new KeyValuePair <string, string>(
                                                   buff.Key.Id + "", percentage + ""
                                                   ));
                }
                Dictionary <Skills.Skill.Skill, SkillStats> notimedskills;
                if (timedEncounter)
                {
                    notimedskills = NoTimedSkills(user.Dealt.GetSkillsByTime(entity));
                }
                else
                {
                    notimedskills = NoTimedSkills(user.Dealt.GetSkills(entity));
                }

                foreach (var skill in notimedskills)
                {
                    var skillLog    = new SkillLog();
                    var skilldamage = skill.Value.Damage;

                    skillLog.skillAverageCrit   = skill.Value.DmgAverageCrit + "";
                    skillLog.skillAverageWhite  = skill.Value.DmgAverageHit + "";
                    skillLog.skillCritRate      = skill.Value.CritRateDmg + "";
                    skillLog.skillDamagePercent = skill.Value.DamagePercentage(entity, timedEncounter) + "";
                    skillLog.skillHighestCrit   = skill.Value.DmgBiggestCrit + "";
                    skillLog.skillHits          = skill.Value.HitsDmg + "";
                    skillLog.skillId            = skill.Key.SkillId.ElementAt(0) + "";
                    skillLog.skillLowestCrit    = skill.Value.DmgLowestCrit + "";
                    skillLog.skillTotalDamage   = skilldamage + "";

                    if (skilldamage == 0)
                    {
                        continue;
                    }
                    teradpsUser.skillLog.Add(skillLog);
                }
                teradpsData.members.Add(teradpsUser);
            }

            if (BasicTeraData.Instance.WindowData.Excel)
            {
                var excelThread = new Thread(() => ExcelExport.ExcelSave(teradpsData));
                excelThread.Start();
            }
            if (string.IsNullOrEmpty(BasicTeraData.Instance.WindowData.TeraDpsToken) || string.IsNullOrEmpty(BasicTeraData.Instance.WindowData.TeraDpsUser))
            {
                return;
            }
            string json       = JsonConvert.SerializeObject(teradpsData);
            var    sendThread = new Thread(() => Send(entity, json, 3));

            sendThread.Start();
            var jsonThread = new Thread(() => JsonExport(json));

            jsonThread.Start();
        }