public SkillAggregate(Skill skill, Skills skillsData, Entity source, Entity target, PlayerDamageDealt playerDamageDealt, bool timed, Database.Database.Type type) { _playerDamageDealt = playerDamageDealt; _timed = timed; _target = target; Type = type; Skills = new Dictionary<Skill, List<Entity>>(); Name = skill.ShortName; SkillsData = skillsData; Skills.Add(skill, new List<Entity>{ source }); }
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); } }
public static IEnumerable<SkillAggregate> GetAggregate(PlayerDamageDealt playerDamageDealt, Entity entity, Skills skillsData, bool timedEncounter, Database.Database.Type type) { if(skillsData==null)return new List<SkillAggregate>(); if (type != Database.Database.Type.Damage) { timedEncounter = false; } if (!playerDamageDealt.Source.IsHealer && type != Database.Database.Type.Damage) { var skills = skillsData.SkillsIdByTarget(playerDamageDealt.Source.User); var skillsAggregate = new Dictionary<string, SkillAggregate>(); foreach (var skill in skills) { if (skill.Value == null) continue; if (!skillsData.Type(skill.Key, playerDamageDealt.Source.User, skill.Value.Id, skill.Value.NpcInfo, false, type) ) { continue; } if (!skillsAggregate.ContainsKey(skill.Value.ShortName)) { skillsAggregate.Add(skill.Value.ShortName, new SkillAggregate(skill.Value, skillsData, skill.Key, playerDamageDealt.Source.User, playerDamageDealt, false, type)); continue; } skillsAggregate[skill.Value.ShortName].Add(skill.Value, skill.Key); } return skillsAggregate.Values; } if (playerDamageDealt.Source.IsHealer && type != Database.Database.Type.Damage) { var skills = skillsData.SkillsIdBySource(playerDamageDealt.Source.User, null, true); var skillsAggregate = new Dictionary<string, SkillAggregate>(); foreach (var skill in skills) { if (skill == null) continue; if (!skillsData.Type(playerDamageDealt.Source.User, null, skill.Id, skill.NpcInfo, true, type)) { continue; } if (!skillsAggregate.ContainsKey(skill.ShortName)) { skillsAggregate.Add(skill.ShortName, new SkillAggregate(skill, skillsData, playerDamageDealt.Source.User, null, playerDamageDealt, true, type)); continue; } skillsAggregate[skill.ShortName].Add(skill, playerDamageDealt.Source.User); } return skillsAggregate.Values; } else { var skills = skillsData.SkillsIdBySource(playerDamageDealt.Source.User, entity, timedEncounter); var skillsAggregate = new Dictionary<string, SkillAggregate>(); foreach (var skill in skills) { if (skill == null) continue; if (!skillsData.Type(playerDamageDealt.Source.User, entity, skill.Id, skill.NpcInfo , timedEncounter, type)) { continue; } if (!skillsAggregate.ContainsKey(skill.ShortName)) { skillsAggregate.Add(skill.ShortName, new SkillAggregate(skill, skillsData, playerDamageDealt.Source.User, entity, playerDamageDealt, timedEncounter, type)); continue; } skillsAggregate[skill.ShortName].Add(skill, playerDamageDealt.Source.User); } return skillsAggregate.Values; } }
public Skills GetSkills(long beginTime, long endTime) { var sql = "SELECT amount, type, target, targetServerIdPlayerId , source, sourceServerIdPlayerId, pet_zone, pet_id, skill_id, hotdot, critic, time, direction FROM skills WHERE time BETWEEN $begin AND $end ;"; var command = new SQLiteCommand(sql, Connexion); command.Parameters.AddWithValue("$begin", beginTime); command.Parameters.AddWithValue("$end", endTime); var targetSourceSkills = new Dictionary<Entity, Dictionary<Entity, List<Skill>>>(); var sourceTargetSkills = new Dictionary<Entity, Dictionary<Entity, List<Skill>>>(); var sourceTargetIdSkill = new Dictionary<Entity, Dictionary<Entity, Dictionary<int, List<Skill>>>>(); var sourceIdSkill = new Dictionary<Entity, Dictionary<int, List<Skill>>>(); var rdr = command.ExecuteReader(); command.Dispose(); while (rdr.Read()) { var amount = rdr.GetFieldValue<long>(rdr.GetOrdinal("amount")); var type = (Type) rdr.GetFieldValue<long>(rdr.GetOrdinal("type")); var target = new EntityId((ulong) rdr.GetFieldValue<long>(rdr.GetOrdinal("target"))); var targetServerIdPlayerId = rdr.IsDBNull(rdr.GetOrdinal("targetServerIdPlayerId")) ? 0 : (ulong)rdr.GetFieldValue<long>(rdr.GetOrdinal("targetServerIdPlayerId")); var source = new EntityId((ulong) rdr.GetFieldValue<long>(rdr.GetOrdinal("source"))); var sourceServerIdPlayerId = rdr.IsDBNull(rdr.GetOrdinal("sourceServerIdPlayerId")) ? 0 : (ulong)rdr.GetFieldValue<long>(rdr.GetOrdinal("sourceServerIdPlayerId")); var skillid = rdr.GetFieldValue<long>(rdr.GetOrdinal("skill_id")); var direction = (HitDirection)rdr.GetFieldValue<long>(rdr.GetOrdinal("direction")); var critic = rdr.GetFieldValue<long>(rdr.GetOrdinal("critic")) == 1; var hotdot = rdr.GetFieldValue<long>(rdr.GetOrdinal("hotdot")) == 1; var time = rdr.GetFieldValue<long>(rdr.GetOrdinal("time")); var petZone = rdr.IsDBNull(rdr.GetOrdinal("pet_zone")) ? 0 : rdr.GetFieldValue<long>(rdr.GetOrdinal("pet_zone")); var petId = rdr.IsDBNull(rdr.GetOrdinal("pet_id")) ? 0 : rdr.GetFieldValue<long>(rdr.GetOrdinal("pet_id")); var pet = BasicTeraData.Instance.MonsterDatabase.GetOrNull((ushort)petZone, (uint)petId); Player sourcePlayer = null; if (sourceServerIdPlayerId != 0) { sourcePlayer = NetworkController.Instance.PlayerTracker.Get((uint)(sourceServerIdPlayerId >> 32), (uint)(sourceServerIdPlayerId << 32 >> 32)); } Player targetPlayer = null; if (targetServerIdPlayerId != 0) { targetPlayer = NetworkController.Instance.PlayerTracker.Get((uint)(targetServerIdPlayerId >> 32), (uint)(targetServerIdPlayerId << 32 >> 32)); } var entityTarget = NetworkController.Instance.EntityTracker.GetOrNull(target); var entitySource = NetworkController.Instance.EntityTracker.GetOrNull(source); var skill = new Skill(amount, type, entityTarget, targetPlayer, entitySource, sourcePlayer, (int) skillid, hotdot, critic, time, pet, direction); if (!targetSourceSkills.ContainsKey(skill.Target)) { targetSourceSkills.Add(skill.Target, new Dictionary<Entity, List<Skill>>()); } if (!targetSourceSkills[skill.Target].ContainsKey(skill.Source)) { targetSourceSkills[skill.Target].Add(skill.Source, new List<Skill>()); } if (!sourceTargetSkills.ContainsKey(skill.Source)) { sourceTargetIdSkill.Add(skill.Source, new Dictionary<Entity, Dictionary<int, List<Skill>>>()); sourceIdSkill.Add(skill.Source, new Dictionary<int, List<Skill>>()); sourceTargetSkills.Add(skill.Source, new Dictionary<Entity, List<Skill>>()); } if (!sourceTargetSkills[skill.Source].ContainsKey(skill.Target)) { sourceTargetSkills[skill.Source].Add(skill.Target, new List<Skill>()); sourceTargetIdSkill[skill.Source].Add(skill.Target, new Dictionary<int, List<Skill>>()); } if (!sourceTargetIdSkill[skill.Source][skill.Target].ContainsKey(skill.SkillId)) { sourceTargetIdSkill[skill.Source][skill.Target].Add(skill.SkillId, new List<Skill>()); } if (!sourceIdSkill[skill.Source].ContainsKey(skill.SkillId)) { sourceIdSkill[skill.Source].Add(skill.SkillId, new List<Skill>()); } targetSourceSkills[skill.Target][skill.Source].Add(skill); sourceTargetSkills[skill.Source][skill.Target].Add(skill); sourceTargetIdSkill[skill.Source][skill.Target][skill.SkillId].Add(skill); sourceIdSkill[skill.Source][skill.SkillId].Add(skill); } var skills = new Skills(sourceTargetSkills, targetSourceSkills, sourceTargetIdSkill, sourceIdSkill); return skills; }
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); }