1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-09 17:02:53 +00:00

Change-Id: I0000000000000000000000000000000000000000

Change-Id: I8636776eaf000fcdfb528cc403710f6d6ee9e73e
Change-Id: Iebc523681d07ecd6d7b7e89343b29a8034558f94
This commit is contained in:
rogiel
2011-05-07 01:06:17 -03:00
parent 81d2babede
commit 51aea46020
100 changed files with 2505 additions and 406 deletions

View File

@@ -1,6 +1,5 @@
package com.l2jserver;
import com.google.inject.AbstractModule;
import com.l2jserver.db.dao.DAOModuleMySQL5;
import com.l2jserver.model.id.factory.IDFactoryModule;

View File

@@ -1,13 +1,17 @@
package com.l2jserver;
import org.apache.log4j.BasicConfigurator;
import com.l2jserver.routines.GameServerInitializationRoutine;
public class L2JGameServerMain {
/**
* @param args
* @throws InterruptedException
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
BasicConfigurator.configure();
final L2JGameServer server = new L2JGameServer();
try {
server.getInjector()
@@ -16,7 +20,7 @@ public class L2JGameServerMain {
System.out.println("GameServer could not be started!");
e.printStackTrace();
}
Thread.sleep(60 * 60 * 1000);
}

View File

@@ -17,6 +17,7 @@ import com.l2jserver.model.world.L2Character;
public class Lineage2Connection {
private final Channel channel;
private L2Character character;
private Lineage2Session session;
public Lineage2Connection(Channel channel) {
this.channel = channel;
@@ -44,6 +45,23 @@ public class Lineage2Connection {
this.character = character;
}
/**
* @return the session
*/
public Lineage2Session getSession() {
return session;
}
/**
* @param session
* the session to set
*/
public void setSession(Lineage2Session session) {
if (this.session != null)
throw new IllegalStateException("Session is already set!");
this.session = session;
}
public Channel getChannel() {
return channel;
}

View File

@@ -0,0 +1,55 @@
package com.l2jserver.game.net;
public class Lineage2Session {
private final String username;
private final int playKey1;
private final int playKey2;
private final int loginKey1;
private final int loginKey2;
public Lineage2Session(String username, int playOK1, int playOK2,
int loginOK1, int loginOK2) {
this.username = username;
this.playKey1 = playOK1;
this.playKey2 = playOK2;
this.loginKey1 = loginOK1;
this.loginKey2 = loginOK2;
}
/**
* @return the username
*/
public String getUsername() {
return username;
}
/**
* @return the playKey1
*/
public int getPlayKey1() {
return playKey1;
}
/**
* @return the playKey2
*/
public int getPlayKey2() {
return playKey2;
}
/**
* @return the loginKey1
*/
public int getLoginKey1() {
return loginKey1;
}
/**
* @return the loginKey2
*/
public int getLoginKey2() {
return loginKey2;
}
}

View File

@@ -14,14 +14,14 @@ public class Lineage2Decrypter extends OneToOneDecoder {
private final byte[] key = new byte[16];
@Override
protected synchronized Object decode(ChannelHandlerContext ctx, Channel channel,
Object msg) throws Exception {
protected synchronized Object decode(ChannelHandlerContext ctx,
Channel channel, Object msg) throws Exception {
if (!(msg instanceof ChannelBuffer))
return msg;
if (!enabled)
return msg;
final ChannelBuffer buffer = (ChannelBuffer) msg;
final int offset = buffer.readerIndex();
final int size = buffer.readableBytes();
int temp = 0;
@@ -45,7 +45,7 @@ public class Lineage2Decrypter extends OneToOneDecoder {
return buffer;
}
public byte[] enable() {
byte[] key = BlowFishKeygen.getRandomKey();
this.setKey(key);

View File

@@ -1,7 +1,6 @@
package com.l2jserver.game.net.codec;
import org.jboss.netty.buffer.ChannelBuffer;
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;
@@ -13,17 +12,15 @@ public class Lineage2Encrypter extends OneToOneEncoder {
private final byte[] key = new byte[16];
@Override
protected synchronized Object encode(ChannelHandlerContext ctx, Channel channel,
Object msg) throws Exception {
protected synchronized Object encode(ChannelHandlerContext ctx,
Channel channel, Object msg) throws Exception {
if (!(msg instanceof ChannelBuffer))
return msg;
if (!enabled)
return msg;
final ChannelBuffer buffer = (ChannelBuffer) msg;
System.out.println(ChannelBuffers.hexDump(buffer));
final int offset = buffer.readerIndex() + 2; //skip header
final int offset = buffer.readerIndex() + 2; // skip header
final int size = buffer.readableBytes() - 2;
int temp = 0;
for (int i = 0; i < size; i++) {

View File

@@ -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.frame.FrameDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Lineage2FrameDecoder extends FrameDecoder {
private static final int HEADER_SIZE = 2;
private static final Logger logger = LoggerFactory
.getLogger(Lineage2FrameDecoder.class);
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel,
ChannelBuffer oldBuffer) throws Exception {
@@ -19,12 +24,13 @@ public class Lineage2FrameDecoder extends FrameDecoder {
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(oldBuffer
.toByteBuffer().order(ByteOrder.LITTLE_ENDIAN));
logger.debug("Received frame segment: {}",
ChannelBuffers.hexDump(buffer));
buffer.markReaderIndex();
final int pending = buffer.readUnsignedShort() - HEADER_SIZE;
if (pending == 0) {
if (pending == 0)
return null;
}
if (buffer.readableBytes() < pending) {
buffer.resetReaderIndex();
return null;

View File

@@ -1,7 +1,6 @@
package com.l2jserver.game.net.codec;
import org.jboss.netty.buffer.ChannelBuffer;
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;
@@ -13,10 +12,8 @@ public class Lineage2FrameEncoder extends OneToOneEncoder {
if (!(msg instanceof ChannelBuffer))
return msg;
final ChannelBuffer buffer = (ChannelBuffer) msg;
buffer.setShort(0, buffer.readableBytes() - 2);
System.out.println(ChannelBuffers.hexDump(buffer));
buffer.setShort(0, buffer.readableBytes());
return buffer;
}
}

View File

@@ -11,7 +11,11 @@ import com.google.inject.Inject;
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.LogoutPacket;
import com.l2jserver.game.net.packet.client.ProtocolVersionPacket;
import com.l2jserver.game.net.packet.client.RequestGotoLobby;
import com.l2jserver.game.net.packet.client.RequestNewCharacterPacket;
public class Lineage2PacketReader extends OneToOneDecoder {
private final Injector injector;
@@ -45,12 +49,30 @@ public class Lineage2PacketReader extends OneToOneDecoder {
private Class<? extends ClientPacket> getPacketClass(ChannelBuffer buffer) {
final short opcode = buffer.readUnsignedByte();
switch (opcode) {
case LogoutPacket.OPCODE:
return LogoutPacket.class;
case ProtocolVersionPacket.OPCODE:
return ProtocolVersionPacket.class;
case AuthLoginPacket.OPCODE:
return AuthLoginPacket.class;
case CharacterCreatePacket.OPCODE:
return CharacterCreatePacket.class;
case RequestNewCharacterPacket.OPCODE:
return RequestNewCharacterPacket.class;
// COMPOSED
case 0xd0:
final int opcode2 = buffer.readUnsignedShort();
switch (opcode2) {
case RequestGotoLobby.OPCODE2:
return RequestGotoLobby.class;
default:
logger.warn("Unknown opcode2: 0x{}",
Integer.toHexString(opcode));
break;
}
break;
default:
logger.info("Unknown opcode: " + Integer.toHexString(opcode));
logger.warn("Unknown opcode: 0x{}", Integer.toHexString(opcode));
break;
}
return null;

View File

@@ -21,7 +21,7 @@ public class Lineage2PacketWriter extends OneToOneEncoder {
final ServerPacket packet = (ServerPacket) msg;
buffer.writeShort(0x0000);
buffer.writeByte(packet.getOpcode()); // packet opcode
packet.write(buffer);
packet.write(buffer);
return buffer;
}
}

View File

@@ -15,9 +15,9 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
connection = new Lineage2Connection(e.getChannel());
System.out.println(e);
super.channelOpen(ctx, e);
}

View File

@@ -1,5 +1,4 @@
package com.l2jserver.game.net.packet;
public abstract class AbstractClientPacket implements ClientPacket {
}

View File

@@ -1,5 +1,4 @@
package com.l2jserver.game.net.packet;
public interface Packet {
}

View File

@@ -4,5 +4,6 @@ import org.jboss.netty.buffer.ChannelBuffer;
public interface ServerPacket extends Packet {
void write(ChannelBuffer buffer);
int getOpcode();
}

View File

@@ -1,23 +1,29 @@
package com.l2jserver.game.net.packet.client;
import java.util.List;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
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.CharSelectionInfoPacket;
import com.l2jserver.model.id.object.factory.CharacterIDFactory;
import com.l2jserver.game.net.packet.server.CharacterSelectionListPacket;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.util.BufferUtil;
/**
* This packet is sent by the client once the login server has authorized
* authentication into this server. A new {@link Lineage2Session} object will be
* set to the current connection and the character list is sent to the client.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class AuthLoginPacket extends AbstractClientPacket {
public static final int OPCODE = 0x2b;
@Inject
private WorldService world;
@Inject
private CharacterIDFactory idFactory;
private final CharacterDAO characterDao;
// packet
private String loginName;
@@ -26,6 +32,11 @@ public class AuthLoginPacket extends AbstractClientPacket {
private int loginKey1;
private int loginKey2;
@Inject
public AuthLoginPacket(CharacterDAO characterDao) {
this.characterDao = characterDao;
}
@Override
public void read(ChannelBuffer buffer) {
this.loginName = BufferUtil.readString(buffer);
@@ -38,11 +49,13 @@ public class AuthLoginPacket extends AbstractClientPacket {
@Override
public void process(final Lineage2Connection conn) {
// assume it is correct, for now
// send character list
// world.getEventDispatcher().dispatch(null);
final L2Character c = idFactory.createID(268435456).getObject();
conn.write(new CharSelectionInfoPacket(loginName, playKey1, -1, c));
conn.setSession(new Lineage2Session(loginName, playKey1, playKey2,
loginKey1, loginKey2));
final List<L2Character> chars = characterDao.selectByAccount(conn
.getSession().getUsername());
conn.write(CharacterSelectionListPacket.fromL2Session(
conn.getSession(), chars.toArray(new L2Character[0])));
}
/**

View File

@@ -0,0 +1,164 @@
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.db.dao.CharacterDAO;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.CharacterCreateFailPacket;
import com.l2jserver.game.net.packet.server.CharacterCreateOkPacket;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.object.factory.CharacterIDFactory;
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.AbstractActor.Race;
import com.l2jserver.model.world.AbstractActor.Sex;
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;
/**
* Completes the creation of an character. Creates the object, inserts into the
* database and notifies the client abou the status of the operation.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterCreatePacket extends AbstractClientPacket {
public static final int OPCODE = 0x0c;
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(CharacterCreatePacket.class);
// services and daos
private final CharacterDAO characterDao;
private final CharacterIDFactory characterIdFactory;
private final CharacterTemplateIDFactory characterTemplateIdFactory;
// packet
private String name;
private Race race;
private Sex sex;
private int classId;
private int intelligence;
private int strength;
private int concentration;
private int mentality;
private int dextry;
private int witness;
private CharacterHairStyle hairStyle;
private CharacterHairColor hairColor;
private CharacterFace face;
@Inject
public CharacterCreatePacket(CharacterDAO characterDao,
CharacterIDFactory characterIdFactory,
CharacterTemplateIDFactory characterTemplateIdFactory) {
this.characterDao = characterDao;
this.characterIdFactory = characterIdFactory;
this.characterTemplateIdFactory = characterTemplateIdFactory;
}
@Override
public void read(ChannelBuffer buffer) {
name = BufferUtil.readString(buffer);
race = Race.fromOption(buffer.readInt());
sex = Sex.fromOption(buffer.readInt());
classId = buffer.readInt();
intelligence = buffer.readInt();
strength = buffer.readInt();
concentration = buffer.readInt();
mentality = buffer.readInt();
dextry = buffer.readInt();
witness = buffer.readInt();
hairStyle = CharacterHairStyle.fromOption(buffer.readInt());
hairColor = CharacterHairColor.fromOption(buffer.readInt());
face = CharacterFace.fromOption(buffer.readInt());
}
@Override
public void process(final Lineage2Connection conn) {
log.debug("Creating a new character");
if ((name.length() < 1) || (name.length() > 16)) {
log.debug("Character name length invalid: {}. Aborting.", name);
conn.write(new CharacterCreateFailPacket(
CharacterCreateFailPacket.Reason.REASON_16_ENG_CHARS));
return;
}
// TODO check alphanumeric name
if (sex == null || hairStyle == null || hairColor == null
|| face == null) {
log.debug("Character appearance invalid. Aborting.");
// if some of those attributes is null, something wrong happened.
// Maybe we don't support the value sent!
conn.write(new CharacterCreateFailPacket(
CharacterCreateFailPacket.Reason.REASON_CREATION_FAILED));
return;
}
// existence check
final L2Character existenceCheck = characterDao.selectByName(name);
if (existenceCheck != null) {
log.debug("Character name already exists: {}. Aborting.", name);
conn.write(new CharacterCreateFailPacket(
CharacterCreateFailPacket.Reason.REASON_NAME_ALREADY_EXISTS));
return;
}
// create template id and lookup for the template instance
final CharacterTemplateID templateId = characterTemplateIdFactory
.createID(classId);
final CharacterTemplate template = templateId.getTemplate();
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())) {
log.debug(
"Values sent by client and sent from template does not match: {}",
template);
// some of the values didn't match, canceling creation
conn.write(new CharacterCreateFailPacket(
CharacterCreateFailPacket.Reason.REASON_CREATION_FAILED));
return;
}
// everything is fine, allocate a new ID
final CharacterID id = characterIdFactory.createID();
// create the instance from the template
final L2Character character = template.create();
log.debug("Character object created, ID: {}, Object: {}", id, character);
// set parameters
character.setID(id);
character.setName(name);
character.setSex(sex);
character.getAppearance().setHairStyle(hairStyle);
character.getAppearance().setHairColor(hairColor);
character.getAppearance().setFace(face);
if (characterDao.save(character)) {
log.debug("Character saved to database");
conn.write(CharacterCreateOkPacket.INSTANCE);
}
}
}

View File

@@ -0,0 +1,34 @@
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;
/**
* 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 LogoutPacket extends AbstractClientPacket {
public static final int OPCODE = 0x00;
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(LogoutPacket.class);
@Override
public void read(ChannelBuffer buffer) {
}
@Override
public void process(final Lineage2Connection conn) {
log.debug("Logging out client {}", conn);
conn.close();
}
}

View File

@@ -11,11 +11,21 @@ import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.KeyPacket;
/**
* In this packet the client is informing its protocol version. It is possible
* to do an test and refuse invalid protocol versions. After this packet, the
* messages received and sent are all encrypted, except for the encryptation key
* which is sent here.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ProtocolVersionPacket extends AbstractClientPacket {
public static final int OPCODE = 0x0e;
// services
private final Logger logger = LoggerFactory
/**
* The logger
*/
private final Logger log = LoggerFactory
.getLogger(ProtocolVersionPacket.class);
// packet
@@ -30,9 +40,11 @@ public class ProtocolVersionPacket extends AbstractClientPacket {
public void process(final Lineage2Connection conn) {
// generate a new key
final byte[] key = conn.getDecrypter().enable();
log.debug("Decrypter has been enabled");
log.debug("Client protocol version: {}", version);
if (L2JConstants.SUPPORTED_PROTOCOL != version) {
logger.info(
log.info(
"Incorrect protocol version: {0}. Only {1} is supported.",
version, L2JConstants.SUPPORTED_PROTOCOL);
// notify wrong protocol and close connection
@@ -53,6 +65,7 @@ public class ProtocolVersionPacket extends AbstractClientPacket {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
log.debug("Encrypter has been enabled");
// enable encrypter
conn.getEncrypter().setKey(key);
conn.getEncrypter().setEnabled(true);

View File

@@ -0,0 +1,42 @@
package com.l2jserver.game.net.packet.client;
import java.util.List;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.db.dao.CharacterDAO;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.CharacterSelectionListPacket;
import com.l2jserver.model.world.L2Character;
/**
* Requests the list of characters to be displayed in the lobby. The list of
* characters is sent to the client.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class RequestGotoLobby extends AbstractClientPacket {
public static final int OPCODE1 = 0xd0;
public static final int OPCODE2 = 0x36;
private final CharacterDAO characterDao;
@Inject
public RequestGotoLobby(CharacterDAO characterDao) {
this.characterDao = characterDao;
}
@Override
public void read(ChannelBuffer buffer) {
}
@Override
public void process(final Lineage2Connection conn) {
final List<L2Character> chars = characterDao.selectByAccount(conn
.getSession().getUsername());
conn.write(CharacterSelectionListPacket.fromL2Session(
conn.getSession(), chars.toArray(new L2Character[0])));
}
}

View File

@@ -0,0 +1,53 @@
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.AbstractClientPacket;
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;
/**
* 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
* characters.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class RequestNewCharacterPacket extends AbstractClientPacket {
public static final int OPCODE = 0x13;
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(RequestNewCharacterPacket.class);
private final CharacterTemplateIDFactory idFactory;
@Inject
public RequestNewCharacterPacket(CharacterTemplateIDFactory idFactory) {
this.idFactory = idFactory;
}
@Override
public void read(ChannelBuffer buffer) {
}
@Override
public void process(final Lineage2Connection conn) {
log.debug("Requested character templates");
final CharacterTemplateID id = idFactory
.createID(Integer.MAX_VALUE - 1);
final CharacterTemplate template = id.getTemplate();
final CharacterTemplatePacket templatePacket = new CharacterTemplatePacket(
template);
conn.write(templatePacket);
}
}

View File

@@ -0,0 +1,74 @@
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.packet.AbstractServerPacket;
/**
* An packet informing that the character could not be created.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see Reason
*/
public class CharacterCreateFailPacket extends AbstractServerPacket {
public static final int OPCODE = 0x10;
private Reason reason;
/**
* The character creation error reason
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum Reason {
/**
* "Your character creation has failed."
*/
REASON_CREATION_FAILED(0x00),
/**
* "You cannot create another character. Please delete the existing
* character and try again." Removes all settings that were selected
* (race, class, etc)"
*/
REASON_TOO_MANY_CHARACTERS(0x01),
/**
* "This name already exists."
*/
REASON_NAME_ALREADY_EXISTS(0x02),
/**
* "Your title cannot exceed 16 characters in length. Please try again."
*/
REASON_16_ENG_CHARS(0x03),
/**
* "Incorrect name. Please try again."
*/
REASON_INCORRECT_NAME(0x04),
/**
* "Characters cannot be created from this server."
*/
REASON_CREATE_NOT_ALLOWED(0x05),
/**
* "Unable to create character. You are unable to create a new character
* on the selected server. A restriction is in place which restricts
* users from creating characters on different servers where no previous
* character exists. Please choose another server."
*/
REASON_CHOOSE_ANOTHER_SVR(0x06);
public final int id;
private Reason(int id) {
this.id = id;
}
}
public CharacterCreateFailPacket(Reason reason) {
super(OPCODE);
this.reason = reason;
}
@Override
public void write(ChannelBuffer buffer) {
buffer.writeInt(reason.id);
}
}

View File

@@ -0,0 +1,25 @@
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.packet.AbstractServerPacket;
/**
* An packet informing that the character was created with success.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterCreateOkPacket extends AbstractServerPacket {
public static final int OPCODE = 0x0f;
public static final CharacterCreateOkPacket INSTANCE = new CharacterCreateOkPacket();
public CharacterCreateOkPacket() {
super(OPCODE);
}
@Override
public void write(ChannelBuffer buffer) {
buffer.writeInt(0x01);
}
}

View File

@@ -2,11 +2,17 @@ package com.l2jserver.game.net.packet.server;
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;
public class CharSelectionInfoPacket extends AbstractServerPacket {
/**
* The list of characters sent to the client.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterSelectionListPacket extends AbstractServerPacket {
public static final int OPCODE = 0x09;
private final String loginName;
@@ -14,7 +20,7 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
private int lastCharacterId;
private final L2Character[] characters;
public CharSelectionInfoPacket(String loginName, int sessionId,
public CharacterSelectionListPacket(String loginName, int sessionId,
int lastCharacterId, L2Character... characters) {
super(OPCODE);
this.loginName = loginName;
@@ -23,6 +29,12 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
this.characters = characters;
}
public static CharacterSelectionListPacket fromL2Session(
Lineage2Session session, L2Character... characters) {
return new CharacterSelectionListPacket(session.getUsername(),
session.getPlayKey1(), -1, characters);
}
@Override
public void write(ChannelBuffer buffer) {
// buffer.writeByte(0x09);
@@ -30,44 +42,28 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
// 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(0x07);
buffer.writeInt(0x01);
buffer.writeByte(0x00);
long lastAccess = 0L;
if (lastCharacterId == -1) {
for (int i = 0; i < characters.length; i++) {
if (characters[i].getLastAccess() == null)
continue;
if (lastAccess < characters[i].getLastAccess().getTime()) {
lastAccess = characters[i].getLastAccess().getTime();
lastCharacterId = i;
}
}
}
int i = 0;
for (final L2Character character : characters) {
// buffer.writeBytes(character.getName().getBytes());
// buffer.writeByte(0x00); // NULL termination
BufferUtil.writeString(buffer, character.getName());
buffer.writeInt(character.getID().getID());
BufferUtil.writeString(buffer, loginName);
// buffer.writeBytes(loginName.getBytes());
// buffer.writeByte(0x00); // NULL termination
buffer.writeInt(sessionId);
if (character.getClanID() == null) {
buffer.writeInt(0x00); // clan id
} else {
buffer.writeInt(character.getClanID().getID()); // clan id
}
// if (character.getClanID() == null) {
buffer.writeInt(0x00); // clan id
// } else {
// buffer.writeInt(character.getClanID().getID()); // clan id
// }
buffer.writeInt(0x00); // ??
buffer.writeInt(0x00); // sex
buffer.writeInt(0x00); // race
buffer.writeInt(character.getSex().option); // sex
buffer.writeInt(character.getRace().option); // race
// if (character.getClassId() == character.getBaseClassId())
buffer.writeInt(0x00);
buffer.writeInt(character.getCharacterClass().id); // base class id
// or class id
// else
// buffer.writeInt(character.getBaseClassId());
@@ -81,20 +77,20 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
buffer.writeDouble(20); // mp cur
buffer.writeInt(3000); // sp
buffer.writeLong(0); // exp
buffer.writeLong(2000); // exp
buffer.writeInt(0x01); // level
buffer.writeInt(0x00); // karma
buffer.writeInt(0x00); // pk
buffer.writeInt(0x00); // pvp
buffer.writeInt(0x00);
buffer.writeInt(0x00);
buffer.writeInt(0x00);
buffer.writeInt(0x00);
buffer.writeInt(0x00);
buffer.writeInt(0x00);
buffer.writeInt(0x00);
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 id = 0; id < 26; id++) {
buffer.writeInt(0x00); // paperdolls
@@ -126,22 +122,19 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO6));
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_BELT));
buffer.writeInt(0x01); // hair style
buffer.writeInt(0x01); // hair color
buffer.writeInt(0x01); // face
// hair style
buffer.writeInt(character.getAppearance().getHairStyle().option);
// hair color
buffer.writeInt(character.getAppearance().getHairColor().option);
// face
buffer.writeInt(character.getAppearance().getFace().option);
buffer.writeDouble(30); // hp max
buffer.writeDouble(30); // mp max
long deleteTime = 0;
int deletedays = 0;
if (deleteTime > 0)
deletedays = (int) ((deleteTime - System.currentTimeMillis()) / 1000);
buffer.writeInt(deletedays); // days left before
// delete .. if != 0
// then char is inactive
buffer.writeInt(0x00); // class
buffer.writeInt(0x01); // c3 auto-select char
buffer.writeInt(0x0); // seconds left before delete
buffer.writeInt(character.getCharacterClass().id); // class
buffer.writeInt(0x00); // c3 auto-select char
buffer.writeByte(0x00); // enchant effect
@@ -153,8 +146,8 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
// character select you don't see your transformation.
// Freya by Vistall:
buffer.writeInt(0); // npdid - 16024 Tame Tiny Baby Kookaburra
// A9E89C
// buffer.writeInt(0); // npdid - 16024 Tame Tiny Baby Kookaburra
// // A9E89C
buffer.writeInt(0); // level
buffer.writeInt(0); // ?
buffer.writeInt(0); // food? - 1200

View File

@@ -0,0 +1,49 @@
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.template.CharacterTemplate;
/**
* An packet that sends all character templates to the client.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterTemplatePacket extends AbstractServerPacket {
public static final int OPCODE = 0x0d;
private CharacterTemplate[] templates;
public CharacterTemplatePacket(CharacterTemplate... templates) {
super(OPCODE);
this.templates = templates;
}
@Override
public void write(ChannelBuffer buffer) {
buffer.writeInt(templates.length);
for (final CharacterTemplate template : templates) {
buffer.writeInt(template.getRace().option);
buffer.writeInt(template.getCharacterClass().id);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseAttributes().getStrength());
buffer.writeInt(0x0a);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseAttributes().getDextry());
buffer.writeInt(0x0a);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseAttributes().getConcentration());
buffer.writeInt(0x0a);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseAttributes().getIntelligence());
buffer.writeInt(0x0a);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseAttributes().getWitness());
buffer.writeInt(0x0a);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseAttributes().getMentality());
buffer.writeInt(0x0a);
}
}
}

View File

@@ -7,10 +7,8 @@ import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.packet.AbstractServerPacket;
/**
* <h1>0x2e "KeyPacket"</h1>
* <p>
* byte[8] key<br>
* byte protocolStatus
* This packet send the encryptation keys for the client. After this message all
* communication is done with the cryptography engine enabled.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/

View File

@@ -1,10 +1,12 @@
package com.l2jserver.model.id;
import com.google.inject.Inject;
import com.l2jserver.model.template.Template;
import com.l2jserver.model.world.WorldObject;
/**
* The ID interface. Each Object or Template must be represented by an unique
* ID.
* The ID interface. Each {@link WorldObject} or {@link Template} must be
* represented by an unique ID.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@@ -35,7 +37,7 @@ public abstract class ID {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + id + this.getClass().hashCode();
return result;
}

View File

@@ -2,7 +2,6 @@ package com.l2jserver.model.id;
import com.l2jserver.model.template.Template;
/**
* Templates IDs, different from {@link ObjectID}s, can be repeated and are
* defined in the template class.
@@ -14,6 +13,6 @@ public abstract class TemplateID<T extends Template> extends ID {
public TemplateID(int id) {
super(id);
}
public abstract T getTemplate();
}

View File

@@ -15,5 +15,5 @@ public interface IDFactory<T extends ID> {
* @param id
* @return
*/
T createID(int id);
T createID(int id);
}

View File

@@ -9,6 +9,7 @@ import com.l2jserver.model.id.object.factory.CharacterIDFactory;
import com.l2jserver.model.id.object.factory.CharacterIDFactory.CharacterIDGuiceFactory;
import com.l2jserver.model.id.object.factory.ItemIDFactory;
import com.l2jserver.model.id.object.factory.ItemIDFactory.ItemIDGuiceFactory;
import com.l2jserver.model.id.template.factory.CharacterTemplateIDFactory;
import com.l2jserver.model.id.template.factory.ItemTemplateIDFactory;
import com.l2jserver.model.id.template.factory.SkillTemplateIDFactory;
@@ -34,5 +35,7 @@ public class IDFactoryModule extends AbstractModule {
// TEMPLATE IDS
install(new FactoryModuleBuilder().build(ItemTemplateIDFactory.class));
install(new FactoryModuleBuilder().build(SkillTemplateIDFactory.class));
install(new FactoryModuleBuilder()
.build(CharacterTemplateIDFactory.class));
}
}

View File

@@ -0,0 +1,13 @@
package com.l2jserver.model.id.object;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.world.capability.Actor;
public abstract class ActorID<T extends Actor> extends ObjectID<T> {
@Inject
public ActorID(@Assisted int id) {
super(id);
}
}

View File

@@ -3,10 +3,9 @@ package com.l2jserver.model.id.object;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.l2jserver.db.dao.CharacterDAO;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.world.L2Character;
public final class CharacterID extends ObjectID<L2Character> {
public final class CharacterID extends ActorID<L2Character> {
/**
* Data Access Object (DAO) for characters
*/

View File

@@ -2,10 +2,9 @@ package com.l2jserver.model.id.object;
import com.google.inject.Inject;
import com.l2jserver.db.dao.PetDAO;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.world.Pet;
public final class PetID extends ObjectID<Pet> {
public final class PetID extends ActorID<Pet> {
/**
* Data Access Object (DAO) for pets
*/

View File

@@ -0,0 +1,23 @@
package com.l2jserver.model.id.template;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.l2jserver.model.id.TemplateID;
import com.l2jserver.model.template.CharacterTemplate;
import com.l2jserver.service.game.template.TemplateService;
public class CharacterTemplateID extends TemplateID<CharacterTemplate> {
private final TemplateService templateService;
@Inject
protected CharacterTemplateID(@Assisted int id,
TemplateService templateService) {
super(id);
this.templateService = templateService;
}
@Override
public CharacterTemplate getTemplate() {
return (CharacterTemplate) templateService.getTemplate(this);
}
}

View File

@@ -0,0 +1,7 @@
package com.l2jserver.model.id.template.factory;
import com.l2jserver.model.id.template.CharacterTemplateID;
public interface CharacterTemplateIDFactory extends
TemplateIDFactory<CharacterTemplateID> {
}

View File

@@ -2,7 +2,7 @@ package com.l2jserver.model.template;
import com.l2jserver.model.id.TemplateID;
public class AbstractTemplate implements Template {
public abstract class AbstractTemplate<T> implements Template<T> {
private final TemplateID<?> id;
public AbstractTemplate(TemplateID<?> id) {

View File

@@ -0,0 +1,250 @@
package com.l2jserver.model.template;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.l2jserver.model.id.template.CharacterTemplateID;
import com.l2jserver.model.world.AbstractActor.Race;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterBaseAttributes;
import com.l2jserver.model.world.character.CharacterClass;
import com.l2jserver.util.Coordinate;
public abstract class CharacterTemplate extends AbstractTemplate<L2Character> {
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(CharacterTemplate.class);
/**
* The character race
*/
protected final Race race;
/**
* The character class
*/
protected final CharacterClass characterClass;
/**
* The initial location for the character to be spawned
*/
protected final Coordinate spawnLocation;
/**
* The base attributes instance
*/
protected final CharacterBaseAttributes baseAttributes;
public CharacterTemplate(CharacterTemplateID id,
CharacterClass characterClass, int intelligence, int strength,
int concentration, int mentality, int dextry, int witness,
int physicalAttack, int magicalAttack, int physicalDefense,
int magicalDefense, int attackSpeed, int castSpeed, int accuracy,
int criticalChance, int evasionChance, int moveSpeed,
int maxWeigth, boolean craft, Coordinate spawnLocation) {
super(id);
this.race = characterClass.race;
this.characterClass = characterClass;
this.spawnLocation = spawnLocation;
baseAttributes = new CharacterBaseAttributes(intelligence, strength,
concentration, mentality, dextry, witness, physicalAttack,
magicalAttack, physicalDefense, magicalDefense, attackSpeed,
castSpeed, accuracy, criticalChance, evasionChance, moveSpeed,
maxWeigth, craft);
}
@Override
public L2Character create() {
log.debug("Creating a new Character instance with template {}", this);
final L2Character character = new L2Character(baseAttributes);
character.setRace(race);
character.setCharacterClass(characterClass);
character.setPosition(spawnLocation);
// character.getBaseAttributes().setIntelligence(intelligence);
// character.getBaseAttributes().setStrength(strength);
// character.getBaseAttributes().setConcentration(concentration);
// character.getBaseAttributes().setMentality(mentality);
// character.getBaseAttributes().setDextry(dextry);
// character.getBaseAttributes().setWitness(witness);
return character;
}
/**
* @return the race
*/
public Race getRace() {
return race;
}
/**
* @return the characterClass
*/
public CharacterClass getCharacterClass() {
return characterClass;
}
/**
* @return the spawnLocation
*/
public Coordinate getSpawnLocation() {
return spawnLocation;
}
/**
* @return the baseAttributes
*/
public CharacterBaseAttributes getBaseAttributes() {
return baseAttributes;
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getIntelligence()
*/
public int getIntelligence() {
return baseAttributes.getIntelligence();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getStrength()
*/
public int getStrength() {
return baseAttributes.getStrength();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getConcentration()
*/
public int getConcentration() {
return baseAttributes.getConcentration();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getMentality()
*/
public int getMentality() {
return baseAttributes.getMentality();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getDextry()
*/
public int getDextry() {
return baseAttributes.getDextry();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getWitness()
*/
public int getWitness() {
return baseAttributes.getWitness();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getPhysicalAttack()
*/
public int getPhysicalAttack() {
return baseAttributes.getPhysicalAttack();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getMagicalAttack()
*/
public int getMagicalAttack() {
return baseAttributes.getMagicalAttack();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getPhysicalDefense()
*/
public int getPhysicalDefense() {
return baseAttributes.getPhysicalDefense();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getMagicalDefense()
*/
public int getMagicalDefense() {
return baseAttributes.getMagicalDefense();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getAttackSpeed()
*/
public int getAttackSpeed() {
return baseAttributes.getAttackSpeed();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getCastSpeed()
*/
public int getCastSpeed() {
return baseAttributes.getCastSpeed();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getAccuracy()
*/
public int getAccuracy() {
return baseAttributes.getAccuracy();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getCriticalChance()
*/
public int getCriticalChance() {
return baseAttributes.getCriticalChance();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getEvasionChance()
*/
public int getEvasionChance() {
return baseAttributes.getEvasionChance();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getMoveSpeed()
*/
public int getMoveSpeed() {
return baseAttributes.getMoveSpeed();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getMaxWeigth()
*/
public int getMaxWeigth() {
return baseAttributes.getMaxWeigth();
}
/**
* @return
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#canCraft()
*/
public boolean canCraft() {
return baseAttributes.canCraft();
}
@Override
public CharacterTemplateID getID() {
return (CharacterTemplateID) super.getID();
}
}

View File

@@ -1,12 +1,28 @@
package com.l2jserver.model.template;
import com.l2jserver.model.id.template.ItemTemplateID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.world.Item;
public abstract class ItemTemplate extends AbstractTemplate<Item> {
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(ItemTemplate.class);
public abstract class ItemTemplate extends AbstractTemplate {
public ItemTemplate(ItemTemplateID id) {
super(id);
}
@Override
public Item create() {
log.debug("Creating a new Item instance with template {}", this);
return new Item(this.getID());
}
@Override
public ItemTemplateID getID() {
return (ItemTemplateID) super.getID();

View File

@@ -2,13 +2,21 @@ package com.l2jserver.model.template;
import com.l2jserver.model.id.template.SkillTemplateID;
import com.l2jserver.model.template.capability.Castable;
import com.l2jserver.model.world.character.CharacterClass;
public abstract class SkillTemplate extends AbstractTemplate implements
public abstract class SkillTemplate extends AbstractTemplate<Void> implements
Castable {
public SkillTemplate(SkillTemplateID id) {
super(id);
}
public abstract CharacterClass[] getClasses();
@Override
public Void create() {
return null;
}
@Override
public SkillTemplateID getID() {
return (SkillTemplateID) super.getID();

View File

@@ -2,6 +2,8 @@ package com.l2jserver.model.template;
import com.l2jserver.model.id.TemplateID;
public interface Template {
public interface Template<T> {
T create();
TemplateID<?> getID();
}

View File

@@ -1,6 +1,5 @@
package com.l2jserver.model.template.capability;
public interface Enchantable extends TemplateCapability {
void enchant(com.l2jserver.model.world.capability.Enchantable target);
}

View File

@@ -1,26 +1,74 @@
package com.l2jserver.model.world;
import java.util.List;
import com.l2jserver.model.template.SkillTemplate;
import com.l2jserver.model.template.capability.Attackable;
import com.l2jserver.model.world.actor.ActorListener;
import com.l2jserver.model.world.actor.ActorEffects;
import com.l2jserver.model.world.capability.Actor;
import com.l2jserver.model.world.capability.Attacker;
import com.l2jserver.model.world.capability.Castable;
import com.l2jserver.model.world.capability.Equipable;
import com.l2jserver.model.world.capability.Equiper;
import com.l2jserver.util.Coordinate;
import com.l2jserver.util.factory.CollectionFactory;
public abstract class AbstractActor extends AbstractObject implements Actor {
private final List<ActorListener> listeners = CollectionFactory
.newList(ActorListener.class);
protected Race race;
/**
* Represents the actor race.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum Race {
HUMAN(0x00), ELF(0x01), DARK_ELF(0x02), ORC(0x03), DWARF(0x04), KAMAEL(
0x05);
public final int option;
Race(int option) {
this.option = option;
}
public static Race fromOption(int option) {
for (final Race race : values()) {
if (race.option == option)
return race;
}
return null;
}
}
protected Sex sex;
/**
* Represent the sex of an actor.
* <p>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum Sex {
MALE(0x00), FEMALE(0x01);
public final int option;
Sex(int option) {
this.option = option;
}
public static Sex fromOption(int option) {
for (Sex sex : values()) {
if (sex.option == option)
return sex;
}
return null;
}
}
protected int level;
protected int hp;
protected Coordinate position;
protected final ActorEffects effects = new ActorEffects(this);
@Override
public void receiveDamage(int damage) {
// TODO Auto-generated method stub
@@ -78,6 +126,36 @@ public abstract class AbstractActor extends AbstractObject implements Actor {
this.position = coord;
}
/**
* @return the race
*/
public Race getRace() {
return race;
}
/**
* @param race
* the race to set
*/
public void setRace(Race race) {
this.race = race;
}
/**
* @return the sex
*/
public Sex getSex() {
return sex;
}
/**
* @param sex
* the sex to set
*/
public void setSex(Sex sex) {
this.sex = sex;
}
@Override
public int getLevel() {
return level;
@@ -88,6 +166,13 @@ public abstract class AbstractActor extends AbstractObject implements Actor {
this.level = level;
}
/**
* @return the active effects on this actor
*/
public ActorEffects getEffects() {
return effects;
}
@Override
public void die(WorldObject killer) {
// TODO

View File

@@ -1,23 +1,23 @@
package com.l2jserver.model.world;
import java.util.List;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.world.capability.Listenable;
import com.l2jserver.model.world.capability.Playable;
import com.l2jserver.model.world.capability.Spawnable;
import com.l2jserver.model.world.item.ItemEvent;
import com.l2jserver.model.world.item.ItemListener;
import com.l2jserver.util.Coordinate;
import com.l2jserver.util.factory.CollectionFactory;
public class Item extends AbstractObject implements Playable, Spawnable,
Listenable<ItemListener, ItemEvent> {
private final List<ItemListener> listeners = CollectionFactory
.newList(ItemListener.class);
private final ItemTemplateID templateID;
private CharacterID ownerID;
public Item(ItemTemplateID templateID) {
this.templateID = templateID;
}
@Override
public void spawn(Coordinate coordinate) {
@@ -39,7 +39,14 @@ public class Item extends AbstractObject implements Playable, Spawnable,
public void setPosition(Coordinate coord) {
}
/**
* @return the templateID
*/
public ItemTemplateID getTemplateID() {
return templateID;
}
/**
* @return the ownerID
*/

View File

@@ -6,6 +6,10 @@ import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.object.ClanID;
import com.l2jserver.model.id.object.PetID;
import com.l2jserver.model.world.character.CharacterAppearance;
import com.l2jserver.model.world.character.CharacterAttributes;
import com.l2jserver.model.world.character.CharacterBaseAttributes;
import com.l2jserver.model.world.character.CharacterCalculatedAttributes;
import com.l2jserver.model.world.character.CharacterClass;
import com.l2jserver.model.world.character.CharacterInventory;
/**
@@ -26,6 +30,10 @@ public class L2Character extends Player {
* The character name
*/
private String name;
/**
* The class of the character
*/
private CharacterClass characterClass;
/**
* The character's status
*/
@@ -43,6 +51,25 @@ public class L2Character extends Player {
* The appearance of this character
*/
private final CharacterAppearance appearance = new CharacterAppearance(this);
/**
* The base attributes of this character
*/
private final CharacterBaseAttributes baseAttributes;
/**
* The attributes of this character
*/
private final CharacterAttributes attributes;
/**
* Creates a new instance
*
* @param baseAttributes
* the base attribute for this character
*/
public L2Character(CharacterBaseAttributes baseAttributes) {
this.baseAttributes = baseAttributes;
this.attributes = new CharacterCalculatedAttributes(this);
}
@Override
public CharacterID getID() {
@@ -112,6 +139,21 @@ public class L2Character extends Player {
this.name = name;
}
/**
* @return the characterClass
*/
public CharacterClass getCharacterClass() {
return characterClass;
}
/**
* @param characterClass
* the characterClass to set
*/
public void setCharacterClass(CharacterClass characterClass) {
this.characterClass = characterClass;
}
/**
* @return the online
*/
@@ -155,4 +197,18 @@ public class L2Character extends Player {
public CharacterAppearance getAppearance() {
return appearance;
}
/**
* @return the base attributes
*/
public CharacterBaseAttributes getBaseAttributes() {
return baseAttributes;
}
/**
* @return the attributes
*/
public CharacterAttributes getAttributes() {
return attributes;
}
}

View File

@@ -12,9 +12,6 @@ import com.l2jserver.util.factory.CollectionFactory;
public class Party extends AbstractObject implements
Listenable<PartyListener, PartyEvent>, Joinable<L2Character> {
private final List<PartyListener> listeners = CollectionFactory
.newList(PartyListener.class);
private final List<CharacterID> members = CollectionFactory
.newList(CharacterID.class);

View File

@@ -0,0 +1,18 @@
package com.l2jserver.model.world.actor;
import com.l2jserver.model.world.capability.Actor;
public class ActorEffects {
private final Actor actor;
public ActorEffects(Actor actor) {
this.actor = actor;
}
/**
* @return the actor
*/
public Actor getActor() {
return actor;
}
}

View File

@@ -1,6 +1,7 @@
package com.l2jserver.model.world.capability;
import com.l2jserver.model.world.AbstractObject;
import com.l2jserver.model.world.actor.ActorEffects;
import com.l2jserver.model.world.actor.ActorEvent;
import com.l2jserver.model.world.actor.ActorListener;
@@ -13,5 +14,5 @@ import com.l2jserver.model.world.actor.ActorListener;
public interface Actor extends Listenable<ActorListener, ActorEvent>,
Spawnable, Positionable, Damagable, Attackable, Attacker, Castable,
Caster, Levelable, Killable, Equiper, Equipable {
ActorEffects getEffects();
}

View File

@@ -10,9 +10,11 @@ import com.l2jserver.model.world.AbstractObject;
*/
public interface Equiper extends ObjectCapability {
void equip(Equipable equipable);
boolean isEquiped(Equipable equipment);
boolean isEquiped(com.l2jserver.model.template.capability.Equipable equipable);
boolean isEquiped(
com.l2jserver.model.template.capability.Equipable equipable);
void setEquipment(Object slot, Equipable equipment);

View File

@@ -10,5 +10,6 @@ import com.l2jserver.util.Coordinate;
*/
public interface Positionable extends ObjectCapability {
Coordinate getPosition();
void setPosition(Coordinate coord);
}

View File

@@ -25,21 +25,19 @@ public class CharacterAppearance {
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum CharacterFace {
FACE1((byte) 0x00),
FACE_A(0x00),
FACE2((byte) 0x01),
FACE_B(0x01),
FACE3((byte) 0x02),
FACE_C(0x02);
FACE4((byte) 0x03);
public final int option;
public final byte option;
CharacterFace(byte option) {
CharacterFace(int option) {
this.option = option;
}
public static CharacterFace fromOption(byte option) {
public static CharacterFace fromOption(int option) {
for (CharacterFace face : values()) {
if (face.option == option)
return face;
@@ -59,21 +57,21 @@ public class CharacterAppearance {
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum CharacterHairColor {
COLOR1((byte) 0x00),
COLOR_A(0x00),
COLOR2((byte) 0x01),
COLOR_B(0x01),
COLOR3((byte) 0x02),
COLOR_C(0x02),
COLOR4((byte) 0x03);
COLOR_D(0x03);
public final byte option;
public final int option;
CharacterHairColor(byte option) {
CharacterHairColor(int option) {
this.option = option;
}
public static CharacterHairColor fromOption(byte option) {
public static CharacterHairColor fromOption(int option) {
for (CharacterHairColor color : values()) {
if (color.option == option)
return color;
@@ -93,21 +91,23 @@ public class CharacterAppearance {
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum CharacterHairStyle {
STYLE1((byte) 0x00),
STYLE_A(0x00),
STYLE2((byte) 0x01),
STYLE_B(0x01),
STYLE3((byte) 0x02),
STYLE_C(0x02),
STYLE4((byte) 0x03);
STYLE_D(0x03),
public final byte option;
STYLE_E(0x04);
CharacterHairStyle(byte option) {
public final int option;
CharacterHairStyle(int option) {
this.option = option;
}
public static CharacterHairStyle fromOption(byte option) {
public static CharacterHairStyle fromOption(int option) {
for (CharacterHairStyle style : values()) {
if (style.option == option)
return style;
@@ -116,23 +116,6 @@ public class CharacterAppearance {
}
}
/**
* The character sex
*/
private CharacterSex sex;
/**
* Represent the sex of an character.
* <p>
* TODO this will be moved soon: not only characters have sex, NPC can
* have'em too.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum CharacterSex {
MALE, FEMALE;
}
/**
* An alternative name. It will be displayed in-game.
* <p>
@@ -148,14 +131,16 @@ public class CharacterAppearance {
/**
* The name color
* <p>
* <b>This is not persisted!</b>
*/
private RGBColor nameColor = new RGBColor((byte) 0xFF, (byte) 0xFF,
(byte) 0xFF);
private RGBColor nameColor = RGBColor.fromInteger(0xFFFFFF);
/**
* The title color
* <p>
* <b>This is not persisted!</b>
*/
private RGBColor titleColor = new RGBColor((byte) 0xFF, (byte) 0xFF,
(byte) 0x77);
private RGBColor titleColor = RGBColor.fromInteger(0xFFFF77);
public CharacterAppearance(L2Character character) {
this.character = character;
@@ -206,21 +191,6 @@ public class CharacterAppearance {
this.hairStyle = hairStyle;
}
/**
* @return the character sex
*/
public CharacterSex getSex() {
return sex;
}
/**
* @param sex
* the character sex to set
*/
public void setSex(CharacterSex sex) {
this.sex = sex;
}
/**
* @return the alternative name
*/

View File

@@ -0,0 +1,93 @@
package com.l2jserver.model.world.character;
public interface CharacterAttributes {
/**
* @return the intelligence
*/
public int getIntelligence();
/**
* @return the strength
*/
public int getStrength();
/**
* @return the concentration
*/
public int getConcentration();
/**
* @return the mentality
*/
public int getMentality();
/**
* @return the dextry
*/
public int getDextry();
/**
* @return the witness
*/
public int getWitness();
/**
* @return the physicalAttack
*/
public int getPhysicalAttack();
/**
* @return the magicalAttack
*/
public int getMagicalAttack();
/**
* @return the physicalDefense
*/
public int getPhysicalDefense();
/**
* @return the magicalDefense
*/
public int getMagicalDefense();
/**
* @return the attackSpeed
*/
public int getAttackSpeed();
/**
* @return the castSpeed
*/
public int getCastSpeed();
/**
* @return the accuracy
*/
public int getAccuracy();
/**
* @return the criticalChance
*/
public int getCriticalChance();
/**
* @return the evasionChance
*/
public int getEvasionChance();
/**
* @return the movement speed
*/
public int getMoveSpeed();
/**
* @return the maxWeigth
*/
public int getMaxWeigth();
/**
* @return the craft
*/
public boolean canCraft();
}

View File

@@ -0,0 +1,276 @@
package com.l2jserver.model.world.character;
/**
* Defines the attributes of an character
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterBaseAttributes implements CharacterAttributes {
/**
* The character intelligence
*/
private final int intelligence;
/**
* The character strength
*/
private final int strength;
/**
* The character concentration
*/
private final int concentration;
/**
* The character mentality power
*/
private final int mentality;
/**
* The character dextry
*/
private final int dextry;
/**
* The character witness
*/
private final int witness;
/**
* The default physical attack
*/
private final int physicalAttack;
/**
* The default magical attack
*/
private final int magicalAttack;
/**
* The physical defense
*/
private final int physicalDefense;
/**
* The magical defense
*/
private final int magicalDefense;
/**
* The physical attack speed
*/
private final int attackSpeed;
/**
* The "magical attack speed" (aka cast speed)
*/
private final int castSpeed;
/**
* The character accuracy
*/
private final int accuracy;
/**
* Chance of issuing an critical attack
*/
private final int criticalChance;
/**
* Chance of avoiding an attack
*/
private final int evasionChance;
/**
* The character's movement speed
*/
private final int moveSpeed;
/**
* The maximum weigth in items to be carried in the inventory
*/
private final int maxWeigth;
/**
* If this character can craft
*/
private final boolean craft;
/**
* Creates a new instance
*
* @param intelligence
* the intelligence
* @param strength
* the strength
* @param concentration
* the concentration
* @param mentality
* the mentality
* @param dextry
* the dextry
* @param witness
* the witness
* @param physicalAttack
* the physical attack
* @param magicalAttack
* the magical attack
* @param physicalDefense
* the physical defense
* @param magicalDefense
* the magical defense
* @param attackSpeed
* the attack speed
* @param castSpeed
* the cast speed
* @param accuracy
* the accuracy
* @param criticalChance
* the critical chance
* @param evasionChance
* the evasion chance
* @param maxWeigth
* the maximum weight in inventory
* @param moveSpeed
* the character movement speed
* @param craft
* if the character can craft items
*/
public CharacterBaseAttributes(int intelligence, int strength,
int concentration, int mentality, int dextry, int witness,
int physicalAttack, int magicalAttack, int physicalDefense,
int magicalDefense, int attackSpeed, int castSpeed, int accuracy,
int criticalChance, int evasionChance, int moveSpeed,
int maxWeigth, boolean craft) {
this.intelligence = intelligence;
this.strength = strength;
this.concentration = concentration;
this.mentality = mentality;
this.dextry = dextry;
this.witness = witness;
this.physicalAttack = physicalAttack;
this.magicalAttack = magicalAttack;
this.physicalDefense = physicalDefense;
this.magicalDefense = magicalDefense;
this.attackSpeed = attackSpeed;
this.castSpeed = castSpeed;
this.accuracy = accuracy;
this.criticalChance = criticalChance;
this.evasionChance = evasionChance;
this.moveSpeed = moveSpeed;
this.maxWeigth = maxWeigth;
this.craft = craft;
}
/**
* @return the intelligence
*/
public int getIntelligence() {
return intelligence;
}
/**
* @return the strength
*/
public int getStrength() {
return strength;
}
/**
* @return the concentration
*/
public int getConcentration() {
return concentration;
}
/**
* @return the mentality
*/
public int getMentality() {
return mentality;
}
/**
* @return the dextry
*/
public int getDextry() {
return dextry;
}
/**
* @return the witness
*/
public int getWitness() {
return witness;
}
/**
* @return the physicalAttack
*/
public int getPhysicalAttack() {
return physicalAttack;
}
/**
* @return the magicalAttack
*/
public int getMagicalAttack() {
return magicalAttack;
}
/**
* @return the physicalDefense
*/
public int getPhysicalDefense() {
return physicalDefense;
}
/**
* @return the magicalDefense
*/
public int getMagicalDefense() {
return magicalDefense;
}
/**
* @return the attackSpeed
*/
public int getAttackSpeed() {
return attackSpeed;
}
/**
* @return the castSpeed
*/
public int getCastSpeed() {
return castSpeed;
}
/**
* @return the accuracy
*/
public int getAccuracy() {
return accuracy;
}
/**
* @return the criticalChance
*/
public int getCriticalChance() {
return criticalChance;
}
/**
* @return the evasionChance
*/
public int getEvasionChance() {
return evasionChance;
}
/**
* @return the moveSpeed
*/
public int getMoveSpeed() {
return moveSpeed;
}
/**
* @return the maxWeigth
*/
public int getMaxWeigth() {
return maxWeigth;
}
/**
* @return the craft
*/
public boolean canCraft() {
return craft;
}
}

View File

@@ -0,0 +1,86 @@
package com.l2jserver.model.world.character;
import com.l2jserver.model.world.L2Character;
public class CharacterCalculatedAttributes implements CharacterAttributes {
private final L2Character character;
private final CharacterAttributes baseAttributes;
public CharacterCalculatedAttributes(L2Character character) {
this.character = character;
this.baseAttributes = this.character.getBaseAttributes();
}
public int getIntelligence() {
return baseAttributes.getIntelligence();
}
public int getStrength() {
return baseAttributes.getStrength();
}
public int getConcentration() {
return baseAttributes.getConcentration();
}
public int getMentality() {
return baseAttributes.getMentality();
}
public int getDextry() {
return baseAttributes.getDextry();
}
public int getWitness() {
return baseAttributes.getWitness();
}
public int getPhysicalAttack() {
return baseAttributes.getPhysicalAttack();
}
public int getMagicalAttack() {
return baseAttributes.getMagicalAttack();
}
public int getPhysicalDefense() {
return baseAttributes.getPhysicalDefense();
}
public int getMagicalDefense() {
return baseAttributes.getMagicalDefense();
}
public int getAttackSpeed() {
return baseAttributes.getAttackSpeed();
}
public int getCastSpeed() {
return baseAttributes.getCastSpeed();
}
public int getAccuracy() {
return baseAttributes.getAccuracy();
}
public int getCriticalChance() {
return baseAttributes.getCriticalChance();
}
public int getEvasionChance() {
return baseAttributes.getEvasionChance();
}
public int getMoveSpeed() {
return baseAttributes.getMoveSpeed();
}
public int getMaxWeigth() {
return baseAttributes.getMaxWeigth();
}
public boolean canCraft() {
return baseAttributes.canCraft();
}
}

View File

@@ -0,0 +1,113 @@
package com.l2jserver.model.world.character;
import com.l2jserver.model.world.AbstractActor.Race;
/**
* Defines all the possible classes for an character
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
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 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),
/**
* 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 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),
/**
* 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 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);
// TODO dwarf classes
// TODO kamael classes
// TODO 3rd classes
public final int id;
public final boolean mystic;
public final boolean summoner;
public final Race race;
public final CharacterClass parent;
private CharacterClass(int id, boolean mystic, boolean summoner, Race race,
CharacterClass parent) {
this.id = id;
this.mystic = mystic;
this.summoner = summoner;
this.race = race;
this.parent = parent;
}
private CharacterClass(int id, CharacterClass parent) {
this(id, parent.mystic, parent.summoner, parent.race, parent);
}
private CharacterClass(int id, Race race, CharacterClass parent) {
this(id, false, false, race, parent);
}
private CharacterClass(int id, Race race) {
this(id, false, false, race, null);
}
private CharacterClass(int id, boolean mystic, Race race) {
this(id, mystic, false, race, null);
}
private CharacterClass(int id, boolean mystic, boolean summoner,
CharacterClass parent) {
this(id, mystic, summoner, parent.race, parent);
}
public CharacterClass fromID(int id) {
for (final CharacterClass c : values()) {
if (c.id == id)
return c;
}
return null;
}
/**
* Calculates the level of the class. Base class is zero.
*
* @return the class level
*/
public final int level() {
if (parent == null)
return 0;
return 1 + parent.level();
}
}

View File

@@ -5,5 +5,6 @@ import com.l2jserver.util.Coordinate;
public interface SpawnEvent extends WorldEvent {
Spawnable getObject();
Coordinate getCoordinate();
}

View File

@@ -11,8 +11,8 @@ public class AndFilter<O extends WorldObject> implements WorldObjectFilter<O> {
@Override
public boolean accept(O object) {
for(final WorldObjectFilter<O> filter : filters) {
if(!filter.accept(object))
for (final WorldObjectFilter<O> filter : filters) {
if (!filter.accept(object))
return false;
}
return true;

View File

@@ -11,8 +11,8 @@ public class OrFilter<O extends WorldObject> implements WorldObjectFilter<O> {
@Override
public boolean accept(O object) {
for(final WorldObjectFilter<O> filter : filters) {
if(filter.accept(object))
for (final WorldObjectFilter<O> filter : filters) {
if (filter.accept(object))
return true;
}
return false;

View File

@@ -3,7 +3,8 @@ package com.l2jserver.model.world.filter.impl;
import com.l2jserver.model.world.WorldObject;
import com.l2jserver.model.world.filter.WorldObjectFilter;
public class InstanceFilter<T extends WorldObject> implements WorldObjectFilter<T> {
public class InstanceFilter<T extends WorldObject> implements
WorldObjectFilter<T> {
private final Class<?> type;
public InstanceFilter(Class<?> instance) {

View File

@@ -4,7 +4,8 @@ import com.google.inject.Inject;
import com.l2jserver.service.ServiceManager;
import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.logging.LoggingService;
import com.l2jserver.service.game.scripting.ScriptingService;
import com.l2jserver.service.game.template.TemplateService;
import com.l2jserver.service.network.NetworkService;
public class GameServerInitializationRoutine implements Routine<Boolean> {
@@ -17,10 +18,13 @@ public class GameServerInitializationRoutine implements Routine<Boolean> {
@Override
public Boolean call() throws Exception {
serviceManager.start(LoggingService.class);
// serviceManager.start(LoggingService.class);
serviceManager.start(ConfigurationService.class);
serviceManager.start(DatabaseService.class);
serviceManager.start(ScriptingService.class);
serviceManager.start(TemplateService.class);
serviceManager.start(NetworkService.class);
return true;
}

View File

@@ -2,6 +2,10 @@ package com.l2jserver.service;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
import com.l2jserver.service.game.scripting.ScriptingService;
import com.l2jserver.service.game.scripting.ScriptingServiceImpl;
import com.l2jserver.service.game.template.StaticTemplateService;
import com.l2jserver.service.game.template.TemplateService;
import com.l2jserver.service.game.world.WorldEventDispatcher;
import com.l2jserver.service.game.world.WorldEventDispatcherImpl;
import com.l2jserver.service.game.world.WorldService;
@@ -14,6 +18,10 @@ public class ServiceModule extends AbstractModule {
protected void configure() {
bind(NetworkService.class).to(NettyNetworkService.class).in(
Scopes.SINGLETON);
bind(ScriptingService.class).to(ScriptingServiceImpl.class).in(
Scopes.SINGLETON);
bind(TemplateService.class).to(StaticTemplateService.class).in(
Scopes.SINGLETON);
bind(WorldService.class).to(WorldServiceImpl.class)
.in(Scopes.SINGLETON);

View File

@@ -212,7 +212,7 @@ public class ScriptContextImpl implements ScriptContext {
}
@Override
public Collection<ScriptContext> getChildScriptContexts() {
public synchronized Collection<ScriptContext> getChildScriptContexts() {
return childScriptContexts;
}
@@ -220,7 +220,7 @@ public class ScriptContextImpl implements ScriptContext {
* {@inheritDoc}
*/
@Override
public void addChildScriptContext(ScriptContext context) {
public synchronized void addChildScriptContext(ScriptContext context) {
synchronized (this) {
if (childScriptContexts == null) {
childScriptContexts = new HashSet<ScriptContext>();

View File

@@ -19,6 +19,8 @@ package com.l2jserver.service.game.scripting.impl.javacc;
import java.io.File;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -109,11 +111,20 @@ public class ClassFileManager extends
@Override
public synchronized ScriptClassLoaderImpl getClassLoader(Location location) {
if (loader == null) {
if (parentClassLoader != null) {
loader = new ScriptClassLoaderImpl(this, parentClassLoader);
} else {
loader = new ScriptClassLoaderImpl(this);
}
return AccessController
.doPrivileged(new PrivilegedAction<ScriptClassLoaderImpl>() {
@Override
public ScriptClassLoaderImpl run() {
if (parentClassLoader != null) {
return new ScriptClassLoaderImpl(
ClassFileManager.this,
ClassFileManager.this.parentClassLoader);
} else {
return new ScriptClassLoaderImpl(
ClassFileManager.this);
}
}
});
}
return loader;
}

View File

@@ -25,8 +25,7 @@ import java.net.URLConnection;
/**
* This class represents URL Connection that is used to "connect" to scripts
* binary data that was loaded by specified
* {@link ScriptCompilerImpl}.<br>
* binary data that was loaded by specified {@link ScriptCompilerImpl}.<br>
* <br>
* TODO: Implement all methods of {@link URLConnection} to ensure valid
* behaviour

View File

@@ -22,6 +22,7 @@ public class StaticTemplateService extends AbstractService implements
private ScriptContext context;
@SuppressWarnings("rawtypes")
private Map<TemplateID, Template> templates = CollectionFactory.newMap(
TemplateID.class, Template.class);
@@ -52,18 +53,18 @@ public class StaticTemplateService extends AbstractService implements
@Override
@SuppressWarnings("unchecked")
public <T extends Template> T getTemplate(TemplateID<T> id) {
public <T extends Template<?>> T getTemplate(TemplateID<T> id) {
return (T) templates.get(id);
}
public void addTemplate(Class<? extends Template> t) {
final Template template = injector.getInstance(t);
public void addTemplate(Class<? extends Template<?>> t) {
final Template<?> template = injector.getInstance(t);
System.out.println(template.getID() + " -> " + template);
if (template.getID() != null)
templates.put(template.getID(), template);
}
public void removeTemplate(Template t) {
public void removeTemplate(Template<?> t) {
// TODO templates.remove(t);
}

View File

@@ -9,6 +9,7 @@ import com.l2jserver.service.configuration.Configuration.ConfigurationName;
public interface StaticTemplateServiceConfiguration extends Configuration {
@ConfigurationPropertyGetter(name = "template.descriptor", defaultValue = "data/script/template/template.xml")
File getTemplateDescriptor();
@ConfigurationPropertySetter(name = "template.descriptor")
void setTemplateDescriptor(File file);
}

View File

@@ -14,7 +14,7 @@ public interface TemplateService extends Service {
* the template id
* @return the template
*/
<T extends Template> T getTemplate(TemplateID<T> id);
<T extends Template<?>> T getTemplate(TemplateID<T> id);
/**
* Reload the template list.

View File

@@ -4,6 +4,9 @@ import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.world.capability.Listenable;
import com.l2jserver.model.world.event.WorldEvent;
@@ -16,6 +19,9 @@ import com.l2jserver.util.factory.CollectionFactory;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class WorldEventDispatcherImpl implements WorldEventDispatcher {
private static final Logger log = LoggerFactory
.getLogger(WorldEventDispatcherImpl.class);
private final Timer timer = new Timer();
private Queue<ListenerIDPair> listeners = CollectionFactory
@@ -39,10 +45,12 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
}
public void dispatch(WorldEvent event) {
log.debug("Queing dispatch for event {}", event);
events.add(event);
}
public void doDispatch(WorldEvent event) {
log.debug("Dispatching event {}", event);
final Listenable<?, ?>[] objects = event.getDispatchableObjects();
for (final ListenerIDPair pair : listeners) {
for (Listenable<?, ?> obj : objects) {
@@ -54,6 +62,9 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
if (pair.dispatch(event))
continue;
} catch (ClassCastException e) {
log.debug(
"Exception in Listener. This might indicate an implementation issue in {}",
pair.listener.getClass());
}
listeners.remove(pair);
}
@@ -64,6 +75,7 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
@SuppressWarnings("unchecked")
public <E extends WorldEvent, L extends WorldListener<E>> void addListener(
Listenable<L, E> object, WorldListener<E> listener) {
log.debug("Adding new listener {} to {}", listener, object.getID());
listeners.add(new ListenerIDPair(object.getID(),
(WorldListener<WorldEvent>) listener));
}
@@ -72,6 +84,7 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
@SuppressWarnings("unchecked")
public <E extends WorldEvent, L extends WorldListener<E>> void addListener(
ObjectID<? extends Listenable<L, E>> id, WorldListener<E> listener) {
log.debug("Adding new listener {} to {}", listener, id);
listeners.add(new ListenerIDPair(id,
(WorldListener<WorldEvent>) listener));
}
@@ -80,6 +93,7 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
@SuppressWarnings("unchecked")
public <E extends WorldEvent, L extends WorldListener<E>> void removeListener(
Listenable<L, E> object, WorldListener<E> listener) {
log.debug("Removing new listener {} from {}", listener, object.getID());
listeners.remove(new ListenerIDPair(object.getID(),
(WorldListener<WorldEvent>) listener));
}
@@ -88,6 +102,7 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
@SuppressWarnings("unchecked")
public <E extends WorldEvent, L extends WorldListener<E>> void removeListener(
ObjectID<? extends Listenable<L, E>> id, WorldListener<E> listener) {
log.debug("Removing new listener {} from {}", listener, id);
listeners.remove(new ListenerIDPair(id,
(WorldListener<WorldEvent>) listener));
}

View File

@@ -4,6 +4,9 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.model.world.WorldObject;
import com.l2jserver.model.world.filter.WorldObjectFilter;
@@ -15,6 +18,9 @@ import com.l2jserver.service.ServiceStopException;
import com.l2jserver.util.factory.CollectionFactory;
public class WorldServiceImpl extends AbstractService implements WorldService {
private static final Logger log = LoggerFactory
.getLogger(WorldServiceImpl.class);
private final Set<WorldObject> objects = CollectionFactory
.newSet(WorldObject.class);
private final WorldEventDispatcher dispatcher;
@@ -31,11 +37,13 @@ public class WorldServiceImpl extends AbstractService implements WorldService {
@Override
public void add(WorldObject object) {
log.debug("Adding object {} to world", object);
objects.add(object);
}
@Override
public void remove(WorldObject object) {
log.debug("Removing object {} from world", object);
objects.remove(object);
}
@@ -51,6 +59,7 @@ public class WorldServiceImpl extends AbstractService implements WorldService {
@Override
public <T extends WorldObject> List<T> list(WorldObjectFilter<T> filter) {
log.debug("Listing objects with filter {}", filter);
final List<T> list = CollectionFactory.newList(null);
for (final T object : this.iterable(filter)) {
list.add(object);
@@ -60,6 +69,7 @@ public class WorldServiceImpl extends AbstractService implements WorldService {
@Override
public <T extends WorldObject> List<T> list(Class<T> type) {
log.debug("Listing of type {}", type);
return list(new InstanceFilter<T>(type));
}

View File

@@ -12,7 +12,8 @@ import com.l2jserver.game.net.Lineage2PipelineFactory;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.configuration.ConfigurationService;
public class NettyNetworkService extends AbstractService implements NetworkService {
public class NettyNetworkService extends AbstractService implements
NetworkService {
private final NetworkConfiguration config;
private final Injector injector;
private ServerBootstrap server;

View File

@@ -16,9 +16,10 @@ public class BufferUtil {
}
public static final void writeString(ChannelBuffer buffer, String str) {
for (char c : str.toCharArray()) {
buffer.writeChar(c);
}
buffer.writeChar(0x00);
if (str != null)
for (char c : str.toCharArray()) {
buffer.writeChar(c);
}
buffer.writeChar('\000');
}
}

View File

@@ -5,7 +5,7 @@ public class Coordinate {
private final int y;
private final int z;
public Coordinate(int x, int y, int z) {
protected Coordinate(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
@@ -22,9 +22,13 @@ public class Coordinate {
public int getZ() {
return z;
}
public int getDistance(Coordinate other) {
//TODO calculation
// TODO calculation
return x + y + z;
}
public static Coordinate fromXYZ(int x, int y, int z) {
return new Coordinate(x, y, z);
}
}

View File

@@ -11,26 +11,23 @@ package com.l2jserver.util;
import java.util.Arrays;
/*
* Modified for Trove to use the java.util.Arrays sort/search
* algorithms instead of those provided with colt.
*/
/**
* Used to keep hash table capacities prime numbers.
* Not of interest for users; only for implementors of hashtables.
*
* <p>Choosing prime numbers as hash table capacities is a good idea
* to keep them working fast, particularly under hash table
* expansions.
*
* <p>However, JDK 1.2, JGL 3.1 and many other toolkits do nothing to
* keep capacities prime. This class provides efficient means to
* choose prime capacities.
*
* <p>Choosing a prime is <tt>O(log 300)</tt> (binary search in a list
* of 300 ints). Memory requirements: 1 KB static memory.
*
* Used to keep hash table capacities prime numbers. Not of interest for users;
* only for implementors of hashtables.
*
* <p>
* Choosing prime numbers as hash table capacities is a good idea to keep them
* working fast, particularly under hash table expansions.
*
* <p>
* However, JDK 1.2, JGL 3.1 and many other toolkits do nothing to keep
* capacities prime. This class provides efficient means to choose prime
* capacities.
*
* <p>
* Choosing a prime is <tt>O(log 300)</tt> (binary search in a list of 300
* ints). Memory requirements: 1 KB static memory.
*
* @author wolfgang.hoschek@cern.ch
* @version 1.0, 09/24/99
*/
@@ -39,119 +36,224 @@ public final class PrimeFinder {
* The largest prime this class can generate; currently equal to
* <tt>Integer.MAX_VALUE</tt>.
*/
public static final int LARGEST_PRIME = Integer.MAX_VALUE; //yes, it is prime.
public static final int LARGEST_PRIME = Integer.MAX_VALUE; // yes, it is
// prime.
/**
* The prime number list consists of 11 chunks.
*
*
* Each chunk contains prime numbers.
*
* A chunk starts with a prime P1. The next element is a prime
* P2. P2 is the smallest prime for which holds: P2 >= 2*P1.
*
* The next element is P3, for which the same holds with respect
* to P2, and so on.
*
* Chunks are chosen such that for any desired capacity >= 1000
* the list includes a prime number <= desired capacity * 1.11.
*
* Therefore, primes can be retrieved which are quite close to any
* desired capacity, which in turn avoids wasting memory.
*
*
* A chunk starts with a prime P1. The next element is a prime P2. P2 is the
* smallest prime for which holds: P2 >= 2*P1.
*
* The next element is P3, for which the same holds with respect to P2, and
* so on.
*
* Chunks are chosen such that for any desired capacity >= 1000 the list
* includes a prime number <= desired capacity * 1.11.
*
* Therefore, primes can be retrieved which are quite close to any desired
* capacity, which in turn avoids wasting memory.
*
* For example, the list includes
* 1039,1117,1201,1277,1361,1439,1523,1597,1759,1907,2081.
*
* So if you need a prime >= 1040, you will find a prime <=
* 1040*1.11=1154.
*
*
* So if you need a prime >= 1040, you will find a prime <= 1040*1.11=1154.
*
* Chunks are chosen such that they are optimized for a hashtable
* growthfactor of 2.0;
*
*
* If your hashtable has such a growthfactor then, after initially
* "rounding to a prime" upon hashtable construction, it will
* later expand to prime capacities such that there exist no
* better primes.
*
* In total these are about 32*10=320 numbers -> 1 KB of static
* memory needed.
*
* "rounding to a prime" upon hashtable construction, it will later expand
* to prime capacities such that there exist no better primes.
*
* In total these are about 32*10=320 numbers -> 1 KB of static memory
* needed.
*
* If you are stingy, then delete every second or fourth chunk.
*/
private static final int[] PRIME_CAPACITIES = {
//chunk #0
LARGEST_PRIME,
//chunk #1
5,11,23,47,97,197,397,797,1597,3203,6421,12853,25717,51437,102877,205759,
411527,823117,1646237,3292489,6584983,13169977,26339969,52679969,105359939,
210719881,421439783,842879579,1685759167,
//chunk #2
433,877,1759,3527,7057,14143,28289,56591,113189,226379,452759,905551,1811107,
3622219,7244441,14488931,28977863,57955739,115911563,231823147,463646329,927292699,
1854585413,
//chunk #3
953,1907,3821,7643,15287,30577,61169,122347,244703,489407,978821,1957651,3915341,
7830701,15661423,31322867,62645741,125291483,250582987,501165979,1002331963,
2004663929,
//chunk #4
1039,2081,4177,8363,16729,33461,66923,133853,267713,535481,1070981,2141977,4283963,
8567929,17135863,34271747,68543509,137087021,274174111,548348231,1096696463,
//chunk #5
31,67,137,277,557,1117,2237,4481,8963,17929,35863,71741,143483,286973,573953,
1147921,2295859,4591721,9183457,18366923,36733847,73467739,146935499,293871013,
587742049,1175484103,
//chunk #6
599,1201,2411,4831,9677,19373,38747,77509,155027,310081,620171,1240361,2480729,
4961459,9922933,19845871,39691759,79383533,158767069,317534141,635068283,1270136683,
//chunk #7
311,631,1277,2557,5119,10243,20507,41017,82037,164089,328213,656429,1312867,
2625761,5251529,10503061,21006137,42012281,84024581,168049163,336098327,672196673,
1344393353,
//chunk #8
3,7,17,37,79,163,331,673,1361,2729,5471,10949,21911,43853,87719,175447,350899,
701819,1403641,2807303,5614657,11229331,22458671,44917381,89834777,179669557,
359339171,718678369,1437356741,
//chunk #9
43,89,179,359,719,1439,2879,5779,11579,23159,46327,92657,185323,370661,741337,
1482707,2965421,5930887,11861791,23723597,47447201,94894427,189788857,379577741,
759155483,1518310967,
//chunk #10
379,761,1523,3049,6101,12203,24407,48817,97649,195311,390647,781301,1562611,
3125257,6250537,12501169,25002389,50004791,100009607,200019221,400038451,800076929,
1600153859
};
static { //initializer
// chunk #0
LARGEST_PRIME,
// chunk #1
5, 11, 23, 47, 97, 197,
397,
797,
1597,
3203,
6421,
12853,
25717,
51437,
102877,
205759,
411527,
823117,
1646237,
3292489,
6584983,
13169977,
26339969,
52679969,
105359939,
210719881,
421439783,
842879579,
1685759167,
// chunk #2
433, 877, 1759,
3527,
7057,
14143,
28289,
56591,
113189,
226379,
452759,
905551,
1811107,
3622219,
7244441,
14488931,
28977863,
57955739,
115911563,
231823147,
463646329,
927292699,
1854585413,
// chunk #3
953, 1907, 3821, 7643,
15287,
30577,
61169,
122347,
244703,
489407,
978821,
1957651,
3915341,
7830701,
15661423,
31322867,
62645741,
125291483,
250582987,
501165979,
1002331963,
2004663929,
// chunk #4
1039, 2081, 4177, 8363, 16729,
33461,
66923,
133853,
267713,
535481,
1070981,
2141977,
4283963,
8567929,
17135863,
34271747,
68543509,
137087021,
274174111,
548348231,
1096696463,
// chunk #5
31, 67, 137, 277, 557, 1117, 2237, 4481, 8963, 17929, 35863, 71741,
143483,
286973,
573953,
1147921,
2295859,
4591721,
9183457,
18366923,
36733847,
73467739,
146935499,
293871013,
587742049,
1175484103,
// chunk #6
599, 1201, 2411, 4831, 9677, 19373, 38747, 77509, 155027, 310081,
620171, 1240361,
2480729,
4961459,
9922933,
19845871,
39691759,
79383533,
158767069,
317534141,
635068283,
1270136683,
// chunk #7
311, 631, 1277, 2557, 5119, 10243, 20507, 41017, 82037, 164089,
328213, 656429, 1312867, 2625761, 5251529,
10503061,
21006137,
42012281,
84024581,
168049163,
336098327,
672196673,
1344393353,
// chunk #8
3, 7, 17, 37, 79, 163, 331, 673, 1361, 2729, 5471, 10949, 21911,
43853, 87719, 175447, 350899, 701819, 1403641, 2807303, 5614657,
11229331, 22458671, 44917381,
89834777,
179669557,
359339171,
718678369,
1437356741,
// chunk #9
43, 89, 179, 359, 719, 1439, 2879, 5779, 11579, 23159, 46327,
92657, 185323, 370661, 741337, 1482707, 2965421, 5930887, 11861791,
23723597, 47447201, 94894427, 189788857, 379577741,
759155483,
1518310967,
// chunk #10
379, 761, 1523, 3049, 6101, 12203, 24407, 48817, 97649, 195311,
390647, 781301, 1562611, 3125257, 6250537, 12501169, 25002389,
50004791, 100009607, 200019221, 400038451, 800076929, 1600153859 };
static { // initializer
// The above prime numbers are formatted for human readability.
// To find numbers fast, we sort them once and for all.
Arrays.sort(PRIME_CAPACITIES);
}
/**
* Returns a prime number which is <code>&gt;= desiredCapacity</code>
* and very close to <code>desiredCapacity</code> (within 11% if
* Returns a prime number which is <code>&gt;= desiredCapacity</code> and
* very close to <code>desiredCapacity</code> (within 11% if
* <code>desiredCapacity &gt;= 1000</code>).
*
* @param desiredCapacity the capacity desired by the user.
*
* @param desiredCapacity
* the capacity desired by the user.
* @return the capacity which should be used for a hashtable.
*/
public static final int nextPrime(int desiredCapacity) {
int i = Arrays.binarySearch(PRIME_CAPACITIES, desiredCapacity);
if (i<0) {
if (i < 0) {
// desired capacity not found, choose next prime greater
// than desired capacity
i = -i -1; // remember the semantics of binarySearch...
i = -i - 1; // remember the semantics of binarySearch...
}
return PRIME_CAPACITIES[i];
}

View File

@@ -5,7 +5,7 @@ public class RGBColor {
private final byte green;
private final byte blue;
public RGBColor(byte r, byte g, byte b) {
protected RGBColor(byte r, byte g, byte b) {
this.red = r;
this.green = g;
this.blue = b;
@@ -35,4 +35,13 @@ public class RGBColor {
public byte[] toByteArray() {
return new byte[] { red, green, blue };
}
public static RGBColor fromByteArray(byte[] rgb) {
return new RGBColor(rgb[0], rgb[1], rgb[2]);
}
public static RGBColor fromInteger(int color) {
return new RGBColor((byte) (color << 0), (byte) (color << 8),
(byte) (color << 16));
}
}