private NetworkController() { TeraSniffer.Instance.NewConnection += HandleNewConnection; AbnormalityStorage = new AbnormalityStorage(); var packetAnalysis = new Thread(PacketAnalysisLoop); packetAnalysis.Start(); }
public void Update(EntityInformation entityInformation, AbnormalityStorage abnormals) { EnduranceAbnormality.Items.Clear(); if (entityInformation == null) { return; } if (entityInformation.Interval == 0) { return; } EnduranceAbnormality.Items.Add(_header); var count = 0; foreach (var abnormality in abnormals.Get(entityInformation.Entity)) { EnduranceDebuff abnormalityUi; if (_enduranceDebuffsList.Count > count) { abnormalityUi = _enduranceDebuffsList[count]; } else { abnormalityUi = new EnduranceDebuff(); _enduranceDebuffsList.Add(abnormalityUi); } abnormalityUi.Update(abnormality.Key, abnormality.Value, entityInformation.BeginTime, entityInformation.EndTime); EnduranceAbnormality.Items.Add(abnormalityUi); count++; } }
public static void ManualExport(NpcEntity entity, AbnormalityStorage abnormality, Dest type) { if (entity == null) { return; } var stats = GenerateStats(entity, abnormality); if (stats == null) { return; } var sendThread = new Thread(() => { if (type.HasFlag(Dest.Site) && PacketProcessor.Instance.BossLink.Any(x => x.Value == entity && x.Key.StartsWith("!"))) { DpsServers.Where(x => PacketProcessor.Instance.BossLink.Where(y => y.Value == entity && y.Key.StartsWith("!")) .Select(y => y.Key.Substring(1, y.Key.IndexOf(" ", StringComparison.Ordinal) - 1)) .Contains(x.Guid.ToString())).ToList().ForEach(x => x.CheckAndSendFightData(stats.BaseStats, entity)); } if (type.HasFlag(Dest.Excel)) { ExcelExporter.ExcelSave(stats, stats.BaseStats.members.Select(x => x.playerName) .FirstOrDefault(x => PacketProcessor.Instance.MeterPlayers.Select(z => z.Name).Contains(x)), type.HasFlag(Dest.Manual)); } }); sendThread.Start(); }
public static void CopyThread(StatsSummary stats, Skills skills, AbnormalityStorage abnormals, bool timedEncounter, CopyKey copy) { if (BasicTeraData.Instance.HotDotDatabase == null) { return; //no database loaded yet => no need to do anything } lock (_pasteLock) { var text = CopyPaste.Copy(stats, skills, abnormals, timedEncounter, copy); for (var i = 0; i < 3; i++) { try { Clipboard.SetText(text.Item2); break; } catch { Thread.Sleep(100); //Ignore } } CopyPaste.Paste(text.Item1); } }
public static void ManualExport(NpcEntity entity, AbnormalityStorage abnormality, Dest type) { if (entity == null) { return; } var stats = GenerateStats(entity, abnormality); if (stats == null) { return; } var name = stats.BaseStats.members.Select(x => x.playerName).FirstOrDefault(x => PacketProcessor.Instance.MeterPlayers.Select(z => z.Name).Contains(x)); if (type.HasFlag(Dest.Json)) { JsonExporter.JsonSave(stats, name, type.HasFlag(Dest.Manual)); } var sendThread = new Thread(() => { if (type.HasFlag(Dest.Site) && PacketProcessor.Instance.BossLink.Any(x => x.Value == entity && !x.Key.Success)) { DpsServers.Where(x => PacketProcessor.Instance.BossLink.Where(y => y.Value == entity && !y.Key.Success) .Select(y => y.Key.Server) .Contains(x.Data.HostName)).ToList().ForEach(x => x.CheckAndSendFightData(stats.BaseStats, entity)); } if (type.HasFlag(Dest.Excel)) { ExcelExporter.ExcelSave(stats, name, type.HasFlag(Dest.Manual)); } }); sendThread.Start(); }
public static void AutomatedExport(NpcEntity entity, AbnormalityStorage abnormality) { if (entity == null) { return; } var stats = GenerateStats(entity, abnormality); if (stats == null) { return; } JsonExporter.JsonSave(stats, PacketProcessor.Instance.EntityTracker.MeterUser.Name); var sendThread = new Thread(() => { DpsServers.Where(x => !x.AnonymousUpload).ToList().ForEach(x => x.CheckAndSendFightData(stats.BaseStats, entity)); ExcelExporter.ExcelSave(stats, PacketProcessor.Instance.EntityTracker.MeterUser.Name); Anonymize(stats.BaseStats); DpsServers.Where(x => x.AnonymousUpload).ToList().ForEach(x => x.CheckAndSendFightData(stats.BaseStats, entity)); if (BasicTeraData.Instance.WindowData.PacketsCollect) { try { PacketsExporter.Instance.Export(stats.BaseStats, entity); } catch (Exception ex) { BasicTeraData.LogError("##### Packets export EXCEPTION #####\r\n" + ex.Message + "\r\n" + ex.StackTrace + "\r\n" + ex.Source + "\r\n" + ex + "\r\n" + ex.Data + "\r\n" + ex.InnerException + "\r\n" + ex.TargetSite); } } }); sendThread.Start(); }
public static void ManualExport(NpcEntity entity, AbnormalityStorage abnormality, Dest type) { if (entity == null) { return; } var stats = GenerateStats(entity, abnormality); if (stats == null) { return; } var sendThread = new Thread(() => { if (type.HasFlag(Dest.Site) && NetworkController.Instance.BossLink.Any(x => x.Value == entity && x.Key.StartsWith("!0"))) { ToTeraDpsApi(stats.BaseStats, entity); } if (type.HasFlag(Dest.Site) && NetworkController.Instance.BossLink.Any(x => x.Value == entity && x.Key.StartsWith("!") && !x.Key.StartsWith("!0"))) { ToPrivateServer(stats.BaseStats, entity, NetworkController.Instance.BossLink.Where(x => x.Value == entity && x.Key.StartsWith("!") && !x.Key.StartsWith("!0")).Select(x => int.Parse(x.Key.Substring(1, x.Key.IndexOf(" ") - 1))).ToList()); } if (type.HasFlag(Dest.Excel)) { ExcelExport.ExcelSave(stats, stats.BaseStats.members.Select(x => x.playerName).FirstOrDefault(x => NetworkController.Instance.MeterPlayers.Select(z => z.Name).Contains(x)), type.HasFlag(Dest.Manual)); } }); sendThread.Start(); }
private NetworkController() { TeraSniffer.Instance.NewConnection += HandleNewConnection; _abnormalityStorage = new AbnormalityStorage(); var packetAnalysis = new Thread(PacketAnalysisLoop); packetAnalysis.Start(); }
public AbnormalityTracker(EntityTracker entityTracker, PlayerTracker playerTracker, HotDotDatabase hotDotDatabase, AbnormalityStorage abnormalityStorage, Action <SkillResult> update = null) { EntityTracker = entityTracker; PlayerTracker = playerTracker; HotDotDatabase = hotDotDatabase; UpdateDamageTracker = update; AbnormalityStorage = abnormalityStorage; }
private PacketProcessor() { TeraSniffer.Instance.NewConnection += HandleNewConnection; TeraSniffer.Instance.EndConnection += HandleEndConnection; AbnormalityStorage = new AbnormalityStorage(); var packetAnalysis = new Thread(PacketAnalysisLoop); packetAnalysis.Start(); TeraSniffer.Instance.EnableMessageStorage = BasicTeraData.Instance.WindowData.PacketsCollect; }
public static void AutomatedExport(SDespawnNpc despawnNpc, AbnormalityStorage abnormality) { if (!despawnNpc.Dead) { return; } var entity = (NpcEntity)DamageTracker.Instance.GetEntity(despawnNpc.Npc); AutomatedExport(entity, abnormality); }
public UiUpdateMessage(StatsSummary statsSummary, Skills skills, List<NpcEntity> entities, bool timedEncounter, AbnormalityStorage abnormals, ConcurrentDictionary<UploadData, NpcEntity> bossHistory, List<ChatMessage> chatbox, List<NotifyFlashMessage> flash) { StatsSummary = statsSummary; Skills = skills; Entities = entities; TimedEncounter = timedEncounter; Abnormals = abnormals; BossHistory = bossHistory; Chatbox = chatbox; Flash = flash; }
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(); }
public static void Export(NpcEntity entity, AbnormalityStorage abnormality, Dest type) { if (entity==null) return; var stats = GenerateStats(entity, abnormality); if (stats == null) { return; } var sendThread = new Thread(() => { if ((type&Dest.Site)!=0 && NetworkController.Instance.BossLink.Any(x=>x.Value==entity&&x.Key.StartsWith("!"))) ToTeraDpsApi(stats.BaseStats, entity); if ((type&Dest.Excel)!=0) ExcelExport.ExcelSave(stats); }); sendThread.Start(); }
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(); }
public static void Export(NpcEntity entity, AbnormalityStorage abnormality) { if (entity == null) { return; } var stats = GenerateStats(entity, abnormality); if (stats == null) { return; } var sendThread = new Thread(() => { ExcelExport.ExcelSave(stats); }); sendThread.Start(); }
public void Update(Dictionary <Entity, EntityInfo> stats, AbnormalityStorage abnormals, Entity currentBoss) { var entity = currentBoss; EnduranceAbnormality.Items.Clear(); if (entity == null) { return; } var statsAbnormalities = stats[entity]; if (statsAbnormalities.Interval == 0 || entity.NpcE == null) { return; } EnduranceAbnormality.Items.Add(_header); var count = 0; foreach (var abnormality in abnormals.Get(entity.NpcE)) { EnduranceDebuff abnormalityUi; if (_enduranceDebuffsList.Count > count) { abnormalityUi = _enduranceDebuffsList[count]; } else { abnormalityUi = new EnduranceDebuff(); _enduranceDebuffsList.Add(abnormalityUi); } abnormalityUi.Update(abnormality.Key, abnormality.Value, statsAbnormalities.FirstHit / TimeSpan.TicksPerSecond, statsAbnormalities.LastHit / TimeSpan.TicksPerSecond); EnduranceAbnormality.Items.Add(abnormalityUi); count++; } }
private void Pause(bool reset = true) { PacketProcessing.Pause(); if (reset) { Database.Database.Instance.DeleteAll(); AbnormalityStorage = new AbnormalityStorage(); AbnormalityTracker = new AbnormalityTracker(EntityTracker, PlayerTracker, BasicTeraData.Instance.HotDotDatabase, AbnormalityStorage, DamageTracker.Instance.Update); if (MessageFactory.ChatEnabled) { AbnormalityTracker.AbnormalityAdded += NotifyProcessor.Instance.AbnormalityNotifierAdded; AbnormalityTracker.AbnormalityRemoved += NotifyProcessor.Instance.AbnormalityNotifierRemoved; } } else { AbnormalityStorage.EndAll(DateTime.UtcNow.Ticks); } TeraSniffer.Instance.Packets = new ConcurrentQueue <Message>(); HudManager.Instance.CurrentBosses.DisposeAll(); NotifyProcessor.Instance.S_LOAD_TOPO(null); }
public static void AutomatedExport(NpcEntity entity, AbnormalityStorage abnormality) { if (entity == null) { return; } var stats = GenerateStats(entity, abnormality); if (stats == null) { return; } var sendThread = new Thread(() => { ToTeraDpsApi(stats.BaseStats, entity); ToPrivateServer(stats.BaseStats, entity); ExcelExport.ExcelSave(stats, NetworkController.Instance.EntityTracker.MeterUser.Name); ToAnonymousStatistics(stats.BaseStats); }); sendThread.Start(); }
public static void AutomatedExport(NpcEntity entity, AbnormalityStorage abnormality) { if (entity == null) { return; } var stats = GenerateStats(entity, abnormality); if (stats == null) { return; } var sendThread = new Thread(() => { DpsServers.Where(x => !x.AnonymousUpload).ToList().ForEach(x => x.CheckAndSendFightData(stats.BaseStats, entity)); ExcelExport.ExcelSave(stats, NetworkController.Instance.EntityTracker.MeterUser.Name); Anonymize(stats.BaseStats); DpsServers.Where(x => x.AnonymousUpload).ToList().ForEach(x => x.CheckAndSendFightData(stats.BaseStats, entity)); }); sendThread.Start(); }
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(); }
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); }
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 + "" )); } 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.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, entity, timedEncounter), skills.DamageReceived(user.Source.User, 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.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 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); } teradpsData.members.Add(teradpsUser); } return extendedStats; }
public static Tuple <string, string> Copy(StatsSummary statsSummary, Skills skills, AbnormalityStorage abnormals, bool timedEncounter, CopyKey copy) { //stop if nothing to paste var entityInfo = statsSummary.EntityInformation; var playersInfos = statsSummary.PlayerDamageDealt; var firstTick = entityInfo.BeginTime; var lastTick = entityInfo.EndTime; var firstHit = firstTick / TimeSpan.TicksPerSecond; var lastHit = lastTick / TimeSpan.TicksPerSecond; var heals = statsSummary.PlayerHealDealt; playersInfos.RemoveAll(x => x.Amount == 0); IEnumerable <PlayerDamageDealt> playerInfosOrdered; if (copy.Order == "ascending") { switch (copy.OrderBy) { case "damage_received": playerInfosOrdered = playersInfos.OrderBy( playerInfo => skills.DamageReceived(playerInfo.Source.User, entityInfo.Entity, timedEncounter)); break; case "name": playerInfosOrdered = playersInfos.OrderBy(playerInfo => playerInfo.Source.Name); break; case "damage_percentage": case "damage_dealt": case "dps": playerInfosOrdered = playersInfos.OrderBy(playerInfo => playerInfo.Amount); break; case "crit_rate": playerInfosOrdered = playersInfos.OrderBy(playerInfo => playerInfo.CritRate); break; case "hits_received": playerInfosOrdered = playersInfos.OrderBy( playerInfo => skills.HitsReceived(playerInfo.Source.User, entityInfo.Entity, timedEncounter)); break; default: Console.WriteLine("wrong value for orderby"); throw new Exception("wrong value for orderby"); } } else { switch (copy.OrderBy) { case "damage_received": playerInfosOrdered = playersInfos.OrderByDescending( playerInfo => skills.DamageReceived(playerInfo.Source.User, entityInfo.Entity, timedEncounter)); break; case "name": playerInfosOrdered = playersInfos.OrderByDescending(playerInfo => playerInfo.Source.Name); break; case "damage_percentage": case "damage_dealt": case "dps": playerInfosOrdered = playersInfos.OrderByDescending(playerInfo => playerInfo.Amount); break; case "crit_rate": playerInfosOrdered = playersInfos.OrderByDescending(playerInfo => playerInfo.CritRate); break; case "hits_received": playerInfosOrdered = playersInfos.OrderByDescending( playerInfo => skills.HitsReceived(playerInfo.Source.User, entityInfo.Entity, timedEncounter)); break; default: Console.WriteLine("wrong value for orderby"); throw new Exception("wrong value for orderby"); } } var dpsString = new StringBuilder(copy.Header + "{body}" + copy.Footer); var name = entityInfo.Entity?.Info.Name ?? ""; AbnormalityDuration enrage; var bossDebuff = abnormals.Get(entityInfo.Entity); bossDebuff.TryGetValue(BasicTeraData.Instance.HotDotDatabase.Enraged, out enrage); var enrageperc = lastTick - firstTick == 0 ? 0 : (double)(enrage?.Duration(firstTick, lastTick) ?? 0) / (lastTick - firstTick); dpsString.Replace("{encounter}", name); var interval = TimeSpan.FromSeconds(lastHit - firstHit); dpsString.Replace("{timer}", interval.ToString(@"mm\:ss")); dpsString.Replace("{partyDps}", FormatHelpers.Instance.FormatValue(lastHit - firstHit > 0 ? entityInfo.TotalDamage / (lastHit - firstHit) : 0) + LP.PerSecond); dpsString.Replace("{enrage}", FormatHelpers.Instance.FormatPercent(enrageperc)); dpsString.Replace("{debuff_list}", String.Join(" | ", bossDebuff.Where(x => x.Key.Id != 8888888 && x.Value.Duration(firstTick, lastTick) > 0).OrderByDescending(x => x.Value.Duration(firstTick, lastTick, -1)).ToList().Select( x => x.Key.ShortName + (x.Value.MaxStack(firstTick, lastTick) > 1 ? "(" + x.Value.MaxStack(firstTick, lastTick) + ")" : "") + " " + FormatHelpers.Instance.FormatPercent((double)x.Value.Duration(firstTick, lastTick, -1) / (lastTick - firstTick)) + " (" + TimeSpan.FromTicks(x.Value.Duration(firstTick, lastTick, -1)).ToString(@"mm\:ss") + ") ") )); dpsString.Replace("{debuff_list_p}", String.Join(" | ", bossDebuff.Where(x => x.Key.Id != 8888888 && x.Value.Duration(firstTick, lastTick) > 0).OrderByDescending(x => x.Value.Duration(firstTick, lastTick, -1)).ToList().Select( x => x.Key.ShortName + (x.Value.MaxStack(firstTick, lastTick) > 1 ? "(" + x.Value.MaxStack(firstTick, lastTick) + ")" : "") + " " + FormatHelpers.Instance.FormatPercent((double)x.Value.Duration(firstTick, lastTick - 1) / (lastTick - firstTick))) )); var placeholders = new List <KeyValuePair <PlayerDamageDealt, Dictionary <string, string> > >(); foreach (var playerStats in playerInfosOrdered) { var playerHolder = new Dictionary <string, string>(); placeholders.Add(new KeyValuePair <PlayerDamageDealt, Dictionary <string, string> >(playerStats, playerHolder)); var buffs = abnormals.Get(playerStats.Source); AbnormalityDuration slaying; var firstOrDefault = heals.FirstOrDefault(x => x.Source == playerStats.Source); double healCritrate = 0; if (firstOrDefault != null) { healCritrate = firstOrDefault.CritRate; } buffs.Times.TryGetValue(BasicTeraData.Instance.HotDotDatabase.Slaying, out slaying); var slayingperc = lastTick - firstTick == 0 ? 0 : (double)(slaying?.Duration(firstTick, lastTick) ?? 0) / (lastTick - firstTick); playerHolder["{slaying}"] = FormatHelpers.Instance.FormatPercent(slayingperc); playerHolder["{dps}"] = FormatHelpers.Instance.FormatValue(playerStats.Interval == 0 ? playerStats.Amount : playerStats.Amount * TimeSpan.TicksPerSecond / playerStats.Interval) + LP.PerSecond; playerHolder["{global_dps}"] = FormatHelpers.Instance.FormatValue(entityInfo.Interval == 0 ? playerStats.Amount : playerStats.Amount * TimeSpan.TicksPerSecond / entityInfo.Interval) + LP.PerSecond; playerHolder["{interval}"] = playerStats.Interval / TimeSpan.TicksPerSecond + LP.Seconds; playerHolder["{damage_dealt}"] = FormatHelpers.Instance.FormatValue(playerStats.Amount); playerHolder["{class}"] = LP.ResourceManager.GetString(playerStats.Source.Class.ToString(), LP.Culture) + ""; playerHolder["{classId}"] = ((int)playerStats.Source.Class) + ""; playerHolder["{fullname}"] = copy.LimitNameLength > 0 && playerStats.Source.FullName.Length > copy.LimitNameLength ? playerStats.Source.FullName.Substring(0, copy.LimitNameLength) : playerStats.Source.FullName; playerHolder["{name}"] = copy.LimitNameLength > 0 && playerStats.Source.Name.Length > copy.LimitNameLength ? playerStats.Source.Name.Substring(0, copy.LimitNameLength) : playerStats.Source.Name; playerHolder["{deaths}"] = buffs.Death.Count(firstTick, lastTick) + ""; playerHolder["{death_duration}"] = TimeSpan.FromTicks(buffs.Death.Duration(firstTick, lastTick)).ToString(@"mm\:ss"); playerHolder["{aggro}"] = buffs.Aggro(entityInfo.Entity).Count(firstTick, lastTick) + ""; playerHolder["{aggro_duration}"] = TimeSpan.FromTicks(buffs.Aggro(entityInfo.Entity).Duration(firstTick, lastTick)).ToString(@"mm\:ss"); playerHolder["{damage_percentage}"] = playerStats.Amount * 100 / entityInfo.TotalDamage + "%"; playerHolder["{crit_rate}"] = playerStats.CritRate + "%"; playerHolder["{crit_damage_rate}"] = playerStats.CritDamageRate + "%"; playerHolder["{crit_rate_heal}"] = healCritrate + "%"; playerHolder["{biggest_crit}"] = FormatHelpers.Instance.FormatValue(skills.BiggestCrit(playerStats.Source.User, entityInfo.Entity, timedEncounter)); playerHolder["{damage_received}"] = FormatHelpers.Instance.FormatValue(skills.DamageReceived(playerStats.Source.User, entityInfo.Entity, timedEncounter)); playerHolder["{hits_received}"] = FormatHelpers.Instance.FormatValue(skills.HitsReceived(playerStats.Source.User, entityInfo.Entity, timedEncounter)); playerHolder["{debuff_list}"] = String.Join(" | ", bossDebuff.Where(x => x.Key.Id != 8888888 && x.Value.InitialPlayerClass == playerStats.Source.Class && x.Value.Duration(firstTick, lastTick) > 0) .OrderByDescending(x => x.Value.Duration(firstTick, lastTick, -1)).ToList().Select( x => x.Key.ShortName + (x.Value.MaxStack(firstTick, lastTick) > 1 ? "(" + x.Value.MaxStack(firstTick, lastTick) + ")" : "") + " " + FormatHelpers.Instance.FormatPercent((double)x.Value.Duration(firstTick, lastTick, -1) / (lastTick - firstTick)) + " (" + TimeSpan.FromTicks(x.Value.Duration(firstTick, lastTick, -1)).ToString(@"mm\:ss") + ") " )); playerHolder["{debuff_list_p}"] = String.Join(" | ", bossDebuff.Where(x => x.Key.Id != 8888888 && x.Value.InitialPlayerClass == playerStats.Source.Class && x.Value.Duration(firstTick, lastTick) > 0) .OrderByDescending(x => x.Value.Duration(firstTick, lastTick, -1)).ToList().Select( x => x.Key.ShortName + (x.Value.MaxStack(firstTick, lastTick) > 1 ? "(" + x.Value.MaxStack(firstTick, lastTick) + ")" : "") + " " + FormatHelpers.Instance.FormatPercent((double)x.Value.Duration(firstTick, lastTick, -1) / (lastTick - firstTick)) )); } var placeholderLength = placeholders.SelectMany(x => x.Value).GroupBy(x => x.Key).ToDictionary(x => x.Key, x => x.Max(z => graphics.MeasureString(z.Value, Font, default(PointF), StringFormat.GenericTypographic).Width)); var dpsLine = new StringBuilder(); var dpsMono = new StringBuilder(); var placeholderMono = placeholders.SelectMany(x => x.Value).GroupBy(x => x.Key).ToDictionary(x => x.Key, x => x.Max(z => z.Value.Length)); if ((copy.Content.Contains('\\') || copy.LowDpsContent.Contains('\\')) && BasicTeraData.Instance.WindowData.FormatPasteString) { placeholders.ForEach(x => { var currentContent = x.Key.Amount * 100 / entityInfo.TotalDamage >= copy.LowDpsThreshold ? new StringBuilder(copy.Content): new StringBuilder(copy.LowDpsContent); x.Value.ToList().ForEach(z => currentContent.Replace(z.Key, PadRight(z.Value, placeholderLength[z.Key]))); dpsLine.Append(currentContent); currentContent = x.Key.Amount * 100 / entityInfo.TotalDamage >= copy.LowDpsThreshold ? new StringBuilder(copy.Content) : new StringBuilder(copy.LowDpsContent); x.Value.ToList().ForEach(z => currentContent.Replace(z.Key, z.Value.PadRight(placeholderMono[z.Key]))); dpsMono.Append(currentContent); }); } else { placeholders.ForEach(x => { var currentContent = x.Key.Amount * 100 / entityInfo.TotalDamage >= copy.LowDpsThreshold ? new StringBuilder(copy.Content) : new StringBuilder(copy.LowDpsContent); x.Value.ToList().ForEach(z => currentContent.Replace(z.Key, z.Value)); dpsLine.Append(currentContent); }); dpsMono = dpsLine; } var paste = dpsString.ToString().Replace("{body}", dpsLine.ToString()); var monoPaste = dpsString.ToString().Replace("{body}", dpsMono.ToString()); while (paste.Contains(" )")) { paste = paste.Replace(" )", ") "); } while (monoPaste.Contains(" )")) { monoPaste = monoPaste.Replace(" )", ") "); } while (paste.Contains(" ]")) { paste = paste.Replace(" ]", "] "); } while (monoPaste.Contains(" ]")) { monoPaste = monoPaste.Replace(" ]", "] "); } while (paste.Contains(" \\")) { paste = paste.Replace(" \\", "\\"); } while (monoPaste.Contains(" \\")) { monoPaste = monoPaste.Replace(" \\", "\\"); } monoPaste = monoPaste.Replace("\\", Environment.NewLine); return(new Tuple <string, string>(paste, monoPaste)); }
public static string Copy(EntityInfo info, IEnumerable <PlayerInfo> playerInfos, AbnormalityStorage abnormals, long totalDamage, long partyDps, long firstHit, long lastHit, Entity currentBoss, bool timedEncounter, string header, string content, string footer, string orderby, string order) { //stop if nothing to paste if (playerInfos == null) { return(""); } IEnumerable <PlayerInfo> playerInfosOrdered; if (order == "ascending") { switch (orderby) { case "damage_received": playerInfosOrdered = playerInfos.OrderBy(playerInfo => playerInfo.Received.Damage(currentBoss, firstHit, lastHit, timedEncounter)); break; case "name": playerInfosOrdered = playerInfos.OrderBy(playerInfo => playerInfo.Name); break; case "damage_percentage": playerInfosOrdered = playerInfos.OrderBy(playerInfo => playerInfo.Dealt.DamageFraction(currentBoss, totalDamage, timedEncounter)); break; case "damage_dealt": playerInfosOrdered = playerInfos.OrderBy(playerInfo => playerInfo.Dealt.Damage(currentBoss, timedEncounter)); break; case "dps": playerInfosOrdered = playerInfos.OrderBy(playerInfo => playerInfo.Dealt.Dps(currentBoss, timedEncounter)); break; case "crit_rate": playerInfosOrdered = playerInfos.OrderBy(playerInfo => playerInfo.Dealt.CritRate(currentBoss, timedEncounter)); break; case "hits_received": playerInfosOrdered = playerInfos.OrderBy(playerInfo => playerInfo.Received.Hits(currentBoss, firstHit, lastHit, timedEncounter)); break; default: Console.WriteLine("wrong value for orderby"); throw new Exception("wrong value for orderby"); } } else { switch (orderby) { case "damage_received": playerInfosOrdered = playerInfos.OrderByDescending(playerInfo => playerInfo.Received.Damage(currentBoss, firstHit, lastHit, timedEncounter)); break; case "hits_received": playerInfosOrdered = playerInfos.OrderByDescending(playerInfo => playerInfo.Received.Hits(currentBoss, firstHit, lastHit, timedEncounter)); break; case "name": playerInfosOrdered = playerInfos.OrderByDescending(playerInfo => playerInfo.Name); break; case "damage_percentage": playerInfosOrdered = playerInfos.OrderByDescending(playerInfo => playerInfo.Dealt.DamageFraction(currentBoss, totalDamage, timedEncounter)); break; case "damage_dealt": playerInfosOrdered = playerInfos.OrderByDescending(playerInfo => playerInfo.Dealt.Damage(currentBoss, timedEncounter)); break; case "dps": playerInfosOrdered = playerInfos.OrderByDescending(playerInfo => playerInfo.Dealt.Dps(currentBoss, timedEncounter)); break; case "crit_rate": playerInfosOrdered = playerInfos.OrderByDescending(playerInfo => playerInfo.Dealt.CritRate(currentBoss, timedEncounter)); break; default: Console.WriteLine("wrong value for orderby"); throw new Exception("wrong value for orderby"); } } var dpsString = header; var name = ""; double enrageperc = 0; if (currentBoss != null) { name = currentBoss.Name; AbnormalityDuration enrage; abnormals.Get(currentBoss.NpcE).TryGetValue(BasicTeraData.Instance.HotDotDatabase.Get(8888888), out enrage); enrageperc = (lastHit - firstHit) == 0 ? 0 : (((double)(enrage?.Duration(firstHit, lastHit) ?? 0) / (lastHit - firstHit))); } dpsString = dpsString.Replace("{encounter}", name); var interval = TimeSpan.FromSeconds(lastHit - firstHit); dpsString = dpsString.Replace("{timer}", interval.ToString(@"mm\:ss")); dpsString = dpsString.Replace("{partyDps}", FormatHelpers.Instance.FormatValue(partyDps) + "/s"); dpsString = dpsString.Replace("{enrage}", FormatHelpers.Instance.FormatPercent(enrageperc)); foreach (var playerStats in playerInfosOrdered) { var currentContent = content; if (playerStats.Dealt.Damage(currentBoss, timedEncounter) == 0) { continue; } var buffs = abnormals.Get(playerStats.Player); AbnormalityDuration slaying; buffs.Times.TryGetValue(BasicTeraData.Instance.HotDotDatabase.Get(8888889), out slaying); double slayingperc = (lastHit - firstHit) == 0 ? 0 : (((double)(slaying?.Duration(firstHit, lastHit) ?? 0) / (lastHit - firstHit))); currentContent = currentContent.Replace("{slaying}", FormatHelpers.Instance.FormatPercent(slayingperc)); currentContent = currentContent.Replace("{dps}", FormatHelpers.Instance.FormatValue(playerStats.Dealt.Dps(currentBoss, timedEncounter)) + "/s"); currentContent = currentContent.Replace("{global_dps}", FormatHelpers.Instance.FormatValue(playerStats.Dealt.GlobalDps(currentBoss, timedEncounter, lastHit - firstHit)) + "/s"); currentContent = currentContent.Replace("{interval}", playerStats.Dealt.Interval(currentBoss) + "s"); currentContent = currentContent.Replace("{damage_dealt}", FormatHelpers.Instance.FormatValue(playerStats.Dealt.Damage(currentBoss, timedEncounter))); currentContent = currentContent.Replace("{class}", playerStats.Class + ""); currentContent = currentContent.Replace("{fullname}", playerStats.Player.FullName); currentContent = currentContent.Replace("{name}", playerStats.Name); currentContent = currentContent.Replace("{deaths}", buffs.Death.Count(firstHit, lastHit) + ""); currentContent = currentContent.Replace("{death_duration}", TimeSpan.FromSeconds(buffs.Death.Duration(firstHit, lastHit)).ToString(@"mm\:ss")); currentContent = currentContent.Replace("{aggro}", buffs.Aggro(currentBoss?.NpcE).Count(firstHit, lastHit) + ""); currentContent = currentContent.Replace("{aggro_duration}", TimeSpan.FromSeconds(buffs.Aggro(currentBoss?.NpcE).Duration(firstHit, lastHit)).ToString(@"mm\:ss")); currentContent = currentContent.Replace("{damage_percentage}", playerStats.Dealt.DamageFraction(currentBoss, totalDamage, timedEncounter) + "%"); currentContent = currentContent.Replace("{crit_rate}", playerStats.Dealt.CritRate(currentBoss, timedEncounter) + "%"); currentContent = currentContent.Replace("{biggest_crit}", FormatHelpers.Instance.FormatValue(playerStats.Dealt.DmgBiggestCrit(currentBoss, timedEncounter))); currentContent = currentContent.Replace("{damage_received}", FormatHelpers.Instance.FormatValue(playerStats.Received.Damage(currentBoss, firstHit, lastHit, timedEncounter))); currentContent = currentContent.Replace("{hits_received}", FormatHelpers.Instance.FormatValue(playerStats.Received.Hits(currentBoss, firstHit, lastHit, timedEncounter))); dpsString += currentContent; } dpsString += footer; return(dpsString); }
public void Update(StatsSummary nstatsSummary, Database.Structures.Skills nskills, List <NpcEntity> nentities, bool ntimedEncounter, AbnormalityStorage nabnormals, ConcurrentDictionary <string, NpcEntity> nbossHistory, List <ChatMessage> nchatbox, int npacketWaiting, NotifyFlashMessage nflash) { void ChangeUi(StatsSummary statsSummary, Database.Structures.Skills skills, List <NpcEntity> entities, bool timedEncounter, AbnormalityStorage abnormals, ConcurrentDictionary <string, NpcEntity> bossHistory, List <ChatMessage> chatbox, int packetWaiting, NotifyFlashMessage flash) { Scroller.MaxHeight = BasicTeraData.Instance.WindowData.NumberOfPlayersDisplayed * 30; UpdateComboboxEncounter(entities, statsSummary.EntityInformation.Entity); _entityStats.Update(statsSummary.EntityInformation, abnormals); _windowHistory.Update(bossHistory); _chatbox?.Update(chatbox); NotifyIcon.ShowBallon(flash); NotifyIcon.UpdatePacketWaiting(packetWaiting); PartyDps.Content = FormatHelpers.Instance.FormatValue(statsSummary.EntityInformation.Interval == 0 ? statsSummary.EntityInformation.TotalDamage : statsSummary.EntityInformation.TotalDamage * TimeSpan.TicksPerSecond / statsSummary.EntityInformation.Interval) + LP.PerSecond; var visiblePlayerStats = new HashSet <Player>(); var statsDamage = statsSummary.PlayerDamageDealt; var statsHeal = statsSummary.PlayerHealDealt; foreach (var playerStats in statsDamage) { PlayerStats playerStatsControl; Controls.TryGetValue(playerStats.Source, out playerStatsControl); if (playerStats.Amount == 0) { continue; } visiblePlayerStats.Add(playerStats.Source); if (playerStatsControl != null) { continue; } playerStatsControl = new PlayerStats(playerStats, statsHeal.FirstOrDefault(x => x.Source == playerStats.Source), statsSummary.EntityInformation, skills, abnormals.Get(playerStats.Source)); Controls.Add(playerStats.Source, playerStatsControl); } var invisibleControls = Controls.Where(x => !visiblePlayerStats.Contains(x.Key)).ToList(); foreach (var invisibleControl in invisibleControls) { Controls[invisibleControl.Key].CloseSkills(); Controls.Remove(invisibleControl.Key); } TotalDamage.Content = FormatHelpers.Instance.FormatValue(statsSummary.EntityInformation.TotalDamage); if (BasicTeraData.Instance.WindowData.ShowTimeLeft && statsSummary.EntityInformation.TimeLeft > 0) { var interval = TimeSpan.FromSeconds(statsSummary.EntityInformation.TimeLeft / TimeSpan.TicksPerSecond); Timer.Content = interval.ToString(@"mm\:ss"); Timer.Foreground = Brushes.LightCoral; } else { var interval = TimeSpan.FromSeconds(statsSummary.EntityInformation.Interval / TimeSpan.TicksPerSecond); Timer.Content = interval.ToString(@"mm\:ss"); if (statsSummary.EntityInformation.Interval == 0 && BasicTeraData.Instance.WindowData.ShowTimeLeft) { Timer.Foreground = Brushes.LightCoral; } else { Timer.Foreground = Brushes.White; } } Players.Items.Clear(); foreach (var item in statsDamage) { if (!Controls.ContainsKey(item.Source)) { continue; } if (Players.Items.Contains(Controls[item.Source])) { BasicTeraData.LogError( "duplicate playerinfo: \r\n" + string.Join("\r\n ", statsDamage.Select(x => x.Source.ToString() + " -> " + x.Amount)), false, true); continue; } Players.Items.Add(Controls[item.Source]); Controls[item.Source].Repaint(item, statsHeal.FirstOrDefault(x => x.Source == item.Source), statsSummary.EntityInformation, skills, abnormals.Get(item.Source), timedEncounter); } if (BasicTeraData.Instance.WindowData.InvisibleUi) { if (Controls.Count > 0 && !ForceWindowVisibilityHidden) { Visibility = Visibility.Visible; } if (Controls.Count == 0) { Visibility = Visibility.Hidden; } } else { if (!ForceWindowVisibilityHidden) { Visibility = Visibility.Visible; } } if (ActualWidth != _oldWidth) // auto snap to right screen border on width change { var screen = Screen.FromHandle(new WindowInteropHelper(GetWindow(this)).Handle); // Transform screen point to WPF device independent point var source = PresentationSource.FromVisual(this); if (source?.CompositionTarget == null) { return; } var dx = source.CompositionTarget.TransformToDevice.M11; if (Math.Abs(screen.WorkingArea.X + screen.WorkingArea.Width - (Left + _oldWidth) * dx) < 50) //snap at 50 px { Left = Left + _oldWidth - ActualWidth; } _oldWidth = ActualWidth; } } Dispatcher.Invoke((NetworkController.UpdateUiHandler)ChangeUi, nstatsSummary, nskills, nentities, ntimedEncounter, nabnormals, nbossHistory, nchatbox, npacketWaiting, nflash); }
private void PacketAnalysisLoop() { try { Database.Database.Instance.DeleteAll(); } catch (Exception ex) { BasicTeraData.LogError( ex.Message + "\r\n" + ex.StackTrace + "\r\n" + ex.Source + "\r\n" + ex + "\r\n" + ex.Data + "\r\n" + ex.InnerException + "\r\n" + ex.TargetSite, true); MessageBox.Show(LP.MainWindow_Fatal_error); Exit(); } while (_keepAlive) { if (NeedToCopy != null) { var currentBoss = Encounter; var timedEncounter = TimedEncounter; var entityInfo = Database.Database.Instance.GlobalInformationEntity(currentBoss, 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(currentBoss); var heals = Database.Database.Instance.PlayerHealInformation(entityInfo.BeginTime, entityInfo.EndTime); var statsSummary = new StatsSummary(playersInfo, heals, entityInfo); var tmpcopy = NeedToCopy; var abnormals = AbnormalityStorage.Clone(currentBoss, entityInfo.BeginTime, entityInfo.EndTime); var pasteThread = new Thread(() => CopyThread(statsSummary, skills, abnormals, timedEncounter, tmpcopy)) { Priority = ThreadPriority.Highest }; pasteThread.SetApartmentState(ApartmentState.STA); pasteThread.Start(); NeedToCopy = null; } if (NeedToReset) { Reset(); NeedToReset = false; } if (NeedToResetCurrent) { ResetCurrent(); NeedToResetCurrent = false; } if (!NeedToExport.HasFlag(DataExporter.Dest.None)) { DataExporter.ManualExport(Encounter, AbnormalityStorage, NeedToExport); NeedToExport = DataExporter.Dest.None; } Encounter = NewEncounter; var packetsWaiting = TeraSniffer.Instance.Packets.Count; if (packetsWaiting > 5000) { PacketProcessing.Pause(); Database.Database.Instance.DeleteAll(); AbnormalityStorage = new AbnormalityStorage(); AbnormalityTracker = new AbnormalityTracker(EntityTracker, PlayerTracker, BasicTeraData.Instance.HotDotDatabase, AbnormalityStorage, DamageTracker.Instance.Update); HudManager.Instance.CurrentBosses.DisposeAll(); TeraSniffer.Instance.Packets = new ConcurrentQueue <Message>(); NotifyProcessor.Instance.S_LOAD_TOPO(null); RaisePause(true); } if (_forceUiUpdate) { UpdateUi(packetsWaiting); _forceUiUpdate = false; } CheckUpdateUi(packetsWaiting); Message obj; var successDequeue = TeraSniffer.Instance.Packets.TryDequeue(out obj); if (!successDequeue) { Thread.Sleep(1); continue; } var message = MessageFactory.Create(obj); if (message.GetType() == typeof(UnknownMessage)) { continue; } if (!PacketProcessing.Process(message)) { //Unprocessed packet } } }
public static void CopyThread(EntityInfo info, List <PlayerInfo> stats, AbnormalityStorage abnormals, long total, long partyDps, long firstHit, long lastHit, Entity currentBoss, bool timedEncounter, CopyKey copy) { var text = CopyPaste.Copy(info, stats, abnormals, total, partyDps, firstHit, lastHit, currentBoss, timedEncounter, copy.Header, copy.Content, copy.Footer, copy.OrderBy, copy.Order); CopyPaste.Paste(text); }
public static void CopyThread(StatsSummary stats, Skills skills, AbnormalityStorage abnormals, bool timedEncounter, CopyKey copy) { if (BasicTeraData.Instance.HotDotDatabase == null) return;//no database loaded yet => no need to do anything lock (pasteLock) { var text = CopyPaste.Copy(stats, skills, abnormals, timedEncounter, copy.Header, copy.Content, copy.Footer, copy.OrderBy, copy.Order,copy.LowDpsContent,copy.LowDpsThreshold); for (var i = 0; i < 3; i++) { try { Clipboard.SetText(text.Item2); break; } catch { Thread.Sleep(100); //Ignore } } CopyPaste.Paste(text.Item1); } }
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); }
public static Tuple<string, string> Copy(StatsSummary statsSummary, Skills skills, AbnormalityStorage abnormals, bool timedEncounter, string header, string content, string footer, string orderby, string order, string lowDpsContent, int lowDpsThreshold) { //stop if nothing to paste var entityInfo = statsSummary.EntityInformation; var playersInfos = statsSummary.PlayerDamageDealt; var firstTick = entityInfo.BeginTime; var lastTick = entityInfo.EndTime; var firstHit = firstTick/TimeSpan.TicksPerSecond; var lastHit = lastTick/TimeSpan.TicksPerSecond; var heals = statsSummary.PlayerHealDealt; playersInfos.RemoveAll(x => x.Amount == 0); IEnumerable<PlayerDamageDealt> playerInfosOrdered; if (order == "ascending") { switch (orderby) { case "damage_received": playerInfosOrdered = playersInfos.OrderBy( playerInfo => skills.DamageReceived(playerInfo.Source.User, entityInfo.Entity, timedEncounter)); break; case "name": playerInfosOrdered = playersInfos.OrderBy(playerInfo => playerInfo.Source.Name); break; case "damage_percentage": case "damage_dealt": case "dps": playerInfosOrdered = playersInfos.OrderBy(playerInfo => playerInfo.Amount); break; case "crit_rate": playerInfosOrdered = playersInfos.OrderBy(playerInfo => playerInfo.CritRate); break; case "hits_received": playerInfosOrdered = playersInfos.OrderBy( playerInfo => skills.HitsReceived(playerInfo.Source.User, entityInfo.Entity, timedEncounter)); break; default: Console.WriteLine("wrong value for orderby"); throw new Exception("wrong value for orderby"); } } else { switch (orderby) { case "damage_received": playerInfosOrdered = playersInfos.OrderByDescending( playerInfo => skills.DamageReceived(playerInfo.Source.User, entityInfo.Entity, timedEncounter)); break; case "name": playerInfosOrdered = playersInfos.OrderByDescending(playerInfo => playerInfo.Source.Name); break; case "damage_percentage": case "damage_dealt": case "dps": playerInfosOrdered = playersInfos.OrderByDescending(playerInfo => playerInfo.Amount); break; case "crit_rate": playerInfosOrdered = playersInfos.OrderByDescending(playerInfo => playerInfo.CritRate); break; case "hits_received": playerInfosOrdered = playersInfos.OrderByDescending( playerInfo => skills.HitsReceived(playerInfo.Source.User, entityInfo.Entity, timedEncounter)); break; default: Console.WriteLine("wrong value for orderby"); throw new Exception("wrong value for orderby"); } } var dpsString = new StringBuilder(header); var name = entityInfo.Entity?.Info.Name ?? ""; AbnormalityDuration enrage; var bossDebuff = abnormals.Get(entityInfo.Entity); bossDebuff.TryGetValue(BasicTeraData.Instance.HotDotDatabase.Enraged, out enrage); var enrageperc = lastTick - firstTick == 0 ? 0 : (double) (enrage?.Duration(firstTick, lastTick) ?? 0)/(lastTick - firstTick); dpsString.Replace("{encounter}", name); var interval = TimeSpan.FromSeconds(lastHit - firstHit); dpsString.Replace("{timer}", interval.ToString(@"mm\:ss")); dpsString.Replace("{partyDps}", FormatHelpers.Instance.FormatValue(lastHit - firstHit > 0 ? entityInfo.TotalDamage/(lastHit - firstHit) : 0) + LP.PerSecond); dpsString.Replace("{enrage}", FormatHelpers.Instance.FormatPercent(enrageperc)); dpsString.Replace("{debuff_list}", String.Join(" | ", bossDebuff.Where(x => x.Key.Id != 8888888 && x.Value.Duration(firstTick, lastTick) > 0).OrderByDescending(x => x.Value.Duration(firstTick, lastTick)).ToList().Select( x => x.Key.ShortName + " " + FormatHelpers.Instance.FormatPercent((double)x.Value.Duration(firstTick, lastTick) / (lastTick - firstTick)) + " (" + TimeSpan.FromTicks(x.Value.Duration(firstTick, lastTick)).ToString(@"mm\:ss") + ") ") )); dpsString.Replace("{debuff_list_p}", String.Join(" | ", bossDebuff.Where(x => x.Key.Id != 8888888 && x.Value.Duration(firstTick, lastTick) > 0).OrderByDescending(x => x.Value.Duration(firstTick, lastTick)).ToList().Select( x => x.Key.ShortName + " " + FormatHelpers.Instance.FormatPercent((double)x.Value.Duration(firstTick, lastTick) / (lastTick - firstTick))) )); var placeholders = new List<KeyValuePair<PlayerDamageDealt, Dictionary<string, string>>>(); foreach (var playerStats in playerInfosOrdered) { var playerHolder = new Dictionary<string, string>(); placeholders.Add(new KeyValuePair<PlayerDamageDealt, Dictionary<string, string>>(playerStats, playerHolder)); var buffs = abnormals.Get(playerStats.Source); AbnormalityDuration slaying; var firstOrDefault = heals.FirstOrDefault(x => x.Source == playerStats.Source); double healCritrate = 0; if (firstOrDefault != null) { healCritrate = firstOrDefault.CritRate; } buffs.Times.TryGetValue(BasicTeraData.Instance.HotDotDatabase.Slaying, out slaying); var slayingperc = lastTick - firstTick == 0 ? 0 : (double)(slaying?.Duration(firstTick, lastTick) ?? 0) / (lastTick - firstTick); playerHolder["{slaying}"] = FormatHelpers.Instance.FormatPercent(slayingperc); playerHolder["{dps}"] = FormatHelpers.Instance.FormatValue(playerStats.Interval == 0 ? playerStats.Amount : playerStats.Amount * TimeSpan.TicksPerSecond / playerStats.Interval) + LP.PerSecond; playerHolder["{global_dps}"] = FormatHelpers.Instance.FormatValue(entityInfo.Interval == 0 ? playerStats.Amount : playerStats.Amount * TimeSpan.TicksPerSecond / entityInfo.Interval) + LP.PerSecond; playerHolder["{interval}"] = playerStats.Interval/TimeSpan.TicksPerSecond + LP.Seconds; playerHolder["{damage_dealt}"] = FormatHelpers.Instance.FormatValue(playerStats.Amount); playerHolder["{class}"] = LP.ResourceManager.GetString(playerStats.Source.Class.ToString(), LP.Culture) + ""; playerHolder["{fullname}"] = playerStats.Source.FullName; playerHolder["{name}"] = playerStats.Source.Name; playerHolder["{deaths}"] = buffs.Death.Count(firstTick, lastTick) + ""; playerHolder["{death_duration}"] = TimeSpan.FromTicks(buffs.Death.Duration(firstTick, lastTick)).ToString(@"mm\:ss"); playerHolder["{aggro}"] = buffs.Aggro(entityInfo.Entity).Count(firstTick, lastTick) + ""; playerHolder["{aggro_duration}"] = TimeSpan.FromTicks(buffs.Aggro(entityInfo.Entity).Duration(firstTick, lastTick)).ToString(@"mm\:ss"); playerHolder["{damage_percentage}"] = playerStats.Amount * 100 / entityInfo.TotalDamage + "%"; playerHolder["{crit_rate}"] = playerStats.CritRate + "%"; playerHolder["{crit_rate_heal}"] = healCritrate + "%"; playerHolder["{biggest_crit}"] = FormatHelpers.Instance.FormatValue(skills.BiggestCrit(playerStats.Source.User, entityInfo.Entity, timedEncounter)); playerHolder["{damage_received}"] = FormatHelpers.Instance.FormatValue(skills.DamageReceived(playerStats.Source.User, entityInfo.Entity, timedEncounter)); playerHolder["{hits_received}"] = FormatHelpers.Instance.FormatValue(skills.HitsReceived(playerStats.Source.User, entityInfo.Entity, timedEncounter)); playerHolder["{debuff_list}"] = String.Join(" | ", bossDebuff.Where(x=>x.Key.Id!=8888888 && x.Value.InitialPlayerClass==playerStats.Source.Class && x.Value.Duration(firstTick,lastTick)>0).OrderByDescending(x => x.Value.Duration(firstTick, lastTick)).ToList().Select( x=>x.Key.ShortName + " " + FormatHelpers.Instance.FormatPercent((double)x.Value.Duration(firstTick,lastTick) / (lastTick - firstTick)) + " ("+ TimeSpan.FromTicks(x.Value.Duration(firstTick, lastTick)).ToString(@"mm\:ss")+") ") ); playerHolder["{debuff_list_p}"] = String.Join(" | ", bossDebuff.Where(x => x.Key.Id != 8888888 && x.Value.InitialPlayerClass == playerStats.Source.Class && x.Value.Duration(firstTick, lastTick) > 0).OrderByDescending(x => x.Value.Duration(firstTick, lastTick)).ToList().Select( x => x.Key.ShortName + " " + FormatHelpers.Instance.FormatPercent((double)x.Value.Duration(firstTick, lastTick) / (lastTick - firstTick))) ); } var placeholderLength = placeholders.SelectMany(x => x.Value).GroupBy(x=>x.Key).ToDictionary(x=>x.Key,x=>x.Max(z=> graphics.MeasureString(z.Value, Font, default(PointF), StringFormat.GenericTypographic).Width)); var dpsmono = new StringBuilder(dpsString.ToString()); var placeholderMono = placeholders.SelectMany(x => x.Value).GroupBy(x => x.Key).ToDictionary(x => x.Key, x => x.Max(z => z.Value.Length)); if ((content.Contains('\\')||lowDpsContent.Contains('\\')) && BasicTeraData.Instance.WindowData.FormatPasteString) placeholders.ForEach(x => { var currentContent = x.Key.Amount*100/entityInfo.TotalDamage >= lowDpsThreshold ? new StringBuilder(content): new StringBuilder(lowDpsContent); x.Value.ToList().ForEach(z => currentContent.Replace(z.Key, PadRight(z.Value,placeholderLength[z.Key]))); dpsString.Append(currentContent); currentContent = x.Key.Amount * 100 / entityInfo.TotalDamage >= lowDpsThreshold ? new StringBuilder(content) : new StringBuilder(lowDpsContent); x.Value.ToList().ForEach(z => currentContent.Replace(z.Key, z.Value.PadRight(placeholderMono[z.Key]))); dpsmono.Append(currentContent); }); else { placeholders.ForEach(x => { var currentContent = x.Key.Amount * 100 / entityInfo.TotalDamage >= lowDpsThreshold ? new StringBuilder(content) : new StringBuilder(lowDpsContent); x.Value.ToList().ForEach(z => currentContent.Replace(z.Key, z.Value)); dpsString.Append(currentContent); }); dpsmono = dpsString; } var footerstr=footer.Replace("{debuff_list}", String.Join(" | ", bossDebuff.Where(x => x.Key.Id != 8888888 && x.Value.Duration(firstTick, lastTick) > 0).OrderByDescending(x => x.Value.Duration(firstTick, lastTick)).ToList().Select( x => x.Key.ShortName + " " + FormatHelpers.Instance.FormatPercent((double)x.Value.Duration(firstTick, lastTick) / (lastTick - firstTick)) + " (" + TimeSpan.FromTicks(x.Value.Duration(firstTick, lastTick)).ToString(@"mm\:ss") + ") ") )).Replace("{debuff_list_p}", String.Join(" | ", bossDebuff.Where(x => x.Key.Id != 8888888 && x.Value.Duration(firstTick, lastTick) > 0).OrderByDescending(x => x.Value.Duration(firstTick, lastTick)).ToList().Select( x => x.Key.ShortName + " " + FormatHelpers.Instance.FormatPercent((double)x.Value.Duration(firstTick, lastTick) / (lastTick - firstTick))) )); dpsString.Append(footerstr); dpsmono.Append(footerstr); var paste = dpsString.ToString(); var monoPaste = dpsmono.ToString(); while (paste.Contains(" \\")) paste = paste.Replace(" \\", "\\"); while (monoPaste.Contains(" \\")) monoPaste = monoPaste.Replace(" \\", "\\"); monoPaste = monoPaste.Replace("\\", Environment.NewLine); return new Tuple<string,string>(paste ,monoPaste); }
public void Update(StatsSummary nstatsSummary, Database.Structures.Skills nskills, List <NpcEntity> nentities, bool ntimedEncounter, AbnormalityStorage nabnormals, ConcurrentDictionary <string, NpcEntity> nbossHistory, List <ChatMessage> nchatbox, int npacketWaiting) { NetworkController.UpdateUiHandler changeUi = delegate(StatsSummary statsSummary, Database.Structures.Skills skills, List <NpcEntity> entities, bool timedEncounter, AbnormalityStorage abnormals, ConcurrentDictionary <string, NpcEntity> bossHistory, List <ChatMessage> chatbox, int packetWaiting) { UpdateComboboxEncounter(entities, statsSummary.EntityInformation.Entity); _entityStats.Update(statsSummary.EntityInformation, abnormals); _windowHistory.Update(bossHistory); _chatbox.Update(chatbox); _systemTray.UpdatePacketWaiting(packetWaiting); PartyDps.Content = FormatHelpers.Instance.FormatValue(statsSummary.EntityInformation.Interval == 0 ? statsSummary.EntityInformation.TotalDamage : statsSummary.EntityInformation.TotalDamage * TimeSpan.TicksPerSecond / statsSummary.EntityInformation.Interval) + LP.PerSecond; var visiblePlayerStats = new HashSet <Player>(); var statsDamage = statsSummary.PlayerDamageDealt; var statsHeal = statsSummary.PlayerHealDealt; foreach (var playerStats in statsDamage) { PlayerStats playerStatsControl; Controls.TryGetValue(playerStats.Source, out playerStatsControl); if (playerStats.Amount == 0) { continue; } visiblePlayerStats.Add(playerStats.Source); if (playerStatsControl != null) { continue; } playerStatsControl = new PlayerStats(playerStats, statsHeal.FirstOrDefault(x => x.Source == playerStats.Source), statsSummary.EntityInformation, skills, abnormals.Get(playerStats.Source)); Controls.Add(playerStats.Source, playerStatsControl); } var invisibleControls = Controls.Where(x => !visiblePlayerStats.Contains(x.Key)).ToList(); foreach (var invisibleControl in invisibleControls) { Controls[invisibleControl.Key].CloseSkills(); Controls.Remove(invisibleControl.Key); } TotalDamage.Content = FormatHelpers.Instance.FormatValue(statsSummary.EntityInformation.TotalDamage); var interval = TimeSpan.FromSeconds(statsSummary.EntityInformation.Interval / TimeSpan.TicksPerSecond); Timer.Content = interval.ToString(@"mm\:ss"); Players.Items.Clear(); foreach (var item in statsDamage) { if (!Controls.ContainsKey(item.Source)) { continue; } if (Players.Items.Contains(Controls[item.Source])) { BasicTeraData.LogError("duplicate playerinfo: \r\n" + String.Join("\r\n ", statsDamage.Select(x => x.Source.ToString() + " -> " + x.Target + ": " + x.Amount)), false, true); continue; } Players.Items.Add(Controls[item.Source]); Controls[item.Source].Repaint(item, statsHeal.FirstOrDefault(x => x.Source == item.Source), statsSummary.EntityInformation, skills, abnormals.Get(item.Source), timedEncounter); } if (BasicTeraData.Instance.WindowData.InvisibleUi) { if (Controls.Count > 0 && !ForceWindowVisibilityHidden) { Visibility = Visibility.Visible; } if (Controls.Count == 0) { Visibility = Visibility.Hidden; } } else { if (!ForceWindowVisibilityHidden) { Visibility = Visibility.Visible; } } }; Dispatcher.Invoke(changeUi, nstatsSummary, nskills, nentities, ntimedEncounter, nabnormals, nbossHistory, nchatbox, npacketWaiting); }
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(); }
public static string Copy(StatsSummary statsSummary, Skills skills, AbnormalityStorage abnormals, bool timedEncounter, string header, string content, string footer, string orderby, string order) { //stop if nothing to paste var entityInfo = statsSummary.EntityInformation; var playersInfos = statsSummary.PlayerDamageDealt; var firstTick = entityInfo.BeginTime; var lastTick = entityInfo.EndTime; var firstHit = firstTick / TimeSpan.TicksPerSecond; var lastHit = lastTick / TimeSpan.TicksPerSecond; var heals = statsSummary.PlayerHealDealt; playersInfos.RemoveAll(x => x.Amount == 0); IEnumerable <PlayerDamageDealt> playerInfosOrdered; if (order == "ascending") { switch (orderby) { case "damage_received": playerInfosOrdered = playersInfos.OrderBy( playerInfo => skills.DamageReceived(playerInfo.Source.User.Id, entityInfo.Entity, timedEncounter)); break; case "name": playerInfosOrdered = playersInfos.OrderBy(playerInfo => playerInfo.Source.Name); break; case "damage_percentage": case "damage_dealt": case "dps": playerInfosOrdered = playersInfos.OrderBy(playerInfo => playerInfo.Amount); break; case "crit_rate": playerInfosOrdered = playersInfos.OrderBy(playerInfo => playerInfo.CritRate); break; case "hits_received": playerInfosOrdered = playersInfos.OrderBy( playerInfo => skills.HitsReceived(playerInfo.Source.User.Id, entityInfo.Entity, timedEncounter)); break; default: Console.WriteLine("wrong value for orderby"); throw new Exception("wrong value for orderby"); } } else { switch (orderby) { case "damage_received": playerInfosOrdered = playersInfos.OrderByDescending( playerInfo => skills.DamageReceived(playerInfo.Source.User.Id, entityInfo.Entity, timedEncounter)); break; case "name": playerInfosOrdered = playersInfos.OrderByDescending(playerInfo => playerInfo.Source.Name); break; case "damage_percentage": case "damage_dealt": case "dps": playerInfosOrdered = playersInfos.OrderByDescending(playerInfo => playerInfo.Amount); break; case "crit_rate": playerInfosOrdered = playersInfos.OrderByDescending(playerInfo => playerInfo.CritRate); break; case "hits_received": playerInfosOrdered = playersInfos.OrderByDescending( playerInfo => skills.HitsReceived(playerInfo.Source.User.Id, entityInfo.Entity, timedEncounter)); break; default: Console.WriteLine("wrong value for orderby"); throw new Exception("wrong value for orderby"); } } var dpsString = header; var name = entityInfo.Entity?.Info.Name ?? ""; AbnormalityDuration enrage; abnormals.Get(entityInfo.Entity).TryGetValue(BasicTeraData.Instance.HotDotDatabase.Get(8888888), out enrage); var enrageperc = lastTick - firstTick == 0 ? 0 : (double)(enrage?.Duration(firstTick, lastTick) ?? 0) / (lastTick - firstTick); dpsString = dpsString.Replace("{encounter}", name); var interval = TimeSpan.FromSeconds(lastHit - firstHit); dpsString = dpsString.Replace("{timer}", interval.ToString(@"mm\:ss")); dpsString = dpsString.Replace("{partyDps}", FormatHelpers.Instance.FormatValue(lastHit - firstHit > 0 ? entityInfo.TotalDamage / (lastHit - firstHit) : 0) + LP.PerSecond); dpsString = dpsString.Replace("{enrage}", FormatHelpers.Instance.FormatPercent(enrageperc)); foreach (var playerStats in playerInfosOrdered) { var currentContent = content; var buffs = abnormals.Get(playerStats.Source); AbnormalityDuration slaying; var firstOrDefault = heals.FirstOrDefault(x => x.Source == playerStats.Source); double healCritrate = 0; if (firstOrDefault != null) { healCritrate = firstOrDefault.CritRate; } buffs.Times.TryGetValue(BasicTeraData.Instance.HotDotDatabase.Get(8888889), out slaying); var slayingperc = lastTick - firstTick == 0 ? 0 : (double)(slaying?.Duration(firstTick, lastTick) ?? 0) / (lastTick - firstTick); currentContent = currentContent.Replace("{slaying}", FormatHelpers.Instance.FormatPercent(slayingperc)); currentContent = currentContent.Replace("{dps}", FormatHelpers.Instance.FormatValue(playerStats.Interval == 0 ? playerStats.Amount : playerStats.Amount * TimeSpan.TicksPerSecond / playerStats.Interval) + "/s"); currentContent = currentContent.Replace("{global_dps}", FormatHelpers.Instance.FormatValue(entityInfo.Interval == 0 ? playerStats.Amount : playerStats.Amount * TimeSpan.TicksPerSecond / entityInfo.Interval) + "/s"); currentContent = currentContent.Replace("{interval}", playerStats.Interval + LP.Seconds); currentContent = currentContent.Replace("{damage_dealt}", FormatHelpers.Instance.FormatValue(playerStats.Amount)); currentContent = currentContent.Replace("{class}", playerStats.Source.Class + ""); currentContent = currentContent.Replace("{fullname}", playerStats.Source.FullName); currentContent = currentContent.Replace("{name}", playerStats.Source.Name); currentContent = currentContent.Replace("{deaths}", buffs.Death.Count(firstTick, lastTick) + ""); currentContent = currentContent.Replace("{death_duration}", TimeSpan.FromTicks(buffs.Death.Duration(firstTick, lastTick)).ToString(@"mm\:ss")); currentContent = currentContent.Replace("{aggro}", buffs.Aggro(entityInfo.Entity).Count(firstTick, lastTick) + ""); currentContent = currentContent.Replace("{aggro_duration}", TimeSpan.FromTicks(buffs.Aggro(entityInfo.Entity).Duration(firstTick, lastTick)) .ToString(@"mm\:ss")); currentContent = currentContent.Replace("{damage_percentage}", playerStats.Amount * 100 / entityInfo.TotalDamage + "%"); currentContent = currentContent.Replace("{crit_rate}", playerStats.CritRate + "%"); currentContent = currentContent.Replace("{crit_rate_heal}", healCritrate + "%"); currentContent = currentContent.Replace("{biggest_crit}", FormatHelpers.Instance.FormatValue(skills.BiggestCrit(playerStats.Source.User.Id, entityInfo.Entity, timedEncounter))); currentContent = currentContent.Replace("{damage_received}", FormatHelpers.Instance.FormatValue(skills.DamageReceived(playerStats.Source.User.Id, entityInfo.Entity, timedEncounter))); currentContent = currentContent.Replace("{hits_received}", FormatHelpers.Instance.FormatValue(skills.HitsReceived(playerStats.Source.User.Id, entityInfo.Entity, timedEncounter))); dpsString += currentContent; } dpsString += footer; return(dpsString); }
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); }