TradeSkillMaster/Core/Service/Mailing/Open.lua

234 lines
8.0 KiB
Lua

-- ------------------------------------------------------------------------------ --
-- 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