From 06db5f15faa74252ef9f543537bc7c66682b0fb3 Mon Sep 17 00:00:00 2001 From: Salikh Gurgenidze Date: Sat, 24 Jan 2026 12:18:20 +0400 Subject: [PATCH] fix: Duplicate BAG_UPDATE handlers --- Sorting/SortEngine.lua | 40 +++++++++++++++++++++++++++------------- UI/BankFrame.lua | 8 +++----- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/Sorting/SortEngine.lua b/Sorting/SortEngine.lua index 80d0702..63a418f 100644 --- a/Sorting/SortEngine.lua +++ b/Sorting/SortEngine.lua @@ -12,8 +12,9 @@ SortEngine.sortingInProgress = false -- Performance: Max items to move per cycle -- Baganator uses 5 for manual transfers, but sorting needs more for smooth operation local MAX_MOVES_PER_CYCLE = 20 --- Bank uses fewer moves per cycle to avoid lock conflicts (bank ops are slower) -local MAX_BANK_MOVES_PER_CYCLE = 15 +-- Bank needs more moves per cycle due to larger capacity (240 vs 160 slots) +-- But not too many to avoid server-side lock conflicts +local MAX_BANK_MOVES_PER_CYCLE = 25 -- Current sort context (set by ExecuteSort, used by ApplySort) local currentSortType = "bags" @@ -1117,22 +1118,35 @@ local function ApplySort(bagIDs, items, targetPositions) end -- Execute swaps with occupied slots (if we haven't hit the limit) + -- Be conservative with swaps - they can cause chain reactions + -- Limit swaps to half of max moves to leave room for next pass corrections + local maxSwaps = math.floor(maxMoves / 2) + local swapCount = 0 + for _, move in ipairs(swapOccupied) do - -- Limit moves per cycle - if moveCount >= maxMoves then + -- Limit total moves and swaps separately + if moveCount >= maxMoves or swapCount >= maxSwaps then break end - local _, _, sourceLocked = GetContainerItemInfo(move.sourceBag, move.sourceSlot) - local _, _, targetLocked = GetContainerItemInfo(move.targetBag, move.targetSlot) - - if not sourceLocked and not targetLocked then - PickupContainerItem(move.sourceBag, move.sourceSlot) - PickupContainerItem(move.targetBag, move.targetSlot) - ClearCursor() - moveCount = moveCount + 1 + -- Verify source item is still there (previous swaps may have moved it) + local sourceLink = GetContainerItemLink(move.sourceBag, move.sourceSlot) + if not sourceLink then + -- Source slot is now empty, skip this swap (will be handled next pass) + addon:DebugSort("Swap skipped: source slot now empty (%d:%d)", move.sourceBag, move.sourceSlot) else - lockedCount = lockedCount + 1 + local _, _, sourceLocked = GetContainerItemInfo(move.sourceBag, move.sourceSlot) + local _, _, targetLocked = GetContainerItemInfo(move.targetBag, move.targetSlot) + + if not sourceLocked and not targetLocked then + PickupContainerItem(move.sourceBag, move.sourceSlot) + PickupContainerItem(move.targetBag, move.targetSlot) + ClearCursor() + moveCount = moveCount + 1 + swapCount = swapCount + 1 + else + lockedCount = lockedCount + 1 + end end end diff --git a/UI/BankFrame.lua b/UI/BankFrame.lua index e43f4b0..cb206ad 100644 --- a/UI/BankFrame.lua +++ b/UI/BankFrame.lua @@ -1714,11 +1714,9 @@ function BankFrame:Initialize() end end - addon.Modules.Events:OnBagUpdate(function() - if addon.Modules.BankScanner:IsBankOpen() and not currentViewChar then - ScheduleBankFrameUpdate(0.1) - end - end, "BankFrameUI") + -- NOTE: BAG_UPDATE for bank bags (5-10) is handled by the updateFrame below + -- which provides incremental update logic. We don't need a separate OnBagUpdate + -- handler here as it would cause duplicate processing. -- Update when items get locked/unlocked (debounced for trading, mailing, etc.) addon.Modules.Events:Register("ITEM_LOCK_CHANGED", function()