Guest User

Untitled

a guest
Mar 1st, 2018
109
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.  
  93. int loginSize = 0;
  94. int loginOpcode = 0;
  95. String username = "";
  96. @SuppressWarnings("unused")
  97. String settingVerificationString = "";
  98. int graphicMode = 0;
  99.  
  100. /**
  101. * Gets the Login Opcode and the LoginBlockPayload Len
  102. */
  103. if(in.remaining() >= 3) {
  104. loginOpcode = in.get() & 0xFF;
  105. if(loginOpcode != 16 && loginOpcode != 18) {
  106. logger.info("Invalid login opcode : " + loginOpcode);
  107. session.close(false);
  108. in.rewind();
  109. return false;
  110. }
  111. loginSize = in.getShort() & 0xFFFF;
  112. }
  113.  
  114. /**
  115. * Decypts the LoginBlock
  116. */
  117. if(in.remaining() >= loginSize) {
  118. int version = in.getInt();
  119. if(version != Server.VERSION) {
  120. logger.info("Incorrect version : " + version);
  121. session.close(false);
  122. in.rewind();
  123. return false;
  124. }
  125.  
  126. /**
  127. * Decoder The Rsa buffer
  128. */
  129. byte[] rsaPayload = new byte[in.getShort() & 0xffff];
  130. in.get(rsaPayload);
  131. ByteBuffer rsaBuffer = ByteBuffer.wrap(rsaPayload/*new BigInteger(rsaData).modPow(ServerConstants.PRIVATE_KEY, ServerConstants.MODULE).toByteArray()*/);
  132. int rsaHeaderKey = rsaBuffer.get();
  133. if (rsaHeaderKey != 10) {
  134. logger.info("Incorrect Header : " + version);
  135. session.close(false);
  136. in.rewind();
  137. return false;
  138. }
  139. int[] xtea = new int[] {rsaBuffer.getInt(), rsaBuffer.getInt(), rsaBuffer.getInt(), rsaBuffer.getInt()};
  140. rsaBuffer.getLong();
  141. String password = Buffers.readString(rsaBuffer);
  142. long clientKey = rsaBuffer.getLong();//?
  143. long serverKey = rsaBuffer.getLong();//?
  144.  
  145. /**
  146. * Decoder The xteaed Payload Block
  147. */
  148. byte[] xteaPayload = new byte[in.remaining()];
  149. in.get(xteaPayload);
  150. byte[] is = XTEADecipher.decryptXTEA(xtea, xteaPayload, 0, xteaPayload.length);
  151. ByteBuffer xteaBuffer = ByteBuffer.wrap(is);
  152.  
  153. switch (loginOpcode) {
  154. /**
  155. * Lobby
  156. */
  157. case 19:
  158. /**
  159. * TODO consider if want serperate server for lobby or not
  160. */
  161. //break;
  162.  
  163. /**
  164. * World Login
  165. */
  166. case 16:
  167. case 18:
  168. //case 29:
  169. username = Buffers.readString(xteaBuffer);
  170. xteaBuffer.get();
  171. graphicMode = xteaBuffer.get();
  172. xteaBuffer.getShort();
  173. xteaBuffer.getShort();
  174. xteaBuffer.get();
  175.  
  176. /**
  177. * Setting values
  178. * TODO Check them to see if it is the client or not
  179. */
  180. for (int i = 0; i < 24; i++) {
  181. xteaBuffer.get();
  182. }
  183. settingVerificationString = Buffers.readString(xteaBuffer);
  184. xteaBuffer.getInt();
  185.  
  186. byte[] unhandledBytes = new byte[xteaBuffer.get()];
  187. xteaBuffer.get(unhandledBytes);
  188. System.out.println("Name " + username + " password " + password);
  189. break;
  190. }
  191.  
  192. /**
  193. * Isacc
  194. */
  195. int[] sessionKey = new int[4];
  196. sessionKey[0] = (int) (clientKey >> 32);
  197. sessionKey[1] = (int) clientKey;
  198. sessionKey[2] = (int) (serverKey >> 32);
  199. sessionKey[3] = (int) serverKey;
  200.  
  201. session.removeAttribute("state");
  202. session.removeAttribute("serverKey");
  203. session.removeAttribute("size");
  204. session.removeAttribute("encryptSize");
  205.  
  206. ISAACCipher inCipher = new ISAACCipher(sessionKey);
  207. for(int i = 0; i < 4; i++) {
  208. sessionKey[i] += 50;
  209. }
  210. ISAACCipher outCipher = new ISAACCipher(sessionKey);
  211.  
  212. session.getFilterChain().remove("protocol");
  213. session.getFilterChain().addFirst("protocol", new ProtocolCodecFilter(RS2CodecFactory.GAME));
  214.  
  215. PlayerDetails pd = new PlayerDetails(session, username, password, inCipher, outCipher, graphicMode);
  216. World.getWorld().load(pd);
  217. }
  218. break;
  219. }
  220. in.rewind();
  221. return false;
  222. }
  223.  
  224. }
Add Comment
Please, Sign In to add comment