1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-05 23:22:47 +00:00

Written javadoc for many classes

Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
2011-05-14 01:51:40 -03:00
parent 14b928cc3b
commit e9c6f1b027
85 changed files with 1205 additions and 26 deletions

View File

@@ -1,11 +1,17 @@
package com.l2jserver;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.l2jserver.db.dao.DAOModuleMySQL5;
import com.l2jserver.model.id.factory.IDFactoryModule;
import com.l2jserver.routines.GameServerInitializationRoutine;
import com.l2jserver.service.ServiceModule;
/**
* The game server Google Guice {@link Module}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class GameServerModule extends AbstractModule {
@Override
protected void configure() {

View File

@@ -2,5 +2,10 @@ package com.l2jserver;
import com.l2jserver.service.configuration.Configuration;
/**
* General configuration interface
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface GeneralConfiguration extends Configuration {
}

View File

@@ -1,5 +1,10 @@
package com.l2jserver;
/**
* Constant values for this L2J compilation
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2JConstants {
/**
* Indicated the supported protocol for this compilation.

View File

@@ -3,10 +3,23 @@ package com.l2jserver;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* The L2JGameServer class
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2JGameServer {
/**
* The server injector
*/
private final Injector injector = Guice
.createInjector(new GameServerModule());
/**
* Get the injector
*
* @return the injector
*/
public Injector getInjector() {
return injector;
}

View File

@@ -6,8 +6,18 @@ package com.l2jserver;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum ProtocolVersion {
RELEASE(0), //UNK ID
FREYA(216);
/**
* Release version
*/
RELEASE(0),
/**
* Freya(216)
*/
FREYA(216, RELEASE),
/**
* High5(217)
*/
HIGH5(217, FREYA);
public final ProtocolVersion parent;
public final int version;
@@ -15,20 +25,20 @@ public enum ProtocolVersion {
ProtocolVersion(int version) {
this(version, null);
}
ProtocolVersion(int version, ProtocolVersion parent) {
this.version = version;
this.parent = parent;
}
public boolean supports(ProtocolVersion version) {
if(this == version)
if (this == version)
return true;
if(this.parent == null)
if (this.parent == null)
return false;
return this.parent.supports(version);
}
public static ProtocolVersion fromVersion(int version) {
for (ProtocolVersion v : values()) {
if (v.version == version)

View File

@@ -18,17 +18,44 @@ import com.l2jserver.model.world.L2Character;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2Connection {
/**
* The connection channel
*/
private final Channel channel;
/**
* The character object
*/
private L2Character character;
/**
* The Lineage 2 session
*/
private Lineage2Session session;
/**
* The connection state
*/
private ConnectionState state = ConnectionState.CONNECTED;
/**
* Each connection is represented by an state: connected, authenticated and
* in-game.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum ConnectionState {
CONNECTED, AUTHENTICATED, IN_GAME;
}
/**
* The client supported protocol version
*/
private ProtocolVersion version;
/**
* Creates a new instance
*
* @param channel
* the channel
*/
public Lineage2Connection(Channel channel) {
this.channel = channel;
}
@@ -116,6 +143,10 @@ public class Lineage2Connection {
return version.supports(version);
}
/**
* Get the channel
* @return the channel
*/
public Channel getChannel() {
return channel;
}

View File

@@ -1,16 +1,39 @@
package com.l2jserver.game.net;
import java.util.Arrays;
import com.l2jserver.util.BlowFishKeygen;
/**
* Manages the cryptography key used to write/read packets. This class also
* updates the key once data has been sent/received.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2CryptographyKey implements Cloneable {
/**
* The raw key
*/
public final byte[] key;
/**
* Creates a new instance
*
* @param key
* the raw key
*/
public Lineage2CryptographyKey(byte[] key) {
this.key = key;
}
/**
* Crates a new random key
*
* @return the random created key
*/
public static Lineage2CryptographyKey createRandomKey() {
return new Lineage2CryptographyKey(BlowFishKeygen.getRandomKey());
return new Lineage2CryptographyKey(Arrays.copyOf(
BlowFishKeygen.getRandomKey(), 16));
}
/**
@@ -20,10 +43,23 @@ public class Lineage2CryptographyKey implements Cloneable {
return key;
}
/**
* Get the key value for byte index <tt>i</tt>
*
* @param i
* the index i
* @return the key byte
*/
public byte get(int i) {
return key[i & 15];
}
/**
* Updates this key once data has been sent/received.
*
* @param size
* the data size
*/
public void update(int size) {
int old = key[8] & 0xff;
old |= key[9] << 8 & 0xff00;

View File

@@ -17,7 +17,16 @@ import com.l2jserver.game.net.codec.Lineage2PacketReader;
import com.l2jserver.game.net.codec.Lineage2PacketWriter;
import com.l2jserver.game.net.handler.Lineage2PacketHandler;
/**
* This class creates a new instance of {@link ChannelPipeline} and attaches all
* handlers and codecs.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2PipelineFactory implements ChannelPipelineFactory {
/**
* The Google Guice {@link Injector}.
*/
private final Injector injector;
@Inject

View File

@@ -1,14 +1,48 @@
package com.l2jserver.game.net;
/**
* Lineage 2 session with the username and loginserver keys
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2Session {
/**
* The username
*/
private final String username;
/**
* The play key, part 1
*/
private final int playKey1;
/**
* The play key, part 2
*/
private final int playKey2;
/**
* The login key, part 1
*/
private final int loginKey1;
/**
* The login key, part 2
*/
private final int loginKey2;
/**
* Creates a new instance
*
* @param username
* the username
* @param playOK1
* the play key, part 1
* @param playOK2
* the play key, part 2
* @param loginOK1
* the login key, part 1
* @param loginOK2
* the login key, part 2
*/
public Lineage2Session(String username, int playOK1, int playOK2,
int loginOK1, int loginOK2) {
this.username = username;

View File

@@ -7,10 +7,24 @@ import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
import com.l2jserver.game.net.Lineage2CryptographyKey;
/**
* Decrypts encrypted Lineage II packets
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2Decrypter extends OneToOneDecoder {
/**
* The handler name
*/
public static final String HANDLER_NAME = "crypto.decoder";
/**
* Enabled state
*/
private boolean enabled = false;
/**
* Crypto key
*/
private Lineage2CryptographyKey key;
@Override
@@ -37,6 +51,11 @@ public class Lineage2Decrypter extends OneToOneDecoder {
return buffer;
}
/**
* Creates a random key and enables descrypting
*
* @return the generated key
*/
public Lineage2CryptographyKey enable() {
Lineage2CryptographyKey key = Lineage2CryptographyKey.createRandomKey();
this.setKey(key);
@@ -44,6 +63,12 @@ public class Lineage2Decrypter extends OneToOneDecoder {
return key;
}
/**
* Set this decrypter key. The key can only be set once.
*
* @param key
* the key
*/
public void setKey(Lineage2CryptographyKey key) {
if (this.key != null)
throw new IllegalStateException("Key is already set");

View File

@@ -7,10 +7,24 @@ import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
import com.l2jserver.game.net.Lineage2CryptographyKey;
/**
* Encrypts Lineage II packets
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2Encrypter extends OneToOneEncoder {
/**
* The handler name
*/
public static final String HANDLER_NAME = "crypto.encoder";
/**
* Enabled state
*/
private boolean enabled = false;
/**
* Crypto key
*/
private Lineage2CryptographyKey key;
@Override
@@ -37,11 +51,23 @@ public class Lineage2Encrypter extends OneToOneEncoder {
return msg;
}
/**
* Enables this encrypter with the given <tt>key</tt>
*
* @param key
* the key
*/
public void enable(Lineage2CryptographyKey key) {
this.setKey(key);
this.setEnabled(true);
}
/**
* Set this decrypter key. The key can only be set once.
*
* @param key
* the key
*/
public void setKey(Lineage2CryptographyKey key) {
if (this.key != null)
throw new IllegalStateException("Key is already set");

View File

@@ -10,6 +10,12 @@ import org.jboss.netty.handler.codec.frame.FrameDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This decoder parses Lineage II frames. Each frame is has a header of 2 bytes
* unsigned short.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2FrameDecoder extends FrameDecoder {
private static final int HEADER_SIZE = 2;

View File

@@ -5,6 +5,12 @@ import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
/**
* This encoder creates Lineage II frames. Each frame is has a header of 2 bytes
* unsigned short.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2FrameEncoder extends OneToOneEncoder {
@Override
protected Object encode(ChannelHandlerContext ctx, Channel channel,

View File

@@ -21,15 +21,43 @@ import com.l2jserver.game.net.packet.client.RequestGotoLobby;
import com.l2jserver.game.net.packet.client.RequestKeyMapping;
import com.l2jserver.game.net.packet.client.RequestManorList;
/**
* This decoder reads an frame and decodes the packet in it. Each packet has an
* fixed single opcode byte. Once the packet has been identified, reading is
* done by the {@link ClientPacket} class.
* <p>
* Note that some packets have an additional opcode. This class also handle
* those cases.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2PacketReader extends OneToOneDecoder {
/**
* The handler name
*/
public static final String HANDLER_NAME = "packet.reader";
/**
* The Google Guice {@link Injector}
*/
private final Injector injector;
/**
* The logger
*/
private final Logger logger = LoggerFactory
.getLogger(Lineage2PacketReader.class);
/**
* The active Lineage 2 connection
*/
private Lineage2Connection connection;
/**
* Creates a new instance
*
* @param injector
* the injector
*/
@Inject
public Lineage2PacketReader(Injector injector) {
this.injector = injector;
@@ -48,12 +76,26 @@ public class Lineage2PacketReader extends OneToOneDecoder {
return packet;
}
/**
* Crates a new instance of the packet <tt>type</tt>
*
* @param type
* the packet type
* @return the created packet
*/
private ClientPacket createPacket(Class<? extends ClientPacket> type) {
if (type == null)
return null;
return injector.getInstance(type);
}
/**
* Discovers the packet type
*
* @param buffer
* the buffer
* @return the packet class
*/
private Class<? extends ClientPacket> getPacketClass(ChannelBuffer buffer) {
final short opcode = buffer.readUnsignedByte();
switch (opcode) {

View File

@@ -13,12 +13,28 @@ import org.slf4j.LoggerFactory;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.ServerPacket;
/**
* This encoder writes the frame content and encodes the packet in it. Each
* packet has an fixed single opcode byte. Once the packet opcode has been
* written, packet data is written by the {@link ServerPacket} class.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2PacketWriter extends OneToOneEncoder {
/**
* The handler name
*/
public static final String HANDLER_NAME = "packet.writer";
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(Lineage2PacketWriter.class);
/**
* The active Lineage 2 connection
*/
private Lineage2Connection connection;
@Override

View File

@@ -8,7 +8,17 @@ import org.jboss.netty.channel.SimpleChannelHandler;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.ClientPacket;
/**
* This handler dispatches the {@link ClientPacket#process(Lineage2Connection)}
* method and creates a new {@link Lineage2Connection} once a new channel is
* open.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2PacketHandler extends SimpleChannelHandler {
/**
* The Lineage 2 connection
*/
private Lineage2Connection connection;
@Override

View File

@@ -1,4 +1,10 @@
package com.l2jserver.game.net.packet;
/**
* An abstract {@link ClientPacket}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see ClientPacket
*/
public abstract class AbstractClientPacket implements ClientPacket {
}

View File

@@ -1,5 +1,11 @@
package com.l2jserver.game.net.packet;
/**
* An abstract {@link ServerPacket}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see ServerPacket
*/
public abstract class AbstractServerPacket implements ServerPacket {
private final int opcode;

View File

@@ -4,6 +4,11 @@ import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Connection;
/**
* Each implementation is an packet sent by the game client.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface ClientPacket extends Packet {
/**
* Read binary data in the {@link ChannelBuffer}.

View File

@@ -1,8 +1,14 @@
package com.l2jserver.game.net.packet;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.l2jserver.game.net.packet.client.ProtocolVersionPacket;
/**
* Google Guice {@link Module} for client packets
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ClientPacketModule extends AbstractModule {
@Override
protected void configure() {

View File

@@ -1,4 +1,10 @@
package com.l2jserver.game.net.packet;
/**
* An simple packet. This must not be used directly, use {@link ClientPacket} or
* {@link ServerPacket} instead.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Packet {
}

View File

@@ -1,7 +1,13 @@
package com.l2jserver.game.net.packet;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
/**
* Google Guice {@link Module} for packets
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class PacketModule extends AbstractModule {
@Override
protected void configure() {

View File

@@ -4,6 +4,11 @@ import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Connection;
/**
* Each implementation is an packet sent by the game server.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface ServerPacket extends Packet {
/**
* Writes this packet binary data.

View File

@@ -1,8 +1,14 @@
package com.l2jserver.game.net.packet;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.l2jserver.game.net.packet.client.ProtocolVersionPacket;
/**
* Google Guice {@link Module} for server packets
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ServerPacketModule extends AbstractModule {
@Override
protected void configure() {

View File

@@ -15,9 +15,20 @@ import com.l2jserver.model.world.WorldObject;
* the {@link WorldObject} type
*/
public abstract class ObjectID<T extends WorldObject> extends ID {
/**
* Creates a new instance
*
* @param id
* the raw id
*/
protected ObjectID(int id) {
super(id);
}
/**
* Returns the {@link WorldObject} associated with this {@link ID}
*
* @return the {@link WorldObject} if existent, <tt>null</tt> otherwise
*/
public abstract T getObject();
}

View File

@@ -7,12 +7,22 @@ import com.l2jserver.model.template.Template;
* defined in the template class.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public abstract class TemplateID<T extends Template<?>> extends ID {
/**
* Creates a new instance
*
* @param id
* the raw id
*/
public TemplateID(int id) {
super(id);
}
/**
* Returns the {@link Template} associated with this {@link ID}
*
* @return the {@link Template} if existent, <tt>null</tt> otherwise
*/
public abstract T getTemplate();
}

View File

@@ -1,6 +1,7 @@
package com.l2jserver.model.id.factory;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.Scopes;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.l2jserver.model.id.object.allocator.BitSetIDAllocator;
@@ -13,6 +14,11 @@ import com.l2jserver.model.id.template.factory.CharacterTemplateIDFactory;
import com.l2jserver.model.id.template.factory.ItemTemplateIDFactory;
import com.l2jserver.model.id.template.factory.SkillTemplateIDFactory;
/**
* Google Guice {@link IDFactory} {@link Module}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class IDFactoryModule extends AbstractModule {
@Override
protected void configure() {

View File

@@ -5,6 +5,13 @@ import com.google.inject.assistedinject.Assisted;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.world.capability.Actor;
/**
* An {@link ObjectID} instance representing an {@link Actor} object
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @param <T>
* the actor subclass
*/
public abstract class ActorID<T extends Actor> extends ObjectID<T> {
@Inject
public ActorID(@Assisted int id) {

View File

@@ -3,8 +3,14 @@ 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;
/**
* An {@link ObjectID} instance representing an {@link L2Character} object
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public final class CharacterID extends ActorID<L2Character> {
/**
* Data Access Object (DAO) for characters

View File

@@ -5,6 +5,11 @@ import com.l2jserver.db.dao.ClanDAO;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.world.Clan;
/**
* An {@link ObjectID} instance representing an {@link Clan} object
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public final class ClanID extends ObjectID<Clan> {
/**
* Data Access Object (DAO) for clans

View File

@@ -6,6 +6,11 @@ import com.l2jserver.db.dao.ItemDAO;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.world.Item;
/**
* An {@link ObjectID} instance representing an {@link Item} object
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public final class ItemID extends ObjectID<Item> {
/**
* Data Access Object (DAO) for items

View File

@@ -2,8 +2,14 @@ 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;
/**
* An {@link ObjectID} instance representing an {@link Pet} object
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public final class PetID extends ActorID<Pet> {
/**
* Data Access Object (DAO) for pets

View File

@@ -10,7 +10,15 @@ import org.slf4j.LoggerFactory;
import com.l2jserver.util.PrimeFinder;
/**
* The {@link BitSet} id allocator allocates new IDs backed by an {@link BitSet}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class BitSetIDAllocator implements IDAllocator {
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(BitSetIDAllocator.class);
@@ -32,6 +40,9 @@ public class BitSetIDAllocator implements IDAllocator {
*/
private AtomicInteger nextId = new AtomicInteger();
/**
* Initializes this allocator
*/
public void init() {
ids = new BitSet(PrimeFinder.nextPrime(100000));
ids.clear();
@@ -108,6 +119,9 @@ public class BitSetIDAllocator implements IDAllocator {
}
}
/**
* Increases the {@link BitSet} capacity
*/
private void increaseBitSetCapacity() {
log.debug("Increasing BitSet capacity from {}", ids.size());
BitSet newBitSet = new BitSet(

View File

@@ -1,5 +1,10 @@
package com.l2jserver.model.id.object.allocator;
/**
* Exception thrown by an {@link IDAllocator}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class IDAllocatorException extends RuntimeException {
private static final long serialVersionUID = 111195059766878062L;

View File

@@ -13,8 +13,17 @@ import com.l2jserver.model.world.WorldObject;
* the return object type
*/
public class WorldObjectIterable<T extends WorldObject> implements Iterable<T> {
/**
* The {@link Iterator}
*/
private final Iterator<T> iterator;
/**
* Creates a new instance
*
* @param iterator
* the iterator
*/
public WorldObjectIterable(Iterator<T> iterator) {
this.iterator = iterator;
}

View File

@@ -17,12 +17,27 @@ import com.l2jserver.util.ArrayIterator;
* the object type
*/
public class WorldObjectIterator<T extends WorldObject> implements Iterator<T> {
/**
* The {@link ObjectID} iterator
*/
private final Iterator<? extends ObjectID<T>> ids;
/**
* Creates a new instance
*
* @param ids
* the {@link ObjectID} var-arg
*/
public WorldObjectIterator(ObjectID<T>... ids) {
this(new ArrayIterator<ObjectID<T>>(ids));
}
/**
* Creates a new instance
*
* @param ids
* the {@link ObjectID} iterator
*/
public WorldObjectIterator(Iterator<? extends ObjectID<T>> ids) {
this.ids = ids;
}

View File

@@ -6,7 +6,16 @@ import com.l2jserver.model.id.TemplateID;
import com.l2jserver.model.template.CharacterTemplate;
import com.l2jserver.service.game.template.TemplateService;
/**
* An {@link TemplateID} instance representing an {@link CharacterTemplate}
* object
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterTemplateID extends TemplateID<CharacterTemplate> {
/**
* The template service
*/
private final TemplateService templateService;
@Inject

View File

@@ -6,7 +6,16 @@ import com.l2jserver.model.id.TemplateID;
import com.l2jserver.model.template.ItemTemplate;
import com.l2jserver.service.game.template.TemplateService;
/**
* An {@link TemplateID} instance representing an {@link ItemTemplate}
* object
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ItemTemplateID extends TemplateID<ItemTemplate> {
/**
* The template service
*/
private final TemplateService templateService;
@Inject

View File

@@ -6,7 +6,16 @@ import com.l2jserver.model.id.TemplateID;
import com.l2jserver.model.template.SkillTemplate;
import com.l2jserver.service.game.template.TemplateService;
/**
* An {@link TemplateID} instance representing an {@link SkillTemplate}
* object
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class SkillTemplateID extends TemplateID<SkillTemplate> {
/**
* The template service
*/
private final TemplateService templateService;
@Inject

View File

@@ -2,6 +2,11 @@ package com.l2jserver.model.id.template.factory;
import com.l2jserver.model.id.template.CharacterTemplateID;
/**
* Creates new {@link CharacterTemplateID} instances
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface CharacterTemplateIDFactory extends
TemplateIDFactory<CharacterTemplateID> {
}

View File

@@ -2,6 +2,11 @@ package com.l2jserver.model.id.template.factory;
import com.l2jserver.model.id.template.ItemTemplateID;
/**
* Creates new {@link ItemTemplateID} instances
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface ItemTemplateIDFactory extends
TemplateIDFactory<ItemTemplateID> {
}

View File

@@ -2,6 +2,11 @@ package com.l2jserver.model.id.template.factory;
import com.l2jserver.model.id.template.SkillTemplateID;
/**
* Creates new {@link SkillTemplateID} instances
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface SkillTemplateIDFactory extends
TemplateIDFactory<SkillTemplateID> {
}

View File

@@ -3,6 +3,14 @@ package com.l2jserver.model.id.template.factory;
import com.l2jserver.model.id.TemplateID;
import com.l2jserver.model.id.factory.IDFactory;
/**
* Creates a new {@link TemplateID}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the subclass of {@link TemplateID} that will be createdF
*/
public interface TemplateIDFactory<T extends TemplateID<?>> extends
IDFactory<T> {
}

View File

@@ -2,11 +2,25 @@ package com.l2jserver.model.template;
import com.l2jserver.model.id.TemplateID;
/**
* An abstract {@link Template}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the type of object created by this template
*/
public abstract class AbstractTemplate<T> implements Template<T> {
/**
* The {@link TemplateID}F
*/
private final TemplateID<?> id;
public AbstractTemplate(TemplateID<?> id) {
super();
/**
* Creates a new instance
* @param id
*/
protected AbstractTemplate(TemplateID<?> id) {
this.id = id;
}

View File

@@ -3,7 +3,13 @@ package com.l2jserver.model.template;
import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.template.capability.Defendable;
import com.l2jserver.model.template.capability.IncomingDamageIntercept;
import com.l2jserver.model.world.Item;
/**
* Template for Armor {@link Item}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class ArmorTemplate extends ItemTemplate implements Defendable,
IncomingDamageIntercept {
public ArmorTemplate(ItemTemplateID id) {

View File

@@ -10,6 +10,11 @@ import com.l2jserver.model.world.character.CharacterBaseAttributes;
import com.l2jserver.model.world.character.CharacterClass;
import com.l2jserver.util.Coordinate;
/**
* Template for {@link L2Character}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class CharacterTemplate extends AbstractTemplate<L2Character> {
/**
* The logger

View File

@@ -2,7 +2,13 @@ package com.l2jserver.model.template;
import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.template.capability.Consumable;
import com.l2jserver.model.world.Item;
/**
* Template for consumable {@link Item}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class ConsumableTemplate extends ItemTemplate implements
Consumable {
public ConsumableTemplate(ItemTemplateID id) {

View File

@@ -6,6 +6,11 @@ import org.slf4j.LoggerFactory;
import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.world.Item;
/**
* Template for an {@link Item}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class ItemTemplate extends AbstractTemplate<Item> {
/**
* The logger

View File

@@ -1,7 +1,13 @@
package com.l2jserver.model.template;
import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.world.Item;
/**
* Template for Potion {@link Item}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class PotionTemplate extends ConsumableTemplate {
public PotionTemplate(ItemTemplateID id) {
super(id);

View File

@@ -4,6 +4,11 @@ import com.l2jserver.model.id.template.SkillTemplateID;
import com.l2jserver.model.template.capability.Castable;
import com.l2jserver.model.world.character.CharacterClass;
/**
* Template for skill
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class SkillTemplate extends AbstractTemplate<Void> implements
Castable {
public SkillTemplate(SkillTemplateID id) {

View File

@@ -1,9 +1,30 @@
package com.l2jserver.model.template;
import com.l2jserver.model.id.TemplateID;
import com.l2jserver.model.world.WorldObject;
/**
* An template is like a base for an {@link WorldObject}. Normally, instead of
* manually creating the object this can be done through templates, that easy
* the need of setting the new objects parameters.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the {@link WorldObject} type
*/
public interface Template<T> {
/**
* Create a new {@link WorldObject}
*
* @return the created object
*/
T create();
/**
* Return this {@link TemplateID}
*
* @return the template id
*/
TemplateID<?> getID();
}

View File

@@ -2,7 +2,13 @@ package com.l2jserver.model.template;
import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.template.capability.Attackable;
import com.l2jserver.model.world.Item;
/**
* Template for Weapon {@link Item}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class WeaponTemplate extends ItemTemplate implements Attackable {
public WeaponTemplate(ItemTemplateID id) {
super(id);

View File

@@ -23,7 +23,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
*/
private final int mentality;
/**
* The character dextry
* The character dexterity
*/
private final int dexterity;
/**
@@ -93,8 +93,8 @@ public class CharacterBaseAttributes implements CharacterAttributes {
* the concentration
* @param mentality
* the mentality
* @param dextry
* the dextry
* @param dexterity
* the dexterity
* @param witness
* the witness
* @param physicalAttack
@@ -151,6 +151,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the intelligence
*/
@Override
public int getIntelligence() {
return intelligence;
}
@@ -158,6 +159,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the strength
*/
@Override
public int getStrength() {
return strength;
}
@@ -165,6 +167,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the concentration
*/
@Override
public int getConcentration() {
return concentration;
}
@@ -172,13 +175,15 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the mentality
*/
@Override
public int getMentality() {
return mentality;
}
/**
* @return the dextry
* @return the dexterity
*/
@Override
public int getDexterity() {
return dexterity;
}
@@ -186,6 +191,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the witness
*/
@Override
public int getWitness() {
return witness;
}
@@ -193,6 +199,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the physicalAttack
*/
@Override
public int getPhysicalAttack() {
return physicalAttack;
}
@@ -200,6 +207,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the magicalAttack
*/
@Override
public int getMagicalAttack() {
return magicalAttack;
}
@@ -207,6 +215,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the physicalDefense
*/
@Override
public int getPhysicalDefense() {
return physicalDefense;
}
@@ -214,6 +223,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the magicalDefense
*/
@Override
public int getMagicalDefense() {
return magicalDefense;
}
@@ -221,6 +231,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the attackSpeed
*/
@Override
public int getAttackSpeed() {
return attackSpeed;
}
@@ -228,6 +239,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the castSpeed
*/
@Override
public int getCastSpeed() {
return castSpeed;
}
@@ -235,6 +247,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the accuracy
*/
@Override
public int getAccuracy() {
return accuracy;
}
@@ -242,6 +255,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the criticalChance
*/
@Override
public int getCriticalChance() {
return criticalChance;
}
@@ -249,6 +263,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the evasionChance
*/
@Override
public int getEvasionChance() {
return evasionChance;
}
@@ -256,6 +271,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the moveSpeed
*/
@Override
public int getMoveSpeed() {
return moveSpeed;
}
@@ -263,6 +279,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the maxWeigth
*/
@Override
public int getMaxWeigth() {
return maxWeigth;
}
@@ -270,6 +287,7 @@ public class CharacterBaseAttributes implements CharacterAttributes {
/**
* @return the craft
*/
@Override
public boolean canCraft() {
return craft;
}

View File

@@ -1,5 +1,10 @@
package com.l2jserver.service;
/**
* An abstract service implementing basic life-cycle methods.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class AbstractService implements Service {
@Override
public void start() throws ServiceStartException {

View File

@@ -1,5 +1,11 @@
package com.l2jserver.service;
/**
* Each Service is a provider of a given feature. Most services will want to
* implement {@link AbstractService} class instead of this interface.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Service {
/**
* Start this service

View File

@@ -1,5 +1,10 @@
package com.l2jserver.service;
/**
* Exception for an {@link Service}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ServiceException extends Exception {
private static final long serialVersionUID = 1L;

View File

@@ -7,6 +7,11 @@ import com.google.inject.Inject;
import com.google.inject.Injector;
import com.l2jserver.service.logging.LoggingService;
/**
* The {@link ServiceManager} is responsible for starting and stopping services
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ServiceManager {
/**
* The logger
@@ -39,8 +44,7 @@ public class ServiceManager {
logger.info("{}: Starting service...",
serviceClass.getCanonicalName());
service.start();
logger.info("{}: Service started!",
serviceClass.getCanonicalName());
logger.info("{}: Service started!", serviceClass.getCanonicalName());
return service;
} catch (ServiceStartException e) {
logger.error("{}: Error starting service: {}",

View File

@@ -1,6 +1,7 @@
package com.l2jserver.service;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.Scopes;
import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.configuration.ProxyConfigurationService;
@@ -19,6 +20,11 @@ import com.l2jserver.service.logging.LoggingService;
import com.l2jserver.service.network.NettyNetworkService;
import com.l2jserver.service.network.NetworkService;
/**
* Google Guice {@link Module} for services
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ServiceModule extends AbstractModule {
@Override
protected void configure() {
@@ -29,7 +35,7 @@ public class ServiceModule extends AbstractModule {
.in(Scopes.SINGLETON);
bind(DatabaseService.class).to(MySQLDatabaseService.class).in(
Scopes.SINGLETON);
bind(NetworkService.class).to(NettyNetworkService.class).in(
Scopes.SINGLETON);
bind(ScriptingService.class).to(ScriptingServiceImpl.class).in(

View File

@@ -1,5 +1,11 @@
package com.l2jserver.service;
/**
* Thrown when an service failed to restart. It's <tt>cause</tt> can be an
* {@link ServiceStartException} or {@link ServiceStopException}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ServiceRestartException extends ServiceException {
private static final long serialVersionUID = 1L;

View File

@@ -1,5 +1,10 @@
package com.l2jserver.service;
/**
* Exception thrown when a service failed to start.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ServiceStartException extends ServiceException {
private static final long serialVersionUID = 1L;

View File

@@ -1,5 +1,10 @@
package com.l2jserver.service;
/**
* Exception thrown when a service failed to stop
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ServiceStopException extends ServiceException {
private static final long serialVersionUID = 1L;

View File

@@ -16,5 +16,16 @@ import com.l2jserver.service.Service;
*
*/
public interface CacheService extends Service {
/**
* Decores the <tt>instance</tt> with the cache
*
* @param <T>
* the <tt>instance</tt> type
* @param interfaceType
* the interface type
* @param instance
* the instance
* @return the cache-decorated object
*/
<T extends Cacheable> T decorate(Class<T> interfaceType, T instance);
}

View File

@@ -1,5 +1,13 @@
package com.l2jserver.service.cache;
/**
* Flags an interface that is capable of caching.
* <p>
* <b>Note</b>: only interfaces can be cached!
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public interface Cacheable {
}

View File

@@ -5,10 +5,16 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Map;
import java.util.WeakHashMap;
import com.l2jserver.service.AbstractService;
import com.l2jserver.util.factory.CollectionFactory;
/**
* Simple cache that stores invocation results in a {@link WeakHashMap}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class SimpleCacheService extends AbstractService implements CacheService {
private final Map<MethodInvocation, Object> cache = CollectionFactory
.newWeakMap(MethodInvocation.class, Object.class);

View File

@@ -6,24 +6,70 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Configuration interface
* <p>
* Each service desiring to use the configuration system must extend the
* interface and define methods for getters and setters. Each method must be
* annotated either with {@link ConfigurationPropertyGetter} or
* {@link ConfigurationPropertySetter}
* <p>
* Each interface may optionally be annotated with {@link ConfigurationName}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Configuration {
/**
* Each configuration can define the name of its configuration. This will be
* used by implementations to look for the configuration.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(value = ElementType.TYPE)
public @interface ConfigurationName {
/**
* @return the configuration name
*/
String value();
}
/**
* The getter method for an configuration property
* <p>
* The method must have no arguments.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface ConfigurationPropertyGetter {
/**
* @return the property name
*/
String name();
/**
* @return the default value to be used
*/
String defaultValue() default "";
}
/**
* The setter method for an configuration property.
* <p>
* The method must have a single argument and return type void.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface ConfigurationPropertySetter {
/**
* @return the property name
*/
String name();
}
}

View File

@@ -2,6 +2,22 @@ package com.l2jserver.service.configuration;
import com.l2jserver.service.Service;
/**
* The configuration service is responsible for reading and writing in
* configuration storage. Each configuration is represented by an interface.
* Implementations of this interface are implementaion specific.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface ConfigurationService extends Service {
/**
* Get the configuration object for <tt>config</tt>
*
* @param <C>
* the configuration type
* @param config
* the configuration interface class
* @return the configuration object
*/
<C extends Configuration> C get(Class<C> config);
}

View File

@@ -23,12 +23,27 @@ import com.l2jserver.service.configuration.Configuration.ConfigurationPropertySe
import com.l2jserver.util.transformer.Transformer;
import com.l2jserver.util.transformer.TransformerFactory;
/**
* Creates {@link Configuration} object through Java {@link Proxy}. Uses the
* annotations in the interface to retrieve and store values.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ProxyConfigurationService extends AbstractService implements
ConfigurationService {
/**
* The directory in which configuration files are stored
*/
private File directory = new File("./config");
/**
* The logger
*/
private final Logger logger = LoggerFactory
.getLogger(ProxyConfigurationService.class);
/**
* The cache of configuration objects
*/
private Map<Class<?>, Object> cache = new WeakHashMap<Class<?>, Object>();
@Override
@@ -59,6 +74,11 @@ public class ProxyConfigurationService extends AbstractService implements
return proxy;
}
/**
* The invocation handler for configuration interfaces
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
private class ConfigInvocationHandler implements InvocationHandler {
private final Properties properties;
private Map<String, Object> cache = new WeakHashMap<String, Object>();
@@ -70,7 +90,8 @@ public class ProxyConfigurationService extends AbstractService implements
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
logger.debug("Configuration service, method invoked: {}", method.getName());
logger.debug("Configuration service, method invoked: {}",
method.getName());
if (args == null || args.length == 0) {
final ConfigurationPropertyGetter getter = method
.getAnnotation(ConfigurationPropertyGetter.class);
@@ -87,6 +108,15 @@ public class ProxyConfigurationService extends AbstractService implements
return null;
}
/**
* Get the untransformed value of an property
*
* @param getter
* the getter annotation
* @param type
* the transformed type
* @return the untransformed property
*/
private Object get(ConfigurationPropertyGetter getter, Class<?> type) {
if (cache.containsKey(getter.name()))
return cache.get(getter.name());
@@ -96,6 +126,16 @@ public class ProxyConfigurationService extends AbstractService implements
return o;
}
/**
* Set the transformed value of an property
*
* @param setter
* the setter annotation
* @param value
* the untransformed value
* @param type
* the transformed type
*/
private void set(ConfigurationPropertySetter setter, Object value,
Class<?> type) {
if (value != null) {
@@ -108,6 +148,15 @@ public class ProxyConfigurationService extends AbstractService implements
}
}
/**
* Untransforms an value
*
* @param value
* the raw value
* @param type
* the output type
* @return the untransformed value
*/
private Object untransform(String value, Class<?> type) {
if (value == null)
return null;
@@ -120,6 +169,15 @@ public class ProxyConfigurationService extends AbstractService implements
return transformer.untransform(value);
}
/**
* Transforms an value
*
* @param value
* the raw typed value
* @param type
* the input type
* @return the string representing <tt>value</tt>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private String transform(Object value, Class<?> type) {
if (value == null)
@@ -133,6 +191,15 @@ public class ProxyConfigurationService extends AbstractService implements
return transformer.transform(value);
}
/**
* Retrieve the raw value from the property file
*
* @param key
* the key
* @param defaultValue
* the default value
* @return the value found or default value
*/
private String getRaw(String key, String defaultValue) {
if (properties == null)
return defaultValue;
@@ -143,6 +210,15 @@ public class ProxyConfigurationService extends AbstractService implements
}
}
/**
* Tries to locate an .properties file
*
* @param clazz
* configuration interface class
* @return the found property
* @throws IOException
* if any i/o error occur
*/
private Properties findProperties(Class<?> clazz) throws IOException {
ConfigurationName config = findAnnotation(ConfigurationName.class,
clazz);
@@ -159,6 +235,17 @@ public class ProxyConfigurationService extends AbstractService implements
return prop;
}
/**
* Tries to find an annotation in the class or any parent-class.
*
* @param <T>
* the annotation type
* @param annotationClass
* the annotation class
* @param clazz
* the class to look for annotations
* @return the annotation found
*/
private <T extends Annotation> T findAnnotation(Class<T> annotationClass,
Class<?> clazz) {
T ann = clazz.getAnnotation(annotationClass);
@@ -175,10 +262,19 @@ public class ProxyConfigurationService extends AbstractService implements
return null;
}
/**
* @return the configuration store directory
*/
public File getDirectory() {
return directory;
}
/**
* Set the configuration store directory
*
* @param directory
* the directory
*/
public void setDirectory(File directory) {
this.directory = directory;
}

View File

@@ -2,7 +2,18 @@ package com.l2jserver.service.database;
import com.google.inject.Inject;
/**
* Abstract DAO implementations. Store an instance of {@link DatabaseService}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the dao object type
*/
public abstract class AbstractDAO<T> implements DataAccessObject<T> {
/**
* The database service instance
*/
protected final DatabaseService database;
@Inject
@@ -10,6 +21,9 @@ public abstract class AbstractDAO<T> implements DataAccessObject<T> {
this.database = database;
}
/**
* @return the database service
*/
public DatabaseService getDatabase() {
return database;
}

View File

@@ -4,6 +4,11 @@ import java.io.File;
import com.l2jserver.service.configuration.Configuration.ConfigurationName;
/**
* Configuration for DB4O Database Service
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@ConfigurationName("db4o")
public interface DB4ODatabaseConfiguration extends DatabaseConfiguration {
/**

View File

@@ -2,6 +2,13 @@ package com.l2jserver.service.database;
import com.l2jserver.service.AbstractService;
/**
* Database service implementation for DB4O database engine.
* <p>
* Note that this is not implemented yet!
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class DB4ODatabaseService extends AbstractService implements
DatabaseService {
}

View File

@@ -3,6 +3,12 @@ package com.l2jserver.service.database;
import com.l2jserver.service.configuration.Configuration;
import com.l2jserver.service.configuration.Configuration.ConfigurationName;
/**
* Database service configuration
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see Configuration
*/
@ConfigurationName("database")
public interface DatabaseConfiguration extends Configuration {

View File

@@ -2,6 +2,12 @@ package com.l2jserver.service.database;
import com.l2jserver.service.Service;
/**
* The database service manages connection between the {@link DataAccessObject}
* implementation and the database.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface DatabaseService extends Service {
}

View File

@@ -1,5 +1,10 @@
package com.l2jserver.service.database;
/**
* Configuration interface for {@link MySQLDatabaseService}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface MySQLDatabaseConfiguration extends DatabaseConfiguration {
/**
* @return the jdbc url

View File

@@ -7,6 +7,8 @@ import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
@@ -24,16 +26,39 @@ import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.util.ArrayIterator;
import com.l2jserver.util.factory.CollectionFactory;
/**
* The database service implementation for MySQL database
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class MySQLDatabaseService extends AbstractService implements
DatabaseService {
/**
* The configuration object
*/
private final MySQLDatabaseConfiguration config;
/**
* The logger
*/
private final Logger logger = LoggerFactory
.getLogger(MySQLDatabaseService.class);
/**
* The database connection pool
*/
private ObjectPool connectionPool;
/**
* The dayabase connection factory
*/
private ConnectionFactory connectionFactory;
/**
* The poolable connection factory
*/
@SuppressWarnings("unused")
private PoolableConnectionFactory poolableConnectionFactory;
/**
* The connection {@link DataSource}.
*/
private PoolingDataSource dataSource;
@Inject
@@ -51,6 +76,15 @@ public class MySQLDatabaseService extends AbstractService implements
dataSource = new PoolingDataSource(connectionPool);
}
/**
* Executes an <tt>query</tt> in the database.
*
* @param <T>
* the query return type
* @param query
* the query
* @return an instance of <tt>T</tt>
*/
public <T> T query(Query<T> query) {
try {
final Connection conn = dataSource.getConnection();
@@ -84,17 +118,59 @@ public class MySQLDatabaseService extends AbstractService implements
}
}
/**
* The query interface. The query will receive an connection an will be
* executed. The can return return a value if required.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <R>
* the return type
*/
public interface Query<R> {
/**
* Execute the query in <tt>conn</tt>
*
* @param conn
* the connection
* @return the query return value
* @throws SQLException
*/
R query(Connection conn) throws SQLException;
}
/**
* This query is used for the following statements:
* <ul>
* <li>INSERT INTO</li>
* <li>UPDATE</li>
* <li>DELETE FROM</li>
* </ul>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the query return type
*/
public static abstract class InsertUpdateQuery<T> implements Query<Integer> {
private final Iterator<T> iterator;
/**
* Creates a new query for <tt>objects</tt>
*
* @param objects
* the object list
*/
public InsertUpdateQuery(T... objects) {
this(new ArrayIterator<T>(objects));
}
/**
* Create a new query for objects in <tt>iterator</tt>
*
* @param iterator
* the object iterator
*/
public InsertUpdateQuery(Iterator<T> iterator) {
this.iterator = iterator;
}
@@ -118,16 +194,46 @@ public class MySQLDatabaseService extends AbstractService implements
return rows;
}
/**
* Creates the <b>prepared</b> query for execution
*
* @return the <b>prepared</b> query
*/
protected abstract String query();
/**
* Set the parameters for in <tt>statement</tt> for <tt>object</tt>
*
* @param st
* the prepared statement
* @param object
* the object
* @throws SQLException
*/
protected abstract void parametize(PreparedStatement st, T object)
throws SQLException;
/**
* Return the key mapper. Can be null if no generated keys are used or
* are not important.
*
* @param object
* the object
* @return the key mapper
*/
protected Mapper<T> keyMapper(T object) {
return null;
}
}
/**
* An select query that returns a list of objects of type <tt>T</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the query return type
*/
public static abstract class SelectListQuery<T> implements Query<List<T>> {
@Override
public List<T> query(Connection conn) throws SQLException {
@@ -142,14 +248,46 @@ public class MySQLDatabaseService extends AbstractService implements
return list;
}
/**
* Creates the <b>prepared</b> query for execution
*
* @return the <b>prepared</b> query
*/
protected abstract String query();
/**
* Set the parameters for in <tt>statement</tt> for <tt>object</tt>
*
* @param st
* the prepared statement
* @param object
* the object
* @throws SQLException
*/
protected void parametize(PreparedStatement st) throws SQLException {
}
/**
* Return the mapper that will bind {@link ResultSet} objects into an
* <tt>T</tt> object instance. The mapper will need to create the object
* instance.
* <p>
* <b>Note</b>: This method will be called for each row, an thus is a
* good idea to create a new instance on each call!
*
* @return the mapper instance
*/
protected abstract Mapper<T> mapper();
}
/**
* An select query that returns a single object of type <tt>T</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the query return type
*/
public static abstract class SelectSingleQuery<T> implements Query<T> {
@Override
public T query(Connection conn) throws SQLException {
@@ -163,15 +301,55 @@ public class MySQLDatabaseService extends AbstractService implements
return null;
}
/**
* Creates the <b>prepared</b> query for execution
*
* @return the <b>prepared</b> query
*/
protected abstract String query();
protected abstract void parametize(PreparedStatement st)
throws SQLException;
/**
* Set the parameters for in <tt>statement</tt> for <tt>object</tt>
*
* @param st
* the prepared statement
* @param object
* the object
* @throws SQLException
*/
protected void parametize(PreparedStatement st) throws SQLException {
}
/**
* Return the mapper that will bind {@link ResultSet} objects into an
* <tt>T</tt> object instance. The mapper will need to create the object
* instance.
*
* @return the mapper
*/
protected abstract Mapper<T> mapper();
}
/**
* The {@link Mapper} maps an {@link ResultSet} into an object <tt>T</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the object type
*/
public interface Mapper<T> {
/**
* Map the result set value into an object.
* <p>
* <b>Note</b>: it is required to call {@link ResultSet#next()}, since
* it is called by the {@link Query}.
*
* @param rs
* the result set
* @return the created instance
* @throws SQLException
*/
T map(ResultSet rs) throws SQLException;
}
}

View File

@@ -18,12 +18,26 @@ import com.l2jserver.service.ServiceStopException;
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
import com.l2jserver.util.factory.CollectionFactory;
/**
* Default implementation for {@link WorldService}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class WorldServiceImpl extends AbstractService implements WorldService {
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(WorldServiceImpl.class);
/**
* The set of all objects registered in the world
*/
private final Set<WorldObject> objects = CollectionFactory
.newSet(WorldObject.class);
/**
* The world event dispatcher
*/
private final WorldEventDispatcher dispatcher;
@Inject

View File

@@ -14,7 +14,7 @@ import com.l2jserver.model.world.event.WorldListener;
import com.l2jserver.util.factory.CollectionFactory;
/**
* {@link WorldEventDispatcher} implementation
* Default {@link WorldEventDispatcher} implementation
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/

View File

@@ -5,6 +5,11 @@ import org.apache.log4j.BasicConfigurator;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.ServiceStopException;
/**
* Logging service implementation for Log4J
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Log4JLoggingService extends AbstractService implements
LoggingService {
@Override

View File

@@ -14,6 +14,11 @@ import com.l2jserver.game.net.Lineage2PipelineFactory;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.configuration.ConfigurationService;
/**
* Netty network service implementation
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class NettyNetworkService extends AbstractService implements
NetworkService {
private final NetworkConfiguration config;

View File

@@ -5,6 +5,11 @@ import java.net.InetSocketAddress;
import com.l2jserver.service.configuration.Configuration;
import com.l2jserver.service.configuration.Configuration.ConfigurationName;
/**
* The network {@link Configuration}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@ConfigurationName("network")
public interface NetworkConfiguration extends Configuration {
// TODO set default value

View File

@@ -2,5 +2,11 @@ package com.l2jserver.service.network;
import com.l2jserver.service.Service;
/**
* The network service is responsible for communicating the server and the game
* client. You can see more details in each implementation.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface NetworkService extends Service {
}

View File

@@ -3,10 +3,30 @@ package com.l2jserver.util;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* This {@link Iterator} takes an array as input and iterate over it.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the array type
*/
public class ArrayIterator<T> implements Iterator<T> {
/**
* The objects
*/
private final T[] objects;
/**
* the iterator index
*/
private int i = 0;
/**
* Creates a new iterator instance
*
* @param objects
* the objects
*/
public ArrayIterator(T... objects) {
this.objects = objects;
}

View File

@@ -4,7 +4,19 @@ import java.util.Arrays;
import org.jboss.netty.buffer.ChannelBuffer;
/**
* This is an Netty {@link ChannelBuffer} utility class.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class BufferUtils {
/**
* Reads an unicode string from the buffer
*
* @param buffer
* the buffer
* @return the read unicode string
*/
public static final String readString(ChannelBuffer buffer) {
char[] str = new char[buffer.readableBytes()];
int index = 0;
@@ -15,6 +27,14 @@ public class BufferUtils {
return String.valueOf(Arrays.copyOfRange(str, 0, index));
}
/**
* Writes an unicode string to the buffer
*
* @param buffer
* the buffer
* @param str
* the string
*/
public static final void writeString(ChannelBuffer buffer, String str) {
if (str != null) {
final int len = str.length();

View File

@@ -1,33 +1,87 @@
package com.l2jserver.util;
/**
* Represents an coordinate in the game world.
* <p>
* Each coordinate has 3 points: x, y and z.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Coordinate {
/**
* The X point
*/
private final int x;
/**
* The Y point
*/
private final int y;
/**
* The Z point
*/
private final int z;
/**
* Creates a new coordinate
*
* @param x
* the x point
* @param y
* the y point
* @param z
* the z point
*/
protected Coordinate(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* @return the x point
*/
public int getX() {
return x;
}
/**
* @return the y point
*/
public int getY() {
return y;
}
/**
* @return the z point
*/
public int getZ() {
return z;
}
/**
* Calculates the distance between <tt>this</tt> coordinate and
* <tt>other</tt>
*
* @param other
* the other coodinate
* @return the computed distance
*/
public int getDistance(Coordinate other) {
// TODO calculation
return x + y + z;
}
/**
* Creates a new instance from the 3 points
*
* @param x
* the x point
* @param y
* the y point
* @param z
* the z point
* @return the new {@link Coordinate} object created
*/
public static Coordinate fromXYZ(int x, int y, int z) {
return new Coordinate(x, y, z);
}

View File

@@ -1,8 +1,22 @@
package com.l2jserver.util;
/**
* An RED-GREEN-BLUE color
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class RGBColor {
/**
* The red value
*/
private final byte red;
/**
* The green value
*/
private final byte green;
/**
* The blue value
*/
private final byte blue;
protected RGBColor(byte r, byte g, byte b) {
@@ -32,10 +46,20 @@ public class RGBColor {
return blue;
}
/**
* Converts to an byte array
*
* @return an byte array of this color
*/
public byte[] toByteArray() {
return new byte[] { red, green, blue };
}
/**
* Convers this color into an integer
*
* @return the color integer
*/
public int toInteger() {
return red + green >> 8 + blue >> 16;
}

View File

@@ -14,7 +14,20 @@ import com.l2jserver.util.transformer.impl.IntegerTransformer;
import com.l2jserver.util.transformer.impl.LongTransformer;
import com.l2jserver.util.transformer.impl.ShortTransformer;
/**
* The {@link TransformerFactory} return the transformer instance for any given
* type.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class TransformerFactory {
/**
* return the transformer instance the given <tt>type</tt>.
*
* @param type
* the type
* @return the transformer
*/
public static final Transformer<?> getTransfromer(Class<?> type) {
if (type == Byte.class || type == Byte.TYPE) {
return ByteTransformer.SHARED_INSTANCE;
@@ -30,11 +43,11 @@ public class TransformerFactory {
return DoubleTransformer.SHARED_INSTANCE;
} else if (type == Boolean.class || type == Boolean.TYPE) {
return BooleanTransformer.SHARED_INSTANCE;
} else if(type == InetSocketAddress.class) {
} else if (type == InetSocketAddress.class) {
return InetSocketAddressTransformer.SHARED_INSTANCE;
} else if(type == File.class) {
} else if (type == File.class) {
return FileTransformer.SHARED_INSTANCE;
}else if(type == Class.class) {
} else if (type == Class.class) {
return ClassTransformer.SHARED_INSTANCE;
}
return null;