/** * The datastorage cost almost nothing, so I will use it to provide statistics about most played class, average dps for each class etc. * Mostly to expose overpowered class * Playername are wiped out client side & server side. No IP address are stored, so it s anonymous. */ private static void ToAnonymousStatistics(EncounterBase teradpsData) { //Leveling area only, don't care about that 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; } foreach (var members in teradpsData.members) { members.playerName = "Anonymous"; } SendAnonymousStatistics( JsonConvert.SerializeObject(teradpsData, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }), 3); }
/** * The datastorage cost almost nothing, so I will use it to provide statistics about most played class, average dps for each class etc. * Mostly to expose overpowered class * Playername are wiped out client side & server side. No IP address are stored, so it s anonymous. */ private static void ToAnonymousStatistics(EncounterBase teradpsData) { //Leveling area only, don't care about that var areaId = int.Parse(teradpsData.areaId); if ( areaId != 459 && areaId != 759 && areaId != 511 && areaId != 611 && areaId != 711 && areaId != 886 && areaId != 460 && areaId != 467 && areaId != 767 && areaId != 768 && areaId != 468 ) { return; } SendAnonymousStatistics(JsonConvert.SerializeObject(teradpsData, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }), 3); }
private static void ToAnonymousStatistics(EncounterBase teradpsData) { 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 != 710 && areaId != 950 ) { return; } foreach (var members in teradpsData.members) { members.playerName = "Anonymous"; members.playerId = 0; members.guild = null; } SendAnonymousStatistics( JsonConvert.SerializeObject(teradpsData, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, TypeNameHandling = TypeNameHandling.None }), 3); }
private static void Anonymize(EncounterBase teradpsData) { foreach (var members in teradpsData.members) { members.playerName = "Anonymous"; members.playerId = 0; members.guild = null; } }
private static void ToTeraDpsApi(EncounterBase teradpsData, NpcEntity entity) { if (!BasicTeraData.Instance.WindowData.SiteExport) { return; } 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 == 950 && int.Parse(teradpsData.bossId) / 100 != 11) ) { return; } long timediff; try { using (var client = new HttpClient()) { client.Timeout = TimeSpan.FromSeconds(40); var response = client.GetAsync("https://moongourd.com/shared/servertime"); timediff = (response.Result.Headers.Date.Value.UtcDateTime.Ticks - DateTime.UtcNow.Ticks) / TimeSpan.TicksPerSecond; teradpsData.encounterUnixEpoch += timediff; } } catch { Debug.WriteLine("Get server time error"); NetworkController.Instance.BossLink.TryAdd( "!0 " + LP.TeraDpsIoApiError + " " + entity.Info.Name + " " + entity.Id + " " + DateTime.UtcNow.Ticks, entity); return; } var json = JsonConvert.SerializeObject(teradpsData, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, TypeNameHandling = TypeNameHandling.None }); teradpsData.encounterUnixEpoch -= timediff; SendTeraDpsIo(entity, json, 3); DELETEME(entity, json); }
private static void ToPrivateServer(EncounterBase teradpsData, NpcEntity entity, List <int> serverlist = null) { if (!BasicTeraData.Instance.WindowData.PrivateServerExport) { return; } 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 != 710 && areaId != 780 && areaId != 980 && areaId != 781 && areaId != 981 && areaId != 950) { return; } var j = BasicTeraData.Instance.WindowData.PrivateDpsServers.Count; for (var i = 0; i < j; i++) { if (serverlist != null && !serverlist.Contains(i + 1)) { continue; } long timediff; try { var url = new Uri(BasicTeraData.Instance.WindowData.PrivateDpsServers[i]).GetLeftPart(UriPartial.Authority); using (var client = new HttpClient()) { client.Timeout = TimeSpan.FromSeconds(40); var response = client.GetAsync(url + "/shared/servertime"); timediff = (response.Result.Headers.Date.Value.UtcDateTime.Ticks - DateTime.UtcNow.Ticks) / TimeSpan.TicksPerSecond; teradpsData.encounterUnixEpoch += timediff; } } catch { Debug.WriteLine("Get server time error"); NetworkController.Instance.BossLink.TryAdd( "!" + (i + 1) + " " + LP.TeraDpsIoApiError + " " + entity.Info.Name + " " + entity.Id + " " + DateTime.UtcNow.Ticks, entity); continue; } var json = JsonConvert.SerializeObject(teradpsData, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, TypeNameHandling = TypeNameHandling.None }); teradpsData.encounterUnixEpoch -= timediff; SendTeraDpsIo(entity, json, 3, i + 1); } }
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); }
public void Export(EncounterBase teradpsData, NpcEntity entity) { FetchAllowedAreaId(); BasicTeraData.LogError("PacketExport: Start", true); // Only export when a notable dungeons is cleared var areaId = int.Parse(teradpsData.areaId); if (!_allowedAreaId.Any(x => x.AreaId == areaId && (x.BossIds.Count == 0 || x.BossIds.Contains((int)entity.Info.TemplateId)))) { BasicTeraData.LogError("PacketExport: Boss not allowed, exiting", true); TeraSniffer.Instance.EnableMessageStorage = false; return; } if (!TeraSniffer.Instance.EnableMessageStorage) { BasicTeraData.LogError("PacketExport: Option not activated, exiting", true); // Message storing have already been stopped return; } // Keep a local reference of the packet list Queue <Message> packetsCopyStorage = TeraSniffer.Instance.GetPacketsLogsAndStop(); if (!packetsCopyStorage.Any()) { BasicTeraData.LogError("PacketExport: Empty packet log, exiting", true); return; } var version = PacketProcessor.Instance.MessageFactory.Version; Guid id = Guid.NewGuid(); string filename = version + "_" + id; Debug.WriteLine("Start exporting data"); BasicTeraData.LogError("PacketExport: Export data to tmp file", true); SaveToTmpFile(version.ToString(), packetsCopyStorage, filename + ".TeraLog"); BasicTeraData.LogError("PacketExport: Compress file", true); Compress(filename + ".TeraLog", filename + ".7z"); File.Delete(filename + ".TeraLog"); BasicTeraData.LogError("PacketExport: Encrypt file", true); Encrypt(filename + ".7z", filename + ".rsa"); File.Delete(filename + ".7z"); BasicTeraData.LogError("PacketExport: Send file", true); Send(filename + ".rsa", version); File.Delete(filename + ".rsa"); }
public static void ExcelSave(EncounterBase data) { lock (savelock) //can't save 2 excel files at one time { if (!BTD.WindowData.Excel) { return; } NpcInfo Boss = BTD.MonsterDatabase.GetOrPlaceholder(ushort.Parse(data.areaId), uint.Parse(data.bossId)); var dir = Path.Combine(BTD.ResourceDirectory, $"logs/{Boss.Area.Replace(":", "-")}"); Directory.CreateDirectory(dir); var fname = Path.Combine(dir, $"{Boss.Name.Replace(":", "-")} {DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss", CultureInfo.InvariantCulture)}.xlsx"); FileInfo file = new FileInfo(fname); if (file.Exists) { return; //the only case this can happen is BAM mobtraining, that's not so interesting statistic to deal with more complex file names. } using (ExcelPackage package = new ExcelPackage(file)) { ExcelWorksheet ws = package.Workbook.Worksheets.Add("Boss"); var linkStyle = package.Workbook.Styles.CreateNamedStyle("HyperLink"); //This one is language dependent linkStyle.Style.Font.UnderLine = true; linkStyle.Style.Font.Color.SetColor(Color.Blue); ws.DefaultRowHeight = 30; ws.Cells.Style.Font.Size = 14; ws.Cells.Style.Font.Name = "Arial"; ws.Cells[1, 1].Value = $"{Boss.Area}: {Boss.Name} {TimeSpan.FromSeconds(double.Parse(data.fightDuration)).ToString(@"mm\:ss")}"; ws.Cells[1, 1, 1, 6].Merge = true; ws.Cells[1, 1, 1, 8].Style.Font.Bold = true; ws.Cells[1, 7].Value = long.Parse(data.partyDps); ws.Cells[1, 7].Style.Numberformat.Format = @"#,#00,\k\/\s"; ws.Cells[2, 1].Value = "Ic"; ws.Cells[2, 1].Style.Font.Color.SetColor(Color.Transparent); ws.Cells[2, 2].Value = "Name"; ws.Cells[2, 3].Value = "Deaths"; ws.Cells[2, 4].Value = "Death time"; ws.Cells[2, 5].Value = "Damage %"; ws.Cells[2, 6].Value = "Crit %"; ws.Cells[2, 7].Value = "DPS"; ws.Cells[2, 8].Value = "Damage"; int i = 2; foreach (var user in data.members.OrderByDescending(x => long.Parse(x.playerTotalDamage))) { i++; ws.Cells[i, 1].Value = i - 2; AddImage(ws, i, 1, ClassIcons.Instance.GetBitmap((PlayerClass)Enum.Parse(typeof(PlayerClass), user.playerClass))); ws.Cells[i, 2].Value = $"{user.playerServer}: {user.playerName}"; ws.Cells[i, 2].Hyperlink = CreateUserSheet(package.Workbook, user); ws.Cells[i, 3].Value = long.Parse(user.playerDeaths); ws.Cells[i, 4].Value = long.Parse(user.playerDeathDuration); ws.Cells[i, 4].Style.Numberformat.Format = @"0\s"; ws.Cells[i, 5].Value = double.Parse(user.playerTotalDamagePercentage) / 100; ws.Cells[i, 5].Style.Numberformat.Format = "0.0%"; ws.Cells[i, 6].Value = double.Parse(user.playerAverageCritRate) / 100; ws.Cells[i, 6].Style.Numberformat.Format = "0.0%"; ws.Cells[i, 7].Value = long.Parse(user.playerDps); ws.Cells[i, 7].Style.Numberformat.Format = @"#,#0,\k\/\s"; ws.Cells[i, 8].Value = long.Parse(user.playerTotalDamage); ws.Cells[i, 8].Style.Numberformat.Format = @"#,#0,\k"; } ws.Cells[1, 8].Formula = $"SUM(H3:H{i})"; ws.Cells[1, 8].Style.Numberformat.Format = @"#,#0,\k"; var border = ws.Cells[1, 1, i, 8].Style.Border; border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thick; ws.Cells[2, 1, i, 8].AutoFilter = true; int j = i + 3; ws.Cells[j, 1].Value = "Ic"; ws.Cells[j, 1].Style.Font.Color.SetColor(Color.Transparent); ws.Cells[j, 2].Value = "Debuff name"; ws.Cells[j, 2, j, 7].Merge = true; ws.Cells[j, 8].Value = "%"; ws.Cells[j, 2, j, 8].Style.Font.Bold = true; foreach (var buf in data.debuffUptime) { j++; var hotdot = BTD.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, 7].Merge = true; ws.Cells[j, 8].Value = double.Parse(buf.Value) / 100; ws.Cells[j, 8].Style.Numberformat.Format = "0%"; } border = ws.Cells[i + 3, 1, j, 8].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.Cells[1, 1, j, 8].Style.VerticalAlignment = ExcelVerticalAlignment.Center; ws.Cells[1, 1, j, 8].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; ws.PrinterSettings.FitToPage = true; package.Workbook.Properties.Title = Boss.Name; package.Workbook.Properties.Author = "ShinraMeter " + AutoUpdate.UpdateManager.Version; package.Workbook.Properties.Company = "github.com/neowutran & github.com/Gl0"; package.Save(); } } }
private static ExtendedStats GenerateStats(NpcEntity entity, AbnormalityStorage abnormals) { if (!entity.Info.Boss) { return(null); } var timedEncounter = false; /* * modify timedEncounter depending on teradps.io need * */ var entityInfo = Database.Database.Instance.GlobalInformationEntity(entity, timedEncounter); var skills = Database.Database.Instance.GetSkills(entityInfo.BeginTime, entityInfo.EndTime); var playersInfo = timedEncounter ? Database.Database.Instance.PlayerDamageInformation(entityInfo.BeginTime, entityInfo.EndTime) : Database.Database.Instance.PlayerDamageInformation(entity); var heals = Database.Database.Instance.PlayerHealInformation(entityInfo.BeginTime, entityInfo.EndTime); playersInfo.RemoveAll(x => x.Amount == 0); var firstTick = entityInfo.BeginTime; var lastTick = entityInfo.EndTime; var interTick = lastTick - firstTick; var interval = interTick / TimeSpan.TicksPerSecond; if (interval == 0) { return(null); } var totaldamage = entityInfo.TotalDamage; var partyDps = TimeSpan.TicksPerSecond * totaldamage / interTick; var teradpsData = new EncounterBase(); var extendedStats = new ExtendedStats(); var _abnormals = abnormals.Clone(entity, firstTick, lastTick); extendedStats.Entity = entity; extendedStats.BaseStats = teradpsData; extendedStats.FirstTick = firstTick; extendedStats.LastTick = lastTick; teradpsData.areaId = entity.Info.HuntingZoneId + ""; teradpsData.bossId = entity.Info.TemplateId + ""; teradpsData.fightDuration = interval + ""; teradpsData.partyDps = partyDps + ""; extendedStats.Debuffs = _abnormals.Get(entity); foreach (var debuff in extendedStats.Debuffs) { var 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 playersInfo) { var teradpsUser = new Members(); var damage = user.Amount; teradpsUser.playerTotalDamage = damage + ""; if (damage <= 0) { continue; } var buffs = _abnormals.Get(user.Source); teradpsUser.playerClass = user.Source.Class.ToString(); teradpsUser.playerName = user.Source.Name; teradpsUser.playerServer = BasicTeraData.Instance.Servers.GetServerName(user.Source.ServerId); teradpsUser.playerAverageCritRate = Math.Round(user.CritRate, 1) + ""; teradpsUser.healCrit = user.Source.IsHealer ? heals.FirstOrDefault(x => x.Source == user.Source)?.CritRate + "" : null; teradpsUser.playerDps = TimeSpan.TicksPerSecond * damage / interTick + ""; teradpsUser.playerTotalDamagePercentage = user.Amount * 100 / entityInfo.TotalDamage + ""; extendedStats.PlayerReceived.Add(user.Source.Name, Tuple.Create(skills.HitsReceived(user.Source.User.Id, entity, timedEncounter), skills.DamageReceived(user.Source.User.Id, entity, timedEncounter))); 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) / interTick + ""; foreach (var buff in buffs.Times) { var 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, skills.GetSkillsDealt(user.Source.User.Id, entity, timedEncounter)); extendedStats.PlayerBuffs.Add(serverPlayerName, buffs); var skillsId = SkillAggregate.GetAggregate(user, entityInfo.Entity, skills, timedEncounter, Database.Database.Type.Damage); extendedStats.PlayerSkillsAggregated[teradpsUser.playerServer + "/" + teradpsUser.playerName] = skillsId; foreach (var skill in skillsId) { var skillLog = new SkillLog(); var skilldamage = skill.Amount(); skillLog.skillAverageCrit = Math.Round(skill.AvgCrit()) + ""; skillLog.skillAverageWhite = Math.Round(skill.AvgWhite()) + ""; skillLog.skillCritRate = skill.CritRate() + ""; skillLog.skillDamagePercent = skill.DamagePercent() + ""; skillLog.skillHighestCrit = skill.BiggestCrit() + ""; skillLog.skillHits = skill.Hits() + ""; skillLog.skillId = skill.Skills.First().Key.Id + ""; skillLog.skillLowestCrit = skill.LowestCrit() + ""; skillLog.skillTotalDamage = skilldamage + ""; if (skilldamage == 0) { continue; } teradpsUser.skillLog.Add(skillLog); } teradpsData.members.Add(teradpsUser); } return(extendedStats); }
private static ExtendedStats GenerateStats(NpcEntity entity, AbnormalityStorage abnormals) { if (!entity.Info.Boss) { return(null); } var timedEncounter = false; /* * modify timedEncounter depending on teradps.io need * */ var entityInfo = Database.Database.Instance.GlobalInformationEntity(entity, timedEncounter); var skills = Database.Database.Instance.GetSkills(entityInfo.BeginTime, entityInfo.EndTime); var playersInfo = timedEncounter ? Database.Database.Instance.PlayerDamageInformation(entityInfo.BeginTime, entityInfo.EndTime) : Database.Database.Instance.PlayerDamageInformation(entity); var heals = Database.Database.Instance.PlayerHealInformation(entityInfo.BeginTime, entityInfo.EndTime); playersInfo.RemoveAll(x => x.Amount == 0); var firstTick = entityInfo.BeginTime; var lastTick = entityInfo.EndTime; var interTick = lastTick - firstTick; var interval = interTick / TimeSpan.TicksPerSecond; if (interval == 0) { return(null); } var totaldamage = entityInfo.TotalDamage; var partyDps = TimeSpan.TicksPerSecond * totaldamage / interTick; var teradpsData = new EncounterBase(); var extendedStats = new ExtendedStats(); var _abnormals = abnormals.Clone(entity, firstTick, lastTick); teradpsData.encounterUnixEpoch = new DateTimeOffset(new DateTime(lastTick, DateTimeKind.Utc)).ToUnixTimeSeconds(); extendedStats.Entity = entity; extendedStats.BaseStats = teradpsData; extendedStats.FirstTick = firstTick; extendedStats.LastTick = lastTick; teradpsData.areaId = entity.Info.HuntingZoneId + ""; teradpsData.bossId = entity.Info.TemplateId + ""; teradpsData.fightDuration = interval + ""; teradpsData.partyDps = partyDps + ""; extendedStats.Debuffs = _abnormals.Get(entity); foreach (var debuff in extendedStats.Debuffs.OrderByDescending(x => x.Value.Duration(firstTick, lastTick))) { var percentage = debuff.Value.Duration(firstTick, lastTick) * 100 / interTick; if (percentage == 0) { continue; } teradpsData.debuffUptime.Add(new KeyValuePair <string, string>( debuff.Key.Id + "", percentage + "" )); 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 / interTick; if (percentage == 0) { continue; } stacks.Add(new List <int> { stack, (int)percentage }); } } foreach (var user in playersInfo.OrderByDescending(x => x.Amount)) { var teradpsUser = new Members(); var damage = user.Amount; teradpsUser.playerTotalDamage = damage + ""; if (damage <= 0) { continue; } var buffs = _abnormals.Get(user.Source); teradpsUser.guild = string.IsNullOrWhiteSpace(user.Source.GuildName) ? null : user.Source.GuildName; teradpsUser.playerClass = user.Source.Class.ToString(); teradpsUser.playerName = user.Source.Name; teradpsUser.playerId = user.Source.PlayerId; teradpsUser.playerServer = BasicTeraData.Instance.Servers.GetServerName(user.Source.ServerId); teradpsUser.playerAverageCritRate = Math.Round(user.CritRate, 1) + ""; teradpsUser.healCrit = user.Source.IsHealer ? heals.FirstOrDefault(x => x.Source == user.Source)?.CritRate + "" : null; teradpsUser.playerDps = TimeSpan.TicksPerSecond * damage / interTick + ""; teradpsUser.playerTotalDamagePercentage = user.Amount * 100 / entityInfo.TotalDamage + ""; extendedStats.PlayerReceived.Add(user.Source.Name, Tuple.Create(skills.HitsReceived(user.Source.User, entity, timedEncounter), skills.DamageReceived(user.Source.User, entity, timedEncounter))); extendedStats.PlayerCritDamageRate.Add(user.Source.Name, user.CritDamageRate); 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) / interTick + ""; foreach (var buff in buffs.Times.OrderByDescending(x => x.Value.Duration(firstTick, lastTick))) { var percentage = buff.Value.Duration(firstTick, lastTick) * 100 / interTick; if (percentage == 0) { continue; } teradpsUser.buffUptime.Add(new KeyValuePair <string, string>( buff.Key.Id + "", percentage + "" )); 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 / interTick; if (percentage == 0) { continue; } stacks.Add(new List <int> { stack, (int)percentage }); } } var serverPlayerName = $"{teradpsUser.playerServer}_{teradpsUser.playerName}"; extendedStats.PlayerSkills.Add(serverPlayerName, skills.GetSkillsDealt(user.Source.User, entity, timedEncounter)); extendedStats.PlayerBuffs.Add(serverPlayerName, buffs); var skillsId = SkillAggregate.GetAggregate(user, entityInfo.Entity, skills, timedEncounter, Database.Database.Type.Damage); extendedStats.PlayerSkillsAggregated[teradpsUser.playerServer + "/" + teradpsUser.playerName] = skillsId; foreach (var skill in skillsId.OrderByDescending(x => x.Amount())) { var skillLog = new SkillLog(); var skilldamage = skill.Amount(); skillLog.skillAverageCrit = Math.Round(skill.AvgCrit()) + ""; skillLog.skillAverageWhite = Math.Round(skill.AvgWhite()) + ""; skillLog.skillCritRate = skill.CritRate() + ""; skillLog.skillDamagePercent = skill.DamagePercent() + ""; skillLog.skillHighestCrit = skill.BiggestCrit() + ""; skillLog.skillHits = skill.Hits() + ""; var skillKey = skill.Skills.First().Key; skillLog.skillId = BasicTeraData.Instance.SkillDatabase.GetSkillByPetName(skillKey.NpcInfo?.Name, user.Source.RaceGenderClass)?.Id.ToString() ?? skillKey.Id.ToString(); skillLog.skillLowestCrit = skill.LowestCrit() + ""; skillLog.skillTotalDamage = skilldamage + ""; if (skilldamage == 0) { continue; } teradpsUser.skillLog.Add(skillLog); } if (NetworkController.Instance.MeterPlayers.Contains(user.Source)) { teradpsData.uploader = teradpsData.members.Count.ToString(); } teradpsData.members.Add(teradpsUser); } return(extendedStats); }
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(); }
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); }