Asa@3: local addonName, addonTable = ...; Asa@3: local addon = _G[addonName] Asa@3: Asa@38: function addon:OnEnable() Asa@3: self:RegisterEvent("MAIL_SHOW") Asa@4: self:RegisterEvent("UNIT_SPELLCAST_START") Asa@24: addon:UpdateCurrentInventory() Asa@3: self:WatchBags() Asa@9: Asa@38: self:SetEnabled(nil, self.db.profile.addon_enabled) Asa@38: end Asa@38: Asa@38: function addon:OnDisable() Asa@38: self:UnwatchBags() Asa@38: self:UnregisterAllEvents() Asa@38: addon:HideAllFrames() Asa@3: end Asa@3: Asa@3: function addon:MAIL_SHOW() Asa@3: self:Debug("MAIL_SHOW") Asa@39: self:UnwatchBags() Asa@24: addon:UpdateCurrentInventory() Asa@3: self.lastMailScan = self:ScanMail() Asa@7: Asa@3: self:UnregisterEvent("MAIL_SHOW") Asa@3: self:RegisterEvent("MAIL_CLOSED") Asa@3: self:RegisterEvent("MAIL_INBOX_UPDATE") Asa@39: Asa@39: self:GenerateBlankOutbox() Asa@39: Asa@39: self:RegisterEvent("MAIL_SUCCESS") Asa@39: end Asa@39: Asa@39: function addon:GenerateBlankOutbox() Asa@39: self.mailOutbox = { Asa@39: from = UnitName("player"), Asa@39: to = "", Asa@39: subject = "", Asa@39: link = '', Asa@39: count = 0, Asa@39: COD = 0, Asa@39: key = random(10000), Asa@39: sent = 0, Asa@39: } Asa@39: Asa@39: if self.db.factionrealm.outbound_cod[self.mailOutbox.key] ~= nil then Asa@39: return self:GenerateBlankOutbox() Asa@39: end Asa@39: end Asa@39: Asa@40: local attachedItems = {} Asa@39: local Orig_SendMail = SendMail Asa@42: local skipCODTracking = false Asa@42: Asa@42: StaticPopupDialogs["ItemAuditor_Send_COD_without_tracking_number"] = { Asa@42: text = "ItemAuditor cannot track COD mail with multiple item types attached. Do you want to send this mail without tracking?", Asa@42: button1 = "Yes", Asa@42: button2 = "No", Asa@42: OnAccept = function() Asa@42: skipCODTracking = true Asa@42: end, Asa@42: timeout = 0, Asa@42: whileDead = true, Asa@42: hideOnEscape = true, Asa@42: } Asa@39: Asa@39: function SendMail(recipient, subject, body, ...) Asa@39: local self = ItemAuditor Asa@39: self:GenerateBlankOutbox() Asa@39: Asa@39: self:Debug(format("[To: %s] [Subject: %s]", recipient, subject)) Asa@39: Asa@39: self.mailOutbox.COD = GetSendMailCOD() Asa@39: Asa@40: attachedItems = {} Asa@40: local totalStacks = 0 Asa@39: local link Asa@40: for index = 1, ATTACHMENTS_MAX_SEND do Asa@39: local itemName, _, itemCount = GetSendMailItem(index) Asa@39: local newLink = GetSendMailItemLink(index) Asa@39: Asa@40: if newLink ~= nil then Asa@40: newLink = self:GetSafeLink(newLink) Asa@40: totalStacks = totalStacks + 1 Asa@40: attachedItems[newLink] = (attachedItems[newLink] or {stacks = 0, count = 0}) Asa@40: attachedItems[newLink].stacks = attachedItems[newLink].stacks + 1 Asa@40: attachedItems[newLink].count = attachedItems[newLink].count + itemCount Asa@40: attachedItems[newLink].price = 0 -- This is a placeholder for below. Asa@39: end Asa@40: end Asa@40: local pricePerStack = GetSendMailPrice() / totalStacks Asa@40: for link, data in pairs(attachedItems) do Asa@40: data.price = pricePerStack * data.stacks Asa@40: end Asa@40: Asa@42: if self.mailOutbox.COD > 0 and skipCODTracking then Asa@42: Asa@42: elseif self.mailOutbox.COD > 0 then Asa@40: if self:tcount(attachedItems) > 1 then Asa@39: self:GenerateBlankOutbox() Asa@42: local vararg = ... Asa@42: StaticPopupDialogs["ItemAuditor_Send_COD_without_tracking_number"].OnAccept = function() Asa@42: skipCODTracking = true Asa@42: SendMail(recipient, subject, body, vararg) Asa@42: skipCODTracking = false Asa@42: end Asa@42: StaticPopup_Show ("ItemAuditor_Send_COD_without_tracking_number"); Asa@39: return Asa@39: end Asa@40: self:Debug("COD mail") Asa@39: Asa@40: subject = format("[IA: %s] %s", self.mailOutbox.key, subject) Asa@40: self.mailOutbox.subject = subject Asa@40: self.mailOutbox.to = recipient Asa@40: Asa@40: -- At this point we know there is only one item Asa@40: for link, data in pairs(attachedItems) do Asa@40: self.mailOutbox.link = link Asa@40: self.mailOutbox.count = data.count Asa@40: end Asa@40: else Asa@40: self:Debug("Non-COD mail") Asa@39: end Asa@40: Asa@39: return Orig_SendMail(recipient, subject, body, ...) Asa@39: end Asa@39: Asa@39: function addon:MAIL_SUCCESS(event) Asa@42: skipCODTracking = false Asa@40: for link, data in pairs(attachedItems) do Asa@40: self:SaveValue(link, data.price, data.count) Asa@40: end Asa@39: if self.mailOutbox.COD > 0 then Asa@39: self:Debug(format("MAIL_SUCCESS %d [To: %s] [Subject: %s] [COD: %s]", self.mailOutbox.key, self.mailOutbox.to, self.mailOutbox.subject, self.mailOutbox.COD)) Asa@39: Asa@39: self.mailOutbox.sent = time() Asa@39: self.db.factionrealm.outbound_cod[self.mailOutbox.key] = self.mailOutbox Asa@39: end Asa@39: Asa@40: Asa@40: self:GenerateBlankOutbox() Asa@3: end Asa@3: Asa@3: function addon:MAIL_CLOSED() Asa@23: self:Debug("MAIL_CLOSED") Asa@3: addon:UnregisterEvent("MAIL_CLOSED") Asa@7: self:MAIL_INBOX_UPDATE() Asa@3: self:UnregisterEvent("MAIL_INBOX_UPDATE") Asa@3: self:RegisterEvent("MAIL_SHOW") Asa@39: self:WatchBags() Asa@3: end Asa@3: Asa@26: local storedCountDiff Asa@3: function addon:MAIL_INBOX_UPDATE() Asa@23: self:Debug("MAIL_INBOX_UPDATE") Asa@3: local newScan = addon:ScanMail() Asa@3: local diff Asa@39: Asa@6: for mailType, collection in pairs(self.lastMailScan) do Asa@7: newScan[mailType] = (newScan[mailType] or {}) Asa@26: for itemName, data in pairs(collection) do Asa@26: newScan[mailType][itemName] = (newScan[mailType][itemName] or {total=0,count=0}) Asa@26: local totalDiff = data.total - newScan[mailType][itemName].total Asa@26: local countDiff = data.count - newScan[mailType][itemName].count Asa@26: --[[ Asa@26: In one update the item will be taken and in the following update the invoice Asa@26: will be gone. I need to store the item difference in order ot pass it into Asa@26: SaveValue. Asa@26: ]] Asa@26: if countDiff ~= 0 then Asa@26: storedCountDiff = countDiff Asa@26: end Asa@26: Asa@26: if totalDiff ~= 0 then Asa@39: if mailType == "CODPayment" then Asa@39: local trackID Asa@39: trackID, itemName= strsplit("|", itemName, 2) Asa@39: self.db.factionrealm.outbound_cod[tonumber(trackID)] = nil Asa@39: self:Debug("Removing COD Tracker: " .. trackID) Asa@39: end Asa@26: self:SaveValue(itemName, totalDiff, storedCountDiff) Asa@26: storedCountDiff = 0 Asa@6: end Asa@6: Asa@3: end Asa@3: end Asa@3: Asa@3: self.lastMailScan = newScan Asa@3: end Asa@3: Asa@4: function addon:UNIT_SPELLCAST_START(event, target, spell) Asa@5: if target == "player" and spell == "Milling" or spell == "Prospecting" or spell == "Disenchanting" then Asa@23: self:Debug(event .. " " .. spell) Asa@4: self:UnwatchBags() Asa@4: self:UpdateCurrentInventory() Asa@4: self:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED") Asa@4: self:RegisterEvent("LOOT_CLOSED") Asa@3: end Asa@3: end Asa@3: Asa@4: --[[ Asa@4: The item should be destroyed before this point, so the last inventory check Asa@4: needs to be kept so it can be combined with the up coming loot. Asa@4: ]] Asa@4: function addon:LOOT_CLOSED() Asa@23: self:Debug("LOOT_CLOSED") Asa@4: self:UnregisterEvent("LOOT_CLOSED") Asa@4: self:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED") Asa@4: local inventory = self.lastInventory Asa@4: self:WatchBags() Asa@4: self.lastInventory = inventory Asa@4: end Asa@3: Asa@4: function addon:UNIT_SPELLCAST_INTERRUPTED(event, target, spell) Asa@5: if target == "player" and spell == "Milling" or spell == "Prospecting" or spell == "Disenchanting" then Asa@23: self:Debug(event .. " " .. spell) Asa@4: self:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED") Asa@4: self:UnregisterEvent("LOOT_CLOSED") Asa@4: self:WatchBags() Asa@4: end Asa@4: end Asa@4: Asa@4: function addon:UpdateCurrentInventory() Asa@4: self.lastInventory = self:GetCurrentInventory() Asa@3: end Asa@3: Asa@46: local function distributeValueByAHValue(self, totalValue, targetItems) Asa@46: Asa@46: local weights = {} Asa@46: local totalWeight = 0 Asa@46: for link, change in pairs(targetItems) do Asa@46: --[[ Asa@46: If something has never been seen on the AH, it must not be very valuable. Asa@46: I'm using 1c so it doesn't have much weight and I can't get a devided by zero error. Asa@46: The only time I know that this is a problem is when crafting a BOP item, and it Asa@46: is always crafted 1 at a time, so a weight of 1 will work. Asa@46: ]] Asa@46: local ap = (addon:GetAuctionPrice(link) or 1) Asa@46: totalWeight = totalWeight + ap Asa@46: weights[link] = ap Asa@46: end Asa@46: Asa@46: local valuePerPoint = totalValue / totalWeight Asa@46: Asa@46: for link, change in pairs(targetItems) do Asa@46: self:SaveValue(link, weights[link] * valuePerPoint, change) Asa@46: end Asa@46: end Asa@46: Asa@46: local function distributeValue(self, totalValue, targetItems) Asa@46: if true then Asa@46: return distributeValueByAHValue(self, totalValue, targetItems) Asa@46: else Asa@46: local valuePerItem = totalChange / positiveCount Asa@46: Asa@46: for link, change in pairs(targetItems) do Asa@46: self:SaveValue(link, valuePerItem * change, change) Asa@46: end Asa@46: end Asa@46: end Asa@46: Asa@3: function addon:UpdateAudit() Asa@23: -- self:Debug("UpdateAudit " .. event) Asa@3: local currentInventory = self:GetCurrentInventory() Asa@3: local diff = addon:GetInventoryDiff(self.lastInventory, currentInventory) Asa@3: Asa@5: local positive, negative = {}, {} Asa@5: local positiveCount, negativeCount = 0, 0 Asa@5: for item, count in pairs(diff.items) do Asa@5: if count > 0 then Asa@5: positive[item] = count Asa@5: positiveCount = positiveCount + count Asa@5: elseif count < 0 then Asa@5: negative[item] = count Asa@5: negativeCount = negativeCount + abs(count) Asa@5: end Asa@5: end Asa@5: Asa@23: if positiveCount + negativeCount == 0 then Asa@33: --[[ Asa@33: Nothing needs to be done, but this will prevent mistakenly attributing Asa@33: the cost of flights to the first item you pick up. Asa@33: ]] Asa@33: elseif diff.money > 0 and self:tcount(positive) > 0 and self:tcount(negative) == 0 then Asa@15: self:Debug("loot") Asa@20: elseif abs(diff.money) > 0 and self:tcount(diff.items) == 1 then Asa@15: self:Debug("purchase or sale") Asa@3: Asa@9: for link, count in pairs(diff.items) do Asa@26: self:SaveValue(link, 0 - diff.money, count) Asa@3: end Asa@23: elseif self:tcount(diff.items) > 1 and self:tcount(positive) > 0 and self:tcount(negative) > 0 then Asa@23: -- we must have created/converted something Asa@23: self:Debug("conversion") Asa@3: Asa@23: local totalChange = 0 Asa@23: for link, change in pairs(negative) do Asa@23: local _, itemCost, count = self:GetItemCost(link, change) Asa@26: self:SaveValue(link, itemCost * change, change) Asa@10: Asa@23: totalChange = totalChange + (itemCost * abs(change)) Asa@3: end Asa@23: Asa@46: distributeValue(self, totalChange, positive) Asa@23: else Asa@23: self:Debug("No match in UpdateAudit.") Asa@3: end Asa@3: Asa@3: self.lastInventory = currentInventory Asa@4: addon:WatchBags() Asa@3: end