mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-05 23:22:47 +00:00
38
data/script/ai/com/l2jserver/game/ai/MonsterAI.java
Normal file
38
data/script/ai/com/l2jserver/game/ai/MonsterAI.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.game.ai;
|
||||
|
||||
import com.l2jserver.game.ai.desires.Desire;
|
||||
import com.l2jserver.model.world.NPC;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public class MonsterAI extends NPCAI {
|
||||
/**
|
||||
* @param creature
|
||||
*/
|
||||
protected MonsterAI(NPC creature) {
|
||||
super(creature);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleDesire(Desire desire) {
|
||||
super.handleDesire(desire);
|
||||
}
|
||||
}
|
||||
47
data/script/ai/com/l2jserver/game/ai/NPCAI.java
Normal file
47
data/script/ai/com/l2jserver/game/ai/NPCAI.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.game.ai;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.game.ai.desires.Desire;
|
||||
import com.l2jserver.game.ai.desires.MoveDesire;
|
||||
import com.l2jserver.model.world.NPC;
|
||||
import com.l2jserver.service.game.npc.NPCService;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public class NPCAI extends AI<NPC> {
|
||||
@Inject
|
||||
protected NPCService npcService;
|
||||
|
||||
/**
|
||||
* @param npc
|
||||
* the npc
|
||||
*/
|
||||
protected NPCAI(NPC npc) {
|
||||
super(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleDesire(Desire desire) {
|
||||
if (desire instanceof MoveDesire) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.l2jserver.db.dao.h2;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.CharacterDAO;
|
||||
import com.l2jserver.db.dao.jdbc.JDBCCharacterDAO;
|
||||
import com.l2jserver.model.id.object.provider.CharacterIDProvider;
|
||||
@@ -31,6 +32,7 @@ import com.l2jserver.service.database.DatabaseService;
|
||||
*/
|
||||
public class H2CharacterDAO extends JDBCCharacterDAO implements
|
||||
CharacterDAO {
|
||||
@Inject
|
||||
public H2CharacterDAO(DatabaseService database,
|
||||
CharacterIDProvider idFactory,
|
||||
CharacterTemplateIDProvider templateIdFactory,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.l2jserver.db.dao.h2;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.CharacterFriendDAO;
|
||||
import com.l2jserver.db.dao.jdbc.JDBCCharacterFriendDAO;
|
||||
import com.l2jserver.model.id.object.provider.CharacterIDProvider;
|
||||
@@ -29,6 +30,7 @@ import com.l2jserver.service.database.DatabaseService;
|
||||
*/
|
||||
public class H2CharacterFriendDAO extends JDBCCharacterFriendDAO implements
|
||||
CharacterFriendDAO {
|
||||
@Inject
|
||||
public H2CharacterFriendDAO(DatabaseService database,
|
||||
FriendIDProvider idProvider, CharacterIDProvider charIdProvider) {
|
||||
super(database, idProvider, charIdProvider);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.l2jserver.db.dao.h2;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.CharacterDAO;
|
||||
import com.l2jserver.db.dao.ClanDAO;
|
||||
import com.l2jserver.db.dao.jdbc.JDBCClanDAO;
|
||||
@@ -29,6 +30,7 @@ import com.l2jserver.service.database.DatabaseService;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class H2ClanDAO extends JDBCClanDAO implements ClanDAO {
|
||||
@Inject
|
||||
public H2ClanDAO(DatabaseService database,
|
||||
ClanIDProvider clanIdFactory, CharacterIDProvider idFactory) {
|
||||
super(database, clanIdFactory, idFactory);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.l2jserver.db.dao.h2;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.ItemDAO;
|
||||
import com.l2jserver.db.dao.jdbc.JDBCItemDAO;
|
||||
import com.l2jserver.model.id.object.provider.CharacterIDProvider;
|
||||
@@ -29,6 +30,7 @@ import com.l2jserver.service.database.DatabaseService;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class H2ItemDAO extends JDBCItemDAO implements ItemDAO {
|
||||
@Inject
|
||||
public H2ItemDAO(DatabaseService database, ItemIDProvider idFactory,
|
||||
ItemTemplateIDProvider templateIdFactory,
|
||||
CharacterIDProvider charIdFactory) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.l2jserver.db.dao.h2;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.CharacterDAO;
|
||||
import com.l2jserver.db.dao.NPCDAO;
|
||||
import com.l2jserver.db.dao.jdbc.JDBCNPCDAO;
|
||||
@@ -29,6 +30,7 @@ import com.l2jserver.service.database.DatabaseService;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class H2NPCDAO extends JDBCNPCDAO implements NPCDAO {
|
||||
@Inject
|
||||
public H2NPCDAO(DatabaseService database, NPCIDProvider idProvider,
|
||||
NPCTemplateIDProvider templateIdProvider) {
|
||||
super(database, idProvider, templateIdProvider);
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
*/
|
||||
package com.l2jserver.game.ai;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.game.ai.desires.Desire;
|
||||
import com.l2jserver.game.ai.desires.DesireQueue;
|
||||
import com.l2jserver.model.world.Actor;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
@@ -26,14 +28,35 @@ import com.l2jserver.model.world.Actor;
|
||||
* the {@link Actor} type for this {@link AI}
|
||||
*/
|
||||
public abstract class AI<T extends Actor> {
|
||||
/**
|
||||
* The desire queue for this AI
|
||||
*/
|
||||
protected DesireQueue desireQueue = new DesireQueue();
|
||||
protected final T creature;
|
||||
/**
|
||||
* The actor controlled by this AI
|
||||
*/
|
||||
protected final T actor;
|
||||
|
||||
protected AI(T creature) {
|
||||
this.creature = creature;
|
||||
@Inject
|
||||
protected WorldEventDispatcher eventDispatcher;
|
||||
|
||||
protected AI(T actor) {
|
||||
this.actor = actor;
|
||||
}
|
||||
|
||||
protected void handleDesire(Desire desire) {
|
||||
desire.handleDesire(this);
|
||||
/**
|
||||
* Executes an AI tick
|
||||
*/
|
||||
protected void tick() {
|
||||
Desire desire = desireQueue.poll();
|
||||
handleDesire(desire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the given desire
|
||||
*
|
||||
* @param desire
|
||||
* the desire
|
||||
*/
|
||||
protected abstract void handleDesire(Desire desire);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
package com.l2jserver.game.ai.desires;
|
||||
|
||||
import com.l2jserver.game.ai.AI;
|
||||
import com.l2jserver.model.world.Actor;
|
||||
|
||||
/**
|
||||
@@ -43,11 +42,6 @@ public final class AttackDesire extends AbstractDesire {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDesire(AI<?> ai) {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
|
||||
@@ -16,14 +16,8 @@
|
||||
*/
|
||||
package com.l2jserver.game.ai.desires;
|
||||
|
||||
import com.l2jserver.game.ai.AI;
|
||||
|
||||
/**
|
||||
* This interface represents basic desire functions.<br>
|
||||
* Each desire should implement {@link #handleDesire(com.l2jserver.game.ai.AI)}
|
||||
* method with default behavior.<br>
|
||||
* AI can override {@link com.l2jserver.game.ai.AI#handleDesire(Desire)} to
|
||||
* implement custom behavior of desire.<br>
|
||||
* This interface represents basic desire functions.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* @see com.l2jserver.game.ai.AI
|
||||
@@ -31,15 +25,6 @@ import com.l2jserver.game.ai.AI;
|
||||
* @see com.l2jserver.game.ai.desires.AbstractDesire
|
||||
*/
|
||||
public interface Desire extends Comparable<Desire> {
|
||||
/**
|
||||
* Invokes default desire action. AI can override invocation of this method
|
||||
* to handle desire in it's own way
|
||||
*
|
||||
* @param ai
|
||||
* actor that is doing this desire
|
||||
*/
|
||||
void handleDesire(AI<?> ai);
|
||||
|
||||
/**
|
||||
* Returns hashcode for this object, must be overrided by child
|
||||
*
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
package com.l2jserver.game.ai.desires;
|
||||
|
||||
import com.l2jserver.game.ai.AI;
|
||||
import com.l2jserver.model.world.Actor;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
@@ -44,14 +43,6 @@ public final class MoveDesire extends AbstractDesire {
|
||||
this.point = point;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDesire(AI<?> ai) {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
@@ -64,9 +55,6 @@ public final class MoveDesire extends AbstractDesire {
|
||||
return point.equals(that.point);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return point.hashCode();
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.id.object.NPCID;
|
||||
import com.l2jserver.model.id.object.provider.ObjectIDResolver;
|
||||
import com.l2jserver.model.world.NPC;
|
||||
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
|
||||
import com.l2jserver.service.game.npc.ActionServiceException;
|
||||
import com.l2jserver.service.game.npc.NPCService;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
@@ -97,6 +98,8 @@ public class CharacterActionPacket extends AbstractClientPacket {
|
||||
npcService.action(npc, conn.getCharacter(), action);
|
||||
} catch (ActionServiceException e) {
|
||||
conn.sendActionFailed();
|
||||
} catch (CannotSetTargetServiceException e) {
|
||||
conn.sendActionFailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.id.object.NPCID;
|
||||
import com.l2jserver.model.id.object.provider.ObjectIDResolver;
|
||||
import com.l2jserver.model.world.NPC;
|
||||
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
|
||||
import com.l2jserver.service.game.npc.ActionServiceException;
|
||||
import com.l2jserver.service.game.npc.NPCService;
|
||||
import com.l2jserver.util.BufferUtils;
|
||||
@@ -86,6 +87,8 @@ public class CharacterRequestBypass extends AbstractClientPacket {
|
||||
createArgumentArray(tokenizer));
|
||||
} catch (ActionServiceException e) {
|
||||
conn.sendActionFailed();
|
||||
} catch (CannotSetTargetServiceException e) {
|
||||
conn.sendActionFailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,12 @@ import com.l2jserver.service.game.ai.AIScript;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class NPC extends Actor {
|
||||
private NPCState state;
|
||||
|
||||
public enum NPCState {
|
||||
MOVING, ATTACKING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
@@ -39,6 +45,42 @@ public class NPC extends Actor {
|
||||
super(templateID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the state
|
||||
*/
|
||||
public NPCState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if NPC is idle
|
||||
*/
|
||||
public boolean isIdle() {
|
||||
return state == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if NPC is idle
|
||||
*/
|
||||
public boolean isMoving() {
|
||||
return state == NPCState.MOVING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if NPC is idle
|
||||
*/
|
||||
public boolean isAttacking() {
|
||||
return state == NPCState.ATTACKING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param state
|
||||
* the state to set
|
||||
*/
|
||||
public void setState(NPCState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActorSex getSex() {
|
||||
return this.getTemplate().getSex();
|
||||
|
||||
@@ -25,6 +25,8 @@ import com.l2jserver.service.configuration.ConfigurationService;
|
||||
import com.l2jserver.service.configuration.ProxyConfigurationService;
|
||||
import com.l2jserver.service.core.Log4JLoggingService;
|
||||
import com.l2jserver.service.core.LoggingService;
|
||||
import com.l2jserver.service.core.threading.ThreadService;
|
||||
import com.l2jserver.service.core.threading.ThreadServiceImpl;
|
||||
import com.l2jserver.service.core.vfs.VFSService;
|
||||
import com.l2jserver.service.core.vfs.VFSServiceImpl;
|
||||
import com.l2jserver.service.database.DatabaseService;
|
||||
@@ -66,9 +68,12 @@ public class ServiceModule extends AbstractModule {
|
||||
bind(LoggingService.class).to(Log4JLoggingService.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(VFSService.class).to(VFSServiceImpl.class).in(Scopes.SINGLETON);
|
||||
bind(ThreadService.class).to(ThreadServiceImpl.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(ConfigurationService.class).to(ProxyConfigurationService.class)
|
||||
.in(Scopes.SINGLETON);
|
||||
bind(CacheService.class).to(EhCacheService.class).in(Scopes.SINGLETON);
|
||||
|
||||
bind(DatabaseService.class).to(JDBCDatabaseService.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(WorldIDService.class).to(CachedWorldIDService.class).in(
|
||||
|
||||
@@ -200,7 +200,7 @@ public class EhCacheService extends AbstractService implements CacheService {
|
||||
final Element element = cache.get(key);
|
||||
if (element == null)
|
||||
return null;
|
||||
return (V) element.getValue();
|
||||
return (V) element.getObjectValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.core.threading;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
/**
|
||||
* This future instance extends {@link ScheduledFuture}. An scheduled future
|
||||
* cannot return values neither await for its termination because its execution
|
||||
* is continuously repeated.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface ScheduledAsyncFuture extends ScheduledFuture<Object> {
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.core.threading;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* This is an ThreadPool you can use it to schedule tasks in the future or to
|
||||
* repeat them many times.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface ThreadPool {
|
||||
/**
|
||||
* Executes an asynchronous tasks.
|
||||
*
|
||||
* @param <T>
|
||||
* the task return type
|
||||
* @param callable
|
||||
* the callable instance
|
||||
* @return the {@link AsyncFuture} notified once the task has completed
|
||||
*/
|
||||
<T> AsyncFuture<T> async(Callable<T> callable);
|
||||
|
||||
/**
|
||||
* Executes an asynchronous tasks at an scheduled time.
|
||||
*
|
||||
* @param <T>
|
||||
* the task return type
|
||||
* @param callable
|
||||
* the callable instance
|
||||
* @param delay
|
||||
* the initial delay to wait before the task is executed
|
||||
* @param unit
|
||||
* the time unit of delay
|
||||
* @return the {@link AsyncFuture} notified once the task has completed
|
||||
*/
|
||||
<T> AsyncFuture<T> async(long delay, TimeUnit unit, Callable<T> callable);
|
||||
|
||||
/**
|
||||
* Executes an asynchronous tasks at an scheduled time.
|
||||
*
|
||||
* @param callable
|
||||
* the callable instance
|
||||
* @param delay
|
||||
* the initial delay to wait before the task is executed
|
||||
* @param repeat
|
||||
* the repeating interval for this task
|
||||
* @param unit
|
||||
* the time unit of delay
|
||||
* @return the {@link AsyncFuture} notified once the task has completed
|
||||
*/
|
||||
ScheduledAsyncFuture async(long delay, TimeUnit unit, long repeat,
|
||||
Runnable task);
|
||||
|
||||
}
|
||||
@@ -30,6 +30,8 @@ import com.l2jserver.service.Service;
|
||||
public interface ThreadService extends Service {
|
||||
/**
|
||||
* Executes an asynchronous tasks.
|
||||
* <p>
|
||||
* Tasks scheduled here will go to an default shared thread pool.
|
||||
*
|
||||
* @param <T>
|
||||
* the task return type
|
||||
@@ -43,6 +45,8 @@ public interface ThreadService extends Service {
|
||||
* Executes an asynchronous tasks at an scheduled time. <b>Please note that
|
||||
* resources in scheduled thread pool are limited and tasks should be
|
||||
* performed fast.</b>
|
||||
* <p>
|
||||
* Tasks scheduled here will go to an default shared thread pool.
|
||||
*
|
||||
* @param <T>
|
||||
* the task return type
|
||||
@@ -55,4 +59,44 @@ public interface ThreadService extends Service {
|
||||
* @return the {@link AsyncFuture} notified once the task has completed
|
||||
*/
|
||||
<T> AsyncFuture<T> async(long delay, TimeUnit unit, Callable<T> callable);
|
||||
|
||||
/**
|
||||
* Executes an asynchronous tasks at an scheduled time. <b>Please note that
|
||||
* resources in scheduled thread pool are limited and tasks should be
|
||||
* performed fast.</b>
|
||||
* <p>
|
||||
* Tasks scheduled here will go to an default shared thread pool.
|
||||
*
|
||||
* @param callable
|
||||
* the callable instance
|
||||
* @param delay
|
||||
* the initial delay to wait before the task is executed
|
||||
* @param repeat
|
||||
* the repeating interval for this task
|
||||
* @param unit
|
||||
* the time unit of delay
|
||||
* @return the {@link AsyncFuture} notified once the task has completed
|
||||
*/
|
||||
ScheduledAsyncFuture async(long delay, TimeUnit unit, long repeat,
|
||||
Runnable task);
|
||||
|
||||
/**
|
||||
* Creates a new thread pool.
|
||||
*
|
||||
* @param name
|
||||
* the pool name
|
||||
* @param maxThreads
|
||||
* the maximum amount of threads.
|
||||
* @return the new thread pool
|
||||
*/
|
||||
ThreadPool createThreadPool(String name, int maxThreads);
|
||||
|
||||
/**
|
||||
* Disposes an given thread pool. After disposing the thread pool will no
|
||||
* longer be usable.
|
||||
*
|
||||
* @param pool
|
||||
* the thread pool to be disposed
|
||||
*/
|
||||
void dispose(ThreadPool pool);
|
||||
}
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
package com.l2jserver.service.core.threading;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
@@ -44,25 +45,19 @@ public class ThreadServiceImpl extends AbstractService implements ThreadService
|
||||
*/
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* The scheduler Thread pool
|
||||
*/
|
||||
private ScheduledExecutorService scheduler;
|
||||
/**
|
||||
* The asynchronous Thread pool
|
||||
*/
|
||||
private ExecutorService async;
|
||||
private ThreadPool pool;
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
scheduler = Executors.newScheduledThreadPool(10);
|
||||
async = Executors.newCachedThreadPool();
|
||||
pool = createThreadPool("shared", 20);
|
||||
// scheduler = Executors.newScheduledThreadPool(10);
|
||||
// async = Executors.newCachedThreadPool();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> AsyncFuture<T> async(Callable<T> callable) {
|
||||
Preconditions.checkNotNull(callable, "callable");
|
||||
return new AsyncFutureImpl<T>(async.submit(callable));
|
||||
return pool.async(callable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,25 +66,37 @@ public class ThreadServiceImpl extends AbstractService implements ThreadService
|
||||
Preconditions.checkArgument(delay >= 0, "delay < 0");
|
||||
Preconditions.checkNotNull(unit, "unit");
|
||||
Preconditions.checkNotNull(callable, "callable");
|
||||
return new AsyncFutureImpl<T>(scheduler.schedule(callable, delay, unit));
|
||||
return pool.async(delay, unit, callable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledAsyncFuture async(long delay, TimeUnit unit, long repeat,
|
||||
Runnable task) {
|
||||
Preconditions.checkArgument(delay >= 0, "delay < 0");
|
||||
Preconditions.checkArgument(repeat >= 0, "repeat < 0");
|
||||
Preconditions.checkNotNull(unit, "unit");
|
||||
Preconditions.checkNotNull(task, "task");
|
||||
return pool.async(delay, unit, repeat, task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThreadPool createThreadPool(String name, int maxThreads) {
|
||||
return new ThreadPoolImpl(name,
|
||||
Executors.newScheduledThreadPool(maxThreads));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose(ThreadPool pool) {
|
||||
if (pool instanceof ThreadPoolImpl)
|
||||
((ThreadPoolImpl) pool).executor.shutdown();
|
||||
throw new UnsupportedOperationException(
|
||||
"The given ThreadPool is not supported by this service");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
scheduler.shutdown();
|
||||
async.shutdown();
|
||||
try {
|
||||
scheduler.awaitTermination(60, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("Scheduler thread did not stop in 60 seconds", e);
|
||||
}
|
||||
try {
|
||||
async.awaitTermination(60, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("Asynchronous thread did not stop in 60 seconds", e);
|
||||
}
|
||||
scheduler = null;
|
||||
async = null;
|
||||
dispose(pool);
|
||||
pool = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +106,7 @@ public class ThreadServiceImpl extends AbstractService implements ThreadService
|
||||
* @param <T>
|
||||
* the return type
|
||||
*/
|
||||
public static class AsyncFutureImpl<T> implements AsyncFuture<T> {
|
||||
private class AsyncFutureImpl<T> implements AsyncFuture<T> {
|
||||
/**
|
||||
* The future that is delegated in this implementation
|
||||
*/
|
||||
@@ -184,4 +191,92 @@ public class ThreadServiceImpl extends AbstractService implements ThreadService
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ScheduledAsyncFutureImpl implements ScheduledAsyncFuture {
|
||||
private final ScheduledFuture<?> future;
|
||||
|
||||
public ScheduledAsyncFutureImpl(ScheduledFuture<?> future) {
|
||||
this.future = future;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDelay(TimeUnit unit) {
|
||||
return future.getDelay(unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return future.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Delayed o) {
|
||||
return future.compareTo(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return future.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return future.isDone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get() throws InterruptedException, ExecutionException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(long timeout, TimeUnit unit)
|
||||
throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ThreadPoolImpl implements ThreadPool {
|
||||
/**
|
||||
* This thread pool name
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* The backing executor
|
||||
*/
|
||||
private final ScheduledExecutorService executor;
|
||||
|
||||
public ThreadPoolImpl(String name, ScheduledExecutorService executor) {
|
||||
this.name = name;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> AsyncFuture<T> async(Callable<T> callable) {
|
||||
log.debug("Task {} submited to {}", callable, name);
|
||||
return new AsyncFutureImpl<T>(executor.submit(callable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> AsyncFuture<T> async(long delay, TimeUnit unit,
|
||||
Callable<T> callable) {
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("Task {} scheduled in {} {} to {}", new Object[] {
|
||||
callable, delay, unit, name });
|
||||
return new AsyncFutureImpl<T>(executor.schedule(callable, delay,
|
||||
unit));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledAsyncFuture async(long delay, TimeUnit unit,
|
||||
long repeat, Runnable task) {
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("Task {} scheduled every {} {} to {}", new Object[] {
|
||||
task, repeat, unit, name });
|
||||
return new ScheduledAsyncFutureImpl(executor.scheduleAtFixedRate(
|
||||
task, delay, repeat, unit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,11 @@ import com.l2jserver.model.template.NPCTemplate;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.model.world.NPC;
|
||||
import com.l2jserver.service.Service;
|
||||
import com.l2jserver.service.core.threading.AsyncFuture;
|
||||
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
|
||||
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
|
||||
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This service manages {@link NPC} instances
|
||||
@@ -43,9 +46,11 @@ public interface NPCService extends Service {
|
||||
* the character
|
||||
* @param action
|
||||
* the action type
|
||||
* @throws CannotSetTargetServiceException
|
||||
* if was not possible to set the target
|
||||
*/
|
||||
void action(NPC npc, L2Character character, CharacterAction action)
|
||||
throws ActionServiceException;
|
||||
throws ActionServiceException, CannotSetTargetServiceException;
|
||||
|
||||
/**
|
||||
* Executes an action for an NPC. Each {@link NPCTemplate} have it's own
|
||||
@@ -57,9 +62,22 @@ public interface NPCService extends Service {
|
||||
* the character
|
||||
* @param args
|
||||
* the action arguments
|
||||
* @throws CannotSetTargetServiceException
|
||||
* if was not possible to set the target
|
||||
*/
|
||||
void action(NPC npc, L2Character character, String... args)
|
||||
throws ActionServiceException;
|
||||
throws ActionServiceException, CannotSetTargetServiceException;
|
||||
|
||||
/**
|
||||
* Moves an given <tt>npc</tt> to an <tt>point</tt>
|
||||
*
|
||||
* @param npc
|
||||
* the NPC
|
||||
* @param point
|
||||
* the destination point
|
||||
* @return the future informing once the NPC has been moved to that location
|
||||
*/
|
||||
AsyncFuture<Boolean> move(NPC npc, Point3D point);
|
||||
|
||||
/**
|
||||
* Load from database and spawn all {@link NPC NPCs} instances
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.l2jserver.service.game.npc;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.inject.Inject;
|
||||
@@ -27,10 +29,16 @@ import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.packet.client.CharacterActionPacket.CharacterAction;
|
||||
import com.l2jserver.game.net.packet.server.ActorAttackPacket;
|
||||
import com.l2jserver.model.server.AttackHit;
|
||||
import com.l2jserver.model.server.AttackHit.AttackHitFlag;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.model.world.NPC;
|
||||
import com.l2jserver.model.world.NPC.NPCState;
|
||||
import com.l2jserver.model.world.npc.controller.NPCController;
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.AbstractService.Depends;
|
||||
import com.l2jserver.service.core.threading.AsyncFuture;
|
||||
import com.l2jserver.service.core.threading.ThreadService;
|
||||
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
|
||||
import com.l2jserver.service.game.character.CharacterService;
|
||||
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
|
||||
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
|
||||
@@ -38,12 +46,15 @@ import com.l2jserver.service.game.spawn.SpawnService;
|
||||
import com.l2jserver.service.network.NetworkService;
|
||||
import com.l2jserver.util.exception.L2Exception;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Default {@link NPCService} implementation
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@Depends({ SpawnService.class, NetworkService.class, CharacterService.class,
|
||||
ThreadService.class })
|
||||
public class NPCServiceImpl extends AbstractService implements NPCService {
|
||||
/**
|
||||
* The {@link SpawnService} used to spawn the {@link NPC} instances
|
||||
@@ -56,8 +67,11 @@ public class NPCServiceImpl extends AbstractService implements NPCService {
|
||||
/**
|
||||
* The {@link CharacterService}
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private final CharacterService characterService;
|
||||
/**
|
||||
* The {@link ThreadService}
|
||||
*/
|
||||
private final ThreadService threadService;
|
||||
|
||||
/**
|
||||
* The {@link NPCDAO}
|
||||
@@ -79,21 +93,25 @@ public class NPCServiceImpl extends AbstractService implements NPCService {
|
||||
@Inject
|
||||
public NPCServiceImpl(SpawnService spawnService,
|
||||
NetworkService networkService, CharacterService characterService,
|
||||
NPCDAO npcDao, Injector injector) {
|
||||
ThreadService threadService, NPCDAO npcDao, Injector injector) {
|
||||
this.spawnService = spawnService;
|
||||
this.networkService = networkService;
|
||||
this.characterService = characterService;
|
||||
this.threadService = threadService;
|
||||
this.npcDao = npcDao;
|
||||
this.injector = injector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void action(NPC npc, L2Character character, CharacterAction action)
|
||||
throws ActionServiceException {
|
||||
throws ActionServiceException, CannotSetTargetServiceException {
|
||||
Preconditions.checkNotNull(npc, "npc");
|
||||
Preconditions.checkNotNull(character, "character");
|
||||
Preconditions.checkNotNull(action, "action");
|
||||
|
||||
if (npc.getTemplate().isTargetable())
|
||||
characterService.target(character, npc);
|
||||
|
||||
final Lineage2Connection conn = networkService.discover(character
|
||||
.getID());
|
||||
try {
|
||||
@@ -106,12 +124,15 @@ public class NPCServiceImpl extends AbstractService implements NPCService {
|
||||
|
||||
@Override
|
||||
public void action(NPC npc, L2Character character, String... args)
|
||||
throws ActionServiceException {
|
||||
throws ActionServiceException, CannotSetTargetServiceException {
|
||||
Preconditions.checkNotNull(npc, "npc");
|
||||
Preconditions.checkNotNull(character, "character");
|
||||
if (args == null)
|
||||
args = new String[0];
|
||||
|
||||
if (npc.getTemplate().isTargetable())
|
||||
characterService.target(character, npc);
|
||||
|
||||
final Lineage2Connection conn = networkService.discover(character
|
||||
.getID());
|
||||
try {
|
||||
@@ -123,7 +144,30 @@ public class NPCServiceImpl extends AbstractService implements NPCService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<NPC> spawnAll() throws SpawnPointNotFoundServiceException,
|
||||
public AsyncFuture<Boolean> move(final NPC npc, final Point3D point) {
|
||||
if (!npc.isIdle())
|
||||
// TODO throw an exception
|
||||
return null;
|
||||
npc.setState(NPCState.MOVING);
|
||||
// calculate walking time
|
||||
final Point3D start = npc.getPoint();
|
||||
final double distance = start.getDistance(point);
|
||||
final double seconds = distance / npc.getTemplate().getRunSpeed();
|
||||
// TODO this is an dirty implementation!
|
||||
return threadService.async((int) (seconds * 1000),
|
||||
TimeUnit.MILLISECONDS, new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
npc.setState(null);
|
||||
npc.setPoint(point);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<NPC> spawnAll()
|
||||
throws SpawnPointNotFoundServiceException,
|
||||
AlreadySpawnedServiceException {
|
||||
final Collection<NPC> npcs = npcDao.loadAll();
|
||||
for (final NPC npc : npcs) {
|
||||
@@ -140,7 +184,8 @@ public class NPCServiceImpl extends AbstractService implements NPCService {
|
||||
Preconditions.checkNotNull(attacker, "attacker");
|
||||
|
||||
conn.write(new ActorAttackPacket(conn.getCharacter(), new AttackHit(
|
||||
conn.getCharacter(), npc)));
|
||||
conn.getCharacter(), npc, AttackHitFlag.MISS,
|
||||
AttackHitFlag.SOULSHOT)));
|
||||
}
|
||||
|
||||
private NPCController getController(NPC npc) {
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.l2jserver.service.game.world.event;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -30,8 +29,11 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.util.concurrent.AbstractFuture;
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.service.core.threading.ThreadPool;
|
||||
import com.l2jserver.service.core.threading.ThreadService;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
/**
|
||||
@@ -46,10 +48,12 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(WorldEventDispatcherImpl.class);
|
||||
|
||||
private final ThreadService threadService;
|
||||
|
||||
/**
|
||||
* The execution thread
|
||||
*/
|
||||
private Timer timer;
|
||||
private ThreadPool threadPool;
|
||||
|
||||
/**
|
||||
* The list of all global listeners
|
||||
@@ -66,10 +70,14 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
private Queue<EventContainer> events = CollectionFactory
|
||||
.newConcurrentQueue();
|
||||
|
||||
@Inject
|
||||
public WorldEventDispatcherImpl(ThreadService threadService) {
|
||||
this.threadService = threadService;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
// TODO event dispatching should be done using ThreadService
|
||||
timer = new Timer();
|
||||
final TimerTask task = new TimerTask() {
|
||||
threadPool = threadService.createThreadPool("event-dispatcher", 1);
|
||||
threadPool.async(0, TimeUnit.MILLISECONDS, 20, new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
EventContainer event;
|
||||
@@ -91,8 +99,7 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
timer.scheduleAtFixedRate(task, 0, 50);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -223,8 +230,8 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
timer.cancel();
|
||||
timer = null;
|
||||
threadService.dispose(threadPool);
|
||||
threadPool = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user