Prevent tapping into System.currentTimeMillis with each Timestamp call.
This commit is contained in:
@ -23,7 +23,7 @@ import org.l2jmobius.gameserver.model.skills.Skill;
|
||||
* Simple class containing all necessary information to maintain<br>
|
||||
* valid time stamps and reuse for skills and items reuse upon re-login.<br>
|
||||
* <b>Filter this carefully as it becomes redundant to store reuse for small delays.</b>
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
@ -211,11 +211,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
/** Map containing all skills of this character. */
|
||||
private final Map<Integer, Skill> _skills = new ConcurrentSkipListMap<>();
|
||||
/** Map containing the skill reuse time stamps. */
|
||||
private volatile Map<Long, TimeStamp> _reuseTimeStampsSkills = null;
|
||||
private final Map<Long, TimeStamp> _reuseTimeStampsSkills = new ConcurrentHashMap<>();
|
||||
/** Map containing the item reuse time stamps. */
|
||||
private volatile Map<Integer, TimeStamp> _reuseTimeStampsItems = null;
|
||||
private final Map<Integer, TimeStamp> _reuseTimeStampsItems = new ConcurrentHashMap<>();
|
||||
/** Map containing all the disabled skills. */
|
||||
private volatile Map<Long, Long> _disabledSkills = null;
|
||||
private final Map<Long, Long> _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;
|
||||
}
|
||||
|
@ -7232,6 +7232,7 @@ public class PlayerInstance extends Playable
|
||||
|
||||
int buff_index = 0;
|
||||
final List<Long> 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<Long, TimeStamp> reuseTimeStamps = getSkillReuseTimeStamps();
|
||||
if (reuseTimeStamps != null)
|
||||
for (Entry<Long, TimeStamp> ts : getSkillReuseTimeStamps().entrySet())
|
||||
{
|
||||
for (Entry<Long, TimeStamp> 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<Integer, TimeStamp> 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)
|
||||
{
|
||||
|
@ -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<TimeStamp> _skillReuseTimeStamps = new ArrayList<>();
|
||||
|
||||
public SkillCoolTime(PlayerInstance player)
|
||||
{
|
||||
final Map<Long, TimeStamp> 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user