mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-09 08:52:51 +00:00
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user