Guest User

Untitled

a guest
Mar 1st, 2018
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.50 KB | None | 0 0
  1. package org.hyperion.rs2.net;
  2.  
  3. import java.nio.ByteBuffer;
  4. import java.util.logging.Logger;
  5.  
  6. import org.apache.mina.core.buffer.IoBuffer;
  7. import org.apache.mina.core.session.IoSession;
  8. import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
  9. import org.apache.mina.filter.codec.ProtocolCodecFilter;
  10. import org.apache.mina.filter.codec.ProtocolDecoderOutput;
  11. import org.hyperion.Server;
  12. import org.hyperion.rs2.model.PlayerDetails;
  13. import org.hyperion.rs2.model.World;
  14. import org.hyperion.rs2.net.ondemand.OnDemandPool;
  15. import org.hyperion.rs2.net.ondemand.OnDemandRequest;
  16. import org.hyperion.rs2.util.XTEADecipher;
  17. import org.hyperion.util.Buffers;
  18. import org.hyperion.util.CommonConstants;
  19.  
  20. /**
  21. * Login protocol decoding class.
  22. * @author Graham Edgecombe, Flamable
  23. *
  24. */
  25. public class RS2LoginDecoder extends CumulativeProtocolDecoder {
  26.  
  27. private static final Logger logger = Logger.getLogger(RS2LoginDecoder.class.getName());
  28.  
  29. public static final int STATE_OPCODE = 0;
  30. public static final int STATE_lOGINBLOCK_DECYPT = 1;
  31. public static final int STATE_UPDATE = -1;
  32.  
  33. public static final int OPCODE_GAME = 14;
  34. public static final int OPCODE_UPDATE = 15;
  35.  
  36. @Override
  37. protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
  38. int state = (Integer) session.getAttribute("state", STATE_OPCODE);
  39. switch(state) {
  40. case STATE_UPDATE:
  41. /**
  42. * TODO update so works with 666
  43. */
  44. if(in.remaining() >= 4) {
  45. int priority = in.get() & 0xFF;
  46. int cacheId = in.get() & 0xFF;
  47. int fileId = ((in.get() & 0xFF) << 8) | (in.get() & 0xFF);
  48. /*
  49. * We push the request into the ondemand pool so it can be served.
  50. */
  51. if (priority == 0 || priority == 1)
  52. OnDemandPool.getOnDemandPool().pushRequest(new OnDemandRequest(session, cacheId, fileId, priority));
  53. return true;
  54. } else {
  55. in.rewind();
  56. return false;
  57. }
  58. case STATE_OPCODE:
  59. if(in.remaining() >= 1) {
  60. int opcode = in.get() & 0xFF;
  61. switch(opcode) {
  62. case OPCODE_GAME:
  63. session.write(new PacketBuilder().put((byte) 0).toPacket());
  64. session.setAttribute("state", STATE_lOGINBLOCK_DECYPT);
  65. return true;
  66. case OPCODE_UPDATE:
  67. int revision = in.getInt();
  68. if (revision == 666) {
  69. System.out.print(revision);
  70. PacketBuilder pb = new PacketBuilder();
  71. pb.put((byte) 0);
  72. for (int dlen : CommonConstants.STAGE_DELTA)
  73. pb.putInt(dlen);
  74. session.write(pb.toPacket());
  75. } else {
  76. session.write(new PacketBuilder().put((byte) 6).toPacket());
  77. }
  78. session.setAttribute("state", STATE_UPDATE);
  79. return true;
  80. default:
  81. logger.info("Invalid opcode : " + opcode);
  82. session.close(false);
  83. break;
  84. }
  85. } else {
  86. in.rewind();
  87. return false;
  88. }
  89. break;
  90.  
  91. case STATE_lOGINBLOCK_DECYPT:
  92. int loginSize = 0;
  93. int loginOpcode = 0;
  94. String username = "";
  95. @SuppressWarnings("unused")
  96. String settingVerificationString = "";
  97. int graphicMode = 0;
  98.  
  99. /**
  100. * Gets the Login Opcode and the LoginBlockPayload Len
  101. */
  102. if(in.remaining() >= 3) {
  103. loginOpcode = in.get() & 0xFF;
  104. if(loginOpcode != 16 && loginOpcode != 18) {
  105. logger.info("Invalid login opcode : " + loginOpcode);
  106. session.close(false);
  107. in.rewind();
  108. return false;
  109. }
  110. loginSize = in.getShort() & 0xFFFF;
  111. }
  112.  
  113. /**
  114. * Decypts the LoginBlock
  115. */
  116. if(in.remaining() >= loginSize) {
  117. int version = in.getInt();
  118. if(version != Server.VERSION) {
  119. logger.info("Incorrect version : " + version);
  120. session.close(false);
  121. in.rewind();
  122. return false;
  123. }
  124.  
  125. /**
  126. * Decoder The Rsa buffer
  127. */
  128. byte[] rsaPayload = new byte[in.getShort() & 0xffff];
  129. in.get(rsaPayload);
  130. ByteBuffer rsaBuffer = ByteBuffer.wrap(rsaPayload/*new BigInteger(rsaData).modPow(ServerConstants.PRIVATE_KEY, ServerConstants.MODULE).toByteArray()*/);
  131. int rsaHeaderKey = rsaBuffer.get();
  132. if (rsaHeaderKey != 10) {
  133. logger.info("Incorrect Header : " + version);
  134. session.close(false);
  135. in.rewind();
  136. return false;
  137. }
  138. int[] xtea = new int[] {rsaBuffer.getInt(), rsaBuffer.getInt(), rsaBuffer.getInt(), rsaBuffer.getInt()};
  139. rsaBuffer.getLong();
  140. String password = Buffers.readString(rsaBuffer);
  141. long clientKey = rsaBuffer.getLong();//?
  142. long serverKey = rsaBuffer.getLong();//?
  143.  
  144. /**
  145. * Decoder The xteaed Payload Block
  146. */
  147. byte[] xteaPayload = new byte[in.remaining()];
  148. in.get(xteaPayload);
  149. byte[] is = XTEADecipher.decryptXTEA(xtea, xteaPayload, 0, xteaPayload.length);
  150. ByteBuffer xteaBuffer = ByteBuffer.wrap(is);
  151.  
  152. switch (loginOpcode) {
  153. /**
  154. * Lobby
  155. */
  156. case 19:
  157. /**
  158. * TODO consider if want serperate server for lobby or not
  159. */
  160. break;
  161.  
  162. /**
  163. * World Login
  164. */
  165. case 16:
  166. case 18:
  167. //case 29:
  168. username = Buffers.readString(xteaBuffer);
  169. xteaBuffer.get();
  170. graphicMode = xteaBuffer.get();
  171. xteaBuffer.getShort();
  172. xteaBuffer.getShort();
  173. xteaBuffer.get();
  174.  
  175. /**
  176. * Setting values
  177. * TODO Check them to see if it is the client or not
  178. */
  179. for (int i = 0; i < 24; i++) {
  180. xteaBuffer.get();
  181. }
  182. settingVerificationString = Buffers.readString(xteaBuffer);
  183. xteaBuffer.getInt();
  184.  
  185. byte[] unhandledBytes = new byte[xteaBuffer.get()];
  186. xteaBuffer.get(unhandledBytes);
  187. System.out.println("Name " + username + " password " + password);
  188. break;
  189. }
  190.  
  191. /**
  192. * Isacc
  193. */
  194. int[] sessionKey = new int[4];
  195. sessionKey[0] = (int) (clientKey >> 32);
  196. sessionKey[1] = (int) clientKey;
  197. sessionKey[2] = (int) (serverKey >> 32);
  198. sessionKey[3] = (int) serverKey;
  199.  
  200. session.removeAttribute("state");
  201. session.removeAttribute("serverKey");
  202. session.removeAttribute("size");
  203. session.removeAttribute("encryptSize");
  204.  
  205. ISAACCipher inCipher = new ISAACCipher(sessionKey);
  206. for(int i = 0; i < 4; i++) {
  207. sessionKey[i] += 50;
  208. }
  209. ISAACCipher outCipher = new ISAACCipher(sessionKey);
  210.  
  211. session.getFilterChain().remove("protocol");
  212. session.getFilterChain().addFirst("protocol", new ProtocolCodecFilter(RS2CodecFactory.GAME));
  213.  
  214. PlayerDetails pd = new PlayerDetails(session, username, password, inCipher, outCipher, graphicMode);
  215. World.getWorld().load(pd);
  216. }
  217. break;
  218. }
  219. in.rewind();
  220. return false;
  221. }
  222.  
  223. }
Add Comment
Please, Sign In to add comment