diff --git a/data/script/template/script/template/character/AbstractCharacterTemplate.java b/data/script/template/script/template/character/AbstractCharacterTemplate.java index b14817c13..c349095d6 100644 --- a/data/script/template/script/template/character/AbstractCharacterTemplate.java +++ b/data/script/template/script/template/character/AbstractCharacterTemplate.java @@ -6,7 +6,7 @@ import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.character.CharacterClass; import com.l2jserver.util.Coordinate; -public class AbstractCharacterTemplate extends CharacterTemplate { +public abstract class AbstractCharacterTemplate extends CharacterTemplate { protected AbstractCharacterTemplate(CharacterTemplateID id, CharacterClass characterClass, int intelligence, int strength, int concentration, int mentality, int dextry, int witness, diff --git a/data/script/template/script/template/character/HumanCharacterTemplate.java b/data/script/template/script/template/character/HumanCharacterTemplate.java index 768e59fff..b895ea812 100644 --- a/data/script/template/script/template/character/HumanCharacterTemplate.java +++ b/data/script/template/script/template/character/HumanCharacterTemplate.java @@ -5,7 +5,7 @@ import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.character.CharacterClass; import com.l2jserver.util.Coordinate; -public class HumanCharacterTemplate extends AbstractCharacterTemplate { +public abstract class HumanCharacterTemplate extends AbstractCharacterTemplate { protected HumanCharacterTemplate(CharacterTemplateID id, CharacterClass characterClass, int intelligence, int strength, int concentration, int mentality, int dextry, int witness, diff --git a/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAO.java b/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAO.java index 101109c59..86dbd07eb 100644 --- a/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAO.java +++ b/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAO.java @@ -199,13 +199,13 @@ public class MySQL5CharacterDAO extends AbstractMySQL5DAO return database.query(new InsertUpdateQuery(character) { @Override protected String query() { - return "INSERT INTO `" + TABLE + "` (`" + CHAR_ID + "`,`" + return "INSERT INTO `" + TABLE + "` (`" + CHAR_ID + "`,`" + ACCOUNT_ID + "`,`" + NAME + "`,`" + RACE + "`,`" + CLASS + "`,`" + SEX + "`,`" + LEVEL + "`,`" + COORD_X + "`,`" + COORD_Y + "`,`" + COORD_Z + "`,`" + APPEARANCE_HAIR_STYLE + "`,`" + APPEARANCE_HAIR_COLOR + "`,`" + APPEARANCE_FACE - + "`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)"; + + "`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)"; } @Override @@ -216,6 +216,7 @@ public class MySQL5CharacterDAO extends AbstractMySQL5DAO int i = 1; st.setInt(i++, character.getID().getID()); + st.setString(i++, "rogiel"); // FIXME st.setString(i++, character.getName()); st.setString(i++, character.getRace().name()); diff --git a/src/main/java/com/l2jserver/ProtocolVersion.java b/src/main/java/com/l2jserver/ProtocolVersion.java new file mode 100644 index 000000000..c0b19cab6 --- /dev/null +++ b/src/main/java/com/l2jserver/ProtocolVersion.java @@ -0,0 +1,24 @@ +package com.l2jserver; + +/** + * Represents the protocol version used by the client + * + * @author Rogiel + */ +public enum ProtocolVersion { + FREYA(216); + + public final int version; + + ProtocolVersion(int version) { + this.version = version; + } + + public static ProtocolVersion fromVersion(int version) { + for (ProtocolVersion v : values()) { + if (v.version == version) + return v; + } + return null; + } +} diff --git a/src/main/java/com/l2jserver/game/net/Lineage2Connection.java b/src/main/java/com/l2jserver/game/net/Lineage2Connection.java index cc57e4678..ae46826aa 100644 --- a/src/main/java/com/l2jserver/game/net/Lineage2Connection.java +++ b/src/main/java/com/l2jserver/game/net/Lineage2Connection.java @@ -18,6 +18,11 @@ public class Lineage2Connection { private final Channel channel; private L2Character character; private Lineage2Session session; + private ConnectionState state = ConnectionState.CONNECTED; + + public enum ConnectionState { + CONNECTED, AUTHENTICATED, IN_GAME; + } public Lineage2Connection(Channel channel) { this.channel = channel; diff --git a/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java b/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java index a9ff63340..029202ab4 100644 --- a/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java +++ b/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java @@ -36,14 +36,16 @@ public class Lineage2PipelineFactory implements ChannelPipelineFactory { new Lineage2Encrypter()); pipeline.addLast(Lineage2Decrypter.HANDLER_NAME, new Lineage2Decrypter()); + + pipeline.addLast("logger-hex", new LoggingHandler(InternalLogLevel.DEBUG, true)); pipeline.addLast("packet.writer", new Lineage2PacketWriter()); pipeline.addLast("packet.reader", new Lineage2PacketReader(injector)); + + pipeline.addLast("logger", new LoggingHandler(InternalLogLevel.DEBUG, true)); pipeline.addLast("packet.handler", new Lineage2PacketHandler()); - pipeline.addLast("logger", new LoggingHandler(InternalLogLevel.WARN)); - return pipeline; } } diff --git a/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java b/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java index 19a460a26..a4262d0da 100644 --- a/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java +++ b/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java @@ -1,5 +1,7 @@ package com.l2jserver.game.net.codec; +import java.util.Arrays; + import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; @@ -26,11 +28,23 @@ public class Lineage2Decrypter extends OneToOneDecoder { final int size = buffer.readableBytes(); int temp = 0; for (int i = 0; i < size; i++) { - int temp2 = buffer.getUnsignedByte(offset + i) & 0xFF; - buffer.setByte(offset + i, (byte) (temp2 ^ key[i & 15] ^ temp)); + int temp2 = buffer.getByte(offset + i) & 0xFF; + buffer.setByte(offset + i, (temp2 ^ key[i & 15] ^ temp)); temp = temp2; } + // int old = _inKey[8] &0xff; + // old |= _inKey[9] << 8 &0xff00; + // old |= _inKey[10] << 0x10 &0xff0000; + // old |= _inKey[11] << 0x18 &0xff000000; + // + // old += size; + // + // _inKey[8] = (byte)(old &0xff); + // _inKey[9] = (byte)(old >> 0x08 &0xff); + // _inKey[10] = (byte)(old >> 0x10 &0xff); + // _inKey[11] = (byte)(old >> 0x18 &0xff); + int old = key[8] & 0xff; old |= key[9] << 8 & 0xff00; old |= key[10] << 0x10 & 0xff0000; @@ -54,9 +68,7 @@ public class Lineage2Decrypter extends OneToOneDecoder { } public void setKey(byte[] key) { - for (int i = 0; i < 16; i++) { - this.key[i] = key[i]; - } + System.arraycopy(key, 0, this.key, 0, key.length); } public boolean isEnabled() { diff --git a/src/main/java/com/l2jserver/game/net/codec/Lineage2Encrypter.java b/src/main/java/com/l2jserver/game/net/codec/Lineage2Encrypter.java index f503a6dda..5f1d43666 100644 --- a/src/main/java/com/l2jserver/game/net/codec/Lineage2Encrypter.java +++ b/src/main/java/com/l2jserver/game/net/codec/Lineage2Encrypter.java @@ -1,5 +1,7 @@ package com.l2jserver.game.net.codec; +import java.util.Arrays; + import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; @@ -24,7 +26,7 @@ public class Lineage2Encrypter extends OneToOneEncoder { final int size = buffer.readableBytes() - 2; int temp = 0; for (int i = 0; i < size; i++) { - int temp2 = buffer.getUnsignedByte(offset + i) & 0xFF; + int temp2 = buffer.getByte(offset + i) & 0xFF; buffer.setByte(offset + i, (byte) (temp2 ^ key[i & 15] ^ temp)); temp = temp2; } @@ -50,9 +52,7 @@ public class Lineage2Encrypter extends OneToOneEncoder { } public void setKey(byte[] key) { - for (int i = 0; i < 16; i++) { - this.key[i] = key[i]; - } + System.arraycopy(key, 0, this.key, 0, key.length); } public boolean isEnabled() { diff --git a/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java b/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java index 1c146dd94..97ac03593 100644 --- a/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java +++ b/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java @@ -12,10 +12,13 @@ import com.google.inject.Injector; import com.l2jserver.game.net.packet.ClientPacket; import com.l2jserver.game.net.packet.client.AuthLoginPacket; import com.l2jserver.game.net.packet.client.CharacterCreatePacket; +import com.l2jserver.game.net.packet.client.EnterWorld; import com.l2jserver.game.net.packet.client.LogoutPacket; import com.l2jserver.game.net.packet.client.ProtocolVersionPacket; +import com.l2jserver.game.net.packet.client.RequestCharacterTemplatesPacket; import com.l2jserver.game.net.packet.client.RequestGotoLobby; -import com.l2jserver.game.net.packet.client.RequestNewCharacterPacket; +import com.l2jserver.game.net.packet.client.RequestKeyMapping; +import com.l2jserver.game.net.packet.client.RequestManorList; public class Lineage2PacketReader extends OneToOneDecoder { private final Injector injector; @@ -57,20 +60,25 @@ public class Lineage2PacketReader extends OneToOneDecoder { return AuthLoginPacket.class; case CharacterCreatePacket.OPCODE: return CharacterCreatePacket.class; - case RequestNewCharacterPacket.OPCODE: - return RequestNewCharacterPacket.class; - // COMPOSED - case 0xd0: + case RequestCharacterTemplatesPacket.OPCODE: + return RequestCharacterTemplatesPacket.class; + case 0xd0: // COMPOSED final int opcode2 = buffer.readUnsignedShort(); switch (opcode2) { case RequestGotoLobby.OPCODE2: return RequestGotoLobby.class; + case RequestKeyMapping.OPCODE2: + return RequestKeyMapping.class; + case RequestManorList.OPCODE2: + return RequestManorList.class; default: - logger.warn("Unknown opcode2: 0x{}", - Integer.toHexString(opcode)); + logger.warn("Unknown opcode2 for 0xd0: 0x{}", + Integer.toHexString(opcode2)); break; } break; + case EnterWorld.OPCODE: + return EnterWorld.class; default: logger.warn("Unknown opcode: 0x{}", Integer.toHexString(opcode)); break; diff --git a/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketWriter.java b/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketWriter.java index f92f37f08..b131676d4 100644 --- a/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketWriter.java +++ b/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketWriter.java @@ -7,10 +7,15 @@ import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.l2jserver.game.net.packet.ServerPacket; public class Lineage2PacketWriter extends OneToOneEncoder { + private static final Logger log = LoggerFactory + .getLogger(Lineage2PacketWriter.class); + @Override protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { @@ -22,6 +27,9 @@ public class Lineage2PacketWriter extends OneToOneEncoder { buffer.writeShort(0x0000); buffer.writeByte(packet.getOpcode()); // packet opcode packet.write(buffer); + + log.debug("Writing message {}", ChannelBuffers.hexDump(buffer)); + return buffer; } } diff --git a/src/main/java/com/l2jserver/game/net/packet/client/AuthLoginPacket.java b/src/main/java/com/l2jserver/game/net/packet/client/AuthLoginPacket.java index c7753bcc7..df30c91e1 100644 --- a/src/main/java/com/l2jserver/game/net/packet/client/AuthLoginPacket.java +++ b/src/main/java/com/l2jserver/game/net/packet/client/AuthLoginPacket.java @@ -9,9 +9,9 @@ import com.l2jserver.db.dao.CharacterDAO; import com.l2jserver.game.net.Lineage2Connection; import com.l2jserver.game.net.Lineage2Session; import com.l2jserver.game.net.packet.AbstractClientPacket; -import com.l2jserver.game.net.packet.server.CharacterSelectionListPacket; +import com.l2jserver.game.net.packet.server.CharacterEnterWorldPacket; import com.l2jserver.model.world.L2Character; -import com.l2jserver.util.BufferUtil; +import com.l2jserver.util.BufferUtils; /** * This packet is sent by the client once the login server has authorized @@ -39,8 +39,7 @@ public class AuthLoginPacket extends AbstractClientPacket { @Override public void read(ChannelBuffer buffer) { - this.loginName = BufferUtil.readString(buffer); - System.out.println(loginName); + this.loginName = BufferUtils.readString(buffer).toLowerCase(); this.playKey1 = buffer.readInt(); this.playKey2 = buffer.readInt(); this.loginKey1 = buffer.readInt(); @@ -54,8 +53,9 @@ public class AuthLoginPacket extends AbstractClientPacket { final List chars = characterDao.selectByAccount(conn .getSession().getUsername()); - conn.write(CharacterSelectionListPacket.fromL2Session( - conn.getSession(), chars.toArray(new L2Character[0]))); +// conn.write(CharacterSelectionListPacket.fromL2Session( +// conn.getSession(), chars.toArray(new L2Character[0]))); + conn.write(new CharacterEnterWorldPacket(chars.get(0), playKey1)); } /** diff --git a/src/main/java/com/l2jserver/game/net/packet/client/CharacterCreatePacket.java b/src/main/java/com/l2jserver/game/net/packet/client/CharacterCreatePacket.java index 45a9da2cd..b7efe440d 100644 --- a/src/main/java/com/l2jserver/game/net/packet/client/CharacterCreatePacket.java +++ b/src/main/java/com/l2jserver/game/net/packet/client/CharacterCreatePacket.java @@ -21,11 +21,11 @@ import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.character.CharacterAppearance.CharacterFace; import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColor; import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairStyle; -import com.l2jserver.util.BufferUtil; +import com.l2jserver.util.BufferUtils; /** * Completes the creation of an character. Creates the object, inserts into the - * database and notifies the client abou the status of the operation. + * database and notifies the client about the status of the operation. * * @author Rogiel */ @@ -71,7 +71,7 @@ public class CharacterCreatePacket extends AbstractClientPacket { @Override public void read(ChannelBuffer buffer) { - name = BufferUtil.readString(buffer); + name = BufferUtils.readString(buffer); race = Race.fromOption(buffer.readInt()); sex = Sex.fromOption(buffer.readInt()); classId = buffer.readInt(); @@ -90,7 +90,8 @@ public class CharacterCreatePacket extends AbstractClientPacket { @Override public void process(final Lineage2Connection conn) { - log.debug("Creating a new character"); + log.debug("Creating a new character, race={}, sex={}, classid={}", + new Object[] { race, sex, classId }); if ((name.length() < 1) || (name.length() > 16)) { log.debug("Character name length invalid: {}. Aborting.", name); conn.write(new CharacterCreateFailPacket( @@ -123,15 +124,29 @@ public class CharacterCreatePacket extends AbstractClientPacket { log.debug("Creating character with template {}", template); // ensure parameters passed by the client are true - if ((intelligence != template.getIntelligence()) - || (strength != template.getStrength()) - || (concentration != template.getConcentration()) - || (mentality != template.getMentality()) - || (dextry != template.getDextry()) - || (witness != template.getWitness()) - || (race != template.getRace())) { + if (/* + * (intelligence != template.getIntelligence()) || (strength != + * template.getStrength()) || (concentration != + * template.getConcentration()) || (mentality != + * template.getMentality()) || (dextry != template.getDextry()) || + * (witness != template.getWitness()) || + */(race != template.getRace())) { + // log.debug("intelligence, expected {}, received {}", + // template.getIntelligence(), intelligence); + // log.debug("strength, expected {}, received {}", + // template.getStrength(), strength); + // log.debug("concentration, expected {}, received {}", + // template.getConcentration(), concentration); + // log.debug("dextry, expected {}, received {}", + // template.getDextry(), + // dextry); + // log.debug("witness, expected {}, received {}", + // template.getWitness(), witness); + log.debug("race, expected {}, received {}", template.getRace(), + race); + log.debug( - "Values sent by client and sent from template does not match: {}", + "Values sent by client and from template does not match: {}", template); // some of the values didn't match, canceling creation conn.write(new CharacterCreateFailPacket( diff --git a/src/main/java/com/l2jserver/game/net/packet/client/EnterWorld.java b/src/main/java/com/l2jserver/game/net/packet/client/EnterWorld.java new file mode 100644 index 000000000..ea6562f6e --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/packet/client/EnterWorld.java @@ -0,0 +1,37 @@ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.game.net.Lineage2Connection; +import com.l2jserver.game.net.packet.AbstractClientPacket; +import com.l2jserver.game.net.packet.server.InventoryPacket; + +/** + * The client is requesting a logout. Currently, when this packet is received + * the connection is immediately closed. + * + * @author Rogiel + */ +public class EnterWorld extends AbstractClientPacket { + public static final int OPCODE = 0x11; + + @Override + public void read(ChannelBuffer buffer) { + buffer.readBytes(new byte[32]); // Unknown Byte Array + buffer.readInt(); // Unknown Value + buffer.readInt(); // Unknown Value + buffer.readInt(); // Unknown Value + buffer.readInt(); // Unknown Value + buffer.readBytes(new byte[32]); // Unknown Byte Array + buffer.readInt(); // Unknown Value + // TODO parse tracert + // for (int i = 0; i < 5; i++) + // for (int o = 0; o < 4; o++) + // tracert[i][o] = readC(); + } + + @Override + public void process(final Lineage2Connection conn) { + conn.write(new InventoryPacket(conn.getCharacter().getInventory())); + } +} diff --git a/src/main/java/com/l2jserver/game/net/packet/client/RequestNewCharacterPacket.java b/src/main/java/com/l2jserver/game/net/packet/client/RequestCharacterTemplatesPacket.java similarity index 77% rename from src/main/java/com/l2jserver/game/net/packet/client/RequestNewCharacterPacket.java rename to src/main/java/com/l2jserver/game/net/packet/client/RequestCharacterTemplatesPacket.java index fa7a96db3..6af7e8552 100644 --- a/src/main/java/com/l2jserver/game/net/packet/client/RequestNewCharacterPacket.java +++ b/src/main/java/com/l2jserver/game/net/packet/client/RequestCharacterTemplatesPacket.java @@ -11,27 +11,28 @@ import com.l2jserver.game.net.packet.server.CharacterTemplatePacket; import com.l2jserver.model.id.template.CharacterTemplateID; import com.l2jserver.model.id.template.factory.CharacterTemplateIDFactory; import com.l2jserver.model.template.CharacterTemplate; +import com.l2jserver.model.world.character.CharacterClass; /** * Requests the creation of a new Character. The list of character templates is - * sent to the client, meaning that the client is autorized to create + * sent to the client, meaning that the client is authorized to create * characters. * * @author Rogiel */ -public class RequestNewCharacterPacket extends AbstractClientPacket { +public class RequestCharacterTemplatesPacket extends AbstractClientPacket { public static final int OPCODE = 0x13; /** * The logger */ private static final Logger log = LoggerFactory - .getLogger(RequestNewCharacterPacket.class); + .getLogger(RequestCharacterTemplatesPacket.class); private final CharacterTemplateIDFactory idFactory; @Inject - public RequestNewCharacterPacket(CharacterTemplateIDFactory idFactory) { + public RequestCharacterTemplatesPacket(CharacterTemplateIDFactory idFactory) { this.idFactory = idFactory; } @@ -43,7 +44,7 @@ public class RequestNewCharacterPacket extends AbstractClientPacket { public void process(final Lineage2Connection conn) { log.debug("Requested character templates"); final CharacterTemplateID id = idFactory - .createID(Integer.MAX_VALUE - 1); + .createID(CharacterClass.HUMAN_FIGHTER.id); final CharacterTemplate template = id.getTemplate(); final CharacterTemplatePacket templatePacket = new CharacterTemplatePacket( diff --git a/src/main/java/com/l2jserver/game/net/packet/client/RequestKeyMapping.java b/src/main/java/com/l2jserver/game/net/packet/client/RequestKeyMapping.java new file mode 100644 index 000000000..fbba7f7c2 --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/packet/client/RequestKeyMapping.java @@ -0,0 +1,26 @@ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.game.net.Lineage2Connection; +import com.l2jserver.game.net.packet.AbstractClientPacket; + +/** + * The client is requesting a logout. Currently, when this packet is received + * the connection is immediately closed. + * + * @author Rogiel + */ +public class RequestKeyMapping extends AbstractClientPacket { + public static final int OPCODE1 = 0xd0; + public static final int OPCODE2 = 0x21; + + @Override + public void read(ChannelBuffer buffer) { + } + + @Override + public void process(final Lineage2Connection conn) { + // TODO + } +} diff --git a/src/main/java/com/l2jserver/game/net/packet/client/RequestManorList.java b/src/main/java/com/l2jserver/game/net/packet/client/RequestManorList.java new file mode 100644 index 000000000..e2234bdf5 --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/packet/client/RequestManorList.java @@ -0,0 +1,36 @@ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.l2jserver.game.net.Lineage2Connection; +import com.l2jserver.game.net.packet.AbstractClientPacket; +import com.l2jserver.game.net.packet.server.ManorListPacket; + +/** + * The client is requesting a logout. Currently, when this packet is received + * the connection is immediately closed. + * + * @author Rogiel + */ +public class RequestManorList extends AbstractClientPacket { + public static final int OPCODE1 = 0xd0; + public static final int OPCODE2 = 0x01; + + /** + * The logger + */ + private static final Logger log = LoggerFactory + .getLogger(RequestManorList.class); + + @Override + public void read(ChannelBuffer buffer) { + } + + @Override + public void process(final Lineage2Connection conn) { + conn.write(new ManorListPacket("gludio", "dion", "giran", "oren", "aden", + "innadril", "goddard", "rune", "schuttgart")); + } +} diff --git a/src/main/java/com/l2jserver/game/net/packet/server/CharacterEnterWorldPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/CharacterEnterWorldPacket.java new file mode 100644 index 000000000..a5569c9b2 --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/packet/server/CharacterEnterWorldPacket.java @@ -0,0 +1,70 @@ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.game.net.packet.AbstractServerPacket; +import com.l2jserver.model.world.L2Character; +import com.l2jserver.model.world.actor.ActorExperience; +import com.l2jserver.util.BufferUtils; + +/** + * An packet informing that the character was created with success. + * + * @author Rogiel + */ +public class CharacterEnterWorldPacket extends AbstractServerPacket { + public static final int OPCODE = 0x0b; + + private final L2Character character; + private final int sessionId; + + public CharacterEnterWorldPacket(L2Character character, int sessionId) { + super(OPCODE); + this.character = character; + this.sessionId = sessionId; + } + + @Override + public void write(ChannelBuffer buffer) { + BufferUtils.writeString(buffer, character.getName()); + buffer.writeInt(character.getID().getID()); + BufferUtils.writeString(buffer, "Hello world!"); + buffer.writeInt(sessionId); + buffer.writeInt(0x00); // clan id + buffer.writeInt(0x00); // ?? + buffer.writeInt(character.getSex().option); + buffer.writeInt(character.getRace().option); + buffer.writeInt(character.getCharacterClass().id); + buffer.writeInt(0x01); // active ?? + buffer.writeInt(character.getPosition().getX()); + buffer.writeInt(character.getPosition().getY()); + buffer.writeInt(character.getPosition().getZ()); + + buffer.writeDouble(100); + buffer.writeDouble(100); + buffer.writeInt(0x00); + buffer.writeLong(ActorExperience.LEVEL_1.experience); + buffer.writeInt(ActorExperience.LEVEL_1.level); + buffer.writeInt(0x00); // karma + buffer.writeInt(0x00); // pk + buffer.writeInt(character.getAttributes().getIntelligence()); // INT + buffer.writeInt(character.getAttributes().getStrength()); // STR + buffer.writeInt(character.getAttributes().getConcentration()); // CON + buffer.writeInt(character.getAttributes().getMentality()); // MEN + buffer.writeInt(character.getAttributes().getDextry()); // DEX + buffer.writeInt(character.getAttributes().getWitness()); // WIT + + buffer.writeInt(250); // game time + buffer.writeInt(0x00); + + buffer.writeInt(character.getCharacterClass().id); + + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + + buffer.writeBytes(new byte[64]); + buffer.writeInt(0x00); + } +} diff --git a/src/main/java/com/l2jserver/game/net/packet/server/CharacterSelectionListPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/CharacterSelectionListPacket.java index 9df07246e..d5b847d0c 100644 --- a/src/main/java/com/l2jserver/game/net/packet/server/CharacterSelectionListPacket.java +++ b/src/main/java/com/l2jserver/game/net/packet/server/CharacterSelectionListPacket.java @@ -5,7 +5,8 @@ import org.jboss.netty.buffer.ChannelBuffer; import com.l2jserver.game.net.Lineage2Session; import com.l2jserver.game.net.packet.AbstractServerPacket; import com.l2jserver.model.world.L2Character; -import com.l2jserver.util.BufferUtil; +import com.l2jserver.model.world.actor.ActorExperience; +import com.l2jserver.util.BufferUtils; /** * The list of characters sent to the client. @@ -32,7 +33,7 @@ public class CharacterSelectionListPacket extends AbstractServerPacket { public static CharacterSelectionListPacket fromL2Session( Lineage2Session session, L2Character... characters) { return new CharacterSelectionListPacket(session.getUsername(), - session.getPlayKey1(), -1, characters); + session.getPlayKey2(), -1, characters); } @Override @@ -40,16 +41,17 @@ public class CharacterSelectionListPacket extends AbstractServerPacket { // buffer.writeByte(0x09); buffer.writeInt(characters.length); - // Can prevent players from creating new characters (if 0); (if 1, - // the client will ask if chars may be created (0x13) Response: (0x0D) ) - buffer.writeInt(0x01); + // Can prevent players from creating new characters (if 0); + // if 1 the client will ask if chars may be created + // (RequestCharacterTemplatesPacket) Response: (CharacterTemplatePacket) + buffer.writeInt(0x07); // max chars buffer.writeByte(0x00); - int i = 0; + //int i = 0; for (final L2Character character : characters) { - BufferUtil.writeString(buffer, character.getName()); + BufferUtils.writeString(buffer, character.getName()); buffer.writeInt(character.getID().getID()); - BufferUtil.writeString(buffer, loginName); + BufferUtils.writeString(buffer, loginName); buffer.writeInt(sessionId); // if (character.getClanID() == null) { buffer.writeInt(0x00); // clan id @@ -58,7 +60,7 @@ public class CharacterSelectionListPacket extends AbstractServerPacket { // } buffer.writeInt(0x00); // ?? - buffer.writeInt(character.getSex().option); // sex + buffer.writeInt(0x01); // sex buffer.writeInt(character.getRace().option); // race // if (character.getClassId() == character.getBaseClassId()) @@ -76,23 +78,26 @@ public class CharacterSelectionListPacket extends AbstractServerPacket { buffer.writeDouble(20); // hp cur buffer.writeDouble(20); // mp cur - buffer.writeInt(3000); // sp - buffer.writeLong(2000); // exp - buffer.writeInt(0x01); // level + buffer.writeInt(0x00); // sp + buffer.writeLong(ActorExperience.LEVEL_1.experience); // exp + buffer.writeInt(ActorExperience.LEVEL_1.level); // level buffer.writeInt(0x00); // karma buffer.writeInt(0x00); // pk buffer.writeInt(0x00); // pvp - buffer.writeInt(0x00); // unk - buffer.writeInt(0x00); // unk - buffer.writeInt(0x00); // unk - buffer.writeInt(0x00); // unk - buffer.writeInt(0x00); // unk - buffer.writeInt(0x00); // unk - buffer.writeInt(0x00); // unk + for (int n = 0; n < 7; n++) { + buffer.writeInt(0x00); // unk + } + // buffer.writeInt(0x00); // unk 1 + // buffer.writeInt(0x00); // unk 2 + // buffer.writeInt(0x00); // unk 3 + // buffer.writeInt(0x00); // unk 4 + // buffer.writeInt(0x00); // unk 5 + // buffer.writeInt(0x00); // unk 6 + // buffer.writeInt(0x00); // unk 7 - for (int id = 0; id < 26; id++) { + for (int id = 0; id < 25; id++) { buffer.writeInt(0x00); // paperdolls } // buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_HAIR)); @@ -123,18 +128,21 @@ public class CharacterSelectionListPacket extends AbstractServerPacket { // buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_BELT)); // hair style - buffer.writeInt(character.getAppearance().getHairStyle().option); + //buffer.writeInt(character.getAppearance().getHairStyle().option); + buffer.writeInt(0x02); // hair color - buffer.writeInt(character.getAppearance().getHairColor().option); + //buffer.writeInt(character.getAppearance().getHairColor().option); + buffer.writeInt(0x03); // face - buffer.writeInt(character.getAppearance().getFace().option); + //buffer.writeInt(character.getAppearance().getFace().option); + buffer.writeInt(0x00); buffer.writeDouble(30); // hp max buffer.writeDouble(30); // mp max buffer.writeInt(0x0); // seconds left before delete buffer.writeInt(character.getCharacterClass().id); // class - buffer.writeInt(0x00); // c3 auto-select char + buffer.writeInt(0x01); // c3 auto-select char buffer.writeByte(0x00); // enchant effect @@ -146,7 +154,7 @@ public class CharacterSelectionListPacket extends AbstractServerPacket { // character select you don't see your transformation. // Freya by Vistall: - // buffer.writeInt(0); // npdid - 16024 Tame Tiny Baby Kookaburra + buffer.writeInt(16024); // npdid - 16024 Tame Tiny Baby Kookaburra // // A9E89C buffer.writeInt(0); // level buffer.writeInt(0); // ? @@ -154,7 +162,9 @@ public class CharacterSelectionListPacket extends AbstractServerPacket { buffer.writeDouble(0); // max Hp buffer.writeDouble(0); // cur Hp - i++; + // buffer.writeInt(0x00); + + //i++; } } } diff --git a/src/main/java/com/l2jserver/game/net/packet/server/InventoryPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/InventoryPacket.java new file mode 100644 index 000000000..665cac3c1 --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/packet/server/InventoryPacket.java @@ -0,0 +1,66 @@ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.game.net.packet.AbstractServerPacket; +import com.l2jserver.model.world.character.CharacterInventory; + +/** + * This packet send the inventory to the client + * + * @author Rogiel + */ +public class InventoryPacket extends AbstractServerPacket { + /** + * Message OPCODE + */ + public static final int OPCODE = 0x11; + + private CharacterInventory inventory; + private boolean showWindow = false; + + public InventoryPacket(CharacterInventory inventory) { + super(OPCODE); + this.inventory = inventory; + } + + @Override + public void write(ChannelBuffer buffer) { + buffer.writeByte((showWindow ? 0x01 : 0x00)); + buffer.writeInt(0x00); // item count + // for (Item item : inventory) { + // buffer.writeInt(item.getID().getID()); + // buffer.writeInt(item.getTemplateID().getID()); + // buffer.writeInt(0x00); // loc slot + // buffer.writeLong(0x00); //count + // buffer.writeShort(0x00); // item type2 + // buffer.writeShort(0x00); // item type3 + // buffer.writeShort(0x00); // equiped? + // buffer.writeInt(0x00); // body part + // buffer.writeShort(0x00); // enchant level + // // race tickets + // buffer.writeShort(temp.getCustomType2()); // item type4 + // buffer.writeInt(0x00); // augument + // buffer.writeInt(temp.getMana()); // mana + // buffer.writeInt(-9999); // time + // buffer.writeShort(temp.getAttackElementType()); // attack element + // type + // buffer.writeShort(temp.getAttackElementPower()); // attack element + // power + // for (byte i = 0; i < 6; i++) { + // buffer.writeShort(temp.getElementDefAttr(i)); // element def attrib + // } + // // Enchant Effects + // buffer.writeShort(0x00); + // buffer.writeShort(0x00); + // buffer.writeShort(0x00); + // } + // if (_inventory.hasInventoryBlock()) { + // buffer.writeShort(_inventory.getBlockItems().length); + // writeC(_inventory.getBlockMode()); + // for (int i : _inventory.getBlockItems()) + // buffer.writeInt(i); + // } else + buffer.writeShort(0x00); + } +} diff --git a/src/main/java/com/l2jserver/game/net/packet/server/ManorListPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/ManorListPacket.java new file mode 100644 index 000000000..5c7551b59 --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/packet/server/ManorListPacket.java @@ -0,0 +1,36 @@ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.game.net.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * This packet send the manor list to the client + * + * @author Rogiel + */ +public class ManorListPacket extends AbstractServerPacket { + /** + * Message OPCODE + */ + public static final int OPCODE = 0xfe; + + private String[] manors; + + public ManorListPacket(String... manors) { + super(OPCODE); + this.manors = manors; + } + + @Override + public void write(ChannelBuffer buffer) { + buffer.writeShort(0x22); + buffer.writeInt(manors.length); + int i = 1; + for (String manor : manors) { + buffer.writeInt(i++); + BufferUtils.writeString(buffer, manor); + } + } +} diff --git a/src/main/java/com/l2jserver/game/net/packet/server/UserinfoPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/UserinfoPacket.java new file mode 100644 index 000000000..afebcfd0c --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/packet/server/UserinfoPacket.java @@ -0,0 +1,36 @@ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.game.net.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * This is an message informing the client of an given player + * + * @author Rogiel + */ +public class UserinfoPacket extends AbstractServerPacket { + /** + * Message OPCODE + */ + public static final int OPCODE = 0xfe; + + private String[] manors; + + public UserinfoPacket(String... manors) { + super(OPCODE); + this.manors = manors; + } + + @Override + public void write(ChannelBuffer buffer) { + buffer.writeShort(0x22); + buffer.writeInt(manors.length); + int i = 1; + for (String manor : manors) { + buffer.writeInt(i++); + BufferUtils.writeString(buffer, manor); + } + } +} diff --git a/src/main/java/com/l2jserver/model/world/actor/ActorExperience.java b/src/main/java/com/l2jserver/model/world/actor/ActorExperience.java new file mode 100644 index 000000000..78ed6c5f0 --- /dev/null +++ b/src/main/java/com/l2jserver/model/world/actor/ActorExperience.java @@ -0,0 +1,76 @@ +package com.l2jserver.model.world.actor; + +public enum ActorExperience { + /** + * This is an unreachable level! + */ + LEVEL_0(-1L), + + LEVEL_1(0L), LEVEL_2(68L), LEVEL_3(363L), LEVEL_4(1168L), LEVEL_5(2884L), LEVEL_6( + 6038L), LEVEL_7(11287L), LEVEL_8(19423L), LEVEL_9(31378L), + + LEVEL_10(48229L), LEVEL_11(71201L), LEVEL_12(101676L), LEVEL_13(141192L), LEVEL_14( + 191452L), LEVEL_15(254327L), LEVEL_16(331864L), LEVEL_17(426284L), LEVEL_18( + 539995L), LEVEL_19(675590L), + + LEVEL_20(835854L), LEVEL_21(1023775L), LEVEL_22(1242536L), LEVEL_23( + 1495531L), LEVEL_24(1786365L), LEVEL_25(2118860L), LEVEL_26( + 2497059L), LEVEL_27(2925229L), LEVEL_28(3407873L), LEVEL_29( + 3949727L), + + LEVEL_30(4555766L), LEVEL_31(5231213L), LEVEL_32(5981539L), LEVEL_33( + 6812472L), LEVEL_34(7729999L), LEVEL_35(8740372L), LEVEL_36( + 9850111L), LEVEL_37(11066012L), LEVEL_38(12395149L), LEVEL_39( + 13844879L), + + LEVEL_40(15422851L), LEVEL_41(17137002L), LEVEL_42(18995573L), LEVEL_43( + 21007103L), LEVEL_44(23180442L), LEVEL_45(25524751L), LEVEL_46( + 28049509L), LEVEL_47(30764519L), LEVEL_48(33679907L), LEVEL_49( + 36806133L), + + LEVEL_50(40153995L), LEVEL_51(45524865L), LEVEL_52(51262204L), LEVEL_53( + 57383682L), LEVEL_54(63907585L), LEVEL_55(70852742L), LEVEL_56( + 80700339L), LEVEL_57(91162131L), LEVEL_58(102265326L), LEVEL_59( + 114038008L), + + LEVEL_60(126509030L), LEVEL_61(146307211L), LEVEL_62(167243291L), LEVEL_63( + 189363788L), LEVEL_64(212716741L), LEVEL_65(237351413L), LEVEL_66( + 271973532L), LEVEL_67(308441375L), LEVEL_68(346825235L), LEVEL_69( + 387197529L), + + LEVEL_70(429632402L), LEVEL_71(474205751L), LEVEL_72(532692055L), LEVEL_73( + 606319094L), LEVEL_74(696376867L), LEVEL_75(804219972L), LEVEL_76( + 931275828L), LEVEL_77(1151275834L), LEVEL_78(1511275834L), LEVEL_79( + 2099275834L), + + LEVEL_80(4200000000L), LEVEL_81(6300000000L), LEVEL_82(8820000000L), LEVEL_83( + 11844000000L), LEVEL_84(15472800000L), LEVEL_85(19827360000L), LEVEL_86( + 25314105600L), LEVEL_87(32211728640L); + /** + * The minimum experience required for this level + */ + public final long experience; + /** + * The level represented by this experience value + */ + public final int level; + + ActorExperience(long experience) { + this.experience = experience; + this.level = this.ordinal(); + } + + public static ActorExperience getLevel(long experience) { + ActorExperience last = ActorExperience.LEVEL_0; + for (ActorExperience exp : values()) { + if (exp.experience < experience) { + last = exp; + continue; + } + if (exp.experience >= experience) { + return exp; + } + } + return last; + } +} diff --git a/src/main/java/com/l2jserver/model/world/character/CharacterClass.java b/src/main/java/com/l2jserver/model/world/character/CharacterClass.java index 2796d1ce7..29d958d4e 100644 --- a/src/main/java/com/l2jserver/model/world/character/CharacterClass.java +++ b/src/main/java/com/l2jserver/model/world/character/CharacterClass.java @@ -11,85 +11,176 @@ public enum CharacterClass { /** * Human fighter */ - HUMAN_FIGHTER(0x00, Race.HUMAN), WARRIOR(0x01, HUMAN_FIGHTER), GLADIATOR( - 0x02, WARRIOR), WARLORD(0x03, WARRIOR), KNIGHT(0x04, HUMAN_FIGHTER), PALADIN( - 0x05, KNIGHT), DARK_AVENGER(0x06, KNIGHT), ROGUE(0x07, - HUMAN_FIGHTER), REASURE_HUNTER(0x08, ROGUE), HAWKEYE(0x09, ROGUE), + HUMAN_FIGHTER(0x00, ClassType.FIGHTER, Race.HUMAN), WARRIOR(0x01, + HUMAN_FIGHTER), GLADIATOR(0x02, WARRIOR), WARLORD(0x03, WARRIOR), KNIGHT( + 0x04, HUMAN_FIGHTER), PALADIN(0x05, KNIGHT), DARK_AVENGER(0x06, + KNIGHT), ROGUE(0x07, HUMAN_FIGHTER), TREASURE_HUNTER(0x08, ROGUE), HAWKEYE( + 0x09, ROGUE), + // 3rd classes + DUELIST(0x58, GLADIATOR), DREADNOUGHT(0x59, WARLORD), phoenixKnight(0x5a, + PALADIN), hellKnight(0x5b, DARK_AVENGER), sagittarius(0x5c, HAWKEYE), adventurer( + 0x5d, TREASURE_HUNTER), + /** * Human mystic */ - HUMAN_MYSTIC(0x0a, true, Race.HUMAN), WIZARD(0x0b, HUMAN_MYSTIC), SORCEROR( - 0x0c, WIZARD), NECROMANCER(0x0d, WIZARD), WARLOCK(0x0e, true, true, - WIZARD), CLERIC(0x0f, HUMAN_MYSTIC), BISHOP(0x10, CLERIC), PROPHET( - 0x11, CLERIC), + HUMAN_MYSTIC(0x0a, ClassType.MYSTIC, Race.HUMAN), WIZARD(0x0b, HUMAN_MYSTIC), SORCEROR( + 0x0c, WIZARD), NECROMANCER(0x0d, WIZARD), WARLOCK(0x0e, true, + WIZARD), CLERIC(0x0f, ClassType.PRIEST, HUMAN_MYSTIC), BISHOP(0x10, + CLERIC), PROPHET(0x11, CLERIC), + // 3rd classes + ARCHMAGE(0x5e, SORCEROR), SOULTAKER(0x5f, NECROMANCER), ARCANA_LORD(0x60, + WARLOCK), CARDINAL(0x61, BISHOP), HIEROPHANT(0x62, PROPHET), /** * Elven fighter */ - ELVEN_FIGHTER(0x12, Race.ELF), ELVEN_KNIGHT(0x13, ELVEN_FIGHTER), TEMPLE_KNIGHT( - 0x14, ELVEN_KNIGHT), SWORD_SINGER(0x15, ELVEN_KNIGHT), ELVEN_SCOUT( - 0x16, ELVEN_FIGHTER), PLAINS_WALKER(0x17, ELVEN_SCOUT), SILVER_RANGER( - 0x18, ELVEN_SCOUT), + ELVEN_FIGHTER(0x12, ClassType.FIGHTER, Race.ELF), ELVEN_KNIGHT(0x13, + ELVEN_FIGHTER), TEMPLE_KNIGHT(0x14, ELVEN_KNIGHT), SWORD_SINGER( + 0x15, ELVEN_KNIGHT), ELVEN_SCOUT(0x16, ELVEN_FIGHTER), PLAINS_WALKER( + 0x17, ELVEN_SCOUT), SILVER_RANGER(0x18, ELVEN_SCOUT), + // 3rd classes + EVA_TEMPLAR(0x63, TEMPLE_KNIGHT), SWORD_MUSE(0x64, SWORD_SINGER), WIND_RIDER( + 0x65, PLAINS_WALKER), MOONLIGHT_SENTINEL(0x66, SILVER_RANGER), /** * Elven mystic */ - ELVEN_MYSTIC(0x19, true, Race.ELF), ELVEN_WIZARD(0x1a, ELVEN_MYSTIC), SPELLSINGER( - 0x1b, ELVEN_WIZARD), ELEMENTAL_SUMMONER(0x1c, true, true, - ELVEN_WIZARD), ORACLE(0x1d, ELVEN_MYSTIC), ELDER(0x1e, ORACLE), + ELVEN_MYSTIC(0x19, ClassType.MYSTIC, Race.ELF), ELVEN_WIZARD(0x1a, + ELVEN_MYSTIC), SPELLSINGER(0x1b, ELVEN_WIZARD), ELEMENTAL_SUMMONER( + 0x1c, true, ELVEN_WIZARD), ORACLE(0x1d, ClassType.PRIEST, + ELVEN_MYSTIC), ELDER(0x1e, ORACLE), + // 3rd classes + MYSTIC_MUSE(0x67, SPELLSINGER), ELEMENTAL_MASTER(0x68, ELEMENTAL_SUMMONER), EVA_SAINT( + 0x69, ELDER), /** * Dark elf fighter */ - DARK_FIGHTER(0x1f, Race.DARK_ELF), PALUS_KNIGHT(0x20, DARK_FIGHTER), SHILLIEN_KNIGHT( - 0x21, PALUS_KNIGHT), BLADEDANCER(0x22, PALUS_KNIGHT), ASSASSIN( - 0x23, DARK_FIGHTER), ABYSS_WALKER(0x24, ASSASSIN), PHANTOM_RANGER( - 0x25, ASSASSIN), + DARK_FIGHTER(0x1f, ClassType.FIGHTER, Race.DARK_ELF), PALUS_KNIGHT(0x20, + DARK_FIGHTER), SHILLIEN_KNIGHT(0x21, PALUS_KNIGHT), BLADEDANCER( + 0x22, PALUS_KNIGHT), ASSASSIN(0x23, DARK_FIGHTER), ABYSS_WALKER( + 0x24, ASSASSIN), PHANTOM_RANGER(0x25, ASSASSIN), + // 3rd classes + SHILLIEN_TEMPLAR(0x6a, SHILLIEN_KNIGHT), spectralDancer(0x6b, BLADEDANCER), ghostHunter( + 0x6c, ABYSS_WALKER), ghostSentinel(0x6d, PHANTOM_RANGER), /** * Dark elf mystic */ - DARK_MYSTIC(0x26, true, Race.DARK_ELF), DARK_WIZARD(0x27, DARK_MYSTIC), SPELLHOWLER( - 0x28, DARK_WIZARD), PHANTOM_SUMMONER(0x29, true, true, DARK_WIZARD), SHILLIEN_ORACLE( - 0x2a, DARK_MYSTIC), SHILLIEN_ELDER(0x2b, SHILLIEN_ORACLE); + DARK_MYSTIC(0x26, ClassType.MYSTIC, Race.DARK_ELF), DARK_WIZARD(0x27, + DARK_MYSTIC), SPELLHOWLER(0x28, DARK_WIZARD), PHANTOM_SUMMONER( + 0x29, true, DARK_WIZARD), SHILLIEN_ORACLE(0x2a, ClassType.PRIEST, + DARK_MYSTIC), SHILLIEN_ELDER(0x2b, SHILLIEN_ORACLE), + // 3rd classes + STORM_SCREAMER(0x6e, SPELLHOWLER), SPECTRAL_MASTER(0x6f, PHANTOM_SUMMONER), SHILLIEAN_SAINT( + 0x70, SHILLIEN_ELDER), - // TODO dwarf classes - // TODO kamael classes - // TODO 3rd classes + /** + * Orc fighter + */ + ORC_FIGHTER(0x2c, ClassType.FIGHTER, Race.ORC), ORC_RAIDER(0x2d, + ORC_FIGHTER), DESTROYER(0x2e, ORC_RAIDER), ORC_MONK(0x2f, + ORC_FIGHTER), TYRANT(0x30, ORC_RAIDER), + // 3rd classes + TITAN(0x71, DESTROYER), GRAND_KHAUATARI(0x72, TYRANT), + + /** + * Orc mystic + */ + ORC_MYSTIC(0x31, ClassType.MYSTIC, Race.ORC), ORC_SHAMAN(0x32, ORC_MYSTIC), OVERLORD( + 0x33, ORC_SHAMAN), WARCRYER(0x34, ORC_SHAMAN), + // 3rd classes + DOMINATOR(0x73, OVERLORD), DOOMCRYER(0x74, WARCRYER), + + /** + * Dwarf fighter + */ + DWARVEN_FIGHTER(0x35, ClassType.FIGHTER, Race.DWARF), SCAVENGER(0x36, + DWARVEN_FIGHTER), BOUNTY_HUNTER(0x37, SCAVENGER), ARTISAN(0x38, + DWARVEN_FIGHTER), WARSMITH(0x39, ARTISAN), + // 3rd classes + FORTUNE_SEEKER(0x75, BOUNTY_HUNTER), MAESTRO(0x76, WARSMITH), + + /** + * Kamael male soldier + */ + MALE_SOLDIER(0x7b, ClassType.FIGHTER, Race.KAMAEL), TROOPER(0x7D, + MALE_SOLDIER), BERSEKER(0x7F, TROOPER), MALE_SOULBREAKER(0x80, + TROOPER), DOOMBRINGER(0x83, BERSEKER), MALE_SOULDHOUND(0x84, + MALE_SOULBREAKER), + + /** + * Kamael female soldier + */ + FEMALE_SOLDIER(0x7C, ClassType.FIGHTER, Race.KAMAEL), WARDER(0x7E, + FEMALE_SOLDIER), FEMALE_SOULBREAKER(0x81, WARDER), ARBALESTER(0x82, + WARDER), FEMALE_SOULDHOUND(0x85, FEMALE_SOULBREAKER), TRICKSTER( + 0x86, ARBALESTER), INSPECTOR(0x87, WARDER), JUDICATOR(0x88, + INSPECTOR), + + // DUMMY ENTRIES, TRASH + DUMMY_ENTRY_1(58, null, false, null, null), DUMMY_ENTRY_2(59, null, false, + null, null), DUMMY_ENTRY_3(60, null, false, null, null), DUMMY_ENTRY_4( + 61, null, false, null, null), DUMMY_ENTRY_5(62, null, false, null, + null), DUMMY_ENTRY_6(63, null, false, null, null), DUMMY_ENTRY_7( + 64, null, false, null, null), DUMMY_ENTRY_8(65, null, false, null, + null), DUMMY_ENTRY_9(66, null, false, null, null), DUMMY_ENTRY_10( + 67, null, false, null, null), DUMMY_ENTRY_11(68, null, false, null, + null), DUMMY_ENTRY_12(69, null, false, null, null), DUMMY_ENTRY_13( + 70, null, false, null, null), DUMMY_ENTRY_14(71, null, false, null, + null), DUMMY_ENTRY_15(72, null, false, null, null), DUMMY_ENTRY_16( + 73, null, false, null, null), DUMMY_ENTRY_17(74, null, false, null, + null), DUMMY_ENTRY_18(75, null, false, null, null), DUMMY_ENTRY_19( + 76, null, false, null, null), DUMMY_ENTRY_20(77, null, false, null, + null), DUMMY_ENTRY_21(78, null, false, null, null), DUMMY_ENTRY_22( + 79, null, false, null, null), DUMMY_ENTRY_23(80, null, false, null, + null), DUMMY_ENTRY_24(81, null, false, null, null), DUMMY_ENTRY_25( + 82, null, false, null, null), DUMMY_ENTRY_26(83, null, false, null, + null), DUMMY_ENTRY_27(84, null, false, null, null), DUMMY_ENTRY_28( + 85, null, false, null, null), DUMMY_ENTRY_29(86, null, false, null, + null), DUMMY_ENTRY_30(87, null, false, null, null), DUMMY_ENTRY_31( + 0x77, null, false, null, null), DUMMY_ENTRY_32(0x78, null, false, + null, null), DUMMY_ENTRY_33(0x79, null, false, null, null), DUMMY_ENTRY_34( + 0x7a, null, false, null, null); public final int id; - public final boolean mystic; + public final ClassType type; public final boolean summoner; public final Race race; public final CharacterClass parent; - private CharacterClass(int id, boolean mystic, boolean summoner, Race race, + private CharacterClass(int id, ClassType type, boolean summoner, Race race, CharacterClass parent) { this.id = id; - this.mystic = mystic; + this.type = type; this.summoner = summoner; this.race = race; this.parent = parent; } private CharacterClass(int id, CharacterClass parent) { - this(id, parent.mystic, parent.summoner, parent.race, parent); + this(id, parent.type, parent.summoner, parent.race, parent); + } + + private CharacterClass(int id, boolean summoner, CharacterClass parent) { + this(id, parent.type, summoner, parent.race, parent); } private CharacterClass(int id, Race race, CharacterClass parent) { - this(id, false, false, race, parent); + this(id, parent.type, parent.summoner, race, parent); } - private CharacterClass(int id, Race race) { - this(id, false, false, race, null); + private CharacterClass(int id, ClassType type, Race race) { + this(id, type, false, race, null); } - private CharacterClass(int id, boolean mystic, Race race) { - this(id, mystic, false, race, null); + private CharacterClass(int id, ClassType type, CharacterClass parent) { + this(id, type, false, parent.race, parent); } - private CharacterClass(int id, boolean mystic, boolean summoner, + private CharacterClass(int id, ClassType type, boolean summoner, CharacterClass parent) { - this(id, mystic, summoner, parent.race, parent); + this(id, type, summoner, parent.race, parent); } public CharacterClass fromID(int id) { @@ -110,4 +201,8 @@ public enum CharacterClass { return 0; return 1 + parent.level(); } + + public enum ClassType { + FIGHTER, MYSTIC, PRIEST; + } } diff --git a/src/main/java/com/l2jserver/service/game/scripting/impl/javacc/ClassFileManager.java b/src/main/java/com/l2jserver/service/game/scripting/impl/javacc/ClassFileManager.java index 6464b9438..2602fe5a6 100644 --- a/src/main/java/com/l2jserver/service/game/scripting/impl/javacc/ClassFileManager.java +++ b/src/main/java/com/l2jserver/service/game/scripting/impl/javacc/ClassFileManager.java @@ -111,7 +111,7 @@ public class ClassFileManager extends @Override public synchronized ScriptClassLoaderImpl getClassLoader(Location location) { if (loader == null) { - return AccessController + loader = AccessController .doPrivileged(new PrivilegedAction() { @Override public ScriptClassLoaderImpl run() { @@ -135,7 +135,7 @@ public class ClassFileManager extends * @param classLoader * parent class loader */ - public void setParentClassLoader(ScriptClassLoader classLoader) { + public synchronized void setParentClassLoader(ScriptClassLoader classLoader) { this.parentClassLoader = classLoader; } diff --git a/src/main/java/com/l2jserver/service/network/NettyNetworkService.java b/src/main/java/com/l2jserver/service/network/NettyNetworkService.java index c612abcbf..4aa0e16ae 100644 --- a/src/main/java/com/l2jserver/service/network/NettyNetworkService.java +++ b/src/main/java/com/l2jserver/service/network/NettyNetworkService.java @@ -5,6 +5,8 @@ import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ServerChannel; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; +import org.jboss.netty.logging.InternalLoggerFactory; +import org.jboss.netty.logging.Slf4JLoggerFactory; import com.google.inject.Inject; import com.google.inject.Injector; @@ -24,6 +26,7 @@ public class NettyNetworkService extends AbstractService implements Injector injector) { this.config = configService.get(NetworkConfiguration.class); this.injector = injector; + InternalLoggerFactory.setDefaultFactory(new Slf4JLoggerFactory()); } @Override diff --git a/src/main/java/com/l2jserver/util/BufferUtil.java b/src/main/java/com/l2jserver/util/BufferUtils.java similarity index 75% rename from src/main/java/com/l2jserver/util/BufferUtil.java rename to src/main/java/com/l2jserver/util/BufferUtils.java index 3de7f342e..e6ba9d8e4 100644 --- a/src/main/java/com/l2jserver/util/BufferUtil.java +++ b/src/main/java/com/l2jserver/util/BufferUtils.java @@ -4,7 +4,7 @@ import java.util.Arrays; import org.jboss.netty.buffer.ChannelBuffer; -public class BufferUtil { +public class BufferUtils { public static final String readString(ChannelBuffer buffer) { char[] str = new char[buffer.readableBytes()]; int index = 0; @@ -16,10 +16,12 @@ public class BufferUtil { } public static final void writeString(ChannelBuffer buffer, String str) { - if (str != null) - for (char c : str.toCharArray()) { - buffer.writeChar(c); + if (str != null) { + final int len = str.length(); + for (int i = 0; i < len; i++) { + buffer.writeChar(str.charAt(i)); } + } buffer.writeChar('\000'); } } diff --git a/src/main/java/com/l2jserver/util/RGBColor.java b/src/main/java/com/l2jserver/util/RGBColor.java index 66da2e593..464f83d4b 100644 --- a/src/main/java/com/l2jserver/util/RGBColor.java +++ b/src/main/java/com/l2jserver/util/RGBColor.java @@ -14,27 +14,31 @@ public class RGBColor { /** * @return the red */ - public byte getR() { + public byte getRed() { return red; } /** * @return the green */ - public byte getG() { + public byte getGreen() { return green; } /** * @return the blue */ - public byte getB() { + public byte getBlue() { return blue; } public byte[] toByteArray() { return new byte[] { red, green, blue }; } + + public int toInteger() { + return red + green >> 8 + blue >> 16; + } public static RGBColor fromByteArray(byte[] rgb) { return new RGBColor(rgb[0], rgb[1], rgb[2]); diff --git a/src/tool/java/com/l2jserver/tool/CharacterSQLEnumGenerator.java b/src/tool/java/com/l2jserver/tool/CharacterSQLEnumGenerator.java new file mode 100644 index 000000000..e68daa325 --- /dev/null +++ b/src/tool/java/com/l2jserver/tool/CharacterSQLEnumGenerator.java @@ -0,0 +1,21 @@ +package com.l2jserver.tool; + +import com.l2jserver.model.world.character.CharacterClass; + +public class CharacterSQLEnumGenerator { + public static void main(String[] args) { + System.out.println("== 'Character' SQL STATEMENT =="); + System.out.println(createClassStatement()); + } + + private static String createClassStatement() { + final StringBuilder builder = new StringBuilder(); + builder.append("ALTER TABLE `character` CHANGE `class` `class` ENUM("); + for (CharacterClass c : CharacterClass.values()) { + builder.append("'" + c.name() + "',"); + } + builder.replace(builder.length() - 1, builder.length(), ""); + builder.append(") CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT 'HUMAN_FIGHTER';"); + return builder.toString(); + } +} diff --git a/src/tool/java/com/l2jserver/tool/ClassesSQLEnumGenerator.java b/src/tool/java/com/l2jserver/tool/ClassesSQLEnumGenerator.java deleted file mode 100644 index d2b947dbf..000000000 --- a/src/tool/java/com/l2jserver/tool/ClassesSQLEnumGenerator.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.l2jserver.tool; - -import com.l2jserver.model.world.character.CharacterClass; - -public class ClassesSQLEnumGenerator { - public static void main(String[] args) { - final StringBuilder builder = new StringBuilder(); - for (CharacterClass c : CharacterClass.values()) { - builder.append("'" + c.name() + "',"); - } - System.out.println(builder.substring(0, builder.length() - 1)); - } -} diff --git a/src/tool/java/com/l2jserver/tool/EndianessTest.java b/src/tool/java/com/l2jserver/tool/EndianessTest.java new file mode 100644 index 000000000..ecb4b9693 --- /dev/null +++ b/src/tool/java/com/l2jserver/tool/EndianessTest.java @@ -0,0 +1,22 @@ +package com.l2jserver.tool; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; + +public class EndianessTest { + /** + * @param args + */ + public static void main(String[] args) { + final ByteBuffer bigEndian = ByteBuffer.allocate(8); + bigEndian.order(ByteOrder.BIG_ENDIAN); + bigEndian.putDouble(20); + System.out.println(Arrays.toString(bigEndian.array())); + + final ByteBuffer littleEndian = ByteBuffer.allocate(8); + littleEndian.order(ByteOrder.LITTLE_ENDIAN); + littleEndian.putDouble(20); + System.out.println(Arrays.toString(littleEndian.array())); + } +}