annotate Core.lua @ 49:9ff6a3b02332 ticket7

I have changed my mind, price distribution will always be based on the AH price, unless none is available, then all items have the same weight which is what was being done before.
author Asa Ayers <Asa.Ayers@Gmail.com>
date Wed, 21 Jul 2010 01:00:14 -0700
parents a66f6fc57cfb
children 234896be4087
rev   line source
Asa@3 1 local addonName, addonTable = ...;
Asa@16 2 _G[addonName] = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceEvent-3.0", "AceBucket-3.0")
Asa@3 3 local addon = _G[addonName]
Asa@9 4 addonTable.ItemAuditor = addon
Asa@0 5
Asa@0 6 local WHITE = "|cFFFFFFFF"
Asa@0 7 local RED = "|cFFFF0000"
Asa@0 8 local GREEN = "|cFF00FF00"
Asa@0 9 local YELLOW = "|cFFFFFF00"
Asa@0 10 local ORANGE = "|cFFFF7F00"
Asa@0 11 local TEAL = "|cFF00FF9A"
Asa@0 12 local GOLD = "|cFFFFD700"
Asa@0 13
Asa@0 14 function addon:OnInitialize()
Asa@0 15 local DB_defaults = {
Asa@0 16 char = {
Asa@13 17 ah = 1,
Asa@13 18 use_quick_auctions = false,
Asa@20 19 crafting_threshold = 1,
Asa@20 20 auction_threshold = 0.15,
Asa@0 21 },
Asa@16 22 profile = {
Asa@16 23 messages = {
Asa@16 24 cost_updates = true,
Asa@20 25 queue_skip = false,
Asa@23 26 },
Asa@38 27 addon_enabled = true,
Asa@23 28 -- This is for development, so I have no plans to turn it into an option.
Asa@23 29 show_debug_frame_on_startup = false,
Asa@16 30 },
Asa@0 31 factionrealm = {
Asa@8 32 item_account = {},
Asa@8 33 items = {},
Asa@39 34 outbound_cod = {},
Asa@0 35 },
Asa@0 36 }
Asa@0 37 self.db = LibStub("AceDB-3.0"):New("ItemAuditorDB", DB_defaults, true)
Asa@8 38 addonTable.db= self.db
Asa@8 39 self.items = self.db.factionrealm.items
Asa@0 40
Asa@0 41 self:RegisterOptions()
Asa@38 42 ItemAuditor:RegisterFrame(ItemAuditor_DebugFrame)
Asa@23 43
Asa@23 44 -- /run ItemAuditor.db.profile.show_debug_frame_on_startup = true
Asa@23 45 if self.db.profile.show_debug_frame_on_startup then
Asa@23 46 ItemAuditor_DebugFrame:Show()
Asa@28 47 self:CreateFrames()
Asa@23 48 end
Asa@0 49 end
Asa@0 50
Asa@38 51 local registeredEvents = {}
Asa@38 52 local originalRegisterEvent = addon.RegisterEvent
Asa@38 53 function addon:RegisterEvent(event, callback, arg)
Asa@38 54 registeredEvents[event] = true
Asa@38 55 if arg ~= nil then
Asa@38 56 return originalRegisterEvent(self, event, callback, arg)
Asa@38 57 elseif callback ~= nil then
Asa@38 58 return originalRegisterEvent(self, event, callback)
Asa@38 59 else
Asa@38 60 return originalRegisterEvent(self, event)
Asa@38 61 end
Asa@38 62 end
Asa@38 63
Asa@38 64 local originalUnregisterEvent = addon.UnregisterEvent
Asa@38 65 function addon:UnregisterEvent(event)
Asa@38 66 registeredEvents[event] = nil
Asa@38 67 return originalUnregisterEvent(self, event)
Asa@38 68 end
Asa@38 69
Asa@38 70 function addon:UnregisterAllEvents()
Asa@38 71 for event in pairs(registeredEvents) do
Asa@38 72 self:UnregisterEvent(event)
Asa@38 73 end
Asa@38 74 end
Asa@38 75
Asa@38 76 local registeredFrames = {}
Asa@38 77 function addon:RegisterFrame(frame)
Asa@38 78 tinsert(registeredFrames, frame)
Asa@38 79 end
Asa@38 80
Asa@38 81 function addon:HideAllFrames()
Asa@38 82 for key, frame in pairs(registeredFrames) do
Asa@38 83 if frame then
Asa@38 84 frame:Hide()
Asa@38 85 end
Asa@38 86 end
Asa@38 87 end
Asa@38 88
Asa@8 89 function addon:ConvertItems()
Asa@8 90 for itemName, value in pairs(self.db.factionrealm.item_account) do
Asa@15 91 local itemID = self:GetItemID(itemName)
Asa@8 92 if itemID ~= nil then
Asa@8 93 self:GetItem('item:' .. itemID)
Asa@8 94 end
Asa@8 95 if value == 0 then
Asa@8 96 self.db.factionrealm.item_account[itemName] = nil
Asa@8 97 end
Asa@8 98 end
Asa@8 99
Asa@8 100 for link, data in pairs(self.db.factionrealm.items) do
Asa@8 101 if self:GetItem(link).count == 0 or self:GetItem(link).invested == 0 then
Asa@8 102 self:RemoveItem(link)
Asa@8 103 end
Asa@10 104 end
Asa@10 105
Asa@12 106 self:RefreshQAGroups()
Asa@12 107 end
Asa@12 108
Asa@24 109 local printPrefix = "|cFFA3CEFFItemAuditor|r: "
Asa@24 110 function addon:Print(message, ...)
Asa@24 111 message = format(message, ...)
Asa@24 112 DEFAULT_CHAT_FRAME:AddMessage( printPrefix .. tostring(message))
Asa@22 113 self:Log(message)
Asa@16 114 end
Asa@16 115
Asa@0 116 function addon:GetCurrentInventory()
Asa@8 117 local i = {}
Asa@8 118 local bagID
Asa@8 119 local slotID
Asa@8 120
Asa@8 121 for bagID = 0, NUM_BAG_SLOTS do
Asa@8 122 bagSize=GetContainerNumSlots(bagID)
Asa@8 123 for slotID = 0, bagSize do
Asa@8 124 local link= GetContainerItemLink(bagID, slotID);
Asa@10 125 link = link and self:GetSafeLink(link)
Asa@8 126
Asa@8 127 if link ~= nil and i[link] == nil then
Asa@8 128 i[link] = GetItemCount(link);
Asa@8 129 end
Asa@8 130 end
Asa@8 131
Asa@8 132 end
Asa@8 133 return {items = i, money = GetMoney()}
Asa@0 134 end
Asa@0 135
Asa@0 136 function addon:GetInventoryDiff(pastInventory, current)
Asa@8 137 if current == nil then
Asa@8 138 current = self:GetCurrentInventory()
Asa@8 139 end
Asa@8 140 local diff = {}
Asa@8 141
Asa@8 142 for link, count in pairs(current.items) do
Asa@8 143 if pastInventory.items[link] == nil then
Asa@8 144 diff[link] = count
Asa@23 145 self:Debug("1 diff[" .. link .. "]=" .. diff[link])
Asa@8 146 elseif count - pastInventory.items[link] ~= 0 then
Asa@8 147 diff[link] = count - pastInventory.items[link]
Asa@23 148 self:Debug("2 diff[" .. link .. "]=" .. diff[link])
Asa@8 149 end
Asa@8 150 end
Asa@8 151
Asa@8 152 for link, count in pairs(pastInventory.items) do
Asa@8 153 if current.items[link] == nil then
Asa@8 154 diff[link] = -count
Asa@23 155 self:Debug("3 diff[" .. link .. "]=" .. diff[link])
Asa@8 156 elseif current.items[link] - count ~= 0 then
Asa@8 157 diff[link] = current.items[link] - pastInventory.items[link]
Asa@23 158 self:Debug("4 diff[" .. link .. "]=" .. diff[link])
Asa@8 159 end
Asa@8 160 end
Asa@8 161
Asa@8 162 local moneyDiff = current.money - pastInventory.money
Asa@23 163 if abs(moneyDiff) > 0 then
Asa@23 164 self:Debug("moneyDiff: " .. moneyDiff)
Asa@23 165 end
Asa@8 166
Asa@8 167 return {items = diff, money = moneyDiff}
Asa@0 168 end
Asa@0 169
Asa@39 170 local inboundCOD = {}
Asa@39 171 local skipMail = {}
Asa@0 172 function addon:ScanMail()
Asa@0 173 local results = {}
Asa@39 174 local CODPaymentRegex = gsub(COD_PAYMENT, "%%s", "(.*)")
Asa@39 175
Asa@0 176 for mailIndex = 1, GetInboxNumItems() or 0 do
Asa@39 177 local sender, msgSubject, msgMoney, msgCOD, daysLeft, msgItem, _, _, msgText, _, isGM = select(3, GetInboxHeaderInfo(mailIndex))
Asa@15 178 local mailType = self:GetMailType(msgSubject)
Asa@6 179
Asa@39 180 local mailSignature = msgSubject .. '-' .. msgMoney .. '-' .. msgCOD .. '-' .. daysLeft
Asa@39 181
Asa@6 182 results[mailType] = (results[mailType] or {})
Asa@6 183
Asa@39 184 if skipMail[mailSignature] ~= nil then
Asa@39 185 -- do nothing
Asa@39 186 elseif mailType == "NonAHMail" and msgCOD > 0 then
Asa@6 187 mailType = 'COD'
Asa@6 188 results[mailType] = (results[mailType] or {})
Asa@5 189
Asa@5 190 local itemTypes = {}
Asa@5 191 for itemIndex = 1, ATTACHMENTS_MAX_RECEIVE do
Asa@5 192 local itemName, _, count, _, _= GetInboxItem(mailIndex, itemIndex)
Asa@5 193 if itemName ~= nil then
Asa@39 194 itemTypes[itemName] = (itemTypes[itemName] or 0) + count
Asa@5 195 end
Asa@5 196 end
Asa@5 197
Asa@15 198 if self:tcount(itemTypes) == 1 then
Asa@5 199 for itemName, count in pairs(itemTypes) do
Asa@39 200 results[mailType][itemName] = (results[mailType][itemName] or {total=0,count=0})
Asa@39 201 results[mailType][itemName].total = results[mailType][itemName].total + msgCOD
Asa@39 202
Asa@39 203 if inboundCOD[mailSignature] == nil then
Asa@39 204 results[mailType][itemName].count = results[mailType][itemName].count + count
Asa@39 205 inboundCOD[mailSignature] = (inboundCOD[mailSignature] or 0) + count
Asa@39 206 else
Asa@39 207 results[mailType][itemName].count = inboundCOD[mailSignature]
Asa@39 208 end
Asa@39 209
Asa@39 210
Asa@5 211 end
Asa@5 212 else
Asa@5 213 self:Debug("Don't know what to do with more than one item type on COD mail.")
Asa@5 214 end
Asa@6 215 elseif mailType == "CODPayment" then
Asa@39 216 -- /dump ItemAuditor.db.factionrealm.outbound_cod
Asa@39 217 self:Debug(msgSubject)
Asa@39 218 self:Debug(CODPaymentRegex)
Asa@39 219 local outboundSubject = select(3, msgSubject:find(CODPaymentRegex))
Asa@39 220 local trackID
Asa@39 221 if outboundSubject ~= nil then
Asa@39 222 self:Debug(outboundSubject)
Asa@45 223 trackID = select(3, outboundSubject:find('[[]IA: (%d*)[]]'))
Asa@39 224
Asa@39 225 if trackID ~= nil then
Asa@45 226 trackID = tonumber(trackID)
Asa@45 227 self:Debug('COD ID: %s', trackID)
Asa@39 228 local cod = self.db.factionrealm.outbound_cod[trackID]
Asa@39 229 if cod == nil then
Asa@39 230 skipMail[mailSignature] = true
Asa@39 231 self:Print("WARNING: {%s} has an invalid ItemAuditor tracking number.", msgSubject)
Asa@39 232 else
Asa@39 233 itemName = trackID .. "|" .. cod['link']
Asa@39 234
Asa@39 235
Asa@39 236 results[mailType][itemName] = (results[mailType][itemName] or {total=0,count=0})
Asa@39 237 results[mailType][itemName].total = results[mailType][itemName].total - msgMoney
Asa@39 238 results[mailType][itemName].count = results[mailType][itemName].count - cod.count
Asa@39 239 end
Asa@39 240 end
Asa@39 241 end
Asa@5 242
Asa@39 243 if trackID == nil then
Asa@39 244 skipMail[mailSignature] = true
Asa@39 245 self:Print("WARNING: {%s} is a COD payment but doesn't have an ItemAuditor tracking number.", msgSubject)
Asa@39 246 end
Asa@5 247
Asa@0 248 elseif mailType == "AHSuccess" then
Asa@0 249 local invoiceType, itemName, playerName, bid, buyout, deposit, consignment = GetInboxInvoiceInfo(mailIndex);
Asa@26 250 results[mailType][itemName] = (results[mailType][itemName] or {total=0,count=0})
Asa@26 251 results[mailType][itemName].total = results[mailType][itemName].total - deposit - buyout + consignment
Asa@26 252
Asa@0 253
Asa@0 254 elseif mailType == "AHWon" then
Asa@0 255 local invoiceType, itemName, playerName, bid, buyout, deposit, consignment = GetInboxInvoiceInfo(mailIndex);
Asa@26 256 results[mailType][itemName] = (results[mailType][itemName] or {total=0,count=0})
Asa@26 257 results[mailType][itemName].total = results[mailType][itemName].total + bid
Asa@26 258
Asa@26 259 local count = select(3, GetInboxItem(1,1))
Asa@26 260 results[mailType][itemName].count = results[mailType][itemName].count + count
Asa@5 261 elseif mailType == "AHExpired" or mailType == "AHCancelled" or mailType == "AHOutbid" then
Asa@0 262 -- These should be handled when you pay the deposit at the AH
Asa@0 263 else
Asa@24 264 -- self:Debug("Unhandled mail type: " .. mailType)
Asa@24 265 -- self:Debug(msgSubject)
Asa@0 266 end
Asa@0 267
Asa@0 268 end
Asa@23 269
Asa@23 270 for mailType, collection in pairs(results) do
Asa@26 271 for item, data in pairs(collection) do
Asa@26 272 self:Debug(format("|cFF00FF00MailScan|r: %s - %s - %s x %s", mailType, item, data.total, data.count))
Asa@23 273 end
Asa@23 274 end
Asa@23 275
Asa@0 276 return results
Asa@0 277 end
Asa@0 278
Asa@9 279 function addon:GetItem(link, viewOnly)
Asa@9 280 if viewOnly == nil then
Asa@9 281 viewOnly = false
Asa@9 282 end
Asa@8 283
Asa@9 284 local itemName = nil
Asa@9 285 if self:GetSafeLink(link) == nil then
Asa@9 286 itemName = link
Asa@9 287 else
Asa@9 288 link = self:GetSafeLink(link)
Asa@9 289 itemName = GetItemInfo(link)
Asa@9 290 end
Asa@9 291
Asa@12 292
Asa@9 293 if self.db.factionrealm.item_account[itemName] ~= nil then
Asa@8 294 self.items[link] = {
Asa@12 295 count = Altoholic:GetItemCount(self:GetIDFromLink(link)),
Asa@8 296 invested = abs(self.db.factionrealm.item_account[itemName] or 0),
Asa@8 297 }
Asa@8 298 self.db.factionrealm.item_account[itemName] = nil
Asa@8 299 end
Asa@8 300
Asa@9 301 if viewOnly == false and self.items[link] == nil then
Asa@24 302
Asa@9 303 self.items[link] = {
Asa@10 304 count = Altoholic:GetItemCount(self:GetIDFromLink(link)),
Asa@9 305 invested = abs(self.db.factionrealm.item_account[itemName] or 0),
Asa@9 306 }
Asa@9 307
Asa@9 308 end
Asa@9 309
Asa@37 310 if self.items[link] ~= nil then
Asa@37 311 self.items[link].count = Altoholic:GetItemCount(self:GetIDFromLink(link))
Asa@45 312
Asa@45 313 if self.items[link].invested == nil then
Asa@45 314 self.items[link].invested = 0
Asa@45 315 end
Asa@37 316 end
Asa@37 317
Asa@9 318 if viewOnly == true and self.items[link] == nil then
Asa@9 319 return {count = 0, invested = 0}
Asa@9 320 elseif viewOnly == true then
Asa@28 321
Asa@9 322 return {count = self.items[link].count, invested = self.items[link].invested}
Asa@9 323 end
Asa@37 324
Asa@28 325
Asa@28 326
Asa@8 327 return self.items[link]
Asa@8 328 end
Asa@8 329
Asa@8 330 function addon:RemoveItem(link)
Asa@9 331 self.db.factionrealm.item_account[link] = nil
Asa@9 332 link = self:GetSafeLink(link)
Asa@9 333 if link ~= nil then
Asa@35 334 local item = addon:GetItem(link)
Asa@35 335 item.invested = 0
Asa@24 336 else
Asa@24 337 self:Debug('Failed to convert link' .. tostring(link))
Asa@9 338 end
Asa@8 339 end
Asa@8 340
Asa@26 341 function addon:SaveValue(link, value, countChange)
Asa@26 342 self:Debug("SaveValue(%s, %s, %s)", tostring(link), value, (countChange or 'default'))
Asa@26 343 countChange = countChange or 0
Asa@9 344 local item = nil
Asa@9 345 local realLink = self:GetSafeLink(link)
Asa@9 346 local itemName = nil
Asa@9 347 if realLink == nil then
Asa@26 348 itemName = link
Asa@23 349 self:Debug('SaveValue: GetSafeLink failed, falling back to storing by name: ' .. tostring(itemName))
Asa@9 350 self.db.factionrealm.item_account[itemName] = (self.db.factionrealm.item_account[itemName] or 0) + value
Asa@9 351 item = {invested = self.db.factionrealm.item_account[itemName], count = 1}
Asa@9 352 else
Asa@23 353
Asa@9 354 item = self:GetItem(realLink)
Asa@9 355 item.invested = item.invested + value
Asa@9 356 itemName = GetItemInfo(realLink)
Asa@9 357 end
Asa@8 358
Asa@26 359 if value > 0 and countChange > 0 and item.invested == value and item.count ~= countChange then
Asa@26 360 local costPerItem = value / countChange
Asa@26 361 value = costPerItem * item.count
Asa@26 362 item.invested = value
Asa@26 363 self:Print("You already owned %s %s with an unknown price, so they have also been updated to %s each", (item.count - countChange), itemName, self:FormatMoney(costPerItem))
Asa@26 364 end
Asa@26 365
Asa@7 366 if abs(value) > 0 then
Asa@22 367 if item.invested < 0 then
Asa@16 368 if self.db.profile.messages.cost_updates then
Asa@16 369 self:Print(format("Updated price of %s from %s to %s. %sYou just made a profit of %s.", itemName, self:FormatMoney(item.invested - value), self:FormatMoney(0), GREEN, self:FormatMoney(abs(item.invested))))
Asa@16 370 end
Asa@12 371 self:RemoveItem(link)
Asa@12 372 -- This doesn't work when you mail the only copy of an item you have to another character.
Asa@12 373 --[[
Asa@12 374 elseif item.count == 0 and realLink and Altoholic:GetItemCount(self:GetIDFromLink(realLink)) then
Asa@15 375 self:Print("You ran out of " .. itemName .. " and never recovered " .. self:FormatMoney(item.invested))
Asa@12 376 self:RemoveItem(link)
Asa@12 377 ]]
Asa@16 378 else
Asa@16 379 if self.db.profile.messages.cost_updates then
Asa@16 380 self:Print(format("Updated price of %s from %s to %s. (total change:%s)", itemName, self:FormatMoney(item.invested - value), self:FormatMoney(item.invested), self:FormatMoney(value)))
Asa@16 381 end
Asa@12 382 end
Asa@0 383 end
Asa@10 384
Asa@10 385 if realLink ~= nil then
Asa@10 386 addon:UpdateQAThreshold(realLink)
Asa@10 387 end
Asa@35 388 UpdateInvestedData()
Asa@10 389 end
Asa@12 390
Asa@0 391
Asa@23 392 function addon:WatchBags()
Asa@4 393 if self.watch_handle == nil then
Asa@4 394 addon:UpdateCurrentInventory()
Asa@23 395 self.watch_handle = self:RegisterBucketEvent({"BAG_UPDATE", "PLAYER_MONEY"}, 0.3, "UpdateAudit")
Asa@4 396 end
Asa@0 397 end
Asa@0 398
Asa@0 399 function addon:UnwatchBags()
Asa@4 400 if self.watch_handle ~= nil then
Asa@4 401 self:UnregisterBucket(self.watch_handle)
Asa@4 402 self.watch_handle = nil
Asa@4 403 end
Asa@0 404 end
Asa@0 405
Asa@9 406
Asa@9 407 function addon:GetSafeLink(link)
Asa@9 408 local newLink = nil
Asa@9 409
Asa@24 410 if link and link == string.match(link, '.-:[-0-9]+[:0-9]*') then
Asa@24 411 newLink = link
Asa@24 412 elseif link then
Asa@9 413 newLink = link and string.match(link, "|H(.-):([-0-9]+):([0-9]+)|h")
Asa@9 414 end
Asa@9 415 if newLink == nil then
Asa@9 416 local itemID = self:GetItemID(link)
Asa@9 417 if itemID ~= nil then
Asa@9 418 _, newLink = GetItemInfo(itemID)
Asa@9 419 return self:GetSafeLink(newLink)
Asa@9 420 end
Asa@9 421 end
Asa@9 422 return newLink and string.gsub(newLink, ":0:0:0:0:0:0", "")
Asa@9 423 end
Asa@9 424
Asa@9 425 function addon:GetIDFromLink(link)
Asa@9 426 local _, _, _, _, Id = string.find(link, "|?c?f?f?(%x*)|?H?([^:]*):?(%d+):?(%d*):?(%d*):?(%d*):?(%d*):?(%d*):?(%-?%d*):?(%-?%d*):?(%d*)|?h?%[?([^%[%]]*)%]?|?h?|?r?")
Asa@9 427 return tonumber(Id)
Asa@9 428 end
Asa@9 429
Asa@8 430 function addon:GetItemCost(link, countModifier)
Asa@9 431 local item = self:GetItem(link, true)
Asa@8 432
Asa@9 433 if item.invested > 0 then
Asa@9 434 local count = item.count
Asa@9 435
Asa@9 436 if countModifier ~= nil then
Asa@9 437 count = count - countModifier
Asa@0 438 end
Asa@9 439 if count > 0 then
Asa@45 440 return ceil(item.invested), ceil(item.invested/count), count
Asa@9 441 end
Asa@9 442
Asa@0 443 end
Asa@35 444 return 0, 0, Altoholic:GetItemCount(ItemAuditor:GetIDFromLink(link))
Asa@0 445 end