Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package org.hyperion.rs2.net;
- import java.nio.ByteBuffer;
- import java.util.logging.Logger;
- import org.apache.mina.core.buffer.IoBuffer;
- import org.apache.mina.core.session.IoSession;
- import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
- import org.apache.mina.filter.codec.ProtocolCodecFilter;
- import org.apache.mina.filter.codec.ProtocolDecoderOutput;
- import org.hyperion.Server;
- import org.hyperion.rs2.model.PlayerDetails;
- import org.hyperion.rs2.model.World;
- import org.hyperion.rs2.net.ondemand.OnDemandPool;
- import org.hyperion.rs2.net.ondemand.OnDemandRequest;
- import org.hyperion.rs2.util.XTEADecipher;
- import org.hyperion.util.Buffers;
- import org.hyperion.util.CommonConstants;
- /**
- * Login protocol decoding class.
- * @author Graham Edgecombe, Flamable
- *
- */
- public class RS2LoginDecoder extends CumulativeProtocolDecoder {
- private static final Logger logger = Logger.getLogger(RS2LoginDecoder.class.getName());
- public static final int STATE_OPCODE = 0;
- public static final int STATE_lOGINBLOCK_DECYPT = 1;
- public static final int STATE_UPDATE = -1;
- public static final int OPCODE_GAME = 14;
- public static final int OPCODE_UPDATE = 15;
- @Override
- protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
- int state = (Integer) session.getAttribute("state", STATE_OPCODE);
- switch(state) {
- case STATE_UPDATE:
- /**
- * TODO update so works with 666
- */
- if(in.remaining() >= 4) {
- int priority = in.get() & 0xFF;
- int cacheId = in.get() & 0xFF;
- int fileId = ((in.get() & 0xFF) << 8) | (in.get() & 0xFF);
- /*
- * We push the request into the ondemand pool so it can be served.
- */
- if (priority == 0 || priority == 1)
- OnDemandPool.getOnDemandPool().pushRequest(new OnDemandRequest(session, cacheId, fileId, priority));
- return true;
- } else {
- in.rewind();
- return false;
- }
- case STATE_OPCODE:
- if(in.remaining() >= 1) {
- int opcode = in.get() & 0xFF;
- switch(opcode) {
- case OPCODE_GAME:
- session.write(new PacketBuilder().put((byte) 0).toPacket());
- session.setAttribute("state", STATE_lOGINBLOCK_DECYPT);
- return true;
- case OPCODE_UPDATE:
- int revision = in.getInt();
- if (revision == 666) {
- System.out.print(revision);
- PacketBuilder pb = new PacketBuilder();
- pb.put((byte) 0);
- for (int dlen : CommonConstants.STAGE_DELTA)
- pb.putInt(dlen);
- session.write(pb.toPacket());
- } else {
- session.write(new PacketBuilder().put((byte) 6).toPacket());
- }
- session.setAttribute("state", STATE_UPDATE);
- return true;
- default:
- logger.info("Invalid opcode : " + opcode);
- session.close(false);
- break;
- }
- } else {
- in.rewind();
- return false;
- }
- break;
- case STATE_lOGINBLOCK_DECYPT:
- int loginSize = 0;
- int loginOpcode = 0;
- String username = "";
- @SuppressWarnings("unused")
- String settingVerificationString = "";
- int graphicMode = 0;
- /**
- * Gets the Login Opcode and the LoginBlockPayload Len
- */
- if(in.remaining() >= 3) {
- loginOpcode = in.get() & 0xFF;
- if(loginOpcode != 16 && loginOpcode != 18) {
- logger.info("Invalid login opcode : " + loginOpcode);
- session.close(false);
- in.rewind();
- return false;
- }
- loginSize = in.getShort() & 0xFFFF;
- }
- /**
- * Decypts the LoginBlock
- */
- if(in.remaining() >= loginSize) {
- int version = in.getInt();
- if(version != Server.VERSION) {
- logger.info("Incorrect version : " + version);
- session.close(false);
- in.rewind();
- return false;
- }
- /**
- * Decoder The Rsa buffer
- */
- byte[] rsaPayload = new byte[in.getShort() & 0xffff];
- in.get(rsaPayload);
- ByteBuffer rsaBuffer = ByteBuffer.wrap(rsaPayload/*new BigInteger(rsaData).modPow(ServerConstants.PRIVATE_KEY, ServerConstants.MODULE).toByteArray()*/);
- int rsaHeaderKey = rsaBuffer.get();
- if (rsaHeaderKey != 10) {
- logger.info("Incorrect Header : " + version);
- session.close(false);
- in.rewind();
- return false;
- }
- int[] xtea = new int[] {rsaBuffer.getInt(), rsaBuffer.getInt(), rsaBuffer.getInt(), rsaBuffer.getInt()};
- rsaBuffer.getLong();
- String password = Buffers.readString(rsaBuffer);
- long clientKey = rsaBuffer.getLong();//?
- long serverKey = rsaBuffer.getLong();//?
- /**
- * Decoder The xteaed Payload Block
- */
- byte[] xteaPayload = new byte[in.remaining()];
- in.get(xteaPayload);
- byte[] is = XTEADecipher.decryptXTEA(xtea, xteaPayload, 0, xteaPayload.length);
- ByteBuffer xteaBuffer = ByteBuffer.wrap(is);
- switch (loginOpcode) {
- /**
- * Lobby
- */
- case 19:
- /**
- * TODO consider if want serperate server for lobby or not
- */
- //break;
- /**
- * World Login
- */
- case 16:
- case 18:
- //case 29:
- username = Buffers.readString(xteaBuffer);
- xteaBuffer.get();
- graphicMode = xteaBuffer.get();
- xteaBuffer.getShort();
- xteaBuffer.getShort();
- xteaBuffer.get();
- /**
- * Setting values
- * TODO Check them to see if it is the client or not
- */
- for (int i = 0; i < 24; i++) {
- xteaBuffer.get();
- }
- settingVerificationString = Buffers.readString(xteaBuffer);
- xteaBuffer.getInt();
- byte[] unhandledBytes = new byte[xteaBuffer.get()];
- xteaBuffer.get(unhandledBytes);
- System.out.println("Name " + username + " password " + password);
- break;
- }
- /**
- * Isacc
- */
- int[] sessionKey = new int[4];
- sessionKey[0] = (int) (clientKey >> 32);
- sessionKey[1] = (int) clientKey;
- sessionKey[2] = (int) (serverKey >> 32);
- sessionKey[3] = (int) serverKey;
- session.removeAttribute("state");
- session.removeAttribute("serverKey");
- session.removeAttribute("size");
- session.removeAttribute("encryptSize");
- ISAACCipher inCipher = new ISAACCipher(sessionKey);
- for(int i = 0; i < 4; i++) {
- sessionKey[i] += 50;
- }
- ISAACCipher outCipher = new ISAACCipher(sessionKey);
- session.getFilterChain().remove("protocol");
- session.getFilterChain().addFirst("protocol", new ProtocolCodecFilter(RS2CodecFactory.GAME));
- PlayerDetails pd = new PlayerDetails(session, username, password, inCipher, outCipher, graphicMode);
- World.getWorld().load(pd);
- }
- break;
- }
- in.rewind();
- return false;
- }
- }
Add Comment
Please, Sign In to add comment