Retail version r90 (06 Jul 2010)
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
------------------------------------------------------------------------
|
||||
r16 | pompachomp | 2010-02-19 18:56:35 +0000 (Fri, 19 Feb 2010) | 3 lines
|
||||
Changed paths:
|
||||
M /trunk/DataStore_Mails.toc
|
||||
A /trunk/Locales (from /trunk/Locals:15)
|
||||
D /trunk/Locals
|
||||
D /trunk/local.xml
|
||||
A /trunk/locale.xml (from /trunk/local.xml:15)
|
||||
|
||||
Locals->Locales
|
||||
local.xml->locale.xml
|
||||
|
||||
------------------------------------------------------------------------
|
||||
r15 | thaoky | 2010-02-15 18:10:07 +0000 (Mon, 15 Feb 2010) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/DataStore_Mails.lua
|
||||
|
||||
Slightly modified CheckExpiries()
|
||||
------------------------------------------------------------------------
|
||||
r14 | thaoky | 2009-12-09 12:34:54 +0000 (Wed, 09 Dec 2009) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/DataStore_Mails.toc
|
||||
|
||||
ToC Update
|
||||
------------------------------------------------------------------------
|
||||
@@ -0,0 +1,590 @@
|
||||
--[[ *** 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
|
||||
|
||||
-- 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)
|
||||
if addon.isOpen then -- if a bag is updated while the mailbox is opened, this means an attachment has been taken.
|
||||
ScanMailbox() -- I could not hook TakeInboxItem because mailbox content is not updated yet
|
||||
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: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
|
||||
@@ -0,0 +1,19 @@
|
||||
## Interface: 30300
|
||||
## Title: DataStore_Mails
|
||||
## Notes: Stores information about character mails
|
||||
## Author: Thaoky (EU-Marécages de Zangar)
|
||||
## Version: 3.3.001
|
||||
## Dependencies: DataStore
|
||||
## OptionalDeps: Ace3
|
||||
## SavedVariables: DataStore_MailsDB
|
||||
## X-Category: Interface Enhancements
|
||||
## X-Embeds: Ace3
|
||||
## X-Curse-Packaged-Version: r16
|
||||
## X-Curse-Project-Name: DataStore_Mails
|
||||
## X-Curse-Project-ID: datastore_mails
|
||||
## X-Curse-Repository-ID: wow/datastore_mails/mainline
|
||||
|
||||
locale.xml
|
||||
|
||||
DataStore_Mails.lua
|
||||
Options.xml
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
All Rights Reserved unless otherwise explicitly stated.
|
||||
@@ -0,0 +1,8 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale( "DataStore_Mails", "deDE" )
|
||||
|
||||
if not L then return end
|
||||
|
||||
L["Mail Expiry Warning"] = "Mail Ablauf Warnung"
|
||||
L["Scan mail body (marks it as read)"] = "Inhalt der Briefe scannen (markiert als gelesen)"
|
||||
L["Warn when mail expires in less days than this value"] = "Warnen, wenn Post abläuft in weniger Tagen als"
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
local debug = false
|
||||
--[===[@debug@
|
||||
debug = true
|
||||
--@end-debug@]===]
|
||||
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale("DataStore_Mails", "enUS", true, debug)
|
||||
|
||||
L["Check mail expiries on all known accounts"] = true
|
||||
L["Check mail expiries on all known realms"] = true
|
||||
L["EXPIRY_ALL_ACCOUNTS_DISABLED"] = "Only the current account will be taken into consideration; imported accounts will be ignored."
|
||||
L["EXPIRY_ALL_ACCOUNTS_ENABLED"] = "The expiry check routine will look for expired mails on all known accounts."
|
||||
L["EXPIRY_ALL_ACCOUNTS_TITLE"] = "Check All Accounts"
|
||||
L["EXPIRY_ALL_REALMS_DISABLED"] = "Only the current realm will be taken into consideration; other realms will be ignored."
|
||||
L["EXPIRY_ALL_REALMS_ENABLED"] = "The expiry check routine will look for expired mails on all known realms."
|
||||
L["EXPIRY_ALL_REALMS_TITLE"] = "Check All Realms"
|
||||
L["EXPIRY_CHECK_DISABLED"] = "No expiry check will be performed."
|
||||
L["EXPIRY_CHECK_ENABLED"] = "Mail expiries will be checked 5 seconds after logon. Client add-ons will get a notification if at least one expired mail is found."
|
||||
L["EXPIRY_CHECK_TITLE"] = "Check Mail Expiries"
|
||||
L["Mail Expiry Warning"] = true
|
||||
L["SCAN_MAIL_BODY_DISABLED"] = "Only mail attachments will be read. Mails will keep their unread status."
|
||||
L["SCAN_MAIL_BODY_ENABLED"] = "The body of each mail will be read when the mailbox is scanned. All mails will be marked as read."
|
||||
L["Scan mail body (marks it as read)"] = true
|
||||
L["SCAN_MAIL_BODY_TITLE"] = "Scan Mail Body"
|
||||
L["Warn when mail expires in less days than this value"] = true
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale( "DataStore_Mails", "esES" )
|
||||
|
||||
if not L then return end
|
||||
|
||||
L["Check mail expiries on all known accounts"] = "Revisar todos los tiempos de borrado de correo en todas las cuentas conocidas"
|
||||
L["Check mail expiries on all known realms"] = "Revisar todos los tiempos de borrado de correo en todas los reinos conocidos"
|
||||
L["EXPIRY_ALL_ACCOUNTS_DISABLED"] = "Sólo la cuenta actual será tomada en consideración; cuentas importadas serán ignoradas."
|
||||
L["EXPIRY_ALL_ACCOUNTS_ENABLED"] = "La revisión de los tiempos de borrado de correo mirará todas las cuentas conocidas."
|
||||
L["EXPIRY_ALL_ACCOUNTS_TITLE"] = "Revisión de Todas las Cuentas"
|
||||
L["EXPIRY_ALL_REALMS_DISABLED"] = "Sólo el reino actual será tomado en consideración; otros reinos serán ignorados."
|
||||
L["EXPIRY_ALL_REALMS_ENABLED"] = "La revisión de los tiempos de borrado de correo mirará todas los reinos conocidos."
|
||||
L["EXPIRY_ALL_REALMS_TITLE"] = "Revisión de Todos los Reinos"
|
||||
L["EXPIRY_CHECK_DISABLED"] = "No se realizará una revisón de tiempos de borrado."
|
||||
L["EXPIRY_CHECK_ENABLED"] = "Los tiempos de borrado de correo serán revisados 5 segundos después de iniciar sesión. Accesorios que use DataStore serán notificados si un correo a punto de borrarse es encontrado."
|
||||
L["EXPIRY_CHECK_TITLE"] = "Revisar Tiempos de Borrado de Correo"
|
||||
L["Mail Expiry Warning"] = "Advertencia de Borrado de Correo"
|
||||
L["SCAN_MAIL_BODY_DISABLED"] = "Sólo correos leídos serán escaneados. Los correos seguirán teniendo el estado de no leídos."
|
||||
L["SCAN_MAIL_BODY_ENABLED"] = "Los correos serán completamente escaneados al abrir el buzón. Todos los correos serán marcados como leídos."
|
||||
L["Scan mail body (marks it as read)"] = "Escanear el contenido de los correos (marcarlos como leídos)"
|
||||
L["SCAN_MAIL_BODY_TITLE"] = "Escaneo Completo del Correo"
|
||||
L["Warn when mail expires in less days than this value"] = "Avisar cuando el correo sea borrado en menos días que los indicados"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale( "DataStore_Mails", "esMX" )
|
||||
|
||||
if not L then return end
|
||||
|
||||
L["Mail Expiry Warning"] = "Advertencia de expiración del correo"
|
||||
L["Scan mail body (marks it as read)"] = "Analizar el contenido de los correos (marcarlos como leídos)"
|
||||
L["Warn when mail expires in less days than this value"] = "Advertir cuando el correo expira en menos días que los indicados"
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale( "DataStore_Mails", "frFR" )
|
||||
|
||||
if not L then return end
|
||||
|
||||
L["Check mail expiries on all known accounts"] = "Vérifier les expirations sur tous les comptes connus"
|
||||
L["Check mail expiries on all known realms"] = "Vérifier les expirations sur tous les royaumes connus"
|
||||
L["EXPIRY_ALL_ACCOUNTS_DISABLED"] = "Seul le compte en cours d'utilisation sera pris en considération; les comptes importés seront ignorés."
|
||||
L["EXPIRY_ALL_ACCOUNTS_ENABLED"] = "La routine de vérification recherchera les courriers expirés sur tous les comptes connus."
|
||||
L["EXPIRY_ALL_ACCOUNTS_TITLE"] = "Vérifier tous les comptes"
|
||||
L["EXPIRY_ALL_REALMS_DISABLED"] = "Seul le royaume en cours d'utilisation sera pris en considération; les autres royaumes seront ignorés."
|
||||
L["EXPIRY_ALL_REALMS_ENABLED"] = "La routine de vérification recherchera les courriers expirés sur tous les royaumes connus."
|
||||
L["EXPIRY_ALL_REALMS_TITLE"] = "Vérifier tous les royaumes"
|
||||
L["EXPIRY_CHECK_DISABLED"] = "Aucune vérification ne sera effectuée."
|
||||
L["EXPIRY_CHECK_ENABLED"] = "Les expirations de courrier seront vérifiées 5 secondes après le login. Les add-ons client en seront informé si au moins un courrier expiré est trouvé."
|
||||
L["EXPIRY_CHECK_TITLE"] = "Vérifier les expirations de courrier"
|
||||
L["Mail Expiry Warning"] = "Avertis. d'expiration du courrier"
|
||||
L["SCAN_MAIL_BODY_DISABLED"] = "Seules les pièces jointes seront lues. Les lettres garderont leur statut 'non-lu'."
|
||||
L["SCAN_MAIL_BODY_ENABLED"] = "Le corps de chaque lettre sera lu durant le scan de la boîte aux lettres. Tous les courriers seront marqués comme lus."
|
||||
L["Scan mail body (marks it as read)"] = "Lire le courrier (le marque comme lu)"
|
||||
L["SCAN_MAIL_BODY_TITLE"] = "Lire le corps du courrier"
|
||||
L["Warn when mail expires in less days than this value"] = "Avertir quand du courrier arrive à expiration dans moins de jours que cette valeur"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale( "DataStore_Mails", "koKR" )
|
||||
|
||||
if not L then return end
|
||||
|
||||
L["Mail Expiry Warning"] = "우편 소멸 경고"
|
||||
L["Scan mail body (marks it as read)"] = "우편물 내용을 검색 (읽은 것으로 표시됨)"
|
||||
L["Warn when mail expires in less days than this value"] = "우편물의 소멸 날짜가 이 값보다 더 적으면 경고"
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale("DataStore_Mails", "enUS", true, true)
|
||||
|
||||
if not L then return end
|
||||
|
||||
L["Warn when mail expires in less days than this value"] = true
|
||||
L["Mail Expiry Warning"] = true
|
||||
L["Scan mail body (marks it as read)"] = true
|
||||
L["Check mail expiries on all known accounts"] = true
|
||||
L["Check mail expiries on all known realms"] = true
|
||||
L["EXPIRY_CHECK_TITLE"] = "Check Mail Expiries"
|
||||
L["EXPIRY_CHECK_ENABLED"] = "Mail expiries will be checked 5 seconds after logon. Client add-ons will get a notification if at least one expired mail is found."
|
||||
L["EXPIRY_CHECK_DISABLED"] = "No expiry check will be performed."
|
||||
L["SCAN_MAIL_BODY_TITLE"] = "Scan Mail Body"
|
||||
L["SCAN_MAIL_BODY_ENABLED"] = "The body of each mail will be read when the mailbox is scanned. All mails will be marked as read."
|
||||
L["SCAN_MAIL_BODY_DISABLED"] = "Only mail attachments will be read. Mails will keep their unread status."
|
||||
L["EXPIRY_ALL_ACCOUNTS_TITLE"] = "Check All Accounts"
|
||||
L["EXPIRY_ALL_ACCOUNTS_ENABLED"] = "The expiry check routine will look for expired mails on all known accounts."
|
||||
L["EXPIRY_ALL_ACCOUNTS_DISABLED"] = "Only the current account will be taken into consideration; imported accounts will be ignored."
|
||||
L["EXPIRY_ALL_REALMS_TITLE"] = "Check All Realms"
|
||||
L["EXPIRY_ALL_REALMS_ENABLED"] = "The expiry check routine will look for expired mails on all known realms."
|
||||
L["EXPIRY_ALL_REALMS_DISABLED"] = "Only the current realm will be taken into consideration; other realms will be ignored."
|
||||
@@ -0,0 +1,8 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale( "DataStore_Mails", "ruRU" )
|
||||
|
||||
if not L then return end
|
||||
|
||||
L["Mail Expiry Warning"] = "Сообщать об истечении срока хранения почты"
|
||||
L["Scan mail body (marks it as read)"] = "Просматривать почту (отмечает как прочитаную)"
|
||||
L["Warn when mail expires in less days than this value"] = "Извещать о истечении срока хранения почты. Указанное значение измеряется в днях."
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale( "DataStore_Mails", "zhCN" )
|
||||
|
||||
if not L then return end
|
||||
|
||||
L["Mail Expiry Warning"] = "邮件过期警告"
|
||||
L["Scan mail body (marks it as read)"] = "扫描邮件内容(标记为已读)"
|
||||
L["Warn when mail expires in less days than this value"] = "在邮件过期前多少天进行警告"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
local L = LibStub("AceLocale-3.0"):NewLocale( "DataStore_Mails", "zhTW" )
|
||||
|
||||
if not L then return end
|
||||
|
||||
L["Mail Expiry Warning"] = "郵件屆滿警告"
|
||||
L["Scan mail body (marks it as read)"] = "掃描郵件內容 (標記為己讀取)"
|
||||
L["Warn when mail expires in less days than this value"] = "當郵件屆滿少過此值的日數時發出警告"
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
if not DataStore then return end
|
||||
|
||||
local addonName = "DataStore_Mails"
|
||||
local addon = _G[addonName]
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale(addonName)
|
||||
|
||||
function addon:SetupOptions()
|
||||
DataStore:AddOptionCategory(DataStoreMailOptions, addonName, "DataStore")
|
||||
|
||||
-- localize options
|
||||
DataStoreMailOptions_SliderMailExpiry.tooltipText = L["Warn when mail expires in less days than this value"];
|
||||
DataStoreMailOptions_SliderMailExpiryLow:SetText("1");
|
||||
DataStoreMailOptions_SliderMailExpiryHigh:SetText("15");
|
||||
DataStoreMailOptions_CheckMailExpiryText:SetText(L["Mail Expiry Warning"])
|
||||
DataStoreMailOptions_ScanMailBodyText:SetText(L["Scan mail body (marks it as read)"])
|
||||
DataStoreMailOptions_CheckMailExpiryAllAccountsText:SetText(L["Check mail expiries on all known accounts"])
|
||||
DataStoreMailOptions_CheckMailExpiryAllRealmsText:SetText(L["Check mail expiries on all known realms"])
|
||||
|
||||
DataStore:SetCheckBoxTooltip(DataStoreMailOptions_CheckMailExpiry, L["EXPIRY_CHECK_TITLE"], L["EXPIRY_CHECK_ENABLED"], L["EXPIRY_CHECK_DISABLED"])
|
||||
DataStore:SetCheckBoxTooltip(DataStoreMailOptions_ScanMailBody, L["SCAN_MAIL_BODY_TITLE"], L["SCAN_MAIL_BODY_ENABLED"], L["SCAN_MAIL_BODY_DISABLED"])
|
||||
DataStore:SetCheckBoxTooltip(DataStoreMailOptions_CheckMailExpiryAllAccounts, L["EXPIRY_ALL_ACCOUNTS_TITLE"], L["EXPIRY_ALL_ACCOUNTS_ENABLED"], L["EXPIRY_ALL_ACCOUNTS_DISABLED"])
|
||||
DataStore:SetCheckBoxTooltip(DataStoreMailOptions_CheckMailExpiryAllRealms, L["EXPIRY_ALL_REALMS_TITLE"], L["EXPIRY_ALL_REALMS_ENABLED"], L["EXPIRY_ALL_REALMS_DISABLED"])
|
||||
|
||||
-- restore saved options to gui
|
||||
DataStoreMailOptions_SliderMailExpiry:SetValue(DataStore:GetOption(addonName, "MailWarningThreshold"))
|
||||
DataStoreMailOptions_SliderMailExpiryText:SetText(format("%s (%s)", L["Mail Expiry Warning"], DataStoreMailOptions_SliderMailExpiry:GetValue()))
|
||||
DataStoreMailOptions_CheckMailExpiry:SetChecked(DataStore:GetOption(addonName, "CheckMailExpiry"))
|
||||
DataStoreMailOptions_ScanMailBody:SetChecked(DataStore:GetOption(addonName, "ScanMailBody"))
|
||||
DataStoreMailOptions_CheckMailExpiryAllAccounts:SetChecked(DataStore:GetOption(addonName, "CheckMailExpiryAllAccounts"))
|
||||
DataStoreMailOptions_CheckMailExpiryAllRealms:SetChecked(DataStore:GetOption(addonName, "CheckMailExpiryAllRealms"))
|
||||
end
|
||||
@@ -0,0 +1,102 @@
|
||||
<Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.blizzard.com/wow/ui/">
|
||||
<Script file="Options.lua"></Script>
|
||||
|
||||
<Frame name="DataStoreMailOptions" hidden="true">
|
||||
<Size>
|
||||
<AbsDimension x="615" y="306"/>
|
||||
</Size>
|
||||
<Frames>
|
||||
<Slider name="$parent_SliderMailExpiry" inherits="OptionsSliderTemplate" minValue="1" maxValue="15" defaultValue="5" valueStep="1">
|
||||
<Size>
|
||||
<AbsDimension x="180" y="16"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="40" y="-40" />
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnValueChanged>
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("DataStore_Mails")
|
||||
|
||||
local name = self:GetName()
|
||||
_G[name .. "Text"]:SetText(L["Mail Expiry Warning"] .. " (" .. self:GetValue() ..")");
|
||||
DataStore:SetOption("DataStore_Mails", "MailWarningThreshold", self:GetValue())
|
||||
</OnValueChanged>
|
||||
</Scripts>
|
||||
</Slider>
|
||||
|
||||
<CheckButton name="$parent_CheckMailExpiry" inherits="InterfaceOptionsSmallCheckButtonTemplate">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parent_SliderMailExpiry" relativePoint="BOTTOMLEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="-20"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
DataStore:ToggleOption(self, "DataStore_Mails", "CheckMailExpiry")
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</CheckButton>
|
||||
<CheckButton name="$parent_ScanMailBody" inherits="InterfaceOptionsSmallCheckButtonTemplate">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="$parent_CheckMailExpiry" relativePoint="BOTTOM" >
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="-10"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
DataStore:ToggleOption(self, "DataStore_Mails", "ScanMailBody")
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</CheckButton>
|
||||
<CheckButton name="$parent_CheckMailExpiryAllAccounts" inherits="InterfaceOptionsSmallCheckButtonTemplate">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="$parent_ScanMailBody" relativePoint="BOTTOM" >
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="-10"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
DataStore:ToggleOption(self, "DataStore_Mails", "CheckMailExpiryAllAccounts")
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</CheckButton>
|
||||
<CheckButton name="$parent_CheckMailExpiryAllRealms" inherits="InterfaceOptionsSmallCheckButtonTemplate">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativeTo="$parent_CheckMailExpiryAllAccounts" relativePoint="BOTTOM" >
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="-10"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
DataStore:ToggleOption(self, "DataStore_Mails", "CheckMailExpiryAllRealms")
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</CheckButton>
|
||||
</Frames>
|
||||
</Frame>
|
||||
|
||||
</Ui>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.blizzard.com/wow/ui/" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
|
||||
<Include file="Locales\deDE.lua"/>
|
||||
<Include file="Locales\enUS.lua"/>
|
||||
<Include file="Locales\esES.lua"/>
|
||||
<Include file="Locales\esMX.lua"/>
|
||||
<Include file="Locales\frFR.lua"/>
|
||||
<Include file="Locales\koKR.lua"/>
|
||||
<Include file="Locales\ruRU.lua"/>
|
||||
<Include file="Locales\zhCN.lua"/>
|
||||
<Include file="Locales\zhTW.lua"/>
|
||||
|
||||
</Ui>
|
||||
Reference in New Issue
Block a user