bbe2492a5b
Each DataStore_* / Altoholic_* addon now lives at the repo root, matching the Exiles fork-layout convention (one folder per addon, no wrapper dir).
616 lines
18 KiB
Lua
616 lines
18 KiB
Lua
--[[ *** DataStore_Mails ***
|
|
Written by : Thaoky, EU-Marécages de Zangar
|
|
July 16th, 2009
|
|
--]]
|
|
if not DataStore then return end
|
|
|
|
local addonName = "DataStore_Mails"
|
|
|
|
_G[addonName] = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceConsole-3.0", "AceEvent-3.0", "AceComm-3.0", "AceSerializer-3.0", "AceTimer-3.0")
|
|
|
|
local addon = _G[addonName]
|
|
|
|
local THIS_ACCOUNT = "Default"
|
|
local commPrefix = "DS_Mails" -- let's keep it a bit shorter than the addon name, this goes on a comm channel, a byte is a byte ffs :p
|
|
local MAIL_EXPIRY = 30 -- Mails expire after 30 days
|
|
|
|
-- Func Call Spam Protection
|
|
local FCSP_timer_OnBagUpdate
|
|
|
|
-- Message types
|
|
local MSG_SENDMAIL_INIT = 1
|
|
local MSG_SENDMAIL_END = 2
|
|
local MSG_SENDMAIL_ATTACHMENT = 3
|
|
local MSG_SENDMAIL_BODY = 4
|
|
|
|
local ICON_COIN = "Interface\\Icons\\INV_Misc_Coin_01"
|
|
local ICON_NOTE = "Interface\\Icons\\INV_Misc_Note_01"
|
|
|
|
local AddonDB_Defaults = {
|
|
global = {
|
|
Options = {
|
|
ScanMailBody = 1, -- by default, scan the body of a mail (this action marks it as read)
|
|
CheckMailExpiry = 1, -- check mail expiry or not
|
|
MailWarningThreshold = 5,
|
|
CheckMailExpiryAllAccounts = 1,
|
|
CheckMailExpiryAllRealms = 1,
|
|
},
|
|
Characters = {
|
|
['*'] = { -- ["Account.Realm.Name"]
|
|
lastUpdate = nil, -- last time the mail was checked for this char
|
|
lastVisitDate = nil, -- in YYYY MM DD hh:mm, for external apps
|
|
Mails = {
|
|
['*'] = {
|
|
icon = nil,
|
|
link = nil,
|
|
count = nil,
|
|
money = nil,
|
|
lastCheck = 0, -- last time "THIS" mail was checked (can be different than that of the mailbox)
|
|
text = nil,
|
|
subject = nil,
|
|
sender = nil,
|
|
daysLeft = 0,
|
|
returned = nil,
|
|
}
|
|
},
|
|
MailCache = { -- same structure as "Mail", but serves as a cache for mails sent by a guildmate, until the mail actually arrives in the real mailbox (1h delay)
|
|
['*'] = {
|
|
icon = nil,
|
|
link = nil,
|
|
count = nil,
|
|
money = nil,
|
|
lastCheck = 0, -- last time "THIS" mail was checked (can be different than that of the mailbox)
|
|
text = nil,
|
|
subject = nil,
|
|
sender = nil,
|
|
daysLeft = 0,
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
-- *** Utility functions ***
|
|
local function GetIDFromLink(link)
|
|
return tonumber(link:match("item:(%d+)"))
|
|
end
|
|
|
|
local function GetOption(option)
|
|
return addon.db.global.Options[option]
|
|
end
|
|
|
|
local function GetMailTable(character, index)
|
|
-- depending on the index passed, returns the right mail entry either from the "Mails" table or the "MailCache" table
|
|
-- The assumption is that the MailCache entries come after the Mails entries
|
|
-- This function is pure utility, and is not made public to client addons
|
|
|
|
if index <= #character.Mails then
|
|
return character.Mails[index]
|
|
else
|
|
index = index - #character.Mails
|
|
return character.MailCache[index]
|
|
end
|
|
end
|
|
|
|
local function GuildWhisper(player, messageType, ...)
|
|
if DataStore:IsGuildMemberOnline(player) then
|
|
local serializedData = addon:Serialize(messageType, ...)
|
|
addon:SendCommMessage(commPrefix, serializedData, "WHISPER", player)
|
|
end
|
|
end
|
|
|
|
local function ReadMailAttachments(mailIndex)
|
|
-- reads the attachments of a mail that is about to be sent or returned
|
|
|
|
wipe(addon.Attachments)
|
|
local name, icon, count, link
|
|
|
|
for attachmentIndex = 1, 12 do
|
|
if mailIndex then -- returned mail
|
|
name, icon, count = GetInboxItem(mailIndex, attachmentIndex)
|
|
link = GetInboxItemLink(mailIndex, attachmentIndex)
|
|
else -- if there is no index, it's a sent mail
|
|
name, icon, count = GetSendMailItem(attachmentIndex)
|
|
link = GetSendMailItemLink(attachmentIndex)
|
|
end
|
|
|
|
if name then -- if attachment slot is not empty .. save it
|
|
table.insert(addon.Attachments, { ["icon"] = icon, ["link"] = link, ["count"] = count } )
|
|
end
|
|
end
|
|
end
|
|
|
|
local function SendGuildMail(recipient, subject, body)
|
|
local player = DataStore:GetNameOfMain(recipient)
|
|
if not player then return end
|
|
|
|
-- this mail is sent to "player", but is for alt "recipient"
|
|
GuildWhisper(player, MSG_SENDMAIL_INIT, recipient)
|
|
if type(addon.Attachments) == "table" then
|
|
for _, attachment in pairs(addon.Attachments) do
|
|
GuildWhisper(player, MSG_SENDMAIL_ATTACHMENT, attachment.icon, attachment.link, attachment.count)
|
|
end
|
|
end
|
|
|
|
-- .. then save the mail itself + gold if any
|
|
local money = GetSendMailMoney()
|
|
if (money > 0) or (strlen(body) > 0) then
|
|
GuildWhisper(player, MSG_SENDMAIL_BODY, subject, body, money)
|
|
end
|
|
GuildWhisper(player, MSG_SENDMAIL_END)
|
|
end
|
|
|
|
-- *** Scanning functions ***
|
|
local function SaveAttachments(character, index, mailSender, days, wasReturned)
|
|
-- saves attachments of a given mail index into a given character mailbox
|
|
|
|
for attachmentIndex = 1, 12 do -- mandatory, loop through all 12 slots, since attachments could be anywhere (ex: slot 4,5,8)
|
|
local item, mailIcon, itemCount = GetInboxItem(index, attachmentIndex)
|
|
if item then
|
|
table.insert(character.Mails, {
|
|
icon = mailIcon,
|
|
count = itemCount,
|
|
link = GetInboxItemLink(index, attachmentIndex),
|
|
sender = mailSender,
|
|
lastCheck = time(),
|
|
daysLeft = days,
|
|
returned = wasReturned,
|
|
} )
|
|
end
|
|
end
|
|
end
|
|
|
|
local function ScanMailbox()
|
|
local character = addon.ThisCharacter
|
|
wipe(character.Mails)
|
|
|
|
local numItems = GetInboxNumItems();
|
|
if numItems == 0 then
|
|
return
|
|
end
|
|
|
|
local cache = character.MailCache
|
|
-- check the cache, and clean entries that are about to be replaced in the scan
|
|
for i = #cache, 1, -1 do
|
|
if cache[i].lastCheck then
|
|
local age = time() - cache[i].lastCheck
|
|
|
|
if age > 3600 then -- if older than 1 hour, delete this entry
|
|
table.remove(cache, i)
|
|
end
|
|
end
|
|
end
|
|
|
|
for i = 1, numItems do
|
|
local _, stationaryIcon, mailSender, mailSubject, mailMoney, _, days, numAttachments, _, wasReturned = GetInboxHeaderInfo(i);
|
|
if numAttachments then -- treat attachments as separate entries
|
|
SaveAttachments(character, i, mailSender, days, wasReturned)
|
|
end
|
|
|
|
local inboxText
|
|
if GetOption("ScanMailBody") == 1 then
|
|
inboxText = GetInboxText(i) -- this marks the mail as read
|
|
end
|
|
|
|
if (mailMoney > 0) or inboxText then -- if there's money or text .. save the entry
|
|
local mailIcon
|
|
if mailMoney > 0 then
|
|
mailIcon = ICON_COIN
|
|
else
|
|
mailIcon = stationaryIcon
|
|
end
|
|
table.insert(character.Mails, {
|
|
icon = mailIcon,
|
|
money = mailMoney,
|
|
text = inboxText,
|
|
subject = mailSubject,
|
|
sender = mailSender,
|
|
lastCheck = time(),
|
|
daysLeft = days,
|
|
returned = wasReturned,
|
|
} )
|
|
end
|
|
end
|
|
|
|
-- show mails with the lowest expiry first
|
|
table.sort(character.Mails, function(a, b) return a.daysLeft < b.daysLeft end)
|
|
end
|
|
|
|
|
|
-- *** Event Handlers ***
|
|
-- local function OnBagUpdate(event, bag)
|
|
local function OnBagUpdate(arg)
|
|
local bag = arg
|
|
|
|
FCSP_timer_OnBagUpdate = nil -- manual reset (safety redundancy)
|
|
|
|
if addon.isOpen then -- if a bag is updated while the mailbox is opened, this means an attachment has been taken.
|
|
-- print("DataStore_Mails.lua -- OnBagUpdate(event, ",bag,")", DEBUG_CNT, format("%.3f",GetTime()%100)) -- DEBUG 2025 07 21 - 2
|
|
|
|
ScanMailbox() -- I could not hook TakeInboxItem because mailbox content is not updated yet
|
|
end
|
|
end
|
|
|
|
local function FCSP_OnBagUpdate(event, bag)
|
|
-- this function limits calls to "OnBagUpdate" to max 1 every second
|
|
|
|
if bag < 0 then
|
|
return
|
|
end
|
|
|
|
if addon.isOpen then -- if a bag is updated while the mailbox is opened, this means an attachment has been taken.
|
|
if FCSP_timer_OnBagUpdate then return end
|
|
-- FCSP_timer_OnBagUpdate = addon:ScheduleTimer(OnBagUpdate, 1, event, bag)
|
|
FCSP_timer_OnBagUpdate = addon:ScheduleTimer(OnBagUpdate, 1, bag)
|
|
end
|
|
end
|
|
|
|
local function OnMailInboxUpdate()
|
|
-- process only one occurence of the event, right after MAIL_SHOW
|
|
addon:UnregisterEvent("MAIL_INBOX_UPDATE")
|
|
ScanMailbox()
|
|
end
|
|
|
|
local function OnMailSendInfoUpdate()
|
|
ReadMailAttachments()
|
|
end
|
|
|
|
local function OnMailClosed()
|
|
addon.isOpen = nil
|
|
addon:UnregisterEvent("MAIL_CLOSED")
|
|
ScanMailbox()
|
|
|
|
local character = addon.ThisCharacter
|
|
character.lastUpdate = time()
|
|
character.lastVisitDate = date("%Y/%m/%d %H:%M")
|
|
|
|
addon:UnregisterEvent("MAIL_SEND_INFO_UPDATE")
|
|
wipe(addon.Attachments)
|
|
end
|
|
|
|
local function OnMailShow()
|
|
-- the event may be triggered multiple times, exit if the mailbox is already open
|
|
if addon.isOpen then return end
|
|
|
|
CheckInbox()
|
|
addon:RegisterEvent("MAIL_CLOSED", OnMailClosed)
|
|
addon:RegisterEvent("MAIL_INBOX_UPDATE", OnMailInboxUpdate)
|
|
addon:RegisterEvent("MAIL_SEND_INFO_UPDATE", OnMailSendInfoUpdate)
|
|
|
|
-- create a temporary table to hold the attachments that will be sent, keep it local since the event is rare
|
|
addon.Attachments = addon.Attachments or {}
|
|
addon.isOpen = true
|
|
end
|
|
|
|
-- ** Mixins **
|
|
local function _GetMailboxLastVisit(character)
|
|
return character.lastUpdate or 0
|
|
end
|
|
|
|
local function _GetMailItemCount(character, searchedID)
|
|
local count = 0
|
|
for _, v in pairs (character.Mails) do
|
|
local link = v.link
|
|
if link and (GetIDFromLink(link) == searchedID) then
|
|
count = count + (v.count or 1)
|
|
end
|
|
end
|
|
|
|
for _, v in pairs (character.MailCache) do
|
|
local link = v.link
|
|
if link and (GetIDFromLink(link) == searchedID) then
|
|
count = count + (v.count or 1)
|
|
end
|
|
end
|
|
return count
|
|
end
|
|
|
|
local function _GetMailAttachments()
|
|
return addon.Attachments
|
|
end
|
|
|
|
local function _GetNumMails(character)
|
|
return #character.Mails + #character.MailCache
|
|
end
|
|
|
|
local function _GetMailInfo(character, index)
|
|
local data = GetMailTable(character, index)
|
|
return data.icon, data.count, data.link, data.money, data.text, data.returned
|
|
end
|
|
|
|
local function _GetMailSender(character, index)
|
|
local data = GetMailTable(character, index)
|
|
return data.sender
|
|
end
|
|
|
|
local function _GetMailExpiry(character, index)
|
|
local data = GetMailTable(character, index)
|
|
|
|
-- return the mail expiry, expressed in days and in seconds
|
|
local diff = time() - data.lastCheck
|
|
local days = data.daysLeft - (diff / 86400)
|
|
local seconds = (data.daysLeft * 86400) - diff
|
|
|
|
return days, seconds
|
|
end
|
|
|
|
local function _GetMailSubject(character, index)
|
|
local data = GetMailTable(character, index)
|
|
|
|
if data.subject then -- if there's a subject, use it
|
|
return data.subject
|
|
end
|
|
-- otherwise, return the name of the item
|
|
|
|
local name
|
|
local link = data.link
|
|
if link then
|
|
local id = GetIDFromLink(link)
|
|
name = GetItemInfo(id)
|
|
end
|
|
return name
|
|
end
|
|
|
|
local function _GetNumExpiredMails(character, threshold)
|
|
local count = 0
|
|
for i = 1, _GetNumMails(character) do
|
|
if _GetMailExpiry(character, i) < threshold then
|
|
count = count + 1
|
|
end
|
|
end
|
|
return count
|
|
end
|
|
|
|
local function _SaveMailToCache(character, mailMoney, mailBody, mailSubject, mailSender)
|
|
local mailIcon = (mailMoney > 0) and ICON_COIN or ICON_NOTE
|
|
|
|
table.insert(character.MailCache, {
|
|
money = mailMoney,
|
|
icon = mailIcon,
|
|
text = mailBody,
|
|
subject = mailSubject,
|
|
sender = mailSender,
|
|
lastCheck = time(),
|
|
daysLeft = MAIL_EXPIRY,
|
|
} )
|
|
end
|
|
|
|
local function _SaveMailAttachmentToCache(character, mailIcon, mailLink, mailCount, mailSender)
|
|
table.insert(character.MailCache, {
|
|
icon = mailIcon,
|
|
link = mailLink,
|
|
count = mailCount,
|
|
sender = mailSender,
|
|
lastCheck = time(),
|
|
daysLeft = MAIL_EXPIRY,
|
|
} )
|
|
end
|
|
|
|
local function _IsMailBoxOpen()
|
|
return addon.isOpen
|
|
end
|
|
|
|
local PublicMethods = {
|
|
GetMailboxLastVisit = _GetMailboxLastVisit,
|
|
GetMailItemCount = _GetMailItemCount,
|
|
GetMailAttachments = _GetMailAttachments,
|
|
GetNumMails = _GetNumMails,
|
|
GetMailInfo = _GetMailInfo,
|
|
GetMailSender = _GetMailSender,
|
|
GetMailExpiry = _GetMailExpiry,
|
|
GetMailSubject = _GetMailSubject,
|
|
GetNumExpiredMails = _GetNumExpiredMails,
|
|
SaveMailToCache = _SaveMailToCache,
|
|
SaveMailAttachmentToCache = _SaveMailAttachmentToCache,
|
|
IsMailBoxOpen = _IsMailBoxOpen,
|
|
}
|
|
|
|
-- *** Guild Comm ***
|
|
local guildMailRecipient -- name of the alt who receives a mail from a guildmate
|
|
local guildMailRecipientKey -- key of the alt who receives a mail from a guildmate
|
|
|
|
local GuildCommCallbacks = {
|
|
[MSG_SENDMAIL_INIT] = function(sender, recipient)
|
|
guildMailRecipient = recipient
|
|
guildMailRecipientKey = format("%s.%s.%s", THIS_ACCOUNT, GetRealmName(), recipient)
|
|
end,
|
|
[MSG_SENDMAIL_END] = function(sender)
|
|
if guildMailRecipient then
|
|
addon:SendMessage("DATASTORE_GUILD_MAIL_RECEIVED", sender, guildMailRecipient)
|
|
end
|
|
guildMailRecipient = nil
|
|
guildMailRecipientKey = nil
|
|
end,
|
|
[MSG_SENDMAIL_ATTACHMENT] = function(sender, icon, link, count)
|
|
local recipientTable = addon.db.global.Characters[guildMailRecipientKey]
|
|
if recipientTable then
|
|
_SaveMailAttachmentToCache(recipientTable, icon, link, count, sender)
|
|
end
|
|
end,
|
|
[MSG_SENDMAIL_BODY] = function(sender, subject, body, money)
|
|
local recipientTable = addon.db.global.Characters[guildMailRecipientKey]
|
|
if recipientTable then
|
|
_SaveMailToCache(recipientTable, money, body, subject, sender)
|
|
end
|
|
end,
|
|
}
|
|
|
|
local function CheckExpiries()
|
|
local allAccounts = GetOption("CheckMailExpiryAllAccounts")
|
|
local allRealms = GetOption("CheckMailExpiryAllRealms")
|
|
local threshold = GetOption("MailWarningThreshold")
|
|
local expiryFound
|
|
|
|
local account, realm
|
|
for key, character in pairs(addon.db.global.Characters) do
|
|
account, realm = strsplit(".", key)
|
|
|
|
if allAccounts == 1 or ((allAccounts == 0) and (account == THIS_ACCOUNT)) then -- all accounts, or only current and current was found
|
|
if allRealms == 1 or ((allRealms == 0) and (realm == GetRealmName())) then -- all realms, or only current and current was found
|
|
|
|
-- detect return vs delete
|
|
local numExpiredMails = _GetNumExpiredMails(character, threshold)
|
|
if numExpiredMails > 0 then
|
|
expiryFound = true
|
|
addon:SendMessage("DATASTORE_MAIL_EXPIRY", character, key, threshold, numExpiredMails)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if expiryFound then
|
|
-- global expiry message, register this one if your addon just wants to know that at least one mail has expired, and you don't care which.
|
|
addon:SendMessage("DATASTORE_GLOBAL_MAIL_EXPIRY", threshold)
|
|
end
|
|
end
|
|
|
|
function addon:OnInitialize()
|
|
addon.db = LibStub("AceDB-3.0"):New(addonName .. "DB", AddonDB_Defaults)
|
|
|
|
DataStore:RegisterModule(addonName, addon, PublicMethods)
|
|
DataStore:SetGuildCommCallbacks(commPrefix, GuildCommCallbacks)
|
|
|
|
DataStore:SetCharacterBasedMethod("GetMailboxLastVisit")
|
|
DataStore:SetCharacterBasedMethod("GetMailItemCount")
|
|
DataStore:SetCharacterBasedMethod("GetNumMails")
|
|
DataStore:SetCharacterBasedMethod("GetMailInfo")
|
|
DataStore:SetCharacterBasedMethod("GetMailSender")
|
|
DataStore:SetCharacterBasedMethod("GetMailExpiry")
|
|
DataStore:SetCharacterBasedMethod("GetMailSubject")
|
|
DataStore:SetCharacterBasedMethod("GetNumExpiredMails")
|
|
DataStore:SetCharacterBasedMethod("SaveMailToCache")
|
|
DataStore:SetCharacterBasedMethod("SaveMailAttachmentToCache")
|
|
|
|
addon:RegisterComm(commPrefix, DataStore:GetGuildCommHandler())
|
|
end
|
|
|
|
function addon:OnEnable()
|
|
addon:RegisterEvent("MAIL_SHOW", OnMailShow)
|
|
-- addon:RegisterEvent("BAG_UPDATE", OnBagUpdate)
|
|
addon:RegisterEvent("BAG_UPDATE", FCSP_OnBagUpdate)
|
|
|
|
addon:SetupOptions()
|
|
if GetOption("CheckMailExpiry") == 1 then
|
|
addon:ScheduleTimer(CheckExpiries, 5) -- check mail expiries 5 seconds later, to decrease the load at startup
|
|
end
|
|
end
|
|
|
|
function addon:OnDisable()
|
|
addon:UnregisterEvent("MAIL_SHOW")
|
|
addon:UnregisterEvent("BAG_UPDATE")
|
|
end
|
|
|
|
|
|
-- *** Hooks ***
|
|
|
|
local Orig_SendMail = SendMail
|
|
|
|
function SendMail(recipient, subject, body, ...)
|
|
-- this function takes care of saving mails sent to alts directly into their mailbox, so that client addons don't have to take care about it
|
|
local isRecipientAnAlt
|
|
|
|
for characterName, characterKey in pairs(DataStore:GetCharacters()) do -- browse alts on current realm
|
|
if strlower(characterName) == strlower(recipient) then -- if recipient is a known alt ..
|
|
local character = addon.db.global.Characters[characterKey]
|
|
|
|
for k, v in pairs(addon.Attachments) do -- .. save attachments into his mailbox
|
|
table.insert(character.Mails, { -- not in the mail cache, since they arrive directly in an alt's mailbox
|
|
icon = v.icon,
|
|
link = v.link,
|
|
count = v.count,
|
|
sender = UnitName("player"),
|
|
lastCheck = time(),
|
|
daysLeft = MAIL_EXPIRY,
|
|
} )
|
|
end
|
|
|
|
-- .. then save the mail itself + gold if any
|
|
local moneySent = GetSendMailMoney()
|
|
if (moneySent > 0) or (strlen(body) > 0) then
|
|
local mailIcon
|
|
if moneySent > 0 then
|
|
mailIcon = ICON_COIN
|
|
else
|
|
mailIcon = ICON_NOTE
|
|
end
|
|
table.insert(character.Mails, {
|
|
money = moneySent,
|
|
icon = mailIcon,
|
|
text = body,
|
|
subject = subject,
|
|
sender = UnitName("player"),
|
|
lastCheck = time(),
|
|
daysLeft = MAIL_EXPIRY,
|
|
} )
|
|
end
|
|
|
|
-- if the alt has never checked his mail before, this value won't be correct, so set it to make sure expiry returns proper results.
|
|
character.lastUpdate = time()
|
|
|
|
table.sort(character.Mails, function(a, b) -- show mails with the lowest expiry first
|
|
return a.daysLeft < b.daysLeft
|
|
end)
|
|
|
|
isRecipientAnAlt = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if not isRecipientAnAlt then -- if recipient is not an alt, maybe it's a guildmate
|
|
SendGuildMail(recipient, subject, body)
|
|
end
|
|
|
|
Orig_SendMail(recipient, subject, body, ...)
|
|
end
|
|
|
|
local Orig_ReturnInboxItem = ReturnInboxItem
|
|
|
|
function ReturnInboxItem(index, ...)
|
|
local _, stationaryIcon, mailSender, mailSubject, mailMoney, _, _, numAttachments = GetInboxHeaderInfo(index)
|
|
local isRecipientAnAlt
|
|
|
|
local inboxText = ""
|
|
|
|
for characterName, characterKey in pairs(DataStore:GetCharacters()) do -- browse alts on current realm
|
|
if strlower(characterName) == strlower(mailSender) then -- if recipient is a known alt ..
|
|
local character = addon.db.global.Characters[characterKey]
|
|
|
|
if numAttachments then -- treat attachments as separate entries
|
|
SaveAttachments(character, index, UnitName("player"), MAIL_EXPIRY, true)
|
|
end
|
|
|
|
inboxText = GetInboxText(index) -- this marks the mail as read, no problem here since the mail is returned anyway
|
|
|
|
if (mailMoney > 0) or inboxText then -- if there's money or text .. save the entry
|
|
local mailIcon
|
|
if mailMoney > 0 then
|
|
mailIcon = ICON_COIN
|
|
else
|
|
mailIcon = stationaryIcon
|
|
end
|
|
table.insert(character.Mails, {
|
|
icon = mailIcon,
|
|
money = mailMoney,
|
|
text = inboxText,
|
|
subject = mailSubject,
|
|
sender = UnitName("player"),
|
|
lastCheck = time(),
|
|
daysLeft = MAIL_EXPIRY,
|
|
returned = true, -- this is the mail we're returning, so true
|
|
} )
|
|
end
|
|
|
|
isRecipientAnAlt = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if not isRecipientAnAlt then -- if recipient is not an alt, maybe it's a guildmate
|
|
ReadMailAttachments(index)
|
|
SendGuildMail(mailSender, mailSubject, inboxText)
|
|
end
|
|
|
|
Orig_ReturnInboxItem(index, ...)
|
|
end
|