Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package net.netty;
- import io.LoadRequest;
- import net.ISAACCipher;
- import net.packet.Packet;
- import org.jboss.netty.buffer.ChannelBuffer;
- import org.jboss.netty.buffer.ChannelBuffers;
- import org.jboss.netty.channel.Channel;
- import org.jboss.netty.channel.ChannelFuture;
- import org.jboss.netty.channel.ChannelFutureListener;
- import org.jboss.netty.channel.ChannelHandlerContext;
- import org.jboss.netty.handler.codec.frame.FrameDecoder;
- import world.World;
- public class LoginProtocolDecoder extends FrameDecoder {
- private static enum LoginStages {
- REQUEST, LOGIN_REQUEST_PART_ONE, LOGIN_REQUEST_PART_TWO, LOGIN_REQUEST_PART_THREE
- }
- private LoginStages loginStage = LoginStages.REQUEST;
- private int encryptedBlockSize;
- private long serverKeyPart;
- private static byte[] junkBytes = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
- static ChannelFutureListener closeFuture = new ChannelFutureListener() {
- @Override
- public void operationComplete(ChannelFuture future) throws Exception {
- future.getChannel().disconnect();
- }
- };
- static void sendReturnCode(int i, Channel channel, boolean closeChannel) {
- ChannelBuffer buf = ChannelBuffers.buffer(1);
- buf.writeByte(i);
- if (closeChannel) {
- channel.write(buf).addListener(closeFuture);
- } else {
- channel.write(buf);
- }
- }
- @Override
- protected Object decode(ChannelHandlerContext ctx, final Channel channel,
- ChannelBuffer buffer) throws Exception {
- if (buffer.readableBytes() <= 0)
- return null;
- switch (loginStage) {
- case REQUEST:
- if (buffer.readableBytes() >= 2) {
- buffer.markReaderIndex();
- int requestType = buffer.readUnsignedByte();
- if (requestType == 14) {
- @SuppressWarnings("unused")
- int nameHash = buffer.readUnsignedByte();
- serverKeyPart = ((long) (java.lang.Math.random() * 99999999D) << 32)
- + (long) (java.lang.Math.random() * 99999999D);
- ChannelBuffer loginResponce = ChannelBuffers.buffer(17);
- loginResponce.writeBytes(junkBytes);
- loginResponce.writeByte(0);
- loginResponce.writeLong(serverKeyPart);
- this.loginStage = LoginStages.LOGIN_REQUEST_PART_ONE;
- channel.write(loginResponce);
- return null;
- }
- /*
- * Not a supported type. Lets close the channel.
- */
- channel.close();
- return null;
- } else {
- return null;
- }
- case LOGIN_REQUEST_PART_ONE:
- if (buffer.readableBytes() >= 42) {
- int loginType = buffer.readByte() & 0xff;
- if (loginType != 16 && loginType != 18) { // 16 normal, 18
- // reconnecting
- sendReturnCode((byte) 0, channel, true); // TODO response
- // code.
- return null;
- }
- encryptedBlockSize = buffer.readByte() - 40;
- // Here we read the 40 extra bytes which are added the the
- // encrypted block size above^^
- int verificationByte = buffer.readByte() & 0xff;
- if (verificationByte != 255) {
- sendReturnCode(0, channel, true); // TODO return code;
- return null;
- }
- int clientVersion = buffer.readShort();
- if (clientVersion != 377) {
- sendReturnCode(0, channel, true); // RuneScape has since
- // been updated.
- return null;
- }
- @SuppressWarnings("unused")
- boolean lowMemoryVersion = buffer.readByte() == 0;
- for (int i = 0; i < 9; i++) {
- buffer.readInt(); // We should make a note of what these are
- // and then compare them against
- // connecting clients. We should then
- // send a RuneScape has since been
- // updated message if they do not match.
- }
- encryptedBlockSize--;
- if (encryptedBlockSize <= 0) {
- sendReturnCode(0, channel, true);
- return null;
- }
- loginStage = LoginStages.LOGIN_REQUEST_PART_TWO;
- return true; // Return true so that this method is instantly
- // called again in case we have the data needed
- // to continue.
- }
- case LOGIN_REQUEST_PART_TWO:
- if (buffer.readableBytes() >= encryptedBlockSize) {
- int remainingBytes = buffer.readByte();
- if (remainingBytes != encryptedBlockSize) {
- sendReturnCode(0, channel, true);
- return null;
- }
- int verificationByte = buffer.readByte() & 0xff;
- if (verificationByte != 10) {
- sendReturnCode(0, channel, true);
- System.out.println("k4:" + verificationByte);
- return null;
- }
- long clientKeyPart = buffer.readLong();
- long serverKeyPart = buffer.readLong();
- if (serverKeyPart != this.serverKeyPart) {
- sendReturnCode(0, channel, true);
- System.out.println("k5");
- return null;
- }
- int uid = buffer.readInt();
- String username = Packet.getString(buffer);
- String password = Packet.getString(buffer);
- int sessionKey[] = new int[4];
- sessionKey[0] = (int) (clientKeyPart >> 32);
- sessionKey[1] = (int) clientKeyPart;
- sessionKey[2] = (int) (serverKeyPart >> 32);
- sessionKey[3] = (int) serverKeyPart;
- ISAACCipher inCipher = new ISAACCipher(sessionKey);
- for (int i = 0; i < 4; i++)
- sessionKey[i] += 50;
- ISAACCipher outCipher = new ISAACCipher(sessionKey);
- LoadRequest lr = new LoadRequest(channel, username, password,
- uid, inCipher, outCipher);
- World.getWorld().getAccountManager().loadPlayer(lr);
- }
- return null;
- }
- return null;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement