-- ------------------------------------------------------------------------------ -- -- TradeSkillMaster -- -- https://tradeskillmaster.com -- -- All Rights Reserved - Detailed license information included with addon. -- -- ------------------------------------------------------------------------------ -- local _, TSM = ... local Open = TSM.Mailing:NewPackage("Open") local L = TSM.Include("Locale").GetTable() local Delay = TSM.Include("Util.Delay") local Event = TSM.Include("Util.Event") local String = TSM.Include("Util.String") local Money = TSM.Include("Util.Money") local Log = TSM.Include("Util.Log") local ItemString = TSM.Include("Util.ItemString") local Theme = TSM.Include("Util.Theme") local Threading = TSM.Include("Service.Threading") local ItemInfo = TSM.Include("Service.ItemInfo") local MailTracking = TSM.Include("Service.MailTracking") local private = { thread = nil, isOpening = false, lastCheck = nil, moneyCollected = 0, } local INBOX_SIZE = TSM.IsWowClassic() and 50 or 100 local MAIL_REFRESH_TIME = TSM.IsWowClassic() and 60 or 15 -- ============================================================================ -- Module Functions -- ============================================================================ function Open.OnInitialize() private.thread = Threading.New("MAIL_OPENING", private.OpenMailThread) Event.Register("MAIL_SHOW", private.ScheduleCheck) Event.Register("MAIL_CLOSED", private.MailClosedHandler) end function Open.KillThread() Threading.Kill(private.thread) private.PrintMoneyCollected() private.isOpening = false end function Open.StartOpening(callback, autoRefresh, keepMoney, filterText, filterType) Threading.Kill(private.thread) private.isOpening = true private.moneyCollected = 0 Threading.SetCallback(private.thread, callback) Threading.Start(private.thread, autoRefresh, keepMoney, filterText, filterType) end function Open.GetLastCheckTime() return private.lastCheck end -- ============================================================================ -- Mail Opening Thread -- ============================================================================ function private.OpenMailThread(autoRefresh, keepMoney, filterText, filterType) local isLastLoop = false while true do local query = TSM.Mailing.Inbox.CreateQuery() query:ResetOrderBy() :OrderBy("index", false) :Or() :Matches("itemList", filterText) :Matches("subject", filterText) :End() :Select("index") if filterType then query:Equal("icon", filterType) end local mails = Threading.AcquireSafeTempTable() for _, index in query:Iterator() do tinsert(mails, index) end query:Release() private.OpenMails(mails, keepMoney, filterType) Threading.ReleaseSafeTempTable(mails) if not autoRefresh or isLastLoop then break end local numLeftMail, totalLeftMail = GetInboxNumItems() if totalLeftMail == numLeftMail or numLeftMail == INBOX_SIZE then isLastLoop = true end CheckInbox() Threading.Sleep(1) end private.PrintMoneyCollected() private.isOpening = false end function private.CanOpenMail() return not C_Mail.IsCommandPending() end function private.OpenMails(mails, keepMoney, filterType) for i = 1, #mails do local index = mails[i] Threading.WaitForFunction(private.CanOpenMail) local mailType = MailTracking.GetMailType(index) local matchesFilter = (not filterType and mailType) or (filterType and filterType == mailType) local hasBagSpace = not MailTracking.GetInboxItemLink(index) or CalculateTotalNumberOfFreeBagSlots() > TSM.db.global.mailingOptions.keepMailSpace if matchesFilter and hasBagSpace then local _, _, _, _, money = GetInboxHeaderInfo(index) if not keepMoney or (keepMoney and money <= 0) then -- marks the mail as read GetInboxText(index) AutoLootMailItem(index) private.moneyCollected = private.moneyCollected + money if Threading.WaitForEvent("CLOSE_INBOX_ITEM", "MAIL_FAILED") ~= "MAIL_FAILED" then if TSM.db.global.mailingOptions.inboxMessages then private.PrintOpenMailMessage(index) end end end end end end -- ============================================================================ -- Private Helper Functions -- ============================================================================ function private.CheckInbox() if private.isOpening then private.ScheduleCheck() return end if not TSM.UI.MailingUI.Inbox.IsMailOpened() then CheckInbox() end private.ScheduleCheck() end function private.PrintMoneyCollected() if TSM.db.global.mailingOptions.inboxMessages and private.moneyCollected > 0 then Log.PrintfUser(L["Total Gold Collected: %s"], Money.ToString(private.moneyCollected)) end private.moneyCollected = 0 end function private.PrintOpenMailMessage(index) local _, _, sender, subject, money, cod, _, hasItem = GetInboxHeaderInfo(index) sender = sender or "?" local _, _, _, _, isInvoice = GetInboxText(index) if isInvoice then -- it's an invoice local invoiceType, itemName, playerName, bid, _, _, ahcut, _, _, _, quantity = GetInboxInvoiceInfo(index) playerName = playerName or (invoiceType == "buyer" and AUCTION_HOUSE_MAIL_MULTIPLE_SELLERS or AUCTION_HOUSE_MAIL_MULTIPLE_BUYERS) if invoiceType == "buyer" then local itemLink = MailTracking.GetInboxItemLink(index) or "["..itemName.."]" Log.PrintfUser(L["Bought %sx%d for %s from %s"], itemLink, quantity, Money.ToString(bid, Theme.GetFeedbackColor("RED"):GetTextColorPrefix()), playerName) elseif invoiceType == "seller" then Log.PrintfUser(L["Sold [%s]x%d for %s to %s"], itemName, quantity, Money.ToString(bid - ahcut, Theme.GetFeedbackColor("GREEN"):GetTextColorPrefix()), 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 ItemString.Get(itemLink) ~= ItemString.Get(link) then itemLink = L["Multiple Items"] quantity = -1 break end end if hasItem == 1 then itemLink = MailTracking.GetInboxItemLink(index) or itemLink end local itemName = ItemInfo.GetName(itemLink) or "?" local itemDesc = (quantity > 0 and format("%sx%d", itemLink, quantity)) or (quantity == -1 and "Multiple Items") or "?" if hasItem == 1 and itemLink and strfind(subject, "^" .. String.Escape(format(AUCTION_EXPIRED_MAIL_SUBJECT, itemName))) then Log.PrintfUser(L["Your auction of %s expired"], itemDesc) elseif hasItem == 1 and quantity > 0 and (subject == format(AUCTION_REMOVED_MAIL_SUBJECT.."x%d", itemName, quantity) or subject == format(AUCTION_REMOVED_MAIL_SUBJECT, itemName)) then Log.PrintfUser(L["Cancelled auction of %sx%d"], itemLink, quantity) elseif cod > 0 then Log.PrintfUser(L["%s sent you a COD of %s for %s"], sender, Money.ToString(cod, Theme.GetFeedbackColor("RED"):GetTextColorPrefix()), itemDesc) elseif money > 0 then Log.PrintfUser(L["%s sent you %s and %s"], sender, itemDesc, Money.ToString(money, Theme.GetFeedbackColor("GREEN"):GetTextColorPrefix())) else Log.PrintfUser(L["%s sent you %s"], sender, itemDesc) end elseif money > 0 then Log.PrintfUser(L["%s sent you %s"], sender, Money.ToString(money, Theme.GetFeedbackColor("GREEN"):GetTextColorPrefix())) elseif subject then Log.PrintfUser(L["%s sent you a message: %s"], sender, subject) end end -- ============================================================================ -- Event Handlers -- ============================================================================ function private.ScheduleCheck() if not private.lastCheck or time() - private.lastCheck > (MAIL_REFRESH_TIME - 1) then private.lastCheck = time() Delay.AfterTime("mailInboxCheck", MAIL_REFRESH_TIME, private.CheckInbox) else local nextUpdate = MAIL_REFRESH_TIME - (time() - private.lastCheck) Delay.AfterTime("mailInboxCheck", nextUpdate, private.CheckInbox) end end function private.MailClosedHandler() Delay.Cancel("mailInboxCheck") end