Beispiel #1
0
        private void OnReceive(BufferData data)
        {
            switch (State)
            {
            case QueueState.Authenticating:
                var keyPacket = new ClientKeyPacket();

                keyPacket.Read(data.GetReader());

                if (keyPacket.PublicKey != Manager.Config.PublicKey)
                {
                    Close();
                    return;
                }

                Socket.Send(new ClientKeyOkPacket());

                State = QueueState.Authenticated;

                break;

            case QueueState.Authenticated:
                if (data[data.Offset++] != 7)
                {
                    throw new Exception("Invalid opcode???");
                }

                var loginPacket = new QueueLoginPacket();

                loginPacket.Read(data.GetReader());

                UserId     = loginPacket.UserId;
                OneTimeKey = loginPacket.OneTimeKey;
                State      = QueueState.InQueue;

                Manager.Enqueue(this);
                EnqueueTime = DateTime.Now;
                break;

            default:
                throw new Exception("Received packet in a invalid queue state!");
            }
        }
Beispiel #2
0
        private void OnReceive(BufferData data)
        {
            var packet = new ClientKeyPacket();

            packet.Read(data.GetReader());

            DHKeyExchange.GenerateServerK(PrivateKey, packet.B, K);

            var key = new byte[64];

            K.WriteToBigEndian(key, 0, key.Length);

            GameCryptManager.Initialize(Data, key);

            Socket.Send(new ClientKeyOkPacket());

            Cleanup();

            Manager.ExchangeDone(this);
        }
Beispiel #3
0
        private void OnReceive(BufferData data)
        {
            var opcode = (CommOpcode)data.Buffer[data.BaseOffset + data.Offset++];

            var packetType = _router.GetPacketType(opcode);

            if (packetType == null)
            {
                return;
            }

            var packet = Activator.CreateInstance(packetType) as IOpcodedPacket <CommOpcode>;

            if (packet == null)
            {
                return;
            }

            packet.Read(data.GetReader());

            _router.RoutePacket(this, packet);
        }
Beispiel #4
0
        private void OnReceive(BufferData data)
        {
            // Reset the timeout after every action
            Timer.ResetTimer("timeout");

            var packetType = PacketRouter.GetPacketType((ClientOpcode)data.Buffer[data.BaseOffset + data.Offset++]);

            if (packetType == null)
            {
                return;
            }

            var packet = Activator.CreateInstance(packetType) as IBasePacket;

            if (packet == null)
            {
                return;
            }

            packet.Read(data.GetReader());

            _packetQueue.EnqueueIncoming(packet);
        }
Beispiel #5
0
        private void OnReceive(BufferData data)
        {
            // Reset the timeout after every action
            TimeoutTime = DateTime.Now.AddMinutes(Server.Config.AuthConfig.ClientTimeout);

            var packetType = PacketRouter.GetPacketType((ClientOpcode)data.Buffer[data.BaseOffset + data.Offset++]);

            if (packetType == null)
            {
                return;
            }

            var packet = Activator.CreateInstance(packetType) as IBasePacket;

            if (packet == null)
            {
                return;
            }

            packet.Read(data.GetReader());

            Server.PacketQueue.EnqueueIncoming(this, packet);
        }
Beispiel #6
0
        public void Read(BinaryReader br)
        {
            if (br.BaseStream.Length < 4)
            {
                throw new Exception("Fragmented receive, should not happen! (4 size header)");
            }

            Size    = br.ReadUInt16();
            Channel = br.ReadByte();

            br.ReadByte(); // padding

            if (Size > br.BaseStream.Length)
            {
                Debugger.Break();

                throw new Exception($"Fragmented receive, should not happen! Packet size: {Size} <-> Buffer length: {br.BaseStream.Length}");
            }

            if (Channel == 0xFF) // Internal channel: Send timeout checking, ignore the packet
            {
                return;
            }

            if (Channel != 0)                     // 0 == ReliableStreamChannel (no extra data), Move message uses channels
            {
                SequenceNumber = br.ReadUInt32(); // Sequence number? if (previousValue - newValue < 0) { process packet; previousValue = newValue; }
                br.ReadInt32();                   // 0xDEADBEEF
                br.ReadInt32();                   // skip
            }

            var packetBeginPosition = br.BaseStream.Position;

            using (var reader = new ProtocolBufferReader(br, ProtocolBufferFlags.DontFragment))
            {
                reader.ReadProtocolFlags();


                reader.ReadPacketType(out ushort type, out bool compress);

                Type     = (ClientMessageOpcode)type;
                Compress = compress;

                reader.ReadXORCheck((int)(br.BaseStream.Position - packetBeginPosition));
            }

            var xorCheckPosition = (int)br.BaseStream.Position;

            var readBr = br;

            BufferData buffer = null;

            if (Compress)
            {
                var someType = br.ReadByte(); // 0 = No compression
                if (someType >= 2)
                {
                    throw new Exception("Invalid compress type received!");
                }

                if (someType == 1)
                {
                    Debugger.Break(); // TODO: test

                    var uncompressedSize = br.ReadInt32();

                    byte[] uncompressedData;
                    var    offset = 0;

                    if (uncompressedSize > BufferManager.BlockSize)
                    {
                        uncompressedData = new byte[uncompressedSize];
                    }
                    else
                    {
                        buffer = BufferManager.RequestBuffer();

                        uncompressedData = buffer.Buffer;
                        offset           = buffer.BaseOffset;
                    }

                    using (var deflateStream = new DeflateStream(br.BaseStream, CompressionMode.Decompress, true)) // TODO: test if the br.BaseStream is cool as the Stream input for the DeflateStream
                        deflateStream.Read(uncompressedData, offset, uncompressedSize);

                    readBr = buffer != null?buffer.GetReader() : new BinaryReader(new MemoryStream(uncompressedData, 0, uncompressedSize, false), Encoding.UTF8, false);
                }
            }

            // ReSharper disable SwitchStatementMissingSomeCases
            switch (Type)
            {
            case ClientMessageOpcode.Login:
                Message = new LoginMessage();
                break;

            case ClientMessageOpcode.Move:
                Message = new MoveMessage();
                break;

            case ClientMessageOpcode.CallServerMethod:
                Message = new CallServerMethodMessage();
                break;

            case ClientMessageOpcode.Ping:
                Message = new PingMessage();
                break;

            default:
                throw new Exception($"Unable to handle packet type {Type}, because it's a Server -> Client packet!");
            }
            // ReSharper restore SwitchStatementMissingSomeCases

            using (var reader = new ProtocolBufferReader(readBr, ProtocolBufferFlags.DontFragment))
            {
                reader.ReadProtocolFlags();

                // Subtype and Message.Read()
                reader.ReadDebugByte(41);

                if ((Message.SubtypeFlags & ClientMessageSubtypeFlag.HasSubtype) == ClientMessageSubtypeFlag.HasSubtype)
                {
                    Message.RawSubtype = reader.ReadByte();
                    if (Message.RawSubtype < Message.MinSubtype || Message.RawSubtype > Message.MaxSubtype)
                    {
                        throw new Exception("Invalid Subtype found!");
                    }
                }

                Message.Read(reader);

                reader.ReadDebugByte(42);

                reader.ReadXORCheck((int)br.BaseStream.Position - xorCheckPosition);
            }

            if (buffer != null) // If we requested a buffer for decompressing, free it
            {
                BufferManager.FreeBuffer(buffer);
            }
        }
Beispiel #7
0
        private bool DecodePacket(BufferData data, out ushort length)
        {
            using (var br = data.GetReader(data.Offset, data.RemainingLength))
            {
                var rawPacket = new ProtocolPacket();

                rawPacket.Read(br);

                if (rawPacket.Channel != 0)
                {
                    if (rawPacket.SequenceNumber < ReceiveSequence[rawPacket.Channel])
                    {
                        Debugger.Break();

                        length = rawPacket.Size; // throw away the packet
                        return(true);
                    }

                    ReceiveSequence[rawPacket.Channel] = rawPacket.SequenceNumber;
                }

                length = rawPacket.Size;

                data.Offset += (int)br.BaseStream.Position;

                if (rawPacket.Type == ClientMessageOpcode.None)
                {
                    if (length != 4)
                    {
                        Debugger.Break(); // If it's not send timeout check, let's investigate...
                    }
                    return(true);
                }

                _packetQueue.EnqueueIncoming(rawPacket);
            }

            /*var packet = new PythonCallPacket(length);
             * using (var br = data.GetReader())
             * {
             *  packet.Read(br);
             *
             *  if (packet.Return.HasValue)
             *      return packet.Return.Value;
             *
             *  if (packet.Type == 2)
             *  {
             *      State = ClientState.LoggedIn;
             *      Entry = Server.AuthenticateClient(this, packet.AccountId, packet.OneTimeKey);
             *      if (Entry == null)
             *      {
             *          Logger.WriteLog(LogType.Error, "Client with ip: {0} tried to log in with invalid session data! User Id: {1} | OneTimeKey: {2}", Socket.RemoteAddress, packet.AccountId, packet.OneTimeKey);
             *          Close(false);
             *          return false;
             *      }
             *
             *      CharacterManager.Instance.StartCharacterSelection(this);
             *      return true;
             *  }
             *
             *  if (packet.DataSize > 0 && br.BaseStream.Position + packet.DataSize < br.BaseStream.Length)
             *  {
             *      if (br.ReadByte() != 0x4F) // 'O' format
             *          throw new Exception("Unsupported serialization format!");
             *
             *      var packetType = PacketRouter.GetPacketType(packet.Opcode);
             *      if (packetType != null)
             *      {
             *          var pythonPacket = Activator.CreateInstance(packetType) as IBasePacket;
             *          if (pythonPacket == null)
             *              return false;
             *
             *          pythonPacket.Read(br);
             *
             *          Server.PacketQueue.EnqueueIncoming(this, pythonPacket);
             *      }
             *      else
             *          Logger.WriteLog(LogType.Error, $"Unhandled game opcode: {packet.Opcode}");
             *  }
             *  else
             *      Logger.WriteLog(LogType.Error, $"Invalid data found in Python method call! Off: {br.BaseStream.Position} | Len: {packet.DataSize} | Array len: {br.BaseStream.Length}");
             * }*/

            return(true);
        }
Beispiel #8
0
        private bool DecodePacket(BufferData data, out ushort length)
        {
            using (var br = data.GetReader(data.Offset, data.RemainingLength))
            {
                var rawPacket = new ProtocolPacket();

                rawPacket.Read(br);

                if (rawPacket.Channel != 0)
                {
                    if (rawPacket.SequenceNumber < ReceiveSequence[rawPacket.Channel])
                    {
                        Debugger.Break();

                        length = rawPacket.Size; // throw away the packet
                        return(true);
                    }

                    ReceiveSequence[rawPacket.Channel] = rawPacket.SequenceNumber;
                }

                length = rawPacket.Size;

                data.Offset += (int)br.BaseStream.Position;

                switch (rawPacket.Type)
                {
                case ClientMessageOpcode.None:     // Send timeout check
                    if (length != 4)
                    {
                        Debugger.Break();     // If it's not send timeout check, let's investigate...
                    }
                    return(true);

                case ClientMessageOpcode.Login:
                    var loginMsg = rawPacket.Message as LoginMessage;
                    if (loginMsg == null)
                    {
                        Close(false);
                        return(false);
                    }


                    if (loginMsg.Version.Length != 8 || loginMsg.Version != "1.16.5.0")
                    {
                        Logger.WriteLog(LogType.Error, $"Client version mismatch: Server: 1.16.5.0 | Client: {loginMsg.Version}");

                        SendMessage(new LoginResponseMessage
                        {
                            ErrorCode = LoginErrorCodes.VersionMismatch,
                            Subtype   = LoginResponseMessageSubtype.Failed
                        });

                        Close(false);
                        return(false);
                    }

                    Entry = Server.AuthenticateClient(this, loginMsg.AccountId, loginMsg.OneTimeKey);     // TODO: implement ban system and check if the account is banned
                    if (Entry == null)
                    {
                        Logger.WriteLog(LogType.Error, "Client with ip: {0} tried to log in with invalid session data! User Id: {1} | OneTimeKey: {2}", Socket.RemoteAddress, loginMsg.AccountId, loginMsg.OneTimeKey);

                        SendMessage(new LoginResponseMessage
                        {
                            ErrorCode = LoginErrorCodes.AuthenticationFailed,
                            Subtype   = LoginResponseMessageSubtype.Failed
                        });

                        Close(false);
                        return(false);
                    }

                    SendMessage(new LoginResponseMessage
                    {
                        AccountId = loginMsg.AccountId,
                        Subtype   = LoginResponseMessageSubtype.Success
                    });

                    State = ClientState.LoggedIn;

                    CharacterManager.Instance.StartCharacterSelection(this);
                    return(true);

                case ClientMessageOpcode.Move:
                    break;

                case ClientMessageOpcode.CallServerMethod:
                    break;

                case ClientMessageOpcode.Ping:
                    break;
                }
            }

            /*var packet = new PythonCallPacket(length);
             * using (var br = data.GetReader())
             * {
             *  packet.Read(br);
             *
             *  if (packet.Return.HasValue)
             *      return packet.Return.Value;
             *
             *  if (packet.Type == 2)
             *  {
             *      State = ClientState.LoggedIn;
             *      Entry = Server.AuthenticateClient(this, packet.AccountId, packet.OneTimeKey);
             *      if (Entry == null)
             *      {
             *          Logger.WriteLog(LogType.Error, "Client with ip: {0} tried to log in with invalid session data! User Id: {1} | OneTimeKey: {2}", Socket.RemoteAddress, packet.AccountId, packet.OneTimeKey);
             *          Close(false);
             *          return false;
             *      }
             *
             *      CharacterManager.Instance.StartCharacterSelection(this);
             *      return true;
             *  }
             *
             *  if (packet.DataSize > 0 && br.BaseStream.Position + packet.DataSize < br.BaseStream.Length)
             *  {
             *      if (br.ReadByte() != 0x4F) // 'O' format
             *          throw new Exception("Unsupported serialization format!");
             *
             *      var packetType = PacketRouter.GetPacketType(packet.Opcode);
             *      if (packetType != null)
             *      {
             *          var pythonPacket = Activator.CreateInstance(packetType) as IBasePacket;
             *          if (pythonPacket == null)
             *              return false;
             *
             *          pythonPacket.Read(br);
             *
             *          Server.PacketQueue.EnqueueIncoming(this, pythonPacket);
             *      }
             *      else
             *          Logger.WriteLog(LogType.Error, $"Unhandled game opcode: {packet.Opcode}");
             *  }
             *  else
             *      Logger.WriteLog(LogType.Error, $"Invalid data found in Python method call! Off: {br.BaseStream.Position} | Len: {packet.DataSize} | Array len: {br.BaseStream.Length}");
             * }*/

            return(true);
        }