public ConanPacket(byte[] bytes) : base(new PacketStream(bytes)) { Length = Stream.ReadUInt32(); Crc32 = Stream.ReadUInt32(); HeaderLength = Stream.ReadUInt32(); Sender = Stream.ReadByte(); SenderBytes = Stream.ReadArrayByteLength(); Receiver = Stream.ReadByte(); ReceiverBytes = Stream.ReadArrayByteLength(); Opcode = Stream.ReadUInt16(); var checkHeaderLength = HeaderLength - (uint)(sizeof(uint) + SenderBytes.Length + ReceiverBytes.Length); if (checkHeaderLength > 0) { HeaderData = new ConanStream(Stream.ReadArray(checkHeaderLength - sizeof(byte) * 2)); } var dataLength = Length - (HeaderLength + sizeof(uint) * 2); if (dataLength > 0) { Data = new ConanStream(Stream.ReadArray(dataLength)); } if (!IsValid) { Console.WriteLine($"Invalid {GetType().Name}"); } }
public static unsafe UInt32 CalculateForPacketBuffer(ConanStream packetBuffer) { fixed(byte *fix = packetBuffer.GetBuffer()) { var buffer = (UInt32 *)fix + 2; // skip length and hash var len = packetBuffer.Length - sizeof(UInt32) * 2; var crc32 = 0xffffffff; UInt32 offset = 0; if (len >= 32) { for (UInt32 i = 0; i < len >> 5; i++) { crc32 ^= buffer[offset]; len -= 4; for (UInt32 ii = 0; ii < 7; ii++) { offset++; crc32 = CrcTab2[crc32 >> 16 & 0xFF] ^ CrcTab3[crc32 >> 8 & 0xFF] ^ CrcTab1[crc32 >> 24] ^ CrcTab4[crc32 & 0xFF] ^ buffer[offset]; len -= 4; } crc32 = CrcTab2[crc32 >> 16 & 0xFF] ^ CrcTab3[crc32 >> 8 & 0xFF] ^ CrcTab1[crc32 >> 24] ^ CrcTab4[crc32 & 0xFF]; offset++; } } if (len >= offset) { for (UInt32 i = 0; i < (len >> 2); i++) { crc32 ^= buffer[offset]; len -= 4; crc32 = CrcTab2[crc32 >> 16 & 0xFF] ^ CrcTab3[crc32 >> 8 & 0xFF] ^ CrcTab1[crc32 >> 24] ^ CrcTab4[crc32 & 0xFF]; offset++; } } if (len > 0) { offset *= 4; for (UInt32 i = 0; i < len; i++) { var tmp = *(byte *)((UInt64)buffer + offset); crc32 = (crc32 >> 8) ^ CrcTab1[(tmp ^ crc32) & 0xFF]; offset++; } } return(crc32 ^ 0xFFFFFFFF); } }
public static void TrimStream(ref ConanStream stream) { if (stream.Position == stream.Length) { stream = new PacketStream(); return; } var remaining = new byte[stream.Length - stream.Position]; stream.Read(remaining, 0, remaining.Length); stream = new ConanStream(remaining); }
public AgentServerPacket(ConanStream stream) : base(stream) { Opcode = (AgentServerOpcodes)stream.ReadUInt16(); Length = stream.ReadUInt16(); if (Length == 0 || stream.Length < Length) { Valid = false; return; } Data = new ConanStream(stream.ReadArray(Length - sizeof(ushort) * 2u)); }
private void ReadCallback(int bytesRead) { if (bytesRead == 0) { return; } var receivedBytes = _buffer.Take(bytesRead).ToArray(); // zlib compression (0x80000005) (Client sends start packet, but does not use compression?) if (receivedBytes[0] == 0x80 && receivedBytes[1] == 0x00 && receivedBytes[2] == 0x00 && receivedBytes[3] == 0x05) { return; // messages; } if (_backBuffer != null && _backBuffer.Length > 0) { _stream = new ConanStream(_backBuffer.Concat(receivedBytes).ToArray()); _backBuffer = null; } else { _stream = new ConanStream(receivedBytes); } while (true) { if (_stream == null || _stream.Length == 0) { break; } _stream.Position = 0; var packet = (TPacketType)Activator.CreateInstance(typeof(TPacketType), _stream); if (packet.Valid) { _server.ReceivedPacket(this, packet); Functions.TrimStream(ref _stream); break; } _backBuffer = _stream.ToArray(); } BeginReceive(); }
public AgentServerPacket(ConanStream stream) { _originalStream = stream; stream.Position = 0; Opcode = stream.ReadUInt16(); Length = stream.ReadUInt16(); if (Length == 0 || stream.Length < Length) { //throw new Exception("stream.Length < length"); Length = UInt16.MaxValue; return; } Data = new ConanStream(stream.ReadArray(Length - sizeof(UInt16) * 2u)); Console.WriteLine(); }
public IEnumerable <IScsMessage> CreateMessages(byte[] receivedBytes) { var messages = new List <IScsMessage>(); if (_backBuffer != null) { _stream = new PacketStream(); _stream.Write(_backBuffer, 0, _backBuffer.Length); _stream.Write(receivedBytes, 0, receivedBytes.Length); _backBuffer = null; } else { _stream = new ConanStream(receivedBytes); } while (ReadMessage(messages)) { ; } return(messages); }