Exemple #1
0
        /// <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);
                }
            }
        }