Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package aphrodite.rs357e.net.codec;
- import java.security.SecureRandom;
- 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.ProtocolDecoderOutput;
- import aphrodite.rs357e.net.stream.OutStream;
- import aphrodite.rs357e.util.BufferUtils;
- /**
- *
- * @author Karl
- *
- */
- public class RS2LoginDecoder extends CumulativeProtocolDecoder {
- /**
- * Represents the login state.
- * @author Karl
- *
- */
- public enum State {
- REQUEST_TYPE, SESSION_INFORMATION;
- }
- /**
- * The logger instance.
- */
- private static final Logger logger = Logger.getLogger(RS2LoginDecoder.class.getName());
- /**
- * The secure randomiser.
- */
- private SecureRandom random = new SecureRandom();
- /**
- * The login state.
- */
- private State state = State.REQUEST_TYPE;
- /**
- * The server key.
- */
- private long serverKey = random.nextLong();
- /**
- * The initial response.
- */
- private static final byte[] INITIAL_RESPONSE = new byte[] {
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
- };
- /**
- * The login size.
- */
- private int loginSize;
- /**
- * The encrypted size.
- */
- private int encrypted;
- @Override
- protected boolean doDecode(IoSession session, IoBuffer buffer,
- ProtocolDecoderOutput out) throws Exception {
- switch(state) {
- case REQUEST_TYPE:
- /*
- * The response.
- */
- byte response = 0;
- if(buffer.remaining() >= 2) {
- /*
- * If the buffer has 2 or more bytes remaining check the game opcode. (14)
- */
- int request = buffer.get() & 0xFF;
- if(request != 14) {
- logger.warning("Invalid request type: "+request+".");
- session.close(false);
- return true;
- }
- /*
- * Read the name hash although it is unused.
- */
- @SuppressWarnings("unused")
- int nameHash = buffer.get() & 0xFF;
- OutStream outStream = new OutStream();
- /*
- * Writes the initial response.
- */
- outStream.put(INITIAL_RESPONSE);
- outStream.put(response);
- outStream.putLong(serverKey);
- /*
- * Writes the initial response to the stream.
- */
- session.write(outStream.toStream());
- /*
- * Checks if the response is not equal to 0.
- */
- if(response != 0) {
- logger.warning("Invalid response: "+response+"");
- session.close(false);
- return true;
- }
- state = State.SESSION_INFORMATION;
- logger.info("Pushing Session information...");
- }
- return false;
- case SESSION_INFORMATION:
- if(buffer.remaining() >= 2) {
- /*
- * Checks the connection type.
- */
- int connectionType = buffer.get() & 0xFF;
- @SuppressWarnings("unused")
- boolean reconnecting = connectionType == 18;
- if(connectionType != 16 && connectionType != 18) {
- logger.warning("Invalid connection type: "+connectionType+".");
- session.close(false);
- return true;
- }
- /*
- * Read the login size.
- */
- loginSize = buffer.get() & 0xFF;
- encrypted = loginSize - 40;
- /*
- * Check if the encrypted packet size is equal to or less then 0.
- */
- if(encrypted <= 0) {
- logger.warning("Invalid encrypted packet size: "+encrypted+".");
- session.close(false);
- return true;
- }
- } else {
- buffer.rewind();
- return false;
- }
- if(buffer.remaining() >= loginSize) {
- /*
- * Check if the login packet is equal to 255.
- */
- boolean loginPacket = buffer.getUnsigned() == 255;
- if(!loginPacket) {
- logger.warning("Invalid login packet: "+loginPacket+".");
- session.close(false);
- return true;
- }
- /*
- * Check if the client version is equal to the servers version.
- */
- short clientVersion = buffer.getShort();
- if(clientVersion != 357) {
- logger.warning("Invalid client version: "+clientVersion+".");
- session.close(false);
- return true;
- }
- /*
- * Check if the player is playing in low memory.
- */
- @SuppressWarnings("unused")
- boolean lowMemmory = buffer.get() == 1;
- /*
- * Read the crc values.
- */
- for(int i = 0; i < 9; i++) {
- buffer.getInt();
- }
- encrypted--;
- /*
- * Check if the encrypted size is equal to a byte.
- */
- if(buffer.get() != encrypted) {
- logger.warning("Invalid encrypted size: "+encrypted+".");
- session.close(false);
- return true;
- }
- /*
- * Read the rsa opcode; although in most old engine clients the rsa
- * has been disabled.
- */
- byte rsaOpcode = buffer.get();
- if(rsaOpcode != 10) {
- logger.warning("Invalid rsa opcode: "+rsaOpcode+".");
- session.close(false);
- return true;
- }
- /*
- * Retrieve the session keys.
- */
- @SuppressWarnings("unused")
- long clientKey = buffer.getLong();
- long reportedKey = buffer.getLong();
- /*
- * Check if the server key is equal to the reported key.
- * Else close the session.
- */
- if(serverKey != reportedKey) {
- logger.warning("Invalid server key or reported key: server key: "+serverKey+"" +
- "reported key: "+reportedKey+".");
- session.close(false);
- return true;
- }
- /*
- * Get the players unique id.
- */
- @SuppressWarnings("unused")
- int uid = buffer.getInt();
- /*
- * Gets the players username and password.
- */
- String username = BufferUtils.getRS2String(buffer);
- String password = BufferUtils.getRS2String(buffer);
- logger.info("Registered player: [username: "+username+" password: "+password+"]");
- /*
- * Writes the login response.
- */
- OutStream resp = new OutStream();
- resp.put((byte) 2);
- resp.put((byte) 2);
- resp.put((byte) 0);
- /*
- * Writes the login response to the stream.
- */
- session.write(resp.toStream());
- return true;
- } else {
- return false;
- }
- }
- return true;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement