fix: mailbox item counter
This commit is contained in:
+8
-30
@@ -287,43 +287,21 @@ function DB:SaveMailbox(mailboxData)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Add a single mail entry to a character's mailbox
|
-- Add a single mail entry to a character's mailbox
|
||||||
|
-- These are predictions for outgoing mail/AH wins — they get replaced by a
|
||||||
|
-- full rescan (SaveMailbox) when the recipient opens their mailbox.
|
||||||
function DB:AddMailToCharacter(name, realm, mailRow)
|
function DB:AddMailToCharacter(name, realm, mailRow)
|
||||||
local fullName = name .. "-" .. (realm or playerRealm)
|
local fullName = name .. "-" .. (realm or playerRealm)
|
||||||
local char = Guda_DB.characters[fullName]
|
local char = Guda_DB.characters[fullName]
|
||||||
|
|
||||||
if char then
|
if char then
|
||||||
if not char.mailbox then
|
if not char.mailbox then
|
||||||
char.mailbox = {}
|
char.mailbox = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if this exact mail already exists (simplistic check)
|
table.insert(char.mailbox, 1, mailRow)
|
||||||
local exists = false
|
char.lastUpdate = time()
|
||||||
for _, m in ipairs(char.mailbox) do
|
addon:Debug("Added outgoing mail to %s's mailbox", fullName)
|
||||||
if m.sender == mailRow.sender and m.subject == mailRow.subject and m.money == mailRow.money then
|
return true
|
||||||
if (not m.item and not mailRow.item) or (m.item and mailRow.item and m.item.name == mailRow.item.name and m.item.count == mailRow.item.count) then
|
|
||||||
exists = true
|
|
||||||
-- Update link/itemID if missing in existing but present in new
|
|
||||||
if mailRow.item and m.item then
|
|
||||||
if not m.item.link and mailRow.item.link then
|
|
||||||
m.item.link = mailRow.item.link
|
|
||||||
addon:Debug("Updated link for existing mail item")
|
|
||||||
end
|
|
||||||
if not m.item.itemID and mailRow.item.itemID then
|
|
||||||
m.item.itemID = mailRow.item.itemID
|
|
||||||
addon:Debug("Updated itemID for existing mail item")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not exists then
|
|
||||||
table.insert(char.mailbox, 1, mailRow) -- Add to beginning
|
|
||||||
char.lastUpdate = time()
|
|
||||||
addon:Debug("Added outgoing mail to %s's mailbox", fullName)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ local function CountFromSavedMailbox(mailboxData, itemID)
|
|||||||
count = count + (item.count or 1)
|
count = count + (item.count or 1)
|
||||||
elseif not slotItemID and item.name then
|
elseif not slotItemID and item.name then
|
||||||
-- Fallback to name matching if link is missing
|
-- Fallback to name matching if link is missing
|
||||||
local targetName = GetItemInfo(itemID)
|
local targetName = GetItemInfo("item:" .. itemID .. ":0:0:0")
|
||||||
if targetName == item.name then
|
if targetName == item.name then
|
||||||
count = count + (item.count or 1)
|
count = count + (item.count or 1)
|
||||||
end
|
end
|
||||||
|
|||||||
+93
-52
@@ -151,60 +151,100 @@ function MailboxScanner:SaveToDatabase()
|
|||||||
addon:Debug("Mailbox data saved")
|
addon:Debug("Mailbox data saved")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Build item data from name/texture/count/quality
|
||||||
|
local function BuildSendMailItemData(name, texture, count, quality)
|
||||||
|
local _, link = GetItemInfo(name)
|
||||||
|
local itemData = {
|
||||||
|
name = name,
|
||||||
|
texture = texture or "Interface\\Icons\\INV_Misc_Bag_08",
|
||||||
|
count = count or 1,
|
||||||
|
quality = quality or 0,
|
||||||
|
link = link,
|
||||||
|
itemID = addon.Modules.Utils:ExtractItemID(link),
|
||||||
|
}
|
||||||
|
|
||||||
|
local itemName, retLink, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc = addon.Modules.Utils:GetItemInfo(name)
|
||||||
|
if itemName then
|
||||||
|
itemData.link = retLink or itemData.link
|
||||||
|
itemData.itemID = addon.Modules.Utils:ExtractItemID(itemData.link) or itemData.itemID
|
||||||
|
itemData.quality = itemQuality or itemData.quality
|
||||||
|
itemData.iLevel = iLevel
|
||||||
|
itemData.type = itemType
|
||||||
|
itemData.class = itemCategory
|
||||||
|
itemData.subclass = itemSubType
|
||||||
|
itemData.equipSlot = itemEquipLoc
|
||||||
|
if itemTexture then itemData.texture = itemTexture end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not itemData.itemID and itemData.link then
|
||||||
|
itemData.itemID = addon.Modules.Utils:ExtractItemID(itemData.link)
|
||||||
|
end
|
||||||
|
|
||||||
|
return itemData
|
||||||
|
end
|
||||||
|
|
||||||
-- Handle outgoing mail
|
-- Handle outgoing mail
|
||||||
function MailboxScanner:OnSendMail(recipient, subject, body)
|
function MailboxScanner:OnSendMail(recipient, subject, body)
|
||||||
if not recipient or recipient == "" then return end
|
if not recipient or recipient == "" then return end
|
||||||
|
|
||||||
-- In WoW 1.12.1, SendMail(recipient, subject, body) is the signature.
|
|
||||||
-- To get the attached item, we use GetSendMailItem().
|
|
||||||
-- GetSendMailItem() returns: name, texture, count, quality
|
|
||||||
local name, texture, count, quality = GetSendMailItem()
|
|
||||||
local moneyAmount = GetSendMailMoney()
|
|
||||||
|
|
||||||
local itemData = nil
|
|
||||||
if name then
|
|
||||||
local _, link = GetItemInfo(name)
|
|
||||||
itemData = {
|
|
||||||
name = name,
|
|
||||||
texture = texture or "Interface\\Icons\\INV_Misc_Bag_08",
|
|
||||||
count = count or 1,
|
|
||||||
quality = quality or 0,
|
|
||||||
link = link,
|
|
||||||
itemID = addon.Modules.Utils:ExtractItemID(link),
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Try to get more info if it's in cache
|
|
||||||
local itemName, retLink, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice = addon.Modules.Utils:GetItemInfo(name)
|
|
||||||
if itemName then
|
|
||||||
itemData.link = retLink or itemData.link
|
|
||||||
itemData.itemID = addon.Modules.Utils:ExtractItemID(itemData.link) or itemData.itemID
|
|
||||||
itemData.quality = itemQuality or itemData.quality
|
|
||||||
itemData.iLevel = iLevel
|
|
||||||
itemData.type = itemType
|
|
||||||
itemData.class = itemCategory
|
|
||||||
itemData.subclass = itemSubType
|
|
||||||
itemData.equipSlot = itemEquipLoc
|
|
||||||
if itemTexture then itemData.texture = itemTexture end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Double check itemID
|
local moneyAmount = GetSendMailMoney()
|
||||||
if not itemData.itemID and itemData.link then
|
local subjectText = (subject and subject ~= "") and subject or "No Subject"
|
||||||
itemData.itemID = addon.Modules.Utils:ExtractItemID(itemData.link)
|
local senderName = UnitName("player")
|
||||||
|
local addedAny = false
|
||||||
|
|
||||||
|
-- Try multi-attachment (TurtleWoW): check if HasSendMailItem exists
|
||||||
|
if HasSendMailItem then
|
||||||
|
for itemIndex = 1, 12 do
|
||||||
|
if not HasSendMailItem(itemIndex) then break end
|
||||||
|
local name, texture, count, quality = GetSendMailItem(itemIndex)
|
||||||
|
if not name then break end
|
||||||
|
|
||||||
|
local mailRow = {
|
||||||
|
sender = senderName,
|
||||||
|
subject = subjectText,
|
||||||
|
money = (itemIndex == 1) and moneyAmount or 0,
|
||||||
|
CODAmount = 0,
|
||||||
|
daysLeft = 30,
|
||||||
|
hasItem = true,
|
||||||
|
item = BuildSendMailItemData(name, texture, count, quality),
|
||||||
|
wasRead = false,
|
||||||
|
}
|
||||||
|
addon.Modules.DB:AddMailToCharacter(recipient, nil, mailRow)
|
||||||
|
addedAny = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if itemData or moneyAmount > 0 then
|
-- Fallback: single attachment (vanilla API)
|
||||||
|
if not addedAny then
|
||||||
|
local name, texture, count, quality = GetSendMailItem()
|
||||||
|
if name then
|
||||||
|
local mailRow = {
|
||||||
|
sender = senderName,
|
||||||
|
subject = subjectText,
|
||||||
|
money = moneyAmount,
|
||||||
|
CODAmount = 0,
|
||||||
|
daysLeft = 30,
|
||||||
|
hasItem = true,
|
||||||
|
item = BuildSendMailItemData(name, texture, count, quality),
|
||||||
|
wasRead = false,
|
||||||
|
}
|
||||||
|
addon.Modules.DB:AddMailToCharacter(recipient, nil, mailRow)
|
||||||
|
addedAny = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Money-only mail (no items)
|
||||||
|
if not addedAny and moneyAmount > 0 then
|
||||||
local mailRow = {
|
local mailRow = {
|
||||||
sender = UnitName("player"),
|
sender = senderName,
|
||||||
subject = (subject and subject ~= "") and subject or "No Subject",
|
subject = subjectText,
|
||||||
money = moneyAmount,
|
money = moneyAmount,
|
||||||
CODAmount = 0,
|
CODAmount = 0,
|
||||||
daysLeft = 30, -- Outgoing mail typically has 30 days
|
daysLeft = 30,
|
||||||
hasItem = itemData ~= nil,
|
hasItem = false,
|
||||||
item = itemData,
|
item = nil,
|
||||||
wasRead = false,
|
wasRead = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
addon.Modules.DB:AddMailToCharacter(recipient, nil, mailRow)
|
addon.Modules.DB:AddMailToCharacter(recipient, nil, mailRow)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -270,28 +310,29 @@ function MailboxScanner:Initialize()
|
|||||||
return originalPlaceAuctionBid(type, index, bid)
|
return originalPlaceAuctionBid(type, index, bid)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Hook taking items/money to update database immediately
|
-- Hook taking items/money (original calls only, DB save handled by MAIL_INBOX_UPDATE)
|
||||||
local originalTakeInboxItem = TakeInboxItem
|
local originalTakeInboxItem = TakeInboxItem
|
||||||
TakeInboxItem = function(index, attachmentIndex)
|
TakeInboxItem = function(index, attachmentIndex)
|
||||||
local result = originalTakeInboxItem(index, attachmentIndex)
|
return originalTakeInboxItem(index, attachmentIndex)
|
||||||
MailboxScanner:SaveToDatabase()
|
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local originalTakeInboxMoney = TakeInboxMoney
|
local originalTakeInboxMoney = TakeInboxMoney
|
||||||
TakeInboxMoney = function(index)
|
TakeInboxMoney = function(index)
|
||||||
local result = originalTakeInboxMoney(index)
|
return originalTakeInboxMoney(index)
|
||||||
MailboxScanner:SaveToDatabase()
|
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local originalAutoLootMailItem = AutoLootMailItem
|
local originalAutoLootMailItem = AutoLootMailItem
|
||||||
AutoLootMailItem = function(index)
|
AutoLootMailItem = function(index)
|
||||||
local result = originalAutoLootMailItem(index)
|
return originalAutoLootMailItem(index)
|
||||||
MailboxScanner:SaveToDatabase()
|
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Rescan mailbox when server confirms inbox changes
|
||||||
|
addon.Modules.Events:Register("MAIL_INBOX_UPDATE", function()
|
||||||
|
if mailboxOpen then
|
||||||
|
MailboxScanner:SaveToDatabase()
|
||||||
|
end
|
||||||
|
end, "MailboxScanner_InboxUpdate")
|
||||||
|
|
||||||
-- Mailbox opened
|
-- Mailbox opened
|
||||||
addon.Modules.Events:OnMailShow(function()
|
addon.Modules.Events:OnMailShow(function()
|
||||||
mailboxOpen = true
|
mailboxOpen = true
|
||||||
|
|||||||
Reference in New Issue
Block a user