|
|
|
|
-- ------------------------------------------------------------------------------ --
|
|
|
|
|
-- TradeSkillMaster_Mailing --
|
|
|
|
|
-- http://www.curse.com/addons/wow/tradeskillmaster_mailing --
|
|
|
|
|
-- --
|
|
|
|
|
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
|
|
|
|
-- All Rights Reserved* - Detailed license information included with addon. --
|
|
|
|
|
-- ------------------------------------------------------------------------------ --
|
|
|
|
|
|
|
|
|
|
local TSM = select(2, ...)
|
|
|
|
|
local Inbox = TSM:NewModule("Inbox", "AceEvent-3.0", "AceHook-3.0")
|
|
|
|
|
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_Mailing") -- loads the localization table
|
|
|
|
|
|
|
|
|
|
local private = { recheckTime = 1, allowTimerStart = true, lootIndex = 1, freeSlots = true }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function Inbox:OnEnable()
|
|
|
|
|
Inbox:RegisterEvent("MAIL_SHOW")
|
|
|
|
|
TSMAPI:CreateEventBucket("MAIL_INBOX_UPDATE", private.InboxUpdate, 0.3)
|
|
|
|
|
Inbox:RegisterEvent("MAIL_CLOSED")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Inbox:CreateTab(parent)
|
|
|
|
|
local frame = CreateFrame("Frame", nil, parent)
|
|
|
|
|
frame:Hide()
|
|
|
|
|
frame:SetAllPoints()
|
|
|
|
|
frame:SetScript("OnHide", function() private:StopAutoLooting() end)
|
|
|
|
|
frame:SetScript("OnShow", private.InboxUpdate)
|
|
|
|
|
|
|
|
|
|
local label = TSMAPI.GUI:CreateLabel(frame, "small")
|
|
|
|
|
label:SetPoint("TOPLEFT", 5, -5)
|
|
|
|
|
label:SetPoint("TOPRIGHT", -5, -5)
|
|
|
|
|
label:SetHeight(15)
|
|
|
|
|
label:SetJustifyH("CENTER")
|
|
|
|
|
label:SetJustifyV("CENTER")
|
|
|
|
|
frame.topLabel = label
|
|
|
|
|
|
|
|
|
|
TSMAPI.GUI:CreateHorizontalLine(frame, -25)
|
|
|
|
|
|
|
|
|
|
local stContainer = CreateFrame("Frame", nil, frame)
|
|
|
|
|
stContainer:SetPoint("TOPLEFT", 5, -35)
|
|
|
|
|
stContainer:SetPoint("BOTTOMRIGHT", -5, 55)
|
|
|
|
|
TSMAPI.Design:SetFrameColor(stContainer)
|
|
|
|
|
|
|
|
|
|
local handlers = {
|
|
|
|
|
OnClick = function(_, data)
|
|
|
|
|
if IsShiftKeyDown() and select(6, GetInboxHeaderInfo(data.index)) <= 0 then
|
|
|
|
|
if private:CanLootMailIndex(data.index) then
|
|
|
|
|
private:LootMailItem(data.index)
|
|
|
|
|
else
|
|
|
|
|
TSM:Print(L["Could not loot item from mail because your bags are full."])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if InboxFrame.openMailID ~= data.index then
|
|
|
|
|
InboxFrame.openMailID = data.index
|
|
|
|
|
OpenMailFrame.updateButtonPositions = true
|
|
|
|
|
OpenMail_Update()
|
|
|
|
|
ShowUIPanel(OpenMailFrame)
|
|
|
|
|
OpenMailFrame:SetPoint("TOPLEFT", InboxFrame, "TOPRIGHT", 32, 0)
|
|
|
|
|
PlaySound("igSpellBookOpen")
|
|
|
|
|
else
|
|
|
|
|
InboxFrame.openMailID = 0
|
|
|
|
|
HideUIPanel(OpenMailFrame)
|
|
|
|
|
end
|
|
|
|
|
InboxFrame_Update()
|
|
|
|
|
end,
|
|
|
|
|
OnEnter = function(_, data, self)
|
|
|
|
|
end,
|
|
|
|
|
OnLeave = function()
|
|
|
|
|
end,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
local st = TSMAPI:CreateScrollingTable(stContainer, nil, handlers)
|
|
|
|
|
st:SetData({})
|
|
|
|
|
frame.st = st
|
|
|
|
|
|
|
|
|
|
local btn = TSMAPI.GUI:CreateButton(frame, 18, "TSMMailingOpenAllButton")
|
|
|
|
|
btn:SetPoint("BOTTOMLEFT", 5, 30)
|
|
|
|
|
btn:SetPoint("BOTTOMRIGHT", -5, 30)
|
|
|
|
|
btn:SetHeight(20)
|
|
|
|
|
btn:SetText(L["Open All Mail"])
|
|
|
|
|
btn:SetScript("OnClick", function() private:StartAutoLooting("all") end)
|
|
|
|
|
frame.allBtn = btn
|
|
|
|
|
|
|
|
|
|
local label = TSMAPI.GUI:CreateLabel(frame, "normal")
|
|
|
|
|
label:SetPoint("BOTTOMLEFT", 5, 5)
|
|
|
|
|
label:SetHeight(20)
|
|
|
|
|
label:SetJustifyH("LEFT")
|
|
|
|
|
label:SetJustifyV("CENTER")
|
|
|
|
|
label:SetText(L["AH Mail:"])
|
|
|
|
|
|
|
|
|
|
local btnWidth = (frame:GetWidth() - label:GetWidth() - 25) / 5
|
|
|
|
|
|
|
|
|
|
local btn = TSMAPI.GUI:CreateButton(frame, 18, "TSMMailingSalesButton")
|
|
|
|
|
btn:SetPoint("BOTTOMLEFT", label, "BOTTOMRIGHT", 5, 0)
|
|
|
|
|
btn:SetWidth(btnWidth)
|
|
|
|
|
btn:SetHeight(20)
|
|
|
|
|
btn:SetText(L["Sales"])
|
|
|
|
|
btn:SetScript("OnClick", function() private:StartAutoLooting("sales") end)
|
|
|
|
|
frame.salesBtn = btn
|
|
|
|
|
|
|
|
|
|
local btn = TSMAPI.GUI:CreateButton(frame, 18, "TSMMailingBuysButton")
|
|
|
|
|
btn:SetPoint("BOTTOMLEFT", frame.salesBtn, "BOTTOMRIGHT", 5, 0)
|
|
|
|
|
btn:SetWidth(btnWidth)
|
|
|
|
|
btn:SetHeight(20)
|
|
|
|
|
btn:SetText(L["Buys"])
|
|
|
|
|
btn:SetScript("OnClick", function() private:StartAutoLooting("buys") end)
|
|
|
|
|
frame.buysBtn = btn
|
|
|
|
|
|
|
|
|
|
local btn = TSMAPI.GUI:CreateButton(frame, 18, "TSMMailingCancelsButton")
|
|
|
|
|
btn:SetPoint("BOTTOMLEFT", frame.buysBtn, "BOTTOMRIGHT", 5, 0)
|
|
|
|
|
btn:SetWidth(btnWidth)
|
|
|
|
|
btn:SetHeight(20)
|
|
|
|
|
btn:SetText(L["Cancels"])
|
|
|
|
|
btn:SetScript("OnClick", function() private:StartAutoLooting("cancels") end)
|
|
|
|
|
frame.cancelsBtn = btn
|
|
|
|
|
|
|
|
|
|
local btn = TSMAPI.GUI:CreateButton(frame, 18, "TSMMailingExpiresButton")
|
|
|
|
|
btn:SetPoint("BOTTOMLEFT", frame.cancelsBtn, "BOTTOMRIGHT", 5, 0)
|
|
|
|
|
btn:SetWidth(btnWidth)
|
|
|
|
|
btn:SetHeight(20)
|
|
|
|
|
btn:SetText(L["Expires"])
|
|
|
|
|
btn:SetScript("OnClick", function() private:StartAutoLooting("expires") end)
|
|
|
|
|
frame.expiresBtn = btn
|
|
|
|
|
|
|
|
|
|
local btn = TSMAPI.GUI:CreateButton(frame, 18)
|
|
|
|
|
btn:SetPoint("BOTTOMLEFT", frame.expiresBtn, "BOTTOMRIGHT", 5, 0)
|
|
|
|
|
btn:SetPoint("BOTTOMRIGHT", -5, 5)
|
|
|
|
|
btn:SetHeight(20)
|
|
|
|
|
btn:SetText("Pending")
|
|
|
|
|
btn:SetScript("OnClick", function() private:StartAutoLooting("pendings") end)
|
|
|
|
|
frame.expiresBtn = btn
|
|
|
|
|
|
|
|
|
|
local btn = TSMAPI.GUI:CreateButton(frame, 16)
|
|
|
|
|
btn:SetFrameStrata("HIGH")
|
|
|
|
|
btn:SetPoint("CENTER")
|
|
|
|
|
btn:SetHeight(30)
|
|
|
|
|
btn:SetWidth(150)
|
|
|
|
|
btn:SetText(L["Reload UI"])
|
|
|
|
|
btn:SetScript("OnClick", ReloadUI)
|
|
|
|
|
btn:Hide()
|
|
|
|
|
frame.reloadBtn = btn
|
|
|
|
|
|
|
|
|
|
frame.EnableButtons = function(self)
|
|
|
|
|
self.allBtn:Enable()
|
|
|
|
|
self.salesBtn:Enable()
|
|
|
|
|
self.buysBtn:Enable()
|
|
|
|
|
self.cancelsBtn:Enable()
|
|
|
|
|
self.expiresBtn:Enable()
|
|
|
|
|
self.buttonsEnabled = true
|
|
|
|
|
end
|
|
|
|
|
frame.DisableButtons = function(self)
|
|
|
|
|
self.allBtn:Disable()
|
|
|
|
|
self.salesBtn:Disable()
|
|
|
|
|
self.buysBtn:Disable()
|
|
|
|
|
self.cancelsBtn:Disable()
|
|
|
|
|
self.expiresBtn:Disable()
|
|
|
|
|
self.buttonsEnabled = nil
|
|
|
|
|
end
|
|
|
|
|
frame.buttonsEnabled = true
|
|
|
|
|
|
|
|
|
|
private.frame = frame
|
|
|
|
|
return frame
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function CacheFrameOnUpdate(self, elapsed)
|
|
|
|
|
if not private.waitingForData then
|
|
|
|
|
local seconds = self.endTime - GetTime()
|
|
|
|
|
if seconds <= 0 then
|
|
|
|
|
-- Look for new mail
|
|
|
|
|
-- Sometimes it fails and isn't available at exactly 60-61 seconds, and more like 62-64, will keep rechecking every 1 second
|
|
|
|
|
-- until data becomes available
|
|
|
|
|
if TSM.db.global.autoCheck then
|
|
|
|
|
private.waitingForData = true
|
|
|
|
|
self.timeLeft = private.recheckTime
|
|
|
|
|
private.lootIndex = 1
|
|
|
|
|
private.resetIndex = nil
|
|
|
|
|
CheckInbox()
|
|
|
|
|
private.frame.reloadBtn:Hide()
|
|
|
|
|
else
|
|
|
|
|
self:Hide()
|
|
|
|
|
end
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private:UpdateTopLabel()
|
|
|
|
|
else
|
|
|
|
|
self.timeLeft = self.timeLeft - elapsed
|
|
|
|
|
if self.timeLeft <= 0 then
|
|
|
|
|
self.timeLeft = private.recheckTime
|
|
|
|
|
private.lootIndex = 1
|
|
|
|
|
private.resetIndex = nil
|
|
|
|
|
CheckInbox()
|
|
|
|
|
private.frame.reloadBtn:Hide()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Inbox:MAIL_SHOW()
|
|
|
|
|
if not private.cacheFrame then
|
|
|
|
|
-- Timer for mailbox cache updates
|
|
|
|
|
private.cacheFrame = CreateFrame("Frame", nil, MailFrame)
|
|
|
|
|
private.cacheFrame:Hide()
|
|
|
|
|
private.cacheFrame:SetScript("OnUpdate", CacheFrameOnUpdate)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function FormatDaysLeft(daysLeft, index)
|
|
|
|
|
-- code taken from Blizzard MailFrame.lua code
|
|
|
|
|
if daysLeft >= 1 then
|
|
|
|
|
if InboxItemCanDelete(index) then
|
|
|
|
|
daysLeft = YELLOW_FONT_COLOR_CODE .. format(DAYS_ABBR, floor(daysLeft)) .. " " .. FONT_COLOR_CODE_CLOSE;
|
|
|
|
|
else
|
|
|
|
|
daysLeft = GREEN_FONT_COLOR_CODE .. format(DAYS_ABBR, floor(daysLeft)) .. " " .. FONT_COLOR_CODE_CLOSE;
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
daysLeft = RED_FONT_COLOR_CODE .. SecondsToTime(floor(daysLeft * 24 * 60 * 60)) .. FONT_COLOR_CODE_CLOSE;
|
|
|
|
|
end
|
|
|
|
|
return daysLeft
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function private:UpdateTopLabel()
|
|
|
|
|
local parts = {}
|
|
|
|
|
|
|
|
|
|
local numMail, totalMail = GetInboxNumItems()
|
|
|
|
|
if totalMail == numMail then
|
|
|
|
|
tinsert(parts, format(L["Showing all %d mail."], numMail))
|
|
|
|
|
else
|
|
|
|
|
tinsert(parts, format(L["Showing %d of %d mail."], numMail, totalMail))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local collectGold = private.collectGold or 0
|
|
|
|
|
if collectGold > 0 then
|
|
|
|
|
tinsert(parts, format(L["%s to collect."], TSMAPI:FormatTextMoney(collectGold)))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local nextRefresh = private.cacheFrame:IsVisible() and private.cacheFrame.endTime
|
|
|
|
|
if nextRefresh then
|
|
|
|
|
if numMail == 0 and TSM.db.global.showReloadBtn then
|
|
|
|
|
private.frame.reloadBtn:Show()
|
|
|
|
|
end
|
|
|
|
|
tinsert(parts, format(L["Next inbox update in %d seconds."], max(ceil(nextRefresh - GetTime()), 0)))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private.frame.topLabel:SetText(table.concat(parts, " "))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function private:InboxUpdate()
|
|
|
|
|
if not private.frame or not private.frame:IsVisible() then return end
|
|
|
|
|
TSMAPI:CancelFrame("inboxLootTextDelay")
|
|
|
|
|
|
|
|
|
|
local numMail, totalMail = GetInboxNumItems()
|
|
|
|
|
|
|
|
|
|
local greenColor, redColor, yellowColor = "|cff00ff00", "|cffff0000", "|cffeeff00"
|
|
|
|
|
local mailInfo = {}
|
|
|
|
|
local collectGold = 0
|
|
|
|
|
for i = 1, numMail do
|
|
|
|
|
mailInfo[i] = ""
|
|
|
|
|
local isInvoice = select(4, GetInboxText(i))
|
|
|
|
|
--local _, _, sender, subject, money, cod, _, hasItem = GetInboxHeaderInfo(index)
|
|
|
|
|
local _, _, sender, subject, money, cod, daysLeft, hasItem, _, _, _, _, _, itemQuantity = GetInboxHeaderInfo(i)
|
|
|
|
|
if isInvoice then
|
|
|
|
|
local invoiceType, itemName, playerName, bid, buyout, deposit, ahcut, _, _, _, quantity = GetInboxInvoiceInfo(i)
|
|
|
|
|
|
|
|
|
|
sender = sender or "?"
|
|
|
|
|
if sender == "Blackwater Auction House" then sender = "AH" end
|
|
|
|
|
if not quantity then
|
|
|
|
|
quantity = select(3, GetInboxItem(i))
|
|
|
|
|
end
|
|
|
|
|
-- fix MoP difference
|
|
|
|
|
if invoiceType == "buyer" then
|
|
|
|
|
local itemLink = GetInboxItemLink(i, 1) or itemName
|
|
|
|
|
mailInfo[i] = format(L["Buy: %s (%d) | %s | %s"], itemLink, quantity or 1, TSMAPI:FormatTextMoney(bid, redColor), FormatDaysLeft(daysLeft, i))
|
|
|
|
|
elseif invoiceType == "seller" then
|
|
|
|
|
collectGold = collectGold + bid - ahcut
|
|
|
|
|
mailInfo[i] = format(L["Sale: %s (%d) | %s | %s"], itemName, quantity or 1, TSMAPI:FormatTextMoney(bid - ahcut, greenColor), FormatDaysLeft(daysLeft, i))
|
|
|
|
|
-- mailInfo[i] = format("Sale: %s | %s | %s", itemName, TSMAPI:FormatTextMoney(bid - ahcut, greenColor), FormatDaysLeft(daysLeft, i))
|
|
|
|
|
elseif invoiceType == "seller_temp_invoice" then
|
|
|
|
|
mailInfo[i] = format("Pending Sale: %s (%d) | %s | %s", itemName, quantity or 1, TSMAPI:FormatTextMoney(bid - ahcut, yellowColor), FormatDaysLeft(daysLeft, i))
|
|
|
|
|
-- mailInfo[i] = format("Pending Sale: %s | %s | %s", itemName, TSMAPI:FormatTextMoney(bid - ahcut, yellowColor), FormatDaysLeft(daysLeft, i))
|
|
|
|
|
end
|
|
|
|
|
elseif hasItem then
|
|
|
|
|
local itemLink
|
|
|
|
|
local quantity = 0
|
|
|
|
|
for j = 1, hasItem do
|
|
|
|
|
local link = GetInboxItemLink(i, j)
|
|
|
|
|
itemLink = itemLink or link
|
|
|
|
|
quantity = quantity + select(3, GetInboxItem(i, j))
|
|
|
|
|
if TSMAPI:GetItemString(itemLink) ~= TSMAPI:GetItemString(link) then
|
|
|
|
|
itemLink = L["Multiple Items"]
|
|
|
|
|
quantity = -1
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
local itemDesc = (quantity > 0 and format("%s (%d)", itemLink, quantity)) or (quantity == -1 and L["Multiple Items"]) or "---"
|
|
|
|
|
|
|
|
|
|
if hasItem == 1 and itemLink and strfind(subject, "^" .. TSMAPI:StrEscape(format(AUCTION_EXPIRED_MAIL_SUBJECT, TSMAPI:GetSafeItemInfo(itemLink)))) then
|
|
|
|
|
mailInfo[i] = format(L["Expired: %s | %s"], itemDesc, FormatDaysLeft(daysLeft, i))
|
|
|
|
|
elseif cod > 0 then
|
|
|
|
|
mailInfo[i] = format(L["COD: %s | %s | %s | %s"], itemDesc, TSMAPI:FormatTextMoney(cod, redColor), sender or "---", FormatDaysLeft(daysLeft, i))
|
|
|
|
|
elseif money > 0 then
|
|
|
|
|
collectGold = collectGold + money
|
|
|
|
|
mailInfo[i] = format("%s + %s | %s | %s", itemDesc, TSMAPI:FormatTextMoney(money, greenColor), sender or "---", FormatDaysLeft(daysLeft, i))
|
|
|
|
|
else
|
|
|
|
|
mailInfo[i] = format("%s | %s | %s", itemDesc, sender or "---", FormatDaysLeft(daysLeft, i))
|
|
|
|
|
end
|
|
|
|
|
elseif money > 0 then
|
|
|
|
|
mailInfo[i] = format("%s | %s | %s | %s", subject, TSMAPI:FormatTextMoney(money, greenColor), sender or "---", FormatDaysLeft(daysLeft, i))
|
|
|
|
|
else
|
|
|
|
|
mailInfo[i] = format("%s | %s | %s", subject, sender or "---", FormatDaysLeft(daysLeft, i))
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
private.collectGold = collectGold
|
|
|
|
|
|
|
|
|
|
local stData = {}
|
|
|
|
|
for i, info in ipairs(mailInfo) do
|
|
|
|
|
tinsert(stData, { cols = { { value = info } }, index = i })
|
|
|
|
|
end
|
|
|
|
|
private.frame.st:SetData(stData)
|
|
|
|
|
|
|
|
|
|
private:UpdateTopLabel()
|
|
|
|
|
|
|
|
|
|
-- -- Yay nothing else to loot, so nothing else to update the cache for!
|
|
|
|
|
-- if private.cacheFrame.endTime and numMail == totalMail and private.lastTotal ~= totalMail then
|
|
|
|
|
-- private.cacheFrame.endTime = nil
|
|
|
|
|
-- private.cacheFrame:Hide()
|
|
|
|
|
-- -- Start a timer since we're over the limit of 50 items before waiting for it to recache
|
|
|
|
|
-- elseif (private.cacheFrame.endTime and numMail >= 50 and private.lastTotal ~= totalMail) or (numMail >= 50 and private.allowTimerStart) then
|
|
|
|
|
-- private.resetIndex = nil
|
|
|
|
|
-- private.allowTimerStart = nil
|
|
|
|
|
-- private.waitingForData = nil
|
|
|
|
|
-- private.lastTotal = totalMail
|
|
|
|
|
-- private.cacheFrame.endTime = GetTime() + 60
|
|
|
|
|
-- private.cacheFrame:Show()
|
|
|
|
|
-- end
|
|
|
|
|
|
|
|
|
|
-- The last item we setup to auto loot is finished, time for the next one
|
|
|
|
|
if not private.frame.buttonsEnabled then
|
|
|
|
|
-- if private.autoLootTotal ~= numMail then
|
|
|
|
|
-- private.autoLootTotal = GetInboxNumItems()
|
|
|
|
|
|
|
|
|
|
-- If we're auto checking mail when new data is available, will wait and continue auto looting, otherwise we just stop now
|
|
|
|
|
if totalMail == 0 then
|
|
|
|
|
private:StopAutoLooting()
|
|
|
|
|
else
|
|
|
|
|
private:AutoLoot()
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
TSMAPI:CreateTimeDelay("mailSkipDelay", 1, function()
|
|
|
|
|
local money, _, _, hasItem, _, _, _, canReply = select(5, GetInboxHeaderInfo(private.lootIndex))
|
|
|
|
|
if not hasItem and money == 0 then
|
|
|
|
|
private.lootIndex = private.lootIndex + 1
|
|
|
|
|
return private:AutoLoot()
|
|
|
|
|
end
|
|
|
|
|
end)
|
|
|
|
|
-- end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function private:ShouldOpenMail(index)
|
|
|
|
|
local shouldOpen
|
|
|
|
|
if private.mode == "all" then
|
|
|
|
|
return true
|
|
|
|
|
elseif private.mode == "sales" then
|
|
|
|
|
local money = select(5, GetInboxHeaderInfo(index))
|
|
|
|
|
if money > 0 and GetInboxInvoiceInfo(index) == "seller" then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
elseif private.mode == "buys" then
|
|
|
|
|
local hasItem = select(8, GetInboxHeaderInfo(index))
|
|
|
|
|
if hasItem and GetInboxInvoiceInfo(index) == "buyer" then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
elseif private.mode == "cancels" then
|
|
|
|
|
local isInvoice = select(4, GetInboxText(index))
|
|
|
|
|
local subject, _, _, _, hasItem = select(4, GetInboxHeaderInfo(index))
|
|
|
|
|
if not isInvoice and hasItem == 1 then
|
|
|
|
|
local itemLink = GetInboxItemLink(index, 1)
|
|
|
|
|
if itemLink then
|
|
|
|
|
local itemName = TSMAPI:GetSafeItemInfo(itemLink)
|
|
|
|
|
local quantity = select(3, GetInboxItem(index, 1))
|
|
|
|
|
if quantity and quantity > 0 and (subject == format(AUCTION_REMOVED_MAIL_SUBJECT.." (%d)", itemName, quantity) or subject == format(AUCTION_REMOVED_MAIL_SUBJECT, itemName)) then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
elseif private.mode == "pendings" then
|
|
|
|
|
local isInvoice = select(4, GetInboxText(index))
|
|
|
|
|
if isInvoice then
|
|
|
|
|
invoiceType = GetInboxInvoiceInfo(index)
|
|
|
|
|
if invoiceType == "seller_temp_invoice" then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
elseif private.mode == "expires" then
|
|
|
|
|
local isInvoice = select(4, GetInboxText(index))
|
|
|
|
|
local subject, _, _, _, hasItem = select(4, GetInboxHeaderInfo(index))
|
|
|
|
|
if not isInvoice and hasItem == 1 then
|
|
|
|
|
local itemLink = GetInboxItemLink(index, 1)
|
|
|
|
|
if itemLink and strfind(subject, "^" .. TSMAPI:StrEscape(format(AUCTION_EXPIRED_MAIL_SUBJECT, TSMAPI:GetSafeItemInfo(itemLink)))) then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Deals with auto looting of mail!
|
|
|
|
|
function private:StartAutoLooting(mode)
|
|
|
|
|
private.mode = mode
|
|
|
|
|
local canCollectMail
|
|
|
|
|
if private.mode == "all" then
|
|
|
|
|
local total
|
|
|
|
|
private.autoLootTotal, total = GetInboxNumItems()
|
|
|
|
|
canCollectMail = not (private.autoLootTotal == 0 and total == 0)
|
|
|
|
|
else
|
|
|
|
|
for i = 1, GetInboxNumItems() do
|
|
|
|
|
if private:ShouldOpenMail(i) then
|
|
|
|
|
canCollectMail = true
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
if not canCollectMail then
|
|
|
|
|
private.mode = nil
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
Inbox:RegisterEvent("UI_ERROR_MESSAGE")
|
|
|
|
|
private.frame:DisableButtons()
|
|
|
|
|
private.moneyCollected = 0
|
|
|
|
|
private.mode = mode
|
|
|
|
|
private.lootIndex = 1
|
|
|
|
|
private:AutoLoot()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function CanLootItem(itemString, quantity)
|
|
|
|
|
if not itemString or not quantity then return false end
|
|
|
|
|
local maxStack = select(8, TSMAPI:GetSafeItemInfo(itemString))
|
|
|
|
|
local hasPartial = false
|
|
|
|
|
local hasEmpty = false
|
|
|
|
|
local totalFreeSlots = 0
|
|
|
|
|
|
|
|
|
|
for bag = 0, NUM_BAG_SLOTS do
|
|
|
|
|
if TSMAPI:ItemWillGoInBag(itemString, bag) then
|
|
|
|
|
totalFreeSlots = totalFreeSlots + (GetContainerNumFreeSlots(bag) or 0)
|
|
|
|
|
for slot = 1, GetContainerNumSlots(bag) do
|
|
|
|
|
local iLink = GetContainerItemLink(bag, slot)
|
|
|
|
|
if iLink then
|
|
|
|
|
if TSMAPI:GetItemString(iLink) == itemString and maxStack then
|
|
|
|
|
local stackSize = select(2, GetContainerItemInfo(bag, slot))
|
|
|
|
|
if stackSize and (maxStack - stackSize) >= quantity then
|
|
|
|
|
hasPartial = true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
hasEmpty = true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if hasPartial then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
if not hasEmpty then
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
if TSM.db.global.keepMailSpace and TSM.db.global.keepMailSpace > 0 then
|
|
|
|
|
return (totalFreeSlots - 1) >= TSM.db.global.keepMailSpace
|
|
|
|
|
end
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function HasFittableStack(itemString, needed)
|
|
|
|
|
if not itemString or not needed or needed <= 0 then return false end
|
|
|
|
|
for i = 1, GetInboxNumItems() do
|
|
|
|
|
local _, _, _, _, _, cod, _, hasItem = GetInboxHeaderInfo(i)
|
|
|
|
|
if hasItem and hasItem > 0 and (not cod or cod == 0) then
|
|
|
|
|
for j = 1, hasItem do
|
|
|
|
|
local itemLink = GetInboxItemLink(i, j)
|
|
|
|
|
if itemLink and TSMAPI:GetItemString(itemLink) == itemString then
|
|
|
|
|
local quantity = select(3, GetInboxItem(i, j)) or 0
|
|
|
|
|
if quantity > 0 and quantity <= needed then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Inbox:CollectItems(items, callback)
|
|
|
|
|
if not items or not next(items) then return end
|
|
|
|
|
if not MailFrame or not MailFrame:IsShown() then return end
|
|
|
|
|
|
|
|
|
|
local remaining = CopyTable(items)
|
|
|
|
|
local collected = false
|
|
|
|
|
local candidates = {}
|
|
|
|
|
for i = GetInboxNumItems(), 1, -1 do
|
|
|
|
|
local _, _, _, _, _, cod, _, hasItem = GetInboxHeaderInfo(i)
|
|
|
|
|
if hasItem and hasItem > 0 and (not cod or cod == 0) then
|
|
|
|
|
for j = hasItem, 1, -1 do
|
|
|
|
|
local itemLink = GetInboxItemLink(i, j)
|
|
|
|
|
local itemString = itemLink and TSMAPI:GetItemString(itemLink)
|
|
|
|
|
local need = itemString and remaining[itemString]
|
|
|
|
|
if need and need > 0 then
|
|
|
|
|
local quantity = select(3, GetInboxItem(i, j)) or 0
|
|
|
|
|
if quantity > 0 then
|
|
|
|
|
if not candidates[itemString] then
|
|
|
|
|
candidates[itemString] = {}
|
|
|
|
|
end
|
|
|
|
|
tinsert(candidates[itemString], { index = i, itemIndex = j, quantity = quantity })
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
for itemString, entries in pairs(candidates) do
|
|
|
|
|
table.sort(entries, function(a, b)
|
|
|
|
|
if a.quantity ~= b.quantity then
|
|
|
|
|
return a.quantity < b.quantity
|
|
|
|
|
end
|
|
|
|
|
return a.index > b.index
|
|
|
|
|
end)
|
|
|
|
|
for _, entry in ipairs(entries) do
|
|
|
|
|
local need = remaining[itemString]
|
|
|
|
|
if not need or need <= 0 then
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
if entry.quantity > 0 and (entry.quantity <= need or not HasFittableStack(itemString, need)) then
|
|
|
|
|
if CanLootItem(itemString, entry.quantity) then
|
|
|
|
|
TakeInboxItem(entry.index, entry.itemIndex)
|
|
|
|
|
remaining[itemString] = max(need - entry.quantity, 0)
|
|
|
|
|
collected = true
|
|
|
|
|
elseif callback then
|
|
|
|
|
callback(L["Cannot finish auto looting, inventory is full or too many unique items."])
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Keep looting as new mail indexes shift, while preserving 1 free slot.
|
|
|
|
|
if collected then
|
|
|
|
|
TSMAPI:CreateTimeDelay("craftingGatherMailLoop", 0.4, function()
|
|
|
|
|
Inbox:CollectItems(remaining, callback)
|
|
|
|
|
end)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function private:AutoLoot()
|
|
|
|
|
TSMAPI:CancelFrame("mailSkipDelay")
|
|
|
|
|
|
|
|
|
|
-- Already looted everything after the invalid indexes we had, so fail it
|
|
|
|
|
if private.lootIndex > 1 and private.lootIndex > GetInboxNumItems() then
|
|
|
|
|
if private.resetIndex then
|
|
|
|
|
private:StopAutoLooting()
|
|
|
|
|
else
|
|
|
|
|
private.resetIndex = true
|
|
|
|
|
private.lootIndex = 1
|
|
|
|
|
private:AutoLoot()
|
|
|
|
|
end
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local _, _, sender, subject, money, cod, _, items, _, _, _, _, isGM = GetInboxHeaderInfo(private.lootIndex)
|
|
|
|
|
if (sender == "The Postmaster" or sender == "Blackwater Auction House" or sender == "Customer Support") or not isGM and (not cod or cod <= 0) and ((money and money > 0) or (items and items > 0)) or GetInboxInvoiceInfo(private.lootIndex) == "seller_temp_invoice" then
|
|
|
|
|
TSMAPI:CancelFrame("mailWaitDelay")
|
|
|
|
|
if private.mode == "all" then
|
|
|
|
|
if money > 0 then
|
|
|
|
|
if TSM.db.global.openAllLeaveGold then
|
|
|
|
|
private.lootIndex = private.lootIndex + 1
|
|
|
|
|
return private:AutoLoot()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
if private:CanLootMailIndex(private.lootIndex) then
|
|
|
|
|
if money > 0 then
|
|
|
|
|
private.moneyCollected = private.moneyCollected + money
|
|
|
|
|
end
|
|
|
|
|
private:LootMailItem(private.lootIndex)
|
|
|
|
|
else
|
|
|
|
|
private.lootIndex = private.lootIndex + 1
|
|
|
|
|
return private:AutoLoot()
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
if private:CanLootMailIndex(private.lootIndex) and private:ShouldOpenMail(private.lootIndex) then
|
|
|
|
|
if money > 0 then
|
|
|
|
|
private.moneyCollected = private.moneyCollected + money
|
|
|
|
|
end
|
|
|
|
|
private:LootMailItem(private.lootIndex)
|
|
|
|
|
else
|
|
|
|
|
private.lootIndex = private.lootIndex + 1
|
|
|
|
|
return private:AutoLoot()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
-- Can't grab the first mail, so increase it and try again
|
|
|
|
|
elseif GetInboxNumItems() >= private.lootIndex then
|
|
|
|
|
private.lootIndex = private.lootIndex + 1
|
|
|
|
|
private:AutoLoot()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function private:LootMailItem(index)
|
|
|
|
|
if TSM.db.global.inboxMessages then
|
|
|
|
|
--local _, _, sender, subject, money, cod, _, hasItem = GetInboxHeaderInfo(index)
|
|
|
|
|
local _, _, sender, subject, money, cod, daysLeft, hasItem, _, _, _, _, _, itemQuantity = GetInboxHeaderInfo(index)
|
|
|
|
|
sender = sender or "?"
|
|
|
|
|
isTakeable = select(4, GetInboxText(index))
|
|
|
|
|
if isTakeable then
|
|
|
|
|
-- it's an invoice
|
|
|
|
|
local invoiceType, itemName, playerName, bid, _, _, ahcut, _, _, _, quantity = GetInboxInvoiceInfo(index)
|
|
|
|
|
|
|
|
|
|
-- fix MoP difference
|
|
|
|
|
if not quantity then
|
|
|
|
|
quantity = select(3, GetInboxItem(index))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local redColor = "|cffFF0000"
|
|
|
|
|
local greenColor = "|cff00FF00"
|
|
|
|
|
local yellowColor = "|cffFFFF00"
|
|
|
|
|
|
|
|
|
|
if invoiceType == "buyer" then
|
|
|
|
|
local itemLink = GetInboxItemLink(index, 1) or itemName
|
|
|
|
|
TSM:Printf(L["Collected purchase of %s (%d) for %s."], itemLink, quantity or 1, TSMAPI:FormatTextMoney(bid, redColor))
|
|
|
|
|
elseif invoiceType == "seller" then
|
|
|
|
|
TSM:Printf(L["Collected sale of %s (%d) for %s."], itemName, quantity or 1, TSMAPI:FormatTextMoney(bid - ahcut, greenColor))
|
|
|
|
|
-- TSM:Printf("Collected sale of %s for %s.", itemName, TSMAPI:FormatTextMoney(bid - ahcut, greenColor))
|
|
|
|
|
elseif invoiceType == "seller_temp_invoice" then
|
|
|
|
|
-- TSM:Printf("Removing pending sale: %s (%s)", itemName, TSMAPI:FormatTextMoney(bid - ahcut, yellowColor))
|
|
|
|
|
TSM:Printf("Removing pending sale of %s (%d) for %s.", itemName, quantity or 1, TSMAPI:FormatTextMoney(bid - ahcut, yellowColor))
|
|
|
|
|
DeleteInboxItem(index)
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
elseif hasItem then
|
|
|
|
|
local itemLink
|
|
|
|
|
local quantity = 0
|
|
|
|
|
for i = 1, hasItem do
|
|
|
|
|
local link = GetInboxItemLink(index, i)
|
|
|
|
|
itemLink = itemLink or link
|
|
|
|
|
quantity = quantity + select(3, GetInboxItem(index, i))
|
|
|
|
|
if TSMAPI:GetItemString(itemLink) ~= TSMAPI:GetItemString(link) then
|
|
|
|
|
itemLink = L["Multiple Items"]
|
|
|
|
|
quantity = -1
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
local itemDesc = (quantity > 0 and format("%s (%d)", itemLink, quantity)) or (quantity == -1 and "Multiple Items") or "?"
|
|
|
|
|
if hasItem == 1 and itemLink and strfind(subject, "^" .. TSMAPI:StrEscape(format(AUCTION_EXPIRED_MAIL_SUBJECT, TSMAPI:GetSafeItemInfo(itemLink)))) then
|
|
|
|
|
TSM:Printf(L["Collected expired auction of %s"], itemDesc)
|
|
|
|
|
elseif cod > 0 then
|
|
|
|
|
TSM:Printf(L["Collected COD of %s from %s for %s."], itemDesc, sender, TSMAPI:FormatTextMoney(cod, redColor))
|
|
|
|
|
elseif money > 0 then
|
|
|
|
|
TSM:Printf(L["Collected %s and %s from %s."], itemDesc, TSMAPI:FormatTextMoney(money, greenColor), sender)
|
|
|
|
|
else
|
|
|
|
|
TSM:Printf(L["Collected %s from %s."], itemDesc, sender)
|
|
|
|
|
end
|
|
|
|
|
elseif money > 0 then
|
|
|
|
|
TSM:Printf(L["Collected %s from %s."], TSMAPI:FormatTextMoney(money, greenColor), sender)
|
|
|
|
|
elseif (sender == "The Postmaster" or sender == "Blackwater Auction House" or sender == "Customer Support" and subject == "Your Ascension Order" and daysLeft < 270) and money == 0 and hasItem == nil then
|
|
|
|
|
TSM:Printf("Removing empty mail from %s.", sender)
|
|
|
|
|
DeleteInboxItem(index)
|
|
|
|
|
else
|
|
|
|
|
TSM:Printf(L["Collected mail from %s with a subject of '%s'."], sender, subject)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
AutoLootMailItem(index)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function private:CanLootMailIndex(index)
|
|
|
|
|
local hasItem = select(8, GetInboxHeaderInfo(index))
|
|
|
|
|
if not hasItem or hasItem == 0 then return true end
|
|
|
|
|
|
|
|
|
|
if not TSM.db.global.keepMailSpace or TSM.db.global.keepMailSpace == 0 then
|
|
|
|
|
for j = 1, ATTACHMENTS_MAX_RECEIVE do
|
|
|
|
|
local itemString = TSMAPI:GetItemString(GetInboxItemLink(index, j))
|
|
|
|
|
local quantity = select(3, GetInboxItem(index, j))
|
|
|
|
|
local space = 0
|
|
|
|
|
if itemString then
|
|
|
|
|
for bag = 0, NUM_BAG_SLOTS do
|
|
|
|
|
if TSMAPI:ItemWillGoInBag(itemString, bag) then
|
|
|
|
|
for slot = 1, GetContainerNumSlots(bag) do
|
|
|
|
|
local iString = TSMAPI:GetItemString(GetContainerItemLink(bag, slot))
|
|
|
|
|
if iString == itemString then
|
|
|
|
|
local stackSize = select(2, GetContainerItemInfo(bag, slot))
|
|
|
|
|
local maxStackSize = select(8, TSMAPI:GetSafeItemInfo(itemString))
|
|
|
|
|
if (maxStackSize - stackSize) >= quantity then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
elseif not iString then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
-- get number of free slots per generic / special bags and partial slots by bag
|
|
|
|
|
local genericSpace, uniqueSpace, partSlots = private:GetBagSlots()
|
|
|
|
|
local usedSlots = {}
|
|
|
|
|
for j = 1, ATTACHMENTS_MAX_RECEIVE do
|
|
|
|
|
local itemString = TSMAPI:GetItemString(GetInboxItemLink(index, j))
|
|
|
|
|
local quantity = select(3, GetInboxItem(index, j))
|
|
|
|
|
local isDone = false
|
|
|
|
|
if itemString then
|
|
|
|
|
for bag = 0, NUM_BAG_SLOTS do
|
|
|
|
|
if TSMAPI:ItemWillGoInBag(itemString, bag) then
|
|
|
|
|
for slot = 1, GetContainerNumSlots(bag) do
|
|
|
|
|
local iString = TSMAPI:GetItemString(GetContainerItemLink(bag, slot))
|
|
|
|
|
if iString == itemString and (partSlots[bag] and partSlots[bag][slot]) then
|
|
|
|
|
local stackSize = select(2, GetContainerItemInfo(bag, slot))
|
|
|
|
|
local maxStackSize = select(8, TSMAPI:GetSafeItemInfo(itemString))
|
|
|
|
|
if (maxStackSize - stackSize - (usedSlots[bag] and usedSlots[bag][slot] or 0)) >= quantity then
|
|
|
|
|
if stackSize + quantity == maxStackSize then
|
|
|
|
|
if partSlots[bag] and partSlots[bag][slot] then
|
|
|
|
|
partSlots[bag][slot] = nil -- this partial slot would be filled so remove it from available part slots
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
if not usedSlots[bag] then
|
|
|
|
|
usedSlots[bag] = {}
|
|
|
|
|
end
|
|
|
|
|
usedSlots[bag][slot] = (usedSlots[bag][slot] or 0) + stackSize -- store the stacksize for this slot after adding this item
|
|
|
|
|
end
|
|
|
|
|
isDone = true
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
local itemFamily = GetItemFamily(itemString)
|
|
|
|
|
local bagFamily = GetItemFamily(GetBagName(bag)) or 0
|
|
|
|
|
if itemFamily and bagFamily and bagFamily > 0 and bit.band(itemFamily, bagFamily) > 0 and (uniqueSpace[bag] and uniqueSpace[bag] > 0) then
|
|
|
|
|
uniqueSpace[bag] = uniqueSpace[bag] - 1 -- remove one empty slot from the bag
|
|
|
|
|
isDone = true
|
|
|
|
|
break
|
|
|
|
|
else
|
|
|
|
|
if genericSpace[bag] and genericSpace[bag] > 0 then
|
|
|
|
|
genericSpace[bag] = genericSpace[bag] - 1 -- remove one empty slot from the bag
|
|
|
|
|
if genericSpace[bag] <= 0 then
|
|
|
|
|
genericSpace[bag] = nil
|
|
|
|
|
end
|
|
|
|
|
isDone = true
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
if isDone then break end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--calculate the total remaining empty slots in generic bags after looting this mail
|
|
|
|
|
local remainingSpace = 0
|
|
|
|
|
for bag, space in pairs(genericSpace) do
|
|
|
|
|
remainingSpace = remainingSpace + space
|
|
|
|
|
end
|
|
|
|
|
if remainingSpace >= TSM.db.global.keepMailSpace then
|
|
|
|
|
return true -- either not using keepMailSpace option or we can loot all of this mail
|
|
|
|
|
else
|
|
|
|
|
private.keepFreeSlots = true -- can't loot the whole of this mail and leave enough free slots so set the flag that displays the chat message
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function private:StopAutoLooting(failed)
|
|
|
|
|
if failed and (not private.frame or not private.frame:IsVisible()) then
|
|
|
|
|
TSM:Print(L["Cannot finish auto looting, inventory is full or too many unique items."])
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if private.keepFreeSlots then
|
|
|
|
|
TSM:Printf(L["Cannot finish auto looting, keeping %s slots free."], TSM.db.global.keepMailSpace)
|
|
|
|
|
private.keepFreeSlots = false
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private.mode = nil
|
|
|
|
|
private.resetIndex = nil
|
|
|
|
|
private.autoLootTotal = nil
|
|
|
|
|
if not private.frame then return end
|
|
|
|
|
private.frame:EnableButtons()
|
|
|
|
|
|
|
|
|
|
--Tell user how much money has been collected if they don't have it turned off in TradeSkillMaster_Mailing options
|
|
|
|
|
if private.moneyCollected and private.moneyCollected > 0 and TSM.db.global.displayMoneyCollected then
|
|
|
|
|
TSM:Printf(L["%s total gold collected!"], TSMAPI:FormatTextMoney(private.moneyCollected))
|
|
|
|
|
private.moneyCollected = 0
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function private:GetBagSlots()
|
|
|
|
|
local genericSpace, uniqueSpace, partSlots = {}, {}, {}
|
|
|
|
|
for bag = 0, NUM_BAG_SLOTS do
|
|
|
|
|
if (GetItemFamily(GetBagName(bag)) or 0) > 0 then
|
|
|
|
|
uniqueSpace[bag] = GetContainerNumFreeSlots(bag) or 0
|
|
|
|
|
else
|
|
|
|
|
genericSpace[bag] = GetContainerNumFreeSlots(bag) or 0
|
|
|
|
|
end
|
|
|
|
|
for slot = 1, GetContainerNumSlots(bag) do
|
|
|
|
|
local iLink = GetContainerItemLink(bag, slot)
|
|
|
|
|
if iLink then
|
|
|
|
|
if not partSlots[bag] then
|
|
|
|
|
partSlots[bag] = {}
|
|
|
|
|
end
|
|
|
|
|
table.insert(partSlots[bag], slot)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return genericSpace, uniqueSpace, partSlots
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Inbox:UI_ERROR_MESSAGE(event, msg)
|
|
|
|
|
if msg == ERR_MAIL_DATABASE_ERROR then
|
|
|
|
|
-- recover from internal mail error
|
|
|
|
|
TSMAPI:CreateTimeDelay("mailWaitDelay", 1, private.AutoLoot)
|
|
|
|
|
elseif msg == ERR_INV_FULL or msg == ERR_ITEM_MAX_COUNT then
|
|
|
|
|
-- Try the next index in case we can still loot more such as in the case of glyphs
|
|
|
|
|
private.lootIndex = private.lootIndex + 1
|
|
|
|
|
|
|
|
|
|
-- If we've exhausted all slots, but we still have <50 and more mail pending, wait until new data comes and keep looting it
|
|
|
|
|
local current, total = GetInboxNumItems()
|
|
|
|
|
if private.lootIndex > current then
|
|
|
|
|
if private.lootIndex > total and total <= 50 then
|
|
|
|
|
private:StopAutoLooting(true)
|
|
|
|
|
end
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
TSMAPI:CreateTimeDelay("mailWaitDelay", math.max(5/GetFramerate(), 0.3), private.AutoLoot)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function Inbox:MAIL_CLOSED()
|
|
|
|
|
private.resetIndex = nil
|
|
|
|
|
private.allowTimerStart = true
|
|
|
|
|
private.waitingForData = nil
|
|
|
|
|
private:StopAutoLooting()
|
|
|
|
|
TSMAPI:CancelFrame("inboxLootTextDelay")
|
|
|
|
|
TSMAPI:CancelFrame("mailSkipDelay")
|
|
|
|
|
Inbox:UnregisterEvent("UI_ERROR_MESSAGE") --sometimes shows error messages even when closed, so unregister that event.
|
|
|
|
|
end
|