internal PacketEncoder(ISAACCipher cipher) { _cipher = cipher; }
private async Task DecodeLogin(IChannelHandlerContext context, IByteBuffer input, List <object> output) { if (input.ReadableBytes < 2) { return; //Invalid. } int loginType = input.ReadByte(); //16 = connecting, 18 = reconnecting. if (loginType != 16 && loginType != 18) { Console.WriteLine($"Invalid login type: {loginType}"); await context.CloseAsync(); return; } int blockLength = input.ReadByte() - 40; //40 is the extra offset. if (blockLength <= 0) { await CloseChannel(context, $"Encrypted packet size zero or negative: {blockLength}"); return; } byte magicNumber = input.ReadByte(); short clientVersion = input.ReadShort(); byte highOrLowMemory = input.ReadByte(); // Skip the CRC keys. for (int i = 0; i < 9; i++) { input.ReadInt(); } input.ReadByte(); //RSA is disabled, skip the block length. int rsaOpCode = input.ReadByte(); if (rsaOpCode != 10) { await CloseChannel(context, "Unable to decode RSA block properly!"); return; } long clientHalf = input.ReadLong(); long serverHalf = input.ReadLong(); int[] isaacSeed = { (int)(clientHalf >> 32), (int)clientHalf, (int)(serverHalf >> 32), (int)serverHalf }; ISAACCipher inCipher = new ISAACCipher(isaacSeed); for (int i = 0; i < isaacSeed.Length; i++) { isaacSeed[i] += 50; } ISAACCipher outCipher = new ISAACCipher(isaacSeed); int uid = input.ReadInt(); string username = input.GetString(); string password = input.GetString(); bool userExists = await _playerController.UserExists(username); if (userExists) { if (!await _playerController.TryLogin(username, password)) //Invalid credentials. { await context.WriteAndFlushAsync(new LoginErrorComposer(LoginMessage.INVALID_CREDS).Buffer).ContinueWith(async(task, channel) => { await((IChannelHandlerContext)channel).CloseAsync(); }, context); return; } } else { await _playerController.TryRegister(username, password); } if (_sessionController.TryGetSession(context.Channel.Id, out ISession session)) { await context.WriteAndFlushAsync(new LoginSuccessComposer().Buffer); context.Channel.Pipeline .AddBefore("decoder", "packetEncoder", new PacketEncoder(outCipher)) .AddAfter("packetEncoder", "packetDecoder", new PacketDecoder(inCipher)) .Remove(this); IPlayer player = await _playerController.GetPlayer(username, password); session.Player = player; await session.PostLogin(); } }