1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-08 08:23:11 +00:00

Several improvements

Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
2011-05-19 01:40:53 -03:00
parent 9bb83652e4
commit 2c4af6d91d
263 changed files with 2135 additions and 663 deletions

View File

@@ -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);

View File

@@ -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)

View File

@@ -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>
*

View File

@@ -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();

View File

@@ -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();
}
}

View File

@@ -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);
}