net.ieldor.utility.flooder.FlooderChannelHandler.java Source code

Java tutorial

Introduction

Here is the source code for net.ieldor.utility.flooder.FlooderChannelHandler.java

Source

/*
 * This file is part of Ieldor.
 *
 * Ieldor is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Ieldor is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Ieldor.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.ieldor.utility.flooder;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.SecureRandom;

import net.ieldor.utility.Base37Utils;
import net.ieldor.utility.ByteBufUtils;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundByteHandlerAdapter;

public final class FlooderChannelHandler extends ChannelInboundByteHandlerAdapter {

    private enum State {
        READ_SERVER_SESSION_KEY, READ_LOGIN_STATUS, READ_LOGIN_PAYLOAD, READ_GAME_OPCODE
    }

    private static final SecureRandom random = new SecureRandom();

    private State state = State.READ_SERVER_SESSION_KEY;
    private final int[] crc;
    private final long clientSessionKey = random.nextLong();
    private String username, password;
    private long serverSessionKey, encodedUsername;

    public FlooderChannelHandler(int[] crc) {
        this.crc = crc;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        Channel channel = ctx.channel();

        username = "bot" + ((InetSocketAddress) channel.localAddress()).getPort();
        password = "password";
        encodedUsername = Base37Utils.encodeBase37(username);

        ByteBuf packet = Unpooled.buffer();
        packet.writeByte(14);
        packet.writeByte((byte) ((encodedUsername >> 16) & 31));
        channel.write(packet);
    }

    @Override
    public void inboundBufferUpdated(ChannelHandlerContext ctx, ByteBuf buf) throws IOException {
        Channel channel = ctx.channel();

        if (state == State.READ_SERVER_SESSION_KEY) {
            if (buf.readableBytes() >= 9) {
                if (buf.readUnsignedByte() != 0)
                    throw new IOException("expecting EXCHANGE_KEYS opcode");

                serverSessionKey = buf.readLong();

                ByteBuf payload = Unpooled.buffer();
                payload.writeInt(530);

                payload.writeByte(0);
                payload.writeByte(0);
                payload.writeByte(0);

                payload.writeByte(0);
                payload.writeShort(765);
                payload.writeShort(503);

                payload.writeByte(0);

                for (int i = 0; i < 24; i++)
                    payload.writeByte(0);

                ByteBufUtils.writeString(payload, "kKmok3kJqOeN6D3mDdihco3oPeYN2KFy6W5--vZUbNA");

                payload.writeInt(0);
                payload.writeInt(0);
                payload.writeShort(0);

                for (int i = 0; i < 28; i++) {
                    payload.writeInt(crc[i]);
                }

                payload.writeByte(10);
                payload.writeLong(clientSessionKey);
                payload.writeLong(serverSessionKey);
                payload.writeLong(encodedUsername);
                ByteBufUtils.writeString(payload, password);

                ByteBuf packet = Unpooled.buffer();
                packet.writeByte(18);
                packet.writeShort(payload.readableBytes());
                packet.writeBytes(payload);

                channel.write(packet);

                int[] seed = new int[4];
                seed[0] = (int) (clientSessionKey >> 32);
                seed[1] = (int) clientSessionKey;
                seed[2] = (int) (serverSessionKey >> 32);
                seed[3] = (int) serverSessionKey;

                state = State.READ_LOGIN_STATUS;
            }
        }

        if (state == State.READ_LOGIN_STATUS) {
            if (buf.readable()) {
                int status = buf.readUnsignedByte();
                if (status != 2)
                    throw new IOException("expecting OK login response");

                state = State.READ_LOGIN_PAYLOAD;
            }
        }

        if (state == State.READ_LOGIN_PAYLOAD) {
            if (buf.readableBytes() >= 11) {
                buf.readerIndex(buf.readerIndex() + 11);

                state = State.READ_GAME_OPCODE;
            }
        }

        if (state == State.READ_GAME_OPCODE) {

        }
    }
}