Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class LoginDecoder extends ByteToMessageDecoder {
- private LoginType type;
- int size;
- @Override
- protected void decode(ChannelHandlerContext context, ByteBuf buffer, List<Object> out) throws Exception {
- if (!buffer.isReadable()) {
- throw new IllegalStateException("The data in the buffer could not be read!");
- }
- int loginType = buffer.readUnsignedByte();
- if (loginType != 16 && loginType != 19 && loginType != 18) {
- throw new ProtocolException("Invalid login type received: " + loginType + ".");
- }
- type = loginType == 19 ? LoginType.LOBBY : LoginType.WORLD;
- size = buffer.readUnsignedShort();
- if (buffer.readableBytes() < size) {
- throw new IllegalStateException("Not enough readable bytes from the buffer!");
- }
- int revision = buffer.readInt();
- int subrevision = buffer.readInt();
- if (revision != Constants.REVISION && subrevision != Constants.SUB_REVISION) {
- throw new IllegalStateException("Invalid client version received: " + revision + ", " + subrevision + ".");
- }
- if (type.equals(LoginType.WORLD)) {
- buffer.readByte();
- }
- if (type.equals(LoginType.LOBBY)) {
- decodeLobbyPayload(context, buffer, out);
- } else if (type.equals(LoginType.WORLD)) {
- //decodeWorldPayload(context, buffer, out);
- }
- }
- private void decodeLobbyPayload(ChannelHandlerContext context, ByteBuf buffer, List<Object> out) throws ProtocolException {
- if (buffer.readableBytes() < 2) {
- throw new IllegalStateException("Not enough readable bytes from the buffer!");
- }
- int secureBufferSize = buffer.readUnsignedShort();
- if (buffer.readableBytes() < secureBufferSize) {
- throw new IllegalStateException("Not enough readable bytes from the buffer!");
- }
- byte[] secureBytes = new byte[secureBufferSize];
- buffer.readBytes(secureBytes);
- ByteBuf secureBuffer = Unpooled.wrappedBuffer(new BigInteger(secureBytes).modPow(Protocol.LOGIN_EXPONENT, Protocol.LOGIN_MODULUS).toByteArray());
- int block = secureBuffer.readUnsignedByte();
- if (block != 10) {
- throw new ProtocolException("Invalid block opcode received: " + block + ".");
- }
- int[] xteaKey = new int [4];
- for (int i = 0; i < xteaKey.length; i++) {
- xteaKey[i] = secureBuffer.readInt();
- }
- long loginHash = secureBuffer.readLong();
- if (loginHash != 0) {
- throw new ProtocolException("Invalid login hash received: " + loginHash + ".");
- }
- String password = BufferUtility.readString(secureBuffer);
- long[] loginSeeds = new long[2];
- for (int i = 0; i < loginSeeds.length; i++) {
- loginSeeds[i] = secureBuffer.readLong();
- }
- byte[] xteaBlock = new byte[buffer.readableBytes()];
- buffer.readBytes(xteaBlock);
- XTEACipher xtea = new XTEACipher(xteaKey);
- xtea.decrypt(xteaBlock, 0, xteaBlock.length);
- ByteBuf xteaBuffer = Unpooled.wrappedBuffer(xteaBlock);
- boolean decodeAsString = xteaBuffer.readByte() == 1;
- String username = decodeAsString ? BufferUtility.readString(xteaBuffer) : Base37Utility.decodeBase37(xteaBuffer.readLong());
- xteaBuffer.readUnsignedByte(); // Game identifier.
- xteaBuffer.readUnsignedByte(); // Language identifier.
- xteaBuffer.readUnsignedByte(); // Frame type (Fixed, Resizable, or Full Screen).
- xteaBuffer.readUnsignedShort(); // Canvas width.
- xteaBuffer.readUnsignedShort(); // Canvas height.
- xteaBuffer.readUnsignedByte();
- int[] randomData = new int[24];
- for (int index = 0; index < randomData.length; index++) {
- randomData[index] = xteaBuffer.readUnsignedByte();
- }
- String token = BufferUtility.readString(xteaBuffer);
- if (token != Protocol.LOGIN_TOKEN) {
- throw new ProtocolException("Invalid login token received: " + token + ".");
- }
- int length = xteaBuffer.readUnsignedByte();
- byte[] machineData = new byte[length];
- for (int data = 0; data < machineData.length; data++) {
- machineData[data] = (byte) xteaBuffer.readUnsignedByte();
- }
- xteaBuffer.readInt();
- BufferUtility.readString(xteaBuffer);
- xteaBuffer.readInt();
- xteaBuffer.readInt();
- BufferUtility.readString(xteaBuffer);
- xteaBuffer.readUnsignedByte();
- int[] crc = new int[36];
- for (int index = 0; index < crc.length; index++) {
- crc[index] = xteaBuffer.readInt();
- }
- int[] serverKeys = new int[xteaKey.length];
- for (int i = 0; i < serverKeys.length; i++) {
- serverKeys[i] = xteaKey[i] + 50;
- }
- out.add(new LoginRequestMessage(context.channel(), UsernameUtility.formatForProtocol(username), password, username.contains("@"), new ISAACCipher(serverKeys), new ISAACCipher(xteaKey), type));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement