1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-06 07:32:46 +00:00

Change-Id: I04b40ac9094ed82a87bba234191ea0b8db67c718

This commit is contained in:
rogiel
2011-05-08 22:33:08 -03:00
parent d8bb472d57
commit e071ced9b2
30 changed files with 732 additions and 129 deletions

View File

@@ -6,7 +6,7 @@ import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterClass; import com.l2jserver.model.world.character.CharacterClass;
import com.l2jserver.util.Coordinate; import com.l2jserver.util.Coordinate;
public class AbstractCharacterTemplate extends CharacterTemplate { public abstract class AbstractCharacterTemplate extends CharacterTemplate {
protected AbstractCharacterTemplate(CharacterTemplateID id, protected AbstractCharacterTemplate(CharacterTemplateID id,
CharacterClass characterClass, int intelligence, int strength, CharacterClass characterClass, int intelligence, int strength,
int concentration, int mentality, int dextry, int witness, int concentration, int mentality, int dextry, int witness,

View File

@@ -5,7 +5,7 @@ import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterClass; import com.l2jserver.model.world.character.CharacterClass;
import com.l2jserver.util.Coordinate; import com.l2jserver.util.Coordinate;
public class HumanCharacterTemplate extends AbstractCharacterTemplate { public abstract class HumanCharacterTemplate extends AbstractCharacterTemplate {
protected HumanCharacterTemplate(CharacterTemplateID id, protected HumanCharacterTemplate(CharacterTemplateID id,
CharacterClass characterClass, int intelligence, int strength, CharacterClass characterClass, int intelligence, int strength,
int concentration, int mentality, int dextry, int witness, int concentration, int mentality, int dextry, int witness,

View File

@@ -199,13 +199,13 @@ public class MySQL5CharacterDAO extends AbstractMySQL5DAO<L2Character>
return database.query(new InsertUpdateQuery<L2Character>(character) { return database.query(new InsertUpdateQuery<L2Character>(character) {
@Override @Override
protected String query() { protected String query() {
return "INSERT INTO `" + TABLE + "` (`" + CHAR_ID + "`,`" return "INSERT INTO `" + TABLE + "` (`" + CHAR_ID + "`,`" + ACCOUNT_ID + "`,`"
+ NAME + "`,`" + RACE + "`,`" + CLASS + "`,`" + SEX + NAME + "`,`" + RACE + "`,`" + CLASS + "`,`" + SEX
+ "`,`" + LEVEL + "`,`" + COORD_X + "`,`" + COORD_Y + "`,`" + LEVEL + "`,`" + COORD_X + "`,`" + COORD_Y
+ "`,`" + COORD_Z + "`,`" + APPEARANCE_HAIR_STYLE + "`,`" + COORD_Z + "`,`" + APPEARANCE_HAIR_STYLE
+ "`,`" + APPEARANCE_HAIR_COLOR + "`,`" + "`,`" + APPEARANCE_HAIR_COLOR + "`,`"
+ APPEARANCE_FACE + APPEARANCE_FACE
+ "`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)"; + "`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)";
} }
@Override @Override
@@ -216,6 +216,7 @@ public class MySQL5CharacterDAO extends AbstractMySQL5DAO<L2Character>
int i = 1; int i = 1;
st.setInt(i++, character.getID().getID()); st.setInt(i++, character.getID().getID());
st.setString(i++, "rogiel"); // FIXME
st.setString(i++, character.getName()); st.setString(i++, character.getName());
st.setString(i++, character.getRace().name()); st.setString(i++, character.getRace().name());

View File

@@ -0,0 +1,24 @@
package com.l2jserver;
/**
* Represents the protocol version used by the client
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
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;
}
}

View File

@@ -18,6 +18,11 @@ public class Lineage2Connection {
private final Channel channel; private final Channel channel;
private L2Character character; private L2Character character;
private Lineage2Session session; private Lineage2Session session;
private ConnectionState state = ConnectionState.CONNECTED;
public enum ConnectionState {
CONNECTED, AUTHENTICATED, IN_GAME;
}
public Lineage2Connection(Channel channel) { public Lineage2Connection(Channel channel) {
this.channel = channel; this.channel = channel;

View File

@@ -36,14 +36,16 @@ public class Lineage2PipelineFactory implements ChannelPipelineFactory {
new Lineage2Encrypter()); new Lineage2Encrypter());
pipeline.addLast(Lineage2Decrypter.HANDLER_NAME, pipeline.addLast(Lineage2Decrypter.HANDLER_NAME,
new Lineage2Decrypter()); new Lineage2Decrypter());
pipeline.addLast("logger-hex", new LoggingHandler(InternalLogLevel.DEBUG, true));
pipeline.addLast("packet.writer", new Lineage2PacketWriter()); pipeline.addLast("packet.writer", new Lineage2PacketWriter());
pipeline.addLast("packet.reader", new Lineage2PacketReader(injector)); pipeline.addLast("packet.reader", new Lineage2PacketReader(injector));
pipeline.addLast("logger", new LoggingHandler(InternalLogLevel.DEBUG, true));
pipeline.addLast("packet.handler", new Lineage2PacketHandler()); pipeline.addLast("packet.handler", new Lineage2PacketHandler());
pipeline.addLast("logger", new LoggingHandler(InternalLogLevel.WARN));
return pipeline; return pipeline;
} }
} }

View File

@@ -1,5 +1,7 @@
package com.l2jserver.game.net.codec; package com.l2jserver.game.net.codec;
import java.util.Arrays;
import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelHandlerContext;
@@ -26,11 +28,23 @@ public class Lineage2Decrypter extends OneToOneDecoder {
final int size = buffer.readableBytes(); final int size = buffer.readableBytes();
int temp = 0; int temp = 0;
for (int i = 0; i < size; i++) { 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)); buffer.setByte(offset + i, (temp2 ^ key[i & 15] ^ temp));
temp = temp2; 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; int old = key[8] & 0xff;
old |= key[9] << 8 & 0xff00; old |= key[9] << 8 & 0xff00;
old |= key[10] << 0x10 & 0xff0000; old |= key[10] << 0x10 & 0xff0000;
@@ -54,9 +68,7 @@ public class Lineage2Decrypter extends OneToOneDecoder {
} }
public void setKey(byte[] key) { public void setKey(byte[] key) {
for (int i = 0; i < 16; i++) { System.arraycopy(key, 0, this.key, 0, key.length);
this.key[i] = key[i];
}
} }
public boolean isEnabled() { public boolean isEnabled() {

View File

@@ -1,5 +1,7 @@
package com.l2jserver.game.net.codec; package com.l2jserver.game.net.codec;
import java.util.Arrays;
import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelHandlerContext;
@@ -24,7 +26,7 @@ public class Lineage2Encrypter extends OneToOneEncoder {
final int size = buffer.readableBytes() - 2; final int size = buffer.readableBytes() - 2;
int temp = 0; int temp = 0;
for (int i = 0; i < size; i++) { 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)); buffer.setByte(offset + i, (byte) (temp2 ^ key[i & 15] ^ temp));
temp = temp2; temp = temp2;
} }
@@ -50,9 +52,7 @@ public class Lineage2Encrypter extends OneToOneEncoder {
} }
public void setKey(byte[] key) { public void setKey(byte[] key) {
for (int i = 0; i < 16; i++) { System.arraycopy(key, 0, this.key, 0, key.length);
this.key[i] = key[i];
}
} }
public boolean isEnabled() { public boolean isEnabled() {

View File

@@ -12,10 +12,13 @@ import com.google.inject.Injector;
import com.l2jserver.game.net.packet.ClientPacket; import com.l2jserver.game.net.packet.ClientPacket;
import com.l2jserver.game.net.packet.client.AuthLoginPacket; import com.l2jserver.game.net.packet.client.AuthLoginPacket;
import com.l2jserver.game.net.packet.client.CharacterCreatePacket; 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.LogoutPacket;
import com.l2jserver.game.net.packet.client.ProtocolVersionPacket; 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.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 { public class Lineage2PacketReader extends OneToOneDecoder {
private final Injector injector; private final Injector injector;
@@ -57,20 +60,25 @@ public class Lineage2PacketReader extends OneToOneDecoder {
return AuthLoginPacket.class; return AuthLoginPacket.class;
case CharacterCreatePacket.OPCODE: case CharacterCreatePacket.OPCODE:
return CharacterCreatePacket.class; return CharacterCreatePacket.class;
case RequestNewCharacterPacket.OPCODE: case RequestCharacterTemplatesPacket.OPCODE:
return RequestNewCharacterPacket.class; return RequestCharacterTemplatesPacket.class;
// COMPOSED case 0xd0: // COMPOSED
case 0xd0:
final int opcode2 = buffer.readUnsignedShort(); final int opcode2 = buffer.readUnsignedShort();
switch (opcode2) { switch (opcode2) {
case RequestGotoLobby.OPCODE2: case RequestGotoLobby.OPCODE2:
return RequestGotoLobby.class; return RequestGotoLobby.class;
case RequestKeyMapping.OPCODE2:
return RequestKeyMapping.class;
case RequestManorList.OPCODE2:
return RequestManorList.class;
default: default:
logger.warn("Unknown opcode2: 0x{}", logger.warn("Unknown opcode2 for 0xd0: 0x{}",
Integer.toHexString(opcode)); Integer.toHexString(opcode2));
break; break;
} }
break; break;
case EnterWorld.OPCODE:
return EnterWorld.class;
default: default:
logger.warn("Unknown opcode: 0x{}", Integer.toHexString(opcode)); logger.warn("Unknown opcode: 0x{}", Integer.toHexString(opcode));
break; break;

View File

@@ -7,10 +7,15 @@ import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.l2jserver.game.net.packet.ServerPacket; import com.l2jserver.game.net.packet.ServerPacket;
public class Lineage2PacketWriter extends OneToOneEncoder { public class Lineage2PacketWriter extends OneToOneEncoder {
private static final Logger log = LoggerFactory
.getLogger(Lineage2PacketWriter.class);
@Override @Override
protected Object encode(ChannelHandlerContext ctx, Channel channel, protected Object encode(ChannelHandlerContext ctx, Channel channel,
Object msg) throws Exception { Object msg) throws Exception {
@@ -22,6 +27,9 @@ public class Lineage2PacketWriter extends OneToOneEncoder {
buffer.writeShort(0x0000); buffer.writeShort(0x0000);
buffer.writeByte(packet.getOpcode()); // packet opcode buffer.writeByte(packet.getOpcode()); // packet opcode
packet.write(buffer); packet.write(buffer);
log.debug("Writing message {}", ChannelBuffers.hexDump(buffer));
return buffer; return buffer;
} }
} }

View File

@@ -9,9 +9,9 @@ import com.l2jserver.db.dao.CharacterDAO;
import com.l2jserver.game.net.Lineage2Connection; import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.Lineage2Session; import com.l2jserver.game.net.Lineage2Session;
import com.l2jserver.game.net.packet.AbstractClientPacket; 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.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 * This packet is sent by the client once the login server has authorized
@@ -39,8 +39,7 @@ public class AuthLoginPacket extends AbstractClientPacket {
@Override @Override
public void read(ChannelBuffer buffer) { public void read(ChannelBuffer buffer) {
this.loginName = BufferUtil.readString(buffer); this.loginName = BufferUtils.readString(buffer).toLowerCase();
System.out.println(loginName);
this.playKey1 = buffer.readInt(); this.playKey1 = buffer.readInt();
this.playKey2 = buffer.readInt(); this.playKey2 = buffer.readInt();
this.loginKey1 = buffer.readInt(); this.loginKey1 = buffer.readInt();
@@ -54,8 +53,9 @@ public class AuthLoginPacket extends AbstractClientPacket {
final List<L2Character> chars = characterDao.selectByAccount(conn final List<L2Character> chars = characterDao.selectByAccount(conn
.getSession().getUsername()); .getSession().getUsername());
conn.write(CharacterSelectionListPacket.fromL2Session( // conn.write(CharacterSelectionListPacket.fromL2Session(
conn.getSession(), chars.toArray(new L2Character[0]))); // conn.getSession(), chars.toArray(new L2Character[0])));
conn.write(new CharacterEnterWorldPacket(chars.get(0), playKey1));
} }
/** /**

View File

@@ -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.CharacterFace;
import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColor; import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColor;
import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairStyle; 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 * 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 <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
@@ -71,7 +71,7 @@ public class CharacterCreatePacket extends AbstractClientPacket {
@Override @Override
public void read(ChannelBuffer buffer) { public void read(ChannelBuffer buffer) {
name = BufferUtil.readString(buffer); name = BufferUtils.readString(buffer);
race = Race.fromOption(buffer.readInt()); race = Race.fromOption(buffer.readInt());
sex = Sex.fromOption(buffer.readInt()); sex = Sex.fromOption(buffer.readInt());
classId = buffer.readInt(); classId = buffer.readInt();
@@ -90,7 +90,8 @@ public class CharacterCreatePacket extends AbstractClientPacket {
@Override @Override
public void process(final Lineage2Connection conn) { 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)) { if ((name.length() < 1) || (name.length() > 16)) {
log.debug("Character name length invalid: {}. Aborting.", name); log.debug("Character name length invalid: {}. Aborting.", name);
conn.write(new CharacterCreateFailPacket( conn.write(new CharacterCreateFailPacket(
@@ -123,15 +124,29 @@ public class CharacterCreatePacket extends AbstractClientPacket {
log.debug("Creating character with template {}", template); log.debug("Creating character with template {}", template);
// ensure parameters passed by the client are true // ensure parameters passed by the client are true
if ((intelligence != template.getIntelligence()) if (/*
|| (strength != template.getStrength()) * (intelligence != template.getIntelligence()) || (strength !=
|| (concentration != template.getConcentration()) * template.getStrength()) || (concentration !=
|| (mentality != template.getMentality()) * template.getConcentration()) || (mentality !=
|| (dextry != template.getDextry()) * template.getMentality()) || (dextry != template.getDextry()) ||
|| (witness != template.getWitness()) * (witness != template.getWitness()) ||
|| (race != template.getRace())) { */(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( log.debug(
"Values sent by client and sent from template does not match: {}", "Values sent by client and from template does not match: {}",
template); template);
// some of the values didn't match, canceling creation // some of the values didn't match, canceling creation
conn.write(new CharacterCreateFailPacket( conn.write(new CharacterCreateFailPacket(

View File

@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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()));
}
}

View File

@@ -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.CharacterTemplateID;
import com.l2jserver.model.id.template.factory.CharacterTemplateIDFactory; import com.l2jserver.model.id.template.factory.CharacterTemplateIDFactory;
import com.l2jserver.model.template.CharacterTemplate; 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 * 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. * characters.
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class RequestNewCharacterPacket extends AbstractClientPacket { public class RequestCharacterTemplatesPacket extends AbstractClientPacket {
public static final int OPCODE = 0x13; public static final int OPCODE = 0x13;
/** /**
* The logger * The logger
*/ */
private static final Logger log = LoggerFactory private static final Logger log = LoggerFactory
.getLogger(RequestNewCharacterPacket.class); .getLogger(RequestCharacterTemplatesPacket.class);
private final CharacterTemplateIDFactory idFactory; private final CharacterTemplateIDFactory idFactory;
@Inject @Inject
public RequestNewCharacterPacket(CharacterTemplateIDFactory idFactory) { public RequestCharacterTemplatesPacket(CharacterTemplateIDFactory idFactory) {
this.idFactory = idFactory; this.idFactory = idFactory;
} }
@@ -43,7 +44,7 @@ public class RequestNewCharacterPacket extends AbstractClientPacket {
public void process(final Lineage2Connection conn) { public void process(final Lineage2Connection conn) {
log.debug("Requested character templates"); log.debug("Requested character templates");
final CharacterTemplateID id = idFactory final CharacterTemplateID id = idFactory
.createID(Integer.MAX_VALUE - 1); .createID(CharacterClass.HUMAN_FIGHTER.id);
final CharacterTemplate template = id.getTemplate(); final CharacterTemplate template = id.getTemplate();
final CharacterTemplatePacket templatePacket = new CharacterTemplatePacket( final CharacterTemplatePacket templatePacket = new CharacterTemplatePacket(

View File

@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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"));
}
}

View File

@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -5,7 +5,8 @@ import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Session; import com.l2jserver.game.net.Lineage2Session;
import com.l2jserver.game.net.packet.AbstractServerPacket; import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.L2Character; 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. * The list of characters sent to the client.
@@ -32,7 +33,7 @@ public class CharacterSelectionListPacket extends AbstractServerPacket {
public static CharacterSelectionListPacket fromL2Session( public static CharacterSelectionListPacket fromL2Session(
Lineage2Session session, L2Character... characters) { Lineage2Session session, L2Character... characters) {
return new CharacterSelectionListPacket(session.getUsername(), return new CharacterSelectionListPacket(session.getUsername(),
session.getPlayKey1(), -1, characters); session.getPlayKey2(), -1, characters);
} }
@Override @Override
@@ -40,16 +41,17 @@ public class CharacterSelectionListPacket extends AbstractServerPacket {
// buffer.writeByte(0x09); // buffer.writeByte(0x09);
buffer.writeInt(characters.length); buffer.writeInt(characters.length);
// Can prevent players from creating new characters (if 0); (if 1, // Can prevent players from creating new characters (if 0);
// the client will ask if chars may be created (0x13) Response: (0x0D) ) // if 1 the client will ask if chars may be created
buffer.writeInt(0x01); // (RequestCharacterTemplatesPacket) Response: (CharacterTemplatePacket)
buffer.writeInt(0x07); // max chars
buffer.writeByte(0x00); buffer.writeByte(0x00);
int i = 0; //int i = 0;
for (final L2Character character : characters) { for (final L2Character character : characters) {
BufferUtil.writeString(buffer, character.getName()); BufferUtils.writeString(buffer, character.getName());
buffer.writeInt(character.getID().getID()); buffer.writeInt(character.getID().getID());
BufferUtil.writeString(buffer, loginName); BufferUtils.writeString(buffer, loginName);
buffer.writeInt(sessionId); buffer.writeInt(sessionId);
// if (character.getClanID() == null) { // if (character.getClanID() == null) {
buffer.writeInt(0x00); // clan id buffer.writeInt(0x00); // clan id
@@ -58,7 +60,7 @@ public class CharacterSelectionListPacket extends AbstractServerPacket {
// } // }
buffer.writeInt(0x00); // ?? buffer.writeInt(0x00); // ??
buffer.writeInt(character.getSex().option); // sex buffer.writeInt(0x01); // sex
buffer.writeInt(character.getRace().option); // race buffer.writeInt(character.getRace().option); // race
// if (character.getClassId() == character.getBaseClassId()) // if (character.getClassId() == character.getBaseClassId())
@@ -76,23 +78,26 @@ public class CharacterSelectionListPacket extends AbstractServerPacket {
buffer.writeDouble(20); // hp cur buffer.writeDouble(20); // hp cur
buffer.writeDouble(20); // mp cur buffer.writeDouble(20); // mp cur
buffer.writeInt(3000); // sp buffer.writeInt(0x00); // sp
buffer.writeLong(2000); // exp buffer.writeLong(ActorExperience.LEVEL_1.experience); // exp
buffer.writeInt(0x01); // level buffer.writeInt(ActorExperience.LEVEL_1.level); // level
buffer.writeInt(0x00); // karma buffer.writeInt(0x00); // karma
buffer.writeInt(0x00); // pk buffer.writeInt(0x00); // pk
buffer.writeInt(0x00); // pvp buffer.writeInt(0x00); // pvp
buffer.writeInt(0x00); // unk for (int n = 0; n < 7; n++) {
buffer.writeInt(0x00); // unk buffer.writeInt(0x00); // unk
buffer.writeInt(0x00); // unk }
buffer.writeInt(0x00); // unk // buffer.writeInt(0x00); // unk 1
buffer.writeInt(0x00); // unk // buffer.writeInt(0x00); // unk 2
buffer.writeInt(0x00); // unk // buffer.writeInt(0x00); // unk 3
buffer.writeInt(0x00); // unk // 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(0x00); // paperdolls
} }
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_HAIR)); // buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_HAIR));
@@ -123,18 +128,21 @@ public class CharacterSelectionListPacket extends AbstractServerPacket {
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_BELT)); // buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_BELT));
// hair style // hair style
buffer.writeInt(character.getAppearance().getHairStyle().option); //buffer.writeInt(character.getAppearance().getHairStyle().option);
buffer.writeInt(0x02);
// hair color // hair color
buffer.writeInt(character.getAppearance().getHairColor().option); //buffer.writeInt(character.getAppearance().getHairColor().option);
buffer.writeInt(0x03);
// face // face
buffer.writeInt(character.getAppearance().getFace().option); //buffer.writeInt(character.getAppearance().getFace().option);
buffer.writeInt(0x00);
buffer.writeDouble(30); // hp max buffer.writeDouble(30); // hp max
buffer.writeDouble(30); // mp max buffer.writeDouble(30); // mp max
buffer.writeInt(0x0); // seconds left before delete buffer.writeInt(0x0); // seconds left before delete
buffer.writeInt(character.getCharacterClass().id); // class 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 buffer.writeByte(0x00); // enchant effect
@@ -146,7 +154,7 @@ public class CharacterSelectionListPacket extends AbstractServerPacket {
// character select you don't see your transformation. // character select you don't see your transformation.
// Freya by Vistall: // Freya by Vistall:
// buffer.writeInt(0); // npdid - 16024 Tame Tiny Baby Kookaburra buffer.writeInt(16024); // npdid - 16024 Tame Tiny Baby Kookaburra
// // A9E89C // // A9E89C
buffer.writeInt(0); // level buffer.writeInt(0); // level
buffer.writeInt(0); // ? buffer.writeInt(0); // ?
@@ -154,7 +162,9 @@ public class CharacterSelectionListPacket extends AbstractServerPacket {
buffer.writeDouble(0); // max Hp buffer.writeDouble(0); // max Hp
buffer.writeDouble(0); // cur Hp buffer.writeDouble(0); // cur Hp
i++; // buffer.writeInt(0x00);
//i++;
} }
} }
} }

View File

@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}
}

View File

@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -11,85 +11,176 @@ public enum CharacterClass {
/** /**
* Human fighter * Human fighter
*/ */
HUMAN_FIGHTER(0x00, Race.HUMAN), WARRIOR(0x01, HUMAN_FIGHTER), GLADIATOR( HUMAN_FIGHTER(0x00, ClassType.FIGHTER, Race.HUMAN), WARRIOR(0x01,
0x02, WARRIOR), WARLORD(0x03, WARRIOR), KNIGHT(0x04, HUMAN_FIGHTER), PALADIN( HUMAN_FIGHTER), GLADIATOR(0x02, WARRIOR), WARLORD(0x03, WARRIOR), KNIGHT(
0x05, KNIGHT), DARK_AVENGER(0x06, KNIGHT), ROGUE(0x07, 0x04, HUMAN_FIGHTER), PALADIN(0x05, KNIGHT), DARK_AVENGER(0x06,
HUMAN_FIGHTER), REASURE_HUNTER(0x08, ROGUE), HAWKEYE(0x09, ROGUE), 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
*/ */
HUMAN_MYSTIC(0x0a, true, Race.HUMAN), WIZARD(0x0b, HUMAN_MYSTIC), SORCEROR( HUMAN_MYSTIC(0x0a, ClassType.MYSTIC, Race.HUMAN), WIZARD(0x0b, HUMAN_MYSTIC), SORCEROR(
0x0c, WIZARD), NECROMANCER(0x0d, WIZARD), WARLOCK(0x0e, true, true, 0x0c, WIZARD), NECROMANCER(0x0d, WIZARD), WARLOCK(0x0e, true,
WIZARD), CLERIC(0x0f, HUMAN_MYSTIC), BISHOP(0x10, CLERIC), PROPHET( WIZARD), CLERIC(0x0f, ClassType.PRIEST, HUMAN_MYSTIC), BISHOP(0x10,
0x11, CLERIC), 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
*/ */
ELVEN_FIGHTER(0x12, Race.ELF), ELVEN_KNIGHT(0x13, ELVEN_FIGHTER), TEMPLE_KNIGHT( ELVEN_FIGHTER(0x12, ClassType.FIGHTER, Race.ELF), ELVEN_KNIGHT(0x13,
0x14, ELVEN_KNIGHT), SWORD_SINGER(0x15, ELVEN_KNIGHT), ELVEN_SCOUT( ELVEN_FIGHTER), TEMPLE_KNIGHT(0x14, ELVEN_KNIGHT), SWORD_SINGER(
0x16, ELVEN_FIGHTER), PLAINS_WALKER(0x17, ELVEN_SCOUT), SILVER_RANGER( 0x15, ELVEN_KNIGHT), ELVEN_SCOUT(0x16, ELVEN_FIGHTER), PLAINS_WALKER(
0x18, ELVEN_SCOUT), 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
*/ */
ELVEN_MYSTIC(0x19, true, Race.ELF), ELVEN_WIZARD(0x1a, ELVEN_MYSTIC), SPELLSINGER( ELVEN_MYSTIC(0x19, ClassType.MYSTIC, Race.ELF), ELVEN_WIZARD(0x1a,
0x1b, ELVEN_WIZARD), ELEMENTAL_SUMMONER(0x1c, true, true, ELVEN_MYSTIC), SPELLSINGER(0x1b, ELVEN_WIZARD), ELEMENTAL_SUMMONER(
ELVEN_WIZARD), ORACLE(0x1d, ELVEN_MYSTIC), ELDER(0x1e, ORACLE), 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 elf fighter
*/ */
DARK_FIGHTER(0x1f, Race.DARK_ELF), PALUS_KNIGHT(0x20, DARK_FIGHTER), SHILLIEN_KNIGHT( DARK_FIGHTER(0x1f, ClassType.FIGHTER, Race.DARK_ELF), PALUS_KNIGHT(0x20,
0x21, PALUS_KNIGHT), BLADEDANCER(0x22, PALUS_KNIGHT), ASSASSIN( DARK_FIGHTER), SHILLIEN_KNIGHT(0x21, PALUS_KNIGHT), BLADEDANCER(
0x23, DARK_FIGHTER), ABYSS_WALKER(0x24, ASSASSIN), PHANTOM_RANGER( 0x22, PALUS_KNIGHT), ASSASSIN(0x23, DARK_FIGHTER), ABYSS_WALKER(
0x25, ASSASSIN), 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 elf mystic
*/ */
DARK_MYSTIC(0x26, true, Race.DARK_ELF), DARK_WIZARD(0x27, DARK_MYSTIC), SPELLHOWLER( DARK_MYSTIC(0x26, ClassType.MYSTIC, Race.DARK_ELF), DARK_WIZARD(0x27,
0x28, DARK_WIZARD), PHANTOM_SUMMONER(0x29, true, true, DARK_WIZARD), SHILLIEN_ORACLE( DARK_MYSTIC), SPELLHOWLER(0x28, DARK_WIZARD), PHANTOM_SUMMONER(
0x2a, DARK_MYSTIC), SHILLIEN_ELDER(0x2b, SHILLIEN_ORACLE); 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 * Orc fighter
// TODO 3rd classes */
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 int id;
public final boolean mystic; public final ClassType type;
public final boolean summoner; public final boolean summoner;
public final Race race; public final Race race;
public final CharacterClass parent; 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) { CharacterClass parent) {
this.id = id; this.id = id;
this.mystic = mystic; this.type = type;
this.summoner = summoner; this.summoner = summoner;
this.race = race; this.race = race;
this.parent = parent; this.parent = parent;
} }
private CharacterClass(int id, CharacterClass 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) { 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) { private CharacterClass(int id, ClassType type, Race race) {
this(id, false, false, race, null); this(id, type, false, race, null);
} }
private CharacterClass(int id, boolean mystic, Race race) { private CharacterClass(int id, ClassType type, CharacterClass parent) {
this(id, mystic, false, race, null); 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) { CharacterClass parent) {
this(id, mystic, summoner, parent.race, parent); this(id, type, summoner, parent.race, parent);
} }
public CharacterClass fromID(int id) { public CharacterClass fromID(int id) {
@@ -110,4 +201,8 @@ public enum CharacterClass {
return 0; return 0;
return 1 + parent.level(); return 1 + parent.level();
} }
public enum ClassType {
FIGHTER, MYSTIC, PRIEST;
}
} }

View File

@@ -111,7 +111,7 @@ public class ClassFileManager extends
@Override @Override
public synchronized ScriptClassLoaderImpl getClassLoader(Location location) { public synchronized ScriptClassLoaderImpl getClassLoader(Location location) {
if (loader == null) { if (loader == null) {
return AccessController loader = AccessController
.doPrivileged(new PrivilegedAction<ScriptClassLoaderImpl>() { .doPrivileged(new PrivilegedAction<ScriptClassLoaderImpl>() {
@Override @Override
public ScriptClassLoaderImpl run() { public ScriptClassLoaderImpl run() {
@@ -135,7 +135,7 @@ public class ClassFileManager extends
* @param classLoader * @param classLoader
* parent class loader * parent class loader
*/ */
public void setParentClassLoader(ScriptClassLoader classLoader) { public synchronized void setParentClassLoader(ScriptClassLoader classLoader) {
this.parentClassLoader = classLoader; this.parentClassLoader = classLoader;
} }

View File

@@ -5,6 +5,8 @@ import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ServerChannel; import org.jboss.netty.channel.ServerChannel;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; 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.Inject;
import com.google.inject.Injector; import com.google.inject.Injector;
@@ -24,6 +26,7 @@ public class NettyNetworkService extends AbstractService implements
Injector injector) { Injector injector) {
this.config = configService.get(NetworkConfiguration.class); this.config = configService.get(NetworkConfiguration.class);
this.injector = injector; this.injector = injector;
InternalLoggerFactory.setDefaultFactory(new Slf4JLoggerFactory());
} }
@Override @Override

View File

@@ -4,7 +4,7 @@ import java.util.Arrays;
import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffer;
public class BufferUtil { public class BufferUtils {
public static final String readString(ChannelBuffer buffer) { public static final String readString(ChannelBuffer buffer) {
char[] str = new char[buffer.readableBytes()]; char[] str = new char[buffer.readableBytes()];
int index = 0; int index = 0;
@@ -16,10 +16,12 @@ public class BufferUtil {
} }
public static final void writeString(ChannelBuffer buffer, String str) { public static final void writeString(ChannelBuffer buffer, String str) {
if (str != null) if (str != null) {
for (char c : str.toCharArray()) { final int len = str.length();
buffer.writeChar(c); for (int i = 0; i < len; i++) {
buffer.writeChar(str.charAt(i));
} }
}
buffer.writeChar('\000'); buffer.writeChar('\000');
} }
} }

View File

@@ -14,27 +14,31 @@ public class RGBColor {
/** /**
* @return the red * @return the red
*/ */
public byte getR() { public byte getRed() {
return red; return red;
} }
/** /**
* @return the green * @return the green
*/ */
public byte getG() { public byte getGreen() {
return green; return green;
} }
/** /**
* @return the blue * @return the blue
*/ */
public byte getB() { public byte getBlue() {
return blue; return blue;
} }
public byte[] toByteArray() { public byte[] toByteArray() {
return new byte[] { red, green, blue }; return new byte[] { red, green, blue };
} }
public int toInteger() {
return red + green >> 8 + blue >> 16;
}
public static RGBColor fromByteArray(byte[] rgb) { public static RGBColor fromByteArray(byte[] rgb) {
return new RGBColor(rgb[0], rgb[1], rgb[2]); return new RGBColor(rgb[0], rgb[1], rgb[2]);

View File

@@ -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();
}
}

View File

@@ -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));
}
}

View File

@@ -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()));
}
}