Addition of ThreadPool.

This commit is contained in:
MobiusDevelopment
2019-11-24 11:36:26 +00:00
parent 48ed880262
commit b9f9638f4c
15 changed files with 571 additions and 426 deletions

View File

@@ -0,0 +1,11 @@
# ---------------------------------------------------------------------------
# Threadpool Settings
# ---------------------------------------------------------------------------
# Specifies how many threads will be in the scheduled pool.
# Default: 40
ScheduledThreadPoolCount = 40
# Specifies how many threads will be in the single instant pool.
# Default: 20
InstantThreadPoolCount = 20

View File

@@ -39,6 +39,7 @@ public class Config
private static final String SERVER_CONFIG_FILE = "config/server.ini"; private static final String SERVER_CONFIG_FILE = "config/server.ini";
private static final String RATES_CONFIG_FILE = "config/rates.ini"; private static final String RATES_CONFIG_FILE = "config/rates.ini";
private static final String KARMA_CONFIG_FILE = "config/karma.ini"; private static final String KARMA_CONFIG_FILE = "config/karma.ini";
private static final String THREADPOOL_CONFIG_FILE = "config/threadpool.ini";
// Game // Game
public static String _ip; public static String _ip;
@@ -64,6 +65,9 @@ public class Config
public static float KARMA_LOST_MULTIPLIER; public static float KARMA_LOST_MULTIPLIER;
public static int KARMA_DROP_CHANCE; public static int KARMA_DROP_CHANCE;
public static List<Integer> KARMA_PROTECTED_ITEMS; public static List<Integer> KARMA_PROTECTED_ITEMS;
// ThreadPool
public static int SCHEDULED_THREAD_POOL_COUNT;
public static int INSTANT_THREAD_POOL_COUNT;
public static void load() public static void load()
{ {
@@ -107,5 +111,11 @@ public class Config
KARMA_LOST_MULTIPLIER = karmaSettings.getFloat("KarmaLostMultiplier", 1); KARMA_LOST_MULTIPLIER = karmaSettings.getFloat("KarmaLostMultiplier", 1);
KARMA_DROP_CHANCE = karmaSettings.getInt("KarmaDropChance", 5); KARMA_DROP_CHANCE = karmaSettings.getInt("KarmaDropChance", 5);
KARMA_PROTECTED_ITEMS = Arrays.stream(karmaSettings.getIntArray("KarmaProtectedItems", ";")).boxed().collect(Collectors.toList()); KARMA_PROTECTED_ITEMS = Arrays.stream(karmaSettings.getIntArray("KarmaProtectedItems", ";")).boxed().collect(Collectors.toList());
// Load threadpool config file (if exists)
final PropertiesParser threadpoolSettings = new PropertiesParser(THREADPOOL_CONFIG_FILE);
SCHEDULED_THREAD_POOL_COUNT = threadpoolSettings.getInt("ScheduledThreadPoolCount", 40);
INSTANT_THREAD_POOL_COUNT = threadpoolSettings.getInt("InstantThreadPoolCount", 20);
} }
} }

View File

@@ -52,6 +52,7 @@ import org.l2jmobius.gameserver.handler.skillhandlers.HealSkill;
import org.l2jmobius.gameserver.managers.GmListManager; import org.l2jmobius.gameserver.managers.GmListManager;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.network.ClientThread; import org.l2jmobius.gameserver.network.ClientThread;
import org.l2jmobius.gameserver.threadpool.ThreadPool;
import org.l2jmobius.loginserver.LoginController; import org.l2jmobius.loginserver.LoginController;
public class GameServer extends Thread public class GameServer extends Thread
@@ -124,6 +125,8 @@ public class GameServer extends Thread
{ {
super("GameServer"); super("GameServer");
ThreadPool.init();
if (!Config.SERVER_HOST_NAME.equals("*")) if (!Config.SERVER_HOST_NAME.equals("*"))
{ {
final InetAddress adr = InetAddress.getByName(Config.SERVER_HOST_NAME); final InetAddress adr = InetAddress.getByName(Config.SERVER_HOST_NAME);

View File

@@ -31,6 +31,7 @@ import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
import org.l2jmobius.gameserver.network.serverpackets.PetInfo; import org.l2jmobius.gameserver.network.serverpackets.PetInfo;
import org.l2jmobius.gameserver.network.serverpackets.PetItemList; import org.l2jmobius.gameserver.network.serverpackets.PetItemList;
import org.l2jmobius.gameserver.templates.Npc; import org.l2jmobius.gameserver.templates.Npc;
import org.l2jmobius.gameserver.threadpool.ThreadPool;
public class PetSummon implements IItemHandler public class PetSummon implements IItemHandler
{ {
@@ -109,20 +110,17 @@ public class PetSummon implements IItemHandler
activeChar.broadcastPacket(ni); activeChar.broadcastPacket(ni);
activeChar.sendPacket(ownerni); activeChar.sendPacket(ownerni);
activeChar.sendPacket(new PetItemList(newpet)); activeChar.sendPacket(new PetItemList(newpet));
try
ThreadPool.schedule(() ->
{ {
Thread.sleep(900L);
}
catch (InterruptedException e)
{
// empty catch block
}
activeChar.sendPacket(new MagicSkillLaunched(activeChar, 2046, 1)); activeChar.sendPacket(new MagicSkillLaunched(activeChar, 2046, 1));
activeChar.setPet(newpet); activeChar.setPet(newpet);
newpet.setOwner(activeChar); newpet.setOwner(activeChar);
newpet.addKnownObject(activeChar); newpet.addKnownObject(activeChar);
newpet.setFollowStatus(true); newpet.setFollowStatus(true);
newpet.followOwner(activeChar); newpet.followOwner(activeChar);
}, 900);
return 0; return 0;
} }

View File

@@ -23,10 +23,9 @@ import org.l2jmobius.gameserver.handler.IItemHandler;
import org.l2jmobius.gameserver.model.Skill; import org.l2jmobius.gameserver.model.Skill;
import org.l2jmobius.gameserver.model.actor.instance.ItemInstance; import org.l2jmobius.gameserver.model.actor.instance.ItemInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import org.l2jmobius.gameserver.network.serverpackets.MagicSkillUser; import org.l2jmobius.gameserver.network.serverpackets.MagicSkillUser;
import org.l2jmobius.gameserver.network.serverpackets.SetupGauge; import org.l2jmobius.gameserver.network.serverpackets.SetupGauge;
import org.l2jmobius.gameserver.network.serverpackets.StopMove; import org.l2jmobius.gameserver.threadpool.ThreadPool;
public class ScrollOfEscape implements IItemHandler public class ScrollOfEscape implements IItemHandler
{ {
@@ -38,30 +37,28 @@ public class ScrollOfEscape implements IItemHandler
@Override @Override
public int useItem(PlayerInstance activeChar, ItemInstance item) public int useItem(PlayerInstance activeChar, ItemInstance item)
{ {
final int[] townCords = MapRegionTable.getInstance().getClosestTownCords(activeChar); if (activeChar.isAllSkillsDisabled())
{
return 0;
}
activeChar.disableAllSkills();
activeChar.setTarget(activeChar); activeChar.setTarget(activeChar);
final Skill skill = SkillTable.getInstance().getInfo(1050, 1); final Skill skill = SkillTable.getInstance().getInfo(1050, 1);
final MagicSkillUser msk = new MagicSkillUser(activeChar, 1050, 1, 20000, 0); final MagicSkillUser msk = new MagicSkillUser(activeChar, 1050, 1, 20000, 0);
activeChar.sendPacket(msk); activeChar.sendPacket(msk);
activeChar.broadcastPacket(msk); activeChar.broadcastPacket(msk);
activeChar.sendPacket(new SetupGauge(SetupGauge.BLUE, skill.getSkillTime())); activeChar.sendPacket(new SetupGauge(SetupGauge.BLUE, skill.getSkillTime()));
if (skill.getSkillTime() > 200)
ThreadPool.schedule(() ->
{ {
try if (activeChar.isAllSkillsDisabled())
{ {
Thread.sleep(skill.getSkillTime() - 200); final int[] townCords = MapRegionTable.getInstance().getClosestTownCords(activeChar);
}
catch (InterruptedException e)
{
// empty catch block
}
}
final StopMove sm = new StopMove(activeChar);
activeChar.sendPacket(sm);
activeChar.broadcastPacket(sm);
final ActionFailed af = new ActionFailed();
activeChar.sendPacket(af);
activeChar.teleToLocation(townCords[0], townCords[1], townCords[2]); activeChar.teleToLocation(townCords[0], townCords[1], townCords[2]);
activeChar.enableAllSkills();
}
}, skill.getSkillTime() > 200 ? skill.getSkillTime() - 200 : 0);
return 1; return 1;
} }

View File

@@ -17,21 +17,16 @@
*/ */
package org.l2jmobius.gameserver.model; package org.l2jmobius.gameserver.model;
import java.util.Timer; import java.util.concurrent.ScheduledFuture;
import java.util.TimerTask;
import java.util.logging.Logger;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.threadpool.ThreadPool;
public class Potion extends WorldObject public class Potion extends WorldObject
{ {
private static final Logger _log = Logger.getLogger(Potion.class.getName());
Creature _target; Creature _target;
private static Timer _regenTimer = new Timer(true); private ScheduledFuture<?> _potionhpRegTask;
private PotionHpHealing _potionhpRegTask; private ScheduledFuture<?> _potionmpRegTask;
// private boolean _potionhpRegenActive;
private PotionMpHealing _potionmpRegTask;
// private boolean _potionmpRegenActive;
private int _seconds; private int _seconds;
private double _effect; private double _effect;
private int _duration; private int _duration;
@@ -41,27 +36,22 @@ public class Potion extends WorldObject
public Potion() public Potion()
{ {
_potionhpRegTask = new PotionHpHealing(_target);
_potionmpRegTask = new PotionMpHealing(_target);
_mpLock = new Object(); _mpLock = new Object();
_hpLock = new Object(); _hpLock = new Object();
} }
private void startPotionHpRegeneration(Creature activeChar) private void startPotionHpRegeneration(Creature activeChar)
{ {
_potionhpRegTask = new PotionHpHealing(activeChar); _potionhpRegTask = ThreadPool.scheduleAtFixedRate(new PotionHpHealing(activeChar), 1000, _seconds);
_regenTimer.schedule(_potionhpRegTask, 1000L, _seconds);
// this._potionhpRegenActive = true;
} }
public void stopPotionHpRegeneration() public void stopPotionHpRegeneration()
{ {
if (_potionhpRegTask != null) if (_potionhpRegTask != null)
{ {
_potionhpRegTask.cancel(); _potionhpRegTask.cancel(true);
} }
_potionhpRegTask = null; _potionhpRegTask = null;
// this._potionhpRegenActive = false;
} }
public void setCurrentHpPotion2(Creature activeChar) public void setCurrentHpPotion2(Creature activeChar)
@@ -149,19 +139,16 @@ public class Potion extends WorldObject
private void startPotionMpRegeneration(Creature activeChar) private void startPotionMpRegeneration(Creature activeChar)
{ {
_potionmpRegTask = new PotionMpHealing(activeChar); _potionmpRegTask = ThreadPool.scheduleAtFixedRate(new PotionMpHealing(activeChar), 1000, _seconds);
_regenTimer.schedule(_potionmpRegTask, 1000L, _seconds);
// this._potionmpRegenActive = true;
} }
public void stopPotionMpRegeneration() public void stopPotionMpRegeneration()
{ {
if (_potionmpRegTask != null) if (_potionmpRegTask != null)
{ {
_potionmpRegTask.cancel(); _potionmpRegTask.cancel(true);
} }
_potionmpRegTask = null; _potionmpRegTask = null;
// this._potionmpRegenActive = false;
} }
public void setCurrentMpPotion2(Creature activeChar) public void setCurrentMpPotion2(Creature activeChar)
@@ -199,7 +186,7 @@ public class Potion extends WorldObject
} }
} }
class PotionMpHealing extends TimerTask class PotionMpHealing implements Runnable
{ {
Creature _instance; Creature _instance;
@@ -210,8 +197,6 @@ public class Potion extends WorldObject
@Override @Override
public void run() public void run()
{
try
{ {
final Object object = _mpLock; final Object object = _mpLock;
synchronized (object) synchronized (object)
@@ -229,14 +214,9 @@ public class Potion extends WorldObject
} }
} }
} }
catch (Exception e)
{
_log.warning("error in mp potion task:" + e);
}
}
} }
class PotionHpHealing extends TimerTask class PotionHpHealing implements Runnable
{ {
Creature _instance; Creature _instance;
@@ -247,8 +227,6 @@ public class Potion extends WorldObject
@Override @Override
public void run() public void run()
{
try
{ {
final Object object = _hpLock; final Object object = _hpLock;
synchronized (object) synchronized (object)
@@ -266,11 +244,5 @@ public class Potion extends WorldObject
} }
} }
} }
catch (Exception e)
{
_log.warning("Error in hp potion task:" + e);
} }
}
}
} }

View File

@@ -18,14 +18,13 @@
package org.l2jmobius.gameserver.model; package org.l2jmobius.gameserver.model;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.gameserver.IdFactory; import org.l2jmobius.gameserver.IdFactory;
import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
import org.l2jmobius.gameserver.model.actor.instance.NpcInstance; import org.l2jmobius.gameserver.model.actor.instance.NpcInstance;
import org.l2jmobius.gameserver.templates.Npc; import org.l2jmobius.gameserver.templates.Npc;
import org.l2jmobius.gameserver.threadpool.ThreadPool;
import org.l2jmobius.util.Rnd; import org.l2jmobius.util.Rnd;
public class Spawn public class Spawn
@@ -45,7 +44,6 @@ public class Spawn
private int _randomy; private int _randomy;
private int _heading; private int _heading;
private int _respawnDelay; private int _respawnDelay;
private static Timer _spawnTimer = new Timer(true);
private final Constructor<?> _constructor; private final Constructor<?> _constructor;
public Spawn(Npc mobTemplate) throws SecurityException, ClassNotFoundException public Spawn(Npc mobTemplate) throws SecurityException, ClassNotFoundException
@@ -161,8 +159,7 @@ public class Spawn
if ((_scheduledCount + _currentCount) < _maximumCount) if ((_scheduledCount + _currentCount) < _maximumCount)
{ {
++_scheduledCount; ++_scheduledCount;
final SpawnTask task = new SpawnTask(npcId); ThreadPool.schedule(new SpawnTask(npcId), _respawnDelay);
_spawnTimer.schedule(task, _respawnDelay);
} }
} }
@@ -256,7 +253,7 @@ public class Spawn
_respawnDelay = i * 1000; _respawnDelay = i * 1000;
} }
class SpawnTask extends TimerTask class SpawnTask implements Runnable
{ {
NpcInstance _instance; NpcInstance _instance;
int _objId; int _objId;
@@ -268,15 +265,8 @@ public class Spawn
@Override @Override
public void run() public void run()
{
try
{ {
doSpawn(); doSpawn();
}
catch (Exception e)
{
e.printStackTrace();
}
_scheduledCount--; _scheduledCount--;
} }
} }

View File

@@ -21,9 +21,7 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Timer; import java.util.concurrent.ScheduledFuture;
import java.util.TimerTask;
import java.util.logging.Logger;
import org.l2jmobius.Config; import org.l2jmobius.Config;
import org.l2jmobius.gameserver.data.ItemTable; import org.l2jmobius.gameserver.data.ItemTable;
@@ -38,18 +36,15 @@ import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.network.serverpackets.DropItem; import org.l2jmobius.gameserver.network.serverpackets.DropItem;
import org.l2jmobius.gameserver.templates.Npc; import org.l2jmobius.gameserver.templates.Npc;
import org.l2jmobius.gameserver.templates.Weapon; import org.l2jmobius.gameserver.templates.Weapon;
import org.l2jmobius.gameserver.threadpool.ThreadPool;
import org.l2jmobius.util.Rnd; import org.l2jmobius.util.Rnd;
public class Attackable extends NpcInstance public class Attackable extends NpcInstance
{ {
private static Logger _log = Logger.getLogger(Attackable.class.getName());
// private int _moveRadius; // private int _moveRadius;
private boolean _active; private boolean _active;
private AITask _currentAiTask; private ScheduledFuture<?> _currentAiTask;
private AIAttackeTask _currentAIAttackTask; private ScheduledFuture<?> _currentAIAttackTask;
private static Timer _aiTimer = new Timer(true);
private static Timer _attackTimer = new Timer(true);
private final Map<WorldObject, Integer> _aggroList = new HashMap<>(); private final Map<WorldObject, Integer> _aggroList = new HashMap<>();
private Weapon _dummyWeapon; private Weapon _dummyWeapon;
private boolean _sweepActive; private boolean _sweepActive;
@@ -89,16 +84,14 @@ public class Attackable extends NpcInstance
if (_active) if (_active)
{ {
final int wait = (10 + Rnd.get(120)) * 1000; final int wait = (10 + Rnd.get(120)) * 1000;
_currentAiTask = new AITask(this); _currentAiTask = ThreadPool.schedule(new AITask(this), wait);
_aiTimer.schedule(_currentAiTask, wait);
} }
} }
protected void startRandomWalking() protected void startRandomWalking()
{ {
_currentAiTask = new AITask(this);
final int wait = (10 + Rnd.get(120)) * 1000; final int wait = (10 + Rnd.get(120)) * 1000;
_aiTimer.schedule(_currentAiTask, wait); _currentAiTask = ThreadPool.schedule(new AITask(this), wait);
setCurrentState(CreatureState.RANDOM_WALK); setCurrentState(CreatureState.RANDOM_WALK);
} }
@@ -106,8 +99,7 @@ public class Attackable extends NpcInstance
{ {
if ((_currentAIAttackTask == null) && (getTarget() == null)) if ((_currentAIAttackTask == null) && (getTarget() == null))
{ {
_currentAIAttackTask = new AIAttackeTask(this); _currentAIAttackTask = ThreadPool.scheduleAtFixedRate(new AIAttackeTask(this), 100, 1000);
_attackTimer.scheduleAtFixedRate(_currentAIAttackTask, 100L, 1000L);
} }
} }
@@ -320,7 +312,7 @@ public class Attackable extends NpcInstance
{ {
if (_currentAiTask != null) if (_currentAiTask != null)
{ {
_currentAiTask.cancel(); _currentAiTask.cancel(true);
_currentAiTask = null; _currentAiTask = null;
} }
} }
@@ -334,7 +326,7 @@ public class Attackable extends NpcInstance
{ {
if (_currentAIAttackTask != null) if (_currentAIAttackTask != null)
{ {
_currentAIAttackTask.cancel(); _currentAIAttackTask.cancel(true);
_currentAIAttackTask = null; _currentAIAttackTask = null;
} }
} }
@@ -401,7 +393,7 @@ public class Attackable extends NpcInstance
_sweepActive = sweepActive; _sweepActive = sweepActive;
} }
class AIAttackeTask extends TimerTask class AIAttackeTask implements Runnable
{ {
Creature _instance; Creature _instance;
@@ -412,8 +404,6 @@ public class Attackable extends NpcInstance
@Override @Override
public void run() public void run()
{
try
{ {
if (!isInCombat()) if (!isInCombat())
{ {
@@ -425,7 +415,7 @@ public class Attackable extends NpcInstance
} }
if (_currentAiTask != null) if (_currentAiTask != null)
{ {
_currentAiTask.cancel(); _currentAiTask.cancel(true);
} }
setTarget(player); setTarget(player);
startAttack(player); startAttack(player);
@@ -433,17 +423,12 @@ public class Attackable extends NpcInstance
} }
else if (_currentAIAttackTask != null) else if (_currentAIAttackTask != null)
{ {
_currentAIAttackTask.cancel(); _currentAIAttackTask.cancel(true);
}
}
catch (Exception e)
{
_log.severe(e.toString());
} }
} }
} }
class AITask extends TimerTask class AITask implements Runnable
{ {
Creature _instance; Creature _instance;
@@ -454,18 +439,10 @@ public class Attackable extends NpcInstance
@Override @Override
public void run() public void run()
{
try
{ {
final int x1 = (getX() + Rnd.get(500)) - 250; final int x1 = (getX() + Rnd.get(500)) - 250;
final int y1 = (getY() + Rnd.get(500)) - 250; final int y1 = (getY() + Rnd.get(500)) - 250;
moveTo(x1, y1, getZ(), 0); moveTo(x1, y1, getZ(), 0);
} }
catch (Exception e)
{
_log.severe(e.toString());
} }
}
}
} }

View File

@@ -21,8 +21,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.Timer; import java.util.concurrent.ScheduledFuture;
import java.util.TimerTask;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.gameserver.enums.CreatureState; import org.l2jmobius.gameserver.enums.CreatureState;
@@ -47,6 +46,7 @@ import org.l2jmobius.gameserver.network.serverpackets.StopMove;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.network.serverpackets.TeleportToLocation; import org.l2jmobius.gameserver.network.serverpackets.TeleportToLocation;
import org.l2jmobius.gameserver.templates.Weapon; import org.l2jmobius.gameserver.templates.Weapon;
import org.l2jmobius.gameserver.threadpool.ThreadPool;
import org.l2jmobius.util.Rnd; import org.l2jmobius.util.Rnd;
public abstract class Creature extends WorldObject public abstract class Creature extends WorldObject
@@ -54,29 +54,20 @@ public abstract class Creature extends WorldObject
private static final Logger _log = Logger.getLogger(Creature.class.getName()); private static final Logger _log = Logger.getLogger(Creature.class.getName());
public long serialVersionUID = 305402420L; public long serialVersionUID = 305402420L;
private final List<Creature> _statusListener = new ArrayList<>(); private final List<Creature> _statusListener = new ArrayList<>();
private static Timer _attackTimer = new Timer(true); private ScheduledFuture<?> _attackTask;
private AttackTask _currentAttackTask; private ScheduledFuture<?> _hitTask;
private static Timer _hitTimer = new Timer(true); private ScheduledFuture<?> _regenTask;
private HitTask _currentHitTask;
private static Timer _regenTimer = new Timer(true);
private MpRegenTask _mpRegTask;
private final Object _mpLock = new Object(); private final Object _mpLock = new Object();
private boolean _mpRegenActive; private boolean _mpRegenActive;
private HpRegenTask _hpRegTask = new HpRegenTask(this);
private final Object _hpLock = new Object(); private final Object _hpLock = new Object();
private boolean _hpRegenActive; private boolean _hpRegenActive;
// private static Timer _bowAttack = new Timer(true);
private int _moveOffset; private int _moveOffset;
private float _effectiveSpeed; private float _effectiveSpeed;
// private float _dx;
// private float _dy;
// private float _dz;
private long _moveStartTime; private long _moveStartTime;
private double _xAddition; private double _xAddition;
private double _yAddition; private double _yAddition;
private long _timeToTarget; private long _timeToTarget;
private static Timer _moveTimer = new Timer(true); private ScheduledFuture<?> _moveTask;
private ArriveTask _currentMoveTask;
private String _name; private String _name;
private int _level = 1; private int _level = 1;
private int _maxHp; private int _maxHp;
@@ -246,10 +237,10 @@ public abstract class Creature extends WorldObject
public void stopMove() public void stopMove()
{ {
if (_currentMoveTask != null) if (_moveTask != null)
{ {
_currentMoveTask.cancel(); _moveTask.cancel(true);
_currentMoveTask = null; _moveTask = null;
} }
setX(getX()); setX(getX());
setY(getY()); setY(getY());
@@ -341,16 +332,18 @@ public abstract class Creature extends WorldObject
{ {
if (_hpRegenActive) if (_hpRegenActive)
{ {
_hpRegTask.cancel(); if (_regenTask != null)
_hpRegTask = null; {
_regenTask.cancel(true);
_regenTask = null;
}
_hpRegenActive = false; _hpRegenActive = false;
} }
} }
private void startHpRegeneration() private void startHpRegeneration()
{ {
_hpRegTask = new HpRegenTask(this); _regenTask = ThreadPool.scheduleAtFixedRate(new HpRegenTask(this), 3000, 3000);
_regenTimer.scheduleAtFixedRate(_hpRegTask, 3000L, 3000L);
_hpRegenActive = true; _hpRegenActive = true;
} }
@@ -376,8 +369,7 @@ public abstract class Creature extends WorldObject
private void startMpRegeneration() private void startMpRegeneration()
{ {
_mpRegTask = new MpRegenTask(this); _regenTask = ThreadPool.scheduleAtFixedRate(new MpRegenTask(this), 3000, 3000);
_regenTimer.scheduleAtFixedRate(_mpRegTask, 3000L, 3000L);
_mpRegenActive = true; _mpRegenActive = true;
} }
@@ -385,8 +377,8 @@ public abstract class Creature extends WorldObject
{ {
if (_mpRegenActive) if (_mpRegenActive)
{ {
_mpRegTask.cancel(); _regenTask.cancel(true);
_mpRegTask = null; _regenTask = null;
_mpRegenActive = false; _mpRegenActive = false;
} }
} }
@@ -807,17 +799,17 @@ public abstract class Creature extends WorldObject
_currentHp = 0.0; _currentHp = 0.0;
stopHpRegeneration(); stopHpRegeneration();
stopMpRegeneration(); stopMpRegeneration();
if (_currentAttackTask != null) if (_attackTask != null)
{ {
_currentAttackTask.cancel(); _attackTask.cancel(true);
} }
if (_currentHitTask != null) if (_hitTask != null)
{ {
_currentHitTask.cancel(); _hitTask.cancel(true);
} }
if (_currentMoveTask != null) if (_moveTask != null)
{ {
_currentMoveTask.cancel(); _moveTask.cancel(true);
} }
broadcastStatusUpdate(); broadcastStatusUpdate();
final StopMove stop = new StopMove(this); final StopMove stop = new StopMove(this);
@@ -840,7 +832,7 @@ public abstract class Creature extends WorldObject
{ {
_moveOffset = offset; _moveOffset = offset;
final double distance = getDistance(x, y); final double distance = getDistance(x, y);
if ((distance > 0.0) || (offset > 0)) if ((distance > 0) || (offset > 0))
{ {
if (offset == 0) if (offset == 0)
{ {
@@ -896,9 +888,7 @@ public abstract class Creature extends WorldObject
} }
if ((getPawnTarget() != null) && (distance <= getAttackRange()) && (getCurrentState() == CreatureState.FOLLOW)) if ((getPawnTarget() != null) && (distance <= getAttackRange()) && (getCurrentState() == CreatureState.FOLLOW))
{ {
final ArriveTask newMoveTask = new ArriveTask(this); _moveTask = ThreadPool.schedule(new ArriveTask(this), 3000);
_moveTimer.schedule(newMoveTask, 3000L);
_currentMoveTask = newMoveTask;
return; return;
} }
int dx = x - getX(); int dx = x - getX();
@@ -945,48 +935,46 @@ public abstract class Creature extends WorldObject
{ {
if (getCurrentState() == CreatureState.INTERACT) if (getCurrentState() == CreatureState.INTERACT)
{ {
_moveTimer.schedule(newMoveTask, _timeToTarget); _moveTask = ThreadPool.schedule(newMoveTask, _timeToTarget);
_currentMoveTask = newMoveTask;
setIsMoving(true); setIsMoving(true);
return; return;
} }
if ((_timeToTarget < 2000L) && (distance > getAttackRange())) if ((_timeToTarget < 2000L) && (distance > getAttackRange()))
{ {
_moveTimer.schedule(newMoveTask, _timeToTarget); _moveTask = ThreadPool.schedule(newMoveTask, _timeToTarget);
} }
else if (getPawnTarget().isMoving()) else if (getPawnTarget().isMoving())
{ {
_moveTimer.schedule(newMoveTask, 2000L); _moveTask = ThreadPool.schedule(newMoveTask, 2000);
} }
else else
{ {
_moveTimer.schedule(newMoveTask, 3000L); _moveTask = ThreadPool.schedule(newMoveTask, 3000);
} }
} }
else else
{ {
_moveTimer.schedule(newMoveTask, _timeToTarget); _moveTask = ThreadPool.schedule(newMoveTask, _timeToTarget);
} }
_currentMoveTask = newMoveTask;
setIsMoving(true); setIsMoving(true);
} }
} }
protected void stopHitTask() protected void stopHitTask()
{ {
if (_currentHitTask != null) if (_hitTask != null)
{ {
_currentHitTask.cancel(); _hitTask.cancel(true);
_currentHitTask = null; _hitTask = null;
} }
} }
protected void stopAttackTask() protected void stopAttackTask()
{ {
if (_currentAttackTask != null) if (_attackTask != null)
{ {
_currentAttackTask.cancel(); _attackTask.cancel(true);
_currentAttackTask = null; _attackTask = null;
} }
} }
@@ -1073,20 +1061,19 @@ public abstract class Creature extends WorldObject
protected void startCombat() protected void startCombat()
{ {
if (_currentAttackTask == null) if (_attackTask == null)
{ {
_currentAttackTask = new AttackTask(this); _attackTask = ThreadPool.schedule(new AttackTask(this), 0);
_attackTimer.schedule(_currentAttackTask, 0L);
}
else
{
_log.warning("Multiple attacks want to start in parallel. Prevented.");
} }
// else
// {
// _log.warning("Multiple attacks want to start in parallel. Prevented.");
// }
} }
private void onAttackTimer() private void onAttackTimer()
{ {
_currentAttackTask = null; _attackTask = null;
final Creature target = (Creature) _attackTarget; final Creature target = (Creature) _attackTarget;
if (isDead() || (target == null) || target.isDead() || ((getCurrentState() != CreatureState.ATTACKING) && (getCurrentState() != CreatureState.CASTING)) || !target.knownsObject(this) || !knownsObject(target)) if (isDead() || (target == null) || target.isDead() || ((getCurrentState() != CreatureState.ATTACKING) && (getCurrentState() != CreatureState.CASTING)) || !target.knownsObject(this) || !knownsObject(target))
{ {
@@ -1166,8 +1153,8 @@ public abstract class Creature extends WorldObject
} }
if (isUsingDualWeapon()) if (isUsingDualWeapon())
{ {
_hitTimer.schedule(new HitTask(this, target, damage, crit, miss, false), calculateHitSpeed(weaponItem, 1)); _hitTask = ThreadPool.schedule(new HitTask(this, target, damage, crit, miss, false), calculateHitSpeed(weaponItem, 1));
_hitTimer.schedule(new HitTask(this, target, damage, crit, miss, false), calculateHitSpeed(weaponItem, 2)); _hitTask = ThreadPool.schedule(new HitTask(this, target, damage, crit, miss, false), calculateHitSpeed(weaponItem, 2));
} }
else if (getActiveWeapon().getWeaponType() == 5) else if (getActiveWeapon().getWeaponType() == 5)
{ {
@@ -1183,11 +1170,11 @@ public abstract class Creature extends WorldObject
reduceCurrentMp(weaponItem.getMpConsume()); reduceCurrentMp(weaponItem.getMpConsume());
sendPacket(new SystemMessage(SystemMessage.GETTING_READY_TO_SHOOT_AN_ARROW)); sendPacket(new SystemMessage(SystemMessage.GETTING_READY_TO_SHOOT_AN_ARROW));
sendPacket(new SetupGauge(SetupGauge.RED, calculateAttackSpeed(weaponItem) * 2)); sendPacket(new SetupGauge(SetupGauge.RED, calculateAttackSpeed(weaponItem) * 2));
_hitTimer.schedule(new HitTask(this, target, damage, crit, miss, false), calculateHitSpeed(weaponItem, 1)); _hitTask = ThreadPool.schedule(new HitTask(this, target, damage, crit, miss, false), calculateHitSpeed(weaponItem, 1));
} }
else else
{ {
_hitTimer.schedule(new HitTask(this, target, damage, crit, miss, false), calculateHitSpeed(weaponItem, 1)); _hitTask = ThreadPool.schedule(new HitTask(this, target, damage, crit, miss, false), calculateHitSpeed(weaponItem, 1));
} }
final Attack attack = new Attack(getObjectId(), _attackTarget.getObjectId(), damage, miss, crit, soulShotUse, getX(), getY(), getZ()); final Attack attack = new Attack(getObjectId(), _attackTarget.getObjectId(), damage, miss, crit, soulShotUse, getX(), getY(), getZ());
setActiveSoulshotGrade(0); setActiveSoulshotGrade(0);
@@ -1224,7 +1211,7 @@ public abstract class Creature extends WorldObject
if (getActiveWeapon().getWeaponType() == 5) if (getActiveWeapon().getWeaponType() == 5)
{ {
reduceArrowCount(); reduceArrowCount();
_attackTimer.schedule(new AttackTask(this), calculateAttackSpeed(getActiveWeapon())); _attackTask = ThreadPool.schedule(new AttackTask(this), calculateAttackSpeed(getActiveWeapon()));
} }
displayHitMessage(damage, crit, miss); displayHitMessage(damage, crit, miss);
if (!miss) if (!miss)
@@ -1237,7 +1224,7 @@ public abstract class Creature extends WorldObject
{ {
_2ndHit = false; _2ndHit = false;
_currentlyAttacking = false; _currentlyAttacking = false;
_attackTimer.schedule(new AttackTask(this), calculateAttackSpeed(getActiveWeapon())); _attackTask = ThreadPool.schedule(new AttackTask(this), calculateAttackSpeed(getActiveWeapon()));
} }
else else
{ {
@@ -1247,7 +1234,7 @@ public abstract class Creature extends WorldObject
if (!isUsingDualWeapon()) if (!isUsingDualWeapon())
{ {
_currentlyAttacking = false; _currentlyAttacking = false;
_attackTimer.schedule(new AttackTask(this), calculateAttackSpeed(getActiveWeapon())); _attackTask = ThreadPool.schedule(new AttackTask(this), calculateAttackSpeed(getActiveWeapon()));
} }
} }
} }
@@ -1389,11 +1376,11 @@ public abstract class Creature extends WorldObject
_currentlyAttacking = status; _currentlyAttacking = status;
} }
protected void enableAllSkills() public void enableAllSkills()
{ {
} }
public class DecayTask extends TimerTask public class DecayTask implements Runnable
{ {
Creature _instance; Creature _instance;
@@ -1409,7 +1396,7 @@ public abstract class Creature extends WorldObject
} }
} }
class MpRegenTask extends TimerTask class MpRegenTask implements Runnable
{ {
Creature _instance; Creature _instance;
@@ -1420,8 +1407,6 @@ public abstract class Creature extends WorldObject
@Override @Override
public void run() public void run()
{
try
{ {
final Object object = _mpLock; final Object object = _mpLock;
synchronized (object) synchronized (object)
@@ -1433,14 +1418,9 @@ public abstract class Creature extends WorldObject
} }
} }
} }
catch (Exception e)
{
_log.severe(e.toString());
}
}
} }
class HpRegenTask extends TimerTask class HpRegenTask implements Runnable
{ {
Creature _instance; Creature _instance;
@@ -1451,8 +1431,6 @@ public abstract class Creature extends WorldObject
@Override @Override
public void run() public void run()
{
try
{ {
synchronized (_hpLock) synchronized (_hpLock)
{ {
@@ -1467,14 +1445,9 @@ public abstract class Creature extends WorldObject
} }
} }
} }
catch (Exception e)
{
_log.severe(e.toString());
}
}
} }
class HitTask extends TimerTask class HitTask implements Runnable
{ {
Creature _instance; Creature _instance;
Creature _target; Creature _target;
@@ -1495,19 +1468,12 @@ public abstract class Creature extends WorldObject
@Override @Override
public void run() public void run()
{
try
{ {
_instance.onHitTimer(_target, _damage, _crit, _miss, _soulshot); _instance.onHitTimer(_target, _damage, _crit, _miss, _soulshot);
} }
catch (Exception e)
{
_log.severe(e.toString());
}
}
} }
class AttackTask extends TimerTask class AttackTask implements Runnable
{ {
Creature _instance; Creature _instance;
@@ -1518,19 +1484,12 @@ public abstract class Creature extends WorldObject
@Override @Override
public void run() public void run()
{
try
{ {
_instance.onAttackTimer(); _instance.onAttackTimer();
} }
catch (Exception e)
{
_log.severe(e.toString());
}
}
} }
class ArriveTask extends TimerTask class ArriveTask implements Runnable
{ {
Creature _instance; Creature _instance;
@@ -1541,16 +1500,9 @@ public abstract class Creature extends WorldObject
@Override @Override
public void run() public void run()
{
try
{ {
_instance.onTargetReached(); _instance.onTargetReached();
} _moveTask = null;
catch (Exception e)
{
_log.severe(e.toString());
}
_currentMoveTask = null;
} }
} }
@@ -1564,13 +1516,9 @@ public abstract class Creature extends WorldObject
setX(x); setX(x);
setY(y); setY(y);
setZ(z); setZ(z);
try ThreadPool.schedule(() ->
{ {
Thread.sleep(2000);
}
catch (InterruptedException e)
{
}
World.getInstance().addVisibleObject(this); World.getInstance().addVisibleObject(this);
}, 2000);
} }
} }

View File

@@ -19,7 +19,7 @@ package org.l2jmobius.gameserver.model.actor.instance;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.util.Timer; import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.Config; import org.l2jmobius.Config;
@@ -36,6 +36,7 @@ import org.l2jmobius.gameserver.network.serverpackets.SetToLocation;
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate; import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
import org.l2jmobius.gameserver.templates.Npc; import org.l2jmobius.gameserver.templates.Npc;
import org.l2jmobius.gameserver.templates.Weapon; import org.l2jmobius.gameserver.templates.Weapon;
import org.l2jmobius.gameserver.threadpool.ThreadPool;
public class NpcInstance extends Creature public class NpcInstance extends Creature
{ {
@@ -49,8 +50,7 @@ public class NpcInstance extends Creature
private int _spReward; private int _spReward;
private int _attackRange; private int _attackRange;
private boolean _aggressive; private boolean _aggressive;
private Creature.DecayTask _decayTask; private ScheduledFuture<?> _decayTask;
private static Timer _decayTimer = new Timer(true);
private Spawn _spawn; private Spawn _spawn;
public NpcInstance(Npc template) public NpcInstance(Npc template)
@@ -260,32 +260,19 @@ public class NpcInstance extends Creature
} }
else else
{ {
FileInputStream fis = null;
try try
{ {
fis = new FileInputStream(file); FileInputStream fis = new FileInputStream(file);
final byte[] raw = new byte[fis.available()]; final byte[] raw = new byte[fis.available()];
fis.read(raw); fis.read(raw);
final String content = new String(raw, "UTF-8"); final String content = new String(raw, "UTF-8");
insertObjectIdAndShowChatWindow(player, content); insertObjectIdAndShowChatWindow(player, content);
fis.close();
} }
catch (Exception e) catch (Exception e)
{ {
_log.warning("problem with npc text " + e); _log.warning("problem with npc text " + e);
} }
finally
{
try
{
if (fis != null)
{
fis.close();
}
}
catch (Exception e1)
{
}
}
} }
player.sendPacket(new ActionFailed()); player.sendPacket(new ActionFailed());
} }
@@ -330,10 +317,9 @@ public class NpcInstance extends Creature
final NpcInstance NpcInstance = this; final NpcInstance NpcInstance = this;
synchronized (NpcInstance) synchronized (NpcInstance)
{ {
if (_decayTask == null) if ((_decayTask == null) || _decayTask.isCancelled() || _decayTask.isDone())
{ {
_decayTask = new Creature.DecayTask(this); _decayTask = ThreadPool.schedule(new Creature.DecayTask(this), 7000);
_decayTimer.schedule(_decayTask, 7000L);
} }
} }
} }

View File

@@ -17,7 +17,7 @@
*/ */
package org.l2jmobius.gameserver.model.actor.instance; package org.l2jmobius.gameserver.model.actor.instance;
import java.util.Timer; import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.gameserver.data.ExperienceTable; import org.l2jmobius.gameserver.data.ExperienceTable;
@@ -47,6 +47,7 @@ import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.network.serverpackets.UserInfo; import org.l2jmobius.gameserver.network.serverpackets.UserInfo;
import org.l2jmobius.gameserver.templates.Npc; import org.l2jmobius.gameserver.templates.Npc;
import org.l2jmobius.gameserver.templates.Weapon; import org.l2jmobius.gameserver.templates.Weapon;
import org.l2jmobius.gameserver.threadpool.ThreadPool;
public class PetInstance extends Creature public class PetInstance extends Creature
{ {
@@ -64,8 +65,7 @@ public class PetInstance extends Creature
private final Npc _template; private final Npc _template;
private int _attackRange = 36; private int _attackRange = 36;
private boolean _follow = true; private boolean _follow = true;
private Creature.DecayTask _decayTask; private ScheduledFuture<?> _decayTask;
private static Timer _decayTimer = new Timer(true);
private int _controlItemId; private int _controlItemId;
private int _nextLevel; private int _nextLevel;
private int _lastLevel; private int _lastLevel;
@@ -403,10 +403,9 @@ public class PetInstance extends Creature
final PetInstance PetInstance = this; final PetInstance PetInstance = this;
synchronized (PetInstance) synchronized (PetInstance)
{ {
if (_decayTask == null) if ((_decayTask == null) || _decayTask.isCancelled() || _decayTask.isDone())
{ {
_decayTask = new Creature.DecayTask(this); _decayTask = ThreadPool.schedule(new Creature.DecayTask(this), 7000);
_decayTimer.schedule(_decayTask, 10000L);
} }
} }
} }

View File

@@ -21,9 +21,9 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.Config; import org.l2jmobius.Config;
@@ -80,16 +80,15 @@ import org.l2jmobius.gameserver.templates.Armor;
import org.l2jmobius.gameserver.templates.CharTemplate; import org.l2jmobius.gameserver.templates.CharTemplate;
import org.l2jmobius.gameserver.templates.Item; import org.l2jmobius.gameserver.templates.Item;
import org.l2jmobius.gameserver.templates.Weapon; import org.l2jmobius.gameserver.templates.Weapon;
import org.l2jmobius.gameserver.threadpool.ThreadPool;
import org.l2jmobius.util.Rnd; import org.l2jmobius.util.Rnd;
public class PlayerInstance extends Creature public class PlayerInstance extends Creature
{ {
private static Logger _log = Logger.getLogger(PlayerInstance.class.getName()); private static Logger _log = Logger.getLogger(PlayerInstance.class.getName());
private static Timer _magicUseTimer = new Timer(true);
private static Timer _enableSkillTimer = new Timer(true); private final Map<Integer, Boolean> _disabledSkills = new ConcurrentHashMap<>();
private static Timer _enableAllSkillsTimer = new Timer(true); private volatile boolean _allSkillsDisabled = false;
private final Map<Integer, Boolean> _disabledSkills = new HashMap<>();
private boolean _allSkillsDisabled = false;
private Connection _netConnection; private Connection _netConnection;
private int _charId = 199546; private int _charId = 199546;
private int _canCraft = 0; private int _canCraft = 0;
@@ -100,7 +99,7 @@ public class PlayerInstance extends Creature
private int _pkKills; private int _pkKills;
private int _pvpFlag = 0; private int _pvpFlag = 0;
private long _lastPvpTime; private long _lastPvpTime;
private static Timer _pvpTimer = null; private ScheduledFuture<?> _pvpTask;
private int _maxLoad; private int _maxLoad;
private int _race; private int _race;
private int _classId; private int _classId;
@@ -135,7 +134,7 @@ public class PlayerInstance extends Creature
private long _uptime; private long _uptime;
public byte updateKnownCounter = 0; public byte updateKnownCounter = 0;
private Creature _interactTarget; private Creature _interactTarget;
private static Timer _waterTimer = null; private ScheduledFuture<?> _waterTask;
public Skill addSkill(Skill newSkill) public Skill addSkill(Skill newSkill)
{ {
@@ -417,10 +416,10 @@ public class PlayerInstance extends Creature
private void stopPvPFlag() private void stopPvPFlag()
{ {
if (_pvpTimer != null) if (_pvpTask != null)
{ {
_pvpTimer.cancel(); _pvpTask.cancel(true);
_pvpTimer = null; _pvpTask = null;
} }
updatePvPFlag(0); updatePvPFlag(0);
} }
@@ -433,10 +432,9 @@ public class PlayerInstance extends Creature
} }
if (value == 1) if (value == 1)
{ {
if (_pvpTimer == null) if (_pvpTask == null)
{ {
_pvpTimer = new Timer(); _pvpTask = ThreadPool.scheduleAtFixedRate(new pvpTask(), 1000, 1000);
_pvpTimer.schedule(new pvpTask(), 1000, 1000);
} }
_lastPvpTime = System.currentTimeMillis() + 30000; _lastPvpTime = System.currentTimeMillis() + 30000;
} }
@@ -450,12 +448,10 @@ public class PlayerInstance extends Creature
broadcastPacket(userInfo); broadcastPacket(userInfo);
} }
class pvpTask extends TimerTask class pvpTask implements Runnable
{ {
@Override @Override
public void run() public void run()
{
try
{ {
final long currentTime = System.currentTimeMillis(); final long currentTime = System.currentTimeMillis();
if (currentTime > _lastPvpTime) if (currentTime > _lastPvpTime)
@@ -467,10 +463,6 @@ public class PlayerInstance extends Creature
updatePvPFlag(2); updatePvPFlag(2);
} }
} }
catch (Throwable e)
{
}
}
} }
public boolean isEnemy(WorldObject target) public boolean isEnemy(WorldObject target)
@@ -1558,9 +1550,62 @@ public class PlayerInstance extends Creature
{ {
disableSkill(skill.getId(), true); disableSkill(skill.getId(), true);
disableAllSkills(); disableAllSkills();
_magicUseTimer.schedule(new MagicUseTask(target, skill), skill.getHitTime()); ThreadPool.schedule(new MagicUseTask(target, skill), skill.getHitTime());
_enableSkillTimer.schedule(new EnableSkill(skill.getId()), skill.getReuseDelay()); ThreadPool.schedule(new EnableSkill(skill.getId()), skill.getReuseDelay());
_enableAllSkillsTimer.schedule(new EnableAllSkills(skill), skill.getSkillTime()); ThreadPool.schedule(new EnableAllSkills(skill), skill.getSkillTime());
}
}
private class MagicUseTask implements Runnable
{
Creature _target;
Skill _skill;
public MagicUseTask(Creature target, Skill skill)
{
_target = target;
_skill = skill;
}
@Override
public void run()
{
onMagicUseTimer(_target, _skill);
}
}
private class EnableSkill implements Runnable
{
int _skillId;
public EnableSkill(int skillId)
{
_skillId = skillId;
}
@Override
public void run()
{
disableSkill(_skillId, false);
}
}
private class EnableAllSkills implements Runnable
{
Skill _skill;
public EnableAllSkills(Skill skill)
{
_skill = skill;
}
@Override
public void run()
{
if (getSkill() == _skill)
{
enableAllSkills();
}
} }
} }
@@ -1678,14 +1723,16 @@ public class PlayerInstance extends Creature
public boolean isSkillDisabled(int skillId) public boolean isSkillDisabled(int skillId)
{ {
try if (!_disabledSkills.containsKey(skillId))
{
return _disabledSkills.get(skillId);
}
catch (NullPointerException e)
{ {
return false; return false;
} }
return _disabledSkills.get(skillId);
}
public boolean isAllSkillsDisabled()
{
return _allSkillsDisabled;
} }
public void disableAllSkills() public void disableAllSkills()
@@ -1694,7 +1741,7 @@ public class PlayerInstance extends Creature
} }
@Override @Override
protected void enableAllSkills() public void enableAllSkills()
{ {
_allSkillsDisabled = false; _allSkillsDisabled = false;
} }
@@ -1763,66 +1810,6 @@ public class PlayerInstance extends Creature
broadcastPacket(msc); broadcastPacket(msc);
} }
class EnableAllSkills extends TimerTask
{
Skill _skill;
public EnableAllSkills(Skill skill)
{
_skill = skill;
}
@Override
public void run()
{
if (getSkill() == _skill)
{
enableAllSkills();
}
}
}
class EnableSkill extends TimerTask
{
int _skillId;
public EnableSkill(int skillId)
{
_skillId = skillId;
}
@Override
public void run()
{
disableSkill(_skillId, false);
}
}
class MagicUseTask extends TimerTask
{
Creature _target;
Skill _skill;
public MagicUseTask(Creature target, Skill skill)
{
_target = target;
_skill = skill;
}
@Override
public void run()
{
try
{
onMagicUseTimer(_target, _skill);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public void checkWaterState() public void checkWaterState()
{ {
// Water level. // Water level.
@@ -1859,30 +1846,29 @@ public class PlayerInstance extends Creature
public boolean isInWater() public boolean isInWater()
{ {
return _waterTimer != null; return _waterTask != null;
} }
private void startWaterTask() private void startWaterTask()
{ {
if ((_waterTimer == null) && !isDead()) if ((_waterTask == null) && !isDead())
{ {
_waterTimer = new Timer(); _waterTask = ThreadPool.scheduleAtFixedRate(new waterTask(this), 86000, 1000);
_waterTimer.schedule(new waterTask(this), 86000, 1000);
sendPacket(new SetupGauge(SetupGauge.CYAN, 86000)); sendPacket(new SetupGauge(SetupGauge.CYAN, 86000));
} }
} }
private void stopWaterTask() private void stopWaterTask()
{ {
if (_waterTimer != null) if (_waterTask != null)
{ {
_waterTimer.cancel(); _waterTask.cancel(true);
_waterTimer = null; _waterTask = null;
sendPacket(new SetupGauge(SetupGauge.CYAN, 0)); sendPacket(new SetupGauge(SetupGauge.CYAN, 0));
} }
} }
class waterTask extends TimerTask class waterTask implements Runnable
{ {
private final PlayerInstance _player; private final PlayerInstance _player;
@@ -1893,8 +1879,6 @@ public class PlayerInstance extends Creature
@Override @Override
public void run() public void run()
{
try
{ {
int reduceHp = (int) (getMaxHp() / 100.0); int reduceHp = (int) (getMaxHp() / 100.0);
if (reduceHp < 1) if (reduceHp < 1)
@@ -1907,10 +1891,6 @@ public class PlayerInstance extends Creature
sm.addNumber(reduceHp); sm.addNumber(reduceHp);
sendPacket(sm); sendPacket(sm);
} }
catch (Throwable e)
{
}
}
} }
@Override @Override

View File

@@ -0,0 +1,51 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.l2jmobius.gameserver.threadpool;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.logging.Logger;
/**
* @author NB4L1
*/
public class RejectedExecutionHandlerImpl implements RejectedExecutionHandler
{
private static final Logger LOGGER = Logger.getLogger(RejectedExecutionHandlerImpl.class.getName());
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
{
if (executor.isShutdown())
{
return;
}
LOGGER.warning(r + " from " + executor + " " + new RejectedExecutionException());
if (Thread.currentThread().getPriority() > Thread.NORM_PRIORITY)
{
new Thread(r).start();
}
else
{
r.run();
}
}
}

View File

@@ -0,0 +1,51 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.l2jmobius.gameserver.threadpool;
import java.lang.Thread.UncaughtExceptionHandler;
/**
* @author Mobius
*/
public class RunnableWrapper implements Runnable
{
private final Runnable _runnable;
public RunnableWrapper(Runnable runnable)
{
_runnable = runnable;
}
@Override
public void run()
{
try
{
_runnable.run();
}
catch (Throwable e)
{
final Thread t = Thread.currentThread();
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
if (h != null)
{
h.uncaughtException(t, e);
}
}
}
}

View File

@@ -0,0 +1,172 @@
/*
* This file is part of the L2J Mobius project.
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.l2jmobius.gameserver.threadpool;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import org.l2jmobius.Config;
/**
* This class handles thread pooling system.<br>
* It relies on two threadpool executors, which pool size is set using config.<br>
* Those arrays hold following pools:<br>
* <ul>
* <li>Scheduled pool keeps a track about incoming, future events.</li>
* <li>Instant pool handles short-life events.</li>
* </ul>
*/
public class ThreadPool
{
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
private static final ScheduledThreadPoolExecutor SCHEDULED_POOL = new ScheduledThreadPoolExecutor(Config.SCHEDULED_THREAD_POOL_COUNT);
private static final ThreadPoolExecutor INSTANT_POOL = new ThreadPoolExecutor(Config.INSTANT_THREAD_POOL_COUNT, Config.INSTANT_THREAD_POOL_COUNT, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
public static void init()
{
// Set pool options.
SCHEDULED_POOL.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
SCHEDULED_POOL.setRemoveOnCancelPolicy(true);
SCHEDULED_POOL.prestartAllCoreThreads();
INSTANT_POOL.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
INSTANT_POOL.prestartAllCoreThreads();
// Launch purge task.
scheduleAtFixedRate(() ->
{
purge();
}, 60000, 60000);
LOGGER.info("ThreadPool: Initialized");
LOGGER.info("...scheduled pool executor with " + Config.SCHEDULED_THREAD_POOL_COUNT + " total threads.");
LOGGER.info("...instant pool executor with " + Config.INSTANT_THREAD_POOL_COUNT + " total threads.");
}
public static void purge()
{
SCHEDULED_POOL.purge();
INSTANT_POOL.purge();
}
/**
* Creates and executes a one-shot action that becomes enabled after the given delay.
* @param runnable : the task to execute.
* @param delay : the time from now to delay execution.
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
*/
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
{
try
{
return SCHEDULED_POOL.schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
}
catch (Exception e)
{
LOGGER.warning(e.getMessage() + Config.EOL + e.getStackTrace());
return null;
}
}
/**
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
* @param runnable : the task to execute.
* @param initialDelay : the time to delay first execution.
* @param period : the period between successive executions.
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
*/
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
{
try
{
return SCHEDULED_POOL.scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
}
catch (Exception e)
{
LOGGER.warning(e.getMessage() + Config.EOL + e.getStackTrace());
return null;
}
}
/**
* Executes the given task sometime in the future.
* @param runnable : the task to execute.
*/
public static void execute(Runnable runnable)
{
try
{
INSTANT_POOL.execute(new RunnableWrapper(runnable));
}
catch (Exception e)
{
LOGGER.warning(e.getMessage() + Config.EOL + e.getStackTrace());
}
}
public static String[] getStats()
{
final String[] stats = new String[20];
int pos = 0;
stats[pos++] = "Scheduled pool:";
stats[pos++] = " |- ActiveCount: ...... " + SCHEDULED_POOL.getActiveCount();
stats[pos++] = " |- CorePoolSize: ..... " + SCHEDULED_POOL.getCorePoolSize();
stats[pos++] = " |- PoolSize: ......... " + SCHEDULED_POOL.getPoolSize();
stats[pos++] = " |- LargestPoolSize: .. " + SCHEDULED_POOL.getLargestPoolSize();
stats[pos++] = " |- MaximumPoolSize: .. " + SCHEDULED_POOL.getMaximumPoolSize();
stats[pos++] = " |- CompletedTaskCount: " + SCHEDULED_POOL.getCompletedTaskCount();
stats[pos++] = " |- QueuedTaskCount: .. " + SCHEDULED_POOL.getQueue().size();
stats[pos++] = " |- TaskCount: ........ " + SCHEDULED_POOL.getTaskCount();
stats[pos++] = " | -------";
stats[pos++] = "Instant pool:";
stats[pos++] = " |- ActiveCount: ...... " + INSTANT_POOL.getActiveCount();
stats[pos++] = " |- CorePoolSize: ..... " + INSTANT_POOL.getCorePoolSize();
stats[pos++] = " |- PoolSize: ......... " + INSTANT_POOL.getPoolSize();
stats[pos++] = " |- LargestPoolSize: .. " + INSTANT_POOL.getLargestPoolSize();
stats[pos++] = " |- MaximumPoolSize: .. " + INSTANT_POOL.getMaximumPoolSize();
stats[pos++] = " |- CompletedTaskCount: " + INSTANT_POOL.getCompletedTaskCount();
stats[pos++] = " |- QueuedTaskCount: .. " + INSTANT_POOL.getQueue().size();
stats[pos++] = " |- TaskCount: ........ " + INSTANT_POOL.getTaskCount();
stats[pos++] = " | -------";
return stats;
}
/**
* Shutdown thread pooling system correctly. Send different informations.
*/
public static void shutdown()
{
try
{
LOGGER.info("ThreadPool: Shutting down.");
SCHEDULED_POOL.shutdownNow();
INSTANT_POOL.shutdownNow();
}
catch (Throwable t)
{
t.printStackTrace();
}
}
}