Guest User

Untitled

a guest
Jan 23rd, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.10 KB | None | 0 0
  1.  
  2. package org.extinal.net.codec;
  3.  
  4. import org.extinal.util.Logger.Level;
  5. import org.extinal.util.Logger;
  6. import java.io.IOException;
  7. import org.extinal.net.PacketBuilder;
  8. import org.extinal.util.Constants;
  9. import org.extinal.util.NameUtility;
  10. import org.extinal.util.TextUtility;
  11. import org.jboss.netty.buffer.ChannelBuffer;
  12. import org.jboss.netty.channel.Channel;
  13. import org.jboss.netty.channel.ChannelHandlerContext;
  14. import org.jboss.netty.handler.codec.replay.ReplayingDecoder;
  15.  
  16. import static org.extinal.net.codec.LoginDecoder.State;
  17.  
  18. /**
  19. * Decodes the logins sent from various clients - Cache loading and handling is
  20. * written by Graham Edgecombe, I don't know too much on the subject right now
  21. *
  22. * @author smokey
  23. */
  24. public class LoginDecoder extends ReplayingDecoder<State> {
  25.  
  26. /**
  27. * The login states
  28. */
  29. public enum State {
  30.  
  31. READ_OPCODE, UPDATE, LOGIN, HEADER, FINALIZE;
  32. };
  33.  
  34. /**
  35. * The initial response for the client
  36. */
  37. public byte[] INITIAL_RESPONSE = {
  38. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
  39. };
  40.  
  41. /**
  42. * Random server key and blank client key.
  43. */
  44. public long serverKey = (long) (Math.random() * 9.99999999D),
  45. clientKey;
  46. /**
  47. * The logger instance
  48. */
  49. private static final Logger logger = Logger
  50. .getLogger(LoginDecoder.class.getName());
  51.  
  52. /**
  53. * Set the state
  54. */
  55. public LoginDecoder() {
  56.  
  57. super(State.HEADER);
  58. }
  59.  
  60. /**
  61. * The encrypted login size. This is only a field outside the decode
  62. * method because we don't want the size being set after every state..
  63. */
  64. public int encryptSize = -1;
  65.  
  66. @Override
  67. protected Object decode(ChannelHandlerContext ctx,
  68. final Channel channel, ChannelBuffer buffer,
  69. State state) throws Exception {
  70.  
  71. if (buffer.readableBytes() < 4) {
  72. return null;
  73. }
  74. buffer.markReaderIndex();
  75. int length = buffer.readInt();
  76. if (buffer.readableBytes() < length) {
  77. buffer.resetReaderIndex();
  78. return null;
  79. }
  80.  
  81. switch (state) {
  82.  
  83. case HEADER:
  84. int opcode = buffer.readUnsignedByte();
  85. int nameHash = buffer
  86. .readUnsignedByte();
  87. PacketBuilder pb = new PacketBuilder();
  88. pb.addByte(0);
  89. pb.addLong(serverKey);
  90. checkpoint(State.FINALIZE);
  91. return pb;
  92.  
  93. case FINALIZE:
  94.  
  95. int loginOpcode = buffer
  96. .readUnsignedByte();
  97.  
  98. if (loginOpcode != 16
  99. && loginOpcode != 18) {
  100. throw new IOException(
  101. "Invalid login opcode: "
  102. + loginOpcode);
  103. }
  104.  
  105. int loginSize = buffer
  106. .readUnsignedByte();
  107. int loginEncryptSize = loginSize
  108. - (36 + 1 + 1 + 2);
  109.  
  110. if (loginEncryptSize <= 0) {
  111. throw new IOException(
  112. "Invalid login size: "
  113. + loginSize
  114. + ", expected "
  115. + 39);
  116. }
  117.  
  118. encryptSize = loginEncryptSize;
  119.  
  120. checkpoint(State.LOGIN);
  121. return buffer;
  122.  
  123. case LOGIN:
  124.  
  125. int magicId = buffer.readUnsignedByte();
  126. int revision = buffer
  127. .readUnsignedShort();
  128.  
  129. if (magicId != 255
  130. || revision != Constants.REVISION) {
  131. throw new IOException(
  132. "Incorrect magicId or revision: ("
  133. + magicId
  134. + ", "
  135. + revision
  136. + ")");
  137. }
  138.  
  139. int memory = buffer.readUnsignedByte();
  140.  
  141. for (int i = 0; i < 9; i++) {
  142. buffer.readInt();
  143. }
  144.  
  145. encryptSize--;
  146. int reportedSize = buffer
  147. .readUnsignedByte();
  148. if (reportedSize != encryptSize) {
  149. throw new IOException(
  150. "Encrypted login size mismatch: "
  151. + reportedSize
  152. + ", expected: "
  153. + encryptSize);
  154. }
  155.  
  156. int blockOpcode = buffer
  157. .readUnsignedByte();
  158. if (blockOpcode != 10) {
  159. throw new IOException(
  160. "Invalid block opcode: "
  161. + blockOpcode);
  162. }
  163.  
  164. clientKey = buffer.readLong();
  165. long reportedServerKey = buffer
  166. .readLong();
  167. if (reportedServerKey != serverKey) {
  168. throw new IOException(
  169. "Server key mismatch! Reported: "
  170. + reportedServerKey
  171. + ", Expected: "
  172. + serverKey);
  173. }
  174.  
  175. int uid = buffer.readInt();
  176.  
  177. String username = NameUtility
  178. .formatName(TextUtility
  179. .readString(buffer));
  180. String password = TextUtility
  181. .readString(buffer);
  182.  
  183. logger.log(Level.INFO,
  184. "Login request: "
  185. + username);
  186. int[] sessionKey = new int[4];
  187. sessionKey[0] = (int) (clientKey >> 32);
  188. sessionKey[1] = (int) clientKey;
  189. sessionKey[2] = (int) (serverKey >> 32);
  190. sessionKey[3] = (int) serverKey;
  191.  
  192. ISAACAlgorithm in = new ISAACAlgorithm(
  193. sessionKey);
  194. for (int i = 0; i < 4; i++) {
  195. sessionKey[i] += 50;
  196. }
  197. ISAACAlgorithm out = new ISAACAlgorithm(
  198. sessionKey);
  199.  
  200. channel.getPipeline()
  201. .addFirst("PacketDecoder",
  202. new PacketDecoder());
  203. channel.getPipeline()
  204. .addFirst("PacketEncoder",
  205. new PacketEncoder());
  206. channel.getPipeline().remove(this);
  207. return buffer;
  208. }
  209. return null;
  210. }
  211. }
Add Comment
Please, Sign In to add comment