Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package org.extinal.net.codec;
- import org.extinal.util.Logger.Level;
- import org.extinal.util.Logger;
- import java.io.IOException;
- import org.extinal.net.PacketBuilder;
- import org.extinal.util.Constants;
- import org.extinal.util.NameUtility;
- import org.extinal.util.TextUtility;
- import org.jboss.netty.buffer.ChannelBuffer;
- import org.jboss.netty.channel.Channel;
- import org.jboss.netty.channel.ChannelHandlerContext;
- import org.jboss.netty.handler.codec.replay.ReplayingDecoder;
- import static org.extinal.net.codec.LoginDecoder.State;
- /**
- * Decodes the logins sent from various clients - Cache loading and handling is
- * written by Graham Edgecombe, I don't know too much on the subject right now
- *
- * @author smokey
- */
- public class LoginDecoder extends ReplayingDecoder<State> {
- /**
- * The login states
- */
- public enum State {
- READ_OPCODE, UPDATE, LOGIN, HEADER, FINALIZE;
- };
- /**
- * The initial response for the client
- */
- public byte[] INITIAL_RESPONSE = {
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
- };
- /**
- * Random server key and blank client key.
- */
- public long serverKey = (long) (Math.random() * 9.99999999D),
- clientKey;
- /**
- * The logger instance
- */
- private static final Logger logger = Logger
- .getLogger(LoginDecoder.class.getName());
- /**
- * Set the state
- */
- public LoginDecoder() {
- super(State.HEADER);
- }
- /**
- * The encrypted login size. This is only a field outside the decode
- * method because we don't want the size being set after every state..
- */
- public int encryptSize = -1;
- @Override
- protected Object decode(ChannelHandlerContext ctx,
- final Channel channel, ChannelBuffer buffer,
- State state) throws Exception {
- if (buffer.readableBytes() < 4) {
- return null;
- }
- buffer.markReaderIndex();
- int length = buffer.readInt();
- if (buffer.readableBytes() < length) {
- buffer.resetReaderIndex();
- return null;
- }
- switch (state) {
- case HEADER:
- int opcode = buffer.readUnsignedByte();
- int nameHash = buffer
- .readUnsignedByte();
- PacketBuilder pb = new PacketBuilder();
- pb.addByte(0);
- pb.addLong(serverKey);
- checkpoint(State.FINALIZE);
- return pb;
- case FINALIZE:
- int loginOpcode = buffer
- .readUnsignedByte();
- if (loginOpcode != 16
- && loginOpcode != 18) {
- throw new IOException(
- "Invalid login opcode: "
- + loginOpcode);
- }
- int loginSize = buffer
- .readUnsignedByte();
- int loginEncryptSize = loginSize
- - (36 + 1 + 1 + 2);
- if (loginEncryptSize <= 0) {
- throw new IOException(
- "Invalid login size: "
- + loginSize
- + ", expected "
- + 39);
- }
- encryptSize = loginEncryptSize;
- checkpoint(State.LOGIN);
- return buffer;
- case LOGIN:
- int magicId = buffer.readUnsignedByte();
- int revision = buffer
- .readUnsignedShort();
- if (magicId != 255
- || revision != Constants.REVISION) {
- throw new IOException(
- "Incorrect magicId or revision: ("
- + magicId
- + ", "
- + revision
- + ")");
- }
- int memory = buffer.readUnsignedByte();
- for (int i = 0; i < 9; i++) {
- buffer.readInt();
- }
- encryptSize--;
- int reportedSize = buffer
- .readUnsignedByte();
- if (reportedSize != encryptSize) {
- throw new IOException(
- "Encrypted login size mismatch: "
- + reportedSize
- + ", expected: "
- + encryptSize);
- }
- int blockOpcode = buffer
- .readUnsignedByte();
- if (blockOpcode != 10) {
- throw new IOException(
- "Invalid block opcode: "
- + blockOpcode);
- }
- clientKey = buffer.readLong();
- long reportedServerKey = buffer
- .readLong();
- if (reportedServerKey != serverKey) {
- throw new IOException(
- "Server key mismatch! Reported: "
- + reportedServerKey
- + ", Expected: "
- + serverKey);
- }
- int uid = buffer.readInt();
- String username = NameUtility
- .formatName(TextUtility
- .readString(buffer));
- String password = TextUtility
- .readString(buffer);
- logger.log(Level.INFO,
- "Login request: "
- + username);
- int[] sessionKey = new int[4];
- sessionKey[0] = (int) (clientKey >> 32);
- sessionKey[1] = (int) clientKey;
- sessionKey[2] = (int) (serverKey >> 32);
- sessionKey[3] = (int) serverKey;
- ISAACAlgorithm in = new ISAACAlgorithm(
- sessionKey);
- for (int i = 0; i < 4; i++) {
- sessionKey[i] += 50;
- }
- ISAACAlgorithm out = new ISAACAlgorithm(
- sessionKey);
- channel.getPipeline()
- .addFirst("PacketDecoder",
- new PacketDecoder());
- channel.getPipeline()
- .addFirst("PacketEncoder",
- new PacketEncoder());
- channel.getPipeline().remove(this);
- return buffer;
- }
- return null;
- }
- }
Add Comment
Please, Sign In to add comment