From a8446eaa9cf4772b849b8760b6b7ddf8c35b4f17 Mon Sep 17 00:00:00 2001 From: Neon Date: Mon, 26 Aug 2024 01:16:57 +0200 Subject: [PATCH] Memory optimizations --- .../data/handlers/ai/ServantNpcAI.java | 2 +- .../ai/manager/SkillAttackManager.java | 4 +- .../controllers/ObserveController.java | 28 +++------ .../aionemu/gameserver/model/PlayerClass.java | 54 +++++++++++----- .../model/gameobjects/Creature.java | 54 ++-------------- .../gameserver/model/gameobjects/Npc.java | 2 +- .../model/gameobjects/player/Player.java | 9 +++ .../stats/container/CreatureGameStats.java | 16 ++++- .../stats/container/CreatureLifeStats.java | 61 ++++++------------- .../model/stats/container/NpcGameStats.java | 31 +--------- .../model/stats/container/NpcLifeStats.java | 8 +-- .../stats/container/PlayerGameStats.java | 14 +++-- .../stats/container/PlayerLifeStats.java | 20 ++---- .../stats/container/SummonGameStats.java | 17 ------ .../stats/container/SummonLifeStats.java | 5 +- .../model/templates/item/ItemTemplate.java | 5 +- .../model/templates/stats/StatsTemplate.java | 41 ++----------- .../aion/clientpackets/CM_CASTSPELL.java | 3 +- 18 files changed, 121 insertions(+), 253 deletions(-) diff --git a/game-server/data/handlers/ai/ServantNpcAI.java b/game-server/data/handlers/ai/ServantNpcAI.java index 71108e366..c7ad5f96f 100644 --- a/game-server/data/handlers/ai/ServantNpcAI.java +++ b/game-server/data/handlers/ai/ServantNpcAI.java @@ -78,7 +78,7 @@ private void healOrAttack() { if ((template.getType() != SkillType.MAGICAL || !getOwner().getEffectController().isAbnormalSet(AbnormalState.SILENCE)) && (template.getType() != SkillType.PHYSICAL || !getOwner().getEffectController().isAbnormalSet(AbnormalState.BIND)) && (!getOwner().getEffectController().isInAnyAbnormalState(AbnormalState.CANT_ATTACK_STATE)) - && (!getOwner().getTransformModel().isActive() || getOwner().getTransformModel().getBanUseSkills() != 1)) { + && (!getOwner().isTransformed() || getOwner().getTransformModel().getBanUseSkills() != 1)) { SkillEngine.getInstance().getSkill(getOwner(), skill.getSkillId(), skill.getSkillLevel(), getOwner().getTarget()).useSkill(); } } diff --git a/game-server/src/com/aionemu/gameserver/ai/manager/SkillAttackManager.java b/game-server/src/com/aionemu/gameserver/ai/manager/SkillAttackManager.java index bb4f70d7f..3fb42dc57 100644 --- a/game-server/src/com/aionemu/gameserver/ai/manager/SkillAttackManager.java +++ b/game-server/src/com/aionemu/gameserver/ai/manager/SkillAttackManager.java @@ -73,7 +73,7 @@ protected static void skillAction(NpcAI npcAI) { if ((template.getType() == SkillType.MAGICAL && owner.getEffectController().isAbnormalSet(AbnormalState.SILENCE)) || (template.getType() == SkillType.PHYSICAL && owner.getEffectController().isAbnormalSet(AbnormalState.BIND)) || (owner.getEffectController().isInAnyAbnormalState(AbnormalState.CANT_ATTACK_STATE)) - || (owner.getTransformModel().isActive() && owner.getTransformModel().getBanUseSkills() == 1)) { + || (owner.isTransformed() && owner.getTransformModel().getBanUseSkills() == 1)) { afterUseSkill(npcAI); } else { if (template.getProperties().getFirstTarget() == FirstTargetAttribute.ME) { @@ -233,7 +233,7 @@ private static boolean isReady(Npc owner, NpcSkillEntry entry) { if ((template.getType() == SkillType.MAGICAL && owner.getEffectController().isAbnormalSet(AbnormalState.SILENCE)) || (template.getType() == SkillType.PHYSICAL && owner.getEffectController().isAbnormalSet(AbnormalState.BIND)) || (owner.getEffectController().isInAnyAbnormalState(AbnormalState.CANT_ATTACK_STATE)) - || (owner.getTransformModel().isActive() && owner.getTransformModel().getBanUseSkills() == 1)) { + || (owner.isTransformed() && owner.getTransformModel().getBanUseSkills() == 1)) { return false; } else { return true; diff --git a/game-server/src/com/aionemu/gameserver/controllers/ObserveController.java b/game-server/src/com/aionemu/gameserver/controllers/ObserveController.java index 58596478f..6c9d0a6e7 100644 --- a/game-server/src/com/aionemu/gameserver/controllers/ObserveController.java +++ b/game-server/src/com/aionemu/gameserver/controllers/ObserveController.java @@ -2,7 +2,6 @@ import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.locks.ReentrantLock; import com.aionemu.gameserver.controllers.attack.AttackResult; import com.aionemu.gameserver.controllers.attack.AttackStatus; @@ -20,21 +19,17 @@ */ public class ObserveController { - private ReentrantLock lock = new ReentrantLock(); - protected Collection observers = new CopyOnWriteArrayList<>(); - protected List onceUsedObservers = new ArrayList<>(); - protected Collection attackCalcObservers = new CopyOnWriteArrayList<>(); + protected final Collection observers = new CopyOnWriteArrayList<>(); + protected final List onceUsedObservers = new ArrayList<>(); + protected final Collection attackCalcObservers = new CopyOnWriteArrayList<>(); /** * Once used observer add to observerController. If observer notify will be removed. */ public void attach(ActionObserver observer) { observer.makeOneTimeUse(); - lock.lock(); - try { + synchronized (onceUsedObservers) { onceUsedObservers.add(observer); - } finally { - lock.unlock(); } } @@ -48,11 +43,8 @@ public void addAttackCalcObserver(AttackCalcObserver observer) { public void removeObserver(ActionObserver observer) { observers.remove(observer); - lock.lock(); - try { + synchronized (onceUsedObservers) { onceUsedObservers.remove(observer); - } finally { - lock.unlock(); } } @@ -62,8 +54,7 @@ public void removeAttackCalcObserver(AttackCalcObserver observer) { public void notifyObservers(ObserverType type, Object... object) { List tempOnceused = Collections.emptyList(); - lock.lock(); - try { + synchronized (onceUsedObservers) { if (onceUsedObservers.size() > 0) { tempOnceused = new ArrayList<>(); Iterator iterator = onceUsedObservers.iterator(); @@ -77,8 +68,6 @@ public void notifyObservers(ObserverType type, Object... object) { } } } - } finally { - lock.unlock(); } // notify outside of lock @@ -276,11 +265,8 @@ public float getBaseMagicalDamageMultiplier() { * Clear all observers */ public void clear() { - lock.lock(); - try { + synchronized (onceUsedObservers) { onceUsedObservers.clear(); - } finally { - lock.unlock(); } observers.clear(); attackCalcObservers.clear(); diff --git a/game-server/src/com/aionemu/gameserver/model/PlayerClass.java b/game-server/src/com/aionemu/gameserver/model/PlayerClass.java index e1143b3c6..d6386ae38 100644 --- a/game-server/src/com/aionemu/gameserver/model/PlayerClass.java +++ b/game-server/src/com/aionemu/gameserver/model/PlayerClass.java @@ -1,9 +1,5 @@ package com.aionemu.gameserver.model; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - import javax.xml.bind.annotation.XmlEnum; import com.aionemu.gameserver.configs.main.GSConfig; @@ -48,7 +44,7 @@ public enum PlayerClass implements L10n { /** Tells whether player can create new character with this class */ private PlayerClass startingClass; - private Map templatesByLevel = new HashMap<>(); + private final StatsTemplate[] templatesByLevel = new StatsTemplate[GSConfig.PLAYER_MAX_LEVEL]; private final int power, health, agility, accuracy, knowledge, will, healthMultiplier, willMultiplier; PlayerClass(int classId, int nameId, PlayerClass startingClass, int power, int health, int agility, int accuracy, int knowledge, int will, int healthMultiplier, int willMultiplier, int physicalAttack, int physicalCritical, int magicalCritical, int magicalCriticalResist) { @@ -74,14 +70,8 @@ public enum PlayerClass implements L10n { } private void initializeTemplatesForEachLevel(int physicalAttack, int physicalCritical, int magicalCritical, int magicalCriticalResist) { - for (int level = 1; level <= 65; level++) { - StatsTemplate statsTemplate = new StatsTemplate(); - statsTemplate.setPower(power); - statsTemplate.setHealth(health); - statsTemplate.setAgility(agility); - statsTemplate.setBaseAccuracy(accuracy); - statsTemplate.setKnowledge(knowledge); - statsTemplate.setWill(will); + for (int level = 1; level <= templatesByLevel.length; level++) { + PlayerStatsTemplate statsTemplate = new PlayerStatsTemplate(); statsTemplate.setMaxHp(PlayerStatCalculator.calculateMaxHp(this, level)); statsTemplate.setMaxMp(PlayerStatCalculator.calculateMaxMp(this, level)); statsTemplate.setBlock(PlayerStatCalculator.calculateBlockEvasionOrParry(level)); @@ -99,7 +89,7 @@ private void initializeTemplatesForEachLevel(int physicalAttack, int physicalCri speeds.setRunSpeed(6f); speeds.setFlySpeed(9f); statsTemplate.setSpeeds(speeds); - templatesByLevel.put(level, statsTemplate); + templatesByLevel[level - 1] = statsTemplate; } } @@ -190,8 +180,7 @@ public String getIconImage() { } public StatsTemplate getStatsTemplateFor(int level) { - StatsTemplate template = templatesByLevel.get(Math.min(level, GSConfig.PLAYER_MAX_LEVEL)); - return Objects.requireNonNull(template, () -> "Missing template for PlayerClass." + this + " on level " + level); + return templatesByLevel[Math.min(level, templatesByLevel.length) - 1]; } public int getPower() { @@ -237,4 +226,37 @@ public int getAccuracyMultiplier() { public int getNoWeaponPowerMultiplier() { return 70; } + + private class PlayerStatsTemplate extends StatsTemplate { + + @Override + public int getPower() { + return power; + } + + @Override + public int getHealth() { + return health; + } + + @Override + public int getAgility() { + return agility; + } + + @Override + public int getBaseAccuracy() { + return accuracy; + } + + @Override + public int getKnowledge() { + return knowledge; + } + + @Override + public int getWill() { + return will; + } + } } diff --git a/game-server/src/com/aionemu/gameserver/model/gameobjects/Creature.java b/game-server/src/com/aionemu/gameserver/model/gameobjects/Creature.java index e36fe259c..2ff98d7a0 100644 --- a/game-server/src/com/aionemu/gameserver/model/gameobjects/Creature.java +++ b/game-server/src/com/aionemu/gameserver/model/gameobjects/Creature.java @@ -51,14 +51,12 @@ public abstract class Creature extends VisibleObject { private Skill castingSkill; private Map skillCoolDowns; private ObserveController observeController; - private final TransformModel transformModel; + private TransformModel transformModel; private final AggroList aggroList; - private Item usingItem; private final byte[] zoneTypes = new byte[ZoneType.values().length]; private int skillNumber; private int attackedCount; private long spawnTime = System.currentTimeMillis(); - private TribeClass tribe = TribeClass.GENERAL; public Creature(int objId, CreatureController controller, SpawnTemplate spawnTemplate, CreatureTemplate objectTemplate, WorldPosition position, boolean autoReleaseObjectId) { @@ -68,7 +66,6 @@ public Creature(int objId, CreatureController controller, Sp aiName = SpawnTemplate.NO_AI.equals(spawnTemplate.getAiName()) ? null : spawnTemplate.getAiName(); this.ai = AIEngine.getInstance().newAI(aiName, this); this.observeController = new ObserveController(); - this.transformModel = new TransformModel(this); this.aggroList = createAggroList(); } @@ -210,42 +207,6 @@ public void clearAttackedCount() { attackedCount = 0; } - /** - * Is using item - * - * @return - */ - public boolean isUsingItem() { - return usingItem != null; - } - - /** - * Set using item - * - * @param usingItem - */ - public void setUsingItem(Item usingItem) { - this.usingItem = usingItem; - } - - /** - * get Using ItemId - * - * @return - */ - public int getUsingItemId() { - return usingItem != null ? usingItem.getItemTemplate().getTemplateId() : 0; - } - - /** - * Using Item - * - * @return - */ - public Item getUsingItem() { - return usingItem; - } - /** * All abnormal effects are checked that disable movements * @@ -374,10 +335,9 @@ public boolean isInSeeState(CreatureSeeState seeState) { return false; } - /** - * @return the transformModel - */ public TransformModel getTransformModel() { + if (transformModel == null) + transformModel = new TransformModel(this); return transformModel; } @@ -386,7 +346,7 @@ public void endTransformation() { } public boolean isTransformed() { - return getTransformModel().isActive(); + return transformModel != null && getTransformModel().isActive(); } /** @@ -437,11 +397,7 @@ public boolean isEnemyFrom(Npc npc) { } public TribeClass getTribe() { - return tribe; - } - - public void setTribe(TribeClass tribe) { - this.tribe = tribe; + return TribeClass.GENERAL; } public TribeClass getBaseTribe() { diff --git a/game-server/src/com/aionemu/gameserver/model/gameobjects/Npc.java b/game-server/src/com/aionemu/gameserver/model/gameobjects/Npc.java index ccc0ecf01..638330e98 100644 --- a/game-server/src/com/aionemu/gameserver/model/gameobjects/Npc.java +++ b/game-server/src/com/aionemu/gameserver/model/gameobjects/Npc.java @@ -165,7 +165,7 @@ public boolean isPathWalker() { @Override public TribeClass getTribe() { - TribeClass transformTribe = getTransformModel().getTribe(); + TribeClass transformTribe = isTransformed() ? getTransformModel().getTribe() : null; if (transformTribe != null) { return transformTribe; } diff --git a/game-server/src/com/aionemu/gameserver/model/gameobjects/player/Player.java b/game-server/src/com/aionemu/gameserver/model/gameobjects/player/Player.java index 1b30326d3..b63e06a2d 100644 --- a/game-server/src/com/aionemu/gameserver/model/gameobjects/player/Player.java +++ b/game-server/src/com/aionemu/gameserver/model/gameobjects/player/Player.java @@ -113,6 +113,7 @@ public class Player extends Creature { private Storage[] cabinets = new Storage[StorageType.HOUSE_WH_MAX - StorageType.HOUSE_WH_MIN + 1]; private Storage regularWarehouse; private Equipment equipment; + private Item usingItem; private final AbsoluteStatOwner absStatsHolder; private PlayerSettings playerSettings; @@ -465,6 +466,14 @@ public void setEquipment(Equipment equipment) { this.equipment = equipment; } + public Item getUsingItem() { + return usingItem; + } + + public void setUsingItem(Item usingItem) { + this.usingItem = usingItem; + } + /** * @return the player private store */ diff --git a/game-server/src/com/aionemu/gameserver/model/stats/container/CreatureGameStats.java b/game-server/src/com/aionemu/gameserver/model/stats/container/CreatureGameStats.java index 350fc8cdc..7c31e069f 100644 --- a/game-server/src/com/aionemu/gameserver/model/stats/container/CreatureGameStats.java +++ b/game-server/src/com/aionemu/gameserver/model/stats/container/CreatureGameStats.java @@ -8,6 +8,7 @@ import org.apache.commons.lang3.ArrayUtils; +import com.aionemu.gameserver.model.EmotionType; import com.aionemu.gameserver.model.SkillElement; import com.aionemu.gameserver.model.enchants.EnchantEffect; import com.aionemu.gameserver.model.gameobjects.Creature; @@ -20,7 +21,9 @@ import com.aionemu.gameserver.model.stats.calc.functions.StatFunctionProxy; import com.aionemu.gameserver.model.templates.itemset.ItemSetTemplate; import com.aionemu.gameserver.model.templates.stats.StatsTemplate; +import com.aionemu.gameserver.network.aion.serverpackets.SM_EMOTION; import com.aionemu.gameserver.skillengine.model.Effect; +import com.aionemu.gameserver.utils.PacketSendUtility; import com.aionemu.gameserver.utils.stats.CalculationType; /** @@ -35,7 +38,7 @@ public abstract class CreatureGameStats { private long lastGeoUpdate = 0; private int attackCounter = 0; - private int cachedMaxHp, cachedMaxMp; + private int cachedMaxHp, cachedMaxMp, cachedSpeed; protected CreatureGameStats(T owner) { this.owner = owner; @@ -314,6 +317,17 @@ public void updateStatInfo() { * Send packet about speed info */ public void updateSpeedInfo() { + PacketSendUtility.broadcastPacket(owner, new SM_EMOTION(owner, EmotionType.CHANGE_SPEED)); + } + + protected boolean checkSpeedStats() { + int currentSpeed = getMovementSpeed().getCurrent(); + if (currentSpeed != cachedSpeed) { + updateSpeedInfo(); + cachedSpeed = currentSpeed; + return true; + } + return false; } /** diff --git a/game-server/src/com/aionemu/gameserver/model/stats/container/CreatureLifeStats.java b/game-server/src/com/aionemu/gameserver/model/stats/container/CreatureLifeStats.java index 547bb3cb4..169e2b11c 100644 --- a/game-server/src/com/aionemu/gameserver/model/stats/container/CreatureLifeStats.java +++ b/game-server/src/com/aionemu/gameserver/model/stats/container/CreatureLifeStats.java @@ -2,8 +2,6 @@ import java.util.Objects; import java.util.concurrent.Future; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; import com.aionemu.gameserver.model.gameobjects.Creature; import com.aionemu.gameserver.network.aion.serverpackets.SM_ATTACK_STATUS; @@ -25,10 +23,10 @@ public abstract class CreatureLifeStats { protected boolean isAboutToDie = false;// for long animation skills that will kill protected int killingBlow;// for long animation skills that will kill - last damage protected final T owner; - private final Lock hpLock = new ReentrantLock(); - private final Lock mpLock = new ReentrantLock(); - protected final Lock restoreLock = new ReentrantLock(); - protected volatile Future lifeRestoreTask; + private final Object hpLock = new Object(); + private final Object mpLock = new Object(); + protected final Object restoreLock = new Object(); + protected Future lifeRestoreTask; public CreatureLifeStats(T owner, int currentHp, int currentMp) { this.owner = owner; @@ -122,8 +120,7 @@ public int reduceHp(TYPE type, int value, int skillId, LOG log, Creature attacke int hpReduced = 0; boolean died = false; - hpLock.lock(); - try { + synchronized (hpLock) { if (isDead) return 0; @@ -136,8 +133,6 @@ public int reduceHp(TYPE type, int value, int skillId, LOG log, Creature attacke setIsDead(died = true); } } - } finally { - hpLock.unlock(); } if (hpReduced > 0 || skillId != 0) @@ -164,8 +159,7 @@ public int reduceHp(TYPE type, int value, int skillId, LOG log, Creature attacke */ public int reduceMp(TYPE type, int value, int skillId, LOG log) { int mpReduced = 0; - mpLock.lock(); - try { + synchronized (mpLock) { if (isDead) return 0; @@ -174,8 +168,6 @@ public int reduceMp(TYPE type, int value, int skillId, LOG log) { mpReduced = currentMp - newMp; currentMp = newMp; } - } finally { - mpLock.unlock(); } if (mpReduced > 0 || skillId != 0) @@ -211,8 +203,7 @@ private int increaseHp(TYPE type, int value, Creature effector, int skillId, LOG int hpIncreased; boolean died = false; - hpLock.lock(); - try { + synchronized (hpLock) { if (isDead) return 0; @@ -223,8 +214,6 @@ private int increaseHp(TYPE type, int value, Creature effector, int skillId, LOG currentHp = 0; setIsDead(died = true); } - } finally { - hpLock.unlock(); } if (hpIncreased > 0 || skillId != 0) @@ -251,8 +240,7 @@ public int increaseMp(int value) { public int increaseMp(TYPE type, int value, int skillId, LOG log) { int mpIncreased = 0; - mpLock.lock(); - try { + synchronized (mpLock) { if (isDead) return 0; @@ -261,8 +249,6 @@ public int increaseMp(TYPE type, int value, int skillId, LOG log) { mpIncreased = newMp - currentMp; currentMp = newMp; } - } finally { - mpLock.unlock(); } if (mpIncreased > 0 || skillId != 0) @@ -288,13 +274,10 @@ public final void restoreMp() { * Will trigger restore task if not already */ public void triggerRestoreTask() { - restoreLock.lock(); - try { + synchronized (restoreLock) { if (lifeRestoreTask == null && !isDead()) { lifeRestoreTask = LifeStatsRestoreService.getInstance().scheduleRestoreTask(this); } - } finally { - restoreLock.unlock(); } } @@ -303,14 +286,11 @@ public void triggerRestoreTask() { * Cancel currently running restore task */ public void cancelRestoreTask() { - restoreLock.lock(); - try { + synchronized (restoreLock) { if (lifeRestoreTask != null) { lifeRestoreTask.cancel(false); lifeRestoreTask = null; } - } finally { - restoreLock.unlock(); } } @@ -425,14 +405,13 @@ public final void setCurrentHp(int hp) { } public final void setCurrentHp(int hp, Creature effector) { - hpLock.lock(); - boolean wasDead = isDead; - int prevHp = currentHp; - try { + boolean wasDead; + int prevHp; + synchronized (hpLock) { + wasDead = isDead; + prevHp = currentHp; currentHp = Math.max(0, Math.min(hp, getMaxHp())); setIsDead(currentHp == 0); - } finally { - hpLock.unlock(); } onSetHp(); if (!wasDead && isDead) @@ -455,11 +434,8 @@ protected void onHpChanged() { * Sets the current MP without notifying observers */ public final void setCurrentMp(int value) { - mpLock.lock(); - try { + synchronized (mpLock) { currentMp = Math.max(0, Math.min(value, getMaxMp())); - } finally { - mpLock.unlock(); } onSetMp(); } @@ -470,11 +446,8 @@ public final void setCurrentMp(int value) { * @param mpPercent */ public final void setCurrentMpPercent(int mpPercent) { - mpLock.lock(); - try { + synchronized (mpLock) { currentMp = (int) (mpPercent / 100f * getMaxMp()); - } finally { - mpLock.unlock(); } onSetMp(); } diff --git a/game-server/src/com/aionemu/gameserver/model/stats/container/NpcGameStats.java b/game-server/src/com/aionemu/gameserver/model/stats/container/NpcGameStats.java index cd5009f54..f4f9e57b1 100644 --- a/game-server/src/com/aionemu/gameserver/model/stats/container/NpcGameStats.java +++ b/game-server/src/com/aionemu/gameserver/model/stats/container/NpcGameStats.java @@ -3,7 +3,6 @@ import com.aionemu.commons.utils.Rnd; import com.aionemu.gameserver.ai.AILogger; import com.aionemu.gameserver.ai.AISubState; -import com.aionemu.gameserver.model.EmotionType; import com.aionemu.gameserver.model.gameobjects.Creature; import com.aionemu.gameserver.model.gameobjects.Npc; import com.aionemu.gameserver.model.gameobjects.state.CreatureState; @@ -11,9 +10,7 @@ import com.aionemu.gameserver.model.stats.calc.Stat2; import com.aionemu.gameserver.model.templates.npc.AbyssNpcType; import com.aionemu.gameserver.model.templates.stats.StatsTemplate; -import com.aionemu.gameserver.network.aion.serverpackets.SM_EMOTION; import com.aionemu.gameserver.skillengine.model.Effect; -import com.aionemu.gameserver.utils.PacketSendUtility; import com.aionemu.gameserver.utils.PositionUtil; import com.aionemu.gameserver.utils.stats.CalculationType; @@ -26,12 +23,9 @@ public class NpcGameStats extends CreatureGameStats { private long lastAttackedTime = 0; private long nextAttackTime = 0; private long lastSkillTime = 0; - private long nextSkillDelay = 0; + private int nextSkillDelay = 0; private NpcSkillEntry lastSkill = null; private long fightStartingTime = 0; - private int cachedState; - private AISubState cachedSubState; - private Stat2 cachedSpeedStat; private long nextGeoZUpdate; private long lastChangeTarget = 0; @@ -45,16 +39,6 @@ protected void onStatsChange(Effect effect) { checkSpeedStats(); } - private void checkSpeedStats() { - Stat2 oldSpeed = cachedSpeedStat; - cachedSpeedStat = null; - Stat2 newSpeed = getMovementSpeed(); - cachedSpeedStat = newSpeed; - if (oldSpeed == null || oldSpeed.getCurrent() != newSpeed.getCurrent()) { - updateSpeedInfo(); - } - } - @Override public StatsTemplate getStatsTemplate() { return owner.getObjectTemplate().getStatsTemplate(); @@ -74,11 +58,6 @@ public Stat2 getAttackSpeed() { @Override public Stat2 getMovementSpeed() { - int currentState = owner.getState(); - AISubState currentSubState = owner.getAi().getSubState(); - if (cachedSpeedStat != null && cachedState == currentState && cachedSubState == currentSubState) { - return cachedSpeedStat; - } Stat2 newSpeedStat; if (owner.isInState(CreatureState.WEAPON_EQUIPPED)) { float speed; @@ -98,9 +77,6 @@ public Stat2 getMovementSpeed() { float multiplier = owner.isFlying() ? 1.3f : 1.0f; newSpeedStat = getStat(StatEnum.SPEED, Math.round(getStatsTemplate().getRunSpeed() * multiplier * 1000)); } - cachedState = currentState; - cachedSubState = currentSubState; - cachedSpeedStat = newSpeedStat; return newSpeedStat; } @@ -220,11 +196,6 @@ public NpcSkillEntry getLastSkill() { return lastSkill; } - @Override - public void updateSpeedInfo() { - PacketSendUtility.broadcastPacket(owner, new SM_EMOTION(owner, EmotionType.CHANGE_SPEED, 0, 0)); - } - public final long getNextGeoZUpdate() { return nextGeoZUpdate; } diff --git a/game-server/src/com/aionemu/gameserver/model/stats/container/NpcLifeStats.java b/game-server/src/com/aionemu/gameserver/model/stats/container/NpcLifeStats.java index d310ffb1c..b8e2c131c 100644 --- a/game-server/src/com/aionemu/gameserver/model/stats/container/NpcLifeStats.java +++ b/game-server/src/com/aionemu/gameserver/model/stats/container/NpcLifeStats.java @@ -8,22 +8,16 @@ */ public class NpcLifeStats extends CreatureLifeStats { - /** - * @param owner - */ public NpcLifeStats(Npc owner) { super(owner, owner.getGameStats().getMaxHp().getCurrent(), owner.getGameStats().getMaxMp().getCurrent()); } @Override public void triggerRestoreTask() { - restoreLock.lock(); - try { + synchronized (restoreLock) { if (lifeRestoreTask == null && !isDead) { this.lifeRestoreTask = LifeStatsRestoreService.getInstance().scheduleHpRestoreTask(this); } - } finally { - restoreLock.unlock(); } } } diff --git a/game-server/src/com/aionemu/gameserver/model/stats/container/PlayerGameStats.java b/game-server/src/com/aionemu/gameserver/model/stats/container/PlayerGameStats.java index 5f8f994d6..628b8d3e0 100644 --- a/game-server/src/com/aionemu/gameserver/model/stats/container/PlayerGameStats.java +++ b/game-server/src/com/aionemu/gameserver/model/stats/container/PlayerGameStats.java @@ -26,7 +26,6 @@ */ public class PlayerGameStats extends CreatureGameStats { - private int cachedSpeed; private int cachedAttackSpeed; private int maxDamageChance; private float minDamageRatio; @@ -51,14 +50,17 @@ public void updateStatsVisually() { updateStatInfo(); } - private void checkSpeedStats() { - int current = getMovementSpeed().getCurrent(); + @Override + protected boolean checkSpeedStats() { + boolean speedChanged = super.checkSpeedStats(); int currentAttackSpeed = getAttackSpeed().getCurrent(); - if (current != cachedSpeed || currentAttackSpeed != cachedAttackSpeed) { - updateSpeedInfo(); - cachedSpeed = current; + if (currentAttackSpeed != cachedAttackSpeed) { + if (!speedChanged) // prevent double packet broadcast (super.checkSpeedStats() already broadcasts on true) + updateSpeedInfo(); cachedAttackSpeed = currentAttackSpeed; + return true; } + return speedChanged; } @Override diff --git a/game-server/src/com/aionemu/gameserver/model/stats/container/PlayerLifeStats.java b/game-server/src/com/aionemu/gameserver/model/stats/container/PlayerLifeStats.java index f9aac21c4..62cb1f2ed 100644 --- a/game-server/src/com/aionemu/gameserver/model/stats/container/PlayerLifeStats.java +++ b/game-server/src/com/aionemu/gameserver/model/stats/container/PlayerLifeStats.java @@ -235,25 +235,19 @@ public void specialrestoreFp() { public void triggerFpRestore() { cancelFpReduce(); - restoreLock.lock(); - try { + synchronized (restoreLock) { if (flyRestoreTask == null && !isDead && !isFlyTimeFullyRestored()) { flyRestoreTask = LifeStatsRestoreService.getInstance().scheduleFpRestoreTask(this); } - } finally { - restoreLock.unlock(); } } public void cancelFpRestore() { - restoreLock.lock(); - try { + synchronized (restoreLock) { if (flyRestoreTask != null && !flyRestoreTask.isCancelled()) { flyRestoreTask.cancel(false); flyRestoreTask = null; } - } finally { - restoreLock.unlock(); } } @@ -267,8 +261,7 @@ public void triggerFpReduce() { private void triggerFpReduce(Integer costFp) { cancelFpRestore(); - restoreLock.lock(); - try { + synchronized (restoreLock) { if (!owner.hasAccess(AdminConfig.UNLIMITED_FLIGHT_TIME) && !isDead) { if (costFp != null) { flightReduceValue.set(costFp); @@ -288,20 +281,15 @@ private void triggerFpReduce(Integer costFp) { } } } - } finally { - restoreLock.unlock(); } } public void cancelFpReduce() { - restoreLock.lock(); - try { + synchronized (restoreLock) { if (flyReduceTask != null && !flyReduceTask.isCancelled()) { flyReduceTask.cancel(false); flyReduceTask = null; } - } finally { - restoreLock.unlock(); } } diff --git a/game-server/src/com/aionemu/gameserver/model/stats/container/SummonGameStats.java b/game-server/src/com/aionemu/gameserver/model/stats/container/SummonGameStats.java index 89f8d9044..db3d90701 100644 --- a/game-server/src/com/aionemu/gameserver/model/stats/container/SummonGameStats.java +++ b/game-server/src/com/aionemu/gameserver/model/stats/container/SummonGameStats.java @@ -1,12 +1,10 @@ package com.aionemu.gameserver.model.stats.container; -import com.aionemu.gameserver.model.EmotionType; import com.aionemu.gameserver.model.gameobjects.Summon; import com.aionemu.gameserver.model.gameobjects.player.Player; import com.aionemu.gameserver.model.stats.calc.Stat2; import com.aionemu.gameserver.model.summons.SummonMode; import com.aionemu.gameserver.model.templates.stats.StatsTemplate; -import com.aionemu.gameserver.network.aion.serverpackets.SM_EMOTION; import com.aionemu.gameserver.network.aion.serverpackets.SM_SUMMON_UPDATE; import com.aionemu.gameserver.skillengine.model.Effect; import com.aionemu.gameserver.utils.PacketSendUtility; @@ -17,8 +15,6 @@ */ public class SummonGameStats extends CreatureGameStats { - private int cachedSpeed; - public SummonGameStats(Summon owner) { super(owner); } @@ -37,14 +33,6 @@ public void updateStatsVisually() { owner.getGameStats().updateStatInfo(); } - private void checkSpeedStats() { - int current = getMovementSpeed().getCurrent(); - if (current != cachedSpeed) { - owner.getGameStats().updateSpeedInfo(); - } - cachedSpeed = current; - } - @Override public Stat2 getStat(StatEnum statEnum, float base, CalculationType... calculationTypes) { Stat2 stat = super.getStat(statEnum, base, calculationTypes); @@ -158,9 +146,4 @@ public void updateStatInfo() { PacketSendUtility.sendPacket(master, new SM_SUMMON_UPDATE(owner)); } } - - @Override - public void updateSpeedInfo() { - PacketSendUtility.broadcastPacket(owner, new SM_EMOTION(owner, EmotionType.CHANGE_SPEED, 0, 0)); - } } diff --git a/game-server/src/com/aionemu/gameserver/model/stats/container/SummonLifeStats.java b/game-server/src/com/aionemu/gameserver/model/stats/container/SummonLifeStats.java index 4d784840a..283bd5e06 100644 --- a/game-server/src/com/aionemu/gameserver/model/stats/container/SummonLifeStats.java +++ b/game-server/src/com/aionemu/gameserver/model/stats/container/SummonLifeStats.java @@ -27,13 +27,10 @@ protected void onIncreaseHp(TYPE type, int value, int skillId, LOG log) { @Override public void triggerRestoreTask() { - restoreLock.lock(); - try { + synchronized (restoreLock) { if (lifeRestoreTask == null && !isDead) { this.lifeRestoreTask = LifeStatsRestoreService.getInstance().scheduleHpRestoreTask(this); } - } finally { - restoreLock.unlock(); } } } diff --git a/game-server/src/com/aionemu/gameserver/model/templates/item/ItemTemplate.java b/game-server/src/com/aionemu/gameserver/model/templates/item/ItemTemplate.java index 4f7fc8920..82ccca501 100644 --- a/game-server/src/com/aionemu/gameserver/model/templates/item/ItemTemplate.java +++ b/game-server/src/com/aionemu/gameserver/model/templates/item/ItemTemplate.java @@ -123,7 +123,7 @@ public class ItemTemplate extends VisibleObjectTemplate { @XmlElement(name = "improve") private Improvement improvement; @XmlElement(name = "uselimits") - private ItemUseLimits useLimits = new ItemUseLimits(); + private ItemUseLimits useLimits; @XmlElement(name = "inventory") private ExtraInventory extraInventory; @XmlElement(name = "idian") @@ -134,6 +134,7 @@ public class ItemTemplate extends VisibleObjectTemplate { private ExceedEnchantSkillSetType exceedEnchantSkill; private static final WeaponStats emptyWeaponStats = new WeaponStats(); + private static final ItemUseLimits emptyUseLimits = new ItemUseLimits(); @XmlID @XmlAttribute(name = "id", required = true) @@ -144,6 +145,8 @@ private void setXmlUid(String uid) { void afterUnmarshal(Unmarshaller u, Object parent) { if (weaponStats == null) weaponStats = emptyWeaponStats; + if (useLimits == null) + useLimits = emptyUseLimits; // check if it can be randomized if (getItemSlot() == 0) diff --git a/game-server/src/com/aionemu/gameserver/model/templates/stats/StatsTemplate.java b/game-server/src/com/aionemu/gameserver/model/templates/stats/StatsTemplate.java index 3b95a1eaf..94b57c30f 100644 --- a/game-server/src/com/aionemu/gameserver/model/templates/stats/StatsTemplate.java +++ b/game-server/src/com/aionemu/gameserver/model/templates/stats/StatsTemplate.java @@ -57,11 +57,6 @@ public class StatsTemplate { @XmlElement private CreatureSpeeds speeds; - @XmlTransient - private int power = 100, health = 100, agility = 100, baseAccuracy = 100, knowledge = 100, will = 100; - - /* ======================================= */ - public int getMaxHp() { return maxHp; } @@ -243,50 +238,26 @@ public void setSpeeds(CreatureSpeeds speeds) { } public int getPower() { - return power; - } - - public void setPower(int power) { - this.power = power; + return 100; } public int getHealth() { - return health; - } - - public void setHealth(int health) { - this.health = health; + return 100; } public int getAgility() { - return agility; - } - - public void setAgility(int agility) { - this.agility = agility; + return 100; } public int getBaseAccuracy() { - return baseAccuracy; - } - - public void setBaseAccuracy(int baseAccuracy) { - this.baseAccuracy = baseAccuracy; + return 100; } public int getKnowledge() { - return knowledge; - } - - public void setKnowledge(int knowledge) { - this.knowledge = knowledge; + return 100; } public int getWill() { - return will; - } - - public void setWill(int will) { - this.will = will; + return 100; } } diff --git a/game-server/src/com/aionemu/gameserver/network/aion/clientpackets/CM_CASTSPELL.java b/game-server/src/com/aionemu/gameserver/network/aion/clientpackets/CM_CASTSPELL.java index 5bec8781a..51798c6fd 100644 --- a/game-server/src/com/aionemu/gameserver/network/aion/clientpackets/CM_CASTSPELL.java +++ b/game-server/src/com/aionemu/gameserver/network/aion/clientpackets/CM_CASTSPELL.java @@ -92,8 +92,7 @@ protected void runImpl() { if (player.isProtectionActive()) player.getController().stopProtectionActiveTask(); - if (player.isUsingItem()) - player.getController().cancelUseItem(); + player.getController().cancelUseItem(); long currentTime = System.currentTimeMillis(); if (player.getNextSkillUse() > currentTime) {