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; }