public void Update(StatsSummary nstatsSummary, Database.Structures.Skills nskills, List <NpcEntity> nentities, bool ntimedEncounter, AbnormalityStorage nabnormals, ConcurrentDictionary <string, NpcEntity> nbossHistory, List <ChatMessage> nchatbox, int npacketWaiting, NotifyFlashMessage nflash) { NetworkController.UpdateUiHandler changeUi = delegate(StatsSummary statsSummary, Database.Structures.Skills skills, List <NpcEntity> entities, bool timedEncounter, AbnormalityStorage abnormals, ConcurrentDictionary <string, NpcEntity> bossHistory, List <ChatMessage> chatbox, int packetWaiting, NotifyFlashMessage flash) { Scroller.MaxHeight = BasicTeraData.Instance.WindowData.NumberOfPlayersDisplayed * 30; UpdateComboboxEncounter(entities, statsSummary.EntityInformation.Entity); _entityStats.Update(statsSummary.EntityInformation, abnormals); _windowHistory.Update(bossHistory); _chatbox?.Update(chatbox); NotifyIcon.ShowBallon(flash); NotifyIcon.UpdatePacketWaiting(packetWaiting); PartyDps.Content = FormatHelpers.Instance.FormatValue(statsSummary.EntityInformation.Interval == 0 ? statsSummary.EntityInformation.TotalDamage : statsSummary.EntityInformation.TotalDamage * TimeSpan.TicksPerSecond / statsSummary.EntityInformation.Interval) + LP.PerSecond; var visiblePlayerStats = new HashSet <Player>(); var statsDamage = statsSummary.PlayerDamageDealt; var statsHeal = statsSummary.PlayerHealDealt; foreach (var playerStats in statsDamage) { PlayerStats playerStatsControl; Controls.TryGetValue(playerStats.Source, out playerStatsControl); if (playerStats.Amount == 0) { continue; } visiblePlayerStats.Add(playerStats.Source); if (playerStatsControl != null) { continue; } playerStatsControl = new PlayerStats(playerStats, statsHeal.FirstOrDefault(x => x.Source == playerStats.Source), statsSummary.EntityInformation, skills, abnormals.Get(playerStats.Source)); Controls.Add(playerStats.Source, playerStatsControl); } var invisibleControls = Controls.Where(x => !visiblePlayerStats.Contains(x.Key)).ToList(); foreach (var invisibleControl in invisibleControls) { Controls[invisibleControl.Key].CloseSkills(); Controls.Remove(invisibleControl.Key); } TotalDamage.Content = FormatHelpers.Instance.FormatValue(statsSummary.EntityInformation.TotalDamage); if (BasicTeraData.Instance.WindowData.ShowTimeLeft && statsSummary.EntityInformation.TimeLeft > 0) { var interval = TimeSpan.FromSeconds(statsSummary.EntityInformation.TimeLeft / TimeSpan.TicksPerSecond); Timer.Content = interval.ToString(@"mm\:ss"); Timer.Foreground = System.Windows.Media.Brushes.LightCoral; } else { var interval = TimeSpan.FromSeconds(statsSummary.EntityInformation.Interval / TimeSpan.TicksPerSecond); Timer.Content = interval.ToString(@"mm\:ss"); if (statsSummary.EntityInformation.Interval == 0 && BasicTeraData.Instance.WindowData.ShowTimeLeft) { Timer.Foreground = System.Windows.Media.Brushes.LightCoral; } else { Timer.Foreground = System.Windows.Media.Brushes.White; } } Players.Items.Clear(); foreach (var item in statsDamage) { if (!Controls.ContainsKey(item.Source)) { continue; } if (Players.Items.Contains(Controls[item.Source])) { BasicTeraData.LogError("duplicate playerinfo: \r\n" + String.Join("\r\n ", statsDamage.Select(x => x.Source.ToString() + " -> " + x.Amount)), false, true); continue; } Players.Items.Add(Controls[item.Source]); Controls[item.Source].Repaint(item, statsHeal.FirstOrDefault(x => x.Source == item.Source), statsSummary.EntityInformation, skills, abnormals.Get(item.Source), timedEncounter); } if (BasicTeraData.Instance.WindowData.InvisibleUi) { if (Controls.Count > 0 && !ForceWindowVisibilityHidden) { Visibility = Visibility.Visible; } if (Controls.Count == 0) { Visibility = Visibility.Hidden; } } else { if (!ForceWindowVisibilityHidden) { Visibility = Visibility.Visible; } } if (ActualWidth != _oldWidth) // auto snap to right screen border on width change { Screen screen = Screen.FromHandle(new WindowInteropHelper(Window.GetWindow(this)).Handle); // Transform screen point to WPF device independent point PresentationSource source = PresentationSource.FromVisual(this); if (source?.CompositionTarget == null) { return; } double dx = source.CompositionTarget.TransformToDevice.M11; if (Math.Abs(screen.WorkingArea.X + screen.WorkingArea.Width - (Left + _oldWidth) * dx) < 50) //snap at 50 px { Left = Left + _oldWidth - ActualWidth; } _oldWidth = ActualWidth; } }; Dispatcher.Invoke(changeUi, nstatsSummary, nskills, nentities, ntimedEncounter, nabnormals, nbossHistory, nchatbox, npacketWaiting, nflash); }
public void PcapWarning(string str) { BasicTeraData.LogError(str, false, true); }
public void Update(UiUpdateMessage nmessage) { void ChangeUi(UiUpdateMessage message) { RefreshClickThrou(); Scroller.MaxHeight = BasicTeraData.Instance.WindowData.NumberOfPlayersDisplayed * 30; UpdateComboboxEncounter(message.Entities, message.StatsSummary.EntityInformation.Entity); _entityStats.Update(message.StatsSummary.EntityInformation, message.Abnormals); _windowHistory.Update(message.BossHistory); _chatbox?.Update(message.Chatbox); _popupNotification.AddNotification(message.Flash); PartyDps.Content = FormatHelpers.Instance.FormatValue(message.StatsSummary.EntityInformation.Interval == 0 ? message.StatsSummary.EntityInformation.TotalDamage : message.StatsSummary.EntityInformation.TotalDamage * TimeSpan.TicksPerSecond / message.StatsSummary.EntityInformation.Interval) + LP.PerSecond; var visiblePlayerStats = new HashSet <Player>(); var statsDamage = message.StatsSummary.PlayerDamageDealt; var statsHeal = message.StatsSummary.PlayerHealDealt; foreach (var playerStats in statsDamage) { PlayerStats playerStatsControl; Controls.TryGetValue(playerStats.Source, out playerStatsControl); if (playerStats.Amount == 0) { continue; } visiblePlayerStats.Add(playerStats.Source); if (playerStatsControl != null) { continue; } playerStatsControl = new PlayerStats(playerStats, statsHeal.FirstOrDefault(x => x.Source == playerStats.Source), message.StatsSummary.EntityInformation, message.Skills, message.Abnormals.Get(playerStats.Source)); Controls.Add(playerStats.Source, playerStatsControl); } DXrender?.Draw(statsDamage.ToClassInfo(message.StatsSummary.EntityInformation.TotalDamage, message.StatsSummary.EntityInformation.Interval)); var invisibleControls = Controls.Where(x => !visiblePlayerStats.Contains(x.Key)).ToList(); foreach (var invisibleControl in invisibleControls) { Controls[invisibleControl.Key].CloseSkills(); Controls.Remove(invisibleControl.Key); } TotalDamage.Content = FormatHelpers.Instance.FormatValue(message.StatsSummary.EntityInformation.TotalDamage); if (BasicTeraData.Instance.WindowData.ShowTimeLeft && message.StatsSummary.EntityInformation.TimeLeft > 0) { var interval = TimeSpan.FromSeconds(message.StatsSummary.EntityInformation.TimeLeft / TimeSpan.TicksPerSecond); Timer.Content = interval.ToString(@"mm\:ss"); Timer.Foreground = Brushes.LightCoral; } else { var interval = TimeSpan.FromSeconds(message.StatsSummary.EntityInformation.Interval / TimeSpan.TicksPerSecond); Timer.Content = interval.ToString(@"mm\:ss"); if (message.StatsSummary.EntityInformation.Interval == 0 && BasicTeraData.Instance.WindowData.ShowTimeLeft) { Timer.Foreground = Brushes.LightCoral; } else { Timer.Foreground = Brushes.White; } } Players.Items.Clear(); foreach (var item in statsDamage) { if (!Controls.ContainsKey(item.Source)) { continue; } if (Players.Items.Contains(Controls[item.Source])) { BasicTeraData.LogError( "duplicate playerinfo: \r\n" + string.Join("\r\n ", statsDamage.Select(x => x.Source.ToString() + " -> " + x.Amount)), false, true); continue; } Players.Items.Add(Controls[item.Source]); Controls[item.Source].Repaint(item, statsHeal.FirstOrDefault(x => x.Source == item.Source), message.StatsSummary.EntityInformation, message.Skills, message.Abnormals.Get(item.Source), message.TimedEncounter); } if (BasicTeraData.Instance.WindowData.InvisibleUi && !_paused) { if (Controls.Count > 0 && !ForceWindowVisibilityHidden && Visibility != Visibility.Visible) { ShowWindow(); } //Visibility = Visibility.Visible; } if (Controls.Count == 0 && Visibility != Visibility.Hidden) { HideWindow(); } //Visibility = Visibility.Hidden; } } else if (!ForceWindowVisibilityHidden && Visibility != Visibility.Visible) { ShowWindow(); } //Visibility = Visibility.Visible; } if (TeraWindow.IsTeraActive() && BasicTeraData.Instance.WindowData.Topmost) { StayTopMost(); } } Dispatcher.Invoke((PacketProcessor.UpdateUiHandler)ChangeUi, nmessage); }
internal S_LOGIN(LoginServerMessage message) { if (PacketProcessor.Instance.NeedInit) { PacketProcessor.Instance.RaiseConnected(BasicTeraData.Instance.Servers.GetServerName(message.ServerId, PacketProcessor.Instance.Server)); PacketProcessor.Instance.Server = BasicTeraData.Instance.Servers.GetServer(message.ServerId, PacketProcessor.Instance.Server); PacketProcessor.Instance.MessageFactory.Region = PacketProcessor.Instance.Server.Region; var trackerreset = true; if (PacketProcessor.Instance.EntityTracker != null) { try { var oldregion = BasicTeraData.Instance.Servers.GetServer(PacketProcessor.Instance.EntityTracker.MeterUser.ServerId).Region; trackerreset = PacketProcessor.Instance.Server.Region != oldregion; } catch { BasicTeraData.LogError( "New server:" + PacketProcessor.Instance.Server + ";Old server Id:" + PacketProcessor.Instance.EntityTracker.MeterUser?.ServerId, false, true); } } if (trackerreset) { PacketProcessor.Instance.TeraData = BasicTeraData.Instance.DataForRegion(PacketProcessor.Instance.Server.Region); BasicTeraData.Instance.HotDotDatabase.Enraged.Name = LP.Enrage; BasicTeraData.Instance.HotDotDatabase.Slaying.Name = LP.Slaying; BasicTeraData.Instance.HotDotDatabase.Slaying.Tooltip = LP.SlayingTooltip; PacketProcessor.Instance.EntityTracker = new EntityTracker(BasicTeraData.Instance.MonsterDatabase, PacketProcessor.Instance.UserLogoTracker); PacketProcessor.Instance.PlayerTracker = new PlayerTracker(PacketProcessor.Instance.EntityTracker, BasicTeraData.Instance.Servers); PacketProcessor.Instance.MeterPlayers.Clear(); Database.Database.Instance.DeleteAll(); SelectFont(PacketProcessor.Instance.Server.Region); } PacketProcessor.Instance.NeedInit = false; } PacketProcessor.Instance.AbnormalityStorage.EndAll(message.Time.Ticks); PacketProcessor.Instance.AbnormalityTracker = new AbnormalityTracker(PacketProcessor.Instance.EntityTracker, PacketProcessor.Instance.PlayerTracker, BasicTeraData.Instance.HotDotDatabase, PacketProcessor.Instance.AbnormalityStorage, DamageTracker.Instance.Update); if (PacketProcessor.Instance.MessageFactory.ChatEnabled) { PacketProcessor.Instance.AbnormalityTracker.AbnormalityAdded += NotifyProcessor.Instance.AbnormalityNotifierAdded; PacketProcessor.Instance.AbnormalityTracker.AbnormalityRemoved += NotifyProcessor.Instance.AbnormalityNotifierRemoved; } PacketProcessor.Instance.OnGuildIconAction(PacketProcessor.Instance.UserLogoTracker.GetLogo(message.PlayerId)); PacketProcessor.Instance.EntityTracker.Update(message); PacketProcessor.Instance.PlayerTracker.UpdateParty(message); BasicTeraData.Instance.EventsData.Load(PacketProcessor.Instance.EntityTracker.MeterUser.RaceGenderClass.Class); if (BasicTeraData.Instance.WindowData.UserPaused) { PacketProcessor.Instance.PacketProcessing.Pause(); } else { PacketProcessor.Instance.PacketProcessing.Update(); } PacketProcessor.Instance.RaisePause(BasicTeraData.Instance.WindowData.UserPaused); var me = PacketProcessor.Instance.PlayerTracker.Me(); if (!PacketProcessor.Instance.MeterPlayers.Contains(me)) { PacketProcessor.Instance.MeterPlayers.Add(me); } RichPresence.Instance.Login(me); }
public void Invoke() { try { _client?.Invoke(); } catch (Exception e) { BasicTeraData.LogError("Discord RPC invoke error: " + e.Message, false, true); } }
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 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 sLogin = message as LoginServerMessage; if (sLogin != null) { if (_needInit) { Server = BasicTeraData.Servers.GetServer(sLogin.ServerId, Server); _messageFactory.Version = Server.Region; Logger.Info($"Logged in to server {Server.Name}."); _teraData = BasicTeraData.DataForRegion(Server.Region); _entityTracker = new EntityTracker(_teraData.NpcDatabase); _playerTracker = new PlayerTracker(_entityTracker, BasicTeraData.Servers); _abnormalityTracker = new AbnormalityTracker(_entityTracker, _playerTracker, _teraData.HotDotDatabase, _abnormalityStorage, CheckUpdate); _entityTracker.Update(message); _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); return; } }
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 (_keepAlive) { if (NeedToCopy != null) { var currentBoss = Encounter; var timedEncounter = TimedEncounter; var entityInfo = Database.Database.Instance.GlobalInformationEntity(currentBoss, timedEncounter, BasicTeraData.Instance.WindowData.DisplayTimerBasedOnAggro); 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.HasFlag(DataExporter.Dest.None)) { DataExporter.ManualExport(Encounter, AbnormalityStorage, NeedToExport); NeedToExport = DataExporter.Dest.None; } Encounter = NewEncounter; var packetsWaiting = TeraSniffer.Instance.Packets.Count; if (packetsWaiting > 5000) { PacketProcessing.Pause(); Database.Database.Instance.DeleteAll(); AbnormalityStorage = new AbnormalityStorage(); AbnormalityTracker = new AbnormalityTracker(EntityTracker, PlayerTracker, BasicTeraData.Instance.HotDotDatabase, AbnormalityStorage, DamageTracker.Instance.Update); HudManager.Instance.CurrentBosses.DisposeAll(); TeraSniffer.Instance.Packets = new ConcurrentQueue <Message>(); NotifyProcessor.Instance.S_LOAD_TOPO(null); RaisePause(true); } if (_forceUiUpdate) { UpdateUi(packetsWaiting); _forceUiUpdate = false; } CheckUpdateUi(packetsWaiting); var successDequeue = TeraSniffer.Instance.Packets.TryDequeue(out Message obj); if (!successDequeue) { Thread.Sleep(1); continue; } var message = MessageFactory.Create(obj); if (message.GetType() == typeof(UnknownMessage)) { continue; } if (!PacketProcessing.Process(message)) { //Unprocessed packet } } }
internal void HandleTcpReceived(uint sequenceNumber, byte[] data) { var dataPosition = SequenceNumberToBytesReceived(sequenceNumber); long needToSkip = 0; NextSequenceNumber = (uint)(sequenceNumber + data.Length); if (dataPosition == BytesReceived) { OnDataReceived(data, (int)needToSkip); BytesReceived += data.Length; } else { //if (!_bufferedPackets.ContainsKey(dataPosition) || // _bufferedPackets[dataPosition].Length < data.Length) //{ _bufferedPackets[dataPosition] = data; //} } if (_bufferedPackets.Count > 500) { var name = (from x in new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem").Get().Cast <ManagementObject>() select x.GetPropertyValue("Version") + " Memory Total:" + x.GetPropertyValue("TotalVisibleMemorySize") + " Virtual:" + x.GetPropertyValue("TotalVirtualMemorySize") + " PhFree:" + x.GetPropertyValue("FreePhysicalMemory") + " VFree:" + x.GetPropertyValue("FreeVirtualMemory") ).FirstOrDefault() ?? "unknown"; name = name + " CPU:" + ((from x in new ManagementObjectSearcher("SELECT * FROM Win32_Processor").Get().Cast <ManagementObject>() select x.GetPropertyValue("Name") + " load:" + x.GetPropertyValue("LoadPercentage") + "%").FirstOrDefault() ?? "processor unknown"); string debug = (BasicTeraData.Instance.WindowData.LowPriority ? "Low priority " : "Normal priority ") + SnifferType + " running on win " + name + " Received: " + BytesReceived + "\r\n" + _bufferedPackets.First().Key + ": " + _bufferedPackets.First().Value.Length + "\r\nQueue length:" + _bufferedPackets.Count; while (_bufferedPackets.Values.First().Length >= 500) { _bufferedPackets.Remove(_bufferedPackets.Keys.First()); if (_bufferedPackets.Count == 0) { return; } } //we don't know, whether large packet is continuation of previous message or not - so skip until new short message. if (BytesReceived + 500 <= _bufferedPackets.Keys.First()) { _bufferedPackets.Remove(_bufferedPackets.Keys.First()); } //and even after skipping long fragments we don't know, whether small fragment after big is a new short message or a big message tail - skip small one too. needToSkip = _bufferedPackets.Keys.First() - BytesReceived; BytesReceived = _bufferedPackets.Keys.First(); BasicTeraData.LogError(debug + "\r\nNew Queue length:" + _bufferedPackets.Count + "\r\nSkipping bytes:" + needToSkip, false, true); } long firstBufferedPosition; while (_bufferedPackets.Any() && ((firstBufferedPosition = _bufferedPackets.Keys.First()) <= BytesReceived)) { var dataArray = _bufferedPackets[firstBufferedPosition]; _bufferedPackets.Remove(firstBufferedPosition); var alreadyReceivedBytes = BytesReceived - firstBufferedPosition; Debug.Assert(alreadyReceivedBytes >= 0); if (alreadyReceivedBytes > dataArray.Length) { continue; } var count = dataArray.Length - alreadyReceivedBytes; OnDataReceived(dataArray.Skip((int)alreadyReceivedBytes).Take((int)count).ToArray(), (int)needToSkip); BytesReceived += count; needToSkip = 0; } }
internal void HandleTcpReceived(uint sequenceNumber, byte[] data) { var dataPosition = SequenceNumberToBytesReceived(sequenceNumber); long needToSkip = 0; NextSequenceNumber = (uint)(sequenceNumber + data.Length); if (dataPosition == BytesReceived) { OnDataReceived(data, (int)needToSkip); BytesReceived += data.Length; } else { //if (!_bufferedPackets.ContainsKey(dataPosition) || // _bufferedPackets[dataPosition].Length < data.Length) //{ _bufferedPackets[dataPosition] = data; //} } if (_bufferedPackets.Count > 500) { var debug = (BasicTeraData.Instance.WindowData.LowPriority ? "Low priority " : "Normal priority ") + SnifferType + " Received: " + BytesReceived + "\r\n" + _bufferedPackets.First().Key + ": " + _bufferedPackets.First().Value.Length + "\r\nQueue length:" + _bufferedPackets.Count; while (_bufferedPackets.Values.First().Length >= 500) { _bufferedPackets.Remove(_bufferedPackets.Keys.First()); if (_bufferedPackets.Count == 0) { return; } } //we don't know, whether large packet is continuation of previous message or not - so skip until new short message. if (BytesReceived + 500 <= _bufferedPackets.Keys.First()) { _bufferedPackets.Remove(_bufferedPackets.Keys.First()); } //and even after skipping long fragments we don't know, whether small fragment after big is a new short message or a big message tail - skip small one too. needToSkip = _bufferedPackets.Keys.First() - BytesReceived; BytesReceived = _bufferedPackets.Keys.First(); BasicTeraData.LogError(debug + "\r\nNew Queue length:" + _bufferedPackets.Count + "\r\nSkipping bytes:" + needToSkip, false, true); } long firstBufferedPosition; while (_bufferedPackets.Any() && (firstBufferedPosition = _bufferedPackets.Keys.First()) <= BytesReceived) { var dataArray = _bufferedPackets[firstBufferedPosition]; _bufferedPackets.Remove(firstBufferedPosition); var alreadyReceivedBytes = BytesReceived - firstBufferedPosition; Debug.Assert(alreadyReceivedBytes >= 0); if (alreadyReceivedBytes > dataArray.Length) { continue; } var count = dataArray.Length - alreadyReceivedBytes; OnDataReceived(dataArray.Skip((int)alreadyReceivedBytes).Take((int)count).ToArray(), (int)needToSkip); BytesReceived += count; needToSkip = 0; } }
public void ShowBallon(Tuple <string, string> flash) { if (flash == null) { return; } Tray.HideBalloonTip(); if (BasicTeraData.Instance.WindowData.PopupDisplayTime >= 500) { var balloon = new Balloon(); balloon.Value(flash.Item1, flash.Item2); Tray.ShowCustomBalloon(balloon, System.Windows.Controls.Primitives.PopupAnimation.Fade, BasicTeraData.Instance.WindowData.PopupDisplayTime); } var file = Path.Combine(BasicTeraData.Instance.ResourceDirectory, "sound/", BasicTeraData.Instance.WindowData.NotifySound); if (!File.Exists(file)) { file = BasicTeraData.Instance.WindowData.NotifySound; if (!File.Exists(file)) { return; } } lock (_lock) { if (_needToStop) { return; } } try { _outputStream = new MediaFoundationReader(file); _volumeStream = new WaveChannel32(_outputStream); _volumeStream.Volume = BasicTeraData.Instance.WindowData.Volume; //Create WaveOutEvent since it works in Background and UI Threads _player = new WaveOutEvent(); //Init Player with Configured Volume Stream _player.Init(_volumeStream); _player.Play(); _needToStop = true; var timer = new System.Threading.Timer((obj) => { lock (_lock) { _needToStop = false; _player.Stop(); _player.Dispose(); _volumeStream.Dispose(); _outputStream.Dispose(); _outputStream = null; _player = null; _volumeStream = null; } }, null, BasicTeraData.Instance.WindowData.SoundNotifyDuration, System.Threading.Timeout.Infinite); } catch (Exception e) { // Get stack trace for the exception with source file information var st = new StackTrace(e, true); // Get the top stack frame var frame = st.GetFrame(0); // Get the line number from the stack frame var line = frame.GetFileLineNumber(); BasicTeraData.LogError("Sound ERROR test" + e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine + e.InnerException + Environment.NewLine + e + Environment.NewLine + "filename:" + file + Environment.NewLine + "line:" + line, false, true); } }
private void Receive(ArraySegment <byte> ipData) { var ipPacket = new Ip4Packet(ipData); var protocol = ipPacket.Protocol; if (protocol != IpProtocol.Tcp) { return; } var tcpPacket = new TcpPacket(ipPacket.Payload); if (tcpPacket.Bad) { return; } var isFirstPacket = (tcpPacket.Flags & TcpFlags.Syn) != 0; var connectionId = new ConnectionId(ipPacket.SourceIp, tcpPacket.SourcePort, ipPacket.DestinationIp, tcpPacket.DestinationPort); lock (_lock) { TcpConnection connection; bool isInterestingConnection; if (isFirstPacket) { connection = new TcpConnection(connectionId, tcpPacket.SequenceNumber); OnNewConnection(connection); isInterestingConnection = connection.HasSubscribers; if (!isInterestingConnection) { return; } _connections[connectionId] = connection; Debug.Assert(tcpPacket.Payload.Count == 0); } else { isInterestingConnection = _connections.TryGetValue(connectionId, out connection); if (!isInterestingConnection) { return; } if ((ipPacket.Flags & 1) == 1) { BasicTeraData.LogError("Fragmented packet"); } if (!string.IsNullOrEmpty(TcpLogFile)) { File.AppendAllText(TcpLogFile, string.Format("{0} {1}+{4} | {2} {3}+{4} ACK {5} ({6})\r\n", connection.CurrentSequenceNumber, tcpPacket.SequenceNumber, connection.BytesReceived, connection.SequenceNumberToBytesReceived(tcpPacket.SequenceNumber), tcpPacket.Payload.Count, tcpPacket.AcknowledgementNumber, connection.BufferedPacketDescription)); } connection.HandleTcpReceived(tcpPacket.SequenceNumber, tcpPacket.Payload); } } }
public void Update(StatsSummary nstatsSummary, Database.Structures.Skills nskills, List <NpcEntity> nentities, bool ntimedEncounter, AbnormalityStorage nabnormals, ConcurrentDictionary <string, NpcEntity> nbossHistory, List <ChatMessage> nchatbox, int npacketWaiting, Tuple <string, string> nflash) { NetworkController.UpdateUiHandler changeUi = delegate(StatsSummary statsSummary, Database.Structures.Skills skills, List <NpcEntity> entities, bool timedEncounter, AbnormalityStorage abnormals, ConcurrentDictionary <string, NpcEntity> bossHistory, List <ChatMessage> chatbox, int packetWaiting, Tuple <string, string> flash) { Scroller.MaxHeight = BasicTeraData.Instance.WindowData.NumberOfPlayersDisplayed * 30; UpdateComboboxEncounter(entities, statsSummary.EntityInformation.Entity); _entityStats.Update(statsSummary.EntityInformation, abnormals); _windowHistory.Update(bossHistory); _chatbox?.Update(chatbox); NotifyIcon.ShowBallon(flash); NotifyIcon.UpdatePacketWaiting(packetWaiting); PartyDps.Content = FormatHelpers.Instance.FormatValue(statsSummary.EntityInformation.Interval == 0 ? statsSummary.EntityInformation.TotalDamage : statsSummary.EntityInformation.TotalDamage * TimeSpan.TicksPerSecond / statsSummary.EntityInformation.Interval) + LP.PerSecond; var visiblePlayerStats = new HashSet <Player>(); var statsDamage = statsSummary.PlayerDamageDealt; var statsHeal = statsSummary.PlayerHealDealt; foreach (var playerStats in statsDamage) { PlayerStats playerStatsControl; Controls.TryGetValue(playerStats.Source, out playerStatsControl); if (playerStats.Amount == 0) { continue; } visiblePlayerStats.Add(playerStats.Source); if (playerStatsControl != null) { continue; } playerStatsControl = new PlayerStats(playerStats, statsHeal.FirstOrDefault(x => x.Source == playerStats.Source), statsSummary.EntityInformation, skills, abnormals.Get(playerStats.Source)); Controls.Add(playerStats.Source, playerStatsControl); } var invisibleControls = Controls.Where(x => !visiblePlayerStats.Contains(x.Key)).ToList(); foreach (var invisibleControl in invisibleControls) { Controls[invisibleControl.Key].CloseSkills(); Controls.Remove(invisibleControl.Key); } TotalDamage.Content = FormatHelpers.Instance.FormatValue(statsSummary.EntityInformation.TotalDamage); var interval = TimeSpan.FromSeconds(statsSummary.EntityInformation.Interval / TimeSpan.TicksPerSecond); Timer.Content = interval.ToString(@"mm\:ss"); Players.Items.Clear(); foreach (var item in statsDamage) { if (!Controls.ContainsKey(item.Source)) { continue; } if (Players.Items.Contains(Controls[item.Source])) { BasicTeraData.LogError("duplicate playerinfo: \r\n" + String.Join("\r\n ", statsDamage.Select(x => x.Source.ToString() + " -> " + x.Amount)), false, true); continue; } Players.Items.Add(Controls[item.Source]); Controls[item.Source].Repaint(item, statsHeal.FirstOrDefault(x => x.Source == item.Source), statsSummary.EntityInformation, skills, abnormals.Get(item.Source), timedEncounter); } if (BasicTeraData.Instance.WindowData.InvisibleUi) { if (Controls.Count > 0 && !ForceWindowVisibilityHidden) { Visibility = Visibility.Visible; } if (Controls.Count == 0) { Visibility = Visibility.Hidden; } } else { if (!ForceWindowVisibilityHidden) { Visibility = Visibility.Visible; } } }; Dispatcher.Invoke(changeUi, nstatsSummary, nskills, nentities, ntimedEncounter, nabnormals, nbossHistory, nchatbox, npacketWaiting, nflash); }