Advertisement
Guest User

Untitled

a guest
Jun 10th, 2017
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.17 KB | None | 0 0
  1. package com.rs2hd.net.codec;
  2.  
  3. import org.apache.mina.common.ByteBuffer;
  4. import org.apache.mina.common.IdleStatus;
  5. import org.apache.mina.common.IoFuture;
  6. import org.apache.mina.common.IoFutureListener;
  7. import org.apache.mina.common.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.  
  12. import com.rs2hd.Constants;
  13. import com.rs2hd.WorkerThread;
  14. import com.rs2hd.model.PlayerDetails;
  15. import com.rs2hd.net.Packet;
  16. import com.rs2hd.packetbuilder.StaticPacketBuilder;
  17. import com.rs2hd.util.Misc;
  18. import com.rs2hd.util.log.Logger;
  19.  
  20. /**
  21. * Login protocol decoder.
  22. * @author Graham
  23. *
  24. */
  25. public class RS2LoginProtocolDecoder extends CumulativeProtocolDecoder {
  26.  
  27. /**
  28. * Logger instance.
  29. */
  30. private Logger logger = Logger.getInstance();
  31.  
  32. private WorkerThread workerThread;
  33.  
  34. public RS2LoginProtocolDecoder(WorkerThread workerThread) {
  35. this.workerThread = workerThread;
  36. }
  37.  
  38. /**
  39. * Parses the data in the provided byte buffer and writes it to
  40. * <code>out</code> as a <code>Packet</code>.
  41. *
  42. * @param session The IoSession the data was read from
  43. * @param in The buffer
  44. * @param out The decoder output stream to which to write the <code>Packet</code>
  45. * @return Whether enough data was available to create a packet
  46. */
  47. @Override
  48. public boolean doDecode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) {
  49. try {
  50. Object loginStageObj = session.getAttribute("LOGIN_STAGE");
  51. int loginStage = 0;
  52. if(loginStageObj != null) {
  53. loginStage = (Integer)loginStageObj;
  54. }
  55. switch(loginStage) {
  56. case -3:
  57. if (in.remaining() >= 4) {
  58. final int loginOpcode = in.getInt();
  59. logger.info("Loginopcode " + loginOpcode);
  60. if (loginOpcode == 0) {
  61. session.write(RS2WorldListEncoder.encode(true, true));
  62. } else {
  63. session.write(RS2WorldListEncoder.encode(false, true));
  64. }
  65. return true;
  66. }
  67. in.rewind();
  68. break;
  69. case -2:
  70. if(8 <= in.remaining()) {
  71. for(int i = 0; i < 8; i++) {
  72. in.get();
  73. }
  74. StaticPacketBuilder ukeys = new StaticPacketBuilder();
  75. ukeys.setBare(true);
  76. for(int key : Constants.UPDATE_KEYS) {
  77. ukeys.addByte((byte) key);
  78. }
  79. session.write(ukeys.toPacket()).addListener(new IoFutureListener() {
  80. @Override
  81. public void operationComplete(IoFuture arg0) {
  82. arg0.getSession().close();
  83. }
  84. });
  85. return true;
  86. }
  87. in.rewind();
  88. return false;
  89. case -1:
  90. if(3 <= in.remaining()) {
  91. int clientVersion = in.getInt();
  92. if(clientVersion == 525) {
  93. StaticPacketBuilder u1Response = new StaticPacketBuilder();
  94. u1Response.setBare(true).addByte((byte) 0);
  95. session.write(u1Response.toPacket());
  96. session.setAttribute("LOGIN_STAGE", -2);
  97. } else {
  98. StaticPacketBuilder u1Response = new StaticPacketBuilder();
  99. u1Response.setBare(true).addByte((byte) 6);
  100. session.write(u1Response.toPacket()).addListener(new IoFutureListener() {
  101. @Override
  102. public void operationComplete(IoFuture arg0) {
  103. arg0.getSession().close();
  104. }
  105. });
  106. session.removeAttribute("LOGIN_STAGE");
  107. }
  108. return true;
  109. }
  110. in.rewind();
  111. return false;
  112. case 0: //first login packets
  113. if(2 <= in.remaining()) {
  114. int protocolId = in.get() & 0xff;
  115. if(protocolId == 15) {
  116. session.setAttribute("LOGIN_STAGE", -1);
  117. } else if (protocolId == 131) {
  118. session.setAttribute("LOGIN_STAGE", -3);
  119. } else {
  120. int nameHash = in.get() & 0xff;
  121. long serverSessionKey = ((long) (java.lang.Math.random() * 99999999D) << 32) + (long) (java.lang.Math.random() * 99999999D);
  122. StaticPacketBuilder s1Response = new StaticPacketBuilder();
  123. s1Response.setBare(true).addByte((byte) 0).addLong(serverSessionKey);
  124. session.setAttribute("SERVER_SESSION_KEY", serverSessionKey);
  125. session.write(s1Response.toPacket());
  126. session.setAttribute("LOGIN_STAGE", 1);
  127. session.setAttribute("NAME_HASH", nameHash);
  128. //Logger.log("protocolId="+protocolId+"; namePart="+namePart);
  129. logger.info("Protocol id " + protocolId);
  130. }
  131. return true;
  132. } else {
  133. in.rewind();
  134. return false;
  135. }
  136. case 1: //here's where we get the username and password
  137. @SuppressWarnings("unused")
  138. int loginType = -1, loginPacketSize = -1;
  139. if(3 <= in.remaining()) {
  140. loginType = in.get() & 0xff; //should be 16 or 18
  141. loginPacketSize = in.getUnsignedShort();
  142. //Logger.log("loginType="+loginType);
  143. } else {
  144. in.rewind();
  145. return false;
  146. }
  147. if(loginPacketSize <= in.remaining()) {
  148. byte[] payload = new byte[loginPacketSize];
  149. in.get(payload);
  150. Packet p = new Packet(session, -1, payload);
  151. @SuppressWarnings("unused")
  152. int loginEncryptPacketSize = loginPacketSize - (36 + 1 + 1 + 2); // can't be negative
  153. int clientVersion = p.readInt();
  154. if(clientVersion != 525) {
  155. Logger.getInstance().error("Invalid ver : " + clientVersion);
  156. session.close();
  157. return true;
  158. }
  159. in.get();
  160. boolean memoryVersion = (p.readByte() & 0xff) == 1 ? true : false;
  161. boolean hd = p.readByte() == 1 ? true : false;
  162. boolean resized = p.readByte() == 1 ? true : false;
  163. short width = p.readShort();
  164. short height = p.readShort();
  165. Logger.getInstance().info("HD: " + hd + " Resized: " + resized + " Width: " + width + " Height: " + height
  166. + " Memory version " + memoryVersion);
  167. in.get();
  168. for (int i = 0; i < 24; i ++) {
  169. in.get();
  170. }
  171. p.readRS2String();
  172. in.getInt();
  173. in.getInt();
  174. in.getShort();
  175. for (int i = 0; i < 28; i++ ) {
  176. in.getInt();
  177. }
  178. int blockOpcode = p.readByte() & 0xff; //hopefully same as (--loginEncryptPacketSize)
  179. if(blockOpcode != 10) {
  180. logger.info("Invalid login block opcode : " + blockOpcode);
  181. in.rewind();
  182. return false;
  183. }
  184. long clientSessionKey = p.readLong();
  185. long serverSessionKey = p.readLong();
  186. //int uid = p.readInt(); //unique identifier for this session i think ?
  187. long l = p.readLong();
  188. int hash = (int) (31 & l >> 16);
  189. if(hash != (Integer) session.getAttribute("NAME_HASH")) {
  190. // invalid name hash (possibly a bot attacking)
  191. session.close();
  192. return true;
  193. }
  194. String user = Misc.longToPlayerName(l), //given username
  195. pass = p.readRS2String(); //given password
  196.  
  197. int sessionKey[] = new int[4];
  198. sessionKey[0] = (int)(clientSessionKey >> 32);
  199. sessionKey[1] = (int)clientSessionKey;
  200. sessionKey[2] = (int)(serverSessionKey >> 32);
  201. sessionKey[3] = (int)serverSessionKey;
  202.  
  203. // set in ISAAC
  204. for(int i = 0; i < 4; i++) sessionKey[i] += 50;
  205. // set out ISAAC
  206.  
  207. session.removeAttribute("LOGIN_STAGE");
  208. session.removeAttribute("NAME_HASH");
  209.  
  210. /**
  211. * Here's where we add the user to the login queue, and if the login is
  212. * accepted, we change their session filter to a standard RS2ProtocolCodec.
  213. */
  214. logger.debug("Login request: [username="+user+",password="+pass+"].");
  215.  
  216. PlayerDetails d = new PlayerDetails(user, pass, session, hd);
  217. workerThread.loadPlayer(d);
  218.  
  219. session.setIdleTime(IdleStatus.BOTH_IDLE, Constants.SESSION_IDLE_TIME);
  220.  
  221. session.getFilterChain().remove("protocolFilter");
  222. session.getFilterChain().addLast("protocolFilter", new ProtocolCodecFilter(new CodecFactory()));
  223.  
  224. return true;
  225. } else {
  226. in.rewind();
  227. return false;
  228. }
  229. }
  230. } catch(Exception e) {
  231. //logger.stackTrace(e);
  232. }
  233. return false;
  234. }
  235.  
  236.  
  237. /**
  238. * Releases the buffer used by the given session.
  239. *
  240. * @param session The session for which to release the buffer
  241. * @throws Exception if failed to dispose all resources
  242. */
  243. @Override
  244. public void dispose(IoSession session) throws Exception {
  245. super.dispose(session);
  246. }
  247.  
  248. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement