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!"); } }
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); }
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); }
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); }
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); }
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); } }
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); }
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); }