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); }
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)); }