示例#1
0
        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}");
            }
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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));
        }
示例#5
0
        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();
        }
示例#6
0
        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);
        }