From 01f16fdd823d4263bac61ab54f2c678cb195ee9b Mon Sep 17 00:00:00 2001
From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com>
Date: Mon, 4 Nov 2019 17:01:20 +0000
Subject: [PATCH] Prevent tapping into System.currentTimeMillis with each
Timestamp call.
---
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/Timestamp.java | 22 ++++-
.../model/actor/instance/PlayerInstance.java | 10 +--
.../network/serverpackets/SkillCoolTime.java | 16 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 90 ++++++-------------
.../model/actor/instance/PlayerInstance.java | 72 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 17 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 90 ++++++-------------
.../model/actor/instance/PlayerInstance.java | 72 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 17 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
.../l2jmobius/gameserver/model/TimeStamp.java | 30 +++++--
.../gameserver/model/actor/Creature.java | 88 ++++++------------
.../model/actor/instance/PlayerInstance.java | 74 +++++++--------
.../network/serverpackets/SkillCoolTime.java | 19 ++--
71 files changed, 1583 insertions(+), 2048 deletions(-)
diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 86b952cb78..7b3f8473a3 100644
--- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -212,11 +212,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1342,16 +1342,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1360,9 +1350,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1373,13 +1363,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1414,16 +1409,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1431,23 +1416,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1455,9 +1434,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1466,9 +1445,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1479,7 +1458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1497,7 +1476,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1516,30 +1495,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1570,7 +1534,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 1be5a06f05..e6b9ced7ac 100644
--- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7260,6 +7260,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7319,8 +7320,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7330,34 +7331,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7379,23 +7376,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 86b952cb78..7b3f8473a3 100644
--- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -212,11 +212,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1342,16 +1342,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1360,9 +1350,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1373,13 +1363,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1414,16 +1409,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1431,23 +1416,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1455,9 +1434,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1466,9 +1445,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1479,7 +1458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1497,7 +1476,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1516,30 +1495,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1570,7 +1534,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 703fe6c659..a6b1d28572 100644
--- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7267,6 +7267,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7326,8 +7327,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7337,34 +7338,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7386,23 +7383,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 7932804985..4956b9f796 100644
--- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -212,11 +212,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1342,16 +1342,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1360,9 +1350,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1373,13 +1363,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1414,16 +1409,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1431,23 +1416,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1455,9 +1434,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1466,9 +1445,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1479,7 +1458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1497,7 +1476,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1516,30 +1495,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1570,7 +1534,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 0319b6bb46..9352269d24 100644
--- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7269,6 +7269,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7328,8 +7329,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7339,34 +7340,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7388,23 +7385,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 7932804985..4956b9f796 100644
--- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -212,11 +212,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1342,16 +1342,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1360,9 +1350,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1373,13 +1363,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1414,16 +1409,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1431,23 +1416,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1455,9 +1434,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1466,9 +1445,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1479,7 +1458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1497,7 +1476,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1516,30 +1495,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1570,7 +1534,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 6277c3ee3c..e37530ac5a 100644
--- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7264,6 +7264,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7323,8 +7324,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7334,34 +7335,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7383,23 +7380,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 7932804985..4956b9f796 100644
--- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -212,11 +212,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1342,16 +1342,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1360,9 +1350,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1373,13 +1363,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1414,16 +1409,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1431,23 +1416,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1455,9 +1434,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1466,9 +1445,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1479,7 +1458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1497,7 +1476,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1516,30 +1495,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1570,7 +1534,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 33f7edcae2..77b65efa4d 100644
--- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7242,6 +7242,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7301,8 +7302,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7312,34 +7313,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7361,23 +7358,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 7932804985..4956b9f796 100644
--- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -212,11 +212,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1342,16 +1342,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1360,9 +1350,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1373,13 +1363,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1414,16 +1409,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1431,23 +1416,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1455,9 +1434,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1466,9 +1445,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1479,7 +1458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1497,7 +1476,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1516,30 +1495,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1570,7 +1534,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index d218f49abe..40001cf652 100644
--- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7242,6 +7242,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7301,8 +7302,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7312,34 +7313,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7361,23 +7358,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 7932804985..4956b9f796 100644
--- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -212,11 +212,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1342,16 +1342,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1360,9 +1350,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1373,13 +1363,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1414,16 +1409,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1431,23 +1416,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1455,9 +1434,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1466,9 +1445,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1479,7 +1458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1497,7 +1476,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1516,30 +1495,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1570,7 +1534,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index b2f3cd0d26..277f5a0068 100644
--- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7243,6 +7243,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7302,8 +7303,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7313,34 +7314,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7362,23 +7359,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/Creature.java
index f427de700b..38af7c27b4 100644
--- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -212,11 +212,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1342,16 +1342,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1360,9 +1350,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1373,13 +1363,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1414,16 +1409,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1431,23 +1416,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1455,9 +1434,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1466,9 +1445,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1479,7 +1458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1497,7 +1476,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1516,30 +1495,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1570,7 +1534,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 810f5d6acf..54d5b5e39a 100644
--- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7204,6 +7204,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7263,8 +7264,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7274,34 +7275,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7323,23 +7320,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/Timestamp.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/Timestamp.java
index 67baed8403..00f5a41c52 100644
--- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/Timestamp.java
+++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/Timestamp.java
@@ -93,7 +93,16 @@ public class Timestamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -102,6 +111,15 @@ public class Timestamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 0699189f34..6690e8ec78 100644
--- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -9693,9 +9693,9 @@ public class PlayerInstance extends Playable
final Effect[] effects = getAllEffects();
statement = con.prepareStatement(ADD_SKILL_SAVE);
- final List storedSkills = new ArrayList<>();
-
int buff_index = 0;
+ final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
for (Effect effect : effects)
{
@@ -9717,8 +9717,8 @@ public class PlayerInstance extends Playable
if (_reuseTimestamps.containsKey(effect.getSkill().getId()))
{
final Timestamp t = _reuseTimestamps.get(effect.getSkill().getId());
- statement.setLong(6, t.hasNotPassed() ? t.getReuse() : 0);
- statement.setLong(7, t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, currentTime < t.getStamp() ? t.getReuse() : 0);
+ statement.setLong(7, currentTime < t.getStamp() ? t.getStamp() : 0);
}
else
{
@@ -9734,7 +9734,7 @@ public class PlayerInstance extends Playable
// Store the reuse delays of remaining skills which lost effect but still under reuse delay. 'restore_type' 1.
for (Timestamp t : _reuseTimestamps.values())
{
- if (t.hasNotPassed())
+ if (currentTime < t.getStamp())
{
final int skillId = t.getSkillId();
final int skillLvl = t.getSkillLevel();
diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c8abcfc62b..906b68406a 100644
--- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -21,12 +21,18 @@ import java.util.Collection;
import org.l2jmobius.gameserver.model.Timestamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+/**
+ * Skill Cool Time server packet implementation.
+ * @author KenM, Zoey76, Mobius
+ */
public class SkillCoolTime extends GameServerPacket
{
+ private final long _currentTime;
public Collection _reuseTimestamps;
public SkillCoolTime(PlayerInstance player)
{
+ _currentTime = System.currentTimeMillis();
_reuseTimestamps = player.getReuseTimeStamps();
}
@@ -40,12 +46,12 @@ public class SkillCoolTime extends GameServerPacket
}
writeC(0xc1);
writeD(_reuseTimestamps.size());
- for (Timestamp reuseTimestamp : _reuseTimestamps)
+ for (Timestamp ts : _reuseTimestamps)
{
- writeD(reuseTimestamp.getSkillId());
- writeD(reuseTimestamp.getSkillLevel());
- writeD((int) reuseTimestamp.getReuse() / 1000);
- writeD((int) reuseTimestamp.getRemaining() / 1000);
+ writeD(ts.getSkillId());
+ writeD(ts.getSkillLevel());
+ writeD((int) ts.getReuse() / 1000);
+ writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
}
}
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b0573c2905..40319a41e1 100644
--- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -34,7 +34,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -49,7 +49,7 @@ public class TimeStamp
_id1 = skill.getId();
_id2 = skill.getLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -64,7 +64,7 @@ public class TimeStamp
_id1 = item.getId();
_id2 = item.getObjectId();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -138,7 +138,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -147,6 +156,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/Creature.java
index ce8a0c7e7a..8f0c1bdecb 100644
--- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -216,11 +216,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentHashMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -2102,16 +2102,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -2120,9 +2110,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -2133,13 +2123,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -2174,16 +2169,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -2191,23 +2176,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -2215,9 +2194,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(int hashCode)
+ public long getSkillRemainingReuseTime(int hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -2226,9 +2205,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(int hashCode)
+ public boolean hasSkillReuse(int hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -2237,9 +2216,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the skill reuse time stamp, otherwise {@code null}
*/
- public synchronized TimeStamp getSkillReuseTimeStamp(int hashCode)
+ public TimeStamp getSkillReuseTimeStamp(int hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -2257,7 +2236,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -2276,30 +2255,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -2325,7 +2289,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 4eb6294c8d..cea30608bc 100644
--- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7589,6 +7589,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7634,8 +7635,8 @@ public class PlayerInstance extends Playable
statement.setInt(4, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(5, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(5, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(7, 0); // Store type 0, active buffs/debuffs.
statement.setInt(8, _classIndex);
@@ -7645,33 +7646,29 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final int hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final int hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, -1);
- statement.setLong(5, t.getReuse());
- statement.setLong(6, t.getStamp());
- statement.setInt(7, 1); // Restore type 1, skill reuse.
- statement.setInt(8, _classIndex);
- statement.setInt(9, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, -1);
+ statement.setLong(5, t.getReuse());
+ statement.setLong(6, t.getStamp());
+ statement.setInt(7, 1); // Restore type 1, skill reuse.
+ statement.setInt(8, _classIndex);
+ statement.setInt(9, ++buff_index);
+ statement.addBatch();
}
}
@@ -7693,23 +7690,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setLong(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setLong(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index 4ccae0ceb9..6fee8f510b 100644
--- a/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_CT_2.4_Epilogue/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,7 +18,6 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.model.TimeStamp;
@@ -27,23 +26,21 @@ import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if (_currentTime < ts.getStamp())
{
- if (ts.hasNotPassed())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -58,7 +55,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(ts.getSkillLvl());
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b0573c2905..40319a41e1 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -34,7 +34,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -49,7 +49,7 @@ public class TimeStamp
_id1 = skill.getId();
_id2 = skill.getLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -64,7 +64,7 @@ public class TimeStamp
_id1 = item.getId();
_id2 = item.getObjectId();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -138,7 +138,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -147,6 +156,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 654cbaf974..2555570268 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -217,11 +217,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentHashMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -2104,16 +2104,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -2122,9 +2112,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -2135,13 +2125,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -2176,16 +2171,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -2193,23 +2178,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -2217,9 +2196,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(int hashCode)
+ public long getSkillRemainingReuseTime(int hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -2228,9 +2207,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(int hashCode)
+ public boolean hasSkillReuse(int hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -2239,9 +2218,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the skill reuse time stamp, otherwise {@code null}
*/
- public synchronized TimeStamp getSkillReuseTimeStamp(int hashCode)
+ public TimeStamp getSkillReuseTimeStamp(int hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -2259,7 +2238,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -2278,30 +2257,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -2327,7 +2291,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index da321cac22..53b9dda308 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7467,6 +7467,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7512,8 +7513,8 @@ public class PlayerInstance extends Playable
statement.setInt(4, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(5, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(5, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(7, 0); // Store type 0, active buffs/debuffs.
statement.setInt(8, _classIndex);
@@ -7523,33 +7524,29 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final int hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final int hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, -1);
- statement.setLong(5, t.getReuse());
- statement.setLong(6, t.getStamp());
- statement.setInt(7, 1); // Restore type 1, skill reuse.
- statement.setInt(8, _classIndex);
- statement.setInt(9, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, -1);
+ statement.setLong(5, t.getReuse());
+ statement.setLong(6, t.getStamp());
+ statement.setInt(7, 1); // Restore type 1, skill reuse.
+ statement.setInt(8, _classIndex);
+ statement.setInt(9, ++buff_index);
+ statement.addBatch();
}
}
@@ -7571,23 +7568,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setLong(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setLong(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index 4ccae0ceb9..6fee8f510b 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,7 +18,6 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.model.TimeStamp;
@@ -27,23 +26,21 @@ import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if (_currentTime < ts.getStamp())
{
- if (ts.hasNotPassed())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -58,7 +55,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(ts.getSkillLvl());
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 69c1f81bc4..ccb26ecf79 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -211,11 +211,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1341,16 +1341,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1359,9 +1349,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1372,13 +1362,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1413,16 +1408,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1430,23 +1415,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1454,9 +1433,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1465,9 +1444,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1478,7 +1457,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1496,7 +1475,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1515,30 +1494,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1569,7 +1533,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 2d30fcbbf8..bbe9016159 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7231,6 +7231,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7290,8 +7291,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7301,34 +7302,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7350,23 +7347,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 69c1f81bc4..ccb26ecf79 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -211,11 +211,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1341,16 +1341,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1359,9 +1349,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1372,13 +1362,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1413,16 +1408,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1430,23 +1415,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1454,9 +1433,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1465,9 +1444,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1478,7 +1457,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1496,7 +1475,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1515,30 +1494,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1569,7 +1533,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 4c36275955..73d08b2914 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7232,6 +7232,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7291,8 +7292,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7302,34 +7303,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7351,23 +7348,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 69c1f81bc4..ccb26ecf79 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -211,11 +211,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1341,16 +1341,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1359,9 +1349,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1372,13 +1362,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1413,16 +1408,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1430,23 +1415,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1454,9 +1433,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1465,9 +1444,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1478,7 +1457,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1496,7 +1475,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1515,30 +1494,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1569,7 +1533,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index af543b939a..858950b02e 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7217,6 +7217,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7276,8 +7277,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7287,34 +7288,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7336,23 +7333,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 9e3245115e..f85455fe5b 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -212,11 +212,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1342,16 +1342,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1360,9 +1350,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1373,13 +1363,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1414,16 +1409,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1431,23 +1416,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1455,9 +1434,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1466,9 +1445,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1479,7 +1458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1497,7 +1476,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1516,30 +1495,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1570,7 +1534,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index cdf65deb5e..8c00ee3161 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7244,6 +7244,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7303,8 +7304,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7314,34 +7315,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7363,23 +7360,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 9e3245115e..f85455fe5b 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -212,11 +212,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1342,16 +1342,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1360,9 +1350,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1373,13 +1363,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1414,16 +1409,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1431,23 +1416,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1455,9 +1434,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1466,9 +1445,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1479,7 +1458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1497,7 +1476,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1516,30 +1495,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1570,7 +1534,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index bb950ddf03..df063a2a04 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7244,6 +7244,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7303,8 +7304,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7314,34 +7315,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7363,23 +7360,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 2ba159c8fd..f31b7318e8 100644
--- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -212,11 +212,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1342,16 +1342,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1360,9 +1350,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1373,13 +1363,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1414,16 +1409,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1431,23 +1416,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1455,9 +1434,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1466,9 +1445,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1479,7 +1458,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1497,7 +1476,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1516,30 +1495,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1570,7 +1534,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 7fff519869..e4be35c9e1 100644
--- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7143,6 +7143,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7202,8 +7203,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7213,34 +7214,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7262,23 +7259,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}
diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/TimeStamp.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/TimeStamp.java
index b8a8581f85..1cbb5a3e3b 100644
--- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/TimeStamp.java
+++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/TimeStamp.java
@@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
* Simple class containing all necessary information to maintain
* valid time stamps and reuse for skills and items reuse upon re-login.
* Filter this carefully as it becomes redundant to store reuse for small delays.
- * @author Yesod, Zoey76
+ * @author Yesod, Zoey76, Mobius
*/
public class TimeStamp
{
@@ -36,7 +36,7 @@ public class TimeStamp
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
- private final long _stamp;
+ private volatile long _stamp;
/** Shared reuse group. */
private final int _group;
@@ -52,7 +52,7 @@ public class TimeStamp
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = -1;
}
@@ -68,7 +68,7 @@ public class TimeStamp
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
- _stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
+ _stamp = systime > 0 ? systime : reuse != 0 ? System.currentTimeMillis() + reuse : 0;
_group = item.getSharedReuseGroup();
}
@@ -151,7 +151,16 @@ public class TimeStamp
*/
public long getRemaining()
{
- return Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (_stamp == 0)
+ {
+ return 0;
+ }
+ final long remainingTime = Math.max(_stamp - System.currentTimeMillis(), 0);
+ if (remainingTime == 0)
+ {
+ _stamp = 0;
+ }
+ return remainingTime;
}
/**
@@ -160,6 +169,15 @@ public class TimeStamp
*/
public boolean hasNotPassed()
{
- return System.currentTimeMillis() < _stamp;
+ if (_stamp == 0)
+ {
+ return false;
+ }
+ final boolean hasNotPassed = System.currentTimeMillis() < _stamp;
+ if (!hasNotPassed)
+ {
+ _stamp = 0;
+ }
+ return hasNotPassed;
}
}
diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/Creature.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/Creature.java
index 69c1f81bc4..ccb26ecf79 100644
--- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/Creature.java
+++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/Creature.java
@@ -211,11 +211,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
- private volatile Map _reuseTimeStampsSkills = null;
+ private final Map _reuseTimeStampsSkills = new ConcurrentHashMap<>();
/** Map containing the item reuse time stamps. */
- private volatile Map _reuseTimeStampsItems = null;
+ private final Map _reuseTimeStampsItems = new ConcurrentHashMap<>();
/** Map containing all the disabled skills. */
- private volatile Map _disabledSkills = null;
+ private final Map _disabledSkills = new ConcurrentHashMap<>();
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1341,16 +1341,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStampItem(ItemInstance item, long reuse, long systime)
{
- if (_reuseTimeStampsItems == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsItems == null)
- {
- _reuseTimeStampsItems = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsItems.put(item.getObjectId(), new TimeStamp(item, reuse, systime));
}
@@ -1359,9 +1349,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param itemObjId the item object ID
* @return if the item has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getItemRemainingReuseTime(int itemObjId)
+ public long getItemRemainingReuseTime(int itemObjId)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsItems != null) ? _reuseTimeStampsItems.get(itemObjId) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsItems.get(itemObjId);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1372,13 +1362,18 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public long getReuseDelayOnGroup(int group)
{
- if ((group > 0) && (_reuseTimeStampsItems != null))
+ if ((group > 0) && !_reuseTimeStampsItems.isEmpty())
{
+ final long currentTime = System.currentTimeMillis();
for (TimeStamp ts : _reuseTimeStampsItems.values())
{
- if ((ts.getSharedReuseGroup() == group) && ts.hasNotPassed())
+ if (ts.getSharedReuseGroup() == group)
{
- return ts.getRemaining();
+ final long stamp = ts.getStamp();
+ if (currentTime < stamp)
+ {
+ return Math.max(stamp - currentTime, 0);
+ }
}
}
}
@@ -1413,16 +1408,6 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void addTimeStamp(Skill skill, long reuse, long systime)
{
- if (_reuseTimeStampsSkills == null)
- {
- synchronized (this)
- {
- if (_reuseTimeStampsSkills == null)
- {
- _reuseTimeStampsSkills = new ConcurrentHashMap<>();
- }
- }
- }
_reuseTimeStampsSkills.put(skill.getReuseHashCode(), new TimeStamp(skill, reuse, systime));
}
@@ -1430,23 +1415,17 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* Removes a skill reuse time stamp.
* @param skill the skill to remove
*/
- public synchronized void removeTimeStamp(Skill skill)
+ public void removeTimeStamp(Skill skill)
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
- }
+ _reuseTimeStampsSkills.remove(skill.getReuseHashCode());
}
/**
* Removes all skill reuse time stamps.
*/
- public synchronized void resetTimeStamps()
+ public void resetTimeStamps()
{
- if (_reuseTimeStampsSkills != null)
- {
- _reuseTimeStampsSkills.clear();
- }
+ _reuseTimeStampsSkills.clear();
}
/**
@@ -1454,9 +1433,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
- public synchronized long getSkillRemainingReuseTime(long hashCode)
+ public long getSkillRemainingReuseTime(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
}
@@ -1465,9 +1444,9 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
- public synchronized boolean hasSkillReuse(long hashCode)
+ public boolean hasSkillReuse(long hashCode)
{
- final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
+ final TimeStamp reuseStamp = _reuseTimeStampsSkills.get(hashCode);
return (reuseStamp != null) && reuseStamp.hasNotPassed();
}
@@ -1478,7 +1457,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public synchronized TimeStamp getSkillReuseTimeStamp(long hashCode)
{
- return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
+ return _reuseTimeStampsSkills.get(hashCode);
}
/**
@@ -1496,7 +1475,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
*/
public void enableSkill(Skill skill)
{
- if ((skill == null) || (_disabledSkills == null))
+ if (skill == null)
{
return;
}
@@ -1515,30 +1494,15 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
{
return;
}
-
- if (_disabledSkills == null)
- {
- synchronized (this)
- {
- if (_disabledSkills == null)
- {
- _disabledSkills = new ConcurrentHashMap<>();
- }
- }
- }
-
_disabledSkills.put(skill.getReuseHashCode(), delay > 0 ? System.currentTimeMillis() + delay : Long.MAX_VALUE);
}
/**
* Removes all the disabled skills.
*/
- public synchronized void resetDisabledSkills()
+ public void resetDisabledSkills()
{
- if (_disabledSkills != null)
- {
- _disabledSkills.clear();
- }
+ _disabledSkills.clear();
}
/**
@@ -1569,7 +1533,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
return true;
}
- if (_disabledSkills == null)
+ if (_disabledSkills.isEmpty())
{
return false;
}
diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index 9732a1bb6e..aa3d6a21b6 100644
--- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -7232,6 +7232,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List storedSkills = new ArrayList<>();
+ final long currentTime = System.currentTimeMillis();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7291,8 +7292,8 @@ public class PlayerInstance extends Playable
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
- statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
- statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
+ statement.setLong(6, (t != null) && (currentTime < t.getStamp()) ? t.getReuse() : 0);
+ statement.setDouble(7, (t != null) && (currentTime < t.getStamp()) ? t.getStamp() : 0);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, _classIndex);
@@ -7302,34 +7303,30 @@ public class PlayerInstance extends Playable
}
// Skills under reuse.
- final Map reuseTimeStamps = getSkillReuseTimeStamps();
- if (reuseTimeStamps != null)
+ for (Entry ts : getSkillReuseTimeStamps().entrySet())
{
- for (Entry ts : reuseTimeStamps.entrySet())
+ final long hash = ts.getKey();
+ if (storedSkills.contains(hash))
{
- final long hash = ts.getKey();
- if (storedSkills.contains(hash))
- {
- continue;
- }
+ continue;
+ }
+
+ final TimeStamp t = ts.getValue();
+ if ((t != null) && (currentTime < t.getStamp()))
+ {
+ storedSkills.add(hash);
- final TimeStamp t = ts.getValue();
- if ((t != null) && t.hasNotPassed())
- {
- storedSkills.add(hash);
-
- statement.setInt(1, getObjectId());
- statement.setInt(2, t.getSkillId());
- statement.setInt(3, t.getSkillLvl());
- statement.setInt(4, t.getSkillSubLvl());
- statement.setInt(5, -1);
- statement.setLong(6, t.getReuse());
- statement.setDouble(7, t.getStamp());
- statement.setInt(8, 1); // Restore type 1, skill reuse.
- statement.setInt(9, _classIndex);
- statement.setInt(10, ++buff_index);
- statement.addBatch();
- }
+ statement.setInt(1, getObjectId());
+ statement.setInt(2, t.getSkillId());
+ statement.setInt(3, t.getSkillLvl());
+ statement.setInt(4, t.getSkillSubLvl());
+ statement.setInt(5, -1);
+ statement.setLong(6, t.getReuse());
+ statement.setDouble(7, t.getStamp());
+ statement.setInt(8, 1); // Restore type 1, skill reuse.
+ statement.setInt(9, _classIndex);
+ statement.setInt(10, ++buff_index);
+ statement.addBatch();
}
}
@@ -7351,23 +7348,20 @@ public class PlayerInstance extends Playable
ps1.setInt(1, getObjectId());
ps1.execute();
- final Map itemReuseTimeStamps = getItemReuseTimeStamps();
- if (itemReuseTimeStamps != null)
+ final long currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : getItemReuseTimeStamps().values())
{
- for (TimeStamp ts : itemReuseTimeStamps.values())
+ if ((ts != null) && (currentTime < ts.getStamp()))
{
- if ((ts != null) && ts.hasNotPassed())
- {
- ps2.setInt(1, getObjectId());
- ps2.setInt(2, ts.getItemId());
- ps2.setInt(3, ts.getItemObjectId());
- ps2.setLong(4, ts.getReuse());
- ps2.setDouble(5, ts.getStamp());
- ps2.addBatch();
- }
+ ps2.setInt(1, getObjectId());
+ ps2.setInt(2, ts.getItemId());
+ ps2.setInt(3, ts.getItemObjectId());
+ ps2.setLong(4, ts.getReuse());
+ ps2.setDouble(5, ts.getStamp());
+ ps2.addBatch();
}
- ps2.executeBatch();
}
+ ps2.executeBatch();
}
catch (Exception e)
{
diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
index c698b949d7..0869c62304 100644
--- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
+++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/network/serverpackets/SkillCoolTime.java
@@ -18,35 +18,30 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.l2jmobius.commons.network.PacketWriter;
import org.l2jmobius.gameserver.data.xml.impl.SkillData;
import org.l2jmobius.gameserver.model.TimeStamp;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.OutgoingPackets;
/**
* Skill Cool Time server packet implementation.
- * @author KenM, Zoey76
+ * @author KenM, Zoey76, Mobius
*/
public class SkillCoolTime implements IClientOutgoingPacket
{
+ private final long _currentTime;
private final List _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
- final Map skillReuseTimeStamps = player.getSkillReuseTimeStamps();
- if (skillReuseTimeStamps != null)
+ _currentTime = System.currentTimeMillis();
+ for (TimeStamp ts : player.getSkillReuseTimeStamps().values())
{
- for (TimeStamp ts : skillReuseTimeStamps.values())
+ if ((_currentTime < ts.getStamp()) && !SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl()).isNotBroadcastable())
{
- final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
- if (ts.hasNotPassed() && !skill.isNotBroadcastable())
- {
- _skillReuseTimeStamps.add(ts);
- }
+ _skillReuseTimeStamps.add(ts);
}
}
}
@@ -62,7 +57,7 @@ public class SkillCoolTime implements IClientOutgoingPacket
packet.writeD(ts.getSkillId());
packet.writeD(0x00); // ?
packet.writeD((int) ts.getReuse() / 1000);
- packet.writeD((int) ts.getRemaining() / 1000);
+ packet.writeD((int) Math.max(ts.getStamp() - _currentTime, 0) / 1000);
}
return true;
}