Mercurial > wow > itemauditor
diff Core.lua @ 0:169f5211fc7f
First public revision.
At this point ItemAuditor watches mail for auctions sold or purchased, watches for buy/sell (money and 1 item type change) and conversions/tradeskills. Milling isn't working yet because there is too much time between the first event and the last event.
author | Asa Ayers <Asa.Ayers@Gmail.com> |
---|---|
date | Thu, 20 May 2010 19:22:19 -0700 |
parents | |
children | 6c87720c301c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core.lua Thu May 20 19:22:19 2010 -0700 @@ -0,0 +1,539 @@ +local addon = LibStub("AceAddon-3.0"):NewAddon("ItemAuditor", "AceConsole-3.0", "AceEvent-3.0", "AceBucket-3.0") + +ItemAuditor = addon + +local WHITE = "|cFFFFFFFF" +local RED = "|cFFFF0000" +local GREEN = "|cFF00FF00" +local YELLOW = "|cFFFFFF00" +local ORANGE = "|cFFFF7F00" +local TEAL = "|cFF00FF9A" +local GOLD = "|cFFFFD700" + +function addon:OnInitialize() + -- declare defaults to be used in the DB + local DB_defaults = { + char = { + debug = false + }, + factionrealm = { + item_account = {} + }, + } + self.db = LibStub("AceDB-3.0"):New("ItemAuditorDB", DB_defaults, true) + self.db.factionrealm.backup = self.db.factionrealm.item_account + + self.db.char.debug = true + + --[[ + Fine Thread = 510 + Greater Magic Essence = 120000 + Simple Kilt = 5913 + Bolt of Linen Cloth = 5672 + ]] + + self:RegisterOptions() + + self:Debug("Hello, world! OnInitialize") + + self:RegisterEvent("MAIL_SHOW") + self:WatchBags() +end + +function IA_tcount(tab) + local n = #tab + if (n == 0) then + for _ in pairs(tab) do + n = n + 1 + end + end + return n +end + + +local options = { + name = "ItemAuditor", + handler = ItemAuditor, + type = 'group', + args = { + debug = { + type = "toggle", + name = "Debug", + desc = "Toggles debug messages in chat", + get = "GetDebug", + set = "SetDebug" + }, + dump = { + type = "execute", + name = "dump", + desc = "dumps IA database", + func = "DumpInfo", + }, + options = { + type = "execute", + name = "options", + desc = "Show Blizzard's options GUI", + func = "ShowOptionsGUI", + guiHidden = true, + }, + }, +} + + +function addon:DumpInfo() + self:Print("self.db.char") + DevTools_Dump(self.db.char) + self:Print("self.db.factionrealm") + DevTools_Dump(self.db.factionrealm) +end + +function addon:RegisterOptions() + self.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("ItemAuditor", "ItemAuditor") + + LibStub("AceConfig-3.0"):RegisterOptionsTable("ItemAuditor", options, {"ia"}) + + self:RegisterChatCommand("fuck", "ChatCommand") +end + +function addon:GetMessage(info) + return self.message +end + +function addon:SetMessage(info, newValue) + self.message = newValue +end + + +function addon:ShowOptionsGUI() + InterfaceOptionsFrame_OpenToCategory(self.optionsFrame) +end + +function addon:GetDebug(info) + return self.db.char.debug +end + +function addon:SetDebug(info, input) + self.db.char.debug = input + local value = "off" + if input then + value = "on" + end + self:Print("Debugging is now: " .. value) +end + + +-- ================ DEBUG ================ +addon.OriginalRegisterEvent = addon.RegisterEvent +addon.OriginalUnregisterEvent = addon.UnregisterEvent + +function addon:RegisterEvent(event, callback, arg) + self:Debug("RegisterEvent " .. event ) + if arg ~= nil then + addon:OriginalRegisterEvent(event, callback, arg) + elseif callback ~= nil then + addon:OriginalRegisterEvent(event, callback) + else + addon:OriginalRegisterEvent(event) + end +end + +function addon:UnregisterEvent(event) + self:Debug("UnregisterEvent " .. event ) + addon:OriginalUnregisterEvent (event) +end + +-- ================ DEBUG ================ + +function addon:FormatMoney(money) + return Altoholic:GetMoneyString(money, WHITE, false) +end + +function addon:GetCurrentInventory() + local i = {} + local link + + for bagID = 0, NUM_BAG_SLOTS do + bagSize=GetContainerNumSlots(bagID) + for slotID = 0, bagSize do + itemID = GetContainerItemID(bagID, slotID); + + if itemID ~= nil then + _, itemCount, _, _, _= GetContainerItemInfo(bagID, slotID); + name = GetItemInfo(itemID) + if i[name] == nil then + i[name] = 0 + end + i[name] = i[name] + (itemCount or 0) + end + + end + + end + return {items = i, money = GetMoney()} +end + +function addon:GetInventoryDiff(pastInventory, current) + if current == nil then + current = self:GetCurrentInventory() + end + local diff = {} + + for name, count in pairs(current.items) do + if pastInventory.items[name] == nil then + diff[name] = count + self:Debug("1 diff[" .. name .. "]=" .. diff[name]) + elseif count - pastInventory.items[name] ~= 0 then + diff[name] = count - pastInventory.items[name] + self:Debug("2 diff[" .. name .. "]=" .. diff[name]) + end + end + + for name, count in pairs(pastInventory.items) do + if current.items[name] == nil then + diff[name] = -count + self:Debug("3 diff[" .. name .. "]=" .. diff[name]) + elseif current.items[name] - count ~= 0 then + diff[name] = current.items[name] - pastInventory.items[name] + self:Debug("4 diff[" .. name .. "]=" .. diff[name]) + end + end + + local moneyDiff = current.money - pastInventory.money + + return {items = diff, money = moneyDiff} +end + + +function addon:ScanMail() + local results = {} + for mailIndex = 1, GetInboxNumItems() or 0 do + local sender, msgSubject, msgMoney, msgCOD, _, msgItem, _, _, msgText, _, isGM = select(3, GetInboxHeaderInfo(mailIndex)) + local mailType = Postal:GetMailType(msgSubject) + + if mailType == "NonAHMail" then + -- Don't know how to handle these yet + elseif mailType == "AHSuccess" then + local invoiceType, itemName, playerName, bid, buyout, deposit, consignment = GetInboxInvoiceInfo(mailIndex); + if results[itemName] == nil then + results[itemName] = 0 + end + results[itemName] = results[itemName] + deposit + buyout - consignment + + elseif mailType == "AHWon" then + local invoiceType, itemName, playerName, bid, buyout, deposit, consignment = GetInboxInvoiceInfo(mailIndex); + if results[itemName] == nil then + results[itemName] = 0 + end + results[itemName] = results[itemName] - bid + elseif mailType == "AHExpired" or mailType == "AHCancelled" then + -- These should be handled when you pay the deposit at the AH + else + self:Debug("Unhandled mail type: " .. mailType) + self:Debug(msgSubject) + end + + end + return results +end + +function addon:MAIL_SHOW() + self:Debug("MAIL_SHOW") + self.lastMailScan = self:ScanMail() + self:UnregisterEvent("MAIL_SHOW") + self:RegisterEvent("MAIL_CLOSED") + self:RegisterEvent("MAIL_INBOX_UPDATE") + self:Debug("MAIL_SHOW complete") + -- the mail scanner will handle everything + -- self:UnwatchBags() +end + +function addon:MAIL_CLOSED() + addon:UnregisterEvent("MAIL_CLOSED") + self:UnregisterEvent("MAIL_INBOX_UPDATE") + self:RegisterEvent("MAIL_SHOW") + -- self:WatchBags() +end + +function addon:MAIL_INBOX_UPDATE() + local newScan = addon:ScanMail() + local diff + for item, total in pairs(self.lastMailScan) do + + if newScan[item] == nil then + newScan[item] = 0 + end + diff = total - newScan[item] + if diff ~= 0 then + self:SaveValue(item, diff) + end + + end + + self.lastMailScan = newScan +end + +function addon:SaveValue(item, value) + local item_account = self.db.factionrealm.item_account + if item_account[item] == nil then + item_account[item] = 0 + end + item_account[item] = item_account[item] + value + + if item_account[item] >= 0 then + item_account[item] = nil + end +end + +function addon:OnEnable() + self:Debug("Hello, world! OnEnable") +end + +function addon:Debug(msg) + if self.db.char.debug then + self:Print(msg) + end +end + +function addon:WatchBags() + if self.watch_handle == nil then + self.lastInventory = self:GetCurrentInventory() + self.watch_handle = self:RegisterBucketEvent({"BAG_UPDATE", "PLAYER_MONEY"}, 0.2, "UpdateAudit") + end +end + +function addon:UnwatchBags() + if self.watch_handle ~= nil then + self:UnregisterBucket(self.watch_handle) + self.watch_handle = nil + end +end + +function addon:UpdateAudit() + self:Debug("UpdateAudit") + local currentInventory = self:GetCurrentInventory() + local diff = addon:GetInventoryDiff(self.lastInventory, currentInventory) + -- this is only here for debugging + self.lastdiff = diff + + if abs(diff.money) > 0 and IA_tcount(diff.items) == 1 then + self:Debug("purchase or sale") + + for itemName, count in pairs(diff.items) do + self:SaveValue(itemName, diff.money) + end + elseif IA_tcount(diff.items) > 1 then + local positive, negative = {}, {} + local positiveCount, negativeCount = 0, 0 + for item, count in pairs(diff.items) do + if count > 0 then + positive[item] = count + positiveCount = positiveCount + count + elseif count < 0 then + negative[item] = count + negativeCount = negativeCount + abs(count) + end + end + + if IA_tcount(positive) > 0 and IA_tcount(negative) > 0 then + -- we must have created/converted something + self:Debug("conversion") + local totalChange = 0 + for itemName, change in pairs(negative) do + local _, itemCost, count = self:GetItemCost(itemName, change) + self:SaveValue(itemName, abs(itemCost * change)) + + totalChange = totalChange + abs(itemCost * change) + end + + self:Debug("totalChange") + self:Debug(totalChange) + + local valuePerItem = totalChange / positiveCount + self:Debug(valuePerItem ) + for itemName, change in pairs(positive) do + self:Debug(itemName) + self:Debug(0-abs(valuePerItem * change)) + self:SaveValue(itemName, 0-abs(valuePerItem * change)) + end + end + end + + self.lastInventory = currentInventory +end +-- /run ItemAuditor.db.factionrealm.item_account["Tiger Lily"] = -586625 +-- /run ItemAuditor.db.factionrealm.item_account["Icy Pigment"] = -12303 +-- /run ItemAuditor.db.factionrealm.item_account["Azure Pigment"] = -258357 + +function addon:GetItemCost(itemName, countModifier) + local invested = abs(self.db.factionrealm.item_account[itemName] or 0) + + if invested > 0 then + local _, itemLink = GetItemInfo (itemName); + local _, _, _, _, Id = string.find(itemLink, "|?c?f?f?(%x*)|?H?([^:]*):?(%d+):?(%d*):?(%d*):?(%d*):?(%d*):?(%d*):?(%-?%d*):?(%-?%d*):?(%d*)|?h?%[?([^%[%]]*)%]?|?h?|?r?") + local count = Altoholic:GetItemCount(tonumber(Id)) + if countModifier ~= nil then + count = count - countModifier + end + if count == 0 then + self.db.factionrealm.item_account[itemName] = nil + self:Print("You ran out of " .. itemName .. "and never recovered " .. self:FormatMoney(invested)) + return 0, 0, 0 + end + return ceil(invested), ceil(invested/count), count + end + return 0, 0, 0 +end + +function addon:ShowTooltip(tip, link, num) + if (link == nil) then + return; + end + + local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, _, _, _, _, itemVendorPrice = GetItemInfo (link); + -- local _, _, Color, Ltype, Id, Enchant, Gem1, Gem2, Gem3, Gem4, Suffix, Unique, LinkLvl, Name = string.find(link, "|?c?f?f?(%x*)|?H?([^:]*):?(%d+):?(%d*):?(%d*):?(%d*):?(%d*):?(%d*):?(%-?%d*):?(%-?%d*):?(%d*)|?h?%[?([^%[%]]*)%]?|?h?|?r?") + + local investedTotal, investedPerItem, count = self:GetItemCost(itemName) + + local AHCut = 0.05 + local keep = 1 - AHCut + + if investedTotal > 0 then + tip:AddDoubleLine("\124cffffffffIA: Total Invested", self:FormatMoney(investedTotal)); + tip:AddDoubleLine("\124cffffffffIA: Invested/Item (" .. count .. ")", self:FormatMoney(ceil(investedPerItem))); + tip:AddDoubleLine("\124cffffffffIA: Minimum faction AH Price: ", self:FormatMoney(ceil(investedPerItem/keep))) + tip:Show() + end +end + +local function ShowTipWithPricing(tip, link, num) + addon:ShowTooltip(tip, link, num) +end + +hooksecurefunc (GameTooltip, "SetBagItem", + function(tip, bag, slot) + local _, num = GetContainerItemInfo(bag, slot); + ShowTipWithPricing (tip, GetContainerItemLink(bag, slot), num); + end +); + + +hooksecurefunc (GameTooltip, "SetAuctionItem", + function (tip, type, index) + ShowTipWithPricing (tip, GetAuctionItemLink(type, index)); + end +); + +hooksecurefunc (GameTooltip, "SetAuctionSellItem", + function (tip) + local name, _, count = GetAuctionSellItemInfo(); + local __, link = GetItemInfo(name); + ShowTipWithPricing (tip, link, num); + end +); + + +hooksecurefunc (GameTooltip, "SetLootItem", + function (tip, slot) + if LootSlotIsItem(slot) then + local link, _, num = GetLootSlotLink(slot); + ShowTipWithPricing (tip, link, num); + end + end +); + +hooksecurefunc (GameTooltip, "SetLootRollItem", + function (tip, slot) + local _, _, num = GetLootRollItemInfo(slot); + ShowTipWithPricing (tip, GetLootRollItemLink(slot), num); + end +); + + +hooksecurefunc (GameTooltip, "SetInventoryItem", + function (tip, unit, slot) + ShowTipWithPricing (tip, GetInventoryItemLink(unit, slot), GetInventoryItemCount(unit, slot)); + end +); + +hooksecurefunc (GameTooltip, "SetGuildBankItem", + function (tip, tab, slot) + local _, num = GetGuildBankItemInfo(tab, slot); + ShowTipWithPricing (tip, GetGuildBankItemLink(tab, slot), num); + end +); + +hooksecurefunc (GameTooltip, "SetTradeSkillItem", + function (tip, skill, id) + local link = GetTradeSkillItemLink(skill); + local num = GetTradeSkillNumMade(skill); + if id then + link = GetTradeSkillReagentItemLink(skill, id); + num = select (3, GetTradeSkillReagentInfo(skill, id)); + end + + ShowTipWithPricing (tip, link, num); + end +); + +hooksecurefunc (GameTooltip, "SetTradePlayerItem", + function (tip, id) + local _, _, num = GetTradePlayerItemInfo(id); + ShowTipWithPricing (tip, GetTradePlayerItemLink(id), num); + end +); + +hooksecurefunc (GameTooltip, "SetTradeTargetItem", + function (tip, id) + local _, _, num = GetTradeTargetItemInfo(id); + ShowTipWithPricing (tip, GetTradeTargetItemLink(id), num); + end +); + +hooksecurefunc (GameTooltip, "SetQuestItem", + function (tip, type, index) + local _, _, num = GetQuestItemInfo(type, index); + ShowTipWithPricing (tip, GetQuestItemLink(type, index), num); + end +); + +hooksecurefunc (GameTooltip, "SetQuestLogItem", + function (tip, type, index) + local num, _; + if type == "choice" then + _, _, num = GetQuestLogChoiceInfo(index); + else + _, _, num = GetQuestLogRewardInfo(index) + end + + ShowTipWithPricing (tip, GetQuestLogItemLink(type, index), num); + end +); + +hooksecurefunc (GameTooltip, "SetInboxItem", + function (tip, index, attachIndex) + local _, _, num = GetInboxItem(index, attachIndex); + ShowTipWithPricing (tip, GetInboxItemLink(index, attachIndex), num); + end +); + +hooksecurefunc (GameTooltip, "SetSendMailItem", + function (tip, id) + local name, _, num = GetSendMailItem(id) + local name, link = GetItemInfo(name); + ShowTipWithPricing (tip, link, num); + end +); + +hooksecurefunc (GameTooltip, "SetHyperlink", + function (tip, itemstring, num) + local name, link = GetItemInfo (itemstring); + ShowTipWithPricing (tip, link, num); + end +); + +hooksecurefunc (ItemRefTooltip, "SetHyperlink", + function (tip, itemstring) + local name, link = GetItemInfo (itemstring); + ShowTipWithPricing (tip, link); + end +);