public void Update(SkillResult skillResult, long time) { PlayerInfo playerStats; if (skillResult.SourcePlayer != null) { playerStats = GetOrCreate(skillResult.SourcePlayer); var entityTarget = GetActorEntity(skillResult.Target.Id); if (entityTarget == null) { throw new Exception("Unknow target" + skillResult.Target.GetType()); } UpdateStatsDealt(playerStats, skillResult, entityTarget, time); } if (skillResult.TargetPlayer == null) { return; } playerStats = GetOrCreate(skillResult.TargetPlayer); var entitySource = new Entity("UNKNOW"); if (skillResult.Source != null) { entitySource = GetEntity(skillResult.Source.Id) ?? new Entity("UNKNOW"); } UpdateStatsReceived(playerStats, skillResult, entitySource, time); }
private void UpdateEncounter(Entity entity, SkillResult msg) { if (!EntitiesStats.ContainsKey(entity) && msg.Damage != 0) { EntitiesStats.Add(entity, new EntityInfo()); } }
public void Update(SkillResult skillResult) { if (skillResult.Source == null || skillResult.Target == null) { return; } var entitySource = UserEntity.ForEntity(NetworkController.Instance.EntityTracker.GetOrPlaceholder(skillResult.Source.Id)); var entityTarget = GetActorEntity(skillResult.Target.Id); if (skillResult.SourcePlayer == null && skillResult.TargetPlayer == null) { return; } if (BasicTeraData.Instance.WindowData.PartyOnly && (skillResult.SourcePlayer == null || !NetworkController.Instance.PlayerTracker.MyParty(skillResult.SourcePlayer)) && (skillResult.TargetPlayer == null || !NetworkController.Instance.PlayerTracker.MyParty(skillResult.TargetPlayer))) { return; } if (BasicTeraData.Instance.WindowData.OnlyBoss && !(((entityTarget as NpcEntity)?.Info.Boss ?? false) || (skillResult.SourcePlayer != null && skillResult.TargetPlayer != null) || ((entitySource["root_source"] as NpcEntity)?.Info.Boss ?? false))) { return; } if (entitySource["root_source"] is PlaceHolderEntity || entityTarget == null) { return; } InsertSkill(entityTarget, entitySource["root_source"], entitySource["source"], skillResult); }
private static void UpdateSkillStats(SkillResult message, Entity entityTarget, PlayerInfo playerInfo, long time) { var entities = playerInfo.Dealt; entities.AddStats(time, entityTarget, new SkillsStats(playerInfo)); var skillName = message.SkillId.ToString(); var skillShortName = message.SkillShortName; var iconName = ""; if (message.Skill != null) { skillName = message.Skill.Name; iconName = message.Skill.IconName; } var skillKey = new Skill(skillName, skillShortName, new List <int> { message.SkillId }, iconName, message.Skill?.NpcInfo); SkillStats skillStats; var dictionarySkillStats = entities.GetSkills(time, entityTarget); dictionarySkillStats.TryGetValue(skillKey, out skillStats); if (skillStats == null) { skillStats = new SkillStats(playerInfo, entityTarget); } if (message.IsHp) { if (message.IsHeal) { skillStats.AddData(message.SkillId, message.Heal, message.IsCritical, SkillStats.Type.Heal, time); } else { skillStats.AddData(message.SkillId, message.Damage, message.IsCritical, SkillStats.Type.Damage, time); } } else { skillStats.AddData(message.SkillId, message.Mana, message.IsCritical, SkillStats.Type.Mana, time); } var skill = dictionarySkillStats.Keys.ToList(); var indexSkill = skill.IndexOf(skillKey); if (indexSkill != -1) { foreach ( var skillid in skill[indexSkill].SkillId.Where(skillid => !skillKey.SkillId.Contains(skillid))) { skillKey.SkillId.Add(skillid); } } dictionarySkillStats.Remove(skillKey); dictionarySkillStats.Add(skillKey, skillStats); }
private void UpdateStatsDealt(PlayerInfo playerInfo, SkillResult message, Entity entityTarget, long time) { if (!IsValidAttack(message)) { return; } UpdateEncounter(entityTarget, message); UpdateSkillStats(message, entityTarget, playerInfo, time); }
private static bool IsValidSkill(SkillResult message) { if (message.Amount == 0) // to count buff skills/consumable usage - need additional hitstat for it (damage/heal/mana/uses) { return(false); } return((UserEntity.ForEntity(message.Source)["root_source"] != UserEntity.ForEntity(message.Target)["root_source"]) || (message.Damage == 0)); }
private void UpdateStatsReceived(PlayerInfo playerInfo, SkillResult message, Entity entitySource, long time) { if (_hasReset.Contains(entitySource) && entitySource.IsBoss()) { Console.WriteLine("Remove:" + entitySource.Name); DeleteEntity(entitySource); _hasReset.Remove(entitySource); } if (!IsValidAttack(message)) { return; } //Not damage & if you are a healer, don't show heal / mana regen affecting you, as that will modify your crit rate and other stats. if ((message.IsHp && message.Amount > 0 || !message.IsHp) && !PlayerClassHelper.IsHeal(playerInfo.Class) && (UserEntity.ForEntity(message.Source)["user"] != UserEntity.ForEntity(message.Target)["user"])) { UpdateSkillStats(message, new Entity(playerInfo.Player.User.Name), playerInfo, time); return; } if (message.Damage <= 0) { return; } var entity = entitySource; if (entitySource.IsBoss()) { foreach ( var t in EntitiesStats.Where(t => t.Key.Name == entitySource.Name).OrderByDescending(t => t.Value.FirstHit)) { entity = t.Key; break; } //Don't count damage taken if boss haven't taken any damage if (entity == null) { return; } } playerInfo.Received.AddStats(time, entity, message.Damage); if (EntitiesStats.ContainsKey(entity)) { return; } EntitiesStats.Add(entity, new EntityInfo()); }
private static bool IsValidAttack(SkillResult message) { if (message.Amount == 0) // to count buff skills/consumable usage - need additional hitstat for it (damage/heal/mana/uses) { return(false); } if ((UserEntity.ForEntity(message.Source)["user"] == UserEntity.ForEntity(message.Target)["user"]) && (message.Damage != 0)) { return(false); } return(true); }
private static bool IsValidAttack(SkillResult message) { if (message.Amount == 0) { return(false); } if ((UserEntity.ForEntity(message.Source)["user"] == UserEntity.ForEntity(message.Target)["user"]) && (message.Damage != 0)) { return(false); } return(true); }
private void UpdateStatsDealt(PlayerInfo playerInfo, SkillResult message, Entity entityTarget, long time) { if (!IsValidAttack(message)) { return; } if (_toDelete.Contains(entityTarget)) { DeleteEntity(entityTarget); _toDelete.Remove(entityTarget); } UpdateEncounter(entityTarget, message); UpdateSkillStats(message, entityTarget, playerInfo, time); }
private void UpdateStatsDealt(PlayerInfo playerInfo, SkillResult message, Entity entityTarget, long time) { if (_hasReset.Contains(entityTarget) && entityTarget.IsBoss()) { Console.WriteLine("Remove:" + entityTarget.Name); DeleteEntity(entityTarget); _hasReset.Remove(entityTarget); } if (!IsValidAttack(message)) { return; } UpdateEncounter(entityTarget, message); UpdateSkillStats(message, entityTarget, playerInfo, time); }
private void UpdateStatsReceived(PlayerInfo playerInfo, SkillResult message, Entity entitySource, long time) { if (!IsValidAttack(message)) { return; } //Not damage & if you are a healer, don't show heal / mana regen affecting you, as that will modify your crit rate and other stats. if ((message.IsHp && message.Amount > 0 || !message.IsHp) && !playerInfo.IsHealer && (UserEntity.ForEntity(message.Source)["user"] != UserEntity.ForEntity(message.Target)["user"])) { UpdateSkillStats(message, new Entity(playerInfo.Player.User.Name), playerInfo, time); return; } if (message.Damage <= 0) { return; } var entity = entitySource; if (entitySource.IsBoss) { foreach ( var t in EntitiesStats.Where(t => t.Key.Name == entitySource.Name && t.Key.Id == entitySource.Id)) { entity = t.Key; break; } //Don't count damage taken if boss haven't taken any damage if (entity == null) { return; } } playerInfo.Received.AddStats(time, entity, message.Damage); if (EntitiesStats.ContainsKey(entity)) { return; } EntitiesStats.Add(entity, new EntityInfo()); }
public void Update(SkillResult skillResult) { PlayerInfo playerStats; if (skillResult.SourcePlayer != null) { if (!BasicTeraData.Instance.WindowData.PartyOnly || NetworkController.Instance.PlayerTracker.MyParty(skillResult.SourcePlayer)) { playerStats = GetOrCreate(skillResult.SourcePlayer); var entityTarget = GetActorEntity(skillResult.Target.Id); if (entityTarget == null) { throw new Exception("Unknow target" + skillResult.Target.GetType()); } UpdateStatsDealt(playerStats, skillResult, entityTarget, skillResult.Time.Ticks); } } if (skillResult.TargetPlayer == null) { return; } if (!BasicTeraData.Instance.WindowData.PartyOnly || ((skillResult.SourcePlayer == null)?false:NetworkController.Instance.PlayerTracker.MyParty(skillResult.SourcePlayer)) || NetworkController.Instance.PlayerTracker.MyParty(skillResult.TargetPlayer)) { playerStats = GetOrCreate(skillResult.TargetPlayer); var entitySource = new Entity("UNKNOW"); if (skillResult.Source != null) { entitySource = GetEntity(skillResult.Source.Id) ?? new Entity("UNKNOW"); } UpdateStatsReceived(playerStats, skillResult, entitySource, skillResult.Time.Ticks); } }
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))); } }
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))); } }
private void PacketAnalysisLoop() { while (true) { if (NeedToReset) { Reset(); NeedToReset = false; } if (NeedToResetCurrent) { ResetCurrent(); NeedToResetCurrent = false; } if (NeedToCopy != null) { var stats = DamageTracker.Instance.GetPlayerStats(); var currentBoss = Encounter; var info = currentBoss == null?new EntityInfo():DamageTracker.Instance.GetEntityStats()[currentBoss]; var timedEncounter = TimedEncounter; var totaldamage = DamageTracker.Instance.TotalDamage(currentBoss, timedEncounter); var firstHit = DamageTracker.Instance.FirstHit(currentBoss); var lastHit = DamageTracker.Instance.LastHit(currentBoss); var partyDps = DamageTracker.Instance.PartyDps(currentBoss, timedEncounter); var tmpcopy = NeedToCopy; var pasteThread = new Thread(() => CopyThread(info, stats, _abnormalityStorage.Clone(currentBoss?.NpcE), totaldamage, partyDps, firstHit, lastHit, currentBoss, timedEncounter, tmpcopy)); pasteThread.Priority = ThreadPriority.Highest; pasteThread.Start(); NeedToCopy = null; } Encounter = NewEncounter; if (_forceUiUpdate) { UpdateUi(); _forceUiUpdate = false; } CheckUpdateUi(); Message obj; var successDequeue = TeraSniffer.Instance.Packets.TryDequeue(out obj); if (!successDequeue) { Thread.Sleep(1); continue; } if (TeraSniffer.Instance.Packets.Count > 3000) { MessageBox.Show( "Your computer is too slow to use this DPS meter. Can't analyse all those packet in decent amount of time. Shutting down now."); Exit(); } var message = _messageFactory.Create(obj); 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); AbnormalityTracker.RegisterSlaying(user?.User, pchangeHp.Slaying, pchangeHp.Time.Ticks); continue; } var changeMp = message as SPlayerChangeMp; if (changeMp != null) { 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.ToTeraDpsApi(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; } EntityTracker.Update(message); PlayerTracker.UpdateParty(message); //var sSpawnUser = message as SpawnUserServerMessage; //if (sSpawnUser != null) //{ // Console.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); continue; } var sLogin = message as LoginServerMessage; if (sLogin != null) { _abnormalityStorage.EndAll(message.Time.Ticks); AbnormalityTracker = new AbnormalityTracker(EntityTracker, PlayerTracker, BasicTeraData.Instance.HotDotDatabase, _abnormalityStorage, DamageTracker.Instance.Update); CharmTracker = new CharmTracker(AbnormalityTracker); Connected(BasicTeraData.Instance.Servers.GetServerName(sLogin.ServerId, Server)); //Console.WriteLine(sLogin.Name + " : " + BitConverter.ToString(BitConverter.GetBytes(sLogin.Id.Id))); continue; } } }
private static bool IsValidSkill(SkillResult message) { return(UserEntity.ForEntity(message.Source)["root_source"] != UserEntity.ForEntity(message.Target)["root_source"] || message.Damage == 0); }
private void InsertSkill(Entity entityTarget, Entity entitySource, Entity petSource, SkillResult message) { var skillType = Database.Database.Type.Mana; if (message.IsHp) { skillType = message.IsHeal ? Database.Database.Type.Heal : Database.Database.Type.Damage; } if (message.Amount == 0) { return; skillType = Database.Database.Type.Counter; } if (!IsValidSkill(message)) { return; skillType = Database.Database.Type.Counter; } // count DFA etc if (entityTarget is NpcEntity entity) { /* * Remove data from resetted boss when hitting a new boss * (we don't remove the data directly when the boss reset, to let the time for a review of the encounter.) */ if (LastIdleStartTime > 0 && message.Time.AddSeconds(-BasicTeraData.Instance.WindowData.IdleResetTimeout).Ticks >= LastIdleStartTime) { Reset(); } else { LastIdleStartTime = 0; } if (skillType == Database.Database.Type.Damage && entity.Info.Boss) { foreach (var delete in _toDelete) { DeleteEntity(delete); } _toDelete = new List <Entity>(); } if ((BasicTeraData.Instance.WindowData.DisplayOnlyBossHitByMeterUser && PacketProcessor.Instance.EntityTracker.MeterUser.Id == entitySource.Id) || !BasicTeraData.Instance.WindowData.DisplayOnlyBossHitByMeterUser) { UpdateCurrentBoss(entity); } } Database.Database.Instance.Insert(message.Amount, skillType, entityTarget, entitySource, message.SkillId, message.Abnormality, message.IsCritical, message.Time.Ticks, petSource, message.HitDirection); }
private void InsertSkill(Entity entityTarget, Entity entitySource, Entity petSource, SkillResult message) { if (!IsValidSkill(message)) { return; } var skillType = Database.Database.Type.Mana; if (message.IsHp) { skillType = message.IsHeal ? Database.Database.Type.Heal : Database.Database.Type.Damage; } var entity = entityTarget as NpcEntity; if (entity != null) { /* * Remove data from resetted boss when hitting a new boss * (we don't remove the data directly when the boss reset, to let the time for a review of the encounter.) */ if (skillType == Database.Database.Type.Damage && entity.Info.Boss) { foreach (var delete in _toDelete) { DeleteEntity(delete); } _toDelete = new List <Entity>(); } UpdateCurrentBoss(entity); } Database.Database.Instance.Insert(message.Amount, skillType, entityTarget, entitySource, message.SkillId, message.Abnormality, message.IsCritical, message.Time.Ticks, petSource, message.HitDirection); }