Пример #1
0
        private static ExcelHyperLink CreateUserSheet(ExcelWorkbook wb, Members user, TeraData teraData)
        {
            ExcelWorksheet ws  = wb.Worksheets.Add($"{user.playerServer}_{user.playerName}");
            var            rgc = new RaceGenderClass("Common", "Common", user.playerClass);

            ws.DefaultRowHeight      = 30;
            ws.Cells.Style.Font.Size = 14;
            ws.Cells.Style.Font.Name = "Arial";
            AddImage(ws, 1, 1, Invert(new Bitmap(SettingsHelper.Instance.GetImage((PlayerClass)Enum.Parse(typeof(PlayerClass), user.playerClass)))));
            ws.Cells[1, 2].Value                  = $"{user.playerServer}: {user.playerName}";
            ws.Cells[1, 2, 1, 10].Merge           = true;
            ws.Cells[1, 2, 1, 10].Style.Font.Bold = true;
            ws.Cells[2, 2].Value                  = "Skill";
            ws.Cells[2, 3].Value                  = "Damage %";
            ws.Cells[2, 4].Value                  = "Damage";
            ws.Cells[2, 5].Value                  = "Crit %";
            ws.Cells[2, 6].Value                  = "Hits";
            ws.Cells[2, 7].Value                  = "Max Crit";
            ws.Cells[2, 8].Value                  = "Min Crit";
            ws.Cells[2, 9].Value                  = "Avg Crit";
            ws.Cells[2, 10].Value                 = "Avg White";
            int i = 2;

            foreach (var stat in user.skillLog.OrderByDescending(x => long.Parse(x.skillTotalDamage)))
            {
                i++;
                var skill = teraData.SkillDatabase.GetOrNull(rgc, int.Parse(stat.skillId));
                if (skill == null)
                {
                    ws.Cells[i, 1].Value = i - 2;
                    ws.Cells[i, 2].Value = "Some pet skill";
                }
                else
                {
                    ws.Cells[i, 1].Value = i - 2;
                    AddImage(ws, i, 1, BTD.Icons.GetBitmap(skill.IconName));
                    ws.Cells[i, 2].Value = skill.Name;
                }
                ws.Cells[i, 3].Value = double.Parse(stat.skillDamagePercent) / 100;
                ws.Cells[i, 3].Style.Numberformat.Format = "0.0%";
                ws.Cells[i, 4].Value = long.Parse(stat.skillTotalDamage);
                ws.Cells[i, 4].Style.Numberformat.Format = @"#,#0,\k";
                ws.Cells[i, 5].Value = double.Parse(stat.skillCritRate) / 100;
                ws.Cells[i, 5].Style.Numberformat.Format = "0.0%";
                ws.Cells[i, 6].Value = long.Parse(stat.skillHits);
                ws.Cells[i, 7].Value = long.Parse(stat.skillHighestCrit);
                ws.Cells[i, 7].Style.Numberformat.Format = @"#,#0,\k";
                ws.Cells[i, 8].Value = long.Parse(stat.skillLowestCrit);
                ws.Cells[i, 8].Style.Numberformat.Format = @"#,#0,\k";
                ws.Cells[i, 9].Value = long.Parse(stat.skillAverageCrit);
                ws.Cells[i, 9].Style.Numberformat.Format = @"#,#0,\k";
                ws.Cells[i, 10].Value = long.Parse(stat.skillAverageWhite);
                ws.Cells[i, 10].Style.Numberformat.Format = @"#,#0,\k";
            }
            var border = ws.Cells[1, 1, i, 10].Style.Border;

            border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thick;
            ws.Cells[2, 1, i, 10].AutoFilter = true;

            int j = i + 3;

            ws.Cells[j, 2].Value                  = "Buff name";
            ws.Cells[j, 2, j, 9].Merge            = true;
            ws.Cells[j, 10].Value                 = "%";
            ws.Cells[j, 2, j, 10].Style.Font.Bold = true;
            foreach (var buf in user.buffUptime)
            {
                j++;
                var hotdot = teraData.HotDotDatabase.Get(int.Parse(buf.Key));
                ws.Cells[j, 1].Value = j - i - 3;
                AddImage(ws, j, 1, BTD.Icons.GetBitmap(hotdot.IconName));
                ws.Cells[j, 2].Value = hotdot.Name;
                if (!string.IsNullOrEmpty(hotdot.Tooltip))
                {
                    ws.Cells[j, 2].AddComment("" + hotdot.Tooltip, "info");
                }
                ws.Cells[j, 2, j, 9].Merge = true;
                ws.Cells[j, 10].Value      = double.Parse(buf.Value) / 100;
                ws.Cells[j, 10].Style.Numberformat.Format = "0%";
                if (!string.IsNullOrEmpty(hotdot.ItemName))
                {
                    ws.Cells[j, 10].AddComment("" + hotdot.ItemName, "info");
                }
            }
            border = ws.Cells[i + 3, 1, j, 10].Style.Border;
            border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thick;

            ws.Column(1).Width = 5.6;
            ws.Column(2).AutoFit();
            ws.Column(3).AutoFit();
            ws.Column(4).AutoFit();
            ws.Column(5).AutoFit();
            ws.Column(6).AutoFit();
            ws.Column(7).AutoFit();
            ws.Column(8).AutoFit();
            ws.Column(9).AutoFit();
            ws.Column(10).AutoFit();
            ws.Column(2).Width  = GetTrueColumnWidth(ws.Column(2).Width);
            ws.Column(3).Width  = GetTrueColumnWidth(ws.Column(3).Width);
            ws.Column(4).Width  = GetTrueColumnWidth(ws.Column(4).Width);
            ws.Column(5).Width  = GetTrueColumnWidth(ws.Column(5).Width);
            ws.Column(6).Width  = GetTrueColumnWidth(ws.Column(6).Width);
            ws.Column(7).Width  = GetTrueColumnWidth(ws.Column(7).Width);
            ws.Column(8).Width  = GetTrueColumnWidth(ws.Column(8).Width);
            ws.Column(9).Width  = GetTrueColumnWidth(ws.Column(9).Width);
            ws.Column(10).Width = GetTrueColumnWidth(ws.Column(10).Width);
            ws.Cells[1, 1, j, 10].Style.VerticalAlignment   = ExcelVerticalAlignment.Center;
            ws.Cells[1, 1, j, 10].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
            ws.PrinterSettings.FitToPage = true;
            return(new ExcelHyperLink($"'{user.playerServer}_{user.playerName}'!A1", $"{user.playerServer}: {user.playerName}"));
        }
Пример #2
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));
        }
Пример #3
0
        private static ExcelHyperLink CreateUserSheet(ExcelWorkbook wb, Members user, TeraData teraData)
        {
            ExcelWorksheet ws = wb.Worksheets.Add($"{user.playerServer}_{user.playerName}");
            var rgc = new RaceGenderClass("Common", "Common", user.playerClass);
            ws.DefaultRowHeight = 30;
            ws.Cells.Style.Font.Size = 14;
            ws.Cells.Style.Font.Name = "Arial";
            AddImage(ws, 1, 1, Invert(new Bitmap(SettingsHelper.Instance.GetImage((PlayerClass)Enum.Parse(typeof(PlayerClass), user.playerClass)))));
            ws.Cells[1, 2].Value = $"{user.playerServer}: {user.playerName}";
            ws.Cells[1, 2, 1, 10].Merge = true;
            ws.Cells[1, 2, 1, 10].Style.Font.Bold = true;
            ws.Cells[2, 2].Value = "Skill";
            ws.Cells[2, 3].Value = "Damage %";
            ws.Cells[2, 4].Value = "Damage";
            ws.Cells[2, 5].Value = "Crit %";
            ws.Cells[2, 6].Value = "Hits";
            ws.Cells[2, 7].Value = "Max Crit";
            ws.Cells[2, 8].Value = "Min Crit";
            ws.Cells[2, 9].Value = "Avg Crit";
            ws.Cells[2, 10].Value = "Avg White";
            int i = 2;
            foreach (var stat in user.skillLog.OrderByDescending(x => long.Parse(x.skillTotalDamage)))
            {
                i++;
                var skill = teraData.SkillDatabase.GetOrNull(rgc, int.Parse(stat.skillId));
                if (skill == null)
                {
                    ws.Cells[i, 1].Value = i-2;
                    ws.Cells[i, 2].Value = "Some pet skill";
                }
                else
                {
                    ws.Cells[i, 1].Value = i - 2;
                    AddImage(ws, i, 1, BTD.Icons.GetBitmap(skill.IconName));
                    ws.Cells[i, 2].Value = skill.Name;
                }
                ws.Cells[i, 3].Value = double.Parse(stat.skillDamagePercent) / 100;
                ws.Cells[i, 3].Style.Numberformat.Format = "0.0%";
                ws.Cells[i, 4].Value = long.Parse(stat.skillTotalDamage);
                ws.Cells[i, 4].Style.Numberformat.Format = @"#,#0,\k";
                ws.Cells[i, 5].Value = double.Parse(stat.skillCritRate) / 100;
                ws.Cells[i, 5].Style.Numberformat.Format = "0.0%";
                ws.Cells[i, 6].Value = long.Parse(stat.skillHits);
                ws.Cells[i, 7].Value = long.Parse(stat.skillHighestCrit);
                ws.Cells[i, 7].Style.Numberformat.Format = @"#,#0,\k";
                ws.Cells[i, 8].Value = long.Parse(stat.skillLowestCrit);
                ws.Cells[i, 8].Style.Numberformat.Format = @"#,#0,\k";
                ws.Cells[i, 9].Value = long.Parse(stat.skillAverageCrit);
                ws.Cells[i, 9].Style.Numberformat.Format = @"#,#0,\k";
                ws.Cells[i, 10].Value = long.Parse(stat.skillAverageWhite);
                ws.Cells[i, 10].Style.Numberformat.Format = @"#,#0,\k";
            }
            var border = ws.Cells[1, 1, i, 10].Style.Border;
            border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thick;
            ws.Cells[2, 1, i, 10].AutoFilter = true;

            int j = i + 3;
            ws.Cells[j, 2].Value = "Buff name";
            ws.Cells[j, 2, j, 9].Merge = true;
            ws.Cells[j, 10].Value = "%";
            ws.Cells[j, 2, j, 10].Style.Font.Bold = true;
            foreach (var buf in user.buffUptime)
            {
                j++;
                var hotdot = teraData.HotDotDatabase.Get(int.Parse(buf.Key));
                ws.Cells[j, 1].Value = j - i - 3;
                AddImage(ws, j, 1, BTD.Icons.GetBitmap(hotdot.IconName));
                ws.Cells[j, 2].Value = hotdot.Name;
                if (!string.IsNullOrEmpty(hotdot.Tooltip)) ws.Cells[j, 2].AddComment("" + hotdot.Tooltip, "info");
                ws.Cells[j, 2, j, 9].Merge = true;
                ws.Cells[j, 10].Value = double.Parse(buf.Value) / 100;
                ws.Cells[j, 10].Style.Numberformat.Format = "0%";
                if (!string.IsNullOrEmpty(hotdot.ItemName)) ws.Cells[j, 10].AddComment("" + hotdot.ItemName, "info");
            }
            border = ws.Cells[i + 3, 1, j, 10].Style.Border;
            border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thick;

            ws.Column(1).Width = 5.6;
            ws.Column(2).AutoFit();
            ws.Column(3).AutoFit();
            ws.Column(4).AutoFit();
            ws.Column(5).AutoFit();
            ws.Column(6).AutoFit();
            ws.Column(7).AutoFit();
            ws.Column(8).AutoFit();
            ws.Column(9).AutoFit();
            ws.Column(10).AutoFit();
            ws.Column(2).Width = GetTrueColumnWidth(ws.Column(2).Width);
            ws.Column(3).Width = GetTrueColumnWidth(ws.Column(3).Width);
            ws.Column(4).Width = GetTrueColumnWidth(ws.Column(4).Width);
            ws.Column(5).Width = GetTrueColumnWidth(ws.Column(5).Width);
            ws.Column(6).Width = GetTrueColumnWidth(ws.Column(6).Width);
            ws.Column(7).Width = GetTrueColumnWidth(ws.Column(7).Width);
            ws.Column(8).Width = GetTrueColumnWidth(ws.Column(8).Width);
            ws.Column(9).Width = GetTrueColumnWidth(ws.Column(9).Width);
            ws.Column(10).Width = GetTrueColumnWidth(ws.Column(10).Width);
            ws.Cells[1, 1, j, 10].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
            ws.Cells[1, 1, j, 10].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
            ws.PrinterSettings.FitToPage = true;
            return new ExcelHyperLink($"'{user.playerServer}_{user.playerName}'!A1", $"{user.playerServer}: {user.playerName}");
        }
Пример #4
0
        public static void ToTeraDpsApi(ExportType exportType, DamageTracker damageTracker, TeraData teraData, NpcEntity forcedBoss = null)
        {
            if (exportType == ExportType.None)
            {
                return;
            }

            //if we want to upload, primary target must be dead or it's Vergos p2/p3
            if (exportType.HasFlag(ExportType.Upload) && !(forcedBoss != null || damageTracker.IsPrimaryTargetDead))
            {
                return;
            }

            var exportToExcel = (exportType & (ExportType.Excel | ExportType.ExcelTemp)) != 0;
            //if we're not exporting to excel and credentials aren't fully entered, return
            //if (!exportToExcel
            //    && (string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsToken)
            //        || string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsUser)))
            //    return;

            //ignore if not a boss
            var entity = forcedBoss ?? damageTracker.PrimaryTarget;

            if (!(entity?.Info.Boss ?? false))
            {
                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 => (long)x.Damage);
            }
            else
            {
                totaldamage =
                    damageTracker.StatsByUser.SelectMany(x => x.SkillLog)
                    .Where(x => x.Target == entity)
                    .Sum(x => (long)x.Damage);
            }

            var partyDps    = TimeSpan.TicksPerSecond * totaldamage / interval;
            var teradpsData = new EncounterBase
            {
                encounterUnixEpoch = DateTimeTools.DateTimeToUnixTimestamp(damageTracker.LastAttack?.ToUniversalTime() ?? DateTime.UtcNow),
                areaId             = entity.Info.HuntingZoneId + "",
                bossId             = entity.Info.TemplateId + "",
                fightDuration      = seconds + "",
                partyDps           = partyDps + ""
            };

            foreach (var debuff in abnormals.Get(entity).OrderByDescending(x => x.Value.Duration(firstTick, lastTick)))
            {
                long percentage = debuff.Value.Duration(firstTick, lastTick) * 100 / interval;
                if (percentage == 0)
                {
                    continue;
                }
                var stacks = new List <List <int> > {
                    new List <int> {
                        0, (int)percentage
                    }
                };
                var stackList = debuff.Value.Stacks(firstTick, lastTick).OrderBy(x => x);
                teradpsData.debuffDetail.Add(new List <object> {
                    debuff.Key.Id, stacks
                });
                if (stackList.Any() && stackList.Max() == 1)
                {
                    continue;
                }
                foreach (var stack in stackList)
                {
                    percentage = debuff.Value.Duration(firstTick, lastTick, stack) * 100 / interval;
                    if (percentage == 0)
                    {
                        continue;
                    }
                    stacks.Add(new List <int> {
                        stack, (int)percentage
                    });
                }
            }

            foreach (var user in damageTracker.StatsByUser.OrderByDescending(x => x.Dealt.Damage))
            {
                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.guild        = string.IsNullOrWhiteSpace(user.Player.GuildName) ? null : user.Player.GuildName;
                teradpsUser.playerServer = SettingsHelper.Instance.BasicTeraData.Servers.GetServerName(user.Player.ServerId);
                var hits = filteredSkillog.Count(x => x.Damage > 0 && !x.Abnormality);
                teradpsUser.playerAverageCritRate = hits == 0? "0" : Math.Round(100 * (double)filteredSkillog.Count(x => x.IsCritical && x.Damage > 0) / hits) + "";
                hits = filteredSkillog.Count(x => x.Heal > 0 && !x.Abnormality);
                teradpsUser.healCrit  = user.Player.IsHealer && hits > 0 ? Math.Round(100 * (double)filteredSkillog.Count(x => x.IsCritical && x.Heal > 0) / filteredSkillog.Count(x => x.Heal > 0 && !x.Abnormality)) + "" : 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.OrderByDescending(x => x.Value.Duration(firstTick, lastTick)))
                {
                    long percentage = (buff.Value.Duration(firstTick, lastTick) * 100 / interval);
                    if (percentage == 0)
                    {
                        continue;
                    }
                    var stacks = new List <List <int> > {
                        new List <int> {
                            0, (int)percentage
                        }
                    };
                    var stackList = buff.Value.Stacks(firstTick, lastTick).OrderBy(x => x);
                    teradpsUser.buffDetail.Add(new List <object> {
                        buff.Key.Id, stacks
                    });
                    if (stackList.Any() && stackList.Max() == 1)
                    {
                        continue;
                    }
                    foreach (var stack in buff.Value.Stacks(firstTick, lastTick).OrderBy(x => x))
                    {
                        percentage = buff.Value.Duration(firstTick, lastTick, stack) * 100 / interval;
                        if (percentage == 0)
                        {
                            continue;
                        }
                        stacks.Add(new List <int> {
                            stack, (int)percentage
                        });
                    }
                }

                var aggregated = new List <AggregatedSkillResult>();
                var collection = new SynchronizedObservableCollection <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.OrderByDescending(x => x.Damage))
                {
                    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) + "";
                    skillLog.skillDamagePercent = Math.Round(skill.DamagePercent * 100) + "";
                    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);
                }
                if (damageTracker.MeterPlayer == user.Player)
                {
                    teradpsData.uploader = teradpsData.members.Count.ToString();
                }
                teradpsData.members.Add(teradpsUser);
            }

            //export to excel if specified
            if (exportToExcel)
            {
                Task.Run(() => ExcelExport.ExcelSave(exportType, teradpsData, teraData));
            }

            //return if we don't need to upload
            if (!exportType.HasFlag(ExportType.Upload))
            {
                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 != 468 &&
                areaId != 770 &&
                areaId != 769 &&
                areaId != 916 &&
                areaId != 969 &&
                areaId != 970 &&
                areaId != 710 &&
                areaId != 780 &&
                areaId != 980 &&
                areaId != 781 &&
                areaId != 981 &&
                !(areaId == 950 && int.Parse(teradpsData.bossId) / 100 != 11)
                )
            {
                return;
            }

            try
            {
                using (var client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromSeconds(40);
                    var response = client.GetAsync("https://moongourd.com/shared/servertime");
                    var timediff = (response.Result.Headers.Date.Value.UtcDateTime.Ticks - DateTime.UtcNow.Ticks) / TimeSpan.TicksPerSecond;
                    teradpsData.encounterUnixEpoch += timediff;
                }
            }
            catch (Exception)
            {
                Debug.WriteLine("Get server time error");
                return;
            }
            var json = JsonConvert.SerializeObject(teradpsData, new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore, TypeNameHandling = TypeNameHandling.None
            });

            Task.Run(() => Send(entity, json, 3));
        }
Пример #5
0
        public static void ToTeraDpsApi(ExportType exportType, DamageTracker damageTracker, TeraData teraData)
        {
            if (exportType == ExportType.None) return;

            //if we want to upload, primary target must be dead
            if (exportType.HasFlag(ExportType.Upload) && !damageTracker.IsPrimaryTargetDead)
                return;

            var exportToExcel = (exportType & (ExportType.Excel | ExportType.ExcelTemp)) != 0;
            //if we're not exporting to excel and credentials aren't fully entered, return
            //if (!exportToExcel
            //    && (string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsToken)
            //        || string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsUser)))
            //    return;

            //ignore if not a boss
            var entity = damageTracker.PrimaryTarget;
            if (!(entity?.Info.Boss ?? false)) 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
            {
                encounterUnixEpoch = DateTimeTools.DateTimeToUnixTimestamp(damageTracker.LastAttack?.ToUniversalTime() ?? DateTime.UtcNow),
                areaId = entity.Info.HuntingZoneId + "",
                bossId = entity.Info.TemplateId + "",
                fightDuration = seconds + "",
                partyDps = partyDps + ""
            };

            foreach (var debuff in abnormals.Get(entity).OrderByDescending(x=>x.Value.Duration(firstTick, lastTick)))
            {
                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.OrderByDescending(x=>x.Dealt.Damage))
            {
                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)) + "";
                teradpsUser.healCrit = user.Player.IsHealer ? Math.Round(100 * (double)filteredSkillog.Count(x => x.IsCritical && x.Heal > 0) / filteredSkillog.Count(x => x.Heal > 0)) + "" : 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.OrderByDescending(x => x.Value.Duration(firstTick, lastTick)))
                {
                    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 List<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, CollectionHelper.Instance.CreateSyncedCollection(collection)));
                }
                foreach (var skill in aggregated.OrderByDescending(x=>x.Damage))
                {
                    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) + "";
                    skillLog.skillDamagePercent = Math.Round(skill.DamagePercent * 100) + "";
                    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);
            }

            //export to excel if specified
            if (exportToExcel) Task.Run(() => ExcelExport.ExcelSave(exportType, teradpsData, teraData));

            //return if we don't need to upload
            if (!exportType.HasFlag(ExportType.Upload)) 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 != 468 &&
                areaId != 770 &&
                areaId != 769 &&
                areaId != 916 &&
                areaId != 969 &&
                areaId != 970 &&
                areaId != 950
                )
            {
                return;
            }

            //if (int.Parse(teradpsData.partyDps) < 2000000 && areaId != 468)
            //{
            //    return;
            //}
            try
            {
                using (var client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromSeconds(40);
                    var response = client.GetAsync("http://moongourd.com/shared/servertime");
                    var timediff = (response.Result.Headers.Date.Value.UtcDateTime.Ticks - DateTime.UtcNow.Ticks) / TimeSpan.TicksPerSecond;
                    teradpsData.encounterUnixEpoch += timediff;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("Get server time error");
                return;
            }
            var json = JsonConvert.SerializeObject(teradpsData, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
            Task.Run(() => Send(entity, json, 3));
        }