상속: PropertyObservable
예제 #1
0
        public PlayerInfo(Player user, DamageTracker tracker)
        {
            Tracker = tracker;
            Player = user;
            SkillLog = CollectionHelper.Instance.CreateSyncedCollection<SkillResult>();

            Received = new SkillStats(tracker, SkillLog);
            Dealt = new SkillStats(tracker, SkillLog);
        }
예제 #2
0
        public PlayerInfo(Player user, DamageTracker tracker)
        {
            Tracker  = tracker;
            Player   = user;
            SkillLog = new SynchronizedObservableCollection <SkillResult>();

            Received = new SkillStats(tracker, SkillLog);
            Dealt    = new SkillStats(tracker, SkillLog);
        }
예제 #3
0
        private void ResetDamageTracker(ResetPlayerStatsMessage message = null)
        {
            if (Server == null) return;

            var saveEncounter = message != null && message.ShouldSaveCurrent;
            if (saveEncounter && !DamageTracker.IsArchived && DamageTracker.StatsByUser.Count > 0 &&
                DamageTracker.FirstAttack != null && DamageTracker.LastAttack != null)
            {
                DamageTracker.IsArchived = true;
                DamageTracker.Abnormals = _abnormalityStorage.Clone();
                ArchivedDamageTrackers.Add(DamageTracker);
                return;
            }
            if (message != null && !message.ShouldSaveCurrent && DamageTracker.IsArchived)
            {
                ArchivedDamageTrackers.Remove(DamageTracker);
            }

            _abnormalityStorage.ClearEnded();
            DamageTracker = new DamageTracker
            {
                OnlyBosses = OnlyBosses,
                IgnoreOneshots = IgnoreOneshots,
                Abnormals = _abnormalityStorage
            };
        }
예제 #4
0
 private void LoadEncounter(DamageTracker obj)
 {
     DamageTracker = obj;
 }
예제 #5
0
 /// <summary>
 /// Creates a new instance of SkillStats
 /// </summary>
 /// <param name="tracker">DamageTracker used for calculations</param>
 /// <param name="skillLog">SkillLog used for calculations</param>
 public SkillStats(DamageTracker tracker, SyncedCollection<SkillResult> skillLog)
 {
     _tracker = tracker;
     _skillLog = skillLog;
 }
예제 #6
0
 public static bool IsValid(this EachSkillResultServerMessage message, DamageTracker tracker = null)
 {
     return(message != null && !message.IsUseless &&                                            //stuff like warrior DFA
            (tracker?.FirstAttack != null || (!message.IsHeal && message.Amount > 0)) &&        //only record first hit is it's a damage hit (heals occurring outside of fights)
            !(message.Target.Equals(message.Source) && !message.IsHeal && message.Amount > 0)); //disregard damage dealt to self (gunner self destruct)
 }
예제 #7
0
 public static bool IsValid(this EachSkillResultServerMessage message, DamageTracker tracker = null)
 {
     return message != null && !message.IsUseless && //stuff like warrior DFA
            (tracker?.FirstAttack != null || (!message.IsHeal && message.Amount > 0)) &&//only record first hit is it's a damage hit (heals occurring outside of fights)
            !(message.Target.Equals(message.Source) && !message.IsHeal && message.Amount > 0);//disregard damage dealt to self (gunner self destruct)
 }
예제 #8
0
 /// <summary>
 /// Creates a new instance of SkillStats
 /// </summary>
 /// <param name="tracker">DamageTracker used for calculations</param>
 /// <param name="skillLog">SkillLog used for calculations</param>
 public SkillStats(DamageTracker tracker, SynchronizedObservableCollection <SkillResult> skillLog)
 {
     _tracker  = tracker;
     _skillLog = skillLog;
 }
예제 #9
0
        public static void ToTeraDpsApi(ExportType exportType, DamageTracker damageTracker, TeraData teraData)
        {
            if (exportType == ExportType.None) return;

            //if we want to upload, primary target must be dead
            if (exportType.HasFlag(ExportType.Upload) && !damageTracker.IsPrimaryTargetDead)
                return;

            var exportToExcel = (exportType & (ExportType.Excel | ExportType.ExcelTemp)) != 0;
            //if we're not exporting to excel and credentials aren't fully entered, return
            //if (!exportToExcel
            //    && (string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsToken)
            //        || string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsUser)))
            //    return;

            //ignore if not a boss
            var entity = damageTracker.PrimaryTarget;
            if (!(entity?.Info.Boss ?? false)) return;

            var abnormals = damageTracker.Abnormals;

            bool timedEncounter = false;
            //Nightmare desolarus
            if (entity.Info.HuntingZoneId == 759 && entity.Info.TemplateId == 1003)
            {
                timedEncounter = true;
            }

            var firstHit = damageTracker.StatsByUser.SelectMany(x => x.SkillLog).Where(x => x.Target == entity).Min(x => x.Time as DateTime?) ?? new DateTime(0);
            var lastHit  = damageTracker.StatsByUser.SelectMany(x => x.SkillLog).Where(x => x.Target == entity).Max(x => x.Time as DateTime?) ?? new DateTime(0);
            var firstTick = firstHit.Ticks;
            var lastTick = lastHit.Ticks;
            var interval = lastTick - firstTick;
            var seconds = interval/TimeSpan.TicksPerSecond;
            if (seconds == 0) return;
            long totaldamage;
            if (timedEncounter)
                totaldamage =
                    damageTracker.StatsByUser.SelectMany(x => x.SkillLog)
                        .Where(x => x.Time >= firstHit && x.Time <= lastHit)
                        .Sum(x => x.Damage);
            else
                totaldamage =
                    damageTracker.StatsByUser.SelectMany(x => x.SkillLog)
                        .Where(x => x.Target == entity)
                        .Sum(x => x.Damage);

            var partyDps = TimeSpan.TicksPerSecond * totaldamage / interval;
            var teradpsData = new EncounterBase
            {
                encounterUnixEpoch = DateTimeTools.DateTimeToUnixTimestamp(damageTracker.LastAttack?.ToUniversalTime() ?? DateTime.UtcNow),
                areaId = entity.Info.HuntingZoneId + "",
                bossId = entity.Info.TemplateId + "",
                fightDuration = seconds + "",
                partyDps = partyDps + ""
            };

            foreach (var debuff in abnormals.Get(entity).OrderByDescending(x=>x.Value.Duration(firstTick, lastTick)))
            {
                long percentage = debuff.Value.Duration(firstTick, lastTick) * 100 / interval;
                if(percentage == 0)
                {
                    continue;
                }
                teradpsData.debuffUptime.Add(new KeyValuePair<string, string>(
                    debuff.Key.Id+"", percentage+""
                    ));
            }

            foreach (var user in damageTracker.StatsByUser.OrderByDescending(x=>x.Dealt.Damage))
            {
                var filteredSkillog = timedEncounter
                    ? user.SkillLog.Where(x => x.Time >= firstHit && x.Time <= lastHit).ToList()
                    : user.SkillLog.Where(x => x.Target == entity).ToList();

                long damage=filteredSkillog.Sum(x => x.Damage);
                if (damage <= 0) continue;

                var teradpsUser = new Members();

                teradpsUser.playerTotalDamage = damage + "";
                var buffs = abnormals.Get(user.Player);
                teradpsUser.playerClass = user.Class.ToString();
                teradpsUser.playerName = user.Name;
                teradpsUser.playerServer = SettingsHelper.Instance.BasicTeraData.Servers.GetServerName(user.Player.ServerId);
                teradpsUser.playerAverageCritRate = Math.Round(100 * (double)filteredSkillog.Count(x => x.IsCritical && x.Damage > 0) / filteredSkillog.Count(x => x.Damage > 0)) + "";
                teradpsUser.healCrit = user.Player.IsHealer ? Math.Round(100 * (double)filteredSkillog.Count(x => x.IsCritical && x.Heal > 0) / filteredSkillog.Count(x => x.Heal > 0)) + "" : null;
                teradpsUser.playerDps = TimeSpan.TicksPerSecond * damage / interval + "";
                teradpsUser.playerTotalDamagePercentage = damage * 100 / totaldamage + "";

                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) / interval + "";

                foreach (var buff in buffs.Times.OrderByDescending(x => x.Value.Duration(firstTick, lastTick)))
                {
                    long percentage = (buff.Value.Duration(firstTick, lastTick) * 100 / interval);
                    if (percentage == 0)
                    {
                        continue;
                    }
                    teradpsUser.buffUptime.Add(new KeyValuePair<string, string>(
                        buff.Key.Id + "", percentage + ""
                    ));
                }

                var aggregated = new List<AggregatedSkillResult>();
                var collection = new List<SkillResult>();
                foreach (var skill in filteredSkillog)
                {
                    collection.Add(skill);
                    if (aggregated.All(asr => !skill.IsSameSkillAs(asr)))
                        aggregated.Add(new AggregatedSkillResult(skill.SkillShortName, skill.IsHeal,
                            AggregationType.Name, CollectionHelper.Instance.CreateSyncedCollection(collection)));
                }
                foreach (var skill in aggregated.OrderByDescending(x=>x.Damage))
                {
                    var skillLog = new SkillLog();
                    var skilldamage = skill.Damage;
                    if (skilldamage == 0) continue;

                    skillLog.skillAverageCrit = skill.AverageCrit + "";
                    skillLog.skillAverageWhite = skill.AverageWhite + "";
                    skillLog.skillCritRate = Math.Round(skill.CritRate * 100) + "";
                    skillLog.skillDamagePercent = Math.Round(skill.DamagePercent * 100) + "";
                    skillLog.skillHighestCrit = skill.HighestCrit + "";
                    skillLog.skillHits = skill.Hits + "";
                    skillLog.skillId = teraData.SkillDatabase.GetSkillByPetName(skill.NpcInfo?.Name,user.Player.RaceGenderClass)?.Id.ToString() ?? skill.SkillId.ToString();
                    skillLog.skillLowestCrit = skill.LowestCrit + "";
                    skillLog.skillTotalDamage = skilldamage + "";

                    teradpsUser.skillLog.Add(skillLog);
                }
                teradpsData.members.Add(teradpsUser);
            }

            //export to excel if specified
            if (exportToExcel) Task.Run(() => ExcelExport.ExcelSave(exportType, teradpsData, teraData));

            //return if we don't need to upload
            if (!exportType.HasFlag(ExportType.Upload)) return;

            /*
              Validation, without that, the server cpu will be burning \o
            */
            var areaId = int.Parse(teradpsData.areaId);
            if (
                //areaId != 886 &&
                //areaId != 467 &&
                //areaId != 767 &&
                //areaId != 768 &&
                //areaId != 468 &&
                areaId != 770 &&
                areaId != 769 &&
                areaId != 916 &&
                areaId != 969 &&
                areaId != 970 &&
                areaId != 950
                )
            {
                return;
            }

            //if (int.Parse(teradpsData.partyDps) < 2000000 && areaId != 468)
            //{
            //    return;
            //}
            try
            {
                using (var client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromSeconds(40);
                    var response = client.GetAsync("http://moongourd.com/shared/servertime");
                    var timediff = (response.Result.Headers.Date.Value.UtcDateTime.Ticks - DateTime.UtcNow.Ticks) / TimeSpan.TicksPerSecond;
                    teradpsData.encounterUnixEpoch += timediff;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("Get server time error");
                return;
            }
            var json = JsonConvert.SerializeObject(teradpsData, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
            Task.Run(() => Send(entity, json, 3));
        }