Advertisement
Guest User

Untitled

a guest
May 11th, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.98 KB | None | 0 0
  1. package com.arlania.net.login;
  2.  
  3. import java.math.BigInteger;
  4. import java.net.InetSocketAddress;
  5. import java.security.SecureRandom;
  6.  
  7. import org.jboss.netty.buffer.ChannelBuffer;
  8. import org.jboss.netty.buffer.ChannelBuffers;
  9. import org.jboss.netty.channel.Channel;
  10. import org.jboss.netty.channel.ChannelFuture;
  11. import org.jboss.netty.channel.ChannelFutureListener;
  12. import org.jboss.netty.channel.ChannelHandlerContext;
  13. import org.jboss.netty.handler.codec.frame.FrameDecoder;
  14.  
  15. import com.arlania.GameSettings;
  16. import com.arlania.net.PlayerSession;
  17. import com.arlania.net.packet.PacketBuilder;
  18. import com.arlania.net.packet.codec.PacketDecoder;
  19. import com.arlania.net.packet.codec.PacketEncoder;
  20. import com.arlania.net.security.IsaacRandom;
  21. import com.arlania.util.Misc;
  22. import com.arlania.util.NameUtils;
  23. import com.arlania.world.World;
  24. import com.arlania.world.entity.impl.player.Player;
  25.  
  26. /**
  27. * A {@link org.niobe.net.StatefulFrameDecoder} which decodes
  28. * the login requests.
  29. *
  30. * @author Gabriel Hannason
  31. */
  32. public final class LoginDecoder extends FrameDecoder {
  33.  
  34. private static final int CONNECTED = 0;
  35. private static final int LOGGING_IN = 1;
  36. private int state = CONNECTED;
  37. private long seed;
  38.  
  39. @Override
  40. protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
  41. if(!channel.isConnected()) {
  42. return null;
  43. }
  44. switch (state) {
  45. case CONNECTED:
  46. if (buffer.readableBytes() < 2) {
  47. return null;
  48. }
  49. int request = buffer.readUnsignedByte();
  50. if (request != 14) {
  51. System.out.println("Invalid login request: " + request);
  52. channel.close();
  53. return null;
  54. }
  55. buffer.readUnsignedByte();
  56. seed = new SecureRandom().nextLong();
  57. channel.write(new PacketBuilder().putLong(0).put((byte) 0).putLong(seed).toPacket());
  58. state = LOGGING_IN;
  59. return null;
  60. case LOGGING_IN:
  61. if (buffer.readableBytes() < 2) {
  62. System.out.println("no readable bytes");
  63. return null;
  64. }
  65. int loginType = buffer.readByte();
  66. if (loginType != 16 && loginType != 18) {
  67. System.out.println("Invalid login type: " + loginType);
  68. channel.close();
  69. return null;
  70. }
  71. int blockLength = buffer.readByte() & 0xff;
  72. if (buffer.readableBytes() < blockLength) {
  73. channel.close();
  74. return null;
  75. }
  76. int magicId = buffer.readUnsignedByte();
  77. if(magicId != 0xFF) {
  78. System.out.println("Invalid magic id");
  79. channel.close();
  80. return null;
  81. }
  82. int clientVersion = buffer.readShort();
  83. int memory = buffer.readByte();
  84. if (memory != 0 && memory != 1) {
  85. System.out.println("Unhandled memory byte value");
  86. channel.close();
  87. return null;
  88. }
  89. int[] archiveCrcs = new int[9];
  90. for (int i = 0; i < 9; i++) {
  91. archiveCrcs[i] = buffer.readInt();
  92. }
  93. int length = buffer.readUnsignedByte();
  94. /**
  95. * Our RSA components.
  96. */
  97. ChannelBuffer rsaBuffer = buffer.readBytes(length);
  98. BigInteger bigInteger = new BigInteger(rsaBuffer.array());
  99. bigInteger = bigInteger.modPow(GameSettings.RSA_EXPONENT, GameSettings.RSA_MODULUS);
  100. rsaBuffer = ChannelBuffers.wrappedBuffer(bigInteger.toByteArray());
  101. int securityId = rsaBuffer.readByte();
  102. if(securityId != 10) {
  103. //System.out.println("securityId id != 10.");
  104. channel.close();
  105. return null;
  106. }
  107. long clientSeed = rsaBuffer.readLong();
  108. long seedReceived = rsaBuffer.readLong();
  109. if (seedReceived != seed) {
  110. //System.out.println("Unhandled seed read: [seed, seedReceived] : [" + seed + ", " + seedReceived + "]");
  111. channel.close();
  112. return null;
  113. }
  114. int[] seed = new int[4];
  115. seed[0] = (int) (clientSeed >> 32);
  116. seed[1] = (int) clientSeed;
  117. seed[2] = (int) (this.seed >> 32);
  118. seed[3] = (int) this.seed;
  119. IsaacRandom decodingRandom = new IsaacRandom(seed);
  120. for (int i = 0; i < seed.length; i++) {
  121. seed[i] += 50;
  122. }
  123. int uid = rsaBuffer.readInt();
  124. String username = Misc.readString(rsaBuffer);
  125. String password = Misc.readString(rsaBuffer);
  126. String serial = Misc.readString(rsaBuffer);
  127. if (username.length() > 12 || password.length() > 20) {
  128. System.out.println("Username or password length too long");
  129. return null;
  130. }
  131. username = Misc.formatText(username.toLowerCase());
  132. channel.getPipeline().replace("encoder", "encoder", new PacketEncoder(new IsaacRandom(seed)));
  133. channel.getPipeline().replace("decoder", "decoder", new PacketDecoder(decodingRandom));
  134. return login(channel, new LoginDetailsMessage(username, password, ((InetSocketAddress) channel.getRemoteAddress()).getAddress().getHostAddress(), serial, clientVersion, uid));
  135. }
  136. return null;
  137. }
  138.  
  139. public Player login(Channel channel, LoginDetailsMessage msg) {
  140.  
  141. PlayerSession session = new PlayerSession(channel);
  142.  
  143. Player player = new Player(session).setUsername(msg.getUsername())
  144. .setLongUsername(NameUtils.stringToLong(msg.getUsername()))
  145. .setPassword(msg.getPassword())
  146. .setHostAddress(msg.getHost())
  147. .setSerialNumber(msg.getSerialNumber());
  148.  
  149. session.setPlayer(player);
  150.  
  151. int response = LoginResponses.getResponse(player, msg);
  152.  
  153. final boolean newAccount = response == LoginResponses.NEW_ACCOUNT;
  154. if(newAccount) {
  155. player.setNewPlayer(true);
  156. response = LoginResponses.LOGIN_SUCCESSFUL;
  157. }
  158.  
  159. if (response == LoginResponses.LOGIN_SUCCESSFUL) {
  160. channel.write(new PacketBuilder().put((byte)2).put((byte)player.getRights().ordinal()).put((byte)0).toPacket());
  161.  
  162. if(!World.getLoginQueue().contains(player)) {
  163. World.getLoginQueue().add(player);
  164. }
  165.  
  166. return player;
  167. } else {
  168. sendReturnCode(channel, response);
  169. return null;
  170. }
  171. }
  172.  
  173. public static void sendReturnCode(final Channel channel, final int code) {
  174. channel.write(new PacketBuilder().put((byte) code).toPacket()).addListener(new ChannelFutureListener() {
  175. @Override
  176. public void operationComplete(final ChannelFuture arg0) throws Exception {
  177. arg0.getChannel().close();
  178. }
  179. });
  180. }
  181.  
  182. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement