예제 #1
0
        public SkillResult(int amount, bool isCritical, bool isHp, bool isHeal, HotDot hotdot, EntityId source,
                           EntityId target, DateTime time,
                           EntityTracker entityRegistry, PlayerTracker playerTracker)
        {
            Time        = time;
            Amount      = isHp ? Math.Abs(amount) : amount;
            IsCritical  = isCritical;
            IsHp        = isHp;
            IsHeal      = isHeal;
            SkillId     = hotdot.Id;
            Abnormality = true;

            Source = entityRegistry.GetOrPlaceholder(source);
            Target = entityRegistry.GetOrPlaceholder(target);
            var userNpc    = UserEntity.ForEntity(Source);
            var sourceUser = userNpc["root_source"] as UserEntity; // Attribute damage dealt by owned entities to the owner
            var targetUser = Target as UserEntity;                 // But don't attribute damage received by owned entities to the owner

            var pclass = PlayerClass.Common;

            if (sourceUser != null)
            {
                SourcePlayer = playerTracker.Get(sourceUser.ServerId, sourceUser.PlayerId);
                pclass       = SourcePlayer.RaceGenderClass.Class;
            }
            Skill = new UserSkill(hotdot.Id, pclass,
                                  hotdot.Name, "DOT", null, hotdot.IconName);

            if (targetUser != null)
            {
                TargetPlayer = playerTracker.Get(targetUser.ServerId, targetUser.PlayerId);
            }
            HitDirection = HitDirection.Dot;
        }
예제 #2
0
        public SkillResult(EachSkillResultServerMessage message, EntityTracker entityRegistry,
                           PlayerTracker playerTracker, SkillDatabase skillDatabase)
        {
            Time       = message.Time;
            Amount     = message.Amount;
            IsCritical = message.IsCritical;
            IsHeal     = message.IsHeal;
            SkillId    = message.SkillId;

            Source = entityRegistry.GetOrPlaceholder(message.Source);
            Target = entityRegistry.GetOrPlaceholder(message.Target);
            var userNpc    = UserEntity.ForEntity(Source);
            var npc        = (NpcEntity)userNpc["source"];
            var sourceUser = userNpc["root_source"] as UserEntity; // Attribute damage dealt by owned entities to the owner
            var targetUser = Target as UserEntity;                 // But don't attribute damage received by owned entities to the owner

            if (sourceUser != null)
            {
                Skill = skillDatabase.Get(sourceUser, message);
                if (Skill == null && npc != null)
                {
                    Skill = new UserSkill(message.SkillId, sourceUser.RaceGenderClass, npc.Info.Name);
                }
                SourcePlayer = playerTracker.Get(sourceUser.PlayerId);
                if (Skill == null)
                {
                    Skill = new UserSkill(message.SkillId, sourceUser.RaceGenderClass, "Unknown");
                }
            }
            if (targetUser != null)
            {
                TargetPlayer = playerTracker.Get(targetUser.PlayerId);
            }
        }
예제 #3
0
        public SkillResult(EachSkillResultServerMessage message, EntityTracker entityRegistry, PlayerTracker playerTracker, SkillDatabase skillDatabase)
        {
            Time = message.Time;
            Amount = message.Amount;
            IsCritical = message.IsCritical;
            IsHeal = message.IsHeal;
            SkillId = message.SkillId;

            Debug.Assert(!message.IsUseless);

            Source = entityRegistry.GetOrPlaceholder(message.Source);
            Target = entityRegistry.GetOrPlaceholder(message.Target);
            var sourceUser = UserEntity.ForEntity(Source); // Attribute damage dealt by owned entities to the owner
            var targetUser = Target as UserEntity; // But don't attribute damage received by owned entities to the owner

            if (sourceUser != null)
            {
                Skill = skillDatabase.Get(sourceUser, message);
                SourcePlayer = playerTracker.Get(sourceUser.PlayerId);
            }

            if (targetUser != null)
            {
                TargetPlayer = playerTracker.Get(targetUser.PlayerId);
            }
        }
예제 #4
0
        public SkillResult(bool abnormality, int amount, bool isCritical, bool isHp, int skillId, EntityId source,
                           EntityId target, EntityTracker entityRegistry)
        {
            Amount      = amount;
            IsCritical  = isCritical;
            IsHp        = isHp;
            SkillId     = skillId;
            Abnormality = abnormality;

            Source = entityRegistry.GetOrPlaceholder(source);
            Target = entityRegistry.GetOrPlaceholder(target);
            var userNpc    = UserEntity.ForEntity(Source);
            var npc        = (NpcEntity)userNpc["npc"];
            var sourceUser = userNpc["user"] as UserEntity; // Attribute damage dealt by owned entities to the owner
            var targetUser = Target as UserEntity;          // But don't attribute damage received by owned entities to the owner

            if (abnormality)
            {
                var hotdot = BasicTeraData.Instance.HotDotDatabase.Get(skillId);
                if (hotdot == null)
                {
                    return;
                }
                Skill = new UserSkill(skillId, PlayerClass.Common,
                                      hotdot.Name, "DOT", null);
            }

            if (sourceUser != null)
            {
                SourcePlayer = NetworkController.Instance.PlayerTracker.Get(sourceUser.PlayerId);
                if (!abnormality)
                {
                    Skill = BasicTeraData.Instance.SkillDatabase.Get(sourceUser.RaceGenderClass.Class, skillId);
                    if (Skill == null && npc != null)
                    {
                        var petName = BasicTeraData.Instance.MonsterDatabase.GetMonsterName(npc.NpcArea.ToString(),
                                                                                            npc.NpcId.ToString());
                        Skill = new UserSkill(skillId, sourceUser.RaceGenderClass.Class, petName,
                                              BasicTeraData.Instance.PetSkillDatabase.Get(petName, skillId), null);
                    }
                }
            }

            if (targetUser != null)
            {
                TargetPlayer = NetworkController.Instance.PlayerTracker.Get(targetUser.PlayerId);
            }
        }
예제 #5
0
        public SkillResult(EachSkillResultServerMessage message, EntityTracker entityRegistry, PlayerTracker playerTracker, SkillDatabase skillDatabase)
        {
            Time       = message.Time;
            Amount     = message.Amount;
            IsCritical = message.IsCritical;
            IsHeal     = message.IsHeal;
            SkillId    = message.SkillId;

            Source = entityRegistry.GetOrPlaceholder(message.Source);
            Target = entityRegistry.GetOrPlaceholder(message.Target);
            var sourceUser = Source.RootOwner as UserEntity; // Attribute damage dealt by owned entities to the owner
            var targetUser = Target as UserEntity;           // But don't attribute damage received by owned entities to the owner

            if (sourceUser != null)
            {
                Skill        = skillDatabase.GetOrNull(sourceUser, message.SkillId);
                SourcePlayer = playerTracker.Get(sourceUser.ServerId, sourceUser.PlayerId);
            }

            if (targetUser != null)
            {
                TargetPlayer = playerTracker.Get(targetUser.ServerId, targetUser.PlayerId);
            }
        }
예제 #6
0
        private void HandleMessageReceived(Message obj)
        {
            var message = _messageFactory.Create(obj);

            if (DamageTracker.IsArchived)
            {
                var npcOccupier = message as SNpcOccupierInfo;
                if (npcOccupier != null)
                {
                    Entity ent = _entityTracker.GetOrPlaceholder(npcOccupier.NPC);
                    if (ent is NpcEntity)
                    {
                        var npce = ent as NpcEntity;
                        if (npce.Info.Boss && npcOccupier.Target != EntityId.Empty)
                        {
                            CasualMessenger.Instance.ResetPlayerStats(true); //Stop viewing saved encounter on boss aggro
                        }
                    }
                    return;
                }
            }

            _entityTracker?.Update(message);
            var skillResultMessage = message as EachSkillResultServerMessage;

            if (skillResultMessage != null)
            {
                if (skillResultMessage.IsValid(DamageTracker))
                {
                    var skillResult = new SkillResult(skillResultMessage, _entityTracker, _playerTracker, _teraData.SkillDatabase, null, _abnormalityTracker);
                    CheckUpdate(skillResult);
                }
                return;
            }
            _playerTracker?.UpdateParty(message);
            _abnormalityTracker?.Update(message);
            var despawnNpc = message as SDespawnNpc;

            if (despawnNpc != null)
            {
                Entity ent = _entityTracker.GetOrPlaceholder(despawnNpc.Npc);
                if (ent is NpcEntity)
                {
                    var npce = ent as NpcEntity;
                    if (npce.Info.Boss && despawnNpc.Dead && !DamageTracker.IsArchived)
                    {   //no need to do something if we didn't count any skill against this boss
                        if (DamageTracker.StatsByUser.SelectMany(x => x.SkillLog).Any(x => x.Target == npce))
                        {
                            DamageTracker.PrimaryTarget       = npce; //Name encounter with the last dead boss
                            DamageTracker.IsPrimaryTargetDead = despawnNpc.Dead;

                            //determine type
                            ExportType exportType = ExportType.None;
                            if (SettingsHelper.Instance.Settings.ExcelExport)
                            {
                                exportType = exportType | ExportType.Excel;
                            }
                            if (SettingsHelper.Instance.Settings.SiteExport)
                            {
                                exportType = exportType | ExportType.Upload;
                            }

                            if (exportType != ExportType.None)
                            {
                                DataExporter.ToTeraDpsApi(exportType, DamageTracker, _teraData);
                            }
                            if (AutosaveEncounters)
                            {
                                ResetDamageTracker(new ResetPlayerStatsMessage {
                                    ShouldSaveCurrent = true
                                });
                            }
                        }
                    }
                }
                return;
            }
            var spawnNpc = message as SpawnNpcServerMessage;

            if (spawnNpc != null)
            {
                if (spawnNpc.NpcArea == 950 && spawnNpc.NpcId == 9501)
                {
                    var bosses            = DamageTracker.StatsByUser.SelectMany(x => x.SkillLog).Select(x => x.Target).OfType <NpcEntity>().ToList();
                    var vergosPhase2Part1 = bosses.FirstOrDefault(x => x.Info.HuntingZoneId == 950 && x.Info.TemplateId == 1000);
                    var vergosPhase2Part2 = bosses.FirstOrDefault(x => x.Info.HuntingZoneId == 950 && x.Info.TemplateId == 2000);
                    //determine type
                    ExportType exportType = ExportType.None;
                    if (SettingsHelper.Instance.Settings.ExcelExport)
                    {
                        exportType = exportType | ExportType.Excel;
                    }
                    if (SettingsHelper.Instance.Settings.SiteExport)
                    {
                        exportType = exportType | ExportType.Upload;
                    }

                    if (exportType != ExportType.None)
                    {
                        DataExporter.ToTeraDpsApi(exportType, DamageTracker, _teraData, vergosPhase2Part1);
                    }
                    DataExporter.ToTeraDpsApi(exportType, DamageTracker, _teraData, vergosPhase2Part2);
                    if (AutosaveEncounters)
                    {
                        ResetDamageTracker(new ResetPlayerStatsMessage {
                            ShouldSaveCurrent = true
                        });
                    }
                }
                if (spawnNpc.NpcArea == 950 && spawnNpc.NpcId == 9502)
                {
                    var bosses       = DamageTracker.StatsByUser.SelectMany(x => x.SkillLog).Select(x => x.Target).OfType <NpcEntity>().ToList();
                    var vergosPhase3 = bosses.FirstOrDefault(x => x.Info.HuntingZoneId == 950 && x.Info.TemplateId == 3000);
                    //determine type
                    ExportType exportType = ExportType.None;
                    if (SettingsHelper.Instance.Settings.ExcelExport)
                    {
                        exportType = exportType | ExportType.Excel;
                    }
                    if (SettingsHelper.Instance.Settings.SiteExport)
                    {
                        exportType = exportType | ExportType.Upload;
                    }

                    if (exportType != ExportType.None)
                    {
                        DataExporter.ToTeraDpsApi(exportType, DamageTracker, _teraData, vergosPhase3);
                    }
                    if (AutosaveEncounters)
                    {
                        ResetDamageTracker(new ResetPlayerStatsMessage {
                            ShouldSaveCurrent = true
                        });
                    }
                }
                return;
            }

            var sLogin = message as LoginServerMessage;

            if (sLogin != null)
            {
                if (_needInit)
                {
                    Server = BasicTeraData.Servers.GetServer(sLogin.ServerId, Server);
                    _messageFactory.Region = Server.Region;
                    Logger.Info($"Logged in to server {Server.Name}.");
                    _teraData           = BasicTeraData.DataForRegion(Server.Region);
                    _entityTracker      = new EntityTracker(_teraData.NpcDatabase, _userLogoTracker);
                    _playerTracker      = new PlayerTracker(_entityTracker, BasicTeraData.Servers);
                    _abnormalityTracker = new AbnormalityTracker(_entityTracker, _playerTracker, _teraData.HotDotDatabase, _abnormalityStorage, CheckUpdate);
                    _entityTracker.Update(message);
                    if (!DamageTracker.IsArchived)
                    {
                        DamageTracker.MeterPlayer = _playerTracker.Me();
                    }
                    _needInit = false;
                }
                _abnormalityStorage.EndAll(message.Time.Ticks);
                _abnormalityTracker = new AbnormalityTracker(_entityTracker, _playerTracker, _teraData.HotDotDatabase, _abnormalityStorage, CheckUpdate);
                return;
            }
            var cVersion = message as C_CHECK_VERSION;

            if (cVersion != null)
            {
                var opCodeNamer =
                    new OpCodeNamer(Path.Combine(BasicTeraData.ResourceDirectory,
                                                 $"opcodes/{cVersion.Versions[0]}.txt"));
                _messageFactory = new MessageFactory(opCodeNamer, Server.Region, cVersion.Versions[0]);
                return;
            }
            var sGetUserList = message as S_GET_USER_LIST;

            if (sGetUserList != null)
            {
                _userLogoTracker.SetUserList(sGetUserList);
                return;
            }
        }
예제 #7
0
        public SkillResult(EachSkillResultServerMessage message, EntityTracker entityRegistry,
                           PlayerTracker playerTracker, SkillDatabase skillDatabase, PetSkillDatabase petSkillDatabase = null, AbnormalityTracker abnormalityTracker = null)
        {
            Time        = message.Time;
            Amount      = message.Amount;
            IsCritical  = message.IsCritical;
            IsHp        = message.IsHp;
            IsHeal      = message.IsHeal;
            SkillId     = message.SkillId;
            Abnormality = false;

            Source = entityRegistry.GetOrPlaceholder(message.Source);
            Target = entityRegistry.GetOrPlaceholder(message.Target);
            if (Source is PlaceHolderEntity && (Target as NpcEntity)?.Info.Boss == true)
            {
                Source = playerTracker.GetUnknownPlayer() ?? Source;  //track unknown damage dealt to bosses like in raid-30
            }
            if (abnormalityTracker?.AbnormalityExist(message.Target, 950187) ?? false)
            {
                Amount = 0;                                                                      //fix raid-30 bug with 1kkk damage after shield
            }
            var userNpc    = UserEntity.ForEntity(Source);
            var npc        = (NpcEntity)userNpc["source"];
            var sourceUser = userNpc["root_source"] as UserEntity; // Attribute damage dealt by owned entities to the owner
            var targetUser = Target as UserEntity;                 // But don't attribute damage received by owned entities to the owner

            if (sourceUser != null)
            {
                Skill = skillDatabase.Get(sourceUser, message);
                if (Skill == null && npc != null)
                {
                    Skill = petSkillDatabase?.GetOrNull(npc.Info, SkillId) ?? new UserSkill(message.SkillId, sourceUser.RaceGenderClass, npc.Info.Name, null,
                                                                                            "", skillDatabase.GetSkillByPetName(npc.Info.Name, sourceUser.RaceGenderClass)?.IconName ?? "", npc.Info);
                }
                SourcePlayer = playerTracker.Get(sourceUser.ServerId, sourceUser.PlayerId);
                if (Skill == null)
                {
                    Skill = new UserSkill(message.SkillId, sourceUser.RaceGenderClass, "Unknown");
                }
            }
            if (targetUser != null)
            {
                TargetPlayer = playerTracker.Get(targetUser.ServerId, targetUser.PlayerId);
            }
            if (Source is PlaceHolderEntity || Target is PlaceHolderEntity)
            {
                return;                                                            //fix error on skills from or dealt to unknown entities
            }
            Source.Position = Source.Position.MoveForvard(Source.Finish, Source.Speed,
                                                          message.Time.Ticks - Source.StartTime);
            if (Source.EndTime > 0 && Source.EndTime <= Source.StartTime)
            {
                Source.Heading = Source.EndAngle;
                Source.EndTime = 0;
            }
            Target.Position = Target.Position.MoveForvard(Target.Finish, Target.Speed,
                                                          message.Time.Ticks - Target.StartTime);
            if (Target.EndTime > 0 && Target.EndTime <= Target.StartTime)
            {
                Target.Heading = Target.EndAngle;
                Target.EndTime = 0;
            }
            if (SourcePlayer != null && npc != null)
            {
                HitDirection = HitDirection.Pet;
            }
            else if (Source is ProjectileEntity || Source.Heading.Gradus == 0)
            {
                if (Skill?.Boom ?? true)
                {
                    HitDirection = Source.Position.GetHeading(Target.Position).HitDirection(Target.Heading);
                }
                else
                {
                    if ((HitDirection = userNpc["root_source"].Heading.HitDirection(Target.Heading)) != Source.Position.GetHeading(Target.Position).HitDirection(Target.Heading))
                    {
                        HitDirection = HitDirection.Front;
                    }
                }
            }
            else if ((HitDirection = Source.Heading.HitDirection(Target.Heading)) != Source.Position.GetHeading(Target.Position).HitDirection(Target.Heading))
            {
                HitDirection = HitDirection.Front;
            }
            if ((SourcePlayer?.Class == PlayerClass.Archer) && (abnormalityTracker?.AbnormalityExist(sourceUser.Id, 601600) ?? false))
            {
                HitDirection = HitDirection.Back;
            }
            //Debug.WriteLine(HitDirection);
            HitDirection = HitDirection & ~(HitDirection.Left | HitDirection.Right);
        }
예제 #8
0
        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 (true)
            {
                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)
                {
                    DataExporter.Export(Encounter, _abnormalityStorage);
                    NeedToExport = false;
                }

                Encounter = NewEncounter;

                var packetsWaiting = TeraSniffer.Instance.Packets.Count;
                if (packetsWaiting > 3000)
                {
                    MessageBox.Show(
                        LP.Your_computer_is_too_slow);
                    Exit();
                }

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

                EntityTracker?.Update(message);

                var skillResultMessage = message as EachSkillResultServerMessage;
                if (skillResultMessage != null)
                {
                    var skillResult = new SkillResult(skillResultMessage, EntityTracker, PlayerTracker,
                                                      BasicTeraData.Instance.SkillDatabase, BasicTeraData.Instance.PetSkillDatabase);
                    DamageTracker.Instance.Update(skillResult);
                    continue;
                }

                var changeHp = message as SCreatureChangeHp;
                if (changeHp != null)
                {
                    if (changeHp.SourceId != EntityTracker.MeterUser.Id &&
                        changeHp.TargetId != EntityTracker.MeterUser.Id &&
                        EntityTracker.GetOrPlaceholder(changeHp.TargetId).RootOwner == EntityTracker.MeterUser // don't care about damage received by our pets
                        )
                    {
                        BasicTeraData.LogError("SCreatureChangeHP need rootowner update1", false, true);
                    }
                    _abnormalityTracker.Update(changeHp);
                    continue;
                }

                var pchangeHp = message as SPartyMemberChangeHp;
                if (pchangeHp != null)
                {
                    var user = PlayerTracker.GetOrNull(pchangeHp.ServerId, pchangeHp.PlayerId);
                    if (user == null)
                    {
                        continue;
                    }
                    _abnormalityTracker.RegisterSlaying(user.User, pchangeHp.Slaying, pchangeHp.Time.Ticks);
                    continue;
                }

                var pmstatupd = message as S_PARTY_MEMBER_STAT_UPDATE;
                if (pmstatupd != null)
                {
                    var user = PlayerTracker.GetOrNull(pmstatupd.ServerId, pmstatupd.PlayerId);
                    if (user == null)
                    {
                        continue;
                    }
                    _abnormalityTracker.RegisterSlaying(user.User, pmstatupd.Slaying, pmstatupd.Time.Ticks);
                    continue;
                }

                var pstatupd = message as S_PLAYER_STAT_UPDATE;
                if (pstatupd != null)
                {
                    _abnormalityTracker.RegisterSlaying(EntityTracker.MeterUser, pstatupd.Slaying, pstatupd.Time.Ticks);
                    continue;
                }

                var changeMp = message as SPlayerChangeMp;
                if (changeMp != null)
                {
                    if (changeMp.SourceId != EntityTracker.MeterUser.Id && changeMp.TargetId != EntityTracker.MeterUser.Id)
                    {
                        BasicTeraData.LogError("SPlayerChangeMp need rootowner", false, true);
                    }
                    _abnormalityTracker.Update(changeMp);
                    continue;
                }

                var npcStatus = message as SNpcStatus;
                if (npcStatus != null)
                {
                    _abnormalityTracker.RegisterNpcStatus(npcStatus);
                    continue;
                }

                var dead = message as SCreatureLife;
                if (dead != null)
                {
                    _abnormalityTracker.RegisterDead(dead);
                    continue;
                }

                var abnormalityBegin = message as SAbnormalityBegin;
                if (abnormalityBegin != null)
                {
                    _abnormalityTracker.AddAbnormality(abnormalityBegin);
                    continue;
                }

                var abnormalityEnd = message as SAbnormalityEnd;
                if (abnormalityEnd != null)
                {
                    _abnormalityTracker.DeleteAbnormality(abnormalityEnd);
                    continue;
                }

                var abnormalityRefresh = message as SAbnormalityRefresh;
                if (abnormalityRefresh != null)
                {
                    _abnormalityTracker.RefreshAbnormality(abnormalityRefresh);
                    continue;
                }

                var npcOccupier = message as SNpcOccupierInfo;
                if (npcOccupier != null)
                {
                    DamageTracker.Instance.UpdateEntities(new NpcOccupierResult(npcOccupier), npcOccupier.Time.Ticks);
                    continue;
                }

                var despawnNpc = message as SDespawnNpc;
                if (despawnNpc != null)
                {
                    _abnormalityTracker.StopAggro(despawnNpc);
                    _abnormalityTracker.DeleteAbnormality(despawnNpc);
                    DataExporter.Export(despawnNpc, _abnormalityStorage);
                    continue;
                }

                var chatMessage = message as S_CHAT;
                if (chatMessage != null)
                {
                    Chat.Instance.Add(chatMessage);
                    continue;
                }

                var whisperMessage = message as S_WHISPER;
                if (whisperMessage != null)
                {
                    Chat.Instance.Add(whisperMessage);
                    continue;
                }

                var despawnUser = message as SDespawnUser;
                if (despawnUser != null)
                {
                    _charmTracker.CharmReset(despawnUser.User, new List <CharmStatus>(), despawnUser.Time.Ticks);
                    _abnormalityTracker.DeleteAbnormality(despawnUser);
                    continue;
                }

                var charmEnable = message as SEnableCharmStatus;
                if (charmEnable != null)
                {
                    _charmTracker.CharmEnable(EntityTracker.MeterUser.Id, charmEnable.CharmId, charmEnable.Time.Ticks);
                    continue;
                }
                var pcharmEnable = message as SPartyMemberCharmEnable;
                if (pcharmEnable != null)
                {
                    var player = PlayerTracker.GetOrNull(pcharmEnable.ServerId, pcharmEnable.PlayerId);
                    if (player == null)
                    {
                        continue;
                    }
                    _charmTracker.CharmEnable(player.User.Id, pcharmEnable.CharmId, pcharmEnable.Time.Ticks);
                    continue;
                }
                var charmReset = message as SResetCharmStatus;
                if (charmReset != null)
                {
                    _charmTracker.CharmReset(charmReset.TargetId, charmReset.Charms, charmReset.Time.Ticks);
                    continue;
                }
                var pcharmReset = message as SPartyMemberCharmReset;
                if (pcharmReset != null)
                {
                    var player = PlayerTracker.GetOrNull(pcharmReset.ServerId, pcharmReset.PlayerId);
                    if (player == null)
                    {
                        continue;
                    }
                    _charmTracker.CharmReset(player.User.Id, pcharmReset.Charms, pcharmReset.Time.Ticks);
                    continue;
                }
                var charmDel = message as SRemoveCharmStatus;
                if (charmDel != null)
                {
                    _charmTracker.CharmDel(EntityTracker.MeterUser.Id, charmDel.CharmId, charmDel.Time.Ticks);
                    continue;
                }
                var pcharmDel = message as SPartyMemberCharmDel;
                if (pcharmDel != null)
                {
                    var player = PlayerTracker.GetOrNull(pcharmDel.ServerId, pcharmDel.PlayerId);
                    if (player == null)
                    {
                        continue;
                    }
                    _charmTracker.CharmDel(player.User.Id, pcharmDel.CharmId, pcharmDel.Time.Ticks);
                    continue;
                }
                var charmAdd = message as SAddCharmStatus;
                if (charmAdd != null)
                {
                    _charmTracker.CharmAdd(charmAdd.TargetId, charmAdd.CharmId, charmAdd.Status, charmAdd.Time.Ticks);
                    continue;
                }
                var pcharmAdd = message as SPartyMemberCharmAdd;
                if (pcharmAdd != null)
                {
                    var player = PlayerTracker.GetOrNull(pcharmAdd.ServerId, pcharmAdd.PlayerId);
                    if (player == null)
                    {
                        continue;
                    }
                    _charmTracker.CharmAdd(player.User.Id, pcharmAdd.CharmId, pcharmAdd.Status, pcharmAdd.Time.Ticks);
                    continue;
                }

                PlayerTracker?.UpdateParty(message);
                var sSpawnUser = message as SpawnUserServerMessage;
                if (sSpawnUser != null)
                {
                    _abnormalityTracker.RegisterDead(sSpawnUser.Id, sSpawnUser.Time.Ticks, sSpawnUser.Dead);
                    //Debug.WriteLine(sSpawnUser.Name + " : " + BitConverter.ToString(BitConverter.GetBytes(sSpawnUser.Id.Id)) + " : " + BitConverter.ToString(BitConverter.GetBytes(sSpawnUser.ServerId)) + " " + BitConverter.ToString(BitConverter.GetBytes(sSpawnUser.PlayerId)));
                    continue;
                }

                var spawnMe = message as SpawnMeServerMessage;
                if (spawnMe != null)
                {
                    _abnormalityStorage.EndAll(message.Time.Ticks);
                    _abnormalityTracker = new AbnormalityTracker(EntityTracker, PlayerTracker,
                                                                 BasicTeraData.Instance.HotDotDatabase, _abnormalityStorage, DamageTracker.Instance.Update);
                    _charmTracker = new CharmTracker(_abnormalityTracker);
                    _abnormalityTracker.RegisterDead(spawnMe.Id, spawnMe.Time.Ticks, spawnMe.Dead);
                    continue;
                }

                var guildIcon = message as S_GET_USER_GUILD_LOGO;
                if (guildIcon != null)
                {
                    UserLogoTracker.AddLogo(guildIcon);
                    continue;
                }

                var user_list = message as S_GET_USER_LIST;
                if (user_list != null)
                {
                    UserLogoTracker.SetUserList(user_list);
                    continue;
                }

                var cVersion = message as C_CHECK_VERSION;
                if (cVersion != null)
                {
                    Console.WriteLine("VERSION0 = " + cVersion.Versions[0]);
                    Console.WriteLine("VERSION1 = " + cVersion.Versions[1]);
                    var opCodeNamer =
                        new OpCodeNamer(Path.Combine(BasicTeraData.Instance.ResourceDirectory,
                                                     $"data/opcodes/{cVersion.Versions[0]}.txt"));
                    _messageFactory = new MessageFactory(opCodeNamer, Server.Region);
                    continue;
                }

                var sLogin = message as LoginServerMessage;
                if (sLogin == null)
                {
                    continue;
                }
                if (_needInit)
                {
                    Connected(BasicTeraData.Instance.Servers.GetServerName(sLogin.ServerId, Server));
                    Server = BasicTeraData.Instance.Servers.GetServer(sLogin.ServerId, Server);
                    _messageFactory.Version = Server.Region;
                    TeraData = BasicTeraData.Instance.DataForRegion(Server.Region);
                    BasicTeraData.Instance.HotDotDatabase.Get(8888888).Name    = LP.Enrage;
                    BasicTeraData.Instance.HotDotDatabase.Get(8888889).Name    = LP.Slaying;
                    BasicTeraData.Instance.HotDotDatabase.Get(8888889).Tooltip = LP.SlayingTooltip;
                    EntityTracker = new EntityTracker(BasicTeraData.Instance.MonsterDatabase);
                    PlayerTracker = new PlayerTracker(EntityTracker, BasicTeraData.Instance.Servers);
                    PlayerTracker.PlayerIdChangedAction += PlayerTrackerOnPlayerIdChangedAction;
                    EntityTracker.Update(message);
                    PlayerTracker.UpdateParty(message);
                    _needInit = false;
                }
                _abnormalityStorage.EndAll(message.Time.Ticks);
                _abnormalityTracker = new AbnormalityTracker(EntityTracker, PlayerTracker,
                                                             BasicTeraData.Instance.HotDotDatabase, _abnormalityStorage, DamageTracker.Instance.Update);
                _charmTracker = new CharmTracker(_abnormalityTracker);
                OnGuildIconAction(UserLogoTracker.GetLogo(sLogin.PlayerId));
                //Debug.WriteLine(sLogin.Name + " : " + BitConverter.ToString(BitConverter.GetBytes(sLogin.Id.Id)));
            }
        }
예제 #9
0
        private void HandleMessageReceived(Message obj)
        {
            var message = _messageFactory.Create(obj);

            var despawnNpc = message as SDespawnNpc;

            if (despawnNpc != null)
            {
                Entity ent = _entityTracker.GetOrPlaceholder(despawnNpc.NPC);
                if (ent is NpcEntity)
                {
                    _abnormalityTracker.StopAggro(despawnNpc);
                    _abnormalityTracker.DeleteAbnormality(despawnNpc);
                    var npce = ent as NpcEntity;
                    if (npce.Info.Boss && despawnNpc.Dead && !DamageTracker.IsArchived)
                    {   //no need to do something if we didn't count any skill against this boss
                        if (DamageTracker.StatsByUser.SelectMany(x => x.SkillLog).Any(x => x.Target == npce))
                        {
                            DataExporter.ToTeraDpsApi(despawnNpc, DamageTracker, _entityTracker, _teraData);
                            DamageTracker.Name = npce.Info.Name; //Name encounter with the last dead boss
                            if (AutosaveEncounters)
                            {
                                CasualMessenger.Instance.ResetPlayerStats(true);
                            }
                        }
                    }
                }
                return;
            }
            if (DamageTracker.IsArchived)
            {
                var npcOccupier = message as SNpcOccupierInfo;
                if (npcOccupier != null)
                {
                    Entity ent = _entityTracker.GetOrPlaceholder(npcOccupier.NPC);
                    if (ent is NpcEntity)
                    {
                        var npce = ent as NpcEntity;
                        if (npce.Info.Boss && npcOccupier.Target != EntityId.Empty)
                        {
                            CasualMessenger.Instance.ResetPlayerStats(true); //Stop viewing saved encounter on boss aggro
                        }
                    }
                    return;
                }
            }

            var skillResultMessage = message as EachSkillResultServerMessage;

            if (skillResultMessage != null)
            {
                if (skillResultMessage.IsValid(DamageTracker))
                {
                    var skillResult = new SkillResult(skillResultMessage, _entityTracker, _playerTracker, _teraData.SkillDatabase);
                    CheckUpdate(skillResult);
                }
                return;
            }

            var changeHp = message as SCreatureChangeHp;

            if (changeHp != null)
            {
                _abnormalityTracker.Update(changeHp);
                return;
            }

            var pchangeHp = message as SPartyMemberChangeHp;

            if (pchangeHp != null)
            {
                var user = _playerTracker.GetOrNull(pchangeHp.ServerId, pchangeHp.PlayerId);
                if (user == null)
                {
                    return;
                }
                _abnormalityTracker.RegisterSlaying(user.User, pchangeHp.Slaying, pchangeHp.Time.Ticks);
                return;
            }

            var pmstatupd = message as S_PARTY_MEMBER_STAT_UPDATE;

            if (pmstatupd != null)
            {
                var user = _playerTracker.GetOrNull(pmstatupd.ServerId, pmstatupd.PlayerId);
                if (user == null)
                {
                    return;
                }
                _abnormalityTracker.RegisterSlaying(user.User, pmstatupd.Slaying, pmstatupd.Time.Ticks);
                return;
            }

            var pstatupd = message as S_PLAYER_STAT_UPDATE;

            if (pstatupd != null)
            {
                _abnormalityTracker.RegisterSlaying(_entityTracker.MeterUser, pstatupd.Slaying, pstatupd.Time.Ticks);
                return;
            }

            var changeMp = message as SPlayerChangeMp;

            if (changeMp != null)
            {
                _abnormalityTracker.Update(changeMp);
                return;
            }

            var npcStatus = message as SNpcStatus;

            if (npcStatus != null)
            {
                _abnormalityTracker.RegisterNpcStatus(npcStatus);
                return;
            }

            var dead = message as SCreatureLife;

            if (dead != null)
            {
                _abnormalityTracker.RegisterDead(dead);
                return;
            }

            var abnormalityBegin = message as SAbnormalityBegin;

            if (abnormalityBegin != null)
            {
                _abnormalityTracker.AddAbnormality(abnormalityBegin);
                return;
            }

            var abnormalityEnd = message as SAbnormalityEnd;

            if (abnormalityEnd != null)
            {
                _abnormalityTracker.DeleteAbnormality(abnormalityEnd);
                return;
            }

            var abnormalityRefresh = message as SAbnormalityRefresh;

            if (abnormalityRefresh != null)
            {
                _abnormalityTracker.RefreshAbnormality(abnormalityRefresh);
                return;
            }

            var despawnUser = message as SDespawnUser;

            if (despawnUser != null)
            {
                _charmTracker.CharmReset(despawnUser.User, new List <CharmStatus>(), despawnUser.Time.Ticks);
                _abnormalityTracker.DeleteAbnormality(despawnUser);
                return;
            }

            var charmEnable = message as SEnableCharmStatus;

            if (charmEnable != null)
            {
                _charmTracker.CharmEnable(_entityTracker.MeterUser.Id, charmEnable.CharmId, charmEnable.Time.Ticks);
                return;
            }
            var pcharmEnable = message as SPartyMemberCharmEnable;

            if (pcharmEnable != null)
            {
                var player = _playerTracker.GetOrNull(pcharmEnable.ServerId, pcharmEnable.PlayerId);
                if (player == null)
                {
                    return;
                }
                _charmTracker.CharmEnable(player.User.Id, pcharmEnable.CharmId, pcharmEnable.Time.Ticks);
                return;
            }
            var charmReset = message as SResetCharmStatus;

            if (charmReset != null)
            {
                _charmTracker.CharmReset(charmReset.TargetId, charmReset.Charms, charmReset.Time.Ticks);
                return;
            }
            var pcharmReset = message as SPartyMemberCharmReset;

            if (pcharmReset != null)
            {
                var player = _playerTracker.GetOrNull(pcharmReset.ServerId, pcharmReset.PlayerId);
                if (player == null)
                {
                    return;
                }
                _charmTracker.CharmReset(player.User.Id, pcharmReset.Charms, pcharmReset.Time.Ticks);
                return;
            }
            var charmDel = message as SRemoveCharmStatus;

            if (charmDel != null)
            {
                _charmTracker.CharmDel(_entityTracker.MeterUser.Id, charmDel.CharmId, charmDel.Time.Ticks);
                return;
            }
            var pcharmDel = message as SPartyMemberCharmDel;

            if (pcharmDel != null)
            {
                var player = _playerTracker.GetOrNull(pcharmDel.ServerId, pcharmDel.PlayerId);
                if (player == null)
                {
                    return;
                }
                _charmTracker.CharmDel(player.User.Id, pcharmDel.CharmId, pcharmDel.Time.Ticks);
                return;
            }
            var charmAdd = message as SAddCharmStatus;

            if (charmAdd != null)
            {
                _charmTracker.CharmAdd(charmAdd.TargetId, charmAdd.CharmId, charmAdd.Status, charmAdd.Time.Ticks);
                return;
            }
            var pcharmAdd = message as SPartyMemberCharmAdd;

            if (pcharmAdd != null)
            {
                var player = _playerTracker.GetOrNull(pcharmAdd.ServerId, pcharmAdd.PlayerId);
                if (player == null)
                {
                    return;
                }
                _charmTracker.CharmAdd(player.User.Id, pcharmAdd.CharmId, pcharmAdd.Status, pcharmAdd.Time.Ticks);
                return;
            }

            _entityTracker.Update(message);
            _playerTracker.UpdateParty(message);

            var spawnMe = message as SpawnMeServerMessage;

            if (spawnMe != null)
            {
                _abnormalityStorage.EndAll(message.Time.Ticks);
                _abnormalityTracker = new AbnormalityTracker(_entityTracker, _playerTracker, _teraData.HotDotDatabase, _abnormalityStorage, CheckUpdate);
                _charmTracker       = new CharmTracker(_abnormalityTracker);
                return;
            }
            var sLogin = message as LoginServerMessage;

            if (sLogin != null)
            {
                _abnormalityStorage.EndAll(message.Time.Ticks);
                _abnormalityTracker = new AbnormalityTracker(_entityTracker, _playerTracker, _teraData.HotDotDatabase, _abnormalityStorage, CheckUpdate);
                _charmTracker       = new CharmTracker(_abnormalityTracker);
                Server = BasicTeraData.Servers.GetServer(sLogin.ServerId, Server);
                return;
            }
        }
예제 #10
0
        public static void ToTeraDpsApi(SDespawnNpc despawnNpc, DamageTracker damageTracker, EntityTracker entityTracker, TeraData teraData)
        {
            if (!despawnNpc.Dead)
            {
                return;
            }
            var entity = entityTracker.GetOrPlaceholder(despawnNpc.Npc) as NpcEntity;

            if (!(entity?.Info.Boss ?? false))
            {
                return;
            }

            if (!SettingsHelper.Instance.Settings.ExcelExport &&
                (string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsToken) ||
                 string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsUser) ||
                 !SettingsHelper.Instance.Settings.SiteExport)
                )
            {
                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
            {
                areaId        = entity.Info.HuntingZoneId + "",
                bossId        = entity.Info.TemplateId + "",
                fightDuration = seconds + "",
                partyDps      = partyDps + ""
            };

            foreach (var debuff in abnormals.Get(entity))
            {
                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)
            {
                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), 1) + "";
                teradpsUser.healCrit  = user.Player.IsHealer ? Math.Round(100 * (double)filteredSkillog.Count(x => x.IsCritical && x.Heal > 0) / filteredSkillog.Count(x => x.Heal > 0), 1) + "" : 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)
                {
                    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 ThreadSafeObservableCollection <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, collection));
                    }
                }
                foreach (var skill in aggregated)
                {
                    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, 1) + "";
                    skillLog.skillDamagePercent = Math.Round(skill.DamagePercent * 100, 1) + "";
                    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);
            }

            if (SettingsHelper.Instance.Settings.ExcelExport)
            {
                Task.Run(() => ExcelExport.ExcelSave(teradpsData, teraData));
            }
            if (string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsToken) || string.IsNullOrEmpty(SettingsHelper.Instance.Settings.TeraDpsUser) || !SettingsHelper.Instance.Settings.SiteExport)
            {
                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 != 470 &&
                areaId != 468
                )
            {
                return;
            }

            if (int.Parse(teradpsData.partyDps) < 2000000 && areaId != 468)
            {
                return;
            }
            string json = JsonConvert.SerializeObject(teradpsData, new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            });

            Task.Run(() => Send(entity, json, 3));
        }
예제 #11
0
        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 (true)
            {
                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)
                {
                    DataExporter.Export(Encounter, _abnormalityStorage);
                    NeedToExport = false;
                }

                Encounter = NewEncounter;

                var packetsWaiting = TeraSniffer.Instance.Packets.Count;
                if (packetsWaiting > 3000)
                {
                    MessageBox.Show(
                        LP.Your_computer_is_too_slow);
                    Exit();
                }

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

                var cVersion = message as C_CHECK_VERSION;
                if (cVersion != null)
                {
                    Console.WriteLine("VERSION0 = " + cVersion.Versions[0]);
                    Console.WriteLine("VERSION1 = " + cVersion.Versions[1]);
                    var opCodeNamer =
                        new OpCodeNamer(Path.Combine(BasicTeraData.Instance.ResourceDirectory,
                                                     $"data/opcodes/{cVersion.Versions[0]}.txt"));
                    _messageFactory = new MessageFactory(opCodeNamer, Server.Region);
                    continue;
                }

                var sLogin = message as LoginServerMessage;
                if (sLogin != null)
                {
                    if (_needInit)
                    {
                        Connected(BasicTeraData.Instance.Servers.GetServerName(sLogin.ServerId, Server));
                        bool trackerreset = true;
                        if (EntityTracker != null)
                        {
                            try
                            {
                                var oldregion = BasicTeraData.Instance.Servers.GetServer(EntityTracker.MeterUser.ServerId).Region;
                                trackerreset = Server.Region != oldregion;
                            }
                            catch (Exception e)
                            {
                                BasicTeraData.LogError("New server:" + Server + ";Old server Id:" + EntityTracker.MeterUser.ServerId, false, true);
                                throw;
                            }
                        }
                        Server = BasicTeraData.Instance.Servers.GetServer(sLogin.ServerId, Server);
                        _messageFactory.Version = Server.Region;
                        if (trackerreset)
                        {
                            TeraData = BasicTeraData.Instance.DataForRegion(Server.Region);
                            BasicTeraData.Instance.HotDotDatabase.Get(8888888).Name    = LP.Enrage;
                            BasicTeraData.Instance.HotDotDatabase.Get(8888889).Name    = LP.Slaying;
                            BasicTeraData.Instance.HotDotDatabase.Get(8888889).Tooltip = LP.SlayingTooltip;
                            EntityTracker = new EntityTracker(BasicTeraData.Instance.MonsterDatabase);
                            PlayerTracker = new PlayerTracker(EntityTracker, BasicTeraData.Instance.Servers);
                            Database.Database.Instance.DeleteAll();
                        }
                        _needInit = false;
                    }
                    _abnormalityStorage.EndAll(message.Time.Ticks);
                    _abnormalityTracker = new AbnormalityTracker(EntityTracker, PlayerTracker,
                                                                 BasicTeraData.Instance.HotDotDatabase, _abnormalityStorage, DamageTracker.Instance.Update);
                    _charmTracker = new CharmTracker(_abnormalityTracker);
                    OnGuildIconAction(UserLogoTracker.GetLogo(sLogin.PlayerId));
                }

                if (_needInit)
                {
                    //Wait for initialization
                    continue;
                }

                EntityTracker.Update(message);

                var skillResultMessage = message as EachSkillResultServerMessage;
                if (skillResultMessage != null)
                {
                    var skillResult = new SkillResult(skillResultMessage, EntityTracker, PlayerTracker,
                                                      BasicTeraData.Instance.SkillDatabase, BasicTeraData.Instance.PetSkillDatabase);
                    DamageTracker.Instance.Update(skillResult);
                    continue;
                }

                var changeHp = message as SCreatureChangeHp;
                if (changeHp != null)
                {
                    _abnormalityTracker.Update(changeHp);
                    continue;
                }

                var pchangeHp = message as SPartyMemberChangeHp;
                if (pchangeHp != null)
                {
                    var user = PlayerTracker.GetOrNull(pchangeHp.ServerId, pchangeHp.PlayerId);
                    if (user == null)
                    {
                        continue;
                    }
                    _abnormalityTracker.RegisterSlaying(user.User, pchangeHp.Slaying, pchangeHp.Time.Ticks);
                    continue;
                }

                var pmstatupd = message as S_PARTY_MEMBER_STAT_UPDATE;
                if (pmstatupd != null)
                {
                    var user = PlayerTracker.GetOrNull(pmstatupd.ServerId, pmstatupd.PlayerId);
                    if (user == null)
                    {
                        continue;
                    }
                    _abnormalityTracker.RegisterSlaying(user.User, pmstatupd.Slaying, pmstatupd.Time.Ticks);
                    continue;
                }

                var pstatupd = message as S_PLAYER_STAT_UPDATE;
                if (pstatupd != null)
                {
                    _abnormalityTracker.RegisterSlaying(EntityTracker.MeterUser, pstatupd.Slaying, pstatupd.Time.Ticks);
                    continue;
                }

                var changeMp = message as SPlayerChangeMp;
                if (changeMp != null)
                {
                    if (changeMp.SourceId != EntityTracker.MeterUser.Id &&
                        changeMp.TargetId != EntityTracker.MeterUser.Id &&
                        EntityTracker.GetOrPlaceholder(changeHp.TargetId).RootOwner != EntityTracker.MeterUser)
                    {
                        var source = EntityTracker.GetOrPlaceholder(changeMp.SourceId);
                        BasicTeraData.LogError("SPlayerChangeMp need rootowner update2:" + (source as NpcEntity)?.Info.Name ?? source.GetType() + ": " + source, false, true);
                    }
                    _abnormalityTracker.Update(changeMp);
                    continue;
                }

                var npcStatus = message as SNpcStatus;
                if (npcStatus != null)
                {
                    _abnormalityTracker.RegisterNpcStatus(npcStatus);
                    continue;
                }

                var dead = message as SCreatureLife;
                if (dead != null)
                {
                    _abnormalityTracker.RegisterDead(dead);
                    continue;
                }

                var abnormalityBegin = message as SAbnormalityBegin;
                if (abnormalityBegin != null)
                {
                    _abnormalityTracker.AddAbnormality(abnormalityBegin);
                    continue;
                }

                var abnormalityEnd = message as SAbnormalityEnd;
                if (abnormalityEnd != null)
                {
                    _abnormalityTracker.DeleteAbnormality(abnormalityEnd);
                    continue;
                }

                var abnormalityRefresh = message as SAbnormalityRefresh;
                if (abnormalityRefresh != null)
                {
                    _abnormalityTracker.RefreshAbnormality(abnormalityRefresh);
                    continue;
                }

                var npcOccupier = message as SNpcOccupierInfo;
                if (npcOccupier != null)
                {
                    DamageTracker.Instance.UpdateEntities(new NpcOccupierResult(npcOccupier), npcOccupier.Time.Ticks);
                    continue;
                }

                var despawnNpc = message as SDespawnNpc;
                if (despawnNpc != null)
                {
                    _abnormalityTracker.StopAggro(despawnNpc);
                    _abnormalityTracker.DeleteAbnormality(despawnNpc);
                    DataExporter.Export(despawnNpc, _abnormalityStorage);
                    continue;
                }

                var despawnUser = message as SDespawnUser;
                if (despawnUser != null)
                {
                    _charmTracker.CharmReset(despawnUser.User, new List <CharmStatus>(), despawnUser.Time.Ticks);
                    _abnormalityTracker.DeleteAbnormality(despawnUser);
                    continue;
                }

                var charmEnable = message as SEnableCharmStatus;
                if (charmEnable != null)
                {
                    _charmTracker.CharmEnable(EntityTracker.MeterUser.Id, charmEnable.CharmId, charmEnable.Time.Ticks);
                    continue;
                }
                var pcharmEnable = message as SPartyMemberCharmEnable;
                if (pcharmEnable != null)
                {
                    var player = PlayerTracker.GetOrNull(pcharmEnable.ServerId, pcharmEnable.PlayerId);
                    if (player == null)
                    {
                        continue;
                    }
                    _charmTracker.CharmEnable(player.User.Id, pcharmEnable.CharmId, pcharmEnable.Time.Ticks);
                    continue;
                }
                var charmReset = message as SResetCharmStatus;
                if (charmReset != null)
                {
                    _charmTracker.CharmReset(charmReset.TargetId, charmReset.Charms, charmReset.Time.Ticks);
                    continue;
                }
                var pcharmReset = message as SPartyMemberCharmReset;
                if (pcharmReset != null)
                {
                    var player = PlayerTracker.GetOrNull(pcharmReset.ServerId, pcharmReset.PlayerId);
                    if (player == null)
                    {
                        continue;
                    }
                    _charmTracker.CharmReset(player.User.Id, pcharmReset.Charms, pcharmReset.Time.Ticks);
                    continue;
                }
                var charmDel = message as SRemoveCharmStatus;
                if (charmDel != null)
                {
                    _charmTracker.CharmDel(EntityTracker.MeterUser.Id, charmDel.CharmId, charmDel.Time.Ticks);
                    continue;
                }
                var pcharmDel = message as SPartyMemberCharmDel;
                if (pcharmDel != null)
                {
                    var player = PlayerTracker.GetOrNull(pcharmDel.ServerId, pcharmDel.PlayerId);
                    if (player == null)
                    {
                        continue;
                    }
                    _charmTracker.CharmDel(player.User.Id, pcharmDel.CharmId, pcharmDel.Time.Ticks);
                    continue;
                }
                var charmAdd = message as SAddCharmStatus;
                if (charmAdd != null)
                {
                    _charmTracker.CharmAdd(charmAdd.TargetId, charmAdd.CharmId, charmAdd.Status, charmAdd.Time.Ticks);
                    continue;
                }
                var pcharmAdd = message as SPartyMemberCharmAdd;
                if (pcharmAdd != null)
                {
                    var player = PlayerTracker.GetOrNull(pcharmAdd.ServerId, pcharmAdd.PlayerId);
                    if (player == null)
                    {
                        continue;
                    }
                    _charmTracker.CharmAdd(player.User.Id, pcharmAdd.CharmId, pcharmAdd.Status, pcharmAdd.Time.Ticks);
                    continue;
                }

                PlayerTracker.UpdateParty(message);

                var sSpawnUser = message as SpawnUserServerMessage;
                if (sSpawnUser != null)
                {
                    _abnormalityTracker.RegisterDead(sSpawnUser.Id, sSpawnUser.Time.Ticks, sSpawnUser.Dead);
                    //Debug.WriteLine(sSpawnUser.Name + " : " + BitConverter.ToString(BitConverter.GetBytes(sSpawnUser.Id.Id)) + " : " + BitConverter.ToString(BitConverter.GetBytes(sSpawnUser.ServerId)) + " " + BitConverter.ToString(BitConverter.GetBytes(sSpawnUser.PlayerId)));
                    continue;
                }

                if (BasicTeraData.Instance.WindowData.EnableChat)
                {
                    var chatMessage = message as S_CHAT;
                    if (chatMessage != null)
                    {
                        Chat.Instance.Add(chatMessage);
                        continue;
                    }

                    var whisperMessage = message as S_WHISPER;
                    if (whisperMessage != null)
                    {
                        Chat.Instance.Add(whisperMessage);
                        continue;
                    }

                    var privateChatMessage = message as S_PRIVATE_CHAT;
                    if (privateChatMessage != null)
                    {
                        Chat.Instance.Add(privateChatMessage);
                        continue;
                    }

                    var trading = message as S_TRADE_BROKER_DEAL_SUGGESTED;
                    if (trading != null)
                    {
                        if (!TeraWindow.IsTeraActive())
                        {
                            FlashMessage = new Tuple <string, string>(
                                LP.Trading + ": " + trading.PlayerName,
                                LP.SellerPrice + ": " + S_TRADE_BROKER_DEAL_SUGGESTED.Gold(trading.SellerPrice) +
                                Environment.NewLine +
                                LP.OfferedPrice + ": " + S_TRADE_BROKER_DEAL_SUGGESTED.Gold(trading.OfferedPrice)
                                );
                        }
                        continue;
                    }

                    var userApply = message as S_OTHER_USER_APPLY_PARTY;
                    if (userApply != null)
                    {
                        if (!TeraWindow.IsTeraActive())
                        {
                            FlashMessage = new Tuple <string, string>(
                                userApply.PlayerName + " " + LP.ApplyToYourParty,
                                LP.Class + ": " +
                                LP.ResourceManager.GetString(userApply.PlayerClass.ToString(), LP.Culture) +
                                Environment.NewLine +
                                LP.Lvl + ": " + userApply.Lvl + Environment.NewLine
                                );
                        }
                        for (var i = 0; i < 3; i++)
                        {
                            try
                            {
                                Clipboard.SetDataObject("/inspect " + userApply.PlayerName);
                                break;
                            }
                            catch
                            {
                                Thread.Sleep(100);
                                //Ignore
                            }
                        }
                        continue;
                    }

                    var contact = message as S_REQUEST_CONTRACT;
                    if (contact != null)
                    {
                        if (!TeraWindow.IsTeraActive())
                        {
                            if (contact.Type == S_REQUEST_CONTRACT.RequestType.PartyInvite)
                            {
                                FlashMessage = new Tuple <string, string>(
                                    LP.PartyInvite + ": " + contact.Sender,
                                    contact.Sender
                                    );
                            }
                            else if (contact.Type == S_REQUEST_CONTRACT.RequestType.TradeRequest)
                            {
                                FlashMessage = new Tuple <string, string>(
                                    LP.Trading + ": " + contact.Sender,
                                    contact.Sender
                                    );
                            }
                            else
                            {
                                FlashMessage = new Tuple <string, string>(
                                    LP.ContactTry,
                                    LP.ContactTry
                                    );
                            }
                        }
                        continue;
                    }


                    var partyMatch = message as S_FIN_INTER_PARTY_MATCH;
                    var bgMatch    = message as S_BATTLE_FIELD_ENTRANCE_INFO;
                    if (partyMatch != null || bgMatch != null)
                    {
                        if (!TeraWindow.IsTeraActive())
                        {
                            FlashMessage = new Tuple <string, string>(
                                LP.PartyMatchingSuccess,
                                LP.PartyMatchingSuccess
                                );
                        }
                        continue;
                    }
                }
                var spawnMe = message as SpawnMeServerMessage;
                if (spawnMe != null)
                {
                    _abnormalityStorage.EndAll(message.Time.Ticks);
                    _abnormalityTracker = new AbnormalityTracker(EntityTracker, PlayerTracker,
                                                                 BasicTeraData.Instance.HotDotDatabase, _abnormalityStorage, DamageTracker.Instance.Update);
                    _charmTracker = new CharmTracker(_abnormalityTracker);
                    _abnormalityTracker.RegisterDead(spawnMe.Id, spawnMe.Time.Ticks, spawnMe.Dead);
                    continue;
                }

                var guildIcon = message as S_GET_USER_GUILD_LOGO;
                if (guildIcon != null)
                {
                    UserLogoTracker.AddLogo(guildIcon);
                    continue;
                }

                var user_list = message as S_GET_USER_LIST;
                if (user_list != null)
                {
                    UserLogoTracker.SetUserList(user_list);
                    continue;
                }

                //Debug.WriteLine(sLogin.Name + " : " + BitConverter.ToString(BitConverter.GetBytes(sLogin.Id.Id)));
            }
        }