Proper handling for Quest timers concurrency.
This commit is contained in:
parent
25d3220ce2
commit
99c209f0ba
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -87,10 +86,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -252,7 +248,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -267,16 +263,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -284,26 +270,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -316,31 +297,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -349,30 +327,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -384,10 +359,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -398,20 +391,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2833,25 +2823,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -88,10 +87,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -254,7 +250,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -269,16 +265,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -286,26 +272,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -318,31 +299,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -351,30 +329,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,10 +361,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,20 +393,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2835,25 +2825,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -89,10 +88,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -255,7 +251,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -270,16 +266,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -287,26 +273,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,31 +300,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,30 +330,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,10 +362,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -401,20 +394,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2836,25 +2826,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -90,10 +89,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -255,7 +251,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -270,16 +266,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -287,26 +273,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,31 +300,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,30 +330,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,10 +362,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -401,20 +394,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2836,25 +2826,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -90,10 +89,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -255,7 +251,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -270,16 +266,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -287,26 +273,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,31 +300,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,30 +330,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,10 +362,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -401,20 +394,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2836,25 +2826,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -90,10 +89,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -255,7 +251,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -270,16 +266,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -287,26 +273,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,31 +300,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,30 +330,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,10 +362,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -401,20 +394,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2836,25 +2826,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -90,10 +89,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -255,7 +251,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -270,16 +266,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -287,26 +273,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,31 +300,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,30 +330,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,10 +362,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -401,20 +394,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2836,25 +2826,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -90,10 +89,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -265,7 +261,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -280,16 +276,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -297,26 +283,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,31 +310,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -362,30 +340,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -397,10 +372,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -411,20 +404,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2846,25 +2836,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -27,6 +27,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
@ -64,10 +65,10 @@ public class Quest extends ManagedScript
|
||||
private static final String HTML_NONE_AVAILABLE = "<html><body>You are either not on a quest that involves this NPC, or you don't meet this NPC's minimum quest requirements.</body></html>";
|
||||
private static final String HTML_ALREADY_COMPLETED = "<html><body>This quest has already been completed.</body></html>";
|
||||
|
||||
/** HashMap containing events from String value of the event */
|
||||
private static Map<String, Quest> _allEventsS = new HashMap<>();
|
||||
/** HashMap containing lists of timers from the name of the timer */
|
||||
private final Map<String, ArrayList<QuestTimer>> _allEventTimers = new HashMap<>();
|
||||
/** Map containing events from String value of the event */
|
||||
private static Map<String, Quest> _allEvents = new HashMap<>();
|
||||
/** Map containing lists of timers from the name of the timer */
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
|
||||
private final int _questId;
|
||||
private final String _prefixPath; // used only for admin_quest_reload
|
||||
@ -140,7 +141,7 @@ public class Quest extends ManagedScript
|
||||
*/
|
||||
public static Collection<Quest> findAllEvents()
|
||||
{
|
||||
return _allEventsS.values();
|
||||
return _allEvents.values();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -168,7 +169,7 @@ public class Quest extends ManagedScript
|
||||
}
|
||||
else
|
||||
{
|
||||
_allEventsS.put(getName(), this);
|
||||
_allEvents.put(getName(), this);
|
||||
}
|
||||
|
||||
initGlobalData();
|
||||
@ -317,10 +318,12 @@ public class Quest extends ManagedScript
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param time
|
||||
* @param npc
|
||||
* @param player
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, NpcInstance, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, NpcInstance, PlayerInstance, boolean)
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, NpcInstance npc, PlayerInstance player)
|
||||
{
|
||||
@ -328,53 +331,43 @@ public class Quest extends ManagedScript
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a timer to the quest, if it doesn't exist already. If the timer is repeatable, it will auto-fire automatically, at a fixed rate, until explicitly canceled.
|
||||
* @param name name of the timer (also passed back as "event" in onAdvEvent)
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc npc associated with this timer (can be null)
|
||||
* @param player player associated with this timer (can be null)
|
||||
* @param repeating indicates if the timer is repeatable or one-time.
|
||||
* Gets the quest timers.
|
||||
* @return the quest timers
|
||||
*/
|
||||
public synchronized void startQuestTimer(String name, long time, NpcInstance npc, PlayerInstance player, boolean repeating)
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
synchronized (_allEventTimers)
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, NpcInstance, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, NpcInstance npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
ArrayList<QuestTimer> timers = _allEventTimers.get(name);
|
||||
|
||||
// no timer exists with the same name, at all
|
||||
if (timers == null)
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers = new ArrayList<>();
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
|
||||
// a timer with this name exists, but may not be for the same set of npc and player
|
||||
}
|
||||
else
|
||||
{
|
||||
QuestTimer timer = null;
|
||||
for (int i = 0; i < timers.size(); i++)
|
||||
{
|
||||
final QuestTimer tmp = timers.get(i);
|
||||
|
||||
if ((tmp != null) && tmp.equals(this, name, npc, player))
|
||||
{
|
||||
timer = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if there exists a timer with this name, allow the timer only if the [npc, player] set is unique
|
||||
// nulls act as wildcards
|
||||
if (timer == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
}
|
||||
|
||||
_allEventTimers.put(name, timers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a quest timer that matches the provided name and parameters.
|
||||
* @param name the name of the quest timer to get
|
||||
* @param npc the NPC associated with the quest timer to get
|
||||
* @param player the player associated with the quest timer to get
|
||||
* @return the quest timer that matches the specified parameters or {@code null} if nothing was found
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, NpcInstance npc, PlayerInstance player)
|
||||
{
|
||||
if (name == null)
|
||||
@ -382,19 +375,16 @@ public class Quest extends ManagedScript
|
||||
return null;
|
||||
}
|
||||
|
||||
synchronized (_allEventTimers)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final ArrayList<QuestTimer> qt = _allEventTimers.get(name);
|
||||
|
||||
if ((qt == null) || qt.isEmpty())
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < qt.size(); i++)
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
final QuestTimer timer = qt.get(i);
|
||||
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
@ -404,34 +394,10 @@ public class Quest extends ManagedScript
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelQuestTimer(String name, NpcInstance npc, PlayerInstance player)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_allEventTimers)
|
||||
{
|
||||
final ArrayList<QuestTimer> qt = _allEventTimers.get(name);
|
||||
if ((qt == null) || qt.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < qt.size(); i++)
|
||||
{
|
||||
final QuestTimer timer = qt.get(i);
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
qt.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel all quest timers with the specified name.
|
||||
* @param name the name of the quest timers to cancel
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (name == null)
|
||||
@ -439,11 +405,10 @@ public class Quest extends ManagedScript
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_allEventTimers)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final ArrayList<QuestTimer> timers = _allEventTimers.get(name);
|
||||
|
||||
if (timers == null)
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -455,11 +420,48 @@ public class Quest extends ManagedScript
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the quest timer that matches the specified name and parameters.
|
||||
* @param name the name of the quest timer to cancel
|
||||
* @param npc the NPC associated with the quest timer to cancel
|
||||
* @param player the player associated with the quest timer to cancel
|
||||
*/
|
||||
public void cancelQuestTimer(String name, NpcInstance npc, PlayerInstance player)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a quest timer from the list of all timers.<br>
|
||||
* Note: does not stop the timer itself!
|
||||
* @param timer the {@link QuestState} object to remove
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if (timer == null)
|
||||
@ -467,20 +469,18 @@ public class Quest extends ManagedScript
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_allEventTimers)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final ArrayList<QuestTimer> timers = _allEventTimers.get(timer.toString());
|
||||
|
||||
if (timers == null)
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
return;
|
||||
timers.remove(timer);
|
||||
}
|
||||
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
|
||||
// these are methods to call from java
|
||||
// These are methods to call within the core to call the quest events.
|
||||
|
||||
public boolean notifyAttack(NpcInstance npc, PlayerInstance attacker, int damage, boolean isPet)
|
||||
{
|
||||
String res = null;
|
||||
@ -1121,7 +1121,7 @@ public class Quest extends ManagedScript
|
||||
}
|
||||
|
||||
// events
|
||||
for (String name : _allEventsS.keySet())
|
||||
for (String name : _allEvents.keySet())
|
||||
{
|
||||
player.processQuestEvent(name, "enter");
|
||||
}
|
||||
@ -1797,16 +1797,17 @@ public class Quest extends ManagedScript
|
||||
saveGlobalData();
|
||||
// Cancel all pending timers before reloading.
|
||||
// If timers ought to be restarted, the quest can take care of it with its code (example: save global data indicating what timer must be restarted).
|
||||
synchronized (_allEventTimers)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (ArrayList<QuestTimer> timers : _allEventTimers.values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
_allEventTimers.clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
return QuestManager.getInstance().removeQuest(this);
|
||||
|
@ -22,14 +22,12 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@ -75,10 +73,7 @@ import org.l2jmobius.gameserver.util.Util;
|
||||
public class Quest extends AbstractScript implements IIdentifiable
|
||||
{
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Map<Predicate<PlayerInstance>, String> _startCondition = null;
|
||||
|
||||
@ -228,7 +223,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -243,16 +238,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -260,26 +245,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,31 +272,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -325,30 +302,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,10 +334,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -374,20 +366,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2523,25 +2512,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -22,14 +22,12 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@ -77,10 +75,7 @@ import org.l2jmobius.gameserver.util.Util;
|
||||
public class Quest extends AbstractScript implements IIdentifiable
|
||||
{
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Map<Predicate<PlayerInstance>, String> _startCondition = null;
|
||||
|
||||
@ -230,7 +225,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -245,16 +240,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -262,26 +247,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,31 +274,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -327,30 +304,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,10 +336,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -376,20 +368,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2566,25 +2555,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -87,10 +86,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -253,7 +249,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -268,16 +264,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -285,26 +271,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,31 +298,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,30 +328,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,10 +360,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,20 +392,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2790,25 +2780,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -87,10 +86,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -253,7 +249,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -268,16 +264,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -285,26 +271,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,31 +298,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,30 +328,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,10 +360,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,20 +392,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2790,25 +2780,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -87,10 +86,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -253,7 +249,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -268,16 +264,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -285,26 +271,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,31 +298,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,30 +328,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,10 +360,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,20 +392,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2790,25 +2780,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -87,10 +86,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -253,7 +249,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -268,16 +264,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -285,26 +271,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,31 +298,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,30 +328,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,10 +360,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,20 +392,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2790,25 +2780,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -87,10 +86,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -253,7 +249,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -268,16 +264,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -285,26 +271,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,31 +298,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,30 +328,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,10 +360,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,20 +392,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2790,25 +2780,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -87,10 +86,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -253,7 +249,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -268,16 +264,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -285,26 +271,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,31 +298,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,30 +328,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,10 +360,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,20 +392,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2790,25 +2780,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
@ -23,13 +23,12 @@ import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -87,10 +86,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
public static final Logger LOGGER = Logger.getLogger(Quest.class.getName());
|
||||
|
||||
/** Map containing lists of timers from the name of the timer. */
|
||||
private Map<String, List<QuestTimer>> _questTimers = null;
|
||||
private final ReentrantReadWriteLock _rwLock = new ReentrantReadWriteLock();
|
||||
private final WriteLock _writeLock = _rwLock.writeLock();
|
||||
private final ReadLock _readLock = _rwLock.readLock();
|
||||
private final Map<String, List<QuestTimer>> _questTimers = new HashMap<>();
|
||||
/** Map containing all the start conditions. */
|
||||
private Set<QuestCondition> _startCondition = null;
|
||||
|
||||
@ -253,7 +249,7 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @see #startQuestTimer(String, long, Npc, PlayerInstance, boolean)
|
||||
*/
|
||||
@ -268,16 +264,6 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public Map<String, List<QuestTimer>> getQuestTimers()
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
{
|
||||
_questTimers = new ConcurrentHashMap<>(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _questTimers;
|
||||
}
|
||||
|
||||
@ -285,26 +271,21 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
* Add a timer to the quest (if it doesn't exist already) and start it.
|
||||
* @param name the name of the timer (also passed back as "event" in {@link #onAdvEvent(String, Npc, PlayerInstance)})
|
||||
* @param time time in ms for when to fire the timer
|
||||
* @param npc the npc associated with this timer (can be null)
|
||||
* @param npc the NPC associated with this timer (can be null)
|
||||
* @param player the player associated with this timer (can be null)
|
||||
* @param repeating indicates whether the timer is repeatable or one-time.<br>
|
||||
* If {@code true}, the task is repeated every {@code time} milliseconds until explicitly stopped.
|
||||
*/
|
||||
public void startQuestTimer(String name, long time, Npc npc, PlayerInstance player, boolean repeating)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>());
|
||||
// If there exists a timer with this name, allow the timer only if the [npc, player] set is unique nulls act as wildcards.
|
||||
if (getQuestTimer(name, npc, player) == null)
|
||||
{
|
||||
timers.add(new QuestTimer(this, name, time, npc, player, repeating));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,31 +298,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public QuestTimer getQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
return timer;
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,30 +328,27 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimers(String name)
|
||||
{
|
||||
if (_questTimers == null)
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final List<QuestTimer> timers = getQuestTimers().get(name);
|
||||
if (timers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,10 +360,28 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void cancelQuestTimer(String name, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final QuestTimer timer = getQuestTimer(name, npc, player);
|
||||
if (timer != null)
|
||||
if (name == null)
|
||||
{
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(name);
|
||||
if ((timers == null) || timers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
if ((timer != null) && timer.equals(this, name, npc, player))
|
||||
{
|
||||
timer.cancel();
|
||||
timers.remove(timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,20 +392,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
*/
|
||||
public void removeQuestTimer(QuestTimer timer)
|
||||
{
|
||||
if ((timer != null) && (_questTimers != null))
|
||||
if (timer == null)
|
||||
{
|
||||
final List<QuestTimer> timers = getQuestTimers().get(timer.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
final List<QuestTimer> timers = _questTimers.get(timer.toString());
|
||||
if (timers != null)
|
||||
{
|
||||
_writeLock.lock();
|
||||
try
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.unlock();
|
||||
}
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2790,25 +2780,17 @@ public class Quest extends AbstractScript implements IIdentifiable
|
||||
// cancel all pending timers before reloading.
|
||||
// if timers ought to be restarted, the quest can take care of it
|
||||
// with its code (example: save global data indicating what timer must be restarted).
|
||||
if (_questTimers != null)
|
||||
synchronized (_questTimers)
|
||||
{
|
||||
for (List<QuestTimer> timers : getQuestTimers().values())
|
||||
for (List<QuestTimer> timers : _questTimers.values())
|
||||
{
|
||||
_readLock.lock();
|
||||
try
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
for (QuestTimer timer : timers)
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_readLock.unlock();
|
||||
timer.cancel();
|
||||
}
|
||||
timers.clear();
|
||||
}
|
||||
getQuestTimers().clear();
|
||||
_questTimers.clear();
|
||||
}
|
||||
|
||||
if (removeFromList)
|
||||
|
Loading…
Reference in New Issue
Block a user