/// <summary> /// Creates a new instance of XmlParser specifically for the given <c>packet</c>. /// </summary> /// <param name="packet"> /// The packet, that the new instance of XmlParser is created for. /// </param> /// <returns> /// A new instance of XmlParser specifically for the given <c>packet</c>. Can be null. /// </returns> public static XmlParser GetParser(WowPacket packet) { if (!s_initialized) { lock (s_lock) { if (!s_initialized) { Initialize(); } } } if (Definitions[PacketSender.Any].ContainsKey((WowOpcodes)packet.Opcode)) { return(new XmlParser(Definitions[PacketSender.Any][(WowOpcodes)packet.Opcode])); } var sender = packet.Direction == TransferDirection.ToClient ? PacketSender.Server : PacketSender.Client; if (Definitions[sender].ContainsKey((WowOpcodes)packet.Opcode)) { return(new XmlParser(Definitions[sender][(WowOpcodes)packet.Opcode])); } return(null); }
protected override unsafe void InternalWritePacket2(WowPacket packet) { var data = packet.Data; byte[] bytes; if (this.SnifferId == PktSnifferId.Kamilla) { bytes = new byte[OutChunkHeaderKamilla.Size]; fixed(byte *bytesPtr = bytes) { var header = (OutChunkHeaderKamilla *)bytesPtr; header->m_header.UnixTime = packet.ArrivalTime.ToUnixTime(); header->m_header.DataLength = data.Length + 4; header->m_header.Direction = packet.Direction; header->m_header.OptionalDataLength = 2; header->m_header.TickCount = packet.ArrivalTicks; header->m_flags = (byte)packet.Flags; header->m_connId = (byte)packet.ConnectionId; header->m_opcode = packet.Opcode; } } else { bytes = new byte[OutChunkHeader.Size]; fixed(byte *bytesPtr = bytes) { var header = (OutChunkHeader *)bytesPtr; header->m_header.UnixTime = packet.ArrivalTime.ToUnixTime(); header->m_header.DataLength = data.Length + 4; header->m_header.Direction = packet.Direction; header->m_header.OptionalDataLength = 0; header->m_header.TickCount = packet.ArrivalTicks; header->m_opcode = packet.Opcode; } } m_stream.WriteBytes(bytes); m_stream.WriteBytes(data); }
protected abstract void InternalWritePacket2(WowPacket packet);
protected override unsafe void InternalRead(Action <int> reportProgressDelegate) { int headerSize = ChunkHeader.Size; var headerBytes = new byte[headerSize]; var startTicks = this.StartTicks; fixed(byte *ptr = headerBytes) { int progress = 0; var header = (ChunkHeader *)ptr; while (!m_stream.IsRead) { if (m_stream.Read(headerBytes, 0, headerSize) != headerSize) { throw new EndOfStreamException(); } var flags = PacketFlags.None; if (m_snifferId == PktSnifferId.Kamilla && header->OptionalDataLength > 0) { flags = (PacketFlags)m_stream.ReadByte(); m_stream.Skip(header->OptionalDataLength - 1); } else { m_stream.Skip(header->OptionalDataLength); } var opcode = m_stream.ReadUInt32(); var data = m_stream.ReadBytes(header->DataLength - 4); var wowFlags = (WowPacketFlags)(flags & ~PacketFlags.All); if ((wowFlags & WowPacketFlags.HelloPacket) != 0) { opcode = SpecialWowOpcodes.HelloOpcode; } flags &= PacketFlags.All; var packet = new WowPacket(data, header->Direction, flags, wowFlags, this.StartTime.AddMilliseconds(header->TickCount - startTicks), header->TickCount, opcode, header->ConnectionId); this.InternalAddPacket(packet); this.OnPacketAdded(packet); if (reportProgressDelegate != null) { int newProgress = (int)( (m_stream.Position - m_streamOriginalPosition) * 100 / (m_stream.Length - m_streamOriginalPosition)); if (newProgress != progress) { progress = newProgress; reportProgressDelegate(progress); } } } } }
protected override unsafe void InternalRead(Action <int> reportProgressDelegate) { int headerSize = ChunkHeader.Size; var headerBytes = new byte[headerSize]; var startTicks = this.StartTicks; bool firstPacket = true; fixed(byte *ptr = headerBytes) { int progress = 0; var header = (ChunkHeader *)ptr; while (m_stream.CanRead(1)) { if (m_stream.Read(headerBytes, 0, headerSize) != headerSize) { throw new EndOfStreamException(); } var flags = PacketFlags.None; int connId = 0; if (m_snifferId == PktSnifferId.Kamilla) { int nOptBytes = header->OptionalDataLength; if (--nOptBytes >= 0) { flags = (PacketFlags)m_stream.ReadByte(); if (--nOptBytes >= 0) { connId = m_stream.ReadByte(); if (nOptBytes > 0) { m_stream.Skip(nOptBytes); } } } } else { m_stream.Skip(header->OptionalDataLength); } var opcode = m_stream.ReadUInt32(); var data = m_stream.ReadBytes(header->DataLength - 4); var wowFlags = (WowPacketFlags)(flags & ~PacketFlags.All); if ((wowFlags & WowPacketFlags.HelloPacket) != 0) { opcode = SpecialWowOpcodes.HelloOpcode; } flags &= PacketFlags.All; var packet = new WowPacket(data, header->Direction, flags, wowFlags, header->UnixTime.AsUnixTime(), header->TickCount, opcode, connId); this.InternalAddPacket(packet); this.OnPacketAdded(packet); if (firstPacket) { if (this.StartTicks == 0) { this.StartTime = packet.ArrivalTime; this.StartTicks = packet.ArrivalTicks; } } firstPacket = false; if (reportProgressDelegate != null) { int newProgress = (int)( (m_stream.Position - m_streamOriginalPosition) * 100 / (m_stream.Length - m_streamOriginalPosition)); if (newProgress != progress) { progress = newProgress; reportProgressDelegate(progress); } } } } }
/// <summary> /// Creates a new instance of XmlParser specifically for the given <c>packet</c>. /// </summary> /// <param name="packet"> /// The packet, that the new instance of XmlParser is created for. /// </param> /// <returns> /// A new instance of XmlParser specifically for the given <c>packet</c>. Can be null. /// </returns> public static XmlParser GetParser(WowPacket packet) { if (!s_initialized) { lock (s_lock) { if (!s_initialized) Initialize(); } } if (Definitions[PacketSender.Any].ContainsKey((WowOpcodes)packet.Opcode)) return new XmlParser(Definitions[PacketSender.Any][(WowOpcodes)packet.Opcode]); var sender = packet.Direction == TransferDirection.ToClient ? PacketSender.Server : PacketSender.Client; if (Definitions[sender].ContainsKey((WowOpcodes)packet.Opcode)) return new XmlParser(Definitions[sender][(WowOpcodes)packet.Opcode]); return null; }
protected override void InternalRead(Action <int> reportProgressDelegate) { var ConnectionIds = new Dictionary <int, byte>(); int nLine = 0; string line; var direction = TransferDirection.ToClient; uint opcode = SpecialWowOpcodes.UnknownOpcode; var time = DateTime.MinValue; uint ticks = 0; byte conn_id = 0; byte[] data = null; bool waitingDate = true; bool readingData = false; string dataString = null; var flags = PacketFlags.None; var flags2 = WowPacketFlags.None; int progress = 0; try { while ((line = m_streamReader.ReadLine()) != null) { ++nLine; if (nLine == 1) { if (line.StartsWith("EXPECTED CLIENT BUILD ", StringComparison.InvariantCultureIgnoreCase)) { m_version = GetClientBuildInfo(uint.Parse(line.Substring("EXPECTED CLIENT BUILD ".Length))); } continue; } if (line.Trim() == string.Empty) { readingData = false; if (data != null) { string[] datas = dataString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (datas.Length != data.Length) { throw new FormatException( string.Format("Error in data chunk at line {0} ({1} vs {2} len)", nLine, datas.Length, data.Length) ); } for (int i = 0; i < datas.Length; ++i) { data[i] = byte.Parse(datas[i], NumberStyles.AllowHexSpecifier); } var pkt = new WowPacket(data, direction, flags, flags2, time, ticks, opcode, conn_id); this.InternalAddPacket(pkt); this.OnPacketAdded(pkt); if (reportProgressDelegate != null) { int newProgress = (int)(m_streamReader.BaseStream.Position * 100 / m_streamReader.BaseStream.Length); if (newProgress != progress) { progress = newProgress; reportProgressDelegate(progress); } } dataString = null; data = null; flags = PacketFlags.None; flags2 = WowPacketFlags.None; ticks = 0; } waitingDate = true; } else if (waitingDate) { var parts = line.Split(new char[] { ' ' }, 4); time = DateTime.Parse(parts[0] + ' ' + parts[1], CultureInfo.InvariantCulture); waitingDate = false; if (parts.Length >= 4) { ticks = uint.Parse(parts[2], NumberStyles.AllowHexSpecifier); } if (line.IndexOf("SERVER") != -1) { direction = TransferDirection.ToClient; } else if (line.IndexOf("CLIENT") != -1) { direction = TransferDirection.ToServer; } } else if (readingData) { dataString += line; } else if (line.StartsWith("CLIENT")) { direction = TransferDirection.ToServer; } else if (line.StartsWith("SERVER")) { direction = TransferDirection.ToClient; } else if (line.StartsWith("SOCKET")) { int socket = int.Parse(line.Substring(line.IndexOf(':') + 1).Trim()); if (ConnectionIds.ContainsKey(socket)) { conn_id = ConnectionIds[socket]; } else { conn_id = (byte)(ConnectionIds.Count == 0 ? 1 : ConnectionIds.Last().Value + 1); ConnectionIds.Add(socket, conn_id); } } else if (line.StartsWith("LENGTH")) { int len = int.Parse(line.Substring(line.IndexOf(':') + 1).Trim()); data = new byte[len]; } else if (line.StartsWith("OPCODE")) { string substr = line.Substring(line.IndexOf('(') + 1 + 2).TrimEnd(')'); opcode = uint.Parse(substr, NumberStyles.AllowHexSpecifier); if (opcode == 0x4F57 || opcode == 0x4C524F57) { flags2 |= WowPacketFlags.HelloPacket; opcode = SpecialWowOpcodes.HelloOpcode; } } else if (line.StartsWith("DATA")) { readingData = true; dataString = string.Empty; } else if (line.Trim().Equals("NOT SEND", StringComparison.InvariantCultureIgnoreCase)) { flags |= PacketFlags.Freezed; } else { throw new IOException(); } } } catch (Exception ex) { throw new FormatException("Error reading data on line " + nLine + ".", ex); } finally { this.CloseStream(); } }
protected override void InternalWritePacket2(WowPacket packet) { throw new NotSupportedException(); }