diff --git a/pom.xml b/pom.xml
index facbf7503..762675f01 100644
--- a/pom.xml
+++ b/pom.xml
@@ -99,6 +99,13 @@
jar
runtime
+
+ com.google.inject.extensions
+ guice-multibindings
+ 3.0
+ jar
+ runtime
+
diff --git a/src/main/java/com/l2jserver/GameServerModule.java b/src/main/java/com/l2jserver/GameServerModule.java
index 6139edec3..bd16d4ac8 100644
--- a/src/main/java/com/l2jserver/GameServerModule.java
+++ b/src/main/java/com/l2jserver/GameServerModule.java
@@ -20,7 +20,6 @@ import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.l2jserver.db.dao.DAOModuleMySQL5;
import com.l2jserver.model.id.factory.IDFactoryModule;
-import com.l2jserver.routines.GameServerInitializationRoutine;
import com.l2jserver.service.ServiceModule;
/**
@@ -34,8 +33,5 @@ public class GameServerModule extends AbstractModule {
install(new ServiceModule());
install(new IDFactoryModule());
install(new DAOModuleMySQL5());
-
- // routines
- bind(GameServerInitializationRoutine.class);
}
}
diff --git a/src/main/java/com/l2jserver/L2JGameServerMain.java b/src/main/java/com/l2jserver/L2JGameServerMain.java
index f2f86803e..c851b6c73 100644
--- a/src/main/java/com/l2jserver/L2JGameServerMain.java
+++ b/src/main/java/com/l2jserver/L2JGameServerMain.java
@@ -16,7 +16,14 @@
*/
package com.l2jserver;
-import com.l2jserver.routines.GameServerInitializationRoutine;
+import com.l2jserver.service.ServiceManager;
+import com.l2jserver.service.blowfish.BlowfishKeygenService;
+import com.l2jserver.service.cache.CacheService;
+import com.l2jserver.service.configuration.ConfigurationService;
+import com.l2jserver.service.database.DatabaseService;
+import com.l2jserver.service.game.scripting.ScriptingService;
+import com.l2jserver.service.game.template.TemplateService;
+import com.l2jserver.service.network.NetworkService;
public class L2JGameServerMain {
/**
@@ -26,8 +33,18 @@ public class L2JGameServerMain {
public static void main(String[] args) throws InterruptedException {
final L2JGameServer server = new L2JGameServer();
try {
- server.getInjector()
- .getInstance(GameServerInitializationRoutine.class).call();
+ final ServiceManager serviceManager = server.getInjector()
+ .getInstance(ServiceManager.class);
+
+ serviceManager.start(CacheService.class);
+ serviceManager.start(ConfigurationService.class);
+ serviceManager.start(DatabaseService.class);
+
+ serviceManager.start(ScriptingService.class);
+ serviceManager.start(TemplateService.class);
+
+ serviceManager.start(BlowfishKeygenService.class);
+ serviceManager.start(NetworkService.class);
} catch (Exception e) {
System.out.println("GameServer could not be started!");
e.printStackTrace();
diff --git a/src/main/java/com/l2jserver/game/ProtocolVersion.java b/src/main/java/com/l2jserver/game/ProtocolVersion.java
index f879b2e31..34ffb245b 100644
--- a/src/main/java/com/l2jserver/game/ProtocolVersion.java
+++ b/src/main/java/com/l2jserver/game/ProtocolVersion.java
@@ -31,9 +31,9 @@ public enum ProtocolVersion {
*/
FREYA(216, RELEASE),
/**
- * High5(217)
+ * High5(268)
*/
- HIGH5(217, FREYA);
+ HIGH5(268, FREYA);
public final ProtocolVersion parent;
public final int version;
diff --git a/src/main/java/com/l2jserver/game/net/packet/client/EnterWorld.java b/src/main/java/com/l2jserver/game/net/packet/client/EnterWorld.java
index cf149c624..b0813b3a1 100644
--- a/src/main/java/com/l2jserver/game/net/packet/client/EnterWorld.java
+++ b/src/main/java/com/l2jserver/game/net/packet/client/EnterWorld.java
@@ -22,6 +22,11 @@ import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.GameGuardQueryPacket;
import com.l2jserver.game.net.packet.server.UserInformationPacket;
+import com.l2jserver.model.id.object.CharacterID;
+import com.l2jserver.service.game.chat.ChatService;
+import com.l2jserver.service.game.chat.channel.ChatChannel;
+import com.l2jserver.service.game.chat.channel.ChatChannelListener;
+import com.l2jserver.service.game.chat.channel.PublicChatChannel;
/**
* The client is requesting a logout. Currently, when this packet is received
@@ -35,6 +40,21 @@ public class EnterWorld extends AbstractClientPacket {
*/
public static final int OPCODE = 0x11;
+ /**
+ * The chat service
+ */
+ private final ChatService chatService;
+
+ /**
+ * Creates a new instance
+ *
+ * @param chatService
+ * the chat service
+ */
+ public EnterWorld(ChatService chatService) {
+ this.chatService = chatService;
+ }
+
@Override
public void read(Lineage2Connection conn, ChannelBuffer buffer) {
buffer.readBytes(new byte[32]); // Unknown Byte Array
@@ -52,8 +72,20 @@ public class EnterWorld extends AbstractClientPacket {
@Override
public void process(final Lineage2Connection conn) {
+ if (conn.getCharacter().getClanID() != null) {
+ final PublicChatChannel clanChannel = chatService.getChannel(conn
+ .getCharacter().getClanID());
+ clanChannel.addChatChannelListener(new ChatChannelListener() {
+ @Override
+ public void onMessage(ChatChannel channel, CharacterID source,
+ String message) {
+ // TODO write message
+ }
+ });
+ }
+
conn.write(new UserInformationPacket(conn.getCharacter()));
conn.write(new GameGuardQueryPacket());
- //conn.write(new InventoryPacket(conn.getCharacter().getInventory()));
+ // conn.write(new InventoryPacket(conn.getCharacter().getInventory()));
}
}
diff --git a/src/main/java/com/l2jserver/routines/GameServerInitializationRoutine.java b/src/main/java/com/l2jserver/routines/GameServerInitializationRoutine.java
deleted file mode 100644
index 92db24eb6..000000000
--- a/src/main/java/com/l2jserver/routines/GameServerInitializationRoutine.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * This file is part of l2jserver .
- *
- * l2jserver is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * l2jserver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with l2jserver. If not, see .
- */
-package com.l2jserver.routines;
-
-import com.google.inject.Inject;
-import com.l2jserver.service.ServiceManager;
-import com.l2jserver.service.blowfish.BlowfishKeygenService;
-import com.l2jserver.service.cache.CacheService;
-import com.l2jserver.service.configuration.ConfigurationService;
-import com.l2jserver.service.database.DatabaseService;
-import com.l2jserver.service.game.scripting.ScriptingService;
-import com.l2jserver.service.game.template.TemplateService;
-import com.l2jserver.service.network.NetworkService;
-
-/**
- * Routine used to initialize the server. Starts all services.
- *
- * @author Rogiel
- */
-public class GameServerInitializationRoutine implements Routine {
- /**
- * The service manager
- */
- private final ServiceManager serviceManager;
-
- /**
- * Creates a new instance
- *
- * @param serviceManager
- * the service manager
- */
- @Inject
- public GameServerInitializationRoutine(ServiceManager serviceManager) {
- this.serviceManager = serviceManager;
- }
-
- @Override
- public Boolean call() throws Exception {
- serviceManager.start(CacheService.class);
- serviceManager.start(ConfigurationService.class);
- serviceManager.start(DatabaseService.class);
-
- serviceManager.start(ScriptingService.class);
- serviceManager.start(TemplateService.class);
-
- serviceManager.start(BlowfishKeygenService.class);
- serviceManager.start(NetworkService.class);
- return true;
- }
-}
diff --git a/src/main/java/com/l2jserver/routines/Routine.java b/src/main/java/com/l2jserver/routines/Routine.java
deleted file mode 100644
index 0c2b0fa9d..000000000
--- a/src/main/java/com/l2jserver/routines/Routine.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This file is part of l2jserver .
- *
- * l2jserver is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * l2jserver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with l2jserver. If not, see .
- */
-package com.l2jserver.routines;
-
-import java.util.concurrent.Callable;
-
-/**
- * An routine is a set of operations that can be performed on another thread.
- *
- * @author Rogiel
- *
- * @param
- * the routine return type
- */
-public interface Routine extends Callable {
-}
diff --git a/src/main/java/com/l2jserver/service/AbstractService.java b/src/main/java/com/l2jserver/service/AbstractService.java
index 268ff4d72..348751972 100644
--- a/src/main/java/com/l2jserver/service/AbstractService.java
+++ b/src/main/java/com/l2jserver/service/AbstractService.java
@@ -16,18 +16,49 @@
*/
package com.l2jserver.service;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
/**
* An abstract service implementing basic life-cycle methods.
*
* @author Rogiel
*/
-public class AbstractService implements Service {
+public abstract class AbstractService implements Service {
+ /**
+ * Running state of a service
+ */
+ protected boolean running = false;
+
@Override
- public void start() throws ServiceStartException {
+ public final void start() throws ServiceStartException {
+ if (running)
+ throw new ServiceStartException("Service is already started");
+ try {
+ this.doStart();
+ this.running = true;
+ } catch (ServiceStartException e) {
+ this.running = false;
+ }
+ }
+
+ protected void doStart() throws ServiceStartException {
}
@Override
- public void stop() throws ServiceStopException {
+ public final void stop() throws ServiceStopException {
+ if (!running)
+ throw new ServiceStopException("Service is not started");
+ try {
+ this.doStop();
+ } finally {
+ this.running = false;
+ }
+ }
+
+ protected void doStop() throws ServiceStopException {
}
@Override
@@ -35,4 +66,28 @@ public class AbstractService implements Service {
this.stop();
this.start();
}
+
+ @Override
+ public boolean isStarted() {
+ return running;
+ }
+
+ @Override
+ public boolean isStopped() {
+ return !running;
+ }
+
+ @Override
+ public Class extends Service>[] getDependencies() {
+ final Depends deps = this.getClass().getAnnotation(Depends.class);
+ if (deps == null)
+ return null;
+ return deps.value();
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.TYPE)
+ public @interface Depends {
+ Class extends Service>[] value();
+ }
}
diff --git a/src/main/java/com/l2jserver/service/Service.java b/src/main/java/com/l2jserver/service/Service.java
index 414f01625..f76047b53 100644
--- a/src/main/java/com/l2jserver/service/Service.java
+++ b/src/main/java/com/l2jserver/service/Service.java
@@ -46,4 +46,19 @@ public interface Service {
* if an error occurred
*/
void restart() throws ServiceException;
+
+ /**
+ * @return true if service is running
+ */
+ boolean isStarted();
+
+ /**
+ * @return false if service is not running
+ */
+ boolean isStopped();
+
+ /**
+ * @return the other services that the service depends on
+ */
+ Class extends Service>[] getDependencies();
}
diff --git a/src/main/java/com/l2jserver/service/ServiceManager.java b/src/main/java/com/l2jserver/service/ServiceManager.java
index 670efb2c3..a39950fe5 100644
--- a/src/main/java/com/l2jserver/service/ServiceManager.java
+++ b/src/main/java/com/l2jserver/service/ServiceManager.java
@@ -16,12 +16,16 @@
*/
package com.l2jserver.service;
+import java.util.Set;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.l2jserver.service.logging.LoggingService;
+import com.l2jserver.util.ClassUtils;
+import com.l2jserver.util.factory.CollectionFactory;
/**
* The {@link ServiceManager} is responsible for starting and stopping services
@@ -38,11 +42,14 @@ public class ServiceManager {
*/
private final Injector injector;
+ private final Set knownServices = CollectionFactory.newSet(null);
+
@Inject
public ServiceManager(Injector injector) {
this.injector = injector;
final LoggingService service = injector
.getInstance(LoggingService.class);
+ knownServices.add(service);
try {
service.start();
} catch (ServiceStartException e) {
@@ -56,7 +63,11 @@ public class ServiceManager {
final T service = injector.getInstance(serviceClass);
if (service == null)
return null;
+ if (service.isStarted())
+ return service;
+ knownServices.add(service);
try {
+ startDependencies(service.getDependencies());
logger.info("{}: Starting service...",
serviceClass.getCanonicalName());
service.start();
@@ -64,19 +75,34 @@ public class ServiceManager {
return service;
} catch (ServiceStartException e) {
logger.error("{}: Error starting service: {}",
- serviceClass.getCanonicalName(), e.getCause());
+ serviceClass.getCanonicalName(), e);
throw e;
}
}
+ private void startDependencies(Class extends Service>[] dependencies)
+ throws ServiceStartException {
+ if (dependencies == null)
+ return;
+ if (dependencies.length == 0)
+ return;
+ for (final Class extends Service> serviceClass : dependencies) {
+ this.start(serviceClass);
+ }
+ }
+
public void stop(Class extends Service> serviceClass)
throws ServiceStopException {
final Service service = injector.getInstance(serviceClass);
if (service == null)
return;
+ if (service.isStopped())
+ return;
+ knownServices.add(service);
try {
logger.info("{0}: Stopping service...",
serviceClass.getCanonicalName());
+ stopDependencies(service);
service.stop();
logger.info("{0}: Service stopped!",
serviceClass.getCanonicalName());
@@ -87,16 +113,46 @@ public class ServiceManager {
}
}
+ private void stopDependencies(Service service) throws ServiceStopException {
+ final Set> dependencies = createStopDependencies(
+ null, service);
+ for (final Class extends Service> dependency : dependencies) {
+ this.stop(dependency);
+ }
+ }
+
+ private Set> createStopDependencies(
+ Set> depends, Service serviceClass) {
+ if (depends == null)
+ depends = CollectionFactory.newSet(null);
+ for (final Service service : knownServices) {
+ if (service.getDependencies() == null
+ || service.getDependencies().length == 0)
+ continue;
+ for (final Class extends Service> dependency : service
+ .getDependencies()) {
+ if (!ClassUtils.isSubclass(service.getClass(), dependency))
+ continue;
+ depends.add(dependency);
+ createStopDependencies(depends,
+ injector.getInstance(dependency));
+ }
+ }
+ return depends;
+ }
+
public T restart(Class serviceClass)
- throws ServiceStartException, ServiceStopException {
+ throws ServiceException {
final T service = injector.getInstance(serviceClass);
if (service == null)
return null;
+ if (service.isStopped())
+ throw new ServiceStopException("Service is already stopped");
+ knownServices.add(service);
try {
logger.info("{0}: Restaring service...",
serviceClass.getCanonicalName());
- service.stop();
- service.start();
+ service.restart();
logger.info("{0}: Service restarted!",
serviceClass.getCanonicalName());
return service;
@@ -108,6 +164,10 @@ public class ServiceManager {
logger.error("{0}: Error stopping service: {1}",
serviceClass.getCanonicalName(), e.getCause());
throw e;
+ } catch (ServiceException e) {
+ logger.error("{0}: Error restarting service: {1}",
+ serviceClass.getCanonicalName(), e.getCause());
+ throw e;
}
}
}
diff --git a/src/main/java/com/l2jserver/service/blowfish/PseudoRandomBlowfishKeygenService.java b/src/main/java/com/l2jserver/service/blowfish/PseudoRandomBlowfishKeygenService.java
index 7760ce533..e8d239dc6 100644
--- a/src/main/java/com/l2jserver/service/blowfish/PseudoRandomBlowfishKeygenService.java
+++ b/src/main/java/com/l2jserver/service/blowfish/PseudoRandomBlowfishKeygenService.java
@@ -27,7 +27,7 @@ public class PseudoRandomBlowfishKeygenService extends AbstractService
private Random random;
@Override
- public void start() throws ServiceStartException {
+ protected void doStart() throws ServiceStartException {
random = new Random();
}
@@ -52,7 +52,7 @@ public class PseudoRandomBlowfishKeygenService extends AbstractService
}
@Override
- public void stop() throws ServiceStopException {
+ protected void doStop() throws ServiceStopException {
random = null;
}
}
diff --git a/src/main/java/com/l2jserver/service/blowfish/SecureBlowfishKeygenService.java b/src/main/java/com/l2jserver/service/blowfish/SecureBlowfishKeygenService.java
index 51557bae1..ee56330a4 100644
--- a/src/main/java/com/l2jserver/service/blowfish/SecureBlowfishKeygenService.java
+++ b/src/main/java/com/l2jserver/service/blowfish/SecureBlowfishKeygenService.java
@@ -20,6 +20,7 @@ import org.apache.commons.math.random.RandomData;
import org.apache.commons.math.random.RandomDataImpl;
import com.l2jserver.service.AbstractService;
+import com.l2jserver.service.Service;
import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.ServiceStopException;
@@ -38,7 +39,7 @@ public class SecureBlowfishKeygenService extends AbstractService implements
private RandomData random;
@Override
- public void start() throws ServiceStartException {
+ protected void doStart() throws ServiceStartException {
random = new RandomDataImpl();
}
@@ -63,7 +64,7 @@ public class SecureBlowfishKeygenService extends AbstractService implements
}
@Override
- public void stop() throws ServiceStopException {
+ protected void doStop() throws ServiceStopException {
random = null;
}
}
diff --git a/src/main/java/com/l2jserver/service/cache/EhCacheService.java b/src/main/java/com/l2jserver/service/cache/EhCacheService.java
index 64fd349ca..24e9ab00f 100644
--- a/src/main/java/com/l2jserver/service/cache/EhCacheService.java
+++ b/src/main/java/com/l2jserver/service/cache/EhCacheService.java
@@ -48,7 +48,7 @@ public class EhCacheService extends AbstractService implements CacheService {
private Cache interfaceCache;
@Override
- public void start() throws ServiceStartException {
+ protected void doStart() throws ServiceStartException {
manager = new CacheManager();
interfaceCache = createCache("interface-cache");
}
@@ -111,7 +111,7 @@ public class EhCacheService extends AbstractService implements CacheService {
}
@Override
- public void stop() throws ServiceStopException {
+ protected void doStop() throws ServiceStopException {
manager.removalAll();
manager.shutdown();
interfaceCache = null;
diff --git a/src/main/java/com/l2jserver/service/configuration/ProxyConfigurationService.java b/src/main/java/com/l2jserver/service/configuration/ProxyConfigurationService.java
index fc62e0b2d..facf0a925 100644
--- a/src/main/java/com/l2jserver/service/configuration/ProxyConfigurationService.java
+++ b/src/main/java/com/l2jserver/service/configuration/ProxyConfigurationService.java
@@ -32,10 +32,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.l2jserver.service.AbstractService;
+import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.ServiceStartException;
+import com.l2jserver.service.cache.CacheService;
import com.l2jserver.service.configuration.Configuration.ConfigurationName;
import com.l2jserver.service.configuration.Configuration.ConfigurationPropertyGetter;
import com.l2jserver.service.configuration.Configuration.ConfigurationPropertySetter;
+import com.l2jserver.service.logging.LoggingService;
import com.l2jserver.util.transformer.Transformer;
import com.l2jserver.util.transformer.TransformerFactory;
@@ -45,6 +48,7 @@ import com.l2jserver.util.transformer.TransformerFactory;
*
* @author Rogiel
*/
+@Depends({ LoggingService.class, CacheService.class })
public class ProxyConfigurationService extends AbstractService implements
ConfigurationService {
/**
@@ -63,7 +67,7 @@ public class ProxyConfigurationService extends AbstractService implements
private Map, Object> cache = new WeakHashMap, Object>();
@Override
- public void start() throws ServiceStartException {
+ protected void doStart() throws ServiceStartException {
if (!directory.exists())
if (!directory.mkdirs())
throw new ServiceStartException("Failed to create directories");
diff --git a/src/main/java/com/l2jserver/service/database/MySQLDatabaseService.java b/src/main/java/com/l2jserver/service/database/MySQLDatabaseService.java
index 932be1788..98440f3e6 100644
--- a/src/main/java/com/l2jserver/service/database/MySQLDatabaseService.java
+++ b/src/main/java/com/l2jserver/service/database/MySQLDatabaseService.java
@@ -43,10 +43,13 @@ 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.AbstractService.Depends;
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.service.game.template.TemplateService;
+import com.l2jserver.service.logging.LoggingService;
import com.l2jserver.util.ArrayIterator;
import com.l2jserver.util.factory.CollectionFactory;
@@ -55,6 +58,8 @@ import com.l2jserver.util.factory.CollectionFactory;
*
* @author Rogiel
*/
+@Depends({ LoggingService.class, CacheService.class,
+ ConfigurationService.class, TemplateService.class })
public class MySQLDatabaseService extends AbstractService implements
DatabaseService {
/**
@@ -103,7 +108,7 @@ public class MySQLDatabaseService extends AbstractService implements
}
@Override
- public void start() throws ServiceStartException {
+ protected void doStart() throws ServiceStartException {
connectionPool = new GenericObjectPool(null);
connectionFactory = new DriverManagerConnectionFactory(
config.getJdbcUrl(), config.getUsername(), config.getPassword());
@@ -170,7 +175,7 @@ public class MySQLDatabaseService extends AbstractService implements
}
@Override
- public void stop() throws ServiceStopException {
+ protected void doStop() throws ServiceStopException {
if (objectCache != null)
objectCache.dispose();
objectCache = null;
diff --git a/src/main/java/com/l2jserver/service/game/PVPService.java b/src/main/java/com/l2jserver/service/game/PvPService.java
similarity index 91%
rename from src/main/java/com/l2jserver/service/game/PVPService.java
rename to src/main/java/com/l2jserver/service/game/PvPService.java
index 5dcc8e4ec..f4e539ef7 100644
--- a/src/main/java/com/l2jserver/service/game/PVPService.java
+++ b/src/main/java/com/l2jserver/service/game/PvPService.java
@@ -19,10 +19,10 @@ package com.l2jserver.service.game;
import com.l2jserver.service.Service;
/**
- * This service handles PVP battles.
+ * This service handles PvP battles.
*
* @author Rogiel
*/
-public interface PVPService extends Service {
+public interface PvPService extends Service {
}
diff --git a/src/main/java/com/l2jserver/service/game/chat/ChatService.java b/src/main/java/com/l2jserver/service/game/chat/ChatService.java
index 56f32af06..59c082be2 100644
--- a/src/main/java/com/l2jserver/service/game/chat/ChatService.java
+++ b/src/main/java/com/l2jserver/service/game/chat/ChatService.java
@@ -31,11 +31,17 @@ import com.l2jserver.service.game.chat.channel.PublicChatChannel;
*/
public interface ChatService extends Service {
/**
+ * Get the Global {@link ChatChannel}. Messages sent in this chat are
+ * broadcasted to everyone online.
+ *
* @return the global {@link ChatChannel}
*/
PublicChatChannel getGlobalChannel();
/**
+ * Get the Region {@link ChatChannel}. Messages sent in this chat are
+ * broadcasted to everyone nearby.
+ *
* @param character
* the character in the region
* @return the global {@link ChatChannel}
@@ -43,7 +49,8 @@ public interface ChatService extends Service {
PublicChatChannel getRegionChannel(L2Character character);
/**
- * Get an private {@link ChatChannel} to {@link CharacterID}
+ * Get an private {@link ChatChannel} to {@link CharacterID}. Messages sent
+ * in this channel are sent only to character.
*
* @param character
* the target character
@@ -52,6 +59,9 @@ public interface ChatService extends Service {
PrivateChatChannel getChannel(CharacterID character);
/**
+ * Get the Clan {@link ChatChannel}. Messages sent in this channel are
+ * broadcast to all clan members online.
+ *
* @param clan
* the clan
* @return the public clan {@link ChatChannel}
diff --git a/src/main/java/com/l2jserver/service/game/chat/SimpleChatService.java b/src/main/java/com/l2jserver/service/game/chat/SimpleChatService.java
index 2d8dbe15a..0d441ee9e 100644
--- a/src/main/java/com/l2jserver/service/game/chat/SimpleChatService.java
+++ b/src/main/java/com/l2jserver/service/game/chat/SimpleChatService.java
@@ -24,11 +24,15 @@ import com.l2jserver.model.id.object.ClanID;
import com.l2jserver.model.world.Clan;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.AbstractService;
+import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.ServiceStartException;
+import com.l2jserver.service.ServiceStopException;
import com.l2jserver.service.game.chat.channel.ChatChannel;
import com.l2jserver.service.game.chat.channel.ChatChannelListener;
import com.l2jserver.service.game.chat.channel.PrivateChatChannel;
import com.l2jserver.service.game.chat.channel.PublicChatChannel;
+import com.l2jserver.service.game.region.Region;
+import com.l2jserver.service.game.region.RegionService;
import com.l2jserver.util.factory.CollectionFactory;
/**
@@ -36,7 +40,10 @@ import com.l2jserver.util.factory.CollectionFactory;
*
* @author Rogiel
*/
+@Depends(RegionService.class)
public class SimpleChatService extends AbstractService implements ChatService {
+ private final RegionService regionService;
+
/**
* The global chat channel
*/
@@ -51,12 +58,27 @@ public class SimpleChatService extends AbstractService implements ChatService {
* The list of clan chat channels
*/
private Map clanChannels;
+ /**
+ * The list of regional chat channels
+ */
+ private Map regionChannels;
+
+ /**
+ * Creates a new instance
+ *
+ * @param regionService
+ * the region service
+ */
+ public SimpleChatService(RegionService regionService) {
+ this.regionService = regionService;
+ }
@Override
- public void start() throws ServiceStartException {
+ protected void doStart() throws ServiceStartException {
this.global = new GlobalChatChannelImpl();
this.privateChannels = CollectionFactory.newMap(null, null);
this.clanChannels = CollectionFactory.newMap(null, null);
+ this.regionChannels = CollectionFactory.newMap(null, null);
}
@Override
@@ -66,8 +88,13 @@ public class SimpleChatService extends AbstractService implements ChatService {
@Override
public PublicChatChannel getRegionChannel(L2Character character) {
- // TODO Region chat channels
- return null;
+ final Region region = regionService.getRegion(character);
+ RegionChatChannelImpl channel = regionChannels.get(region);
+ if (channel == null) {
+ channel = new RegionChatChannelImpl(region);
+ regionChannels.put(region, channel);
+ }
+ return channel;
}
@Override
@@ -90,6 +117,14 @@ public class SimpleChatService extends AbstractService implements ChatService {
return channel;
}
+ @Override
+ protected void doStop() throws ServiceStopException {
+ this.global = null;
+ this.privateChannels = null;
+ this.clanChannels = null;
+ this.regionChannels = null;
+ }
+
/**
* {@link ChatChannel} abstract implementation
*
@@ -170,4 +205,27 @@ public class SimpleChatService extends AbstractService implements ChatService {
this.clanID = clanID;
}
}
+
+ /**
+ * {@link PublicChatChannel} implemenetation for {@link Region regions}
+ *
+ * @author Rogiel
+ */
+ private class RegionChatChannelImpl extends ChatChannelImpl implements
+ PublicChatChannel {
+ /**
+ * The clan ID
+ */
+ @SuppressWarnings("unused")
+ private final Region region;
+
+ /**
+ * Creates a new instance
+ *
+ * @param clanID
+ */
+ public RegionChatChannelImpl(Region region) {
+ this.region = region;
+ }
+ }
}
diff --git a/src/main/java/com/l2jserver/service/game/region/RegionService.java b/src/main/java/com/l2jserver/service/game/region/RegionService.java
index ecd0e0d64..3760bc774 100644
--- a/src/main/java/com/l2jserver/service/game/region/RegionService.java
+++ b/src/main/java/com/l2jserver/service/game/region/RegionService.java
@@ -16,7 +16,7 @@
*/
package com.l2jserver.service.game.region;
-import com.l2jserver.model.world.L2Character;
+import com.l2jserver.model.world.capability.Actor;
import com.l2jserver.service.Service;
/**
@@ -25,5 +25,12 @@ import com.l2jserver.service.Service;
* @author Rogiel
*/
public interface RegionService extends Service {
- Region getRegion(L2Character character);
+ /**
+ * Get the region in which this actor is.
+ *
+ * @param actor
+ * the actor
+ * @return the current region
+ */
+ Region getRegion(Actor actor);
}
diff --git a/src/main/java/com/l2jserver/service/game/scripting/ScriptingServiceImpl.java b/src/main/java/com/l2jserver/service/game/scripting/ScriptingServiceImpl.java
index 700dd5464..4be9aab93 100644
--- a/src/main/java/com/l2jserver/service/game/scripting/ScriptingServiceImpl.java
+++ b/src/main/java/com/l2jserver/service/game/scripting/ScriptingServiceImpl.java
@@ -32,13 +32,21 @@ import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.l2jserver.service.AbstractService;
+import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.ServiceStopException;
import com.l2jserver.service.game.scripting.impl.ScriptContextImpl;
import com.l2jserver.service.game.scripting.scriptmanager.ScriptInfo;
import com.l2jserver.service.game.scripting.scriptmanager.ScriptList;
+import com.l2jserver.service.logging.LoggingService;
import com.l2jserver.util.factory.CollectionFactory;
+/**
+ * Default {@link ScriptingService} implementation
+ *
+ * @author Rogiel
+ */
+@Depends(LoggingService.class)
public class ScriptingServiceImpl extends AbstractService implements
ScriptingService {
/**
@@ -60,7 +68,7 @@ public class ScriptingServiceImpl extends AbstractService implements
}
@Override
- public void start() throws ServiceStartException {
+ protected void doStart() throws ServiceStartException {
for (ScriptContext context : contexts) {
context.shutdown();
}
@@ -165,7 +173,7 @@ public class ScriptingServiceImpl extends AbstractService implements
}
@Override
- public void stop() throws ServiceStopException {
+ protected void doStop() throws ServiceStopException {
for (ScriptContext context : contexts) {
context.shutdown();
}
diff --git a/src/main/java/com/l2jserver/service/game/template/ScriptTemplateService.java b/src/main/java/com/l2jserver/service/game/template/ScriptTemplateService.java
index 9af6db258..027184c5b 100644
--- a/src/main/java/com/l2jserver/service/game/template/ScriptTemplateService.java
+++ b/src/main/java/com/l2jserver/service/game/template/ScriptTemplateService.java
@@ -23,13 +23,17 @@ import com.google.inject.Injector;
import com.l2jserver.model.id.TemplateID;
import com.l2jserver.model.template.Template;
import com.l2jserver.service.AbstractService;
+import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.ServiceStopException;
import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.game.scripting.ScriptContext;
import com.l2jserver.service.game.scripting.ScriptingService;
+import com.l2jserver.service.logging.LoggingService;
import com.l2jserver.util.factory.CollectionFactory;
+@Depends({ LoggingService.class, ConfigurationService.class,
+ ScriptingService.class })
public class ScriptTemplateService extends AbstractService implements
TemplateService {
private final ScriptingService scriptingService;
@@ -52,7 +56,7 @@ public class ScriptTemplateService extends AbstractService implements
}
@Override
- public void start() throws ServiceStartException {
+ protected void doStart() throws ServiceStartException {
if (context == null) {
try {
context = scriptingService.load(config.getTemplateDescriptor())
@@ -94,7 +98,7 @@ public class ScriptTemplateService extends AbstractService implements
}
@Override
- public void stop() throws ServiceStopException {
+ protected void doStop() throws ServiceStopException {
if (context.isInitialized())
context.shutdown();
context = null;
diff --git a/src/main/java/com/l2jserver/service/game/world/WorldServiceImpl.java b/src/main/java/com/l2jserver/service/game/world/WorldServiceImpl.java
index 0d8c68d82..e0d342956 100644
--- a/src/main/java/com/l2jserver/service/game/world/WorldServiceImpl.java
+++ b/src/main/java/com/l2jserver/service/game/world/WorldServiceImpl.java
@@ -26,12 +26,17 @@ import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.model.world.WorldObject;
import com.l2jserver.service.AbstractService;
+import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.ServiceStopException;
+import com.l2jserver.service.database.DatabaseService;
+import com.l2jserver.service.game.scripting.ScriptingService;
+import com.l2jserver.service.game.template.TemplateService;
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
import com.l2jserver.service.game.world.filter.FilterIterator;
import com.l2jserver.service.game.world.filter.WorldObjectFilter;
import com.l2jserver.service.game.world.filter.impl.InstanceFilter;
+import com.l2jserver.service.logging.LoggingService;
import com.l2jserver.util.factory.CollectionFactory;
/**
@@ -39,6 +44,8 @@ import com.l2jserver.util.factory.CollectionFactory;
*
* @author Rogiel
*/
+@Depends({ LoggingService.class, TemplateService.class, ScriptingService.class,
+ DatabaseService.class })
public class WorldServiceImpl extends AbstractService implements WorldService {
/**
* The logger
@@ -62,7 +69,7 @@ public class WorldServiceImpl extends AbstractService implements WorldService {
}
@Override
- public void start() throws ServiceStartException {
+ protected void doStart() throws ServiceStartException {
objects.clear();
}
@@ -127,7 +134,7 @@ public class WorldServiceImpl extends AbstractService implements WorldService {
}
@Override
- public void stop() throws ServiceStopException {
+ protected void doStop() throws ServiceStopException {
objects.clear();
}
}
diff --git a/src/main/java/com/l2jserver/service/logging/Log4JLoggingService.java b/src/main/java/com/l2jserver/service/logging/Log4JLoggingService.java
index 63fe6af1f..8cb1d99d2 100644
--- a/src/main/java/com/l2jserver/service/logging/Log4JLoggingService.java
+++ b/src/main/java/com/l2jserver/service/logging/Log4JLoggingService.java
@@ -29,7 +29,7 @@ import com.l2jserver.service.ServiceStartException;
public class Log4JLoggingService extends AbstractService implements
LoggingService {
@Override
- public void start() throws ServiceStartException {
+ protected void doStart() throws ServiceStartException {
BasicConfigurator.configure();
}
}
diff --git a/src/main/java/com/l2jserver/service/network/NettyNetworkService.java b/src/main/java/com/l2jserver/service/network/NettyNetworkService.java
index ee6252aa7..bf7636c0d 100644
--- a/src/main/java/com/l2jserver/service/network/NettyNetworkService.java
+++ b/src/main/java/com/l2jserver/service/network/NettyNetworkService.java
@@ -33,7 +33,11 @@ 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.AbstractService.Depends;
+import com.l2jserver.service.blowfish.BlowfishKeygenService;
import com.l2jserver.service.configuration.ConfigurationService;
+import com.l2jserver.service.game.world.WorldService;
+import com.l2jserver.service.logging.LoggingService;
import com.l2jserver.util.factory.CollectionFactory;
/**
@@ -41,6 +45,8 @@ import com.l2jserver.util.factory.CollectionFactory;
*
* @author Rogiel
*/
+@Depends({ LoggingService.class, BlowfishKeygenService.class,
+ WorldService.class })
public class NettyNetworkService extends AbstractService implements
NetworkService {
/**
@@ -75,7 +81,7 @@ public class NettyNetworkService extends AbstractService implements
}
@Override
- public void start() {
+ protected void doStart() {
server = new ServerBootstrap(new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
@@ -116,7 +122,7 @@ public class NettyNetworkService extends AbstractService implements
}
@Override
- public void stop() {
+ protected void doStop() {
try {
channel.close().awaitUninterruptibly();
} finally {
diff --git a/src/test/java/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAOTest.java b/src/test/java/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAOTest.java
index 33d49e3db..c050e4964 100644
--- a/src/test/java/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAOTest.java
+++ b/src/test/java/com/l2jserver/db/dao/mysql5/MySQL5CharacterDAOTest.java
@@ -26,12 +26,10 @@ 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.ServiceManager;
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
@@ -39,11 +37,8 @@ public class MySQL5CharacterDAOTest {
@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();
+ injector.getInstance(ServiceManager.class).start(TemplateService.class);
+ injector.getInstance(ServiceManager.class).start(DatabaseService.class);
final CharacterDAO dao = injector.getInstance(CharacterDAO.class);
final L2Character char1 = dao.load(injector.getInstance(