From a34452106b40c68c06aa6e2fb2359b8e8a22bc7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E9=B9=AD?= <18535853+PkllonG@users.noreply.github.com> Date: Fri, 10 Oct 2025 15:43:29 +0800 Subject: [PATCH 1/4] crash --- src/server/game/Entities/Player/Player.h | 4 ++-- src/server/game/Entities/Player/PlayerUpdates.cpp | 7 ++++--- src/server/game/Entities/Unit/Unit.cpp | 2 +- src/server/game/Spells/Spell.cpp | 5 +++-- src/server/game/Spells/Spell.h | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 74c89cc96d..146aca9fc9 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2071,8 +2071,8 @@ public: void UpdateLocalChannels(uint32 newZone); void UpdateDefense(); - void UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, Item* item = nullptr); - void UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence, Item* item = nullptr); + void UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, ObjectGuid const itemGuid = ObjectGuid::Empty); + void UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence, ObjectGuid const itemGuid = ObjectGuid::Empty); void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal); [[nodiscard]] uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus + temp bonus diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index d3798a083f..d0824722fd 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -978,7 +978,7 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step) return false; } -void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, Item* item /*= nullptr*/) +void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, ObjectGuid const itemGuid /*= ObjectGuid::Empty*/) { if (IsInFeralForm()) return; // always maximized SKILL_FERAL_COMBAT in fact @@ -992,6 +992,7 @@ void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, Item* ite uint32 weapon_skill_gain = sWorld->getIntConfig(CONFIG_SKILL_GAIN_WEAPON); Item* tmpitem = GetWeaponForAttack(attType, true); + Item* item = GetItemByGuid(itemGuid); if (item && item != tmpitem && !item->IsBroken()) { tmpitem = item; @@ -1022,7 +1023,7 @@ void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, Item* ite UpdateAllCritPercentages(); } -void Player::UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence, Item* item /*= nullptr*/) +void Player::UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence, ObjectGuid const itemGuid /*= ObjectGuid::Empty*/) { uint8 playerLevel = GetLevel(); uint16 currentSkillValue = defence ? GetBaseDefenseSkillValue() : GetBaseWeaponSkillValue(attType); @@ -1071,7 +1072,7 @@ void Player::UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool def } else { - UpdateWeaponSkill(victim, attType, item); + UpdateWeaponSkill(victim, attType, itemGuid); } } } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index addcf5b2b8..05455eb013 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -16165,7 +16165,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u // On melee based hit/miss/resist/parry/dodge need to update skill (for victim and attacker) if (procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_MISS | PROC_EX_RESIST | PROC_EX_PARRY | PROC_EX_DODGE)) { - ToPlayer()->UpdateCombatSkills(target, attType, isVictim, procSpell ? procSpell->m_weaponItem : nullptr); + ToPlayer()->UpdateCombatSkills(target, attType, isVictim, procSpell ? procSpell->m_weaponItemGUID : ObjectGuid::Empty); } // Update defence if player is victim and we block - TODO: confirm that blocked attacks only have a chance to increase defence skill else if (isVictim && procExtra & (PROC_EX_BLOCK)) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 4ae8bfca43..4e97f7f03f 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -687,7 +687,7 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, // xinef: _spellTargetsSelected = false; - m_weaponItem = nullptr; + m_weaponItemGUID = ObjectGuid::Empty; } Spell::~Spell() @@ -7691,7 +7691,8 @@ SpellCastResult Spell::CheckItems() return SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND; } - m_weaponItem = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true); + if (Item* weaponItem = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true)) + m_weaponItemGUID = weaponItem->GetGUID(); } return SPELL_CAST_OK; diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 3025e803e6..7b81aa810e 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -530,7 +530,7 @@ public: SpellInfo const* const m_spellInfo; Item* m_CastItem; - Item* m_weaponItem; + ObjectGuid m_weaponItemGUID; ObjectGuid m_castItemGUID; uint8 m_cast_count; uint32 m_glyphIndex; From 52b215ed5f9cda64441f1ab21ef6b3601799822b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E9=B9=AD?= <18535853+PkllonG@users.noreply.github.com> Date: Fri, 10 Oct 2025 21:54:18 +0800 Subject: [PATCH 2/4] ObjectGuid const& --- src/server/game/Entities/Player/Player.h | 4 ++-- src/server/game/Entities/Player/PlayerUpdates.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 146aca9fc9..3bffcb01bf 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2071,8 +2071,8 @@ public: void UpdateLocalChannels(uint32 newZone); void UpdateDefense(); - void UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, ObjectGuid const itemGuid = ObjectGuid::Empty); - void UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence, ObjectGuid const itemGuid = ObjectGuid::Empty); + void UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, ObjectGuid const& itemGuid = ObjectGuid::Empty); + void UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence, ObjectGuid const& itemGuid = ObjectGuid::Empty); void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal); [[nodiscard]] uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus + temp bonus diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index d0824722fd..015a8cdb1e 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -978,7 +978,7 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step) return false; } -void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, ObjectGuid const itemGuid /*= ObjectGuid::Empty*/) +void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, ObjectGuid const& itemGuid /*= ObjectGuid::Empty*/) { if (IsInFeralForm()) return; // always maximized SKILL_FERAL_COMBAT in fact @@ -1023,7 +1023,7 @@ void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, ObjectGui UpdateAllCritPercentages(); } -void Player::UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence, ObjectGuid const itemGuid /*= ObjectGuid::Empty*/) +void Player::UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence, ObjectGuid const& itemGuid /*= ObjectGuid::Empty*/) { uint8 playerLevel = GetLevel(); uint16 currentSkillValue = defence ? GetBaseDefenseSkillValue() : GetBaseWeaponSkillValue(attType); From 1fdccaada77bdc478c53df342da61fd106bee64a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E9=B9=AD?= <18535853+PkllonG@users.noreply.github.com> Date: Sat, 11 Oct 2025 09:26:59 +0800 Subject: [PATCH 3/4] Update Spell.cpp --- src/server/game/Spells/Spell.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 4e97f7f03f..9623bb6da4 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -7693,6 +7693,8 @@ SpellCastResult Spell::CheckItems() if (Item* weaponItem = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true)) m_weaponItemGUID = weaponItem->GetGUID(); + else + m_weaponItemGUID = ObjectGuid::Empty; } return SPELL_CAST_OK; From f4f4d7570fe5b8a267badcfa5e7b38d8a8045a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E9=B9=AD?= <18535853+PkllonG@users.noreply.github.com> Date: Sun, 12 Oct 2025 17:02:08 +0800 Subject: [PATCH 4/4] optimization --- src/server/game/Entities/Player/PlayerUpdates.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 015a8cdb1e..4529eba7f4 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -992,10 +992,12 @@ void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, ObjectGui uint32 weapon_skill_gain = sWorld->getIntConfig(CONFIG_SKILL_GAIN_WEAPON); Item* tmpitem = GetWeaponForAttack(attType, true); - Item* item = GetItemByGuid(itemGuid); - if (item && item != tmpitem && !item->IsBroken()) + ObjectGuid tmpitemGUID = tmpitem ? tmpitem->GetGUID() : ObjectGuid::Empty; + if (itemGuid != ObjectGuid::Empty && itemGuid != tmpitemGUID) { - tmpitem = item; + Item* item = GetItemByGuid(itemGuid); + if (item && !item->IsBroken()) + tmpitem = item; } if (!tmpitem && attType == BASE_ATTACK)