Advertisement
Guest User

Untitled

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