Advertisement
Guest User

Untitled

a guest
May 26th, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.88 KB | None | 0 0
  1. package org.hyperion.rs2.net;
  2.  
  3. import java.security.SecureRandom;
  4. import java.util.logging.Logger;
  5. import java.util.LinkedList;
  6. import java.util.concurrent.ExecutorService;
  7. import java.util.concurrent.Executors;
  8.  
  9. import org.apache.mina.core.buffer.IoBuffer;
  10. import org.apache.mina.core.session.IoSession;
  11. import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
  12. import org.apache.mina.filter.codec.ProtocolCodecFilter;
  13. import org.apache.mina.filter.codec.ProtocolDecoderOutput;
  14.  
  15. import org.hyperion.Server;
  16. import org.hyperion.cache.UpdateServer;
  17. import org.hyperion.rs2.model.PlayerDetails;
  18. import org.hyperion.rs2.model.World;
  19. import org.hyperion.rs2.util.IoBufferUtils;
  20. import org.hyperion.rs2.util.NameUtils;
  21. import org.hyperion.rs2.util.TextUtils;
  22.  
  23. public class RS2LoginDecoder extends CumulativeProtocolDecoder {
  24.  
  25. /**
  26. * Logger instance.
  27. */
  28. private static final Logger logger = Logger.getLogger(RS2LoginDecoder.class.getName());
  29.  
  30. /**
  31. * Opcode stage.
  32. */
  33. public static final int STATE_OPCODE = 0;
  34.  
  35. /**
  36. * Precrypted stage.
  37. */
  38. public static final int STATE_PRECRYPTED = 2;
  39.  
  40. /**
  41. * Crypted stage.
  42. */
  43. public static final int STATE_CRYPTED = 3;
  44.  
  45. /**
  46. * Client Rev Check stage.
  47. */
  48. public static final int STATE_CRC = 1;
  49.  
  50. /**
  51. * Update stage.
  52. */
  53. public static final int STATE_UPDATE = -1;
  54.  
  55. /**
  56. * Game opcode.
  57. */
  58. public static final int OPCODE_GAME = 14;
  59.  
  60. /**
  61. * Update opcode.
  62. */
  63. public static final int OPCODE_UPDATE = 15;
  64.  
  65. /**
  66. * Secure random number generator.
  67. */
  68. private static final SecureRandom RANDOM = new SecureRandom();
  69.  
  70. private LinkedList<Request> requests = new LinkedList<Request>();
  71.  
  72. private static ExecutorService updateService = Executors.newFixedThreadPool(1);
  73.  
  74. /**
  75. * Initial login response.
  76. */
  77. private static final byte[] INITIAL_RESPONSE = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
  78.  
  79. @Override
  80. protected boolean doDecode(final IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
  81. synchronized(session) {
  82. int state = (Integer) session.getAttribute("state", STATE_OPCODE);
  83. switch(state) {
  84. case STATE_UPDATE:
  85. if(in.remaining() >= 4) {
  86. int type = in.get() & 0xff;
  87. final int cache = in.get() & 0xff;
  88. final int id = in.getShort() & 0xffff;
  89. switch (type) {
  90. case 0: // non-urgent
  91. requests.add(new Request(cache, id));
  92. break;
  93. case 1: // urgent
  94. updateService.execute(new Runnable() {
  95. @Override
  96. public void run() {
  97. session.write(UpdateServer.getPacketRequest(cache, id));
  98. }
  99. });
  100. break;
  101. case 2: // clear requests
  102. case 3:
  103. requests.clear();
  104. break;
  105. case 4: // client error
  106. break;
  107. }
  108. while (requests.size() > 0) {
  109. Request request = (Request) requests.removeFirst();
  110. session.write(UpdateServer.getPacketRequest(request.getCache(), request.getId()));
  111. }
  112. return true;
  113. } else {
  114. in.rewind();
  115. return false;
  116. }
  117. case STATE_CRC:
  118. if(in.remaining() >= 3) {
  119. in.get();
  120. int version = in.getShort();
  121. if (version == Server.VERSION) {
  122. session.write(new PacketBuilder().put((byte) 0).toPacket());
  123. session.setAttribute("state", STATE_UPDATE);
  124. } else {
  125. session.write(new PacketBuilder().put((byte) 6).toPacket());
  126. session.removeAttribute("state");
  127. }
  128. return true;
  129. }
  130. break;
  131. case STATE_OPCODE:
  132. if(in.remaining() >= 2) {
  133. int opcode = in.get() & 0xFF;
  134. int hash = in.get() & 0xFF;
  135. switch(opcode) {
  136. case OPCODE_GAME:
  137. long serverKey = RANDOM.nextLong();
  138. session.write(new PacketBuilder().put((byte) 0).putLong(serverKey).toPacket());
  139. session.setAttribute("serverKey", serverKey);
  140. session.setAttribute("state", STATE_PRECRYPTED);
  141. return true;
  142. case OPCODE_UPDATE:
  143. session.setAttribute("state", STATE_CRC);
  144. return true;
  145. default:
  146. logger.info("Invalid opcode : " + opcode);
  147. session.close(false);
  148. break;
  149. }
  150. } else {
  151. in.rewind();
  152. return false;
  153. }
  154. break;
  155. case STATE_PRECRYPTED:
  156. if(in.remaining() >= 2) {
  157. int loginOpcode = in.get() & 0xFF;
  158. if(loginOpcode != 16 && loginOpcode != 18) {
  159. logger.info("Invalid login opcode : " + loginOpcode);
  160. session.close(false);
  161. in.rewind();
  162. return false;
  163. }
  164. int loginSize = in.get() & 0xFF;
  165. int loginEncryptSize = loginSize - (36 + 1 + 1 + 2);
  166. session.setAttribute("state", STATE_CRYPTED);
  167. session.setAttribute("size", loginSize);
  168. session.setAttribute("encryptSize", loginEncryptSize);
  169. return true;
  170. }
  171. break;
  172. case STATE_CRYPTED:
  173. int size = (Integer) session.getAttribute("size");
  174. int encryptSize = (Integer) session.getAttribute("encryptSize");
  175. if(in.remaining() >= size) {
  176. int version = in.getInt();
  177. if(version != Server.VERSION) {
  178. logger.info("Incorrect version : " + version);
  179. session.close(false);
  180. in.rewind();
  181. return false;
  182. }
  183. in.get();
  184. in.get();
  185. for(int i = 0; i < 16; i++) {
  186. in.getInt();
  187. }
  188. int blockOpcode = in.get() & 0xFF;
  189. if(blockOpcode != 10) {
  190. logger.info("Invalid login block opcode : " + blockOpcode);
  191. session.close(false);
  192. in.rewind();
  193. return false;
  194. }
  195. int[] sessionKey = new int[4];
  196. for(int i = 0; i < 4; i++) {
  197. sessionKey[i] = in.getInt();
  198. }
  199. int uid = in.getInt();
  200. logger.info("Size: "+in.remaining());
  201. String name = NameUtils.formatName(NameUtils.longToName(in.getLong()));
  202. String pass = IoBufferUtils.getRS2String(in).trim();
  203. logger.info("Login request : username=" + name + " password=" + pass);
  204. session.removeAttribute("state");
  205. session.removeAttribute("serverKey");
  206. session.removeAttribute("size");
  207. session.removeAttribute("encryptSize");
  208. ISAACCipher inCipher = new ISAACCipher(sessionKey);
  209. for(int i = 0; i < 4; i++) {
  210. sessionKey[i] += 50;
  211. }
  212. ISAACCipher outCipher = new ISAACCipher(sessionKey);
  213.  
  214. session.getFilterChain().remove("protocol");
  215. session.getFilterChain().addFirst("protocol", new ProtocolCodecFilter(RS2CodecFactory.GAME));
  216. PlayerDetails pd = new PlayerDetails(session, name, pass, 0, inCipher, outCipher);
  217. World.getWorld().load(pd);
  218. }
  219. break;
  220. }
  221. in.rewind();
  222. return false;
  223. }
  224. }
  225. private static class Request {
  226.  
  227. private int cache;
  228. private int id;
  229.  
  230. public Request(int cache, int id) {
  231. this.cache = cache;
  232. this.id = id;
  233. }
  234.  
  235. public int getCache() {
  236. return cache;
  237. }
  238.  
  239. public int getId() {
  240. return id;
  241. }
  242. }
  243. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement