fix(sort): refuse to sort inventory when read is inconsistent with server
Post-sort holes were caused by the planning phase, not the execution phase. When GetContainerItemInfo/Link transiently returns nil for an occupied slot during server lag, CreateBagFromID marks it <EMPTY>, the sort algorithm moves real items into that "destination", and we end up with literal gaps where the misclassified items used to be. Validate the read against GetContainerNumFreeSlots before sorting; if counts disagree, print a chat warning and abort instead of corrupting the layout. User retries after a moment.
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user