Advertisement
Guest User

Untitled

a guest
Jun 20th, 2017
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.22 KB | None | 0 0
  1. package aphrodite.rs357e.net.codec;
  2.  
  3. import java.security.SecureRandom;
  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.ProtocolDecoderOutput;
  10.  
  11. import aphrodite.rs357e.net.stream.OutStream;
  12. import aphrodite.rs357e.util.BufferUtils;
  13.  
  14. /**
  15. *
  16. * @author Karl
  17. *
  18. */
  19. public class RS2LoginDecoder extends CumulativeProtocolDecoder {
  20.  
  21. /**
  22. * Represents the login state.
  23. * @author Karl
  24. *
  25. */
  26. public enum State {
  27. REQUEST_TYPE, SESSION_INFORMATION;
  28. }
  29.  
  30. /**
  31. * The logger instance.
  32. */
  33. private static final Logger logger = Logger.getLogger(RS2LoginDecoder.class.getName());
  34.  
  35. /**
  36. * The secure randomiser.
  37. */
  38. private SecureRandom random = new SecureRandom();
  39.  
  40. /**
  41. * The login state.
  42. */
  43. private State state = State.REQUEST_TYPE;
  44.  
  45. /**
  46. * The server key.
  47. */
  48. private long serverKey = random.nextLong();
  49.  
  50. /**
  51. * The initial response.
  52. */
  53. private static final byte[] INITIAL_RESPONSE = new byte[] {
  54. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
  55. };
  56.  
  57. /**
  58. * The login size.
  59. */
  60. private int loginSize;
  61.  
  62. /**
  63. * The encrypted size.
  64. */
  65. private int encrypted;
  66.  
  67. @Override
  68. protected boolean doDecode(IoSession session, IoBuffer buffer,
  69. ProtocolDecoderOutput out) throws Exception {
  70. switch(state) {
  71. case REQUEST_TYPE:
  72. /*
  73. * The response.
  74. */
  75. byte response = 0;
  76. if(buffer.remaining() >= 2) {
  77. /*
  78. * If the buffer has 2 or more bytes remaining check the game opcode. (14)
  79. */
  80. int request = buffer.get() & 0xFF;
  81. if(request != 14) {
  82. logger.warning("Invalid request type: "+request+".");
  83. session.close(false);
  84. return true;
  85. }
  86.  
  87. /*
  88. * Read the name hash although it is unused.
  89. */
  90. @SuppressWarnings("unused")
  91. int nameHash = buffer.get() & 0xFF;
  92. OutStream outStream = new OutStream();
  93. /*
  94. * Writes the initial response.
  95. */
  96. outStream.put(INITIAL_RESPONSE);
  97. outStream.put(response);
  98. outStream.putLong(serverKey);
  99. /*
  100. * Writes the initial response to the stream.
  101. */
  102. session.write(outStream.toStream());
  103. /*
  104. * Checks if the response is not equal to 0.
  105. */
  106. if(response != 0) {
  107. logger.warning("Invalid response: "+response+"");
  108. session.close(false);
  109. return true;
  110. }
  111. buffer.rewind();
  112. state = State.SESSION_INFORMATION;
  113. }
  114. break;
  115. case SESSION_INFORMATION:
  116. logger.info("Test!");
  117. if(buffer.remaining() >= 2) {
  118. /*
  119. * Checks the connection type.
  120. */
  121. int connectionType = buffer.get() & 0xFF;
  122. @SuppressWarnings("unused")
  123. boolean reconnecting = connectionType == 18;
  124. if(connectionType != 16 && connectionType != 18) {
  125. logger.warning("Invalid connection type: "+connectionType+".");
  126. session.close(false);
  127. return true;
  128. }
  129. /*
  130. * Read the login size.
  131. */
  132. loginSize = buffer.get() & 0xFF;
  133. encrypted = loginSize - 40;
  134. /*
  135. * Check if the encrypted packet size is equal to or less then 0.
  136. */
  137. if(encrypted <= 0) {
  138. logger.warning("Invalid encrypted packet size: "+encrypted+".");
  139. session.close(false);
  140. return true;
  141. }
  142. } else {
  143. buffer.rewind();
  144. return false;
  145. }
  146. if(buffer.remaining() >= loginSize) {
  147. /*
  148. * Check if the login packet is equal to 255.
  149. */
  150. boolean loginPacket = buffer.getUnsigned() == 255;
  151. if(!loginPacket) {
  152. logger.warning("Invalid login packet: "+loginPacket+".");
  153. session.close(false);
  154. return true;
  155. }
  156. /*
  157. * Check if the client version is equal to the servers version.
  158. */
  159. short clientVersion = buffer.getShort();
  160. if(clientVersion != 357) {
  161. logger.warning("Invalid client version: "+clientVersion+".");
  162. session.close(false);
  163. return true;
  164. }
  165. /*
  166. * Check if the player is playing in low memory.
  167. */
  168. @SuppressWarnings("unused")
  169. boolean lowMemmory = buffer.get() == 1;
  170. /*
  171. * Read the crc values.
  172. */
  173. for(int i = 0; i < 9; i++) {
  174. buffer.getInt();
  175. }
  176. encrypted--;
  177. /*
  178. * Check if the encrypted size is equal to a byte.
  179. */
  180. if(buffer.get() != encrypted) {
  181. logger.warning("Invalid encrypted size: "+encrypted+".");
  182. session.close(false);
  183. return true;
  184. }
  185. /*
  186. * Read the rsa opcode; although in most old engine clients the rsa
  187. * has been disabled.
  188. */
  189. byte rsaOpcode = buffer.get();
  190. if(rsaOpcode != 10) {
  191. logger.warning("Invalid rsa opcode: "+rsaOpcode+".");
  192. session.close(false);
  193. return true;
  194. }
  195. /*
  196. * Retrieve the session keys.
  197. */
  198. long clientKey = buffer.getLong();
  199. long reportedKey = buffer.getLong();
  200. /*
  201. * Check if the server key is equal to the reported key.
  202. * Else close the session.
  203. */
  204. if(serverKey != reportedKey) {
  205. logger.warning("Invalid server key or reported key: server key: "+serverKey+"" +
  206. "reported key: "+reportedKey+".");
  207. session.close(false);
  208. return true;
  209. }
  210. /*
  211. * Get the players unique id.
  212. */
  213. @SuppressWarnings("unused")
  214. int uid = buffer.getInt();
  215. /*
  216. * Gets the players username and password.
  217. */
  218. String username = BufferUtils.getRS2String(buffer);
  219. String password = BufferUtils.getRS2String(buffer);
  220. logger.info("Registered player: [username: "+username+" password: "+password+"]");
  221. /*
  222. * The isaacSeed.
  223. */
  224. int[] isaacSeed = new int[4];
  225. isaacSeed[0] = (int) (clientKey >> 32);
  226. isaacSeed[1] = (int) clientKey;
  227. isaacSeed[2] = (int) (serverKey >> 32);
  228. isaacSeed[3] = (int) serverKey;
  229. for(int i = 0; i < 4; i++) {
  230. isaacSeed[i] += 50;
  231. }
  232. /*
  233. * Writes the login response.
  234. */
  235. OutStream resp = new OutStream();
  236. resp.put((byte) 2);
  237. resp.put((byte) 2);
  238. resp.put((byte) 0);
  239. /*
  240. * Writes the login response to the stream.
  241. */
  242. session.write(resp.toStream());
  243. return true;
  244. } else {
  245. return false;
  246. }
  247. }
  248. return false;
  249. }
  250. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement