mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-08 08:23:11 +00:00
@@ -39,6 +39,8 @@ import com.l2jserver.service.game.world.WorldService;
|
||||
import com.l2jserver.service.game.world.WorldServiceImpl;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcherImpl;
|
||||
import com.l2jserver.service.game.world.id.CachedWorldIDService;
|
||||
import com.l2jserver.service.game.world.id.WorldIDService;
|
||||
import com.l2jserver.service.logging.Log4JLoggingService;
|
||||
import com.l2jserver.service.logging.LoggingService;
|
||||
import com.l2jserver.service.network.NettyNetworkService;
|
||||
@@ -62,6 +64,8 @@ public class ServiceModule extends AbstractModule {
|
||||
bind(CacheService.class).to(EhCacheService.class).in(Scopes.SINGLETON);
|
||||
bind(DatabaseService.class).to(MySQLDatabaseService.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(WorldIDService.class).to(CachedWorldIDService.class).in(
|
||||
Scopes.SINGLETON);
|
||||
|
||||
bind(BlowfishKeygenService.class).to(SecureBlowfishKeygenService.class)
|
||||
.in(Scopes.SINGLETON);
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.id.object.allocator.IDAllocator;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.AbstractService.Depends;
|
||||
@@ -116,8 +117,10 @@ public class MySQLDatabaseService extends AbstractService implements
|
||||
connectionFactory, connectionPool, null, null, false, true);
|
||||
dataSource = new PoolingDataSource(connectionPool);
|
||||
|
||||
// cache must be large enough for all world objects, to avoid
|
||||
// duplication... this would endanger non-persistent states
|
||||
objectCache = new Cache(new CacheConfiguration("database-service",
|
||||
10 * 1000)
|
||||
IDAllocator.ALLOCABLE_IDS)
|
||||
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(false).timeToLiveSeconds(60)
|
||||
.timeToIdleSeconds(30).diskPersistent(false)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.l2jserver.service.game;
|
||||
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.model.world.capability.Actor;
|
||||
import com.l2jserver.service.Service;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
|
||||
@@ -42,6 +43,16 @@ public interface CharacterService extends Service {
|
||||
*/
|
||||
void leaveWorld(L2Character character);
|
||||
|
||||
/**
|
||||
* Set the target of this <tt>character</tt>
|
||||
*
|
||||
* @param character
|
||||
* the character
|
||||
* @param actor
|
||||
* the targeted actor
|
||||
*/
|
||||
void target(L2Character character, Actor actor);
|
||||
|
||||
/**
|
||||
* Moves the given <tt>character</tt> to <tt>coordinate</tt>
|
||||
*
|
||||
|
||||
@@ -21,17 +21,24 @@ import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.packet.client.CharacterChatMessagePacket.MessageDestination;
|
||||
import com.l2jserver.game.net.packet.server.ActorChatMessagePacket;
|
||||
import com.l2jserver.game.net.packet.server.ActorMovementPacket;
|
||||
import com.l2jserver.game.net.packet.server.CharacterInformationPacket;
|
||||
import com.l2jserver.game.net.packet.server.CharacterMovementTypePacket;
|
||||
import com.l2jserver.game.net.packet.server.CharacterTargetSelectedPacket;
|
||||
import com.l2jserver.game.net.packet.server.GameGuardQueryPacket;
|
||||
import com.l2jserver.game.net.packet.server.InventoryPacket;
|
||||
import com.l2jserver.game.net.packet.server.UserInformationPacket;
|
||||
import com.l2jserver.game.net.packet.server.NPCInformationPacket;
|
||||
import com.l2jserver.model.id.object.CharacterID;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.model.world.L2Character.CharacterMoveType;
|
||||
import com.l2jserver.model.world.NPC;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.model.world.capability.Actor;
|
||||
import com.l2jserver.model.world.character.event.CharacterEnterWorldEvent;
|
||||
import com.l2jserver.model.world.character.event.CharacterEvent;
|
||||
import com.l2jserver.model.world.character.event.CharacterLeaveWorldEvent;
|
||||
import com.l2jserver.model.world.character.event.CharacterListener;
|
||||
import com.l2jserver.model.world.character.event.CharacterTargetDeselectedEvent;
|
||||
import com.l2jserver.model.world.character.event.CharacterTargetSelectedEvent;
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.AbstractService.Depends;
|
||||
import com.l2jserver.service.game.ai.AIService;
|
||||
@@ -40,6 +47,7 @@ import com.l2jserver.service.game.chat.channel.ChatChannel;
|
||||
import com.l2jserver.service.game.chat.channel.ChatChannelListener;
|
||||
import com.l2jserver.service.game.world.WorldService;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||
import com.l2jserver.service.game.world.filter.impl.KnownListFilter;
|
||||
import com.l2jserver.service.network.NetworkService;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
|
||||
@@ -81,17 +89,12 @@ public class CharacterServiceImpl extends AbstractService implements
|
||||
@Inject
|
||||
public CharacterServiceImpl(WorldService worldService,
|
||||
WorldEventDispatcher eventDispatcher, ChatService chatService,
|
||||
NetworkService networkService, SpawnService spawnService/*
|
||||
* ,
|
||||
* AIService
|
||||
* aiService
|
||||
*/) {
|
||||
NetworkService networkService, SpawnService spawnService) {
|
||||
this.worldService = worldService;
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
this.chatService = chatService;
|
||||
this.networkService = networkService;
|
||||
this.spawnService = spawnService;
|
||||
// this.aiService = aiService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,13 +137,24 @@ public class CharacterServiceImpl extends AbstractService implements
|
||||
globalChatListener);
|
||||
|
||||
// send this user information
|
||||
conn.write(new UserInformationPacket(character));
|
||||
conn.write(new CharacterInformationPacket(character));
|
||||
// TODO game guard enforcing
|
||||
conn.write(new GameGuardQueryPacket());
|
||||
conn.write(new InventoryPacket(character.getInventory()));
|
||||
|
||||
// characters start in run mode
|
||||
run(character);
|
||||
|
||||
// broadcast knownlist -- trashy implementation
|
||||
// TODO should be moved to world service
|
||||
for (final WorldObject o : worldService.iterable(new KnownListFilter(
|
||||
character))) {
|
||||
if (o instanceof NPC) {
|
||||
conn.write(new NPCInformationPacket((NPC) o));
|
||||
// conn.write(new ServerObjectPacket((NPC) o));
|
||||
}
|
||||
}
|
||||
|
||||
// dispatch enter world event
|
||||
eventDispatcher.dispatch(new CharacterEnterWorldEvent(character));
|
||||
|
||||
@@ -169,6 +183,28 @@ public class CharacterServiceImpl extends AbstractService implements
|
||||
eventDispatcher.dispatch(new CharacterLeaveWorldEvent(character));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void target(L2Character character, Actor target) {
|
||||
final CharacterID id = character.getID();
|
||||
final Lineage2Connection conn = networkService.discover(id);
|
||||
|
||||
if (target == null && character.getTargetID() != null) {
|
||||
final Actor oldTarget = character.getTarget();
|
||||
character.setTargetID(null);
|
||||
eventDispatcher.dispatch(new CharacterTargetDeselectedEvent(
|
||||
character, oldTarget));
|
||||
} else if (target != null && !target.getID().equals(character.getID())) {
|
||||
if (character.getTargetID() != null) {
|
||||
eventDispatcher.dispatch(new CharacterTargetDeselectedEvent(
|
||||
character, character.getTarget()));
|
||||
}
|
||||
character.setTargetID(null);
|
||||
eventDispatcher.dispatch(new CharacterTargetSelectedEvent(
|
||||
character, target));
|
||||
conn.write(new CharacterTargetSelectedPacket(target));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void walk(L2Character character) {
|
||||
final CharacterID id = character.getID();
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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.game.world.id;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.Element;
|
||||
import net.sf.ehcache.config.CacheConfiguration;
|
||||
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.CharacterDAO;
|
||||
import com.l2jserver.model.id.ID;
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.id.object.allocator.IDAllocator;
|
||||
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.database.DatabaseService;
|
||||
|
||||
/**
|
||||
* Implementation for {@link IDService} that caches all {@link ID} objects in
|
||||
* memory.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@Depends({ DatabaseService.class, CacheService.class })
|
||||
public class CachedWorldIDService extends AbstractService implements
|
||||
WorldIDService {
|
||||
/**
|
||||
* The cache service
|
||||
*/
|
||||
private final CacheService cacheService;
|
||||
/**
|
||||
* The {@link IDAllocator}
|
||||
*/
|
||||
private final IDAllocator allocator;
|
||||
|
||||
// DAOS
|
||||
/**
|
||||
* The {@link CharacterDAO}
|
||||
*/
|
||||
private final CharacterDAO characterDao;
|
||||
|
||||
/**
|
||||
* The ID cache
|
||||
*/
|
||||
private Cache cache;
|
||||
|
||||
@Inject
|
||||
public CachedWorldIDService(CacheService cacheService,
|
||||
IDAllocator allocator, CharacterDAO characterDao) {
|
||||
this.cacheService = cacheService;
|
||||
this.allocator = allocator;
|
||||
this.characterDao = characterDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
// we allocate an cache which can fit all ids
|
||||
cache = new Cache(new CacheConfiguration("id-cache",
|
||||
IDAllocator.ALLOCABLE_IDS)
|
||||
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(false).timeToLiveSeconds(60)
|
||||
.timeToIdleSeconds(30).diskPersistent(false)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
cacheService.register(cache);
|
||||
|
||||
// load all ids
|
||||
load(characterDao.listIDs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the pre-existing ids
|
||||
*
|
||||
* @param ids
|
||||
* an collection of ids
|
||||
*/
|
||||
private void load(Collection<? extends ObjectID<?>> ids) {
|
||||
for (final ObjectID<?> id : ids) {
|
||||
allocator.allocate(id.getID());
|
||||
add(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <I extends ObjectID<?>> I resolve(int id) {
|
||||
final Element element = cache.get(id);
|
||||
if (element == null)
|
||||
return null;
|
||||
return (I) element.getObjectValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <I extends ObjectID<?>> void add(I id) {
|
||||
cache.put(new Element(id.getID(), id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <I extends ObjectID<?>> void remove(I id) {
|
||||
cache.remove(id.getID());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
cacheService.unregister(cache);
|
||||
cache = null;
|
||||
allocator.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.game.world.id;
|
||||
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.id.object.allocator.IDAllocator;
|
||||
import com.l2jserver.service.Service;
|
||||
import com.l2jserver.service.database.DatabaseService;
|
||||
|
||||
/**
|
||||
* This service manages all {@link ObjectID} related tasks. Please note that
|
||||
* this service must be started right after the {@link DatabaseService} has
|
||||
* started, since the database depends on {@link ObjectID} but the
|
||||
* {@link IDAllocator} depends on database data.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface WorldIDService extends Service {
|
||||
/**
|
||||
* Tries to resolve an ID based on its raw value
|
||||
*
|
||||
* @param <V>
|
||||
* the raw ID type
|
||||
* @param <I>
|
||||
* the ID type
|
||||
* @param id
|
||||
* the id raw value
|
||||
* @return the id located
|
||||
*/
|
||||
<I extends ObjectID<?>> I resolve(int id);
|
||||
|
||||
<I extends ObjectID<?>> void add(I id);
|
||||
|
||||
<I extends ObjectID<?>> void remove(I id);
|
||||
}
|
||||
Reference in New Issue
Block a user