Auto spawn handler rework.

This commit is contained in:
MobiusDevelopment
2021-04-22 11:28:02 +00:00
parent c30e5fe198
commit 5916e8d706
10 changed files with 572 additions and 658 deletions

View File

@@ -116,7 +116,7 @@ import org.l2jmobius.gameserver.model.sevensigns.SevenSignsFestival;
import org.l2jmobius.gameserver.model.siege.clanhalls.BanditStrongholdSiege; import org.l2jmobius.gameserver.model.siege.clanhalls.BanditStrongholdSiege;
import org.l2jmobius.gameserver.model.siege.clanhalls.DevastatedCastle; import org.l2jmobius.gameserver.model.siege.clanhalls.DevastatedCastle;
import org.l2jmobius.gameserver.model.siege.clanhalls.FortressOfResistance; import org.l2jmobius.gameserver.model.siege.clanhalls.FortressOfResistance;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn; import org.l2jmobius.gameserver.model.spawn.AutoSpawnHandler;
import org.l2jmobius.gameserver.network.ClientNetworkManager; import org.l2jmobius.gameserver.network.ClientNetworkManager;
import org.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager; import org.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager;
import org.l2jmobius.gameserver.script.EventDroplist; import org.l2jmobius.gameserver.script.EventDroplist;
@@ -336,7 +336,7 @@ public class GameServer
Util.printSection("Seven Signs"); Util.printSection("Seven Signs");
SevenSigns.getInstance(); SevenSigns.getInstance();
SevenSignsFestival.getInstance(); SevenSignsFestival.getInstance();
AutoSpawn.getInstance(); AutoSpawnHandler.getInstance();
AutoChatHandler.getInstance(); AutoChatHandler.getInstance();
Util.printSection("Olympiad System"); Util.printSection("Olympiad System");
@@ -354,7 +354,7 @@ public class GameServer
VoicedCommandHandler.getInstance(); VoicedCommandHandler.getInstance();
LOGGER.info("AutoChatHandler: Loaded " + AutoChatHandler.getInstance().size() + " handlers in total."); LOGGER.info("AutoChatHandler: Loaded " + AutoChatHandler.getInstance().size() + " handlers in total.");
LOGGER.info("AutoSpawnHandler: Loaded " + AutoSpawn.getInstance().size() + " handlers in total."); LOGGER.info("AutoSpawnHandler: Loaded " + AutoSpawnHandler.getInstance().size() + " handlers in total.");
Runtime.getRuntime().addShutdownHook(Shutdown.getInstance()); Runtime.getRuntime().addShutdownHook(Shutdown.getInstance());

View File

@@ -16,7 +16,7 @@
*/ */
package org.l2jmobius.gameserver.handler.admincommandhandlers; package org.l2jmobius.gameserver.handler.admincommandhandlers;
import java.util.List; import java.util.Queue;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -26,8 +26,8 @@ import org.l2jmobius.gameserver.handler.IAdminCommandHandler;
import org.l2jmobius.gameserver.model.actor.instance.NpcInstance; import org.l2jmobius.gameserver.model.actor.instance.NpcInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.sevensigns.SevenSigns; import org.l2jmobius.gameserver.model.sevensigns.SevenSigns;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn; import org.l2jmobius.gameserver.model.spawn.AutoSpawnHandler;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn.AutoSpawnInstance; import org.l2jmobius.gameserver.model.spawn.AutoSpawnHandler.AutoSpawnInstance;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.util.BuilderUtil; import org.l2jmobius.gameserver.util.BuilderUtil;
@@ -54,8 +54,8 @@ public class AdminMammon implements IAdminCommandHandler
int npcId = 0; int npcId = 0;
int teleportIndex = -1; int teleportIndex = -1;
final AutoSpawnInstance blackSpawnInst = AutoSpawn.getInstance().getAutoSpawnInstance(SevenSigns.MAMMON_BLACKSMITH_ID, false); final AutoSpawnInstance blackSpawnInst = AutoSpawnHandler.getInstance().getAutoSpawnInstance(SevenSigns.MAMMON_BLACKSMITH_ID, false);
final AutoSpawnInstance merchSpawnInst = AutoSpawn.getInstance().getAutoSpawnInstance(SevenSigns.MAMMON_MERCHANT_ID, false); final AutoSpawnInstance merchSpawnInst = AutoSpawnHandler.getInstance().getAutoSpawnInstance(SevenSigns.MAMMON_MERCHANT_ID, false);
if (command.startsWith("admin_mammon_find")) if (command.startsWith("admin_mammon_find"))
{ {
try try
@@ -78,12 +78,13 @@ public class AdminMammon implements IAdminCommandHandler
if (blackSpawnInst != null) if (blackSpawnInst != null)
{ {
final List<NpcInstance> blackInst = blackSpawnInst.getNPCInstanceList(); final Queue<NpcInstance> blackInst = blackSpawnInst.getNPCInstanceList();
if (!blackInst.isEmpty()) if (!blackInst.isEmpty())
{ {
final int x1 = blackInst.get(0).getX(); final NpcInstance npc = blackInst.stream().findFirst().get();
final int y1 = blackInst.get(0).getY(); final int x1 = npc.getX();
final int z1 = blackInst.get(0).getZ(); final int y1 = npc.getY();
final int z1 = npc.getZ();
BuilderUtil.sendSysMessage(activeChar, "Blacksmith of Mammon: " + x1 + " " + y1 + " " + z1); BuilderUtil.sendSysMessage(activeChar, "Blacksmith of Mammon: " + x1 + " " + y1 + " " + z1);
if (teleportIndex == 1) if (teleportIndex == 1)
{ {
@@ -98,12 +99,13 @@ public class AdminMammon implements IAdminCommandHandler
if (merchSpawnInst != null) if (merchSpawnInst != null)
{ {
final List<NpcInstance> merchInst = merchSpawnInst.getNPCInstanceList(); final Queue<NpcInstance> merchInst = merchSpawnInst.getNPCInstanceList();
if (!merchInst.isEmpty()) if (!merchInst.isEmpty())
{ {
final int x2 = merchInst.get(0).getX(); final NpcInstance npc = merchInst.stream().findFirst().get();
final int y2 = merchInst.get(0).getY(); final int x2 = npc.getX();
final int z2 = merchInst.get(0).getZ(); final int y2 = npc.getY();
final int z2 = npc.getZ();
BuilderUtil.sendSysMessage(activeChar, "Merchant of Mammon: " + x2 + " " + y2 + " " + z2); BuilderUtil.sendSysMessage(activeChar, "Merchant of Mammon: " + x2 + " " + y2 + " " + z2);
if (teleportIndex == 2) if (teleportIndex == 2)
{ {
@@ -127,7 +129,7 @@ public class AdminMammon implements IAdminCommandHandler
if (merchSpawnInst != null) if (merchSpawnInst != null)
{ {
final long merchRespawn = AutoSpawn.getInstance().getTimeToNextSpawn(merchSpawnInst); final long merchRespawn = AutoSpawnHandler.getInstance().getTimeToNextSpawn(merchSpawnInst);
BuilderUtil.sendSysMessage(activeChar, "The Merchant of Mammon will respawn in " + (merchRespawn / 60000) + " minute(s)."); BuilderUtil.sendSysMessage(activeChar, "The Merchant of Mammon will respawn in " + (merchRespawn / 60000) + " minute(s).");
} }
else else
@@ -137,7 +139,7 @@ public class AdminMammon implements IAdminCommandHandler
if (blackSpawnInst != null) if (blackSpawnInst != null)
{ {
final long blackRespawn = AutoSpawn.getInstance().getTimeToNextSpawn(blackSpawnInst); final long blackRespawn = AutoSpawnHandler.getInstance().getTimeToNextSpawn(blackSpawnInst);
BuilderUtil.sendSysMessage(activeChar, "The Blacksmith of Mammon will respawn in " + (blackRespawn / 60000) + " minute(s)."); BuilderUtil.sendSysMessage(activeChar, "The Blacksmith of Mammon will respawn in " + (blackRespawn / 60000) + " minute(s).");
} }
else else

View File

@@ -21,7 +21,8 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -36,8 +37,8 @@ import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn; import org.l2jmobius.gameserver.model.spawn.AutoSpawnHandler;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn.AutoSpawnInstance; import org.l2jmobius.gameserver.model.spawn.AutoSpawnHandler.AutoSpawnInstance;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SignsSky; import org.l2jmobius.gameserver.network.serverpackets.SignsSky;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -102,10 +103,10 @@ public class SevenSigns
protected int _duskFestivalScore; protected int _duskFestivalScore;
protected int _compWinner; protected int _compWinner;
protected int _previousWinner; protected int _previousWinner;
private final Map<Integer, StatSet> _signsPlayerData; private final Map<Integer, StatSet> _signsPlayerData = new LinkedHashMap<>();
private final Map<Integer, Integer> _signsSealOwners; private final Map<Integer, Integer> _signsSealOwners = new LinkedHashMap<>();
private final Map<Integer, Integer> _signsDuskSealTotals; private final Map<Integer, Integer> _signsDuskSealTotals = new LinkedHashMap<>();
private final Map<Integer, Integer> _signsDawnSealTotals; private final Map<Integer, Integer> _signsDawnSealTotals = new LinkedHashMap<>();
private static AutoSpawnInstance _merchantSpawn; private static AutoSpawnInstance _merchantSpawn;
private static AutoSpawnInstance _blacksmithSpawn; private static AutoSpawnInstance _blacksmithSpawn;
private static AutoSpawnInstance _spiritInSpawn; private static AutoSpawnInstance _spiritInSpawn;
@@ -114,20 +115,15 @@ public class SevenSigns
private static AutoSpawnInstance _anakimSpawn; private static AutoSpawnInstance _anakimSpawn;
private static AutoSpawnInstance _crestofdawnspawn; private static AutoSpawnInstance _crestofdawnspawn;
private static AutoSpawnInstance _crestofduskspawn; private static AutoSpawnInstance _crestofduskspawn;
private static Map<Integer, AutoSpawnInstance> _oratorSpawns; private static List<AutoSpawnInstance> _oratorSpawns;
private static Map<Integer, AutoSpawnInstance> _preacherSpawns; private static List<AutoSpawnInstance> _preacherSpawns;
private static Map<Integer, AutoSpawnInstance> _marketeerSpawns; private static List<AutoSpawnInstance> _marketeerSpawns;
/** /**
* Instantiates a new seven signs. * Instantiates a new seven signs.
*/ */
public SevenSigns() public SevenSigns()
{ {
_signsPlayerData = new HashMap<>();
_signsSealOwners = new HashMap<>();
_signsDuskSealTotals = new HashMap<>();
_signsDawnSealTotals = new HashMap<>();
try try
{ {
restoreSevenSignsData(); restoreSevenSignsData();
@@ -185,22 +181,22 @@ public class SevenSigns
*/ */
public void spawnSevenSignsNPC() public void spawnSevenSignsNPC()
{ {
_merchantSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(MAMMON_MERCHANT_ID, false); _merchantSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(MAMMON_MERCHANT_ID, false);
_blacksmithSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(MAMMON_BLACKSMITH_ID, false); _blacksmithSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(MAMMON_BLACKSMITH_ID, false);
_marketeerSpawns = AutoSpawn.getInstance().getAutoSpawnInstances(MAMMON_MARKETEER_ID); _marketeerSpawns = AutoSpawnHandler.getInstance().getAutoSpawnInstances(MAMMON_MARKETEER_ID);
_spiritInSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(SPIRIT_IN_ID, false); _spiritInSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(SPIRIT_IN_ID, false);
_spiritOutSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(SPIRIT_OUT_ID, false); _spiritOutSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(SPIRIT_OUT_ID, false);
_lilithSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(LILITH_NPC_ID, false); _lilithSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(LILITH_NPC_ID, false);
_anakimSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(ANAKIM_NPC_ID, false); _anakimSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(ANAKIM_NPC_ID, false);
_crestofdawnspawn = AutoSpawn.getInstance().getAutoSpawnInstance(CREST_OF_DAWN_ID, false); _crestofdawnspawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(CREST_OF_DAWN_ID, false);
_crestofduskspawn = AutoSpawn.getInstance().getAutoSpawnInstance(CREST_OF_DUSK_ID, false); _crestofduskspawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(CREST_OF_DUSK_ID, false);
_oratorSpawns = AutoSpawn.getInstance().getAutoSpawnInstances(ORATOR_NPC_ID); _oratorSpawns = AutoSpawnHandler.getInstance().getAutoSpawnInstances(ORATOR_NPC_ID);
_preacherSpawns = AutoSpawn.getInstance().getAutoSpawnInstances(PREACHER_NPC_ID); _preacherSpawns = AutoSpawnHandler.getInstance().getAutoSpawnInstances(PREACHER_NPC_ID);
if (isSealValidationPeriod() || isCompResultsPeriod()) if (isSealValidationPeriod() || isCompResultsPeriod())
{ {
for (AutoSpawnInstance spawnInst : _marketeerSpawns.values()) for (AutoSpawnInstance spawnInst : _marketeerSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, true); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, true);
} }
if ((getSealOwner(SEAL_GNOSIS) == getCabalHighestScore()) && (getSealOwner(SEAL_GNOSIS) != CABAL_NULL)) if ((getSealOwner(SEAL_GNOSIS) == getCabalHighestScore()) && (getSealOwner(SEAL_GNOSIS) != CABAL_NULL))
@@ -210,24 +206,24 @@ public class SevenSigns
_blacksmithSpawn.setBroadcast(false); _blacksmithSpawn.setBroadcast(false);
} }
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_blacksmithSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_blacksmithSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_blacksmithSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_blacksmithSpawn, true);
} }
for (AutoSpawnInstance spawnInst : _oratorSpawns.values()) for (AutoSpawnInstance spawnInst : _oratorSpawns)
{ {
if (!AutoSpawn.getInstance().getAutoSpawnInstance(spawnInst.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(spawnInst.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, true); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, true);
} }
} }
for (AutoSpawnInstance spawnInst : _preacherSpawns.values()) for (AutoSpawnInstance spawnInst : _preacherSpawns)
{ {
if (!AutoSpawn.getInstance().getAutoSpawnInstance(spawnInst.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(spawnInst.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, true); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, true);
} }
} }
@@ -238,15 +234,15 @@ public class SevenSigns
} }
else else
{ {
AutoSpawn.getInstance().setSpawnActive(_blacksmithSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_blacksmithSpawn, false);
for (AutoSpawnInstance spawnInst : _oratorSpawns.values()) for (AutoSpawnInstance spawnInst : _oratorSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, false); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, false);
} }
for (AutoSpawnInstance spawnInst : _preacherSpawns.values()) for (AutoSpawnInstance spawnInst : _preacherSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, false); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, false);
} }
AutoChatHandler.getInstance().setAutoChatActive(false); AutoChatHandler.getInstance().setAutoChatActive(false);
@@ -259,87 +255,87 @@ public class SevenSigns
_merchantSpawn.setBroadcast(false); _merchantSpawn.setBroadcast(false);
} }
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_merchantSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_merchantSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_merchantSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_merchantSpawn, true);
} }
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_spiritInSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_spiritInSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_spiritInSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_spiritInSpawn, true);
} }
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_spiritOutSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_spiritOutSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_spiritOutSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_spiritOutSpawn, true);
} }
switch (getCabalHighestScore()) switch (getCabalHighestScore())
{ {
case CABAL_DAWN: case CABAL_DAWN:
{ {
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_lilithSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_lilithSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_lilithSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_lilithSpawn, true);
} }
AutoSpawn.getInstance().setSpawnActive(_anakimSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_anakimSpawn, false);
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_crestofdawnspawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_crestofdawnspawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_crestofdawnspawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_crestofdawnspawn, true);
} }
AutoSpawn.getInstance().setSpawnActive(_crestofduskspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofduskspawn, false);
break; break;
} }
case CABAL_DUSK: case CABAL_DUSK:
{ {
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_anakimSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_anakimSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_anakimSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_anakimSpawn, true);
} }
AutoSpawn.getInstance().setSpawnActive(_lilithSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_lilithSpawn, false);
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_crestofduskspawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_crestofduskspawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_crestofduskspawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_crestofduskspawn, true);
} }
AutoSpawn.getInstance().setSpawnActive(_crestofdawnspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofdawnspawn, false);
break; break;
} }
} }
} }
else else
{ {
AutoSpawn.getInstance().setSpawnActive(_merchantSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_merchantSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_lilithSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_lilithSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_anakimSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_anakimSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_crestofdawnspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofdawnspawn, false);
AutoSpawn.getInstance().setSpawnActive(_crestofduskspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofduskspawn, false);
AutoSpawn.getInstance().setSpawnActive(_spiritInSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_spiritInSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_spiritOutSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_spiritOutSpawn, false);
} }
} }
else else
{ {
AutoSpawn.getInstance().setSpawnActive(_merchantSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_merchantSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_blacksmithSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_blacksmithSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_lilithSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_lilithSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_anakimSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_anakimSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_crestofdawnspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofdawnspawn, false);
AutoSpawn.getInstance().setSpawnActive(_crestofduskspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofduskspawn, false);
AutoSpawn.getInstance().setSpawnActive(_spiritInSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_spiritInSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_spiritOutSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_spiritOutSpawn, false);
for (AutoSpawnInstance spawnInst : _oratorSpawns.values()) for (AutoSpawnInstance spawnInst : _oratorSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, false); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, false);
} }
for (AutoSpawnInstance spawnInst : _preacherSpawns.values()) for (AutoSpawnInstance spawnInst : _preacherSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, false); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, false);
} }
for (AutoSpawnInstance spawnInst : _marketeerSpawns.values()) for (AutoSpawnInstance spawnInst : _marketeerSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, false); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, false);
} }
AutoChatHandler.getInstance().setAutoChatActive(false); AutoChatHandler.getInstance().setAutoChatActive(false);

View File

@@ -19,13 +19,18 @@ package org.l2jmobius.gameserver.model.spawn;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.LinkedList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.concurrent.ThreadPool;
@@ -41,53 +46,85 @@ import org.l2jmobius.gameserver.model.actor.instance.NpcInstance;
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate; import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
/** /**
* Auto Spawn Handler Allows spawning of a NPC object based on a timer. (From the official idea used for the Merchant and Blacksmith of Mammon) General Usage: - Call registerSpawn() with the parameters listed below. int npcId int[][] spawnPoints or specify NULL to add points later. int initialDelay * Auto Spawn handler.<br>
* (If < 0 = default value) int respawnDelay (If < 0 = default value) int despawnDelay (If < 0 = default value or if = 0, function disabled) spawnPoints is a standard two-dimensional int array containing X,Y and Z coordinates. The default respawn/despawn delays are currently every hour (as for * Allows spawning of a NPC object based on a timer.<br>
* Mammon on official servers). - The resulting AutoSpawnInstance object represents the newly added spawn index. - The internal methods of this object can be used to adjust random spawning, for instance a call to setRandomSpawn(1, true); would set the spawn at index 1 to be randomly rather than * (From the official idea used for the Merchant and Blacksmith of Mammon)<br>
* sequentially-based. - Also they can be used to specify the number of NPC instances to spawn using setSpawnCount(), and broadcast a message to all users using setBroadcast(). Random Spawning = OFF by default Broadcasting = OFF by default * General Usage: - Call registerSpawn() with the parameters listed below.<br>
* int npcId int[][] spawnPoints or specify NULL to add points later.<br>
* int initialDelay (If < 0 = default value) int respawnDelay (If < 0 = default value)<br>
* int despawnDelay (If < 0 = default value or if = 0, function disabled)<br>
* spawnPoints is a standard two-dimensional int array containing X,Y and Z coordinates.<br>
* The default respawn/despawn delays are currently every hour (as for Mammon on official servers).<br>
* The resulting AutoSpawnInstance object represents the newly added spawn index.<br>
* The internal methods of this object can be used to adjust random spawning, for instance a call to setRandomSpawn(1, true); would set the spawn at index 1 to be randomly rather than sequentially-based.<br>
* Also they can be used to specify the number of NPC instances to spawn using setSpawnCount(), and broadcast a message to all users using setBroadcast().<br>
* Random Spawning = OFF by default Broadcasting = OFF by default
* @author Tempy * @author Tempy
*/ */
public class AutoSpawn public class AutoSpawnHandler
{ {
protected static final Logger LOGGER = Logger.getLogger(AutoSpawn.class.getName()); protected static final Logger LOGGER = Logger.getLogger(AutoSpawnHandler.class.getName());
private static final int DEFAULT_INITIAL_SPAWN = 30000; // 30 seconds after registration private static final int DEFAULT_INITIAL_SPAWN = 30000; // 30 seconds after registration
private static final int DEFAULT_RESPAWN = 3600000; // 1 hour in millisecs private static final int DEFAULT_RESPAWN = 3600000; // 1 hour in millisecs
private static final int DEFAULT_DESPAWN = 3600000; // 1 hour in millisecs private static final int DEFAULT_DESPAWN = 3600000; // 1 hour in millisecs
protected Map<Integer, AutoSpawnInstance> _registeredSpawns; protected Map<Integer, AutoSpawnInstance> _registeredSpawns = new ConcurrentHashMap<>();
protected Map<Integer, ScheduledFuture<?>> _runningSpawns; protected Map<Integer, ScheduledFuture<?>> _runningSpawns = new ConcurrentHashMap<>();
protected boolean _activeState = true; protected boolean _activeState = true;
protected AutoSpawn() protected AutoSpawnHandler()
{ {
_registeredSpawns = new HashMap<>();
_runningSpawns = new HashMap<>();
restoreSpawnData(); restoreSpawnData();
} }
public int size() public int size()
{
synchronized (_registeredSpawns)
{ {
return _registeredSpawns.size(); return _registeredSpawns.size();
} }
public void reload()
{
// unload
unload();
// create clean list
_registeredSpawns.clear();
_runningSpawns.clear();
// load
restoreSpawnData();
}
public void unload()
{
// stop all timers
for (ScheduledFuture<?> sf : _runningSpawns.values())
{
if (sf != null)
{
sf.cancel(true);
}
}
// unregister all registered spawns
for (AutoSpawnInstance asi : _registeredSpawns.values())
{
if (asi != null)
{
removeSpawn(asi);
}
}
} }
private void restoreSpawnData() private void restoreSpawnData()
{ {
try (Connection con = DatabaseFactory.getConnection()) try (Connection con = DatabaseFactory.getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM random_spawn ORDER BY groupId ASC");
PreparedStatement ps = con.prepareStatement("SELECT * FROM random_spawn_loc WHERE groupId=?"))
{ {
PreparedStatement statement = null;
PreparedStatement statement2 = null;
ResultSet rs = null;
ResultSet rs2 = null;
// Restore spawn group data, then the location data. // Restore spawn group data, then the location data.
statement = con.prepareStatement("SELECT * FROM random_spawn ORDER BY groupId ASC");
rs = statement.executeQuery();
while (rs.next()) while (rs.next())
{ {
// Register random spawn group, set various options on the created spawn instance. // Register random spawn group, set various options on the created spawn instance.
@@ -97,31 +134,27 @@ public class AutoSpawn
spawnInst.setRandomSpawn(rs.getBoolean("randomSpawn")); spawnInst.setRandomSpawn(rs.getBoolean("randomSpawn"));
// Restore the spawn locations for this spawn group/instance. // Restore the spawn locations for this spawn group/instance.
statement2 = con.prepareStatement("SELECT * FROM random_spawn_loc WHERE groupId=?"); ps.setInt(1, rs.getInt("groupId"));
statement2.setInt(1, rs.getInt("groupId")); try (ResultSet rs2 = ps.executeQuery())
rs2 = statement2.executeQuery(); {
ps.clearParameters();
while (rs2.next()) while (rs2.next())
{ {
// Add each location to the spawn group/instance. // Add each location to the spawn group/instance.
spawnInst.addSpawnLocation(rs2.getInt("x"), rs2.getInt("y"), rs2.getInt("z"), rs2.getInt("heading")); spawnInst.addSpawnLocation(rs2.getInt("x"), rs2.getInt("y"), rs2.getInt("z"), rs2.getInt("heading"));
} }
statement2.close();
rs2.close();
} }
}
statement.close();
rs.close();
} }
catch (Exception e) catch (Exception e)
{ {
LOGGER.warning("AutoSpawnHandler: Could not restore spawn data: " + e); LOGGER.log(Level.WARNING, "AutoSpawnHandler: Could not restore spawn data: " + e.getMessage(), e);
} }
} }
/** /**
* Registers a spawn with the given parameters with the spawner, and marks it as active. Returns a AutoSpawnInstance containing info about the spawn. * Registers a spawn with the given parameters with the spawner, and marks it as active.<br>
* Returns a AutoSpawnInstance containing info about the spawn.
* @param npcId * @param npcId
* @param spawnPoints * @param spawnPoints
* @param initialDelay (If < 0 = default value) * @param initialDelay (If < 0 = default value)
@@ -142,24 +175,21 @@ public class AutoSpawn
final int newId = IdManager.getInstance().getNextId(); final int newId = IdManager.getInstance().getNextId();
newSpawn._objectId = newId; newSpawn._objectId = newId;
synchronized (_registeredSpawns)
{
_registeredSpawns.put(newId, newSpawn); _registeredSpawns.put(newId, newSpawn);
}
setSpawnActive(newSpawn, true); setSpawnActive(newSpawn, true);
return newSpawn; return newSpawn;
} }
/** /**
* Registers a spawn with the given parameters with the spawner, and marks it as active. Returns a AutoSpawnInstance containing info about the spawn.<br> * Registers a spawn with the given parameters with the spawner, and marks it as active.<br>
* Returns a AutoSpawnInstance containing info about the spawn.<br>
* <b>Warning:</b> Spawn locations must be specified separately using addSpawnLocation(). * <b>Warning:</b> Spawn locations must be specified separately using addSpawnLocation().
* @param npcId * @param npcId
* @param initialDelay (If < 0 = default value) * @param initialDelay (If < 0 = default value)
* @param respawnDelay (If < 0 = default value) * @param respawnDelay (If < 0 = default value)
* @param despawnDelay (If < 0 = default value or if = 0, function disabled) * @param despawnDelay (If < 0 = default value or if = 0, function disabled)
* @return spawnInst * @return AutoSpawnInstance spawnInst
*/ */
public AutoSpawnInstance registerSpawn(int npcId, int initialDelay, int respawnDelay, int despawnDelay) public AutoSpawnInstance registerSpawn(int npcId, int initialDelay, int respawnDelay, int despawnDelay)
{ {
@@ -169,37 +199,28 @@ public class AutoSpawn
/** /**
* Remove a registered spawn from the list, specified by the given spawn instance. * Remove a registered spawn from the list, specified by the given spawn instance.
* @param spawnInst * @param spawnInst
* @return removedSuccessfully * @return boolean removedSuccessfully
*/ */
public boolean removeSpawn(AutoSpawnInstance spawnInst) public boolean removeSpawn(AutoSpawnInstance spawnInst)
{ {
synchronized (_registeredSpawns) if (!isSpawnRegistered(spawnInst))
{
if (!_registeredSpawns.containsValue(spawnInst))
{ {
return false; return false;
} }
// Try to remove from the list of registered spawns if it exists.
_registeredSpawns.remove(spawnInst.getNpcId());
synchronized (_runningSpawns)
{
// Cancel the currently associated running scheduled task.
final ScheduledFuture<?> respawnTask = _runningSpawns.remove(spawnInst._objectId);
try try
{ {
respawnTask.cancel(false); // Try to remove from the list of registered spawns if it exists.
_registeredSpawns.remove(spawnInst.getNpcId());
// Cancel the currently associated running scheduled task.
_runningSpawns.remove(spawnInst._objectId).cancel(false);
} }
catch (Exception e) catch (Exception e)
{ {
LOGGER.warning("AutoSpawnHandler: Could not auto spawn for NPC ID " + spawnInst._npcId + " (Object ID = " + spawnInst._objectId + "): " + e); LOGGER.log(Level.WARNING, "AutoSpawnHandler: Could not auto spawn for NPC ID " + spawnInst._npcId + " (Object ID = " + spawnInst._objectId + "): " + e.getMessage(), e);
return false; return false;
} }
}
}
return true; return true;
} }
@@ -210,12 +231,7 @@ public class AutoSpawn
*/ */
public void removeSpawn(int objectId) public void removeSpawn(int objectId)
{ {
AutoSpawnInstance spawn = null; removeSpawn(_registeredSpawns.get(objectId));
synchronized (_registeredSpawns)
{
spawn = _registeredSpawns.get(objectId);
}
removeSpawn(spawn);
} }
/** /**
@@ -231,46 +247,30 @@ public class AutoSpawn
} }
final int objectId = spawnInst._objectId; final int objectId = spawnInst._objectId;
if (isSpawnRegistered(objectId)) if (!isSpawnRegistered(objectId))
{ {
return;
}
ScheduledFuture<?> spawnTask = null; ScheduledFuture<?> spawnTask = null;
if (isActive) if (isActive)
{ {
final AutoSpawner rs = new AutoSpawner(objectId); final AutoSpawner rs = new AutoSpawner(objectId);
if (spawnInst._desDelay > 0) spawnTask = spawnInst._desDelay > 0 ? ThreadPool.scheduleAtFixedRate(rs, spawnInst._initDelay, spawnInst._resDelay) : ThreadPool.schedule(rs, spawnInst._initDelay);
{
spawnTask = ThreadPool.scheduleAtFixedRate(rs, spawnInst._initDelay, spawnInst._resDelay);
}
else
{
spawnTask = ThreadPool.schedule(rs, spawnInst._initDelay);
}
synchronized (_runningSpawns)
{
_runningSpawns.put(objectId, spawnTask); _runningSpawns.put(objectId, spawnTask);
} }
}
else else
{ {
final AutoDespawner rd = new AutoDespawner(objectId); final AutoDespawner rd = new AutoDespawner(objectId);
synchronized (_runningSpawns)
{
spawnTask = _runningSpawns.remove(objectId); spawnTask = _runningSpawns.remove(objectId);
}
if (spawnTask != null) if (spawnTask != null)
{ {
spawnTask.cancel(false); spawnTask.cancel(false);
} }
ThreadPool.schedule(rd, 0); ThreadPool.schedule(rd, 0);
} }
spawnInst.setSpawnActive(isActive); spawnInst.setSpawnActive(isActive);
} }
}
/** /**
* Sets the active state of all auto spawn instances to that specified, and cancels the scheduled spawn task if necessary. * Sets the active state of all auto spawn instances to that specified, and cancels the scheduled spawn task if necessary.
@@ -283,13 +283,7 @@ public class AutoSpawn
return; return;
} }
Collection<AutoSpawnInstance> instances; for (AutoSpawnInstance spawnInst : _registeredSpawns.values())
synchronized (_registeredSpawns)
{
instances = _registeredSpawns.values();
}
for (AutoSpawnInstance spawnInst : instances)
{ {
setSpawnActive(spawnInst, isActive); setSpawnActive(spawnInst, isActive);
} }
@@ -304,21 +298,8 @@ public class AutoSpawn
*/ */
public long getTimeToNextSpawn(AutoSpawnInstance spawnInst) public long getTimeToNextSpawn(AutoSpawnInstance spawnInst)
{ {
if (spawnInst == null)
{
return -1;
}
final int objectId = spawnInst.getObjectId(); final int objectId = spawnInst.getObjectId();
return !isSpawnRegistered(objectId) ? -1 : _runningSpawns.containsKey(objectId) ? _runningSpawns.get(objectId).getDelay(TimeUnit.MILLISECONDS) : 0;
synchronized (_runningSpawns)
{
final ScheduledFuture<?> task = _runningSpawns.get(objectId);
if (task != null)
{
return task.getDelay(TimeUnit.MILLISECONDS);
}
}
return -1;
} }
/** /**
@@ -331,58 +312,47 @@ public class AutoSpawn
public AutoSpawnInstance getAutoSpawnInstance(int id, boolean isObjectId) public AutoSpawnInstance getAutoSpawnInstance(int id, boolean isObjectId)
{ {
if (isObjectId) if (isObjectId)
{
if (isSpawnRegistered(id))
{ {
return _registeredSpawns.get(id); return _registeredSpawns.get(id);
} }
Collection<AutoSpawnInstance> instances;
synchronized (_registeredSpawns)
{
instances = _registeredSpawns.values();
} }
else
for (AutoSpawnInstance spawnInst : instances) {
for (AutoSpawnInstance spawnInst : _registeredSpawns.values())
{ {
if (spawnInst.getNpcId() == id) if (spawnInst.getNpcId() == id)
{ {
return spawnInst; return spawnInst;
} }
} }
}
return null; return null;
} }
public Map<Integer, AutoSpawnInstance> getAutoSpawnInstances(int npcId) public List<AutoSpawnInstance> getAutoSpawnInstances(int npcId)
{ {
final Map<Integer, AutoSpawnInstance> spawnInstList = new HashMap<>(); final List<AutoSpawnInstance> result = new LinkedList<>();
Collection<AutoSpawnInstance> instances; for (AutoSpawnInstance spawnInst : _registeredSpawns.values())
synchronized (_registeredSpawns)
{
instances = _registeredSpawns.values();
}
for (AutoSpawnInstance spawnInst : instances)
{ {
if (spawnInst.getNpcId() == npcId) if (spawnInst.getNpcId() == npcId)
{ {
spawnInstList.put(spawnInst.getObjectId(), spawnInst); result.add(spawnInst);
} }
} }
return result;
return spawnInstList;
} }
/** /**
* Tests if the specified object ID is assigned to an auto spawn. * Tests if the specified object ID is assigned to an auto spawn.
* @param objectId * @param objectId
* @return boolean isAssigned * @return isAssigned
*/ */
public boolean isSpawnRegistered(int objectId) public boolean isSpawnRegistered(int objectId)
{
synchronized (_registeredSpawns)
{ {
return _registeredSpawns.containsKey(objectId); return _registeredSpawns.containsKey(objectId);
} }
}
/** /**
* Tests if the specified spawn instance is assigned to an auto spawn. * Tests if the specified spawn instance is assigned to an auto spawn.
@@ -390,15 +360,12 @@ public class AutoSpawn
* @return boolean isAssigned * @return boolean isAssigned
*/ */
public boolean isSpawnRegistered(AutoSpawnInstance spawnInst) public boolean isSpawnRegistered(AutoSpawnInstance spawnInst)
{
synchronized (_registeredSpawns)
{ {
return _registeredSpawns.containsValue(spawnInst); return _registeredSpawns.containsValue(spawnInst);
} }
}
/** /**
* AutoSpawner Class<br> * AutoSpawner class<br>
* This handles the main spawn task for an auto spawn instance, and initializes a despawner if required. * This handles the main spawn task for an auto spawn instance, and initializes a despawner if required.
* @author Tempy * @author Tempy
*/ */
@@ -415,14 +382,9 @@ public class AutoSpawn
public void run() public void run()
{ {
try try
{
AutoSpawnInstance spawnInst = null;
synchronized (_registeredSpawns)
{ {
// Retrieve the required spawn instance for this spawn task. // Retrieve the required spawn instance for this spawn task.
spawnInst = _registeredSpawns.get(_objectId); final AutoSpawnInstance spawnInst = _registeredSpawns.get(_objectId);
}
// If the spawn is not scheduled to be active, cancel the spawn task. // If the spawn is not scheduled to be active, cancel the spawn task.
if (!spawnInst.isSpawnActive()) if (!spawnInst.isSpawnActive())
@@ -442,12 +404,11 @@ public class AutoSpawn
final int locationCount = locationList.size(); final int locationCount = locationList.size();
int locationIndex = Rnd.get(locationCount); int locationIndex = Rnd.get(locationCount);
// If random spawning is disabled, the spawn at the next set of co-ordinates after the last. If the index is greater than the number of possible spawns, reset the counter to zero. // If random spawning is disabled, the spawn at the next set of co-ordinates after the last.
// If the index is greater than the number of possible spawns, reset the counter to zero.
if (!spawnInst.isRandomSpawn()) if (!spawnInst.isRandomSpawn())
{ {
locationIndex = spawnInst._lastLocIndex; locationIndex = spawnInst._lastLocIndex + 1;
locationIndex++;
if (locationIndex == locationCount) if (locationIndex == locationCount)
{ {
locationIndex = 0; locationIndex = 0;
@@ -479,9 +440,7 @@ public class AutoSpawn
{ {
newSpawn.setHeading(heading); newSpawn.setHeading(heading);
} }
newSpawn.setAmount(spawnInst.getSpawnCount()); newSpawn.setAmount(spawnInst.getSpawnCount());
if (spawnInst._desDelay == 0) if (spawnInst._desDelay == 0)
{ {
newSpawn.setRespawnDelay(spawnInst._resDelay); newSpawn.setRespawnDelay(spawnInst._resDelay);
@@ -509,25 +468,36 @@ public class AutoSpawn
spawnInst.addNpcInstance(npcInst); spawnInst.addNpcInstance(npcInst);
} }
} }
newSpawn.stopRespawn();
final String nearestTown = MapRegionData.getInstance().getClosestTownName(npcInst); if (npcInst != null)
{
if (spawnInst.isRandomSpawn())
{
while (!npcInst.getKnownList().getKnownCharactersInRadius(5).isEmpty())
{
// LOGGER.log(Level.INFO, "AutoSpawnHandler: Random spawn location " + npcInst.getLocation() + " for " + npcInst + " is occupied. Teleporting...");
npcInst.teleToLocation(locationList.get(Rnd.get(locationList.size())), false);
}
}
// Announce to all players that the spawn has taken place, with the nearest town location. // Announce to all players that the spawn has taken place, with the nearest town location.
if (spawnInst.isBroadcasting() && (npcInst != null)) final String nearestTown = MapRegionData.getInstance().getClosestTownName(npcInst);
if (spawnInst.isBroadcasting())
{ {
Announcements.getInstance().announceToAll("The " + npcInst.getName() + " has spawned near " + nearestTown + "!"); Announcements.getInstance().announceToAll("The " + npcInst.getName() + " has spawned near " + nearestTown + "!");
} }
}
// If there is no despawn time, do not create a despawn task. // If there is no despawn time, do not create a despawn task.
if (spawnInst.getDespawnDelay() > 0) if (spawnInst.getDespawnDelay() > 0)
{ {
final AutoDespawner rd = new AutoDespawner(_objectId); ThreadPool.schedule(new AutoDespawner(_objectId), spawnInst.getDespawnDelay() - 1000);
ThreadPool.schedule(rd, spawnInst.getDespawnDelay() - 1000);
} }
} }
catch (Exception e) catch (Exception e)
{ {
LOGGER.warning("AutoSpawnHandler: An error occurred while initializing spawn instance (Object ID = " + _objectId + "): " + e); LOGGER.log(Level.WARNING, "AutoSpawnHandler: An error occurred while initializing spawn instance (Object ID = " + _objectId + "): " + e.getMessage(), e);
} }
} }
} }
@@ -551,39 +521,28 @@ public class AutoSpawn
{ {
try try
{ {
AutoSpawnInstance spawnInst = null; final AutoSpawnInstance spawnInst = _registeredSpawns.get(_objectId);
synchronized (_registeredSpawns)
{
spawnInst = _registeredSpawns.get(_objectId);
}
if (spawnInst == null) if (spawnInst == null)
{ {
LOGGER.info("AutoSpawnHandler: No spawn registered for object ID = " + _objectId + "."); LOGGER.info("AutoSpawnHandler: No spawn registered for object ID = " + _objectId + ".");
return; return;
} }
final List<NpcInstance> npcs = spawnInst.getNPCInstanceList(); for (NpcInstance npcInst : spawnInst.getNPCInstanceList())
if (npcs == null)
{ {
LOGGER.info("AutoSpawnHandler: No spawn registered"); if (npcInst == null)
return;
}
for (NpcInstance npc : npcs)
{
if (npc == null)
{ {
continue; continue;
} }
npc.deleteMe(); npcInst.deleteMe();
spawnInst.removeNpcInstance(npc); SpawnTable.getInstance().deleteSpawn(npcInst.getSpawn(), false);
spawnInst.removeNpcInstance(npcInst);
} }
} }
catch (Exception e) catch (Exception e)
{ {
LOGGER.warning("AutoSpawnHandler: An error occurred while despawning spawn (Object ID = " + _objectId + "): " + e); LOGGER.log(Level.WARNING, "AutoSpawnHandler: An error occurred while despawning spawn (Object ID = " + _objectId + "): " + e.getMessage(), e);
} }
} }
} }
@@ -593,7 +552,7 @@ public class AutoSpawn
* Stores information about a registered auto spawn. * Stores information about a registered auto spawn.
* @author Tempy * @author Tempy
*/ */
public class AutoSpawnInstance public static class AutoSpawnInstance
{ {
protected int _objectId; protected int _objectId;
@@ -611,9 +570,9 @@ public class AutoSpawn
protected int _lastLocIndex = -1; protected int _lastLocIndex = -1;
private final List<NpcInstance> _npcList = new ArrayList<>(); private final Queue<NpcInstance> _npcList = new ConcurrentLinkedQueue<>();
private final List<Location> _locList = new ArrayList<>(); private final List<Location> _locList = new CopyOnWriteArrayList<>();
private boolean _spawnActive; private boolean _spawnActive;
@@ -679,7 +638,7 @@ public class AutoSpawn
return _locList; return _locList;
} }
public List<NpcInstance> getNPCInstanceList() public Queue<NpcInstance> getNPCInstanceList()
{ {
return _npcList; return _npcList;
} }
@@ -699,14 +658,14 @@ public class AutoSpawn
_spawnCount = spawnCount; _spawnCount = spawnCount;
} }
public void setRandomSpawn(boolean random) public void setRandomSpawn(boolean randValue)
{ {
_randomSpawn = random; _randomSpawn = randValue;
} }
public void setBroadcast(boolean broadcast) public void setBroadcast(boolean broadcastValue)
{ {
_broadcastAnnouncement = broadcast; _broadcastAnnouncement = broadcastValue;
} }
public boolean isSpawnActive() public boolean isSpawnActive()
@@ -731,11 +690,7 @@ public class AutoSpawn
public boolean addSpawnLocation(int[] spawnLoc) public boolean addSpawnLocation(int[] spawnLoc)
{ {
if (spawnLoc.length != 3) return (spawnLoc.length == 3) && addSpawnLocation(spawnLoc[0], spawnLoc[1], spawnLoc[2], -1);
{
return false;
}
return addSpawnLocation(spawnLoc[0], spawnLoc[1], spawnLoc[2], -1);
} }
public Location removeSpawnLocation(int locIndex) public Location removeSpawnLocation(int locIndex)
@@ -751,13 +706,13 @@ public class AutoSpawn
} }
} }
public static AutoSpawn getInstance() public static AutoSpawnHandler getInstance()
{ {
return SingletonHolder.INSTANCE; return SingletonHolder.INSTANCE;
} }
private static class SingletonHolder private static class SingletonHolder
{ {
protected static final AutoSpawn INSTANCE = new AutoSpawn(); protected static final AutoSpawnHandler INSTANCE = new AutoSpawnHandler();
} }
} }

View File

@@ -120,7 +120,7 @@ import org.l2jmobius.gameserver.model.sevensigns.SevenSignsFestival;
import org.l2jmobius.gameserver.model.siege.clanhalls.BanditStrongholdSiege; import org.l2jmobius.gameserver.model.siege.clanhalls.BanditStrongholdSiege;
import org.l2jmobius.gameserver.model.siege.clanhalls.DevastatedCastle; import org.l2jmobius.gameserver.model.siege.clanhalls.DevastatedCastle;
import org.l2jmobius.gameserver.model.siege.clanhalls.FortressOfResistance; import org.l2jmobius.gameserver.model.siege.clanhalls.FortressOfResistance;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn; import org.l2jmobius.gameserver.model.spawn.AutoSpawnHandler;
import org.l2jmobius.gameserver.network.ClientNetworkManager; import org.l2jmobius.gameserver.network.ClientNetworkManager;
import org.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager; import org.l2jmobius.gameserver.network.loginserver.LoginServerNetworkManager;
import org.l2jmobius.gameserver.script.EventDroplist; import org.l2jmobius.gameserver.script.EventDroplist;
@@ -343,7 +343,7 @@ public class GameServer
Util.printSection("Seven Signs"); Util.printSection("Seven Signs");
SevenSigns.getInstance(); SevenSigns.getInstance();
SevenSignsFestival.getInstance(); SevenSignsFestival.getInstance();
AutoSpawn.getInstance(); AutoSpawnHandler.getInstance();
AutoChatHandler.getInstance(); AutoChatHandler.getInstance();
Util.printSection("Olympiad System"); Util.printSection("Olympiad System");
@@ -361,7 +361,7 @@ public class GameServer
VoicedCommandHandler.getInstance(); VoicedCommandHandler.getInstance();
LOGGER.info("AutoChatHandler: Loaded " + AutoChatHandler.getInstance().size() + " handlers in total."); LOGGER.info("AutoChatHandler: Loaded " + AutoChatHandler.getInstance().size() + " handlers in total.");
LOGGER.info("AutoSpawnHandler: Loaded " + AutoSpawn.getInstance().size() + " handlers in total."); LOGGER.info("AutoSpawnHandler: Loaded " + AutoSpawnHandler.getInstance().size() + " handlers in total.");
Runtime.getRuntime().addShutdownHook(Shutdown.getInstance()); Runtime.getRuntime().addShutdownHook(Shutdown.getInstance());

View File

@@ -16,7 +16,7 @@
*/ */
package org.l2jmobius.gameserver.handler.admincommandhandlers; package org.l2jmobius.gameserver.handler.admincommandhandlers;
import java.util.List; import java.util.Queue;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -26,8 +26,8 @@ import org.l2jmobius.gameserver.handler.IAdminCommandHandler;
import org.l2jmobius.gameserver.model.actor.instance.NpcInstance; import org.l2jmobius.gameserver.model.actor.instance.NpcInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.sevensigns.SevenSigns; import org.l2jmobius.gameserver.model.sevensigns.SevenSigns;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn; import org.l2jmobius.gameserver.model.spawn.AutoSpawnHandler;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn.AutoSpawnInstance; import org.l2jmobius.gameserver.model.spawn.AutoSpawnHandler.AutoSpawnInstance;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.util.BuilderUtil; import org.l2jmobius.gameserver.util.BuilderUtil;
@@ -54,8 +54,8 @@ public class AdminMammon implements IAdminCommandHandler
int npcId = 0; int npcId = 0;
int teleportIndex = -1; int teleportIndex = -1;
final AutoSpawnInstance blackSpawnInst = AutoSpawn.getInstance().getAutoSpawnInstance(SevenSigns.MAMMON_BLACKSMITH_ID, false); final AutoSpawnInstance blackSpawnInst = AutoSpawnHandler.getInstance().getAutoSpawnInstance(SevenSigns.MAMMON_BLACKSMITH_ID, false);
final AutoSpawnInstance merchSpawnInst = AutoSpawn.getInstance().getAutoSpawnInstance(SevenSigns.MAMMON_MERCHANT_ID, false); final AutoSpawnInstance merchSpawnInst = AutoSpawnHandler.getInstance().getAutoSpawnInstance(SevenSigns.MAMMON_MERCHANT_ID, false);
if (command.startsWith("admin_mammon_find")) if (command.startsWith("admin_mammon_find"))
{ {
try try
@@ -78,12 +78,13 @@ public class AdminMammon implements IAdminCommandHandler
if (blackSpawnInst != null) if (blackSpawnInst != null)
{ {
final List<NpcInstance> blackInst = blackSpawnInst.getNPCInstanceList(); final Queue<NpcInstance> blackInst = blackSpawnInst.getNPCInstanceList();
if (!blackInst.isEmpty()) if (!blackInst.isEmpty())
{ {
final int x1 = blackInst.get(0).getX(); final NpcInstance npc = blackInst.stream().findFirst().get();
final int y1 = blackInst.get(0).getY(); final int x1 = npc.getX();
final int z1 = blackInst.get(0).getZ(); final int y1 = npc.getY();
final int z1 = npc.getZ();
BuilderUtil.sendSysMessage(activeChar, "Blacksmith of Mammon: " + x1 + " " + y1 + " " + z1); BuilderUtil.sendSysMessage(activeChar, "Blacksmith of Mammon: " + x1 + " " + y1 + " " + z1);
if (teleportIndex == 1) if (teleportIndex == 1)
{ {
@@ -98,12 +99,13 @@ public class AdminMammon implements IAdminCommandHandler
if (merchSpawnInst != null) if (merchSpawnInst != null)
{ {
final List<NpcInstance> merchInst = merchSpawnInst.getNPCInstanceList(); final Queue<NpcInstance> merchInst = merchSpawnInst.getNPCInstanceList();
if (!merchInst.isEmpty()) if (!merchInst.isEmpty())
{ {
final int x2 = merchInst.get(0).getX(); final NpcInstance npc = merchInst.stream().findFirst().get();
final int y2 = merchInst.get(0).getY(); final int x2 = npc.getX();
final int z2 = merchInst.get(0).getZ(); final int y2 = npc.getY();
final int z2 = npc.getZ();
BuilderUtil.sendSysMessage(activeChar, "Merchant of Mammon: " + x2 + " " + y2 + " " + z2); BuilderUtil.sendSysMessage(activeChar, "Merchant of Mammon: " + x2 + " " + y2 + " " + z2);
if (teleportIndex == 2) if (teleportIndex == 2)
{ {
@@ -127,7 +129,7 @@ public class AdminMammon implements IAdminCommandHandler
if (merchSpawnInst != null) if (merchSpawnInst != null)
{ {
final long merchRespawn = AutoSpawn.getInstance().getTimeToNextSpawn(merchSpawnInst); final long merchRespawn = AutoSpawnHandler.getInstance().getTimeToNextSpawn(merchSpawnInst);
BuilderUtil.sendSysMessage(activeChar, "The Merchant of Mammon will respawn in " + (merchRespawn / 60000) + " minute(s)."); BuilderUtil.sendSysMessage(activeChar, "The Merchant of Mammon will respawn in " + (merchRespawn / 60000) + " minute(s).");
} }
else else
@@ -137,7 +139,7 @@ public class AdminMammon implements IAdminCommandHandler
if (blackSpawnInst != null) if (blackSpawnInst != null)
{ {
final long blackRespawn = AutoSpawn.getInstance().getTimeToNextSpawn(blackSpawnInst); final long blackRespawn = AutoSpawnHandler.getInstance().getTimeToNextSpawn(blackSpawnInst);
BuilderUtil.sendSysMessage(activeChar, "The Blacksmith of Mammon will respawn in " + (blackRespawn / 60000) + " minute(s)."); BuilderUtil.sendSysMessage(activeChar, "The Blacksmith of Mammon will respawn in " + (blackRespawn / 60000) + " minute(s).");
} }
else else

View File

@@ -21,7 +21,8 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -36,8 +37,8 @@ import org.l2jmobius.gameserver.instancemanager.CastleManager;
import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn; import org.l2jmobius.gameserver.model.spawn.AutoSpawnHandler;
import org.l2jmobius.gameserver.model.spawn.AutoSpawn.AutoSpawnInstance; import org.l2jmobius.gameserver.model.spawn.AutoSpawnHandler.AutoSpawnInstance;
import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.SignsSky; import org.l2jmobius.gameserver.network.serverpackets.SignsSky;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
@@ -102,10 +103,10 @@ public class SevenSigns
protected int _duskFestivalScore; protected int _duskFestivalScore;
protected int _compWinner; protected int _compWinner;
protected int _previousWinner; protected int _previousWinner;
private final Map<Integer, StatSet> _signsPlayerData; private final Map<Integer, StatSet> _signsPlayerData = new LinkedHashMap<>();
private final Map<Integer, Integer> _signsSealOwners; private final Map<Integer, Integer> _signsSealOwners = new LinkedHashMap<>();
private final Map<Integer, Integer> _signsDuskSealTotals; private final Map<Integer, Integer> _signsDuskSealTotals = new LinkedHashMap<>();
private final Map<Integer, Integer> _signsDawnSealTotals; private final Map<Integer, Integer> _signsDawnSealTotals = new LinkedHashMap<>();
private static AutoSpawnInstance _merchantSpawn; private static AutoSpawnInstance _merchantSpawn;
private static AutoSpawnInstance _blacksmithSpawn; private static AutoSpawnInstance _blacksmithSpawn;
private static AutoSpawnInstance _spiritInSpawn; private static AutoSpawnInstance _spiritInSpawn;
@@ -114,20 +115,15 @@ public class SevenSigns
private static AutoSpawnInstance _anakimSpawn; private static AutoSpawnInstance _anakimSpawn;
private static AutoSpawnInstance _crestofdawnspawn; private static AutoSpawnInstance _crestofdawnspawn;
private static AutoSpawnInstance _crestofduskspawn; private static AutoSpawnInstance _crestofduskspawn;
private static Map<Integer, AutoSpawnInstance> _oratorSpawns; private static List<AutoSpawnInstance> _oratorSpawns;
private static Map<Integer, AutoSpawnInstance> _preacherSpawns; private static List<AutoSpawnInstance> _preacherSpawns;
private static Map<Integer, AutoSpawnInstance> _marketeerSpawns; private static List<AutoSpawnInstance> _marketeerSpawns;
/** /**
* Instantiates a new seven signs. * Instantiates a new seven signs.
*/ */
public SevenSigns() public SevenSigns()
{ {
_signsPlayerData = new HashMap<>();
_signsSealOwners = new HashMap<>();
_signsDuskSealTotals = new HashMap<>();
_signsDawnSealTotals = new HashMap<>();
try try
{ {
restoreSevenSignsData(); restoreSevenSignsData();
@@ -185,22 +181,22 @@ public class SevenSigns
*/ */
public void spawnSevenSignsNPC() public void spawnSevenSignsNPC()
{ {
_merchantSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(MAMMON_MERCHANT_ID, false); _merchantSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(MAMMON_MERCHANT_ID, false);
_blacksmithSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(MAMMON_BLACKSMITH_ID, false); _blacksmithSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(MAMMON_BLACKSMITH_ID, false);
_marketeerSpawns = AutoSpawn.getInstance().getAutoSpawnInstances(MAMMON_MARKETEER_ID); _marketeerSpawns = AutoSpawnHandler.getInstance().getAutoSpawnInstances(MAMMON_MARKETEER_ID);
_spiritInSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(SPIRIT_IN_ID, false); _spiritInSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(SPIRIT_IN_ID, false);
_spiritOutSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(SPIRIT_OUT_ID, false); _spiritOutSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(SPIRIT_OUT_ID, false);
_lilithSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(LILITH_NPC_ID, false); _lilithSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(LILITH_NPC_ID, false);
_anakimSpawn = AutoSpawn.getInstance().getAutoSpawnInstance(ANAKIM_NPC_ID, false); _anakimSpawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(ANAKIM_NPC_ID, false);
_crestofdawnspawn = AutoSpawn.getInstance().getAutoSpawnInstance(CREST_OF_DAWN_ID, false); _crestofdawnspawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(CREST_OF_DAWN_ID, false);
_crestofduskspawn = AutoSpawn.getInstance().getAutoSpawnInstance(CREST_OF_DUSK_ID, false); _crestofduskspawn = AutoSpawnHandler.getInstance().getAutoSpawnInstance(CREST_OF_DUSK_ID, false);
_oratorSpawns = AutoSpawn.getInstance().getAutoSpawnInstances(ORATOR_NPC_ID); _oratorSpawns = AutoSpawnHandler.getInstance().getAutoSpawnInstances(ORATOR_NPC_ID);
_preacherSpawns = AutoSpawn.getInstance().getAutoSpawnInstances(PREACHER_NPC_ID); _preacherSpawns = AutoSpawnHandler.getInstance().getAutoSpawnInstances(PREACHER_NPC_ID);
if (isSealValidationPeriod() || isCompResultsPeriod()) if (isSealValidationPeriod() || isCompResultsPeriod())
{ {
for (AutoSpawnInstance spawnInst : _marketeerSpawns.values()) for (AutoSpawnInstance spawnInst : _marketeerSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, true); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, true);
} }
if ((getSealOwner(SEAL_GNOSIS) == getCabalHighestScore()) && (getSealOwner(SEAL_GNOSIS) != CABAL_NULL)) if ((getSealOwner(SEAL_GNOSIS) == getCabalHighestScore()) && (getSealOwner(SEAL_GNOSIS) != CABAL_NULL))
@@ -210,24 +206,24 @@ public class SevenSigns
_blacksmithSpawn.setBroadcast(false); _blacksmithSpawn.setBroadcast(false);
} }
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_blacksmithSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_blacksmithSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_blacksmithSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_blacksmithSpawn, true);
} }
for (AutoSpawnInstance spawnInst : _oratorSpawns.values()) for (AutoSpawnInstance spawnInst : _oratorSpawns)
{ {
if (!AutoSpawn.getInstance().getAutoSpawnInstance(spawnInst.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(spawnInst.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, true); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, true);
} }
} }
for (AutoSpawnInstance spawnInst : _preacherSpawns.values()) for (AutoSpawnInstance spawnInst : _preacherSpawns)
{ {
if (!AutoSpawn.getInstance().getAutoSpawnInstance(spawnInst.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(spawnInst.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, true); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, true);
} }
} }
@@ -238,15 +234,15 @@ public class SevenSigns
} }
else else
{ {
AutoSpawn.getInstance().setSpawnActive(_blacksmithSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_blacksmithSpawn, false);
for (AutoSpawnInstance spawnInst : _oratorSpawns.values()) for (AutoSpawnInstance spawnInst : _oratorSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, false); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, false);
} }
for (AutoSpawnInstance spawnInst : _preacherSpawns.values()) for (AutoSpawnInstance spawnInst : _preacherSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, false); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, false);
} }
AutoChatHandler.getInstance().setAutoChatActive(false); AutoChatHandler.getInstance().setAutoChatActive(false);
@@ -259,87 +255,87 @@ public class SevenSigns
_merchantSpawn.setBroadcast(false); _merchantSpawn.setBroadcast(false);
} }
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_merchantSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_merchantSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_merchantSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_merchantSpawn, true);
} }
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_spiritInSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_spiritInSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_spiritInSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_spiritInSpawn, true);
} }
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_spiritOutSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_spiritOutSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_spiritOutSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_spiritOutSpawn, true);
} }
switch (getCabalHighestScore()) switch (getCabalHighestScore())
{ {
case CABAL_DAWN: case CABAL_DAWN:
{ {
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_lilithSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_lilithSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_lilithSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_lilithSpawn, true);
} }
AutoSpawn.getInstance().setSpawnActive(_anakimSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_anakimSpawn, false);
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_crestofdawnspawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_crestofdawnspawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_crestofdawnspawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_crestofdawnspawn, true);
} }
AutoSpawn.getInstance().setSpawnActive(_crestofduskspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofduskspawn, false);
break; break;
} }
case CABAL_DUSK: case CABAL_DUSK:
{ {
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_anakimSpawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_anakimSpawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_anakimSpawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_anakimSpawn, true);
} }
AutoSpawn.getInstance().setSpawnActive(_lilithSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_lilithSpawn, false);
if (!AutoSpawn.getInstance().getAutoSpawnInstance(_crestofduskspawn.getObjectId(), true).isSpawnActive()) if (!AutoSpawnHandler.getInstance().getAutoSpawnInstance(_crestofduskspawn.getObjectId(), true).isSpawnActive())
{ {
AutoSpawn.getInstance().setSpawnActive(_crestofduskspawn, true); AutoSpawnHandler.getInstance().setSpawnActive(_crestofduskspawn, true);
} }
AutoSpawn.getInstance().setSpawnActive(_crestofdawnspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofdawnspawn, false);
break; break;
} }
} }
} }
else else
{ {
AutoSpawn.getInstance().setSpawnActive(_merchantSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_merchantSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_lilithSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_lilithSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_anakimSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_anakimSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_crestofdawnspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofdawnspawn, false);
AutoSpawn.getInstance().setSpawnActive(_crestofduskspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofduskspawn, false);
AutoSpawn.getInstance().setSpawnActive(_spiritInSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_spiritInSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_spiritOutSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_spiritOutSpawn, false);
} }
} }
else else
{ {
AutoSpawn.getInstance().setSpawnActive(_merchantSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_merchantSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_blacksmithSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_blacksmithSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_lilithSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_lilithSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_anakimSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_anakimSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_crestofdawnspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofdawnspawn, false);
AutoSpawn.getInstance().setSpawnActive(_crestofduskspawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_crestofduskspawn, false);
AutoSpawn.getInstance().setSpawnActive(_spiritInSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_spiritInSpawn, false);
AutoSpawn.getInstance().setSpawnActive(_spiritOutSpawn, false); AutoSpawnHandler.getInstance().setSpawnActive(_spiritOutSpawn, false);
for (AutoSpawnInstance spawnInst : _oratorSpawns.values()) for (AutoSpawnInstance spawnInst : _oratorSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, false); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, false);
} }
for (AutoSpawnInstance spawnInst : _preacherSpawns.values()) for (AutoSpawnInstance spawnInst : _preacherSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, false); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, false);
} }
for (AutoSpawnInstance spawnInst : _marketeerSpawns.values()) for (AutoSpawnInstance spawnInst : _marketeerSpawns)
{ {
AutoSpawn.getInstance().setSpawnActive(spawnInst, false); AutoSpawnHandler.getInstance().setSpawnActive(spawnInst, false);
} }
AutoChatHandler.getInstance().setAutoChatActive(false); AutoChatHandler.getInstance().setAutoChatActive(false);

View File

@@ -19,13 +19,18 @@ package org.l2jmobius.gameserver.model.spawn;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.LinkedList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.concurrent.ThreadPool;
@@ -41,53 +46,85 @@ import org.l2jmobius.gameserver.model.actor.instance.NpcInstance;
import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate; import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
/** /**
* Auto Spawn Handler Allows spawning of a NPC object based on a timer. (From the official idea used for the Merchant and Blacksmith of Mammon) General Usage: - Call registerSpawn() with the parameters listed below. int npcId int[][] spawnPoints or specify NULL to add points later. int initialDelay * Auto Spawn handler.<br>
* (If < 0 = default value) int respawnDelay (If < 0 = default value) int despawnDelay (If < 0 = default value or if = 0, function disabled) spawnPoints is a standard two-dimensional int array containing X,Y and Z coordinates. The default respawn/despawn delays are currently every hour (as for * Allows spawning of a NPC object based on a timer.<br>
* Mammon on official servers). - The resulting AutoSpawnInstance object represents the newly added spawn index. - The internal methods of this object can be used to adjust random spawning, for instance a call to setRandomSpawn(1, true); would set the spawn at index 1 to be randomly rather than * (From the official idea used for the Merchant and Blacksmith of Mammon)<br>
* sequentially-based. - Also they can be used to specify the number of NPC instances to spawn using setSpawnCount(), and broadcast a message to all users using setBroadcast(). Random Spawning = OFF by default Broadcasting = OFF by default * General Usage: - Call registerSpawn() with the parameters listed below.<br>
* int npcId int[][] spawnPoints or specify NULL to add points later.<br>
* int initialDelay (If < 0 = default value) int respawnDelay (If < 0 = default value)<br>
* int despawnDelay (If < 0 = default value or if = 0, function disabled)<br>
* spawnPoints is a standard two-dimensional int array containing X,Y and Z coordinates.<br>
* The default respawn/despawn delays are currently every hour (as for Mammon on official servers).<br>
* The resulting AutoSpawnInstance object represents the newly added spawn index.<br>
* The internal methods of this object can be used to adjust random spawning, for instance a call to setRandomSpawn(1, true); would set the spawn at index 1 to be randomly rather than sequentially-based.<br>
* Also they can be used to specify the number of NPC instances to spawn using setSpawnCount(), and broadcast a message to all users using setBroadcast().<br>
* Random Spawning = OFF by default Broadcasting = OFF by default
* @author Tempy * @author Tempy
*/ */
public class AutoSpawn public class AutoSpawnHandler
{ {
protected static final Logger LOGGER = Logger.getLogger(AutoSpawn.class.getName()); protected static final Logger LOGGER = Logger.getLogger(AutoSpawnHandler.class.getName());
private static final int DEFAULT_INITIAL_SPAWN = 30000; // 30 seconds after registration private static final int DEFAULT_INITIAL_SPAWN = 30000; // 30 seconds after registration
private static final int DEFAULT_RESPAWN = 3600000; // 1 hour in millisecs private static final int DEFAULT_RESPAWN = 3600000; // 1 hour in millisecs
private static final int DEFAULT_DESPAWN = 3600000; // 1 hour in millisecs private static final int DEFAULT_DESPAWN = 3600000; // 1 hour in millisecs
protected Map<Integer, AutoSpawnInstance> _registeredSpawns; protected Map<Integer, AutoSpawnInstance> _registeredSpawns = new ConcurrentHashMap<>();
protected Map<Integer, ScheduledFuture<?>> _runningSpawns; protected Map<Integer, ScheduledFuture<?>> _runningSpawns = new ConcurrentHashMap<>();
protected boolean _activeState = true; protected boolean _activeState = true;
protected AutoSpawn() protected AutoSpawnHandler()
{ {
_registeredSpawns = new HashMap<>();
_runningSpawns = new HashMap<>();
restoreSpawnData(); restoreSpawnData();
} }
public int size() public int size()
{
synchronized (_registeredSpawns)
{ {
return _registeredSpawns.size(); return _registeredSpawns.size();
} }
public void reload()
{
// unload
unload();
// create clean list
_registeredSpawns.clear();
_runningSpawns.clear();
// load
restoreSpawnData();
}
public void unload()
{
// stop all timers
for (ScheduledFuture<?> sf : _runningSpawns.values())
{
if (sf != null)
{
sf.cancel(true);
}
}
// unregister all registered spawns
for (AutoSpawnInstance asi : _registeredSpawns.values())
{
if (asi != null)
{
removeSpawn(asi);
}
}
} }
private void restoreSpawnData() private void restoreSpawnData()
{ {
try (Connection con = DatabaseFactory.getConnection()) try (Connection con = DatabaseFactory.getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM random_spawn ORDER BY groupId ASC");
PreparedStatement ps = con.prepareStatement("SELECT * FROM random_spawn_loc WHERE groupId=?"))
{ {
PreparedStatement statement = null;
PreparedStatement statement2 = null;
ResultSet rs = null;
ResultSet rs2 = null;
// Restore spawn group data, then the location data. // Restore spawn group data, then the location data.
statement = con.prepareStatement("SELECT * FROM random_spawn ORDER BY groupId ASC");
rs = statement.executeQuery();
while (rs.next()) while (rs.next())
{ {
// Register random spawn group, set various options on the created spawn instance. // Register random spawn group, set various options on the created spawn instance.
@@ -97,31 +134,27 @@ public class AutoSpawn
spawnInst.setRandomSpawn(rs.getBoolean("randomSpawn")); spawnInst.setRandomSpawn(rs.getBoolean("randomSpawn"));
// Restore the spawn locations for this spawn group/instance. // Restore the spawn locations for this spawn group/instance.
statement2 = con.prepareStatement("SELECT * FROM random_spawn_loc WHERE groupId=?"); ps.setInt(1, rs.getInt("groupId"));
statement2.setInt(1, rs.getInt("groupId")); try (ResultSet rs2 = ps.executeQuery())
rs2 = statement2.executeQuery(); {
ps.clearParameters();
while (rs2.next()) while (rs2.next())
{ {
// Add each location to the spawn group/instance. // Add each location to the spawn group/instance.
spawnInst.addSpawnLocation(rs2.getInt("x"), rs2.getInt("y"), rs2.getInt("z"), rs2.getInt("heading")); spawnInst.addSpawnLocation(rs2.getInt("x"), rs2.getInt("y"), rs2.getInt("z"), rs2.getInt("heading"));
} }
statement2.close();
rs2.close();
} }
}
statement.close();
rs.close();
} }
catch (Exception e) catch (Exception e)
{ {
LOGGER.warning("AutoSpawnHandler: Could not restore spawn data: " + e); LOGGER.log(Level.WARNING, "AutoSpawnHandler: Could not restore spawn data: " + e.getMessage(), e);
} }
} }
/** /**
* Registers a spawn with the given parameters with the spawner, and marks it as active. Returns a AutoSpawnInstance containing info about the spawn. * Registers a spawn with the given parameters with the spawner, and marks it as active.<br>
* Returns a AutoSpawnInstance containing info about the spawn.
* @param npcId * @param npcId
* @param spawnPoints * @param spawnPoints
* @param initialDelay (If < 0 = default value) * @param initialDelay (If < 0 = default value)
@@ -142,24 +175,21 @@ public class AutoSpawn
final int newId = IdManager.getInstance().getNextId(); final int newId = IdManager.getInstance().getNextId();
newSpawn._objectId = newId; newSpawn._objectId = newId;
synchronized (_registeredSpawns)
{
_registeredSpawns.put(newId, newSpawn); _registeredSpawns.put(newId, newSpawn);
}
setSpawnActive(newSpawn, true); setSpawnActive(newSpawn, true);
return newSpawn; return newSpawn;
} }
/** /**
* Registers a spawn with the given parameters with the spawner, and marks it as active. Returns a AutoSpawnInstance containing info about the spawn.<br> * Registers a spawn with the given parameters with the spawner, and marks it as active.<br>
* Returns a AutoSpawnInstance containing info about the spawn.<br>
* <b>Warning:</b> Spawn locations must be specified separately using addSpawnLocation(). * <b>Warning:</b> Spawn locations must be specified separately using addSpawnLocation().
* @param npcId * @param npcId
* @param initialDelay (If < 0 = default value) * @param initialDelay (If < 0 = default value)
* @param respawnDelay (If < 0 = default value) * @param respawnDelay (If < 0 = default value)
* @param despawnDelay (If < 0 = default value or if = 0, function disabled) * @param despawnDelay (If < 0 = default value or if = 0, function disabled)
* @return spawnInst * @return AutoSpawnInstance spawnInst
*/ */
public AutoSpawnInstance registerSpawn(int npcId, int initialDelay, int respawnDelay, int despawnDelay) public AutoSpawnInstance registerSpawn(int npcId, int initialDelay, int respawnDelay, int despawnDelay)
{ {
@@ -169,37 +199,28 @@ public class AutoSpawn
/** /**
* Remove a registered spawn from the list, specified by the given spawn instance. * Remove a registered spawn from the list, specified by the given spawn instance.
* @param spawnInst * @param spawnInst
* @return removedSuccessfully * @return boolean removedSuccessfully
*/ */
public boolean removeSpawn(AutoSpawnInstance spawnInst) public boolean removeSpawn(AutoSpawnInstance spawnInst)
{ {
synchronized (_registeredSpawns) if (!isSpawnRegistered(spawnInst))
{
if (!_registeredSpawns.containsValue(spawnInst))
{ {
return false; return false;
} }
// Try to remove from the list of registered spawns if it exists.
_registeredSpawns.remove(spawnInst.getNpcId());
synchronized (_runningSpawns)
{
// Cancel the currently associated running scheduled task.
final ScheduledFuture<?> respawnTask = _runningSpawns.remove(spawnInst._objectId);
try try
{ {
respawnTask.cancel(false); // Try to remove from the list of registered spawns if it exists.
_registeredSpawns.remove(spawnInst.getNpcId());
// Cancel the currently associated running scheduled task.
_runningSpawns.remove(spawnInst._objectId).cancel(false);
} }
catch (Exception e) catch (Exception e)
{ {
LOGGER.warning("AutoSpawnHandler: Could not auto spawn for NPC ID " + spawnInst._npcId + " (Object ID = " + spawnInst._objectId + "): " + e); LOGGER.log(Level.WARNING, "AutoSpawnHandler: Could not auto spawn for NPC ID " + spawnInst._npcId + " (Object ID = " + spawnInst._objectId + "): " + e.getMessage(), e);
return false; return false;
} }
}
}
return true; return true;
} }
@@ -210,12 +231,7 @@ public class AutoSpawn
*/ */
public void removeSpawn(int objectId) public void removeSpawn(int objectId)
{ {
AutoSpawnInstance spawn = null; removeSpawn(_registeredSpawns.get(objectId));
synchronized (_registeredSpawns)
{
spawn = _registeredSpawns.get(objectId);
}
removeSpawn(spawn);
} }
/** /**
@@ -231,46 +247,30 @@ public class AutoSpawn
} }
final int objectId = spawnInst._objectId; final int objectId = spawnInst._objectId;
if (isSpawnRegistered(objectId)) if (!isSpawnRegistered(objectId))
{ {
return;
}
ScheduledFuture<?> spawnTask = null; ScheduledFuture<?> spawnTask = null;
if (isActive) if (isActive)
{ {
final AutoSpawner rs = new AutoSpawner(objectId); final AutoSpawner rs = new AutoSpawner(objectId);
if (spawnInst._desDelay > 0) spawnTask = spawnInst._desDelay > 0 ? ThreadPool.scheduleAtFixedRate(rs, spawnInst._initDelay, spawnInst._resDelay) : ThreadPool.schedule(rs, spawnInst._initDelay);
{
spawnTask = ThreadPool.scheduleAtFixedRate(rs, spawnInst._initDelay, spawnInst._resDelay);
}
else
{
spawnTask = ThreadPool.schedule(rs, spawnInst._initDelay);
}
synchronized (_runningSpawns)
{
_runningSpawns.put(objectId, spawnTask); _runningSpawns.put(objectId, spawnTask);
} }
}
else else
{ {
final AutoDespawner rd = new AutoDespawner(objectId); final AutoDespawner rd = new AutoDespawner(objectId);
synchronized (_runningSpawns)
{
spawnTask = _runningSpawns.remove(objectId); spawnTask = _runningSpawns.remove(objectId);
}
if (spawnTask != null) if (spawnTask != null)
{ {
spawnTask.cancel(false); spawnTask.cancel(false);
} }
ThreadPool.schedule(rd, 0); ThreadPool.schedule(rd, 0);
} }
spawnInst.setSpawnActive(isActive); spawnInst.setSpawnActive(isActive);
} }
}
/** /**
* Sets the active state of all auto spawn instances to that specified, and cancels the scheduled spawn task if necessary. * Sets the active state of all auto spawn instances to that specified, and cancels the scheduled spawn task if necessary.
@@ -283,13 +283,7 @@ public class AutoSpawn
return; return;
} }
Collection<AutoSpawnInstance> instances; for (AutoSpawnInstance spawnInst : _registeredSpawns.values())
synchronized (_registeredSpawns)
{
instances = _registeredSpawns.values();
}
for (AutoSpawnInstance spawnInst : instances)
{ {
setSpawnActive(spawnInst, isActive); setSpawnActive(spawnInst, isActive);
} }
@@ -304,21 +298,8 @@ public class AutoSpawn
*/ */
public long getTimeToNextSpawn(AutoSpawnInstance spawnInst) public long getTimeToNextSpawn(AutoSpawnInstance spawnInst)
{ {
if (spawnInst == null)
{
return -1;
}
final int objectId = spawnInst.getObjectId(); final int objectId = spawnInst.getObjectId();
return !isSpawnRegistered(objectId) ? -1 : _runningSpawns.containsKey(objectId) ? _runningSpawns.get(objectId).getDelay(TimeUnit.MILLISECONDS) : 0;
synchronized (_runningSpawns)
{
final ScheduledFuture<?> task = _runningSpawns.get(objectId);
if (task != null)
{
return task.getDelay(TimeUnit.MILLISECONDS);
}
}
return -1;
} }
/** /**
@@ -331,58 +312,47 @@ public class AutoSpawn
public AutoSpawnInstance getAutoSpawnInstance(int id, boolean isObjectId) public AutoSpawnInstance getAutoSpawnInstance(int id, boolean isObjectId)
{ {
if (isObjectId) if (isObjectId)
{
if (isSpawnRegistered(id))
{ {
return _registeredSpawns.get(id); return _registeredSpawns.get(id);
} }
Collection<AutoSpawnInstance> instances;
synchronized (_registeredSpawns)
{
instances = _registeredSpawns.values();
} }
else
for (AutoSpawnInstance spawnInst : instances) {
for (AutoSpawnInstance spawnInst : _registeredSpawns.values())
{ {
if (spawnInst.getNpcId() == id) if (spawnInst.getNpcId() == id)
{ {
return spawnInst; return spawnInst;
} }
} }
}
return null; return null;
} }
public Map<Integer, AutoSpawnInstance> getAutoSpawnInstances(int npcId) public List<AutoSpawnInstance> getAutoSpawnInstances(int npcId)
{ {
final Map<Integer, AutoSpawnInstance> spawnInstList = new HashMap<>(); final List<AutoSpawnInstance> result = new LinkedList<>();
Collection<AutoSpawnInstance> instances; for (AutoSpawnInstance spawnInst : _registeredSpawns.values())
synchronized (_registeredSpawns)
{
instances = _registeredSpawns.values();
}
for (AutoSpawnInstance spawnInst : instances)
{ {
if (spawnInst.getNpcId() == npcId) if (spawnInst.getNpcId() == npcId)
{ {
spawnInstList.put(spawnInst.getObjectId(), spawnInst); result.add(spawnInst);
} }
} }
return result;
return spawnInstList;
} }
/** /**
* Tests if the specified object ID is assigned to an auto spawn. * Tests if the specified object ID is assigned to an auto spawn.
* @param objectId * @param objectId
* @return boolean isAssigned * @return isAssigned
*/ */
public boolean isSpawnRegistered(int objectId) public boolean isSpawnRegistered(int objectId)
{
synchronized (_registeredSpawns)
{ {
return _registeredSpawns.containsKey(objectId); return _registeredSpawns.containsKey(objectId);
} }
}
/** /**
* Tests if the specified spawn instance is assigned to an auto spawn. * Tests if the specified spawn instance is assigned to an auto spawn.
@@ -390,15 +360,12 @@ public class AutoSpawn
* @return boolean isAssigned * @return boolean isAssigned
*/ */
public boolean isSpawnRegistered(AutoSpawnInstance spawnInst) public boolean isSpawnRegistered(AutoSpawnInstance spawnInst)
{
synchronized (_registeredSpawns)
{ {
return _registeredSpawns.containsValue(spawnInst); return _registeredSpawns.containsValue(spawnInst);
} }
}
/** /**
* AutoSpawner Class<br> * AutoSpawner class<br>
* This handles the main spawn task for an auto spawn instance, and initializes a despawner if required. * This handles the main spawn task for an auto spawn instance, and initializes a despawner if required.
* @author Tempy * @author Tempy
*/ */
@@ -415,14 +382,9 @@ public class AutoSpawn
public void run() public void run()
{ {
try try
{
AutoSpawnInstance spawnInst = null;
synchronized (_registeredSpawns)
{ {
// Retrieve the required spawn instance for this spawn task. // Retrieve the required spawn instance for this spawn task.
spawnInst = _registeredSpawns.get(_objectId); final AutoSpawnInstance spawnInst = _registeredSpawns.get(_objectId);
}
// If the spawn is not scheduled to be active, cancel the spawn task. // If the spawn is not scheduled to be active, cancel the spawn task.
if (!spawnInst.isSpawnActive()) if (!spawnInst.isSpawnActive())
@@ -442,12 +404,11 @@ public class AutoSpawn
final int locationCount = locationList.size(); final int locationCount = locationList.size();
int locationIndex = Rnd.get(locationCount); int locationIndex = Rnd.get(locationCount);
// If random spawning is disabled, the spawn at the next set of co-ordinates after the last. If the index is greater than the number of possible spawns, reset the counter to zero. // If random spawning is disabled, the spawn at the next set of co-ordinates after the last.
// If the index is greater than the number of possible spawns, reset the counter to zero.
if (!spawnInst.isRandomSpawn()) if (!spawnInst.isRandomSpawn())
{ {
locationIndex = spawnInst._lastLocIndex; locationIndex = spawnInst._lastLocIndex + 1;
locationIndex++;
if (locationIndex == locationCount) if (locationIndex == locationCount)
{ {
locationIndex = 0; locationIndex = 0;
@@ -479,9 +440,7 @@ public class AutoSpawn
{ {
newSpawn.setHeading(heading); newSpawn.setHeading(heading);
} }
newSpawn.setAmount(spawnInst.getSpawnCount()); newSpawn.setAmount(spawnInst.getSpawnCount());
if (spawnInst._desDelay == 0) if (spawnInst._desDelay == 0)
{ {
newSpawn.setRespawnDelay(spawnInst._resDelay); newSpawn.setRespawnDelay(spawnInst._resDelay);
@@ -509,25 +468,36 @@ public class AutoSpawn
spawnInst.addNpcInstance(npcInst); spawnInst.addNpcInstance(npcInst);
} }
} }
newSpawn.stopRespawn();
final String nearestTown = MapRegionData.getInstance().getClosestTownName(npcInst); if (npcInst != null)
{
if (spawnInst.isRandomSpawn())
{
while (!npcInst.getKnownList().getKnownCharactersInRadius(5).isEmpty())
{
// LOGGER.log(Level.INFO, "AutoSpawnHandler: Random spawn location " + npcInst.getLocation() + " for " + npcInst + " is occupied. Teleporting...");
npcInst.teleToLocation(locationList.get(Rnd.get(locationList.size())), false);
}
}
// Announce to all players that the spawn has taken place, with the nearest town location. // Announce to all players that the spawn has taken place, with the nearest town location.
if (spawnInst.isBroadcasting() && (npcInst != null)) final String nearestTown = MapRegionData.getInstance().getClosestTownName(npcInst);
if (spawnInst.isBroadcasting())
{ {
Announcements.getInstance().announceToAll("The " + npcInst.getName() + " has spawned near " + nearestTown + "!"); Announcements.getInstance().announceToAll("The " + npcInst.getName() + " has spawned near " + nearestTown + "!");
} }
}
// If there is no despawn time, do not create a despawn task. // If there is no despawn time, do not create a despawn task.
if (spawnInst.getDespawnDelay() > 0) if (spawnInst.getDespawnDelay() > 0)
{ {
final AutoDespawner rd = new AutoDespawner(_objectId); ThreadPool.schedule(new AutoDespawner(_objectId), spawnInst.getDespawnDelay() - 1000);
ThreadPool.schedule(rd, spawnInst.getDespawnDelay() - 1000);
} }
} }
catch (Exception e) catch (Exception e)
{ {
LOGGER.warning("AutoSpawnHandler: An error occurred while initializing spawn instance (Object ID = " + _objectId + "): " + e); LOGGER.log(Level.WARNING, "AutoSpawnHandler: An error occurred while initializing spawn instance (Object ID = " + _objectId + "): " + e.getMessage(), e);
} }
} }
} }
@@ -551,39 +521,28 @@ public class AutoSpawn
{ {
try try
{ {
AutoSpawnInstance spawnInst = null; final AutoSpawnInstance spawnInst = _registeredSpawns.get(_objectId);
synchronized (_registeredSpawns)
{
spawnInst = _registeredSpawns.get(_objectId);
}
if (spawnInst == null) if (spawnInst == null)
{ {
LOGGER.info("AutoSpawnHandler: No spawn registered for object ID = " + _objectId + "."); LOGGER.info("AutoSpawnHandler: No spawn registered for object ID = " + _objectId + ".");
return; return;
} }
final List<NpcInstance> npcs = spawnInst.getNPCInstanceList(); for (NpcInstance npcInst : spawnInst.getNPCInstanceList())
if (npcs == null)
{ {
LOGGER.info("AutoSpawnHandler: No spawn registered"); if (npcInst == null)
return;
}
for (NpcInstance npc : npcs)
{
if (npc == null)
{ {
continue; continue;
} }
npc.deleteMe(); npcInst.deleteMe();
spawnInst.removeNpcInstance(npc); SpawnTable.getInstance().deleteSpawn(npcInst.getSpawn(), false);
spawnInst.removeNpcInstance(npcInst);
} }
} }
catch (Exception e) catch (Exception e)
{ {
LOGGER.warning("AutoSpawnHandler: An error occurred while despawning spawn (Object ID = " + _objectId + "): " + e); LOGGER.log(Level.WARNING, "AutoSpawnHandler: An error occurred while despawning spawn (Object ID = " + _objectId + "): " + e.getMessage(), e);
} }
} }
} }
@@ -593,7 +552,7 @@ public class AutoSpawn
* Stores information about a registered auto spawn. * Stores information about a registered auto spawn.
* @author Tempy * @author Tempy
*/ */
public class AutoSpawnInstance public static class AutoSpawnInstance
{ {
protected int _objectId; protected int _objectId;
@@ -611,9 +570,9 @@ public class AutoSpawn
protected int _lastLocIndex = -1; protected int _lastLocIndex = -1;
private final List<NpcInstance> _npcList = new ArrayList<>(); private final Queue<NpcInstance> _npcList = new ConcurrentLinkedQueue<>();
private final List<Location> _locList = new ArrayList<>(); private final List<Location> _locList = new CopyOnWriteArrayList<>();
private boolean _spawnActive; private boolean _spawnActive;
@@ -679,7 +638,7 @@ public class AutoSpawn
return _locList; return _locList;
} }
public List<NpcInstance> getNPCInstanceList() public Queue<NpcInstance> getNPCInstanceList()
{ {
return _npcList; return _npcList;
} }
@@ -699,14 +658,14 @@ public class AutoSpawn
_spawnCount = spawnCount; _spawnCount = spawnCount;
} }
public void setRandomSpawn(boolean random) public void setRandomSpawn(boolean randValue)
{ {
_randomSpawn = random; _randomSpawn = randValue;
} }
public void setBroadcast(boolean broadcast) public void setBroadcast(boolean broadcastValue)
{ {
_broadcastAnnouncement = broadcast; _broadcastAnnouncement = broadcastValue;
} }
public boolean isSpawnActive() public boolean isSpawnActive()
@@ -731,11 +690,7 @@ public class AutoSpawn
public boolean addSpawnLocation(int[] spawnLoc) public boolean addSpawnLocation(int[] spawnLoc)
{ {
if (spawnLoc.length != 3) return (spawnLoc.length == 3) && addSpawnLocation(spawnLoc[0], spawnLoc[1], spawnLoc[2], -1);
{
return false;
}
return addSpawnLocation(spawnLoc[0], spawnLoc[1], spawnLoc[2], -1);
} }
public Location removeSpawnLocation(int locIndex) public Location removeSpawnLocation(int locIndex)
@@ -751,13 +706,13 @@ public class AutoSpawn
} }
} }
public static AutoSpawn getInstance() public static AutoSpawnHandler getInstance()
{ {
return SingletonHolder.INSTANCE; return SingletonHolder.INSTANCE;
} }
private static class SingletonHolder private static class SingletonHolder
{ {
protected static final AutoSpawn INSTANCE = new AutoSpawn(); protected static final AutoSpawnHandler INSTANCE = new AutoSpawnHandler();
} }
} }

View File

@@ -20,7 +20,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
import java.util.Collection; import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -32,7 +32,6 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.database.DatabaseFactory;
@@ -78,11 +77,6 @@ public class AutoSpawnHandler
restoreSpawnData(); restoreSpawnData();
} }
public static AutoSpawnHandler getInstance()
{
return SingletonHolder.INSTANCE;
}
public int size() public int size()
{ {
return _registeredSpawns.size(); return _registeredSpawns.size();
@@ -638,9 +632,14 @@ public class AutoSpawnHandler
return _npcList; return _npcList;
} }
public Collection<Spawn> getSpawns() public List<Spawn> getSpawns()
{ {
return _npcList.stream().map(Npc::getSpawn).collect(Collectors.toList()); final List<Spawn> npcSpawns = new ArrayList<>();
for (Npc npcInst : _npcList)
{
npcSpawns.add(npcInst.getSpawn());
}
return npcSpawns;
} }
public void setSpawnCount(int spawnCount) public void setSpawnCount(int spawnCount)
@@ -696,6 +695,11 @@ public class AutoSpawnHandler
} }
} }
public static AutoSpawnHandler getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder private static class SingletonHolder
{ {
protected static final AutoSpawnHandler INSTANCE = new AutoSpawnHandler(); protected static final AutoSpawnHandler INSTANCE = new AutoSpawnHandler();

View File

@@ -20,7 +20,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
import java.util.Collection; import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -32,7 +32,6 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.concurrent.ThreadPool;
import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.database.DatabaseFactory;
@@ -78,11 +77,6 @@ public class AutoSpawnHandler
restoreSpawnData(); restoreSpawnData();
} }
public static AutoSpawnHandler getInstance()
{
return SingletonHolder.INSTANCE;
}
public int size() public int size()
{ {
return _registeredSpawns.size(); return _registeredSpawns.size();
@@ -638,9 +632,14 @@ public class AutoSpawnHandler
return _npcList; return _npcList;
} }
public Collection<Spawn> getSpawns() public List<Spawn> getSpawns()
{ {
return _npcList.stream().map(Npc::getSpawn).collect(Collectors.toList()); final List<Spawn> npcSpawns = new ArrayList<>();
for (Npc npcInst : _npcList)
{
npcSpawns.add(npcInst.getSpawn());
}
return npcSpawns;
} }
public void setSpawnCount(int spawnCount) public void setSpawnCount(int spawnCount)
@@ -696,6 +695,11 @@ public class AutoSpawnHandler
} }
} }
public static AutoSpawnHandler getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder private static class SingletonHolder
{ {
protected static final AutoSpawnHandler INSTANCE = new AutoSpawnHandler(); protected static final AutoSpawnHandler INSTANCE = new AutoSpawnHandler();