From 4952a6a47bb1e2ac6461c54d8506127179e339ce Mon Sep 17 00:00:00 2001 From: Rogiel Date: Mon, 16 May 2011 13:41:55 -0300 Subject: [PATCH] Service improvements Signed-off-by: Rogiel --- data/plugin/plugin/DisabledPlugin.java | 19 --- data/plugin/plugin/PluginLoader.java | 76 --------- .settings/org.eclipse.jdt.ui.prefs | 4 + .../item/weapon/LongSwordTemplate.java | 2 +- .../item/weapon/ShortSwordTemplate.java | 2 +- pom.xml | 7 + .../com/l2jserver/db/dao/DAOModuleMySQL5.java | 2 + .../db/dao/mysql5/MySQL5CharacterDAO.java | 77 ++++++++- .../db/dao/mysql5/MySQL5ClanDAO.java | 158 ++++++++++++++++++ .../db/dao/mysql5/MySQL5ItemDAO.java | 9 +- .../game/net/Lineage2Connection.java | 22 ++- .../game/net/Lineage2CryptographyKey.java | 14 -- .../game/net/Lineage2PipelineFactory.java | 11 +- .../game/net/codec/Lineage2Decrypter.java | 4 +- .../net/handler/Lineage2PacketHandler.java | 17 ++ .../net/packet/client/AuthLoginPacket.java | 12 ++ .../packet/client/CharacterCreatePacket.java | 82 +++++++-- .../game/net/packet/client/EnterWorld.java | 3 + .../game/net/packet/client/LogoutPacket.java | 3 + .../packet/client/ProtocolVersionPacket.java | 25 ++- .../RequestCharacterTemplatesPacket.java | 9 + .../net/packet/client/RequestGotoLobby.java | 9 + .../net/packet/client/RequestKeyMapping.java | 9 +- .../net/packet/client/RequestManorList.java | 9 +- .../server/CharacterCreateFailPacket.java | 11 +- .../server/CharacterCreateOkPacket.java | 6 + .../server/CharacterEnterWorldPacket.java | 17 ++ .../server/CharacterSelectionListPacket.java | 12 ++ .../server/CharacterTemplatePacket.java | 6 + .../net/packet/server/InventoryPacket.java | 8 +- .../game/net/packet/server/KeyPacket.java | 2 +- .../net/packet/server/ManorListPacket.java | 5 +- .../packet/server/UserInformationPacket.java | 5 +- .../model/id/factory/IDFactoryModule.java | 8 +- .../com/l2jserver/model/id/object/ClanID.java | 3 +- .../com/l2jserver/service/ServiceModule.java | 8 + .../blowfish/BlowfishKeygenService.java | 23 +++ .../PseudoRandomBlowfishKeygenService.java | 58 +++++++ .../blowfish/SecureBlowfishKeygenService.java | 59 +++++++ .../l2jserver/service/cache/CacheService.java | 45 ++++- ...eCacheService.java => EhCacheService.java} | 71 +++++++- .../service/database/DB4ODatabaseService.java | 23 +++ .../service/database/DatabaseService.java | 35 ++++ .../database/MySQLDatabaseService.java | 125 +++++++++++++- .../service/logging/Log4JLoggingService.java | 4 +- .../service/network/NettyNetworkService.java | 58 ++++++- .../service/network/NetworkService.java | 31 ++++ .../com/l2jserver/util/BlowFishKeygen.java | 83 --------- .../java/com/l2jserver/util/ClassUtils.java | 17 -- .../com/l2jserver/util/dimensional/Point.java | 29 +--- .../db/dao/mysql5/MySQL5CharacterDAOTest.java | 56 +++++++ .../service/cache/SimpleCacheServiceTest.java | 2 +- 52 files changed, 1099 insertions(+), 296 deletions(-) delete mode 100644 data/plugin/plugin/DisabledPlugin.java delete mode 100644 data/plugin/plugin/PluginLoader.java create mode 100644 .settings/org.eclipse.jdt.ui.prefs create mode 100644 src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5ClanDAO.java create mode 100644 src/main/java/com/l2jserver/service/blowfish/BlowfishKeygenService.java create mode 100644 src/main/java/com/l2jserver/service/blowfish/PseudoRandomBlowfishKeygenService.java create mode 100644 src/main/java/com/l2jserver/service/blowfish/SecureBlowfishKeygenService.java rename src/main/java/com/l2jserver/service/cache/{SimpleCacheService.java => EhCacheService.java} (62%) delete mode 100644 src/main/java/com/l2jserver/util/BlowFishKeygen.java create mode 100644 src/test/java/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAOTest.java 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> 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> 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>) 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= 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() {