From 91e844e9dcd6358ed2f750ac842a018c2b522941 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Sat, 24 Sep 2022 13:50:39 -0400 Subject: [PATCH] Core/Player: Extend action button value to uint64 to be able to hold battle pet guids Port From (https://github.com/TrinityCore/TrinityCore/commit/f67cd38312014b13624dcb5fe1d117dac4892b7d) --- Source/Game/Entities/Player/Player.DB.cs | 4 +-- Source/Game/Entities/Player/Player.Fields.cs | 6 ++-- Source/Game/Entities/Player/Player.cs | 30 ++++++++++--------- Source/Game/Handlers/MiscHandler.cs | 2 +- .../Game/Networking/Packets/SpellPackets.cs | 6 ++-- Source/Game/Spells/SpellEffects.cs | 2 +- sql/base/characters_database.sql | 5 ++-- .../master/2022_09_18_00_characters.sql | 1 + 8 files changed, 31 insertions(+), 25 deletions(-) create mode 100644 sql/updates/characters/master/2022_09_18_00_characters.sql diff --git a/Source/Game/Entities/Player/Player.DB.cs b/Source/Game/Entities/Player/Player.DB.cs index 2b97a11bf..242d16fd6 100644 --- a/Source/Game/Entities/Player/Player.DB.cs +++ b/Source/Game/Entities/Player/Player.DB.cs @@ -676,7 +676,7 @@ namespace Game.Entities do { byte button = result.Read(0); - uint action = result.Read(1); + ulong action = result.Read(1); byte type = result.Read(2); ActionButton ab = AddActionButton(button, action, type); @@ -684,7 +684,7 @@ namespace Game.Entities ab.uState = ActionButtonUpdateState.UnChanged; else { - Log.outError(LogFilter.Player, " ...at loading, and will deleted in DB also"); + Log.outError(LogFilter.Player, $"Player::_LoadActions: Player '{GetName()}' ({GetGUID()}) has an invalid action button (Button: {button}, Action: {action}, Type: {type}). It will be deleted at next save. This can be due to a player changing their talents."); // Will deleted in DB at next save (it can create data until save but marked as deleted) m_actionButtons[button] = new ActionButton(); diff --git a/Source/Game/Entities/Player/Player.Fields.cs b/Source/Game/Entities/Player/Player.Fields.cs index 077fb349b..6bb1ff6f3 100644 --- a/Source/Game/Entities/Player/Player.Fields.cs +++ b/Source/Game/Entities/Player/Player.Fields.cs @@ -413,8 +413,10 @@ namespace Game.Entities uState = ActionButtonUpdateState.New; } - public ActionButtonType GetButtonType() { return (ActionButtonType)((packedData & 0xFFFFFFFF00000000) >> 56); } - public uint GetAction() { return (uint)(packedData & 0x00000000FFFFFFFF); } + public ActionButtonType GetButtonType() { return (ActionButtonType)((packedData & 0xFF00000000000000) >> 56); } + + public ulong GetAction() { return (packedData & 0x00FFFFFFFFFFFFFF); } + public void SetActionAndType(ulong action, ActionButtonType type) { ulong newData = action | ((ulong)type << 56); diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 3582a4bd3..06cf65747 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -1327,39 +1327,39 @@ namespace Game.Entities return (byte)_CUFProfiles.Count(p => p != null); } - bool IsActionButtonDataValid(byte button, uint action, uint type) + bool IsActionButtonDataValid(byte button, ulong action, uint type) { if (button >= PlayerConst.MaxActionButtons) { - Log.outError(LogFilter.Player, "Action {0} not added into button {1} for player {2} (GUID: {3}): button must be < {4}", action, button, GetName(), GetGUID(), PlayerConst.MaxActionButtons); + Log.outError(LogFilter.Player, $"Player::IsActionButtonDataValid: Action {action} not added into button {button} for player {GetName()} ({GetGUID()}): button must be < {PlayerConst.MaxActionButtons}"); return false; } if (action >= PlayerConst.MaxActionButtonActionValue) { - Log.outError(LogFilter.Player, "Action {0} not added into button {1} for player {2} (GUID: {3}): action must be < {4}", action, button, GetName(), GetGUID(), PlayerConst.MaxActionButtonActionValue); + Log.outError(LogFilter.Player, $"Player::IsActionButtonDataValid: Action {action} not added into button {button} for player {GetName()} ({GetGUID()}): action must be < {PlayerConst.MaxActionButtonActionValue}"); return false; } switch ((ActionButtonType)type) { case ActionButtonType.Spell: - if (!Global.SpellMgr.HasSpellInfo(action, Difficulty.None)) + if (!Global.SpellMgr.HasSpellInfo((uint)action, Difficulty.None)) { - Log.outError(LogFilter.Player, "Spell action {0} not added into button {1} for player {2} (GUID: {3}): spell not exist", action, button, GetName(), GetGUID()); + Log.outError(LogFilter.Player, $"Player::IsActionButtonDataValid: Spell action {action} not added into button {button} for player {GetName()} ({GetGUID()}): spell not exist"); return false; } - if (!HasSpell(action)) + if (!HasSpell((uint)action)) { - Log.outError(LogFilter.Player, "Spell action {0} not added into button {1} for player {2} (GUID: {3}): player don't known this spell", action, button, GetName(), GetGUID()); + Log.outError(LogFilter.Player, $"Player::IsActionButtonDataValid: Spell action {action} not added into button {button} for player {GetName()} ({GetGUID()}): player don't known this spell"); return false; } break; case ActionButtonType.Item: - if (Global.ObjectMgr.GetItemTemplate(action) == null) + if (Global.ObjectMgr.GetItemTemplate((uint)action) == null) { - Log.outError(LogFilter.Player, "Item action {0} not added into button {1} for player {2} (GUID: {3}): item not exist", action, button, GetName(), GetGUID()); + Log.outError(LogFilter.Player, $"Player::IsActionButtonDataValid: Item action {action} not added into button {button} for player {GetName()} ({GetGUID()}): item not exist"); return false; } break; @@ -1376,13 +1376,13 @@ namespace Game.Entities var mount = CliDB.MountStorage.LookupByKey(action); if (mount == null) { - Log.outError(LogFilter.Player, "Mount action {0} not added into button {1} for player {2} ({3}): mount does not exist", action, button, GetName(), GetGUID().ToString()); + Log.outError(LogFilter.Player, $"Player::IsActionButtonDataValid: Mount action {action} not added into button {button} for player {GetName()} ({GetGUID()}): mount does not exist"); return false; } if (!HasSpell(mount.SourceSpellID)) { - Log.outError(LogFilter.Player, "Mount action {0} not added into button {1} for player {2} ({3}): Player does not know this mount", action, button, GetName(), GetGUID().ToString()); + Log.outError(LogFilter.Player, $"Player::IsActionButtonDataValid: Mount action {action} not added into button {button} for player {GetName()} ({GetGUID()}): Player does not know this mount"); return false; } break; @@ -1392,14 +1392,16 @@ namespace Game.Entities case ActionButtonType.Eqset: break; default: - Log.outError(LogFilter.Player, "Unknown action type {0}", type); + Log.outError(LogFilter.Player, $"Unknown action type {type}"); return false; // other cases not checked at this moment } return true; } + public void SetMultiActionBars(byte mask) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.MultiActionBars), mask); } - public ActionButton AddActionButton(byte button, uint action, uint type) + + public ActionButton AddActionButton(byte button, ulong action, uint type) { if (!IsActionButtonDataValid(button, action, type)) return null; @@ -1413,7 +1415,7 @@ namespace Game.Entities // set data and update to CHANGED if not NEW ab.SetActionAndType(action, (ActionButtonType)type); - Log.outDebug(LogFilter.Player, "Player '{0}' Added Action '{1}' (type {2}) to Button '{3}'", GetGUID().ToString(), action, type, button); + Log.outDebug(LogFilter.Player, $"Player::AddActionButton: Player '{GetName()}' ({GetGUID()}) added action '{action}' (type {type}) to button '{button}'"); return ab; } public void RemoveActionButton(byte _button) diff --git a/Source/Game/Handlers/MiscHandler.cs b/Source/Game/Handlers/MiscHandler.cs index f407eb101..05c597db4 100644 --- a/Source/Game/Handlers/MiscHandler.cs +++ b/Source/Game/Handlers/MiscHandler.cs @@ -113,7 +113,7 @@ namespace Game [WorldPacketHandler(ClientOpcodes.SetActionButton)] void HandleSetActionButton(SetActionButton packet) { - uint action = packet.GetButtonAction(); + ulong action = packet.GetButtonAction(); uint type = packet.GetButtonType(); if (packet.Action == 0) diff --git a/Source/Game/Networking/Packets/SpellPackets.cs b/Source/Game/Networking/Packets/SpellPackets.cs index 16033bdfa..f0399932d 100644 --- a/Source/Game/Networking/Packets/SpellPackets.cs +++ b/Source/Game/Networking/Packets/SpellPackets.cs @@ -160,10 +160,10 @@ namespace Game.Networking.Packets Index = _worldPacket.ReadUInt8(); } - public uint GetButtonAction() { return (uint)(Action & 0x00000000FFFFFFFF); } - public uint GetButtonType() { return (uint)((Action & 0xFFFFFFFF00000000) >> 56); } + public uint GetButtonAction() { return (uint)(Action & 0x00FFFFFFFFFFFFFF); } + public uint GetButtonType() { return (uint)((Action & 0xFF00000000000000) >> 56); } - public ulong Action; // two packed public uint (action and type) + public ulong Action; // two packed values (action and type) public byte Index; } diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index 83d06ed71..fb29b60dc 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -4909,7 +4909,7 @@ namespace Game.Spells //! Action button data is unverified when it's set so it can be "hacked" //! to contain invalid spells, so filter here. - uint spell_id = ab.GetAction(); + uint spell_id = (uint)ab.GetAction(); if (spell_id == 0) continue; diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 822e9bcb0..743da3345 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -459,7 +459,7 @@ CREATE TABLE `character_action` ( `guid` bigint unsigned NOT NULL DEFAULT '0', `spec` tinyint unsigned NOT NULL DEFAULT '0', `button` tinyint unsigned NOT NULL DEFAULT '0', - `action` int unsigned NOT NULL DEFAULT '0', + `action` bigint unsigned NOT NULL DEFAULT '0', `type` tinyint unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`guid`,`spec`,`button`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -3676,7 +3676,8 @@ INSERT INTO `updates` VALUES ('2022_07_14_00_characters.sql','2EAD57D77FC39F6678F2D2A7D9C24046E6B836D8','ARCHIVED','2022-07-14 21:44:35',0), ('2022_07_25_00_characters.sql','3159BB2F3C346A7881920AB2B1F8108247CF13EE','ARCHIVED','2022-07-25 18:44:10',0), ('2022_08_19_00_characters.sql','1C076A24F2B48F32E8EF835C01F8907CA9E86491','ARCHIVED','2022-08-19 23:43:01',0), -('2022_08_21_00_characters.sql','1D75688392FBDA18CD8494F32CF682DCB49642EC','ARCHIVED','2022-08-21 00:02:03',0); +('2022_08_21_00_characters.sql','1D75688392FBDA18CD8494F32CF682DCB49642EC','ARCHIVED','2022-08-21 00:02:03',0), +('2022_09_18_00_characters.sql','A7DF0C1F0E074F3E63A6CDD0AF873A1F3DC33B29','RELEASED','2022-09-18 21:48:42',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/characters/master/2022_09_18_00_characters.sql b/sql/updates/characters/master/2022_09_18_00_characters.sql new file mode 100644 index 000000000..c87d83fa1 --- /dev/null +++ b/sql/updates/characters/master/2022_09_18_00_characters.sql @@ -0,0 +1 @@ +ALTER TABLE `character_action` MODIFY `action` bigint unsigned NOT NULL DEFAULT 0;