public void TestUpdatePacket() { var mgr = new BufferManager(2, 128); var segment1 = mgr.CheckOut(); // 1st buffer Assert.AreEqual(1, mgr.AvailableSegmentsCount); var segment2 = mgr.CheckOut(); // 1st buffer Assert.AreEqual(1, mgr.TotalBufferCount); Assert.AreEqual(0, mgr.AvailableSegmentsCount); //Assert.AreEqual(2, segment2.Buffer.UsedSegmentCount); var segment3 = mgr.CheckOut(); // 2nd buffer Assert.AreEqual(2, mgr.TotalBufferCount); Assert.AreEqual(1, mgr.AvailableSegmentsCount); //Assert.AreEqual(1, segment3.Buffer.UsedSegmentCount); segment3.DecrementUsage(); Assert.AreEqual(2, mgr.AvailableSegmentsCount); //Assert.AreEqual(0, segment3.Buffer.UsedSegmentCount); //using (var outPacket = new UpdatePacket(segment2)) using (var outPacket = new UpdatePacket(128)) { Assert.AreEqual(outPacket.PacketId, (PacketId)RealmServerOpCode.SMSG_UPDATE_OBJECT); outPacket.Write(15); outPacket.WriteCString("abc"); using (var inPacket = DisposableRealmPacketIn.CreateFromOutPacket(segment1, outPacket)) { Assert.AreEqual(0, inPacket.ReadInt32()); //update count Assert.AreEqual(15, inPacket.ReadInt32()); Assert.AreEqual("abc", inPacket.ReadCString()); } outPacket.Reset(); Assert.AreEqual(outPacket.PacketId, (PacketId)RealmServerOpCode.SMSG_UPDATE_OBJECT); outPacket.WriteCString("def"); outPacket.WriteUShortBE(300); using (var inPacket = DisposableRealmPacketIn.CreateFromOutPacket(segment1, outPacket)) { Assert.AreEqual(0, inPacket.ReadInt32()); //update count Assert.AreEqual((byte)0, inPacket.ReadByte()); //block count Assert.AreEqual("def", inPacket.ReadCString()); Assert.AreEqual((ushort)300, inPacket.ReadUInt16BE()); } } }
/// <summary> /// Lets the server handle the given packet. /// </summary> public void ReceiveCMSG(DisposableRealmPacketIn packet, bool dispose, bool wait) { HandleCMSG(packet, wait); if (dispose) { ((IDisposable)packet).Dispose(); } }
public static void DumpPacketOut(RealmAccount acc, RealmPacketOut packetOut, PacketSender sender) { if (CanDump(packetOut.PacketId)) { var writer = GetTextWriter(acc); using (var packet = DisposableRealmPacketIn.CreateFromOutPacket(packetOut)) { DumpPacket(packet, sender, false, writer); } } }
public static ParsedSegment Parse(RealmPacketOut realmPacketOut, PacketSender sender, PacketDefinition def) { using (var packetIn = DisposableRealmPacketIn.CreateFromOutPacket(realmPacketOut)) { //if (packetIn.PacketID == RealmServerOpCode.SMSG_COMPRESSED_MOVE) //{ // using (var movePacket = ParseCompressedMove(packetIn)) // { // return Parse(movePacket, sender, def); // } //} return(Parse(packetIn, sender, def)); } }
/// <summary> /// Dumps the content of an Update packet to the console /// </summary> //public static void DumpUpdatePacket(RealmPacketOut packet) //{ // try // { // ParsedUpdatePacket.Dump(packet.GetPacketPayload(), false, m_updatePacketWriter); // m_updatePacketWriter.Flush(); // } // catch (Exception e) // { // OnException("Failed to parse Update-Packet.", e, packet.GetPacketPayload()); // } //} public static void DumpPacketOut(RealmAccount acc, byte[] packetOut, int offset, int length, PacketSender sender) { if (Dumps) { var writer = GetTextWriter(acc); using (var packet = DisposableRealmPacketIn.CreateFromOutPacket(packetOut, offset, length)) { if (CanDump(packet.PacketId)) { DumpPacket(packet, sender, false, writer); } } } }
/// <summary> /// Extracts all Packets out of the given logged and default-formatted lines /// </summary> public static void Extract(string logFile, params LogHandler[] handlers) { var file = File.Open(logFile, FileMode.Open, FileAccess.Read); using (var reader = new BinaryReader(file)) { reader.ReadBytes(3); reader.ReadBytes(2); reader.ReadByte(); reader.ReadInt16(); reader.ReadBytes(4); reader.ReadBytes(20); reader.ReadBytes(64); while (reader.BaseStream.Position != reader.BaseStream.Length) { var direction = reader.ReadByte() != 0xFF ? PacketSender.Client : PacketSender.Server; var time = Utility.GetUTCTimeSeconds(reader.ReadUInt32()); var length = reader.ReadInt32(); var opcode = (RealmServerOpCode)(direction == PacketSender.Client ? reader.ReadInt32() : reader.ReadInt16()); var data = reader.ReadBytes(length - (direction == PacketSender.Client ? 4 : 2)); var opcodeHandlers = handlers.Where(handler => handler.Validator(opcode)).ToList(); if (opcodeHandlers.Count() <= 0) { continue; } if (!Enum.IsDefined(typeof(RealmServerOpCode), opcode)) { Log.Warn("Packet had undefined Opcode: " + opcode); continue; } var rawPacket = DisposableRealmPacketIn.Create(opcode, data); if (rawPacket != null) { foreach (var handler in opcodeHandlers) { handler.PacketParser(new ParsablePacketInfo(rawPacket, direction, time)); } } } } }
/// <summary> /// Lets the server handle the given packet, as though it was sent by this Client. /// </summary> /// <param name="dispose">Whether to dispose the packet after handling</param> /// <param name="wait">Whether to wait for the Packet finish processing</param> public void ReceiveCMSG(RealmPacketOut packet, bool dispose, bool wait) { var inPacket = DisposableRealmPacketIn.CreateFromOutPacket(packet); HandleCMSG(inPacket, wait); var evt = ServerReceivedPacket; if (evt != null) { evt(this, inPacket); } if (dispose) { packet.Close(); } }
public void TestBufferManagerEtc() { var mgr = new BufferManager(2, 128); var segment1 = mgr.CheckOut(); // 1st buffer Assert.AreEqual(1, mgr.AvailableSegmentsCount); var segment2 = mgr.CheckOut(); // 1st buffer Assert.AreEqual(1, mgr.TotalBufferCount); Assert.AreEqual(0, mgr.AvailableSegmentsCount); //Assert.AreEqual(2, segment2.Buffer.UsedSegmentCount); var segment3 = mgr.CheckOut(); // 2nd buffer Assert.AreEqual(2, mgr.TotalBufferCount); Assert.AreEqual(1, mgr.AvailableSegmentsCount); //Assert.AreEqual(1, segment3.Buffer.UsedSegmentCount); segment3.DecrementUsage(); Assert.AreEqual(2, mgr.AvailableSegmentsCount); //Assert.AreEqual(0, segment3.Buffer.UsedSegmentCount); using (var outPacket = new RealmPacketOut(RealmServerOpCode.CMSG_ACCEPT_TRADE)) { outPacket.Position = outPacket.HeaderSize; outPacket.Write(1); outPacket.WriteCString("abc"); var inPacket = DisposableRealmPacketIn.CreateFromOutPacket(segment1, outPacket); Assert.AreEqual(1, inPacket.ReadInt32()); Assert.AreEqual("abc", inPacket.ReadCString()); } using (var outPacket = new RealmPacketOut(RealmServerOpCode.CMSG_ACCEPT_TRADE)) { outPacket.Position = outPacket.HeaderSize; outPacket.WriteCString("def"); outPacket.Write(2); var inPacket = DisposableRealmPacketIn.CreateFromOutPacket(segment2, outPacket); Assert.AreEqual("def", inPacket.ReadCString()); Assert.AreEqual(2, inPacket.ReadInt32()); } }
public void TestEmptyStructure() { var def = new PacketDefinition(RealmServerOpCode.CMSG_SET_CHANNEL_WATCH, PacketSender.Client, new List <PacketSegmentStructure>()); def.Init(); using (var packet = new RealmPacketOut(RealmServerOpCode.CMSG_PLAYER_AI_CHEAT)) { packet.WriteUInt((uint)SpellAttributes.CannotRemove); packet.WriteByte(0); using (var packetIn = DisposableRealmPacketIn.CreateFromOutPacket(packet)) { var parsedPacket = PacketParser.Parse(packetIn, PacketSender.Client, def); Assert.AreEqual(0, parsedPacket.SubSegments.Count); } } }
/// <summary> /// Extracts all Packets out of the given logged and default-formatted lines /// </summary> public static void Extract(string logFile, params LogHandler[] handlers) { var logXml = Load(logFile); var packets = logXml.Packets; for (var i = 0; i < packets.Length; i++) { var pckt = packets[i]; var opCode = (RealmServerOpCode)pckt.Opcode; var opcodeHandlers = handlers.Where(handler => handler.Validator(opCode)).ToList(); if (opcodeHandlers.Count() <= 0) { continue; } var timestamp = Utility.GetUTCTimeSeconds(pckt.Date); var bytes = UpdateFieldsUtil.HexStringConverter.ToByteArray(pckt.Value); if (!Enum.IsDefined(typeof(RealmServerOpCode), opCode)) { log.Warn("Packet #{0} had undefined Opcode: " + opCode, i); continue; } var rawPacket = DisposableRealmPacketIn.Create(opCode, bytes); if (rawPacket == null) { continue; } packets.Initialize(); // UNCOMMENT TO GET PARTICULAR PACKETS PARSED //if (paket.PacketID.ToString().Contains("_QUEST")){ foreach (var handler in opcodeHandlers) { handler.PacketParser(new ParsablePacketInfo(rawPacket, pckt.Sender, timestamp)); } //} } }
protected override RealmPacketIn CreatePacket(RealmPacketOut packet) { return(DisposableRealmPacketIn.CreateFromOutPacket(packet)); }
/// <summary> /// Creates a new PacketIn from the buffer of an existing PacketOut /// </summary> protected override RealmPacketIn CreatePacket(byte[] bytesOut, int offset, int length) { return(DisposableRealmPacketIn.CreateFromOutPacket(bytesOut, offset, length)); }
/// <summary> /// Lets the server handle the given packet. /// </summary> public void ReceiveCMSG(DisposableRealmPacketIn packet, bool wait) { ReceiveCMSG(packet, true, wait); }
/// <summary> /// Extracts all Packets out of the given logged and default-formatted lines /// </summary> /// <param name="singleLinePackets">Whether the packet content is one single line (or false in case of the fancy ksniffer format)</param> public static void Extract(string[] lines, bool singleLinePackets, params LogHandler[] handlers) { var lineNo = -1; var opCode = (RealmServerOpCode)uint.MaxValue; var sender = PacketSender.Any; var timeStrLen = "TimeStamp".Length; for (lineNo = 0; lineNo < lines.Length; lineNo++) { try { var timestamp = DateTime.Now; var line = lines[lineNo]; if (line.Length == 0 || (singleLinePackets && !line.StartsWith("{"))) { continue; } // find sender if (line.IndexOf("SERVER", StringComparison.InvariantCultureIgnoreCase) > -1) { sender = PacketSender.Server; } else { sender = PacketSender.Client; } // find opcode and timestamp var match = Regex.Match(line, @"\(0x(.{4})\)"); if (match.Success) { var timestampIndex = line.IndexOf("TimeStamp", StringComparison.InvariantCultureIgnoreCase) + timeStrLen; if (timestampIndex >= 0) { uint x; while (!uint.TryParse(line[timestampIndex].ToString(), out x)) { timestampIndex++; } var timestampStr = line.Substring(timestampIndex).Trim(); long seconds; if (long.TryParse(timestampStr, out seconds)) { timestamp = Utility.GetUTCTimeMillis(seconds); } } opCode = (RealmServerOpCode)Int32.Parse(match.Groups[1].Value, NumberStyles.HexNumber); } else { match = Regex.Match(line, @"\(([^\)]+)\)"); if (match.Success) { opCode = (RealmServerOpCode)Enum.Parse(typeof(RealmServerOpCode), match.Groups[1].Value); } else { Console.WriteLine("Could not parse Packet Header: " + line); continue; } } lineNo++; // one line for the packet-header var opcodeHandler = handlers.Where(handler => handler.Validator(opCode)).FirstOrDefault(); var buildPacket = opcodeHandler != null; var sb = new StringBuilder(); if (singleLinePackets) { if (buildPacket) { sb.Append(lines[lineNo]); } lineNo++; } else { // skip the column count while (string.IsNullOrEmpty(line = lines[lineNo]) || line.StartsWith("|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F") || line.StartsWith("|--------------------------------")) { lineNo++; } int start, end; while (((line.Length > 5 && line[start = 4] == ':') || (start = line.IndexOf('|')) >= 0) && (end = line.IndexOf('|', start += 1)) > 0) { ++lineNo; if (buildPacket) { end -= 1; var str = line.Substring(start, end - start); var fillerStart = str.IndexOf("--"); if (fillerStart >= 0) { str = str.Substring(0, fillerStart - 1); } sb.Append(str + " "); while ((line = lines[lineNo]).Length == 0) // skip empty lines { ++lineNo; } } } } if (buildPacket) { if (!Enum.IsDefined(typeof(RealmServerOpCode), opCode)) { log.Warn("Packet at line #{0} had undefined Opcode: " + opCode, lineNo); continue; } var bytes = UpdateFieldsUtil.ParseBytes(sb.ToString(), true); var packet = DisposableRealmPacketIn.Create(opCode, bytes); if (packet != null) { if (packet.PacketId == RealmServerOpCode.SMSG_COMPRESSED_UPDATE_OBJECT && packet.Length < 20) { throw new Exception("Format error - Did you specify singlePackets although its not single-line packets?"); } opcodeHandler.PacketParser(new ParsablePacketInfo(packet, sender, timestamp)); } } } catch (Exception e) { LogUtil.ErrorException(e, "Error in KSniffer-log at line {0} ({1})", lineNo, opCode); } } }