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;
            }
        }
Beispiel #4
0
        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;
        }
Beispiel #5
0
        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);
        }