Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- ------------------------------------------------------------------------------ --
- -- 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, moneyCollected=0, threadId=nil, frame=nil, mode=nil, modeModified=nil}
- function Inbox:OnEnable()
- Inbox:RegisterEvent("MAIL_SHOW")
- Inbox:RegisterEvent("MAIL_INBOX_UPDATE", function() TSMAPI.Delay:AfterTime("mailingInboxUpdate", 0.2, private.InboxUpdate) end)
- Inbox:RegisterEvent("MAIL_CLOSED")
- end
- function Inbox:CreateTab()
- local BFC = TSMAPI.GUI:GetBuildFrameConstants()
- local frameInfo = {
- type = "Frame",
- key = "inboxTab",
- hidden = true,
- points = "ALL",
- scripts = {"OnShow", "OnHide"},
- children = {
- {
- type = "Text",
- key = "topLabel",
- text = "",
- textFont = {TSMAPI.Design:GetContentFont("small")},
- justify = {"CENTER", "MIDDLE"},
- size = {0, 15},
- points = {{"TOPLEFT", 5, -5}, {"TOPRIGHT", -5, -5}},
- },
- {
- type = "HLine",
- offset = -25,
- },
- {
- type = "ScrollingTableFrame",
- key = "st",
- points = {{"TOPLEFT", 5, -30}, {"BOTTOMRIGHT", -5, 55}},
- scripts = {"OnClick"},
- },
- {
- type = "Button",
- key = "allBtn",
- text = L["Open All Mail"],
- textHeight = 18,
- tooltip = L["Opens all mail in your inbox. If you have more than 50 items in your inbox, the opening will automatically continue when the inbox refreshes."].."\n\n"..TSMAPI.Design:GetInlineColor("link")..L["Shift-Click|r to leave mail with gold."],
- size = {0, 20},
- points = {{"BOTTOMLEFT", 5, 30}, {"BOTTOMRIGHT", -5, 30}},
- scripts = {"OnClick"},
- },
- {
- type = "Text",
- key = "ahMailLabel",
- text = L["AH Mail:"],
- textFont = {TSMAPI.Design:GetContentFont("normal")},
- justify = {"RIGHT", "CENTER"},
- size = {70, 20},
- points = {{"BOTTOMLEFT", 5, 5}},
- },
- {
- type = "Button",
- key = "salesBtn",
- text = L["Sales"],
- textHeight = 15,
- tooltip = L["Opens all mail containing gold from sales."].."\n\n"..format(L["%sShift-Click|r to continue opening after an inbox refresh if you have more than 50 items in your inbox."], TSMAPI.Design:GetInlineColor("link")),
- size = {55, 20},
- points = {{"BOTTOMLEFT", BFC.PREV, "BOTTOMRIGHT", 5, 0}},
- scripts = {"OnClick"},
- },
- {
- type = "Button",
- key = "buysBtn",
- text = L["Buys"],
- tooltip = L["Opens all mail containing items you have bought."].."\n\n"..format(L["%sShift-Click|r to continue opening after an inbox refresh if you have more than 50 items in your inbox."], TSMAPI.Design:GetInlineColor("link")),
- textHeight = 15,
- size = {55, 20},
- points = {{"BOTTOMLEFT", BFC.PREV, "BOTTOMRIGHT", 5, 0}},
- scripts = {"OnClick"},
- },
- {
- type = "Button",
- key = "cancelsBtn",
- text = L["Cancels"],
- textHeight = 15,
- tooltip = L["Opens all mail containing canceled auctions."].."\n\n"..format(L["%sShift-Click|r to continue opening after an inbox refresh if you have more than 50 items in your inbox."], TSMAPI.Design:GetInlineColor("link")),
- size = {55, 20},
- points = {{"BOTTOMLEFT", BFC.PREV, "BOTTOMRIGHT", 5, 0}},
- scripts = {"OnClick"},
- },
- {
- type = "Button",
- key = "expiresBtn",
- text = L["Expires"],
- textHeight = 15,
- tooltip = L["Opens all mail containing expired auctions."].."\n\n"..format(L["%sShift-Click|r to continue opening after an inbox refresh if you have more than 50 items in your inbox."], TSMAPI.Design:GetInlineColor("link")),
- size = {0, 20},
- points = {{"BOTTOMLEFT", BFC.PREV, "BOTTOMRIGHT", 5, 0}, {"BOTTOMRIGHT", -5, 5}},
- scripts = {"OnClick"},
- },
- {
- type = "Button",
- key = "reloadBtn",
- text = RELOADUI,
- textHeight = 16,
- size = {150, 20},
- points = {{"CENTER"}},
- scripts = {"OnClick"},
- },
- },
- handlers = {
- OnShow = function(self)
- private.frame = self
- self.reloadBtn:SetFrameStrata("HIGH")
- self.reloadBtn:Hide()
- if not self.helpBtn then
- local TOTAL_WIDTH = private.frame:GetParent():GetWidth()
- local helpPlateInfo = {
- FramePos = {x = 0, y = 70},
- FrameSize = {width = TOTAL_WIDTH, height = private.frame:GetHeight()},
- {
- ButtonPos = {x = 100, y = -20},
- HighLightBox = {x = 70, y = -35, width = TOTAL_WIDTH-70, height = 30},
- ToolTipDir = "DOWN",
- ToolTipText = L["These buttons change what is shown in the mailbox frame. You can view your inbox, automatically mail items in groups, quickly send items to other characters, and more in the various tabs."],
- },
- {
- ButtonPos = {x = 200, y = -200},
- HighLightBox = {x = 0, y = -65, width = TOTAL_WIDTH, height = 305},
- ToolTipDir = "RIGHT",
- ToolTipText = L["This is where the items in your inbox are listed in an information and easy to read format."],
- },
- {
- ButtonPos = {x = 300, y = -360},
- HighLightBox = {x = 0, y = -370, width = TOTAL_WIDTH, height = 55},
- ToolTipDir = "RIGHT",
- ToolTipText = L["The 'Open All Mail' button will open all mail in your inbox (including beyond the 50-mail limit). The AH mail buttons below that will open specific types of mail from your inbox."],
- },
- }
- self.helpBtn = CreateFrame("Button", nil, private.frame, "MainHelpPlateButton")
- self.helpBtn:SetPoint("TOPLEFT", 50, 100)
- self.helpBtn:SetScript("OnClick", function() TSM.MailTab:ToggleHelpPlate(private.frame, helpPlateInfo, self.helpBtn, true) end)
- self.helpBtn:SetScript("OnHide", function() if HelpPlate_IsShowing(helpPlateInfo) then TSM.MailTab:ToggleHelpPlate(private.frame, helpPlateInfo, self.helpBtn, false) end end)
- if not TSM.db.global.helpPlatesShown.inbox then
- TSM.db.global.helpPlatesShown.inbox = true
- TSM.MailTab:ToggleHelpPlate(private.frame, helpPlateInfo, self.helpBtn, false)
- end
- end
- private:InboxUpdate()
- end,
- OnHide = private.MailThreadDone,
- st = {
- OnClick = function(_, data)
- if IsShiftKeyDown() and select(6, GetInboxHeaderInfo(data.index)) <= 0 then
- if private:CanLootMailIndex(data.index, true) then
- private:PrintOpenMailMessage(data.index)
- AutoLootMailItem(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)
- OpenMailFrameInset:SetPoint("TOPLEFT", 4, -80)
- PlaySound(SOUNDKIT["IG_SPELLBOOK_OPEN"])
- else
- InboxFrame.openMailID = 0
- HideUIPanel(OpenMailFrame)
- end
- InboxFrame_Update()
- end,
- },
- allBtn = {
- OnClick = function() private:StartOpenMail("all") end,
- },
- buysBtn = {
- OnClick = function() private:StartOpenMail("buys") end,
- },
- salesBtn = {
- OnClick = function() private:StartOpenMail("sales") end,
- },
- cancelsBtn = {
- OnClick = function() private:StartOpenMail("cancels") end,
- },
- expiresBtn = {
- OnClick = function() private:StartOpenMail("expires") end,
- },
- reloadBtn = {
- OnClick = ReloadUI,
- },
- },
- }
- return frameInfo
- 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
- 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
- CheckInbox()
- private.frame.reloadBtn:Hide()
- end
- end
- end
- function Inbox:MAIL_SHOW()
- TSMAPI.Delay:AfterTime("mailingGetSellers", 0.1, private.RequestSellerInfo, 0.1)
- 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
- function private:RequestSellerInfo()
- local isDone = true
- for i=1, GetInboxNumItems() do
- local invoiceType, _, seller = GetInboxInvoiceInfo(i)
- if invoiceType and seller == "" then
- isDone = false
- end
- end
- if isDone and GetInboxNumItems() > 0 then
- TSMAPI.Delay:Cancel("mailingGetSellers")
- 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:MoneyToString(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["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
- local numMail, totalMail = GetInboxNumItems()
- local greenColor, redColor = "|cff00ff00", "|cffff0000"
- local mailInfo = {}
- local collectGold = 0
- for i = 1, numMail do
- mailInfo[i] = ""
- local isInvoice = select(5, GetInboxText(i))
- local _, _, sender, subject, money, cod, daysLeft, hasItem = GetInboxHeaderInfo(i)
- if isInvoice then
- local invoiceType, itemName, playerName, bid, _, _, ahcut, _, _, _, quantity = GetInboxInvoiceInfo(i)
- if invoiceType == "buyer" then
- local itemLink = private:GetFirstInboxItemLink(i) or itemName
- mailInfo[i] = format(L["Buy: %s (%d) | %s | %s"], itemLink, quantity, TSMAPI:MoneyToString(bid, redColor), FormatDaysLeft(daysLeft, i))
- elseif invoiceType == "seller" then
- collectGold = collectGold + bid - ahcut
- mailInfo[i] = format(L["Sale: %s (%d) | %s | %s"], itemName, quantity, TSMAPI:MoneyToString(bid - ahcut, greenColor), 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(4, GetInboxItem(i, j)) or 0)
- if TSMAPI.Item:ToItemString(itemLink) ~= TSMAPI.Item:ToItemString(link) then
- itemLink = L["Multiple Items"]
- quantity = -1
- break
- end
- end
- if hasItem == 1 then
- itemLink = private:GetFirstInboxItemLink(i) or itemLink
- end
- local itemDesc = (quantity > 0 and format("%s (%d)", itemLink, quantity)) or (quantity == -1 and L["Multiple Items"]) or "---"
- local name = TSMAPI.Item:GetName(itemLink) or "?"
- if hasItem == 1 and itemLink and strfind(subject, "^" .. TSMAPI.Util:StrEscape(format(AUCTION_EXPIRED_MAIL_SUBJECT, name))) 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 | %s"], itemDesc, TSMAPI:MoneyToString(cod, redColor), quantity > 0 and TSMAPI:MoneyToString(floor(cod / quantity + 0.5), redColor) or "---", sender or "---", FormatDaysLeft(daysLeft, i))
- elseif money > 0 then
- collectGold = collectGold + money
- mailInfo[i] = format("%s + %s | %s | %s", itemDesc, TSMAPI:MoneyToString(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:MoneyToString(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)
- if numMail > 0 then
- private.frame.reloadBtn:Hide()
- end
- private:UpdateTopLabel()
- if private.cacheFrame.endTime and numMail == totalMail and private.lastTotal ~= totalMail then
- -- Yay nothing else to loot, so nothing else to update the cache for!
- private.cacheFrame.endTime = nil
- private.cacheFrame:Hide()
- elseif (private.cacheFrame.endTime and numMail >= 50 and private.lastTotal ~= totalMail) or (numMail >= 50 and private.allowTimerStart) then
- -- Start a timer since we're over the limit of 50 items before waiting for it to recache
- private.allowTimerStart = nil
- private.waitingForData = nil
- private.lastTotal = totalMail
- private.cacheFrame.endTime = GetTime() + 60
- private.cacheFrame:Show()
- end
- end
- function private:CanLootMailIndex(index, force)
- local money, cod, _, hasItem = select(5, GetInboxHeaderInfo(index))
- -- check if this would put them over the gold cap
- money = (money or 0) + (cod or 0)
- local MAX_COPPER = 99999999999
- local currentMoney = GetMoney()
- TSMAPI:Assert(currentMoney <= MAX_COPPER)
- if currentMoney + money > MAX_COPPER then return end
- if not hasItem or hasItem == 0 then return true end
- if force or not TSM.db.global.keepMailSpace or TSM.db.global.keepMailSpace == 0 then
- for j = 1, ATTACHMENTS_MAX_RECEIVE do
- local link = GetInboxItemLink(index, j)
- local itemString = TSMAPI.Item:ToItemString(link)
- local quantity = select(4, GetInboxItem(index, j)) or 0
- local space = 0
- if itemString then
- for bag = 0, NUM_BAG_SLOTS do
- if TSMAPI.Inventory:ItemWillGoInBag(link, bag) then
- for slot = 1, GetContainerNumSlots(bag) do
- local iString = TSMAPI.Item:ToItemString(GetContainerItemLink(bag, slot))
- if iString == itemString then
- local stackSize = select(2, GetContainerItemInfo(bag, slot))
- local maxStackSize = TSMAPI.Item:GetMaxStack(itemString) or 1
- if (maxStackSize - stackSize) >= quantity then
- return true
- end
- elseif not iString then
- return true
- end
- end
- end
- end
- -- Cannot loot the first item, so return.
- private.inventoryFull = true
- return
- 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 link = GetInboxItemLink(index, j)
- local itemString = TSMAPI.Item:ToItemString(link)
- local quantity = select(4, GetInboxItem(index, j)) or 0
- local isDone = false
- if itemString then
- for bag = 0, NUM_BAG_SLOTS do
- if TSMAPI.Inventory:ItemWillGoInBag(link, bag) then
- for slot = 1, GetContainerNumSlots(bag) do
- local iString = TSMAPI.Item:ToItemString(GetContainerItemLink(bag, slot))
- if iString == itemString and (partSlots[bag] and partSlots[bag][slot]) then
- local stackSize = select(2, GetContainerItemInfo(bag, slot))
- local maxStackSize = TSMAPI.Item:GetMaxStack(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(TSMAPI.Item:ToItemID(itemString)) or 0
- 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: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:MAIL_CLOSED()
- private.allowTimerStart = true
- private.waitingForData = nil
- TSMAPI.Delay:Cancel("mailingGetSellers")
- private:MailThreadDone()
- end
- function private:ShouldDeleteMail(index)
- local subject, money, cod, numItems, wasReturned, canReply, isGM = TSMAPI.Util:Select({4, 5, 6, 8, 10, 12, 13}, GetInboxHeaderInfo(index))
- if not TSM.db.global.deleteEmptyNPCMail then return false end
- if isGM then return false end
- if canReply then return false end
- if numItems then return false end
- if cod > 0 then return false end
- if money > 0 then return false end
- if wasReturned then return false end
- return true
- end
- function private:ShouldOpenMail(index)
- local _, _, _, subject, money, cod, _, numItems, _, _, _, _, isGM = GetInboxHeaderInfo(index)
- cod = cod or 0
- money = money or 0
- numItems = numItems or 0
- if isGM or cod > 0 or (money == 0 and numItems == 0) then return end
- if not private:CanLootMailIndex(index) then return end
- if private.mode == "all" then
- if private.modeModified then
- return money == 0
- else
- return true
- end
- elseif private.mode == "sales" then
- return money > 0 and GetInboxInvoiceInfo(index) == "seller"
- elseif private.mode == "buys" then
- return numItems > 0 and GetInboxInvoiceInfo(index) == "buyer"
- elseif private.mode == "cancels" then
- local isInvoice = select(5, GetInboxText(index))
- if not isInvoice and numItems == 1 then
- local itemName = TSMAPI.Item:GetName(private:GetFirstInboxItemLink(index))
- if itemName then
- local quantity = select(4, 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 == "expires" then
- local isInvoice = select(5, GetInboxText(index))
- if not isInvoice and numItems == 1 then
- local itemName = TSMAPI.Item:GetName(private:GetFirstInboxItemLink(index))
- if itemName and strfind(subject, "^" .. TSMAPI.Util:StrEscape(format(AUCTION_EXPIRED_MAIL_SUBJECT, itemName))) then
- return true
- end
- end
- end
- end
- function private:PrintOpenMailMessage(index)
- if not TSM.db.global.inboxMessages then return end
- local _, _, sender, subject, money, cod, _, hasItem = GetInboxHeaderInfo(index)
- local greenColor, redColor = "|cff00ff00", "|cffff0000"
- sender = sender or "?"
- if select(5, GetInboxText(index)) then
- -- it's an invoice
- local invoiceType, itemName, playerName, bid, _, _, ahcut, _, _, _, quantity = GetInboxInvoiceInfo(index)
- playerName = playerName or "?"
- if invoiceType == "buyer" then
- local itemLink = private:GetFirstInboxItemLink(index) or itemName
- TSM:Printf(L["Bought %sx%d for %s from %s"], itemLink, quantity, TSMAPI:MoneyToString(bid, redColor), playerName)
- elseif invoiceType == "seller" then
- TSM:Printf(L["Sold [%s]x%d for %s to %s"], itemName, quantity, TSMAPI:MoneyToString(bid - ahcut, greenColor), playerName)
- 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(4, GetInboxItem(index, i)) or 0)
- if TSMAPI.Item:ToItemString(itemLink) ~= TSMAPI.Item:ToItemString(link) then
- itemLink = L["Multiple Items"]
- quantity = -1
- break
- end
- end
- if hasItem == 1 then
- itemLink = private:GetFirstInboxItemLink(index) or itemLink
- end
- local itemName = TSMAPI.Item:GetName(itemLink) or "?"
- 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.Util:StrEscape(format(AUCTION_EXPIRED_MAIL_SUBJECT, itemName))) then
- TSM:Printf(L["Your auction of %s expired"], itemDesc)
- elseif hasItem == 1 and quantity > 0 and (subject == format(AUCTION_REMOVED_MAIL_SUBJECT.." (%d)", itemName, quantity) or subject == format(AUCTION_REMOVED_MAIL_SUBJECT, itemName)) then
- TSM:Printf(L["Cancelled auction of %sx%d"], itemLink, quantity)
- elseif cod > 0 then
- TSM:Printf(L["%s sent you a COD of %s for %s"], sender, TSMAPI:MoneyToString(cod, redColor), itemDesc)
- elseif money > 0 then
- TSM:Printf(L["%s sent you %s and %s"], sender, itemDesc, TSMAPI:MoneyToString(money, greenColor))
- else
- TSM:Printf(L["%s sent you %s"], sender, itemDesc)
- end
- elseif money > 0 then
- TSM:Printf(L["%s sent you %s"], sender, TSMAPI:MoneyToString(money, greenColor))
- else
- TSM:Printf(L["%s sent you a message: %s"], sender, subject)
- end
- end
- function private.OpenMailThread(self)
- self:SetThreadName("MAILING_OPEN_MAIL")
- local eventStatus = nil
- self:RegisterEvent("UI_ERROR_MESSAGE", function(_, msg)
- if msg == ERR_MAIL_DATABASE_ERROR or msg == ERR_INV_FULL or msg == ERR_ITEM_MAX_COUNT then
- -- internal mail error, inventory full, or too many unique items
- eventStatus = "ERROR"
- end
- end)
- self:RegisterEvent("MAIL_INBOX_UPDATE", function() eventStatus = "UPDATE" end)
- private.frame.allBtn:Disable()
- private.frame.salesBtn:Disable()
- private.frame.buysBtn:Disable()
- private.frame.cancelsBtn:Disable()
- private.frame.expiresBtn:Disable()
- -- wait for any pending mail to arrive
- while select(2, GetInboxNumItems()) == 0 and HasNewMail() do self:Yield(true) end
- private.moneyCollected = 0
- local attemptedToOpenMail = true
- local shouldWait = false
- while attemptedToOpenMail do
- attemptedToOpenMail = nil
- local encounteredError = nil
- local numMail, totalMail = GetInboxNumItems()
- for index=numMail, 1, -1 do
- if private:ShouldOpenMail(index) then
- if shouldWait then
- -- this isn't the first time through the loop, so give the pending opens some times to clear out
- self:Sleep(2)
- shouldWait = nil
- attemptedToOpenMail = true
- break
- end
- local money = select(5, GetInboxHeaderInfo(index)) or 0
- local numItems = select(8, GetInboxHeaderInfo(index)) or 0
- local numInboxItems = GetInboxNumItems()
- -- auto-loot the mail
- private:PrintOpenMailMessage(index)
- AutoLootMailItem(index)
- -- wait for an inbox event
- eventStatus = nil
- local triedDeleting = nil
- while not eventStatus do self:Yield(true) end
- if eventStatus == "UPDATE" then
- -- wait for the number of mails to go down by 1 (for at most 1 second per item)
- local waitEndTime = debugprofilestop() + (max(numItems, 1) * 1000)
- while debugprofilestop() < waitEndTime do
- if GetInboxNumItems() == numInboxItems - 1 then break end
- if not triedDeleting and private:ShouldDeleteMail(index) then
- DeleteInboxItem(index)
- triedDeleting = true
- end
- if eventStatus == "ERROR" then
- TSM:LOG_ERR("Encountered error at index %d (triedDeleting=%s)", index, tostring(triedDeleting))
- encounteredError = true
- break
- end
- self:Yield(true)
- end
- if not encounteredError then
- attemptedToOpenMail = true
- end
- elseif eventStatus == "ERROR" then
- -- there was an error trying to open this mail, so skip it silently and try again
- encounteredError = true
- end
- -- track money collected
- private.moneyCollected = private.moneyCollected + money
- elseif private:ShouldDeleteMail(index) then
- -- wait for an inbox event
- DeleteInboxItem(index)
- eventStatus = nil
- while not eventStatus do self:Yield(true) end
- if eventStatus == "UPDATE" then
- attemptedToOpenMail = true
- elseif eventStatus == "ERROR" then
- encounteredError = true
- end
- end
- end
- local numMail, totalMail = GetInboxNumItems()
- if attemptedToOpenMail and totalMail > numMail and numMail < 50 and (private.mode == "all" or private.modeModified) then
- -- wait for the inbox to update and then continue
- while true do
- local numMail, totalMail = GetInboxNumItems()
- if numMail == 50 or numMail == totalMail then break end
- self:Sleep(0.5)
- end
- self:Sleep(1)
- elseif not attemptedToOpenMail and encounteredError then
- TSM:Print(L["Cannot finish auto looting, inventory is full or too many unique items."])
- else
- shouldWait = true
- end
- end
- -- check if we ran out of
- if private.keepFreeSlots then
- TSM:Printf(L["Stopped opening mail to keep %d slots free."], TSM.db.global.keepMailSpace)
- private.keepFreeSlots = nil
- end
- if private.inventoryFull then
- TSM:Print(L["Cannot finish auto looting, inventory is full or too many unique items."])
- private.inventoryFull = nil
- end
- -- play sound
- TSMAPI:DoPlaySound(TSM.db.global.openMailSound)
- end
- function private:MailThreadDone()
- if not private.threadId then return end
- -- Tell user how much money has been collected if enabled
- if private.moneyCollected > 0 and TSM.db.global.displayMoneyCollected then
- TSM:Printf(L["Total Gold Collected: %s"], TSMAPI:MoneyToString(private.moneyCollected))
- private.moneyCollected = 0
- end
- TSMAPI.Threading:Kill(private.threadId)
- private.threadId = nil
- private.mode = nil
- private.modeModified = nil
- private.frame.allBtn:Enable()
- private.frame.salesBtn:Enable()
- private.frame.buysBtn:Enable()
- private.frame.cancelsBtn:Enable()
- private.frame.expiresBtn:Enable()
- end
- function private:StartOpenMail(mode)
- private:MailThreadDone()
- private.mode = mode
- private.modeModified = IsShiftKeyDown()
- private.threadId = TSMAPI.Threading:Start(private.OpenMailThread, 0.7, private.MailThreadDone)
- end
- function private:GetFirstInboxItemLink(index)
- if not TSMMailingInboxTooltip then
- CreateFrame("GameTooltip", "TSMMailingInboxTooltip", UIParent, "GameTooltipTemplate")
- end
- TSMMailingInboxTooltip:SetOwner(UIParent, "ANCHOR_NONE")
- TSMMailingInboxTooltip:ClearLines()
- local _, speciesId, level, breedQuality, maxHealth, power, speed, name = TSMMailingInboxTooltip:SetInboxItem(index)
- local link = nil
- if (speciesId or 0) > 0 then
- link = TSMAPI.Item:GetLink(strjoin(":", "p", speciesId, level, breedQuality, maxHealth, power, speed))
- else
- link = GetInboxItemLink(index, 1)
- end
- TSMMailingInboxTooltip:Hide()
- return link
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement