diff --git a/ data/plugin/plugin/DisabledPlugin.java b/ data/plugin/plugin/DisabledPlugin.java
deleted file mode 100644
index 7a236154d..000000000
--- a/ data/plugin/plugin/DisabledPlugin.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package plugin;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Marker annotation that is used to mark disabled plugins so they will be
- * ignored by {@link PluginLoader}
- *
- * @author Rogiel
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface DisabledPlugin {
-}
diff --git a/ data/plugin/plugin/PluginLoader.java b/ data/plugin/plugin/PluginLoader.java
deleted file mode 100644
index 11a62dd5d..000000000
--- a/ data/plugin/plugin/PluginLoader.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package plugin;
-
-import java.lang.reflect.Modifier;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.inject.Inject;
-import com.l2jserver.model.template.Template;
-import com.l2jserver.service.game.scripting.classlistener.Loader;
-import com.l2jserver.service.game.scripting.classlistener.Unloader;
-import com.l2jserver.util.ClassUtils;
-import com.l2jserver.util.factory.CollectionFactory;
-
-/**
- * Utility class that loads all Plugins in classPath of this script context.
- * Plugin should be public, not abstract, not interface, must have default
- * constructor annotated with @Inject.
- *
- * @author Rogiel
- */
-public class PluginLoader implements Loader, Unloader {
- private static final Logger log = LoggerFactory
- .getLogger(PluginLoader.class);
-
- @Inject
- public PluginLoader() {
-
- }
-
- @Override
- public void load(Class>[] classes) {
- log.debug("Loading plugins from {} classes", classes.length);
- for (final Class extends Template>> template : getSuitableClasses(classes)) {
- log.debug("Found loadable plugin class: {}", template);
- //templateService.addTemplate(template);
- }
- }
-
- @Override
- public void unload(Class>[] classes) {
- log.debug("Unloading plugins from {} classes", classes.length);
- for (final Class extends Template>> template : getSuitableClasses(classes)) {
- log.debug("Found unloadable plugin class: {}", template);
- // TODO unloading
- }
- }
-
- /**
- * Returns list of suitable Template classes to load/unload
- *
- * @return list of Template classes to load/unload
- */
- @SuppressWarnings({ "unchecked" })
- private static Set>> getSuitableClasses(
- Class>[] classes) {
- final Set>> suitable = CollectionFactory
- .newSet(null);
- for (Class> clazz : classes) {
- if (!ClassUtils.isSubclass(clazz, Template.class))
- continue;
- if (Modifier.isAbstract(clazz.getModifiers())
- || Modifier.isInterface(clazz.getModifiers()))
- continue;
- if (!Modifier.isPublic(clazz.getModifiers()))
- continue;
- if (clazz.isAnnotationPresent(DisabledPlugin.class))
- continue;
-
- suitable.add((Class extends Template>>) clazz);
- }
-
- return suitable;
- }
-}
diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..81d267315
--- /dev/null
+++ b/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,4 @@
+#Mon May 16 13:41:30 BRT 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.text.custom_code_templates=/**\n * @return the ${bare_field_name}\n *//**\n * @param ${param} the ${bare_field_name} to set\n *//**\n * ${tags}\n *//*\n * This file is part of l2jserver <l2jserver.com>.\n *\n * l2jserver is free software\: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * l2jserver is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with l2jserver. If not, see <http\://www.gnu.org/licenses/>.\n *//**\n * @author <a href\="http\://www.rogiel.com">Rogiel</a>\n *\n * ${tags}\n *//**\n * \n *//**\n * ${tags}\n *//* (non-Javadoc)\n * ${see_to_overridden}\n *//**\n * ${tags}\n * ${see_to_target}\n */${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}\n\n\n\n// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();// ${todo} Auto-generated method stub\n${body_statement}${body_statement}\n// ${todo} Auto-generated constructor stubreturn ${field};${field} \= ${param};
diff --git a/data/script/template/script/template/item/weapon/LongSwordTemplate.java b/data/script/template/script/template/item/weapon/LongSwordTemplate.java
index 7440ff5b9..ea4e7e9d5 100644
--- a/data/script/template/script/template/item/weapon/LongSwordTemplate.java
+++ b/data/script/template/script/template/item/weapon/LongSwordTemplate.java
@@ -24,7 +24,7 @@ import com.l2jserver.model.world.capability.Attacker;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
public class LongSwordTemplate extends AbstractNoGradeWeaponTemplate {
- public static final int ID = 57;
+ public static final int ID = 2;
@Inject
public LongSwordTemplate(ItemTemplateIDFactory factory) {
diff --git a/data/script/template/script/template/item/weapon/ShortSwordTemplate.java b/data/script/template/script/template/item/weapon/ShortSwordTemplate.java
index 080c12f5f..0bafa69f4 100644
--- a/data/script/template/script/template/item/weapon/ShortSwordTemplate.java
+++ b/data/script/template/script/template/item/weapon/ShortSwordTemplate.java
@@ -24,7 +24,7 @@ import com.l2jserver.model.world.capability.Attacker;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
public class ShortSwordTemplate extends AbstractNoGradeWeaponTemplate {
- public static final int ID = 57;
+ public static final int ID = 1;
@Inject
public ShortSwordTemplate(ItemTemplateIDFactory factory) {
diff --git a/pom.xml b/pom.xml
index 56a3bb765..facbf7503 100644
--- a/pom.xml
+++ b/pom.xml
@@ -92,6 +92,13 @@
jar
runtime
+
+ net.sf.ehcache
+ ehcache-core
+ 2.4.2
+ jar
+ runtime
+
diff --git a/src/dao/mysql5/com/l2jserver/db/dao/DAOModuleMySQL5.java b/src/dao/mysql5/com/l2jserver/db/dao/DAOModuleMySQL5.java
index 61c45f01a..7c2c564a4 100644
--- a/src/dao/mysql5/com/l2jserver/db/dao/DAOModuleMySQL5.java
+++ b/src/dao/mysql5/com/l2jserver/db/dao/DAOModuleMySQL5.java
@@ -21,6 +21,7 @@ import com.google.inject.Module;
import com.google.inject.Scopes;
import com.l2jserver.db.dao.mysql5.MySQL5CharacterDAO;
import com.l2jserver.db.dao.mysql5.MySQL5CharacterFriendDAO;
+import com.l2jserver.db.dao.mysql5.MySQL5ClanDAO;
import com.l2jserver.db.dao.mysql5.MySQL5ItemDAO;
/**
@@ -36,5 +37,6 @@ public class DAOModuleMySQL5 extends AbstractModule {
bind(CharacterFriendDAO.class).to(MySQL5CharacterFriendDAO.class).in(
Scopes.SINGLETON);
bind(ItemDAO.class).to(MySQL5ItemDAO.class).in(Scopes.SINGLETON);
+ bind(ClanDAO.class).to(MySQL5ClanDAO.class).in(Scopes.SINGLETON);
}
}
diff --git a/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAO.java b/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAO.java
index d398335ba..1a8b91ce4 100644
--- a/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAO.java
+++ b/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAO.java
@@ -42,6 +42,8 @@ import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColo
import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairStyle;
import com.l2jserver.model.world.character.CharacterClass;
import com.l2jserver.service.database.DatabaseService;
+import com.l2jserver.service.database.MySQLDatabaseService;
+import com.l2jserver.service.database.MySQLDatabaseService.CachedMapper;
import com.l2jserver.service.database.MySQLDatabaseService.InsertUpdateQuery;
import com.l2jserver.service.database.MySQLDatabaseService.Mapper;
import com.l2jserver.service.database.MySQLDatabaseService.SelectListQuery;
@@ -114,16 +116,26 @@ public class MySQL5CharacterDAO extends AbstractMySQL5DAO
/**
* The {@link Mapper} instance
*/
- private final CharacterMapper mapper = new CharacterMapper();
+ private final CharacterMapper mapper = new CharacterMapper(database);
/**
* Character mapper class
*
* @author Rogiel
*/
- private final class CharacterMapper implements Mapper {
+ private final class CharacterMapper extends
+ CachedMapper {
+ public CharacterMapper(MySQLDatabaseService database) {
+ super(database);
+ }
+
@Override
- public L2Character map(ResultSet rs) throws SQLException {
+ protected CharacterID createID(ResultSet rs) throws SQLException {
+ return idFactory.createID(rs.getInt(CHAR_ID));
+ }
+
+ @Override
+ protected L2Character map(CharacterID id, ResultSet rs) throws SQLException {
final CharacterClass charClass = CharacterClass.valueOf(rs
.getString(CLASS));
final CharacterTemplateID templateId = templateIdFactory
@@ -133,7 +145,7 @@ public class MySQL5CharacterDAO extends AbstractMySQL5DAO
final L2Character character = new L2Character(
template.getBaseAttributes());
- character.setID(idFactory.createID(rs.getInt(CHAR_ID)));
+ character.setID(id);
character.setAccountID(accountIdFactory.createID(rs
.getString(ACCOUNT_ID)));
if (rs.getString(CLAN_ID) != null)
@@ -164,8 +176,62 @@ public class MySQL5CharacterDAO extends AbstractMySQL5DAO
character.getAppearance().setFace(
CharacterFace.valueOf(rs.getString(APPEARANCE_FACE)));
+ database.updateCache(character.getID(), character);
+
return character;
}
+
+ // @Override
+ // public L2Character map(ResultSet rs) throws SQLException {
+ // final CharacterID id = idFactory.createID(rs.getInt(CHAR_ID));
+ //
+ // if (database.hasCachedObject(id))
+ // return (L2Character) database.getCachedObject(id);
+ //
+ // final CharacterClass charClass = CharacterClass.valueOf(rs
+ // .getString(CLASS));
+ // final CharacterTemplateID templateId = templateIdFactory
+ // .createID(charClass.id);
+ // final CharacterTemplate template = templateId.getTemplate();
+ //
+ // final L2Character character = new L2Character(
+ // template.getBaseAttributes());
+ //
+ // character.setID(id);
+ // character.setAccountID(accountIdFactory.createID(rs
+ // .getString(ACCOUNT_ID)));
+ // if (rs.getString(CLAN_ID) != null)
+ // character.setClanID(clanIdFactory.createID(rs.getInt(CLAN_ID)));
+ //
+ // character.setName(rs.getString(NAME));
+ //
+ // character.setRace(Race.valueOf(rs.getString(RACE)));
+ // character.setCharacterClass(CharacterClass.valueOf(rs
+ // .getString(CLASS)));
+ // character.setSex(Sex.valueOf(rs.getString(SEX)));
+ //
+ // character.setLevel(rs.getInt(LEVEL));
+ // // TODO load experience
+ // // TODO load sp
+ //
+ // character.setPoint(Point.fromXYZA(rs.getInt(POINT_X),
+ // rs.getInt(POINT_Y), rs.getInt(POINT_Z),
+ // rs.getDouble(POINT_ANGLE)));
+ //
+ // // appearance
+ // character.getAppearance().setHairStyle(
+ // CharacterHairStyle.valueOf(rs
+ // .getString(APPEARANCE_HAIR_STYLE)));
+ // character.getAppearance().setHairColor(
+ // CharacterHairColor.valueOf(rs
+ // .getString(APPEARANCE_HAIR_COLOR)));
+ // character.getAppearance().setFace(
+ // CharacterFace.valueOf(rs.getString(APPEARANCE_FACE)));
+ //
+ // database.updateCache(character.getID(), character);
+ //
+ // return character;
+ // }
}
@Override
@@ -235,8 +301,7 @@ public class MySQL5CharacterDAO extends AbstractMySQL5DAO
return database.query(new SelectListQuery() {
@Override
protected String query() {
- return "SELECT * FROM `" + TABLE + "` WHERE `" + CHAR_ID
- + "` = ?";
+ return "SELECT * FROM `" + TABLE + "`";
}
@Override
diff --git a/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5ClanDAO.java b/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5ClanDAO.java
new file mode 100644
index 000000000..5179af93c
--- /dev/null
+++ b/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5ClanDAO.java
@@ -0,0 +1,158 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * l2jserver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with l2jserver. If not, see .
+ */
+package com.l2jserver.db.dao.mysql5;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+import com.google.inject.Inject;
+import com.l2jserver.db.dao.CharacterDAO;
+import com.l2jserver.db.dao.ClanDAO;
+import com.l2jserver.model.id.object.CharacterID;
+import com.l2jserver.model.id.object.ClanID;
+import com.l2jserver.model.id.object.factory.CharacterIDFactory;
+import com.l2jserver.model.id.object.factory.ClanIDFactory;
+import com.l2jserver.model.world.Clan;
+import com.l2jserver.service.database.DatabaseService;
+import com.l2jserver.service.database.MySQLDatabaseService;
+import com.l2jserver.service.database.MySQLDatabaseService.CachedMapper;
+import com.l2jserver.service.database.MySQLDatabaseService.InsertUpdateQuery;
+import com.l2jserver.service.database.MySQLDatabaseService.Mapper;
+import com.l2jserver.service.database.MySQLDatabaseService.SelectListQuery;
+import com.l2jserver.service.database.MySQLDatabaseService.SelectSingleQuery;
+
+/**
+ * {@link CharacterDAO} implementation for MySQL5
+ *
+ * @author Rogiel
+ */
+public class MySQL5ClanDAO extends AbstractMySQL5DAO implements ClanDAO {
+ /**
+ * The {@link ClanID} factory
+ */
+ private final ClanIDFactory idFactory;
+ /**
+ * The {@link CharacterID} factory
+ */
+ private final CharacterIDFactory charIdFactory;
+
+ /**
+ * Character table name
+ */
+ public static final String TABLE = "clan";
+ // FIELDS
+ public static final String CLAN_ID = "clan_id";
+ public static final String CHAR_ID_LEADER = "character_id_leader";
+
+ @Inject
+ public MySQL5ClanDAO(DatabaseService database, ClanIDFactory clanIdFactory,
+ final CharacterIDFactory idFactory) {
+ super(database);
+ this.idFactory = clanIdFactory;
+ this.charIdFactory = idFactory;
+ }
+
+ /**
+ * The {@link Mapper} instance
+ */
+ private final ClanMapper mapper = new ClanMapper(database);
+
+ /**
+ * Clan mapper class
+ *
+ * @author Rogiel
+ */
+ private final class ClanMapper extends CachedMapper {
+ public ClanMapper(MySQLDatabaseService database) {
+ super(database);
+ }
+
+ @Override
+ protected ClanID createID(ResultSet rs) throws SQLException {
+ return idFactory.createID(rs.getInt(CLAN_ID));
+ }
+
+ @Override
+ protected Clan map(ClanID id, ResultSet rs) throws SQLException {
+ final Clan clan = new Clan();
+ clan.setID(id);
+ return clan;
+ }
+ }
+
+ @Override
+ public Clan load(final ClanID id) {
+ return database.query(new SelectSingleQuery() {
+ @Override
+ protected String query() {
+ return "SELECT * FROM `" + TABLE + "` WHERE `" + CLAN_ID
+ + "` = ?";
+ }
+
+ @Override
+ protected void parametize(PreparedStatement st) throws SQLException {
+ st.setInt(1, id.getID());
+ }
+
+ @Override
+ protected Mapper mapper() {
+ return mapper;
+ }
+ });
+ }
+
+ @Override
+ public List listIDs() {
+ return database.query(new SelectListQuery() {
+ @Override
+ protected String query() {
+ return "SELECT * FROM `" + TABLE + "`";
+ }
+
+ @Override
+ protected Mapper mapper() {
+ return new Mapper() {
+ @Override
+ public ClanID map(ResultSet rs) throws SQLException {
+ return idFactory.createID(rs.getInt(CLAN_ID));
+ }
+ };
+ }
+ });
+ }
+
+ @Override
+ public boolean save(Clan clan) {
+ return database.query(new InsertUpdateQuery(clan) {
+ @Override
+ protected String query() {
+ return "INSERT INTO `" + TABLE + "` (`" + CLAN_ID
+ + "`) VALUES(?)";
+ }
+
+ @Override
+ protected void parametize(PreparedStatement st, Clan clan)
+ throws SQLException {
+ int i = 1;
+
+ st.setInt(i++, clan.getID().getID());
+ }
+ }) > 0;
+ }
+}
diff --git a/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5ItemDAO.java b/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5ItemDAO.java
index b25f481ae..ef5853d30 100644
--- a/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5ItemDAO.java
+++ b/src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5ItemDAO.java
@@ -90,13 +90,20 @@ public class MySQL5ItemDAO extends AbstractMySQL5DAO- implements ItemDAO {
private final class ItemMapper implements Mapper
- {
@Override
public Item map(ResultSet rs) throws SQLException {
+ final ItemID id = idFactory.createID(rs.getInt(ITEM_ID));
+
+ if (database.hasCachedObject(id))
+ return (Item) database.getCachedObject(id);
+
final ItemTemplateID templateId = templateIdFactory.createID(rs
.getInt(TEMPLATE_ID));
final ItemTemplate template = templateId.getTemplate();
final Item item = template.create();
- item.setID(idFactory.createID(rs.getInt(ITEM_ID)));
+ item.setID(id);
item.setOwnerID(charIdFactory.createID(rs.getInt(CHAR_ID)));
+
+ database.updateCache(item.getID(), item);
return item;
}
diff --git a/src/main/java/com/l2jserver/game/net/Lineage2Connection.java b/src/main/java/com/l2jserver/game/net/Lineage2Connection.java
index 870fe45b0..e3077d0b1 100644
--- a/src/main/java/com/l2jserver/game/net/Lineage2Connection.java
+++ b/src/main/java/com/l2jserver/game/net/Lineage2Connection.java
@@ -25,6 +25,7 @@ import com.l2jserver.game.net.codec.Lineage2Encrypter;
import com.l2jserver.game.net.codec.Lineage2PacketReader;
import com.l2jserver.game.net.codec.Lineage2PacketWriter;
import com.l2jserver.game.net.packet.ServerPacket;
+import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.world.L2Character;
/**
@@ -41,7 +42,7 @@ public class Lineage2Connection {
/**
* The character object
*/
- private L2Character character;
+ private CharacterID characterID;
/**
* The Lineage 2 session
*/
@@ -80,22 +81,29 @@ public class Lineage2Connection {
* @return the character
*/
public boolean hasCharacter() {
- return character != null;
+ return characterID != null;
+ }
+
+ /**
+ * @return the character ID
+ */
+ public CharacterID getCharacterID() {
+ return characterID;
}
/**
* @return the character
*/
public L2Character getCharacter() {
- return character;
+ return characterID.getObject();
}
/**
- * @param character
- * the character to set
+ * @param characterID
+ * the character ID to set
*/
- public void setCharacter(L2Character character) {
- this.character = character;
+ public void setCharacterID(CharacterID characterID) {
+ this.characterID = characterID;
}
/**
diff --git a/src/main/java/com/l2jserver/game/net/Lineage2CryptographyKey.java b/src/main/java/com/l2jserver/game/net/Lineage2CryptographyKey.java
index a5392e62c..96b48f19d 100644
--- a/src/main/java/com/l2jserver/game/net/Lineage2CryptographyKey.java
+++ b/src/main/java/com/l2jserver/game/net/Lineage2CryptographyKey.java
@@ -16,10 +16,6 @@
*/
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.
@@ -42,16 +38,6 @@ public class Lineage2CryptographyKey implements Cloneable {
this.key = key;
}
- /**
- * Crates a new random key
- *
- * @return the random created key
- */
- public static Lineage2CryptographyKey createRandomKey() {
- return new Lineage2CryptographyKey(Arrays.copyOf(
- BlowFishKeygen.getRandomKey(), 16));
- }
-
/**
* @return the key
*/
diff --git a/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java b/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java
index 9e4d5aeaa..ef9a7184f 100644
--- a/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java
+++ b/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java
@@ -32,6 +32,7 @@ import com.l2jserver.game.net.codec.Lineage2FrameEncoder;
import com.l2jserver.game.net.codec.Lineage2PacketReader;
import com.l2jserver.game.net.codec.Lineage2PacketWriter;
import com.l2jserver.game.net.handler.Lineage2PacketHandler;
+import com.l2jserver.service.network.NettyNetworkService;
/**
* This class creates a new instance of {@link ChannelPipeline} and attaches all
@@ -44,10 +45,16 @@ public class Lineage2PipelineFactory implements ChannelPipelineFactory {
* The Google Guice {@link Injector}.
*/
private final Injector injector;
+ /**
+ * The {@link NettyNetworkService}
+ */
+ private final NettyNetworkService nettyNetworkService;
@Inject
- public Lineage2PipelineFactory(Injector injector) {
+ public Lineage2PipelineFactory(Injector injector,
+ NettyNetworkService nettyNetworkService) {
this.injector = injector;
+ this.nettyNetworkService = nettyNetworkService;
}
@Override
@@ -73,7 +80,7 @@ public class Lineage2PipelineFactory implements ChannelPipelineFactory {
pipeline.addLast("logger", new LoggingHandler(InternalLogLevel.DEBUG,
true));
- pipeline.addLast("packet.handler", new Lineage2PacketHandler());
+ pipeline.addLast("packet.handler", new Lineage2PacketHandler(nettyNetworkService));
return pipeline;
}
diff --git a/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java b/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java
index 500560889..01844a5c3 100644
--- a/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java
+++ b/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java
@@ -72,11 +72,9 @@ public class Lineage2Decrypter extends OneToOneDecoder {
*
* @return the generated key
*/
- public Lineage2CryptographyKey enable() {
- Lineage2CryptographyKey key = Lineage2CryptographyKey.createRandomKey();
+ public void enable(Lineage2CryptographyKey key) {
this.setKey(key);
this.setEnabled(true);
- return key;
}
/**
diff --git a/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java b/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java
index 7a14fb584..bddeddedb 100644
--- a/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java
+++ b/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java
@@ -23,6 +23,7 @@ import org.jboss.netty.channel.SimpleChannelHandler;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.ClientPacket;
+import com.l2jserver.service.network.NettyNetworkService;
/**
* This handler dispatches the {@link ClientPacket#process(Lineage2Connection)}
@@ -32,17 +33,27 @@ import com.l2jserver.game.net.packet.ClientPacket;
* @author Rogiel
*/
public class Lineage2PacketHandler extends SimpleChannelHandler {
+ /**
+ * The {@link NettyNetworkService}
+ */
+ private final NettyNetworkService nettyNetworkService;
/**
* The Lineage 2 connection
*/
private Lineage2Connection connection;
+ public Lineage2PacketHandler(NettyNetworkService nettyNetworkService) {
+ this.nettyNetworkService = nettyNetworkService;
+ }
+
@Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
connection = new Lineage2Connection(e.getChannel());
connection.getPacketWriter().setConnection(connection);
+ nettyNetworkService.register(connection);
+
super.channelOpen(ctx, e);
}
@@ -62,4 +73,10 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
throws Exception {
super.writeRequested(ctx, e);
}
+
+ @Override
+ public void channelDisconnected(ChannelHandlerContext ctx,
+ ChannelStateEvent e) throws Exception {
+ nettyNetworkService.unregister(connection);
+ }
}
diff --git a/src/main/java/com/l2jserver/game/net/packet/client/AuthLoginPacket.java b/src/main/java/com/l2jserver/game/net/packet/client/AuthLoginPacket.java
index 873060ae1..20741ce24 100644
--- a/src/main/java/com/l2jserver/game/net/packet/client/AuthLoginPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/client/AuthLoginPacket.java
@@ -39,12 +39,24 @@ import com.l2jserver.util.BufferUtils;
* @author Rogiel
*/
public class AuthLoginPacket extends AbstractClientPacket {
+ /**
+ * The packet OPCODE
+ */
public static final int OPCODE = 0x2b;
+ /**
+ * The {@link CharacterDAO} implementation
+ */
private final CharacterDAO characterDao;
+ /**
+ * The {@link AccountID} factory
+ */
private final AccountIDFactory accountIdFactory;
// packet
+ /**
+ * User account name
+ */
private String loginName;
private int playKey1;
private int playKey2;
diff --git a/src/main/java/com/l2jserver/game/net/packet/client/CharacterCreatePacket.java b/src/main/java/com/l2jserver/game/net/packet/client/CharacterCreatePacket.java
index 059a22594..a92cbf701 100644
--- a/src/main/java/com/l2jserver/game/net/packet/client/CharacterCreatePacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/client/CharacterCreatePacket.java
@@ -37,6 +37,7 @@ 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.model.world.character.CharacterClass;
import com.l2jserver.util.BufferUtils;
/**
@@ -46,6 +47,9 @@ import com.l2jserver.util.BufferUtils;
* @author Rogiel
*/
public class CharacterCreatePacket extends AbstractClientPacket {
+ /**
+ * The packet OPCODE
+ */
public static final int OPCODE = 0x0c;
/**
@@ -55,25 +59,79 @@ public class CharacterCreatePacket extends AbstractClientPacket {
.getLogger(CharacterCreatePacket.class);
// services and daos
+ /**
+ * The {@link CharacterDAO} implementation
+ */
private final CharacterDAO characterDao;
+ /**
+ * The {@link CharacterID} factory
+ */
private final CharacterIDFactory characterIdFactory;
+ /**
+ * The {@link CharacterTemplateID} factory
+ */
private final CharacterTemplateIDFactory characterTemplateIdFactory;
// packet
+ /**
+ * The name of the new character
+ */
private String name;
+ /**
+ * The race of the new character
+ */
private Race race;
+ /**
+ * The sex of the new character
+ */
private Sex sex;
- private int classId;
+ /**
+ * The class of the new character
+ */
+ private CharacterClass characterClass;
+ /**
+ * The new character intelligence. Note that this is ignored and the
+ * template value is used.
+ */
private int intelligence;
+ /**
+ * The new character intelligence. Note that this is ignored and the
+ * template value is used.
+ */
private int strength;
+ /**
+ * The new character strength. Note that this is ignored and the template
+ * value is used.
+ */
private int concentration;
+ /**
+ * The new character concentration. Note that this is ignored and the
+ * template value is used.
+ */
private int mentality;
+ /**
+ * The new character mentality. Note that this is ignored and the template
+ * value is used.
+ */
private int dexterity;
+ /**
+ * The new character dexterity. Note that this is ignored and the template
+ * value is used.
+ */
private int witness;
+ /**
+ * The new character hair style
+ */
private CharacterHairStyle hairStyle;
+ /**
+ * The new character hair color
+ */
private CharacterHairColor hairColor;
+ /**
+ * The new character face
+ */
private CharacterFace face;
@Inject
@@ -90,7 +148,7 @@ public class CharacterCreatePacket extends AbstractClientPacket {
name = BufferUtils.readString(buffer);
race = Race.fromOption(buffer.readInt());
sex = Sex.fromOption(buffer.readInt());
- classId = buffer.readInt();
+ characterClass = CharacterClass.fromID(buffer.readInt());
intelligence = buffer.readInt();
strength = buffer.readInt();
@@ -106,8 +164,8 @@ public class CharacterCreatePacket extends AbstractClientPacket {
@Override
public void process(final Lineage2Connection conn) {
- log.debug("Creating a new character, race={}, sex={}, classid={}",
- new Object[] { race, sex, classId });
+ log.debug("Creating a new character, race={}, sex={}, class={}",
+ new Object[] { race, sex, characterClass });
if ((name.length() < 1) || (name.length() > 16)) {
log.debug("Character name length invalid: {}. Aborting.", name);
conn.write(new CharacterCreateFailPacket(
@@ -135,7 +193,7 @@ public class CharacterCreatePacket extends AbstractClientPacket {
// create template id and lookup for the template instance
final CharacterTemplateID templateId = characterTemplateIdFactory
- .createID(classId);
+ .createID(characterClass.id);
final CharacterTemplate template = templateId.getTemplate();
log.debug("Creating character with template {}", template);
@@ -239,18 +297,18 @@ public class CharacterCreatePacket extends AbstractClientPacket {
}
/**
- * @return the classId
+ * @return the character class
*/
- public int getClassId() {
- return classId;
+ public CharacterClass getCharacterClass() {
+ return characterClass;
}
/**
- * @param classId
- * the classId to set
+ * @param characterClass
+ * the character class
*/
- public void setClassId(int classId) {
- this.classId = classId;
+ public void setClassId(CharacterClass characterClass) {
+ this.characterClass = characterClass;
}
/**
diff --git a/src/main/java/com/l2jserver/game/net/packet/client/EnterWorld.java b/src/main/java/com/l2jserver/game/net/packet/client/EnterWorld.java
index c2ae94261..7ce7d1dbf 100644
--- a/src/main/java/com/l2jserver/game/net/packet/client/EnterWorld.java
+++ b/src/main/java/com/l2jserver/game/net/packet/client/EnterWorld.java
@@ -29,6 +29,9 @@ import com.l2jserver.game.net.packet.server.InventoryPacket;
* @author Rogiel
*/
public class EnterWorld extends AbstractClientPacket {
+ /**
+ * The packet OPCODE
+ */
public static final int OPCODE = 0x11;
@Override
diff --git a/src/main/java/com/l2jserver/game/net/packet/client/LogoutPacket.java b/src/main/java/com/l2jserver/game/net/packet/client/LogoutPacket.java
index 17a43296b..cd8797ca2 100644
--- a/src/main/java/com/l2jserver/game/net/packet/client/LogoutPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/client/LogoutPacket.java
@@ -30,6 +30,9 @@ import com.l2jserver.game.net.packet.AbstractClientPacket;
* @author Rogiel
*/
public class LogoutPacket extends AbstractClientPacket {
+ /**
+ * The packet OPCODE
+ */
public static final int OPCODE = 0x00;
/**
diff --git a/src/main/java/com/l2jserver/game/net/packet/client/ProtocolVersionPacket.java b/src/main/java/com/l2jserver/game/net/packet/client/ProtocolVersionPacket.java
index 45e1dd34f..41544df90 100644
--- a/src/main/java/com/l2jserver/game/net/packet/client/ProtocolVersionPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/client/ProtocolVersionPacket.java
@@ -22,12 +22,14 @@ import org.jboss.netty.channel.ChannelFutureListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.inject.Inject;
import com.l2jserver.L2JConstants;
import com.l2jserver.game.ProtocolVersion;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.Lineage2CryptographyKey;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.KeyPacket;
+import com.l2jserver.service.blowfish.BlowfishKeygenService;
/**
* In this packet the client is informing its protocol version. It is possible
@@ -38,6 +40,9 @@ import com.l2jserver.game.net.packet.server.KeyPacket;
* @author Rogiel
*/
public class ProtocolVersionPacket extends AbstractClientPacket {
+ /**
+ * The packet OPCODE
+ */
public static final int OPCODE = 0x0e;
/**
@@ -46,9 +51,24 @@ public class ProtocolVersionPacket extends AbstractClientPacket {
private final Logger log = LoggerFactory
.getLogger(ProtocolVersionPacket.class);
+ // services
+ /**
+ * The {@link BlowfishKeygenService} implementation. Use to generate
+ * cryptography keys.
+ */
+ private final BlowfishKeygenService keygen;
+
// packet
+ /**
+ * The client version of the protocol
+ */
private ProtocolVersion version;
+ @Inject
+ public ProtocolVersionPacket(BlowfishKeygenService keygen) {
+ this.keygen = keygen;
+ }
+
@Override
public void read(Lineage2Connection conn, ChannelBuffer buffer) {
this.version = ProtocolVersion.fromVersion((int) buffer
@@ -58,7 +78,10 @@ public class ProtocolVersionPacket extends AbstractClientPacket {
@Override
public void process(final Lineage2Connection conn) {
// generate a new key
- final Lineage2CryptographyKey inKey = conn.getDecrypter().enable();
+ final Lineage2CryptographyKey inKey = new Lineage2CryptographyKey(
+ keygen.generate());
+
+ conn.getDecrypter().enable(inKey);
final Lineage2CryptographyKey outKey = inKey.clone();
log.debug("Decrypter has been enabled");
diff --git a/src/main/java/com/l2jserver/game/net/packet/client/RequestCharacterTemplatesPacket.java b/src/main/java/com/l2jserver/game/net/packet/client/RequestCharacterTemplatesPacket.java
index 9c13ec1ae..893fe8264 100644
--- a/src/main/java/com/l2jserver/game/net/packet/client/RequestCharacterTemplatesPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/client/RequestCharacterTemplatesPacket.java
@@ -37,8 +37,14 @@ import com.l2jserver.model.world.character.CharacterClass;
* @author Rogiel
*/
public class RequestCharacterTemplatesPacket extends AbstractClientPacket {
+ /**
+ * The packet OPCODE
+ */
public static final int OPCODE = 0x13;
+ /**
+ * List of {@link CharacterClass} templates sent to the client
+ */
public static final CharacterClass[] TEMPLATE_CLASSES = {
CharacterClass.HUMAN_FIGHTER, CharacterClass.HUMAN_MYSTIC,
CharacterClass.ELVEN_FIGHTER, CharacterClass.ELVEN_MYSTIC,
@@ -53,6 +59,9 @@ public class RequestCharacterTemplatesPacket extends AbstractClientPacket {
private static final Logger log = LoggerFactory
.getLogger(RequestCharacterTemplatesPacket.class);
+ /**
+ * The {@link CharacterTemplateID} factory
+ */
private final CharacterTemplateIDFactory idFactory;
@Inject
diff --git a/src/main/java/com/l2jserver/game/net/packet/client/RequestGotoLobby.java b/src/main/java/com/l2jserver/game/net/packet/client/RequestGotoLobby.java
index 8d65863ba..edace873e 100644
--- a/src/main/java/com/l2jserver/game/net/packet/client/RequestGotoLobby.java
+++ b/src/main/java/com/l2jserver/game/net/packet/client/RequestGotoLobby.java
@@ -34,9 +34,18 @@ import com.l2jserver.model.world.L2Character;
* @author Rogiel
*/
public class RequestGotoLobby extends AbstractClientPacket {
+ /**
+ * The packet OPCODE1
+ */
public static final int OPCODE1 = 0xd0;
+ /**
+ * The packet OPCODE2
+ */
public static final int OPCODE2 = 0x36;
+ /**
+ * The {@link CharacterDAO} implementation
+ */
private final CharacterDAO characterDao;
@Inject
diff --git a/src/main/java/com/l2jserver/game/net/packet/client/RequestKeyMapping.java b/src/main/java/com/l2jserver/game/net/packet/client/RequestKeyMapping.java
index d7c6b610d..e7ac1212e 100644
--- a/src/main/java/com/l2jserver/game/net/packet/client/RequestKeyMapping.java
+++ b/src/main/java/com/l2jserver/game/net/packet/client/RequestKeyMapping.java
@@ -22,13 +22,18 @@ 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.
+ * The client is requesting a the key mappings.
*
* @author Rogiel
*/
public class RequestKeyMapping extends AbstractClientPacket {
+ /**
+ * The packet OPCODE1
+ */
public static final int OPCODE1 = 0xd0;
+ /**
+ * The packet OPCODE2
+ */
public static final int OPCODE2 = 0x21;
@Override
diff --git a/src/main/java/com/l2jserver/game/net/packet/client/RequestManorList.java b/src/main/java/com/l2jserver/game/net/packet/client/RequestManorList.java
index 458e3db8a..bfddebe53 100644
--- a/src/main/java/com/l2jserver/game/net/packet/client/RequestManorList.java
+++ b/src/main/java/com/l2jserver/game/net/packet/client/RequestManorList.java
@@ -23,13 +23,18 @@ import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.ManorListPacket;
/**
- * The client is requesting a logout. Currently, when this packet is received
- * the connection is immediately closed.
+ * The client is requesting the manor list.
*
* @author Rogiel
*/
public class RequestManorList extends AbstractClientPacket {
+ /**
+ * The packet OPCODE1
+ */
public static final int OPCODE1 = 0xd0;
+ /**
+ * The packet OPCODE2
+ */
public static final int OPCODE2 = 0x01;
@Override
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/CharacterCreateFailPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/CharacterCreateFailPacket.java
index 0c512282e..9611d2723 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/CharacterCreateFailPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/CharacterCreateFailPacket.java
@@ -28,8 +28,14 @@ import com.l2jserver.game.net.packet.AbstractServerPacket;
* @see Reason
*/
public class CharacterCreateFailPacket extends AbstractServerPacket {
+ /**
+ * The packet OPCODE
+ */
public static final int OPCODE = 0x10;
+ /**
+ * The character creation failure reason
+ */
private Reason reason;
/**
@@ -72,9 +78,12 @@ public class CharacterCreateFailPacket extends AbstractServerPacket {
*/
REASON_CHOOSE_ANOTHER_SVR(0x06);
+ /**
+ * The error code id
+ */
public final int id;
- private Reason(int id) {
+ Reason(int id) {
this.id = id;
}
}
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/CharacterCreateOkPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/CharacterCreateOkPacket.java
index cd1955124..b53797581 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/CharacterCreateOkPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/CharacterCreateOkPacket.java
@@ -27,8 +27,14 @@ import com.l2jserver.game.net.packet.AbstractServerPacket;
* @author Rogiel
*/
public class CharacterCreateOkPacket extends AbstractServerPacket {
+ /**
+ * The packet OPCODE
+ */
public static final int OPCODE = 0x0f;
+ /**
+ * The packet shared instance
+ */
public static final CharacterCreateOkPacket INSTANCE = new CharacterCreateOkPacket();
public CharacterCreateOkPacket() {
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/CharacterEnterWorldPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/CharacterEnterWorldPacket.java
index 0097efbfd..e00c7e088 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/CharacterEnterWorldPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/CharacterEnterWorldPacket.java
@@ -30,11 +30,28 @@ import com.l2jserver.util.BufferUtils;
* @author Rogiel
*/
public class CharacterEnterWorldPacket extends AbstractServerPacket {
+ /**
+ * The packet OPCODE
+ */
public static final int OPCODE = 0x0b;
+ /**
+ * The entering character
+ */
private final L2Character character;
+ /**
+ * The session ID
+ */
private final int sessionId;
+ /**
+ * Creates a new instance
+ *
+ * @param character
+ * the character
+ * @param sessionId
+ * the session id
+ */
public CharacterEnterWorldPacket(L2Character character, int sessionId) {
super(OPCODE);
this.character = character;
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/CharacterSelectionListPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/CharacterSelectionListPacket.java
index e82f9402f..0eea5c647 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/CharacterSelectionListPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/CharacterSelectionListPacket.java
@@ -32,11 +32,23 @@ import com.l2jserver.util.BufferUtils;
* @author Rogiel
*/
public class CharacterSelectionListPacket extends AbstractServerPacket {
+ /**
+ * The packet OPCODE
+ */
public static final int OPCODE = 0x09;
+ /**
+ * The account username
+ */
private final String loginName;
+ /**
+ * The session ID
+ */
private final int sessionId;
// private int lastCharacterId;
+ /**
+ * The list of character to be displayed
+ */
private final L2Character[] characters;
public CharacterSelectionListPacket(String loginName, int sessionId,
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/CharacterTemplatePacket.java b/src/main/java/com/l2jserver/game/net/packet/server/CharacterTemplatePacket.java
index b232b155c..73cbac3e1 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/CharacterTemplatePacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/CharacterTemplatePacket.java
@@ -28,8 +28,14 @@ import com.l2jserver.model.template.CharacterTemplate;
* @author Rogiel
*/
public class CharacterTemplatePacket extends AbstractServerPacket {
+ /**
+ * The packet OPCODE
+ */
public static final int OPCODE = 0x0d;
+ /**
+ * The character template list
+ */
private CharacterTemplate[] templates;
public CharacterTemplatePacket(CharacterTemplate... templates) {
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/InventoryPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/InventoryPacket.java
index 4f70ca5a6..8e0ddb9b5 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/InventoryPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/InventoryPacket.java
@@ -30,11 +30,17 @@ import com.l2jserver.model.world.character.CharacterInventory;
*/
public class InventoryPacket extends AbstractServerPacket {
/**
- * Message OPCODE
+ * The packet OPCODE
*/
public static final int OPCODE = 0x11;
+ /**
+ * The character inventory
+ */
private CharacterInventory inventory;
+ /**
+ * Whether or not to open the inventory window
+ */
private boolean showWindow = false;
public InventoryPacket(CharacterInventory inventory) {
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/KeyPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/KeyPacket.java
index a06af7bbe..ec4181a06 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/KeyPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/KeyPacket.java
@@ -32,7 +32,7 @@ import com.l2jserver.game.net.packet.AbstractServerPacket;
*/
public class KeyPacket extends AbstractServerPacket {
/**
- * Message OPCODE
+ * The packet OPCODE
*/
public static final int OPCODE = 0x2e;
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/ManorListPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/ManorListPacket.java
index 5e11d45c3..91e721e10 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/ManorListPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/ManorListPacket.java
@@ -29,10 +29,13 @@ import com.l2jserver.util.BufferUtils;
*/
public class ManorListPacket extends AbstractServerPacket {
/**
- * Message OPCODE
+ * The packet OPCODE
*/
public static final int OPCODE = 0xfe;
+ /**
+ * List of manors to be sent
+ */
private String[] manors;
public ManorListPacket(String... manors) {
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/UserInformationPacket.java b/src/main/java/com/l2jserver/game/net/packet/server/UserInformationPacket.java
index 10b883fb4..200e10275 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/UserInformationPacket.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/UserInformationPacket.java
@@ -29,10 +29,13 @@ import com.l2jserver.util.BufferUtils;
*/
public class UserInformationPacket extends AbstractServerPacket {
/**
- * Message OPCODE
+ * The packet OPCODE
*/
public static final int OPCODE = 0xfe;
+ /**
+ * TODO
+ */
private String[] manors;
public UserInformationPacket(String... manors) {
diff --git a/src/main/java/com/l2jserver/model/id/factory/IDFactoryModule.java b/src/main/java/com/l2jserver/model/id/factory/IDFactoryModule.java
index 819bc1871..65e3ac373 100644
--- a/src/main/java/com/l2jserver/model/id/factory/IDFactoryModule.java
+++ b/src/main/java/com/l2jserver/model/id/factory/IDFactoryModule.java
@@ -24,6 +24,8 @@ import com.l2jserver.model.id.object.allocator.BitSetIDAllocator;
import com.l2jserver.model.id.object.allocator.IDAllocator;
import com.l2jserver.model.id.object.factory.CharacterIDFactory;
import com.l2jserver.model.id.object.factory.CharacterIDFactory.CharacterIDGuiceFactory;
+import com.l2jserver.model.id.object.factory.ClanIDFactory;
+import com.l2jserver.model.id.object.factory.ClanIDFactory.ClanIDGuiceFactory;
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;
@@ -51,9 +53,9 @@ public class IDFactoryModule extends AbstractModule {
bind(ItemIDFactory.class).in(Scopes.SINGLETON);
install(new FactoryModuleBuilder().build(ItemIDGuiceFactory.class));
- // bind(ClanIDFactory.class).in(Scopes.SINGLETON);
- // install(new FactoryModuleBuilder().build(ClanIDGuiceFactory.class));
- //
+ bind(ClanIDFactory.class).in(Scopes.SINGLETON);
+ install(new FactoryModuleBuilder().build(ClanIDGuiceFactory.class));
+
// bind(PetIDFactory.class).in(Scopes.SINGLETON);
// install(new FactoryModuleBuilder().build(PetIDGuiceFactory.class));
diff --git a/src/main/java/com/l2jserver/model/id/object/ClanID.java b/src/main/java/com/l2jserver/model/id/object/ClanID.java
index f4b6137b5..c3955403f 100644
--- a/src/main/java/com/l2jserver/model/id/object/ClanID.java
+++ b/src/main/java/com/l2jserver/model/id/object/ClanID.java
@@ -17,6 +17,7 @@
package com.l2jserver.model.id.object;
import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
import com.l2jserver.db.dao.ClanDAO;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.world.Clan;
@@ -33,7 +34,7 @@ public final class ClanID extends ObjectID {
private final ClanDAO clanDao;
@Inject
- protected ClanID(int id, ClanDAO clanDao) {
+ protected ClanID(@Assisted int id, ClanDAO clanDao) {
super(id);
this.clanDao = clanDao;
}
diff --git a/src/main/java/com/l2jserver/service/ServiceModule.java b/src/main/java/com/l2jserver/service/ServiceModule.java
index 38d0d5ce6..77801f2e2 100644
--- a/src/main/java/com/l2jserver/service/ServiceModule.java
+++ b/src/main/java/com/l2jserver/service/ServiceModule.java
@@ -19,6 +19,10 @@ package com.l2jserver.service;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.Scopes;
+import com.l2jserver.service.blowfish.BlowfishKeygenService;
+import com.l2jserver.service.blowfish.SecureBlowfishKeygenService;
+import com.l2jserver.service.cache.CacheService;
+import com.l2jserver.service.cache.EhCacheService;
import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.configuration.ProxyConfigurationService;
import com.l2jserver.service.database.DatabaseService;
@@ -49,9 +53,13 @@ public class ServiceModule extends AbstractModule {
Scopes.SINGLETON);
bind(ConfigurationService.class).to(ProxyConfigurationService.class)
.in(Scopes.SINGLETON);
+ bind(CacheService.class).to(EhCacheService.class).in(
+ Scopes.SINGLETON);
bind(DatabaseService.class).to(MySQLDatabaseService.class).in(
Scopes.SINGLETON);
+ bind(BlowfishKeygenService.class).to(SecureBlowfishKeygenService.class)
+ .in(Scopes.SINGLETON);
bind(NetworkService.class).to(NettyNetworkService.class).in(
Scopes.SINGLETON);
bind(ScriptingService.class).to(ScriptingServiceImpl.class).in(
diff --git a/src/main/java/com/l2jserver/service/blowfish/BlowfishKeygenService.java b/src/main/java/com/l2jserver/service/blowfish/BlowfishKeygenService.java
new file mode 100644
index 000000000..9d7e2927a
--- /dev/null
+++ b/src/main/java/com/l2jserver/service/blowfish/BlowfishKeygenService.java
@@ -0,0 +1,23 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * l2jserver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with l2jserver. If not, see .
+ */
+package com.l2jserver.service.blowfish;
+
+import com.l2jserver.service.Service;
+
+public interface BlowfishKeygenService extends Service {
+ byte[] generate();
+}
diff --git a/src/main/java/com/l2jserver/service/blowfish/PseudoRandomBlowfishKeygenService.java b/src/main/java/com/l2jserver/service/blowfish/PseudoRandomBlowfishKeygenService.java
new file mode 100644
index 000000000..7760ce533
--- /dev/null
+++ b/src/main/java/com/l2jserver/service/blowfish/PseudoRandomBlowfishKeygenService.java
@@ -0,0 +1,58 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * l2jserver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with l2jserver. If not, see .
+ */
+package com.l2jserver.service.blowfish;
+
+import java.util.Random;
+
+import com.l2jserver.service.AbstractService;
+import com.l2jserver.service.ServiceStartException;
+import com.l2jserver.service.ServiceStopException;
+
+public class PseudoRandomBlowfishKeygenService extends AbstractService
+ implements BlowfishKeygenService {
+ private Random random;
+
+ @Override
+ public void start() throws ServiceStartException {
+ random = new Random();
+ }
+
+ @Override
+ public byte[] generate() {
+ final byte[] key = new byte[16];
+ // randomize the 8 first bytes
+ for (int i = 0; i < key.length; i++) {
+ key[i] = (byte) random.nextInt(255);
+ }
+
+ // the last 8 bytes are static
+ key[8] = (byte) 0xc8;
+ key[9] = (byte) 0x27;
+ key[10] = (byte) 0x93;
+ key[11] = (byte) 0x01;
+ key[12] = (byte) 0xa1;
+ key[13] = (byte) 0x6c;
+ key[14] = (byte) 0x31;
+ key[15] = (byte) 0x97;
+ return key;
+ }
+
+ @Override
+ public void stop() throws ServiceStopException {
+ random = null;
+ }
+}
diff --git a/src/main/java/com/l2jserver/service/blowfish/SecureBlowfishKeygenService.java b/src/main/java/com/l2jserver/service/blowfish/SecureBlowfishKeygenService.java
new file mode 100644
index 000000000..ccf1d11ef
--- /dev/null
+++ b/src/main/java/com/l2jserver/service/blowfish/SecureBlowfishKeygenService.java
@@ -0,0 +1,59 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * l2jserver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with l2jserver. If not, see .
+ */
+package com.l2jserver.service.blowfish;
+
+import org.apache.commons.math.random.RandomData;
+import org.apache.commons.math.random.RandomDataImpl;
+
+import com.l2jserver.service.AbstractService;
+import com.l2jserver.service.ServiceStartException;
+import com.l2jserver.service.ServiceStopException;
+
+public class SecureBlowfishKeygenService extends AbstractService implements
+ BlowfishKeygenService {
+ private RandomData random;
+
+ @Override
+ public void start() throws ServiceStartException {
+ random = new RandomDataImpl();
+ }
+
+ @Override
+ public byte[] generate() {
+ final byte[] key = new byte[16];
+ // randomize the 8 first bytes
+ for (int i = 0; i < key.length; i++) {
+ key[i] = (byte) random.nextSecureInt(0, 255);
+ }
+
+ // the last 8 bytes are static
+ key[8] = (byte) 0xc8;
+ key[9] = (byte) 0x27;
+ key[10] = (byte) 0x93;
+ key[11] = (byte) 0x01;
+ key[12] = (byte) 0xa1;
+ key[13] = (byte) 0x6c;
+ key[14] = (byte) 0x31;
+ key[15] = (byte) 0x97;
+ return key;
+ }
+
+ @Override
+ public void stop() throws ServiceStopException {
+ random = null;
+ }
+}
diff --git a/src/main/java/com/l2jserver/service/cache/CacheService.java b/src/main/java/com/l2jserver/service/cache/CacheService.java
index 5a1ab954e..5b0e17a46 100644
--- a/src/main/java/com/l2jserver/service/cache/CacheService.java
+++ b/src/main/java/com/l2jserver/service/cache/CacheService.java
@@ -16,6 +16,8 @@
*/
package com.l2jserver.service.cache;
+import net.sf.ehcache.Cache;
+
import com.l2jserver.service.Service;
/**
@@ -33,15 +35,54 @@ import com.l2jserver.service.Service;
*/
public interface CacheService extends Service {
/**
- * Decores the instance with the cache
+ * Decorates the instance with the cache. Note that
+ * interfaceType must be an interface!
*
* @param
* the instance type
* @param interfaceType
* the interface type
* @param instance
- * the instance
+ * the instance implementing the interface
* @return the cache-decorated object
*/
T decorate(Class interfaceType, T instance);
+
+ /**
+ * Creates a new cache with default configurations. Eviction mode is LRU
+ * (Last Recently Used). If you wish more customization, you should manually
+ * create the cache and register it using {@link #register(Cache)}.
+ *
+ * @param name
+ * the cache name
+ * @size the maximum cache size
+ * @return the created cache
+ */
+ Cache createCache(String name, int size);
+
+ /**
+ * Creates a new cache with default configurations. The default cache size
+ * is 200.
+ *
+ * @param name
+ * the cache name
+ * @return the created cache
+ */
+ Cache createCache(String name);
+
+ /**
+ * Registers a new cache
+ *
+ * @param cache
+ * the cache
+ */
+ void register(Cache cache);
+
+ /**
+ * Unregisters an already registered cache
+ *
+ * @param cache
+ * the cache
+ */
+ void unregister(Cache cache);
}
diff --git a/src/main/java/com/l2jserver/service/cache/SimpleCacheService.java b/src/main/java/com/l2jserver/service/cache/EhCacheService.java
similarity index 62%
rename from src/main/java/com/l2jserver/service/cache/SimpleCacheService.java
rename to src/main/java/com/l2jserver/service/cache/EhCacheService.java
index 9af7e71a6..7d2a00135 100644
--- a/src/main/java/com/l2jserver/service/cache/SimpleCacheService.java
+++ b/src/main/java/com/l2jserver/service/cache/EhCacheService.java
@@ -20,20 +20,38 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
-import java.util.Map;
import java.util.WeakHashMap;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.config.CacheConfiguration;
+import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
+
import com.l2jserver.service.AbstractService;
-import com.l2jserver.util.factory.CollectionFactory;
+import com.l2jserver.service.ServiceStartException;
+import com.l2jserver.service.ServiceStopException;
/**
* Simple cache that stores invocation results in a {@link WeakHashMap}.
*
* @author Rogiel
*/
-public class SimpleCacheService extends AbstractService implements CacheService {
- private final Map cache = CollectionFactory
- .newWeakMap(MethodInvocation.class, Object.class);
+public class EhCacheService extends AbstractService implements CacheService {
+ /**
+ * The cache manager
+ */
+ private CacheManager manager;
+ /**
+ * The interface cache
+ */
+ private Cache interfaceCache;
+
+ @Override
+ public void start() throws ServiceStartException {
+ manager = new CacheManager();
+ interfaceCache = createCache("interface-cache");
+ }
@Override
public T decorate(final Class interfaceType,
@@ -51,10 +69,11 @@ public class SimpleCacheService extends AbstractService implements CacheService
return method.invoke(instance, args);
final MethodInvocation invocation = new MethodInvocation(
method, args);
- Object result = cache.get(invocation);
+ Object result = interfaceCache.get(invocation)
+ .getObjectValue();
if (result == null) {
result = method.invoke(instance, args);
- cache.put(invocation, result);
+ interfaceCache.put(new Element(invocation, result));
}
return result;
}
@@ -62,7 +81,43 @@ public class SimpleCacheService extends AbstractService implements CacheService
return proxy;
}
- private class MethodInvocation {
+ @Override
+ public Cache createCache(String name, int size) {
+ Cache cache = new Cache(
+ new CacheConfiguration("database-service", size)
+ .memoryStoreEvictionPolicy(
+ MemoryStoreEvictionPolicy.LRU)
+ .overflowToDisk(true).eternal(false)
+ .timeToLiveSeconds(60).timeToIdleSeconds(30)
+ .diskPersistent(false)
+ .diskExpiryThreadIntervalSeconds(0));
+ register(cache);
+ return cache;
+ }
+
+ @Override
+ public Cache createCache(String name) {
+ return createCache(name, 200);
+ }
+
+ @Override
+ public void register(Cache cache) {
+ manager.addCache(cache);
+ }
+
+ @Override
+ public void unregister(Cache cache) {
+ manager.removeCache(cache.getName());
+ }
+
+ @Override
+ public void stop() throws ServiceStopException {
+ manager.removalAll();
+ manager.shutdown();
+ interfaceCache = null;
+ }
+
+ private static class MethodInvocation {
private final Method method;
private final Object[] args;
diff --git a/src/main/java/com/l2jserver/service/database/DB4ODatabaseService.java b/src/main/java/com/l2jserver/service/database/DB4ODatabaseService.java
index 791a98493..03c9e8c66 100644
--- a/src/main/java/com/l2jserver/service/database/DB4ODatabaseService.java
+++ b/src/main/java/com/l2jserver/service/database/DB4ODatabaseService.java
@@ -27,4 +27,27 @@ import com.l2jserver.service.AbstractService;
*/
public class DB4ODatabaseService extends AbstractService implements
DatabaseService {
+ @Override
+ public Object getCachedObject(Object id) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean hasCachedObject(Object id) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public void updateCache(Object key, Object value) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void removeCache(Object key) {
+ // TODO Auto-generated method stub
+
+ }
}
diff --git a/src/main/java/com/l2jserver/service/database/DatabaseService.java b/src/main/java/com/l2jserver/service/database/DatabaseService.java
index eb5880ec1..6891cd0fa 100644
--- a/src/main/java/com/l2jserver/service/database/DatabaseService.java
+++ b/src/main/java/com/l2jserver/service/database/DatabaseService.java
@@ -25,5 +25,40 @@ import com.l2jserver.service.Service;
* @author Rogiel
*/
public interface DatabaseService extends Service {
+ /**
+ * Get the database object cached. Will return null if the object is not in
+ * cache
+ *
+ * @param id
+ * the object id
+ * @return the cached object
+ */
+ Object getCachedObject(Object id);
+ /**
+ * Tests if the object is cached
+ *
+ * @param id
+ * the object id
+ * @return true if object is in cache
+ */
+ boolean hasCachedObject(Object id);
+
+ /**
+ * Adds or update the cache object
+ *
+ * @param key
+ * the cache key
+ * @param value
+ * the object
+ */
+ void updateCache(Object key, Object value);
+
+ /**
+ * Removes an object from the cache
+ *
+ * @param key
+ * the cache key
+ */
+ void removeCache(Object key);
}
diff --git a/src/main/java/com/l2jserver/service/database/MySQLDatabaseService.java b/src/main/java/com/l2jserver/service/database/MySQLDatabaseService.java
index 16256a270..932be1788 100644
--- a/src/main/java/com/l2jserver/service/database/MySQLDatabaseService.java
+++ b/src/main/java/com/l2jserver/service/database/MySQLDatabaseService.java
@@ -25,6 +25,11 @@ import java.util.List;
import javax.sql.DataSource;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.config.CacheConfiguration;
+import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
+
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
@@ -35,9 +40,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
+import com.l2jserver.model.id.ObjectID;
+import com.l2jserver.model.world.WorldObject;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.ServiceStopException;
+import com.l2jserver.service.cache.CacheService;
import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.util.ArrayIterator;
import com.l2jserver.util.factory.CollectionFactory;
@@ -58,6 +66,11 @@ public class MySQLDatabaseService extends AbstractService implements
*/
private final Logger logger = LoggerFactory
.getLogger(MySQLDatabaseService.class);
+ // services
+ /**
+ * The cache service
+ */
+ private final CacheService cacheService;
/**
* The database connection pool
@@ -77,9 +90,16 @@ public class MySQLDatabaseService extends AbstractService implements
*/
private PoolingDataSource dataSource;
+ /**
+ * An cache object
+ */
+ private Cache objectCache;
+
@Inject
- public MySQLDatabaseService(ConfigurationService configService) {
+ public MySQLDatabaseService(ConfigurationService configService,
+ CacheService cacheService) {
config = configService.get(MySQLDatabaseConfiguration.class);
+ this.cacheService = cacheService;
}
@Override
@@ -90,6 +110,14 @@ public class MySQLDatabaseService extends AbstractService implements
poolableConnectionFactory = new PoolableConnectionFactory(
connectionFactory, connectionPool, null, null, false, true);
dataSource = new PoolingDataSource(connectionPool);
+
+ objectCache = new Cache(new CacheConfiguration("database-service",
+ 10 * 1000)
+ .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
+ .overflowToDisk(true).eternal(false).timeToLiveSeconds(60)
+ .timeToIdleSeconds(30).diskPersistent(false)
+ .diskExpiryThreadIntervalSeconds(0));
+ cacheService.register(objectCache);
}
/**
@@ -118,8 +146,34 @@ public class MySQLDatabaseService extends AbstractService implements
}
}
+ @Override
+ public Object getCachedObject(Object id) {
+ final Element element = objectCache.get(id);
+ if (element == null)
+ return null;
+ return element.getObjectValue();
+ }
+
+ @Override
+ public boolean hasCachedObject(Object id) {
+ return objectCache.get(id) != null;
+ }
+
+ @Override
+ public void updateCache(Object key, Object value) {
+ objectCache.put(new Element(key, value));
+ }
+
+ @Override
+ public void removeCache(Object key) {
+ objectCache.remove(key);
+ }
+
@Override
public void stop() throws ServiceStopException {
+ if (objectCache != null)
+ objectCache.dispose();
+ objectCache = null;
try {
if (connectionPool != null)
connectionPool.close();
@@ -368,4 +422,73 @@ public class MySQLDatabaseService extends AbstractService implements
*/
T map(ResultSet rs) throws SQLException;
}
+
+ /**
+ * The cached mapper will try to lookup the result in the cache, before
+ * create a new instance. If the instance is not found in the cache, then
+ * the {@link Mapper} implementation is called to create the object. Note
+ * that the ID, used for the cache lookup, will be reused. After creation,
+ * the cache is updated.
+ *
+ * @author Rogiel
+ *
+ * @param
+ * the object type
+ * @param
+ * the id type
+ */
+ public abstract static class CachedMapper>
+ implements Mapper {
+ /**
+ * The database service instance
+ */
+ private final MySQLDatabaseService database;
+
+ /**
+ * Creates a new instance
+ *
+ * @param database
+ * the database service
+ */
+ public CachedMapper(MySQLDatabaseService database) {
+ this.database = database;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public final T map(ResultSet rs) throws SQLException {
+ final I id = createID(rs);
+
+ if (database.hasCachedObject(id))
+ return (T) database.getCachedObject(id);
+
+ final T object = map(id, rs);
+ if (object != null)
+ database.updateCache(id, object);
+ return object;
+ }
+
+ /**
+ * Creates an ID for an object
+ *
+ * @param rs
+ * the jdbc result set
+ * @return the id
+ * @throws SQLException
+ */
+ protected abstract I createID(ResultSet rs) throws SQLException;
+
+ /**
+ * Maps an uncached object. Once mapping is complete, it will be added
+ * to the cache.
+ *
+ * @param id
+ * the object id
+ * @param rs
+ * the jdbc result set
+ * @return the created object
+ * @throws SQLException
+ */
+ protected abstract T map(I id, ResultSet rs) throws SQLException;
+ }
}
diff --git a/src/main/java/com/l2jserver/service/logging/Log4JLoggingService.java b/src/main/java/com/l2jserver/service/logging/Log4JLoggingService.java
index 5fb94f8de..63fe6af1f 100644
--- a/src/main/java/com/l2jserver/service/logging/Log4JLoggingService.java
+++ b/src/main/java/com/l2jserver/service/logging/Log4JLoggingService.java
@@ -19,7 +19,7 @@ package com.l2jserver.service.logging;
import org.apache.log4j.BasicConfigurator;
import com.l2jserver.service.AbstractService;
-import com.l2jserver.service.ServiceStopException;
+import com.l2jserver.service.ServiceStartException;
/**
* Logging service implementation for Log4J
@@ -29,7 +29,7 @@ import com.l2jserver.service.ServiceStopException;
public class Log4JLoggingService extends AbstractService implements
LoggingService {
@Override
- public void stop() throws ServiceStopException {
+ public void start() throws ServiceStartException {
BasicConfigurator.configure();
}
}
diff --git a/src/main/java/com/l2jserver/service/network/NettyNetworkService.java b/src/main/java/com/l2jserver/service/network/NettyNetworkService.java
index a0adaf029..ee6252aa7 100644
--- a/src/main/java/com/l2jserver/service/network/NettyNetworkService.java
+++ b/src/main/java/com/l2jserver/service/network/NettyNetworkService.java
@@ -16,9 +16,12 @@
*/
package com.l2jserver.service.network;
+import java.util.Set;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ServerChannel;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.logging.InternalLoggerFactory;
@@ -26,9 +29,12 @@ import org.jboss.netty.logging.Slf4JLoggerFactory;
import com.google.inject.Inject;
import com.google.inject.Injector;
+import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.Lineage2PipelineFactory;
+import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.configuration.ConfigurationService;
+import com.l2jserver.util.factory.CollectionFactory;
/**
* Netty network service implementation
@@ -37,10 +43,28 @@ import com.l2jserver.service.configuration.ConfigurationService;
*/
public class NettyNetworkService extends AbstractService implements
NetworkService {
+ /**
+ * The network configuration object
+ */
private final NetworkConfiguration config;
+ /**
+ * The Google Guice {@link Injector}
+ */
private final Injector injector;
+
+ /**
+ * The server bootstrap
+ */
private ServerBootstrap server;
+ /**
+ * The server channel
+ */
private ServerChannel channel;
+ /**
+ * The client list. This list all active clients in the server
+ */
+ private Set clients = CollectionFactory
+ .newSet(Lineage2Connection.class);
@Inject
public NettyNetworkService(ConfigurationService configService,
@@ -55,10 +79,42 @@ public class NettyNetworkService extends AbstractService implements
server = new ServerBootstrap(new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
- server.setPipelineFactory(new Lineage2PipelineFactory(injector));
+ server.setPipelineFactory(new Lineage2PipelineFactory(injector, this));
channel = (ServerChannel) server.bind(config.getListenAddress());
}
+ @Override
+ public void register(final Lineage2Connection client) {
+ clients.add(client);
+ client.getChannel().getCloseFuture()
+ .addListener(new ChannelFutureListener() {
+ @Override
+ public void operationComplete(ChannelFuture future)
+ throws Exception {
+ unregister(client);
+ }
+ });
+ }
+
+ @Override
+ public void unregister(Lineage2Connection client) {
+ clients.remove(client);
+ }
+
+ @Override
+ public Lineage2Connection discover(CharacterID character) {
+ for (final Lineage2Connection client : clients) {
+ if (character.equals(client.getCharacterID()))
+ return client;
+ }
+ return null;
+ }
+
+ @Override
+ public void cleanup() {
+ // TODO
+ }
+
@Override
public void stop() {
try {
diff --git a/src/main/java/com/l2jserver/service/network/NetworkService.java b/src/main/java/com/l2jserver/service/network/NetworkService.java
index 3c3598889..a891f23e8 100644
--- a/src/main/java/com/l2jserver/service/network/NetworkService.java
+++ b/src/main/java/com/l2jserver/service/network/NetworkService.java
@@ -16,6 +16,8 @@
*/
package com.l2jserver.service.network;
+import com.l2jserver.game.net.Lineage2Connection;
+import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.service.Service;
/**
@@ -25,4 +27,33 @@ import com.l2jserver.service.Service;
* @author Rogiel
*/
public interface NetworkService extends Service {
+ /**
+ * Registers a new client
+ *
+ * @param client
+ * the client
+ */
+ void register(Lineage2Connection client);
+
+ /**
+ * Unregisters a client
+ *
+ * @param client
+ * the client
+ */
+ void unregister(Lineage2Connection client);
+
+ /**
+ * Discover the client using character
+ *
+ * @param character
+ * the character
+ * @return the found connection
+ */
+ Lineage2Connection discover(CharacterID character);
+
+ /**
+ * Searches for idle connection and removes them
+ */
+ void cleanup();
}
diff --git a/src/main/java/com/l2jserver/util/BlowFishKeygen.java b/src/main/java/com/l2jserver/util/BlowFishKeygen.java
deleted file mode 100644
index 74baf0318..000000000
--- a/src/main/java/com/l2jserver/util/BlowFishKeygen.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * This program is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see .
- */
-/*
- * This file is part of l2jserver .
- *
- * l2jserver is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * l2jserver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with l2jserver. If not, see .
- */
-package com.l2jserver.util;
-
-import java.util.Random;
-
-/**
- * Blowfish keygen for GameServer client connections
- *
- * @author KenM
- */
-public class BlowFishKeygen {
- private static final int CRYPT_KEYS_SIZE = 20;
- private static final byte[][] CRYPT_KEYS = new byte[CRYPT_KEYS_SIZE][16];
-
- private static final Random random = new Random();
-
- static {
- // init the GS encryption keys on class load
-
- for (int i = 0; i < CRYPT_KEYS_SIZE; i++) {
- // randomize the 8 first bytes
- for (int j = 0; j < CRYPT_KEYS[i].length; j++) {
- CRYPT_KEYS[i][j] = (byte) random.nextInt(255);
- }
-
- // the last 8 bytes are static
- CRYPT_KEYS[i][8] = (byte) 0xc8;
- CRYPT_KEYS[i][9] = (byte) 0x27;
- CRYPT_KEYS[i][10] = (byte) 0x93;
- CRYPT_KEYS[i][11] = (byte) 0x01;
- CRYPT_KEYS[i][12] = (byte) 0xa1;
- CRYPT_KEYS[i][13] = (byte) 0x6c;
- CRYPT_KEYS[i][14] = (byte) 0x31;
- CRYPT_KEYS[i][15] = (byte) 0x97;
- }
- }
-
- // block instantiation
- private BlowFishKeygen() {
-
- }
-
- /**
- * Returns a key from this keygen pool, the logical ownership is retained by
- * this keygen.
- * Thus when getting a key with interests other then read-only a copy must
- * be performed.
- *
- * @return A key from this keygen pool.
- */
- public static byte[] getRandomKey() {
- return CRYPT_KEYS[random.nextInt(CRYPT_KEYS_SIZE)];
- }
-}
diff --git a/src/main/java/com/l2jserver/util/ClassUtils.java b/src/main/java/com/l2jserver/util/ClassUtils.java
index 25f882bb7..b79dfe1cc 100644
--- a/src/main/java/com/l2jserver/util/ClassUtils.java
+++ b/src/main/java/com/l2jserver/util/ClassUtils.java
@@ -13,23 +13,6 @@
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see .
- */
-
-/*
- * This file is part of l2jserver .
- *
- * l2jserver is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * l2jserver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with l2jserver. If not, see .
*/
package com.l2jserver.util;
diff --git a/src/main/java/com/l2jserver/util/dimensional/Point.java b/src/main/java/com/l2jserver/util/dimensional/Point.java
index 73071b126..3c10058ba 100644
--- a/src/main/java/com/l2jserver/util/dimensional/Point.java
+++ b/src/main/java/com/l2jserver/util/dimensional/Point.java
@@ -16,8 +16,6 @@
*/
package com.l2jserver.util.dimensional;
-import org.apache.commons.math.geometry.Rotation;
-
/**
* An point is composed of an Coordinate and an angle. The angle represents the
* facing angle of the point, that is, the direction the point is "looking".
@@ -30,9 +28,9 @@ public class Point {
*/
protected final Coordinate coordinate;
/**
- * Te point rotation
+ * The point angle
*/
- protected final Rotation rotation;
+ protected final double angle;
/**
* Creates a new point
@@ -44,7 +42,7 @@ public class Point {
*/
public Point(Coordinate coordinate, double angle) {
this.coordinate = coordinate;
- this.rotation = new Rotation(coordinate.vector, angle);
+ this.angle = angle;
}
/**
@@ -93,21 +91,9 @@ public class Point {
/**
* @return the angle
- * @see org.apache.commons.math.geometry.Rotation#getAngle()
*/
public double getAngle() {
- return rotation.getAngle();
- }
-
- /**
- * @param other
- * the other point
- * @return the angle difference between the two points
- * @see org.apache.commons.math.geometry.Rotation#distance(Rotation,
- * Rotation)
- */
- public double getAngleDifference(Point other) {
- return Rotation.distance(this.rotation, other.rotation);
+ return angle;
}
/**
@@ -117,13 +103,6 @@ public class Point {
return coordinate;
}
- /**
- * @return the rotation
- */
- public Rotation getRotation() {
- return rotation;
- }
-
/**
* Creates a new instance from the 3 points and an angle
*
diff --git a/src/test/java/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAOTest.java b/src/test/java/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAOTest.java
new file mode 100644
index 000000000..33d49e3db
--- /dev/null
+++ b/src/test/java/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAOTest.java
@@ -0,0 +1,56 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * l2jserver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with l2jserver. If not, see .
+ */
+package com.l2jserver.db.dao.mysql5;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.l2jserver.GameServerModule;
+import com.l2jserver.db.dao.CharacterDAO;
+import com.l2jserver.model.id.object.factory.CharacterIDFactory;
+import com.l2jserver.model.world.L2Character;
+import com.l2jserver.service.ServiceStartException;
+import com.l2jserver.service.cache.CacheService;
+import com.l2jserver.service.database.DatabaseService;
+import com.l2jserver.service.game.scripting.ScriptingService;
+import com.l2jserver.service.game.template.TemplateService;
+import com.l2jserver.service.logging.LoggingService;
+
+public class MySQL5CharacterDAOTest {
+ private final Injector injector = Guice
+ .createInjector(new GameServerModule());
+
+ @Test
+ public void testCachedLoad() throws ServiceStartException {
+ injector.getInstance(LoggingService.class).start();
+ injector.getInstance(CacheService.class).start();
+ injector.getInstance(DatabaseService.class).start();
+ injector.getInstance(ScriptingService.class).start();
+ injector.getInstance(TemplateService.class).start();
+
+ final CharacterDAO dao = injector.getInstance(CharacterDAO.class);
+ final L2Character char1 = dao.load(injector.getInstance(
+ CharacterIDFactory.class).createID(268437456));
+ final L2Character char2 = dao.load(injector.getInstance(
+ CharacterIDFactory.class).createID(268437456));
+
+ Assert.assertSame(char1, char2);
+ }
+}
diff --git a/src/test/java/com/l2jserver/service/cache/SimpleCacheServiceTest.java b/src/test/java/com/l2jserver/service/cache/SimpleCacheServiceTest.java
index 7e3e194ae..73d69f915 100644
--- a/src/test/java/com/l2jserver/service/cache/SimpleCacheServiceTest.java
+++ b/src/test/java/com/l2jserver/service/cache/SimpleCacheServiceTest.java
@@ -23,7 +23,7 @@ import junit.framework.Assert;
import org.junit.Test;
public class SimpleCacheServiceTest {
- private final SimpleCacheService cacheService = new SimpleCacheService();
+ private final EhCacheService cacheService = new EhCacheService();
@Test
public void testNoArgs() {