Prevent tapping into System.currentTimeMillis with each Timestamp call.

This commit is contained in:
MobiusDevelopment
2019-11-04 17:01:20 +00:00
parent cd918658d1
commit 01f16fdd82
71 changed files with 1583 additions and 2048 deletions

View File

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

View File

@@ -216,11 +216,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map<Integer, Skill> _skills = new ConcurrentHashMap<>();
/** Map containing the skill reuse time stamps. */
private volatile Map<Integer, TimeStamp> _reuseTimeStampsSkills = null;
private final Map<Integer, 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<Integer, Long> _disabledSkills = null;
private final Map<Integer, Long> _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;
}

View File

@@ -7589,6 +7589,7 @@ public class PlayerInstance extends Playable
int buff_index = 0;
final List<Integer> 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<Integer, TimeStamp> reuseTimeStamps = getSkillReuseTimeStamps();
if (reuseTimeStamps != null)
for (Entry<Integer, TimeStamp> ts : getSkillReuseTimeStamps().entrySet())
{
for (Entry<Integer, TimeStamp> 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<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.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)
{

View File

@@ -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<TimeStamp> _skillReuseTimeStamps = new ArrayList<>();
public SkillCoolTime(PlayerInstance player)
{
final Map<Integer, 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())
{
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;
}