mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-06 07:32:46 +00:00
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DisabledPlugin {
|
||||
}
|
||||
@@ -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.<br>
|
||||
* Plugin should be public, not abstract, not interface, must have default
|
||||
* constructor annotated with @Inject.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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<Class<? extends Template<?>>> getSuitableClasses(
|
||||
Class<?>[] classes) {
|
||||
final Set<Class<? extends Template<?>>> 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;
|
||||
}
|
||||
}
|
||||
4
.settings/org.eclipse.jdt.ui.prefs
Normal file
4
.settings/org.eclipse.jdt.ui.prefs
Normal file
File diff suppressed because one or more lines are too long
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
7
pom.xml
7
pom.xml
@@ -92,6 +92,13 @@
|
||||
<type>jar</type>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache-core</artifactId>
|
||||
<version>2.4.2</version>
|
||||
<type>jar</type>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<issueManagement>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<L2Character>
|
||||
/**
|
||||
* The {@link Mapper} instance
|
||||
*/
|
||||
private final CharacterMapper mapper = new CharacterMapper();
|
||||
private final CharacterMapper mapper = new CharacterMapper(database);
|
||||
|
||||
/**
|
||||
* Character mapper class
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
private final class CharacterMapper implements Mapper<L2Character> {
|
||||
private final class CharacterMapper extends
|
||||
CachedMapper<L2Character, CharacterID> {
|
||||
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<L2Character>
|
||||
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<L2Character>
|
||||
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<L2Character>
|
||||
return database.query(new SelectListQuery<CharacterID>() {
|
||||
@Override
|
||||
protected String query() {
|
||||
return "SELECT * FROM `" + TABLE + "` WHERE `" + CHAR_ID
|
||||
+ "` = ?";
|
||||
return "SELECT * FROM `" + TABLE + "`";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
158
src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5ClanDAO.java
Normal file
158
src/dao/mysql5/com/l2jserver/db/dao/mysql5/MySQL5ClanDAO.java
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class MySQL5ClanDAO extends AbstractMySQL5DAO<Clan> 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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
private final class ClanMapper extends CachedMapper<Clan, ClanID> {
|
||||
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<Clan>() {
|
||||
@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<Clan> mapper() {
|
||||
return mapper;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClanID> listIDs() {
|
||||
return database.query(new SelectListQuery<ClanID>() {
|
||||
@Override
|
||||
protected String query() {
|
||||
return "SELECT * FROM `" + TABLE + "`";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mapper<ClanID> mapper() {
|
||||
return new Mapper<ClanID>() {
|
||||
@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>(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;
|
||||
}
|
||||
}
|
||||
@@ -90,13 +90,20 @@ public class MySQL5ItemDAO extends AbstractMySQL5DAO<Item> implements ItemDAO {
|
||||
private final class ItemMapper implements Mapper<Item> {
|
||||
@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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,12 +39,24 @@ import com.l2jserver.util.BufferUtils;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,9 @@ import com.l2jserver.game.net.packet.server.InventoryPacket;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class EnterWorld extends AbstractClientPacket {
|
||||
/**
|
||||
* The packet OPCODE
|
||||
*/
|
||||
public static final int OPCODE = 0x11;
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,6 +30,9 @@ import com.l2jserver.game.net.packet.AbstractClientPacket;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class LogoutPacket extends AbstractClientPacket {
|
||||
/**
|
||||
* The packet OPCODE
|
||||
*/
|
||||
public static final int OPCODE = 0x00;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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");
|
||||
|
||||
|
||||
@@ -37,8 +37,14 @@ import com.l2jserver.model.world.character.CharacterClass;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -34,9 +34,18 @@ import com.l2jserver.model.world.L2Character;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class RequestKeyMapping extends AbstractClientPacket {
|
||||
/**
|
||||
* The packet OPCODE1
|
||||
*/
|
||||
public static final int OPCODE1 = 0xd0;
|
||||
/**
|
||||
* The packet OPCODE2
|
||||
*/
|
||||
public static final int OPCODE2 = 0x21;
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class RequestManorList extends AbstractClientPacket {
|
||||
/**
|
||||
* The packet OPCODE1
|
||||
*/
|
||||
public static final int OPCODE1 = 0xd0;
|
||||
/**
|
||||
* The packet OPCODE2
|
||||
*/
|
||||
public static final int OPCODE2 = 0x01;
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,14 @@ import com.l2jserver.game.net.packet.AbstractServerPacket;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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() {
|
||||
|
||||
@@ -30,11 +30,28 @@ import com.l2jserver.util.BufferUtils;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -32,11 +32,23 @@ import com.l2jserver.util.BufferUtils;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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,
|
||||
|
||||
@@ -28,8 +28,14 @@ import com.l2jserver.model.template.CharacterTemplate;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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<Clan> {
|
||||
private final ClanDAO clanDao;
|
||||
|
||||
@Inject
|
||||
protected ClanID(int id, ClanDAO clanDao) {
|
||||
protected ClanID(@Assisted int id, ClanDAO clanDao) {
|
||||
super(id);
|
||||
this.clanDao = clanDao;
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.blowfish;
|
||||
|
||||
import com.l2jserver.service.Service;
|
||||
|
||||
public interface BlowfishKeygenService extends Service {
|
||||
byte[] generate();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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 <tt>instance</tt> with the cache
|
||||
* Decorates the <tt>instance</tt> with the cache. Note that
|
||||
* <tt>interfaceType</tt> must be an interface!
|
||||
*
|
||||
* @param <T>
|
||||
* the <tt>instance</tt> type
|
||||
* @param interfaceType
|
||||
* the interface type
|
||||
* @param instance
|
||||
* the instance
|
||||
* the instance implementing the interface
|
||||
* @return the cache-decorated object
|
||||
*/
|
||||
<T extends Cacheable> T decorate(Class<T> 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);
|
||||
}
|
||||
|
||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class SimpleCacheService extends AbstractService implements CacheService {
|
||||
private final Map<MethodInvocation, Object> cache = CollectionFactory
|
||||
.newWeakMap(MethodInvocation.class, Object.class);
|
||||
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 extends Cacheable> T decorate(final Class<T> 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;
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,5 +25,40 @@ import com.l2jserver.service.Service;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <T>
|
||||
* the object type
|
||||
* @param <I>
|
||||
* the id type
|
||||
*/
|
||||
public abstract static class CachedMapper<T extends WorldObject, I extends ObjectID<T>>
|
||||
implements Mapper<T> {
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Lineage2Connection> 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 {
|
||||
|
||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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 <tt>character</tt>
|
||||
*
|
||||
* @param character
|
||||
* the character
|
||||
* @return the found connection
|
||||
*/
|
||||
Lineage2Connection discover(CharacterID character);
|
||||
|
||||
/**
|
||||
* Searches for idle connection and removes them
|
||||
*/
|
||||
void cleanup();
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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.<BR>
|
||||
* Thus when getting a key with interests other then read-only a copy must
|
||||
* be performed.<BR>
|
||||
*
|
||||
* @return A key from this keygen pool.
|
||||
*/
|
||||
public static byte[] getRandomKey() {
|
||||
return CRYPT_KEYS[random.nextInt(CRYPT_KEYS_SIZE)];
|
||||
}
|
||||
}
|
||||
@@ -13,23 +13,6 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.util;
|
||||
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user