public static void AutomatedExport(NpcEntity entity, AbnormalityStorage abnormality) { if (entity == null) { return; } var stats = GenerateStats(entity, abnormality); if (stats == null) { return; } JsonExporter.JsonSave(stats, PacketProcessor.Instance.EntityTracker.MeterUser.Name); var sendThread = new Thread(() => { DpsServers.Where(x => !x.AnonymousUpload).ToList().ForEach(x => x.CheckAndSendFightData(stats.BaseStats, entity)); ExcelExporter.ExcelSave(stats, PacketProcessor.Instance.EntityTracker.MeterUser.Name); Anonymize(stats.BaseStats); DpsServers.Where(x => x.AnonymousUpload).ToList().ForEach(x => x.CheckAndSendFightData(stats.BaseStats, entity)); if (BasicTeraData.Instance.WindowData.PacketsCollect) { try { PacketsExporter.Instance.Export(stats.BaseStats, entity); } catch (Exception ex) { BasicTeraData.LogError("##### Packets export EXCEPTION #####\r\n" + 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); } } }); sendThread.Start(); }
public void Error(string message, params object[] args) { if (message != "Failed connection to {0}. {1}" && message != "Failed to connect for some reason.") { BasicTeraData.LogError("DiscordRPC logged error:\r\n" + message, false, true); } }
internal void S_BEGIN_THROUGH_ARBITER_CONTRACT(S_BEGIN_THROUGH_ARBITER_CONTRACT message) { if (message.PlayerName.StartsWith("Error")) { BasicTeraData.LogError(message.PlayerName); } }
private static void MessageReceived(Tera.Message obj) { if (obj.Direction == Tera.MessageDirection.ClientToServer && obj.OpCode == 19900) { var message = new C_CHECK_VERSION_CUSTOM(new CustomReader(obj)); Version = message.Versions[0]; OpcodeDownloader.DownloadIfNotExist(Version, Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/")); if (!File.Exists(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/{message.Versions[0]}.txt")) && !File.Exists(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/protocol.{message.Versions[0]}.map")) || !File.Exists(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/smt_{message.Versions[0]}.txt")) && !File.Exists(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/sysmsg.{message.Versions[0]}.map"))) { { BasicTeraData.LogError("Unknown client version: " + message.Versions[0]); System.Windows.MessageBox.Show("Unknown client version: " + message.Versions[0]); App.CloseApp(); return; } } OpCodeNamer = new OpCodeNamer(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/{message.Versions[0]}.txt")); SystemMessageNamer = new OpCodeNamer(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/smt_{message.Versions[0]}.txt")); MessageFactory.Init(); TeraSniffer.Instance.Connected = true; Proxy.ConnectToProxy(); } Packets.Enqueue(obj); }
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); throw; } } 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); BasicTeraData.Instance.EventsData.Load(PacketProcessor.Instance.EntityTracker.MeterUser.RaceGenderClass.Class); PacketProcessor.Instance.PacketProcessing.Update(); PacketProcessor.Instance.RaisePause(false); var me = PacketProcessor.Instance.PlayerTracker.Me(); if (!PacketProcessor.Instance.MeterPlayers.Contains(me)) { PacketProcessor.Instance.MeterPlayers.Add(me); } RichPresence.Instance.Login(me); }
internal C_CHECK_VERSION(Tera.Game.Messages.C_CHECK_VERSION message) { Debug.WriteLine("VERSION0 = " + message.Versions[0]); // Debug.WriteLine("VERSION1 = " + message.Versions[1]); OpcodeDownloader.DownloadIfNotExist(message.Versions[0], Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/")); if (!File.Exists(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/{message.Versions[0]}.txt")) && !File.Exists(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/protocol.{message.Versions[0]}.map")) || !File.Exists(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/smt_{message.Versions[0]}.txt")) && !File.Exists(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/sysmsg.{message.Versions[0]}.map"))) { BasicTeraData.LogError("Unknown client version: " + message.Versions[0]); MessageBox.Show(LP.Unknown_client_version + message.Versions[0]); PacketProcessor.Instance.Exit(); return; } var opCodeNamer = new OpCodeNamer(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/{message.Versions[0]}.txt")); var sysMsgNamer = new OpCodeNamer(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/smt_{message.Versions[0]}.txt")); TeraSniffer.Instance.Connected = true; PacketProcessor.Instance.MessageFactory = new MessageFactory(opCodeNamer, PacketProcessor.Instance.Server.Region, message.Versions[0], false, sysMsgNamer); if (TeraSniffer.Instance.ClientProxyOverhead + TeraSniffer.Instance.ServerProxyOverhead > 0x1000) { BasicTeraData.LogError("Client Proxy overhead: " + TeraSniffer.Instance.ClientProxyOverhead + "\r\nServer Proxy overhead: " + TeraSniffer.Instance.ServerProxyOverhead); } }
internal void HandleTcpReceived(uint sequenceNumber, ArraySegment <byte> data) { var dataPosition = SequenceNumberToBytesReceived(sequenceNumber); NextSequenceNumber = (uint)(sequenceNumber + data.Count); if (dataPosition == BytesReceived) { OnDataReceived(data); BytesReceived += data.Count; } else { var dataArray = new byte[data.Count]; Array.Copy(data.Array, data.Offset, dataArray, 0, data.Count); if (!_bufferedPackets.ContainsKey(dataPosition) || _bufferedPackets[dataPosition].Length < dataArray.Length) { _bufferedPackets[dataPosition] = dataArray; } } if (_bufferedPackets.Count > 1000) { string debug = (BasicTeraData.Instance.WindowData.LowPriority ? "Low priority" : "Normal priority") + " Received: " + BytesReceived + "\r\n" + String.Join("\r\n", _bufferedPackets.Take(10).Select(x => "" + x.Key + ": " + x.Value.Length)) + "\r\nQueue length:" + _bufferedPackets.Count; while (_bufferedPackets.Values.First().Length >= 500) { _bufferedPackets.Remove(_bufferedPackets.Keys.First()); } //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. BytesReceived = _bufferedPackets.Keys.First(); BasicTeraData.LogError(debug + "\r\nNew Queue length:" + _bufferedPackets.Count, 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(new ArraySegment <byte>(dataArray, (int)alreadyReceivedBytes, (int)count)); BytesReceived += count; } }
private static void GlobalUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e) { var ex = (Exception)e.ExceptionObject; BasicTeraData.LogError("##### CRASH #####\r\n" + 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); MessageBox.Show(LP.MainWindow_Fatal_error); }
private static void GlobalThreadExceptionHandler(object sender, ThreadExceptionEventArgs e) { var ex = e.Exception; BasicTeraData.LogError("##### FORM EXCEPTION #####\r\n" + 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); MessageBox.Show(LP.MainWindow_Fatal_error); }
private void UpdatePresence(DiscordRPC.RichPresence presence = null) { if (!BasicTeraData.Instance.WindowData.EnableRichPresence || !BasicTeraData.Instance.WindowData.EnableChat) { return; } presence = presence ?? Presence; try { Client?.SetPresence(presence); } catch (Exception e) { BasicTeraData.LogError("Discord RPC set presence fail: " + e.Message, false, true); } }
private DiscordRpcClient InitClient() { try { var logger = new ShinraLogger { Level = LogLevel.Error }; _client = new DiscordRpcClient(ClientId, -1, logger); _client.Initialize(); } catch (Exception e) { BasicTeraData.LogError("Discord RPC Init fail: " + e.Message, false, true); } return(_client); }
private void PlaySound() { 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; } } try { //Create Output Stream with Data from Audio File / Network Stream var outputStream = new MediaFoundationReader(file); //Create Volume Stream to control volume of output //ex: volumeStream.Volume = 0.5f; Float between 0 & 1 var volumeStream = new WaveChannel32(outputStream); volumeStream.Volume = BasicTeraData.Instance.WindowData.Volume; //Create WaveOutEvent since it works in Background and UI Threads var player = new WaveOutEvent(); //Init Player with Configured Volume Stream player.Init(volumeStream); player.Play(); var timer = new System.Threading.Timer((obj) => { 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); } }
internal C_CHECK_VERSION(Tera.Game.Messages.C_CHECK_VERSION message) { Debug.WriteLine("VERSION0 = " + message.Versions[0]); // Debug.WriteLine("VERSION1 = " + message.Versions[1]); var opCodeNamer = new OpCodeNamer(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/{message.Versions[0]}.txt")); var sysMsgNamer = new OpCodeNamer(Path.Combine(BasicTeraData.Instance.ResourceDirectory, $"data/opcodes/smt_{message.Versions[0]}.txt")); TeraSniffer.Instance.Connected = true; NetworkController.Instance.MessageFactory = new MessageFactory(opCodeNamer, NetworkController.Instance.Server.Region, message.Versions[0], false, sysMsgNamer); if (TeraSniffer.Instance.ClientProxyOverhead + TeraSniffer.Instance.ServerProxyOverhead > 0x1000) { BasicTeraData.LogError("Client Proxy overhead: " + TeraSniffer.Instance.ClientProxyOverhead + "\r\nServer Proxy overhead: " + TeraSniffer.Instance.ServerProxyOverhead); } }
internal void HandleTcpReceived(uint sequenceNumber, ArraySegment <byte> data) { var dataPosition = SequenceNumberToBytesReceived(sequenceNumber); NextSequenceNumber = (uint)(sequenceNumber + data.Count); if (dataPosition == BytesReceived) { OnDataReceived(data); BytesReceived += data.Count; } else { var dataArray = new byte[data.Count]; Array.Copy(data.Array, data.Offset, dataArray, 0, data.Count); if (!_bufferedPackets.ContainsKey(dataPosition) || _bufferedPackets[dataPosition].Length < dataArray.Length) { _bufferedPackets[dataPosition] = dataArray; } } if (_bufferedPackets.Count > 300) { BasicTeraData.LogError("Received: " + BytesReceived + "\r\n" + String.Join("\r\n", _bufferedPackets.Take(10).Select(x => "" + x.Key + ": " + x.Value.Length)), false, true); BytesReceived = _bufferedPackets.Keys.First(); } 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(new ArraySegment <byte>(dataArray, (int)alreadyReceivedBytes, (int)count)); BytesReceived += count; } }
public void Export(EncounterBase teradpsData, NpcEntity entity) { FetchAllowedAreaId(); BasicTeraData.LogError("PacketExport: Start", true); // Only export when a notable dungeons is cleared var areaId = int.Parse(teradpsData.areaId); if (!_allowedAreaId.Any(x => x.AreaId == areaId && (x.BossIds.Count == 0 || x.BossIds.Contains((int)entity.Info.TemplateId)))) { BasicTeraData.LogError("PacketExport: Boss not allowed, exiting", true); TeraSniffer.Instance.EnableMessageStorage = false; return; } if (!TeraSniffer.Instance.EnableMessageStorage) { BasicTeraData.LogError("PacketExport: Option not activated, exiting", true); // Message storing have already been stopped return; } // Keep a local reference of the packet list Queue <Message> packetsCopyStorage = TeraSniffer.Instance.GetPacketsLogsAndStop(); if (!packetsCopyStorage.Any()) { BasicTeraData.LogError("PacketExport: Empty packet log, exiting", true); return; } var version = PacketProcessor.Instance.MessageFactory.Version; Guid id = Guid.NewGuid(); string filename = version + "_" + id; Debug.WriteLine("Start exporting data"); BasicTeraData.LogError("PacketExport: Export data to tmp file", true); SaveToTmpFile(version.ToString(), packetsCopyStorage, filename + ".TeraLog"); BasicTeraData.LogError("PacketExport: Compress file", true); Compress(filename + ".TeraLog", filename + ".7z"); File.Delete(filename + ".TeraLog"); BasicTeraData.LogError("PacketExport: Encrypt file", true); Encrypt(filename + ".7z", filename + ".rsa"); File.Delete(filename + ".7z"); BasicTeraData.LogError("PacketExport: Send file", true); Send(filename + ".rsa", version); File.Delete(filename + ".rsa"); }
public void Play() { var file = System.IO.File.Exists(File) ? File : Path.Combine(BasicTeraData.Instance.ResourceDirectory, "sound/", File); try { var outputStream = new MediaFoundationReader(file); var volumeStream = new WaveChannel32(outputStream) { Volume = Volume }; //Create WaveOutEvent since it works in Background and UI Threads var player = new DirectSoundOut(); //Init Player with Configured Volume Stream player.Init(volumeStream); player.Play(); var timer = new Timer(obj => { player.Stop(); player.Dispose(); volumeStream.Dispose(); outputStream.Dispose(); outputStream = null; player = null; volumeStream = null; }, null, Duration, 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 Send(string filename, uint version) { var filebytes = File.ReadAllBytes(filename); SHA1Managed sha = new SHA1Managed(); byte[] checksum = sha.ComputeHash(filebytes); var sendCheckSum = BitConverter.ToString(checksum).Replace("-", string.Empty); Debug.WriteLine(sendCheckSum); BasicTeraData.LogError("PacketExport: Send hash: " + sendCheckSum, true); ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; using (var client = new HttpClient()) { client.Timeout = TimeSpan.FromSeconds(3600); var response = client.PostAsync( new Uri("https://neowutran.ovh:8083/store_packets?version=" + version + "&sha1=" + sendCheckSum), new ByteArrayContent(filebytes) ); BasicTeraData.LogError("PacketExport: " + response.Result.Content.ReadAsStringAsync().Result, true); Debug.WriteLine(response.Result.Content.ReadAsStringAsync().Result); } }
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) { 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) { UpdateComboboxEncounter(entities, statsSummary.EntityInformation.Entity); _entityStats.Update(statsSummary.EntityInformation, abnormals); _windowHistory.Update(bossHistory); _chatbox.Update(chatbox); _systemTray.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.Target + ": " + 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); }
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))); } }
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); } }
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) { string 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; } }
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); 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 > 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); if (message.GetType() == typeof(UnknownMessage)) { continue; } if (!PacketProcessing.Process(message)) { //Unprocessed packet } } }
public void Invoke() { try { _client?.Invoke(); } catch (Exception e) { BasicTeraData.LogError("Discord RPC invoke error: " + e.Message, false, true); } }
private void OnResync(MessageDirection direction, int skipped, int size) { BasicTeraData.LogError("Resync occured " + direction + ", skipped:" + skipped + ", block size:" + size, false, true); }
public void PcapWarning(string str) { BasicTeraData.LogError(str, false, true); }
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) { void ChangeUi(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 = 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 = 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), 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 { var screen = Screen.FromHandle(new WindowInteropHelper(GetWindow(this)).Handle); // Transform screen point to WPF device independent point var source = PresentationSource.FromVisual(this); if (source?.CompositionTarget == null) { return; } var 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((NetworkController.UpdateUiHandler)ChangeUi, nstatsSummary, nskills, nentities, ntimedEncounter, nabnormals, nbossHistory, nchatbox, npacketWaiting, nflash); }
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; } }
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); } SGrid.Visibility = !_hideGeneralData ? Visibility.Visible : Visibility.Collapsed; 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(); } if (BasicTeraData.Instance.WindowData.RealtimeGraphEnabled) { GraphViewModel.Update(message); Graph.Visibility = Visibility.Visible; } else { Graph.Visibility = Visibility.Collapsed; GraphViewModel.Reset(); } } Dispatcher.Invoke((PacketProcessor.UpdateUiHandler)ChangeUi, nmessage); }
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 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); } } }