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