mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-06 07:32:46 +00:00
BroadcastService implementation
Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
@@ -57,8 +57,14 @@ public class L2JGameServerMain {
|
|||||||
serviceManager.start(BlowfishKeygenService.class);
|
serviceManager.start(BlowfishKeygenService.class);
|
||||||
serviceManager.start(NetworkService.class);
|
serviceManager.start(NetworkService.class);
|
||||||
|
|
||||||
// spawn
|
// spawn everything
|
||||||
serviceManager.get(NPCService.class).spawnAll();
|
serviceManager.get(NPCService.class).spawnAll();
|
||||||
|
|
||||||
|
// final long free = Runtime.getRuntime().freeMemory();
|
||||||
|
// final long allocated = Runtime.getRuntime().totalMemory();
|
||||||
|
// final long maximum = Runtime.getRuntime().maxMemory();
|
||||||
|
// final long processors =
|
||||||
|
// Runtime.getRuntime().availableProcessors();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("GameServer could not be started!");
|
System.out.println("GameServer could not be started!");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class CM_PROTOCOL_VERSION extends AbstractClientPacket {
|
|||||||
log.debug("Client protocol version: {}", version);
|
log.debug("Client protocol version: {}", version);
|
||||||
conn.setVersion(version);
|
conn.setVersion(version);
|
||||||
if (L2JConstant.SUPPORTED_PROTOCOL != version) {
|
if (L2JConstant.SUPPORTED_PROTOCOL != version) {
|
||||||
log.info("Incorrect protocol version: {0}. Only {1} is supported.",
|
log.info("Incorrect protocol version: {}. Only {} is supported.",
|
||||||
version, L2JConstant.SUPPORTED_PROTOCOL);
|
version, L2JConstant.SUPPORTED_PROTOCOL);
|
||||||
// notify wrong protocol and close connection
|
// notify wrong protocol and close connection
|
||||||
conn.write(new SM_KEY(inKey, false)).addListener(
|
conn.write(new SM_KEY(inKey, false)).addListener(
|
||||||
|
|||||||
@@ -74,18 +74,18 @@ public class ServiceManager {
|
|||||||
knownServices.add(service);
|
knownServices.add(service);
|
||||||
try {
|
try {
|
||||||
startDependencies(service.getDependencies());
|
startDependencies(service.getDependencies());
|
||||||
logger.info("{}: Starting service...",
|
logger.debug("{}: Starting service...",
|
||||||
serviceClass.getCanonicalName());
|
serviceClass.getSimpleName());
|
||||||
service.start();
|
service.start();
|
||||||
logger.info("{}: Service started!", serviceClass.getCanonicalName());
|
logger.info("{} started", serviceClass.getSimpleName());
|
||||||
return service;
|
return service;
|
||||||
} catch (ServiceStartException e) {
|
} catch (ServiceStartException e) {
|
||||||
logger.error("{}: Error starting service: {}",
|
logger.error("{}: Error starting service: {}",
|
||||||
serviceClass.getCanonicalName(), e);
|
serviceClass.getSimpleName(), e);
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("{}: Error starting service: {}",
|
logger.error("{}: Error starting service: {}",
|
||||||
serviceClass.getCanonicalName(), e);
|
serviceClass.getSimpleName(), e);
|
||||||
throw new ServiceStartException(e);
|
throw new ServiceStartException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,15 +110,15 @@ public class ServiceManager {
|
|||||||
return;
|
return;
|
||||||
knownServices.add(service);
|
knownServices.add(service);
|
||||||
try {
|
try {
|
||||||
logger.info("{0}: Stopping service...",
|
logger.debug("{0}: Stopping service...",
|
||||||
serviceClass.getCanonicalName());
|
serviceClass.getSimpleName());
|
||||||
stopDependencies(service);
|
stopDependencies(service);
|
||||||
service.stop();
|
service.stop();
|
||||||
logger.info("{0}: Service stopped!",
|
logger.info("{0}: Service stopped!",
|
||||||
serviceClass.getCanonicalName());
|
serviceClass.getSimpleName());
|
||||||
} catch (ServiceStopException e) {
|
} catch (ServiceStopException e) {
|
||||||
logger.error("{0}: Error stopping service: {1}",
|
logger.error("{0}: Error stopping service: {1}",
|
||||||
serviceClass.getCanonicalName(), e.getCause());
|
serviceClass.getSimpleName(), e.getCause());
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,23 +160,23 @@ public class ServiceManager {
|
|||||||
throw new ServiceStopException("Service is already stopped");
|
throw new ServiceStopException("Service is already stopped");
|
||||||
knownServices.add(service);
|
knownServices.add(service);
|
||||||
try {
|
try {
|
||||||
logger.info("{0}: Restaring service...",
|
logger.debug("{0}: Restaring service...",
|
||||||
serviceClass.getCanonicalName());
|
serviceClass.getSimpleName());
|
||||||
service.restart();
|
service.restart();
|
||||||
logger.info("{0}: Service restarted!",
|
logger.info("{0}: Service restarted!",
|
||||||
serviceClass.getCanonicalName());
|
serviceClass.getSimpleName());
|
||||||
return service;
|
return service;
|
||||||
} catch (ServiceStartException e) {
|
} catch (ServiceStartException e) {
|
||||||
logger.error("{0}: Error starting service: {1}",
|
logger.error("{0}: Error starting service: {1}",
|
||||||
serviceClass.getCanonicalName(), e.getCause());
|
serviceClass.getSimpleName(), e.getCause());
|
||||||
throw e;
|
throw e;
|
||||||
} catch (ServiceStopException e) {
|
} catch (ServiceStopException e) {
|
||||||
logger.error("{0}: Error stopping service: {1}",
|
logger.error("{0}: Error stopping service: {1}",
|
||||||
serviceClass.getCanonicalName(), e.getCause());
|
serviceClass.getSimpleName(), e.getCause());
|
||||||
throw e;
|
throw e;
|
||||||
} catch (ServiceException e) {
|
} catch (ServiceException e) {
|
||||||
logger.error("{0}: Error restarting service: {1}",
|
logger.error("{0}: Error restarting service: {1}",
|
||||||
serviceClass.getCanonicalName(), e.getCause());
|
serviceClass.getSimpleName(), e.getCause());
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
|||||||
import com.l2jserver.service.game.world.event.WorldEventDispatcherImpl;
|
import com.l2jserver.service.game.world.event.WorldEventDispatcherImpl;
|
||||||
import com.l2jserver.service.network.NettyNetworkService;
|
import com.l2jserver.service.network.NettyNetworkService;
|
||||||
import com.l2jserver.service.network.NetworkService;
|
import com.l2jserver.service.network.NetworkService;
|
||||||
|
import com.l2jserver.service.network.broadcast.BroadcastService;
|
||||||
|
import com.l2jserver.service.network.broadcast.BroadcastServiceImpl;
|
||||||
import com.l2jserver.service.network.gameguard.GameGuardService;
|
import com.l2jserver.service.network.gameguard.GameGuardService;
|
||||||
import com.l2jserver.service.network.gameguard.GameGuardServiceImpl;
|
import com.l2jserver.service.network.gameguard.GameGuardServiceImpl;
|
||||||
import com.l2jserver.service.network.keygen.BlowfishKeygenService;
|
import com.l2jserver.service.network.keygen.BlowfishKeygenService;
|
||||||
@@ -101,6 +103,8 @@ public class ServiceModule extends AbstractModule {
|
|||||||
.in(Scopes.SINGLETON);
|
.in(Scopes.SINGLETON);
|
||||||
bind(SpawnService.class).to(SpawnServiceImpl.class)
|
bind(SpawnService.class).to(SpawnServiceImpl.class)
|
||||||
.in(Scopes.SINGLETON);
|
.in(Scopes.SINGLETON);
|
||||||
|
bind(BroadcastService.class).to(BroadcastServiceImpl.class).in(
|
||||||
|
Scopes.SINGLETON);
|
||||||
bind(CharacterService.class).to(CharacterServiceImpl.class).in(
|
bind(CharacterService.class).to(CharacterServiceImpl.class).in(
|
||||||
Scopes.SINGLETON);
|
Scopes.SINGLETON);
|
||||||
bind(AttackService.class).to(AttackServiceImpl.class).in(
|
bind(AttackService.class).to(AttackServiceImpl.class).in(
|
||||||
|
|||||||
@@ -81,13 +81,13 @@ public class ProxyConfigurationService extends AbstractService implements
|
|||||||
|
|
||||||
if (cache.containsKey(config))
|
if (cache.containsKey(config))
|
||||||
return (C) cache.get(config);
|
return (C) cache.get(config);
|
||||||
logger.info("Trying to create {} proxy", config);
|
logger.debug("Trying to create {} proxy", config);
|
||||||
Properties properties;
|
Properties properties;
|
||||||
try {
|
try {
|
||||||
properties = findProperties(config);
|
properties = findProperties(config);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
properties = new Properties();
|
properties = new Properties();
|
||||||
logger.info(
|
logger.warn(
|
||||||
"Configuration file for {} not found, falling back to default values",
|
"Configuration file for {} not found, falling back to default values",
|
||||||
config);
|
config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,16 +21,12 @@ import com.google.inject.Inject;
|
|||||||
import com.l2jserver.db.dao.ItemDAO;
|
import com.l2jserver.db.dao.ItemDAO;
|
||||||
import com.l2jserver.game.net.Lineage2Connection;
|
import com.l2jserver.game.net.Lineage2Connection;
|
||||||
import com.l2jserver.game.net.SystemMessage;
|
import com.l2jserver.game.net.SystemMessage;
|
||||||
import com.l2jserver.game.net.packet.server.SM_ATTACK;
|
|
||||||
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO;
|
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO;
|
||||||
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_BROADCAST;
|
|
||||||
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_EXTRA;
|
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_EXTRA;
|
||||||
import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY;
|
import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY;
|
||||||
import com.l2jserver.game.net.packet.server.SM_CHAT;
|
import com.l2jserver.game.net.packet.server.SM_CHAT;
|
||||||
import com.l2jserver.game.net.packet.server.SM_MOVE;
|
import com.l2jserver.game.net.packet.server.SM_MOVE;
|
||||||
import com.l2jserver.game.net.packet.server.SM_MOVE_TYPE;
|
import com.l2jserver.game.net.packet.server.SM_MOVE_TYPE;
|
||||||
import com.l2jserver.game.net.packet.server.SM_NPC_INFO;
|
|
||||||
import com.l2jserver.game.net.packet.server.SM_OBJECT_REMOVE;
|
|
||||||
import com.l2jserver.game.net.packet.server.SM_TARGET;
|
import com.l2jserver.game.net.packet.server.SM_TARGET;
|
||||||
import com.l2jserver.model.id.object.CharacterID;
|
import com.l2jserver.model.id.object.CharacterID;
|
||||||
import com.l2jserver.model.world.Actor;
|
import com.l2jserver.model.world.Actor;
|
||||||
@@ -38,9 +34,6 @@ import com.l2jserver.model.world.L2Character;
|
|||||||
import com.l2jserver.model.world.L2Character.CharacterMoveType;
|
import com.l2jserver.model.world.L2Character.CharacterMoveType;
|
||||||
import com.l2jserver.model.world.L2Character.CharacterState;
|
import com.l2jserver.model.world.L2Character.CharacterState;
|
||||||
import com.l2jserver.model.world.NPC;
|
import com.l2jserver.model.world.NPC;
|
||||||
import com.l2jserver.model.world.PositionableObject;
|
|
||||||
import com.l2jserver.model.world.WorldObject;
|
|
||||||
import com.l2jserver.model.world.actor.event.ActorAttackHitEvent;
|
|
||||||
import com.l2jserver.model.world.character.event.CharacterEnterWorldEvent;
|
import com.l2jserver.model.world.character.event.CharacterEnterWorldEvent;
|
||||||
import com.l2jserver.model.world.character.event.CharacterEvent;
|
import com.l2jserver.model.world.character.event.CharacterEvent;
|
||||||
import com.l2jserver.model.world.character.event.CharacterLeaveWorldEvent;
|
import com.l2jserver.model.world.character.event.CharacterLeaveWorldEvent;
|
||||||
@@ -50,9 +43,6 @@ import com.l2jserver.model.world.character.event.CharacterRunningEvent;
|
|||||||
import com.l2jserver.model.world.character.event.CharacterTargetDeselectedEvent;
|
import com.l2jserver.model.world.character.event.CharacterTargetDeselectedEvent;
|
||||||
import com.l2jserver.model.world.character.event.CharacterTargetSelectedEvent;
|
import com.l2jserver.model.world.character.event.CharacterTargetSelectedEvent;
|
||||||
import com.l2jserver.model.world.character.event.CharacterWalkingEvent;
|
import com.l2jserver.model.world.character.event.CharacterWalkingEvent;
|
||||||
import com.l2jserver.model.world.npc.event.NPCSpawnEvent;
|
|
||||||
import com.l2jserver.model.world.player.event.PlayerTeleportedEvent;
|
|
||||||
import com.l2jserver.model.world.player.event.PlayerTeleportingEvent;
|
|
||||||
import com.l2jserver.service.AbstractService;
|
import com.l2jserver.service.AbstractService;
|
||||||
import com.l2jserver.service.AbstractService.Depends;
|
import com.l2jserver.service.AbstractService.Depends;
|
||||||
import com.l2jserver.service.game.AttackService;
|
import com.l2jserver.service.game.AttackService;
|
||||||
@@ -67,14 +57,9 @@ import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
|
|||||||
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
|
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
|
||||||
import com.l2jserver.service.game.spawn.SpawnService;
|
import com.l2jserver.service.game.spawn.SpawnService;
|
||||||
import com.l2jserver.service.game.world.WorldService;
|
import com.l2jserver.service.game.world.WorldService;
|
||||||
import com.l2jserver.service.game.world.event.FilteredWorldListener;
|
|
||||||
import com.l2jserver.service.game.world.event.WorldEvent;
|
|
||||||
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||||
import com.l2jserver.service.game.world.event.WorldListener;
|
|
||||||
import com.l2jserver.service.game.world.filter.impl.IDFilter;
|
|
||||||
import com.l2jserver.service.game.world.filter.impl.KnownListFilter;
|
|
||||||
import com.l2jserver.service.game.world.filter.impl.KnownListUpdateFilter;
|
|
||||||
import com.l2jserver.service.network.NetworkService;
|
import com.l2jserver.service.network.NetworkService;
|
||||||
|
import com.l2jserver.service.network.broadcast.BroadcastService;
|
||||||
import com.l2jserver.service.network.gameguard.GameGuardService;
|
import com.l2jserver.service.network.gameguard.GameGuardService;
|
||||||
import com.l2jserver.util.geometry.Coordinate;
|
import com.l2jserver.util.geometry.Coordinate;
|
||||||
import com.l2jserver.util.geometry.Point3D;
|
import com.l2jserver.util.geometry.Point3D;
|
||||||
@@ -85,14 +70,15 @@ import com.l2jserver.util.geometry.Point3D;
|
|||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
@Depends({ WorldService.class, ChatService.class, NetworkService.class,
|
@Depends({ WorldService.class, ChatService.class, NetworkService.class,
|
||||||
SpawnService.class, AttackService.class, GameGuardService.class })
|
SpawnService.class, AttackService.class, GameGuardService.class,
|
||||||
|
BroadcastService.class })
|
||||||
public class CharacterServiceImpl extends AbstractService implements
|
public class CharacterServiceImpl extends AbstractService implements
|
||||||
CharacterService {
|
CharacterService {
|
||||||
/**
|
/**
|
||||||
* The {@link WorldService}
|
* The {@link BroadcastService}
|
||||||
*/
|
*/
|
||||||
private final WorldService worldService;
|
private final BroadcastService broadcastService;
|
||||||
/*
|
/**
|
||||||
* The {@link WorldService} event dispatcher
|
* The {@link WorldService} event dispatcher
|
||||||
*/
|
*/
|
||||||
private final WorldEventDispatcher eventDispatcher;
|
private final WorldEventDispatcher eventDispatcher;
|
||||||
@@ -127,11 +113,11 @@ public class CharacterServiceImpl extends AbstractService implements
|
|||||||
// private final AIService aiService;
|
// private final AIService aiService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CharacterServiceImpl(WorldService worldService,
|
public CharacterServiceImpl(BroadcastService broadcastService,
|
||||||
WorldEventDispatcher eventDispatcher, ChatService chatService,
|
WorldEventDispatcher eventDispatcher, ChatService chatService,
|
||||||
NetworkService networkService, SpawnService spawnService,
|
NetworkService networkService, SpawnService spawnService,
|
||||||
NPCService npcService, GameGuardService ggService, ItemDAO itemDao) {
|
NPCService npcService, GameGuardService ggService, ItemDAO itemDao) {
|
||||||
this.worldService = worldService;
|
this.broadcastService = broadcastService;
|
||||||
this.eventDispatcher = eventDispatcher;
|
this.eventDispatcher = eventDispatcher;
|
||||||
this.chatService = chatService;
|
this.chatService = chatService;
|
||||||
this.networkService = networkService;
|
this.networkService = networkService;
|
||||||
@@ -154,7 +140,7 @@ public class CharacterServiceImpl extends AbstractService implements
|
|||||||
itemDao.loadInventory(character);
|
itemDao.loadInventory(character);
|
||||||
|
|
||||||
character.setOnline(true);
|
character.setOnline(true);
|
||||||
|
|
||||||
// inventory interfere on calculators
|
// inventory interfere on calculators
|
||||||
character.getStats().updateCalculator();
|
character.getStats().updateCalculator();
|
||||||
|
|
||||||
@@ -176,77 +162,8 @@ public class CharacterServiceImpl extends AbstractService implements
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// event broadcast listener
|
// start broadcasting -- will broadcast all nearby objects
|
||||||
// this listener will be filtered so that only interesting events are
|
broadcastService.broadcast(conn);
|
||||||
// dispatched, once a event arrives will be possible to check check if
|
|
||||||
// the given event will be broadcasted or not
|
|
||||||
// TODO this should not be here, it should be in world service or a
|
|
||||||
// newly created broadcast service.
|
|
||||||
final WorldListener neighboorListener = new FilteredWorldListener<PositionableObject>(
|
|
||||||
new KnownListFilter(character)) {
|
|
||||||
@Override
|
|
||||||
protected boolean dispatch(WorldEvent e, PositionableObject object) {
|
|
||||||
if (e instanceof NPCSpawnEvent) {
|
|
||||||
conn.write(new SM_NPC_INFO((NPC) object));
|
|
||||||
} else if (e instanceof CharacterMoveEvent) {
|
|
||||||
final CharacterMoveEvent evt = (CharacterMoveEvent) e;
|
|
||||||
conn.write(new SM_MOVE((L2Character) object, evt.getPoint()
|
|
||||||
.getCoordinate()));
|
|
||||||
} else if (e instanceof PlayerTeleportedEvent
|
|
||||||
|| e instanceof CharacterEnterWorldEvent) {
|
|
||||||
if (object instanceof NPC) {
|
|
||||||
conn.write(new SM_NPC_INFO((NPC) object));
|
|
||||||
} else if (object instanceof L2Character) {
|
|
||||||
conn.write(new SM_CHAR_INFO_BROADCAST(
|
|
||||||
(L2Character) object));
|
|
||||||
}
|
|
||||||
} else if (e instanceof PlayerTeleportingEvent
|
|
||||||
|| e instanceof CharacterLeaveWorldEvent) {
|
|
||||||
// object is not out of sight
|
|
||||||
conn.write(new SM_OBJECT_REMOVE(object));
|
|
||||||
} else if (e instanceof CharacterWalkingEvent) {
|
|
||||||
conn.write(new SM_MOVE_TYPE(((CharacterWalkingEvent) e)
|
|
||||||
.getCharacter()));
|
|
||||||
} else if (e instanceof CharacterRunningEvent) {
|
|
||||||
conn.write(new SM_MOVE_TYPE(((CharacterRunningEvent) e)
|
|
||||||
.getCharacter()));
|
|
||||||
}
|
|
||||||
// keep listener alive
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
eventDispatcher.addListener(neighboorListener);
|
|
||||||
final WorldListener sendPacketListener = new FilteredWorldListener<WorldObject>(
|
|
||||||
new IDFilter(character.getID())) {
|
|
||||||
@Override
|
|
||||||
protected boolean dispatch(WorldEvent e, WorldObject object) {
|
|
||||||
if (e instanceof CharacterMoveEvent) {
|
|
||||||
final CharacterMoveEvent evt = (CharacterMoveEvent) e;
|
|
||||||
// process update known list
|
|
||||||
for (final WorldObject o : worldService
|
|
||||||
.iterable(new KnownListUpdateFilter(character, evt
|
|
||||||
.getPoint()))) {
|
|
||||||
if (o instanceof NPC) {
|
|
||||||
conn.write(new SM_NPC_INFO((NPC) o));
|
|
||||||
} else if (o instanceof L2Character) {
|
|
||||||
conn.write(new SM_CHAR_INFO_BROADCAST(
|
|
||||||
(L2Character) o));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (e instanceof PlayerTeleportedEvent
|
|
||||||
|| e instanceof CharacterEnterWorldEvent) {
|
|
||||||
broadcast(conn, character);
|
|
||||||
} else if (e instanceof ActorAttackHitEvent) {
|
|
||||||
conn.write(new SM_ATTACK(((ActorAttackHitEvent) e).getHit()));
|
|
||||||
conn.sendSystemMessage(SystemMessage.YOU_DID_S1_DMG,
|
|
||||||
(int) ((ActorAttackHitEvent) e).getHit()
|
|
||||||
.getDamage());
|
|
||||||
}
|
|
||||||
// keep listener alive
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
eventDispatcher.addListener(sendPacketListener);
|
|
||||||
|
|
||||||
// leave world event
|
// leave world event
|
||||||
eventDispatcher.addListener(id, new CharacterListener() {
|
eventDispatcher.addListener(id, new CharacterListener() {
|
||||||
@@ -261,9 +178,9 @@ public class CharacterServiceImpl extends AbstractService implements
|
|||||||
chatService.getTradeChannel().removeChatChannelListener(
|
chatService.getTradeChannel().removeChatChannelListener(
|
||||||
tradeChatListener);
|
tradeChatListener);
|
||||||
|
|
||||||
// remove broadcast listener
|
// // remove broadcast listener
|
||||||
eventDispatcher.removeListener(neighboorListener);
|
// eventDispatcher.removeListener(neighboorListener);
|
||||||
eventDispatcher.removeListener(sendPacketListener);
|
// eventDispatcher.removeListener(id, sendPacketListener);s
|
||||||
|
|
||||||
// we can kill this listener now
|
// we can kill this listener now
|
||||||
return false;
|
return false;
|
||||||
@@ -295,7 +212,7 @@ public class CharacterServiceImpl extends AbstractService implements
|
|||||||
// we can ignore this one
|
// we can ignore this one
|
||||||
}
|
}
|
||||||
|
|
||||||
broadcast(conn, character);
|
// broadcast(conn, character);
|
||||||
|
|
||||||
// spawn the player -- this will also dispatch a spawn event
|
// spawn the player -- this will also dispatch a spawn event
|
||||||
// here the object is registered in the world
|
// here the object is registered in the world
|
||||||
@@ -305,20 +222,6 @@ public class CharacterServiceImpl extends AbstractService implements
|
|||||||
eventDispatcher.dispatch(new CharacterEnterWorldEvent(character));
|
eventDispatcher.dispatch(new CharacterEnterWorldEvent(character));
|
||||||
}
|
}
|
||||||
|
|
||||||
// broadcast knownlist -- trashy implementation
|
|
||||||
// TODO should be moved to world service or a newly created broadcast
|
|
||||||
// service, whichever fits the purpose
|
|
||||||
private void broadcast(Lineage2Connection conn, L2Character character) {
|
|
||||||
for (final WorldObject o : worldService.iterable(new KnownListFilter(
|
|
||||||
character))) {
|
|
||||||
if (o instanceof NPC) {
|
|
||||||
conn.write(new SM_NPC_INFO((NPC) o));
|
|
||||||
} else if (o instanceof L2Character) {
|
|
||||||
conn.write(new SM_CHAR_INFO_BROADCAST((L2Character) o));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void leaveWorld(L2Character character)
|
public void leaveWorld(L2Character character)
|
||||||
throws NotSpawnedServiceException {
|
throws NotSpawnedServiceException {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import com.l2jserver.service.AbstractService;
|
|||||||
import com.l2jserver.service.AbstractService.Depends;
|
import com.l2jserver.service.AbstractService.Depends;
|
||||||
import com.l2jserver.service.core.threading.AsyncFuture;
|
import com.l2jserver.service.core.threading.AsyncFuture;
|
||||||
import com.l2jserver.service.core.threading.ThreadService;
|
import com.l2jserver.service.core.threading.ThreadService;
|
||||||
|
import com.l2jserver.service.database.DatabaseService;
|
||||||
import com.l2jserver.service.game.AttackService;
|
import com.l2jserver.service.game.AttackService;
|
||||||
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
|
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
|
||||||
import com.l2jserver.service.game.character.CharacterService;
|
import com.l2jserver.service.game.character.CharacterService;
|
||||||
@@ -53,7 +54,7 @@ import com.l2jserver.util.geometry.Point3D;
|
|||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
@Depends({ SpawnService.class, NetworkService.class, CharacterService.class,
|
@Depends({ SpawnService.class, NetworkService.class, CharacterService.class,
|
||||||
ThreadService.class, AttackService.class })
|
ThreadService.class, AttackService.class, DatabaseService.class })
|
||||||
public class NPCServiceImpl extends AbstractService implements NPCService {
|
public class NPCServiceImpl extends AbstractService implements NPCService {
|
||||||
/**
|
/**
|
||||||
* The {@link SpawnService} used to spawn the {@link NPC} instances
|
* The {@link SpawnService} used to spawn the {@link NPC} instances
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.broadcast;
|
||||||
|
|
||||||
|
import com.l2jserver.game.net.Lineage2Connection;
|
||||||
|
import com.l2jserver.model.world.WorldObject;
|
||||||
|
import com.l2jserver.service.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This service is responsible for sending neighbor {@link WorldObject} packets.
|
||||||
|
* This service also sends some packets that are bounded to an event.
|
||||||
|
*
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*/
|
||||||
|
public interface BroadcastService extends Service {
|
||||||
|
void broadcast(Lineage2Connection conn);
|
||||||
|
}
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.broadcast;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.l2jserver.game.net.Lineage2Connection;
|
||||||
|
import com.l2jserver.game.net.SystemMessage;
|
||||||
|
import com.l2jserver.game.net.packet.server.SM_ATTACK;
|
||||||
|
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_BROADCAST;
|
||||||
|
import com.l2jserver.game.net.packet.server.SM_MOVE;
|
||||||
|
import com.l2jserver.game.net.packet.server.SM_MOVE_TYPE;
|
||||||
|
import com.l2jserver.game.net.packet.server.SM_NPC_INFO;
|
||||||
|
import com.l2jserver.game.net.packet.server.SM_OBJECT_REMOVE;
|
||||||
|
import com.l2jserver.model.id.object.CharacterID;
|
||||||
|
import com.l2jserver.model.world.L2Character;
|
||||||
|
import com.l2jserver.model.world.NPC;
|
||||||
|
import com.l2jserver.model.world.PositionableObject;
|
||||||
|
import com.l2jserver.model.world.WorldObject;
|
||||||
|
import com.l2jserver.model.world.actor.event.ActorAttackHitEvent;
|
||||||
|
import com.l2jserver.model.world.character.event.CharacterEnterWorldEvent;
|
||||||
|
import com.l2jserver.model.world.character.event.CharacterLeaveWorldEvent;
|
||||||
|
import com.l2jserver.model.world.character.event.CharacterMoveEvent;
|
||||||
|
import com.l2jserver.model.world.character.event.CharacterRunningEvent;
|
||||||
|
import com.l2jserver.model.world.character.event.CharacterWalkingEvent;
|
||||||
|
import com.l2jserver.model.world.npc.event.NPCSpawnEvent;
|
||||||
|
import com.l2jserver.model.world.player.event.PlayerTeleportedEvent;
|
||||||
|
import com.l2jserver.model.world.player.event.PlayerTeleportingEvent;
|
||||||
|
import com.l2jserver.service.AbstractService;
|
||||||
|
import com.l2jserver.service.AbstractService.Depends;
|
||||||
|
import com.l2jserver.service.game.world.WorldService;
|
||||||
|
import com.l2jserver.service.game.world.event.FilteredWorldListener;
|
||||||
|
import com.l2jserver.service.game.world.event.WorldEvent;
|
||||||
|
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||||
|
import com.l2jserver.service.game.world.event.WorldListener;
|
||||||
|
import com.l2jserver.service.game.world.filter.impl.KnownListFilter;
|
||||||
|
import com.l2jserver.service.game.world.filter.impl.KnownListUpdateFilter;
|
||||||
|
import com.l2jserver.service.network.NetworkService;
|
||||||
|
import com.l2jserver.util.geometry.Point3D;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*/
|
||||||
|
@Depends({ NetworkService.class, WorldService.class })
|
||||||
|
public class BroadcastServiceImpl extends AbstractService implements
|
||||||
|
BroadcastService {
|
||||||
|
private final WorldService worldService;
|
||||||
|
private final WorldEventDispatcher eventDispatcher;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public BroadcastServiceImpl(WorldService worldService,
|
||||||
|
WorldEventDispatcher eventDispatcher) {
|
||||||
|
this.worldService = worldService;
|
||||||
|
this.eventDispatcher = eventDispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void broadcast(final Lineage2Connection conn) {
|
||||||
|
Preconditions.checkNotNull(conn, "conn");
|
||||||
|
final L2Character character = conn.getCharacter();
|
||||||
|
Preconditions.checkNotNull(character, "character");
|
||||||
|
final CharacterID id = character.getID();
|
||||||
|
|
||||||
|
// broadcast everything nearby
|
||||||
|
broadcast(conn);
|
||||||
|
|
||||||
|
// event broadcast listener
|
||||||
|
// this listener will be filtered so that only interesting events are
|
||||||
|
// dispatched, once a event arrives will be possible to check check if
|
||||||
|
// the given event will be broadcasted or not
|
||||||
|
final WorldListener neighborListener = new FilteredWorldListener<PositionableObject>(
|
||||||
|
new KnownListFilter(character)) {
|
||||||
|
@Override
|
||||||
|
protected boolean dispatch(WorldEvent e, PositionableObject object) {
|
||||||
|
if (e instanceof NPCSpawnEvent) {
|
||||||
|
broadcast(conn, e.getObject());
|
||||||
|
} else if (e instanceof CharacterMoveEvent) {
|
||||||
|
final CharacterMoveEvent evt = (CharacterMoveEvent) e;
|
||||||
|
conn.write(new SM_MOVE((L2Character) object, evt.getPoint()
|
||||||
|
.getCoordinate()));
|
||||||
|
} else if (e instanceof PlayerTeleportedEvent
|
||||||
|
|| e instanceof CharacterEnterWorldEvent) {
|
||||||
|
broadcast(conn, e.getObject());
|
||||||
|
} else if (e instanceof PlayerTeleportingEvent
|
||||||
|
|| e instanceof CharacterLeaveWorldEvent) {
|
||||||
|
// object is now out of sight
|
||||||
|
conn.write(new SM_OBJECT_REMOVE(object));
|
||||||
|
} else if (e instanceof CharacterWalkingEvent) {
|
||||||
|
conn.write(new SM_MOVE_TYPE(((CharacterWalkingEvent) e)
|
||||||
|
.getCharacter()));
|
||||||
|
} else if (e instanceof CharacterRunningEvent) {
|
||||||
|
conn.write(new SM_MOVE_TYPE(((CharacterRunningEvent) e)
|
||||||
|
.getCharacter()));
|
||||||
|
}
|
||||||
|
// keep listener alive
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// add the global listener
|
||||||
|
eventDispatcher.addListener(neighborListener);
|
||||||
|
// this listener is bound directly to the character, no need for filters
|
||||||
|
// or any other test inside listener
|
||||||
|
final WorldListener sendPacketListener = new WorldListener() {
|
||||||
|
@Override
|
||||||
|
public boolean dispatch(WorldEvent e) {
|
||||||
|
if (e instanceof CharacterMoveEvent) {
|
||||||
|
final CharacterMoveEvent evt = (CharacterMoveEvent) e;
|
||||||
|
// process update known list
|
||||||
|
broadcastUpdate(conn, character, evt.getPoint());
|
||||||
|
} else if (e instanceof PlayerTeleportedEvent
|
||||||
|
|| e instanceof CharacterEnterWorldEvent) {
|
||||||
|
broadcastAll(conn, character);
|
||||||
|
} else if (e instanceof ActorAttackHitEvent) {
|
||||||
|
conn.write(new SM_ATTACK(((ActorAttackHitEvent) e).getHit()));
|
||||||
|
conn.sendSystemMessage(SystemMessage.YOU_DID_S1_DMG,
|
||||||
|
(int) ((ActorAttackHitEvent) e).getHit()
|
||||||
|
.getDamage());
|
||||||
|
}
|
||||||
|
// keep listener alive
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// add listener only for this character
|
||||||
|
eventDispatcher.addListener(id, sendPacketListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast all nearby objects to this client
|
||||||
|
*
|
||||||
|
* @param conn
|
||||||
|
* the connection
|
||||||
|
* @param character
|
||||||
|
* the character
|
||||||
|
*/
|
||||||
|
private void broadcastAll(Lineage2Connection conn, L2Character character) {
|
||||||
|
for (final WorldObject o : worldService.iterable(new KnownListFilter(
|
||||||
|
character))) {
|
||||||
|
broadcast(conn, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast new nearby objects to this client. Will only broadcast if the
|
||||||
|
* object was out-of-range before and now is in range.
|
||||||
|
*
|
||||||
|
* @param conn
|
||||||
|
* the connection
|
||||||
|
* @param character
|
||||||
|
* the character
|
||||||
|
* @param point
|
||||||
|
* the old point
|
||||||
|
*/
|
||||||
|
private void broadcastUpdate(Lineage2Connection conn,
|
||||||
|
L2Character character, Point3D point) {
|
||||||
|
for (final WorldObject o : worldService
|
||||||
|
.iterable(new KnownListUpdateFilter(character, point))) {
|
||||||
|
broadcast(conn, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast an object to this client
|
||||||
|
*
|
||||||
|
* @param conn
|
||||||
|
* the connection
|
||||||
|
* @param character
|
||||||
|
* the character
|
||||||
|
*/
|
||||||
|
private void broadcast(Lineage2Connection conn, WorldObject o) {
|
||||||
|
if (o instanceof NPC) {
|
||||||
|
conn.write(new SM_NPC_INFO((NPC) o));
|
||||||
|
} else if (o instanceof L2Character) {
|
||||||
|
conn.write(new SM_CHAR_INFO_BROADCAST((L2Character) o));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user