diff --git a/Bagnon/components/sortBtn.lua b/Bagnon/components/sortBtn.lua index f11c593..4be7592 100644 --- a/Bagnon/components/sortBtn.lua +++ b/Bagnon/components/sortBtn.lua @@ -257,6 +257,23 @@ local function SortBag(bag) end end +-- Returns true iff every slot in `bagID` whose GetContainerItemLink is nil +-- is also reported empty by GetContainerNumFreeSlots. When the server is +-- laggy GetContainerItemInfo/Link can transiently return nil for slots that +-- actually contain items; sorting on that snapshot generates moves that +-- treat occupied slots as empty destinations, leaving holes in the result. +local function IsBagReadConsistent(bagID) + local slots = GetContainerNumSlots(bagID) or 0 + local reportedFree = select(1, GetContainerNumFreeSlots(bagID)) or 0 + local actualEmpty = 0 + for s = 1, slots do + if not GetContainerItemLink(bagID, s) then + actualEmpty = actualEmpty + 1 + end + end + return actualEmpty == reportedFree, actualEmpty, reportedFree +end + local function CreateBagFromID(bagID) local items = GetContainerNumSlots(bagID); local bag = {}; @@ -349,6 +366,18 @@ function SortBtn:OnClick() local bags = {}; if self.frameID == "inventory" then + -- Refuse to sort if any bag's read is inconsistent with the server's + -- reported free-slot count — sorting on that snapshot is what causes + -- the post-sort holes on a laggy server. + for i = 0, NUM_BAG_FRAMES, 1 do + local ok, empty, reported = IsBagReadConsistent(i) + if not ok then + DEFAULT_CHAT_FRAME:AddMessage(format( + "|cFFFFAA00Bagnon: bag %d not fully loaded (read %d empty, server says %d) — try sort again in a moment.|r", + i, empty, reported)) + return + end + end isGuildBankSort = false; for i = 0, NUM_BAG_FRAMES, 1 do local bag = CreateBagFromID(i);