/// <summary> /// Extracts all Packets out of the given logged and default-formatted lines /// </summary> public static List <PinnedRealmPacketIn> Extract(string[] log) { List <PinnedRealmPacketIn> packets = new List <PinnedRealmPacketIn>(); for (int i = 0; i < log.Length; i++) { RealmServerOpCode opCode; var line = log[i]; if (line.StartsWith("{")) { Match match = Regex.Match(line, @"\(0x(.{4})\)"); if (match.Success) { 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; } } // skip the column count i += 4; StringBuilder sb = new StringBuilder(); while ((line = log[i++]).StartsWith("|") && line.EndsWith("|")) { int first = line.IndexOf('|') + 1; int second = line.IndexOf('|', first) - 1; var str = line.Substring(first, second - first); //str = str.TrimEnd(' '); sb.Append(str + " "); } var bytes = UpdateFieldsUtil.ParseBytes(sb.ToString(), true); var packetBytes = new byte[bytes.Length + RealmPacketIn.HEADER_SIZE]; var size = bytes.Length + RealmPacketIn.HEADER_SIZE; packetBytes[0] = (byte)((size >> 8) & 0xFF); packetBytes[1] = (byte)(size & 0xFF); packetBytes[2] = (byte)((int)opCode & 0xFF); packetBytes[3] = (byte)(((int)opCode >> 8) & 0xFF); Array.Copy(bytes, 0, packetBytes, RealmPacketIn.HEADER_SIZE, bytes.Length); var packet = PinnedRealmPacketIn.Create(packetBytes); packet.Initialize(); packets.Add(packet); } } return(packets); }
/// <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); } } }