comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:169f5211fc7f
1 local addon = LibStub("AceAddon-3.0"):NewAddon("ItemAuditor", "AceConsole-3.0", "AceEvent-3.0", "AceBucket-3.0")
2
3 ItemAuditor = addon
4
5 local WHITE = "|cFFFFFFFF"
6 local RED = "|cFFFF0000"
7 local GREEN = "|cFF00FF00"
8 local YELLOW = "|cFFFFFF00"
9 local ORANGE = "|cFFFF7F00"
10 local TEAL = "|cFF00FF9A"
11 local GOLD = "|cFFFFD700"
12
13 function addon:OnInitialize()
14 -- declare defaults to be used in the DB
15 local DB_defaults = {
16 char = {
17 debug = false
18 },
19 factionrealm = {
20 item_account = {}
21 },
22 }
23 self.db = LibStub("AceDB-3.0"):New("ItemAuditorDB", DB_defaults, true)
24 self.db.factionrealm.backup = self.db.factionrealm.item_account
25
26 self.db.char.debug = true
27
28 --[[
29 Fine Thread = 510
30 Greater Magic Essence = 120000
31 Simple Kilt = 5913
32 Bolt of Linen Cloth = 5672
33 ]]
34
35 self:RegisterOptions()
36
37 self:Debug("Hello, world! OnInitialize")
38
39 self:RegisterEvent("MAIL_SHOW")
40 self:WatchBags()
41 end
42
43 function IA_tcount(tab)
44 local n = #tab
45 if (n == 0) then
46 for _ in pairs(tab) do
47 n = n + 1
48 end
49 end
50 return n
51 end
52
53
54 local options = {
55 name = "ItemAuditor",
56 handler = ItemAuditor,
57 type = 'group',
58 args = {
59 debug = {
60 type = "toggle",
61 name = "Debug",
62 desc = "Toggles debug messages in chat",
63 get = "GetDebug",
64 set = "SetDebug"
65 },
66 dump = {
67 type = "execute",
68 name = "dump",
69 desc = "dumps IA database",
70 func = "DumpInfo",
71 },
72 options = {
73 type = "execute",
74 name = "options",
75 desc = "Show Blizzard's options GUI",
76 func = "ShowOptionsGUI",
77 guiHidden = true,
78 },
79 },
80 }
81
82
83 function addon:DumpInfo()
84 self:Print("self.db.char")
85 DevTools_Dump(self.db.char)
86 self:Print("self.db.factionrealm")
87 DevTools_Dump(self.db.factionrealm)
88 end
89
90 function addon:RegisterOptions()
91 self.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("ItemAuditor", "ItemAuditor")
92
93 LibStub("AceConfig-3.0"):RegisterOptionsTable("ItemAuditor", options, {"ia"})
94
95 self:RegisterChatCommand("fuck", "ChatCommand")
96 end
97
98 function addon:GetMessage(info)
99 return self.message
100 end
101
102 function addon:SetMessage(info, newValue)
103 self.message = newValue
104 end
105
106
107 function addon:ShowOptionsGUI()
108 InterfaceOptionsFrame_OpenToCategory(self.optionsFrame)
109 end
110
111 function addon:GetDebug(info)
112 return self.db.char.debug
113 end
114
115 function addon:SetDebug(info, input)
116 self.db.char.debug = input
117 local value = "off"
118 if input then
119 value = "on"
120 end
121 self:Print("Debugging is now: " .. value)
122 end
123
124
125 -- ================ DEBUG ================
126 addon.OriginalRegisterEvent = addon.RegisterEvent
127 addon.OriginalUnregisterEvent = addon.UnregisterEvent
128
129 function addon:RegisterEvent(event, callback, arg)
130 self:Debug("RegisterEvent " .. event )
131 if arg ~= nil then
132 addon:OriginalRegisterEvent(event, callback, arg)
133 elseif callback ~= nil then
134 addon:OriginalRegisterEvent(event, callback)
135 else
136 addon:OriginalRegisterEvent(event)
137 end
138 end
139
140 function addon:UnregisterEvent(event)
141 self:Debug("UnregisterEvent " .. event )
142 addon:OriginalUnregisterEvent (event)
143 end
144
145 -- ================ DEBUG ================
146
147 function addon:FormatMoney(money)
148 return Altoholic:GetMoneyString(money, WHITE, false)
149 end
150
151 function addon:GetCurrentInventory()
152 local i = {}
153 local link
154
155 for bagID = 0, NUM_BAG_SLOTS do
156 bagSize=GetContainerNumSlots(bagID)
157 for slotID = 0, bagSize do
158 itemID = GetContainerItemID(bagID, slotID);
159
160 if itemID ~= nil then
161 _, itemCount, _, _, _= GetContainerItemInfo(bagID, slotID);
162 name = GetItemInfo(itemID)
163 if i[name] == nil then
164 i[name] = 0
165 end
166 i[name] = i[name] + (itemCount or 0)
167 end
168
169 end
170
171 end
172 return {items = i, money = GetMoney()}
173 end
174
175 function addon:GetInventoryDiff(pastInventory, current)
176 if current == nil then
177 current = self:GetCurrentInventory()
178 end
179 local diff = {}
180
181 for name, count in pairs(current.items) do
182 if pastInventory.items[name] == nil then
183 diff[name] = count
184 self:Debug("1 diff[" .. name .. "]=" .. diff[name])
185 elseif count - pastInventory.items[name] ~= 0 then
186 diff[name] = count - pastInventory.items[name]
187 self:Debug("2 diff[" .. name .. "]=" .. diff[name])
188 end
189 end
190
191 for name, count in pairs(pastInventory.items) do
192 if current.items[name] == nil then
193 diff[name] = -count
194 self:Debug("3 diff[" .. name .. "]=" .. diff[name])
195 elseif current.items[name] - count ~= 0 then
196 diff[name] = current.items[name] - pastInventory.items[name]
197 self:Debug("4 diff[" .. name .. "]=" .. diff[name])
198 end
199 end
200
201 local moneyDiff = current.money - pastInventory.money
202
203 return {items = diff, money = moneyDiff}
204 end
205
206
207 function addon:ScanMail()
208 local results = {}
209 for mailIndex = 1, GetInboxNumItems() or 0 do
210 local sender, msgSubject, msgMoney, msgCOD, _, msgItem, _, _, msgText, _, isGM = select(3, GetInboxHeaderInfo(mailIndex))
211 local mailType = Postal:GetMailType(msgSubject)
212
213 if mailType == "NonAHMail" then
214 -- Don't know how to handle these yet
215 elseif mailType == "AHSuccess" then
216 local invoiceType, itemName, playerName, bid, buyout, deposit, consignment = GetInboxInvoiceInfo(mailIndex);
217 if results[itemName] == nil then
218 results[itemName] = 0
219 end
220 results[itemName] = results[itemName] + deposit + buyout - consignment
221
222 elseif mailType == "AHWon" then
223 local invoiceType, itemName, playerName, bid, buyout, deposit, consignment = GetInboxInvoiceInfo(mailIndex);
224 if results[itemName] == nil then
225 results[itemName] = 0
226 end
227 results[itemName] = results[itemName] - bid
228 elseif mailType == "AHExpired" or mailType == "AHCancelled" then
229 -- These should be handled when you pay the deposit at the AH
230 else
231 self:Debug("Unhandled mail type: " .. mailType)
232 self:Debug(msgSubject)
233 end
234
235 end
236 return results
237 end
238
239 function addon:MAIL_SHOW()
240 self:Debug("MAIL_SHOW")
241 self.lastMailScan = self:ScanMail()
242 self:UnregisterEvent("MAIL_SHOW")
243 self:RegisterEvent("MAIL_CLOSED")
244 self:RegisterEvent("MAIL_INBOX_UPDATE")
245 self:Debug("MAIL_SHOW complete")
246 -- the mail scanner will handle everything
247 -- self:UnwatchBags()
248 end
249
250 function addon:MAIL_CLOSED()
251 addon:UnregisterEvent("MAIL_CLOSED")
252 self:UnregisterEvent("MAIL_INBOX_UPDATE")
253 self:RegisterEvent("MAIL_SHOW")
254 -- self:WatchBags()
255 end
256
257 function addon:MAIL_INBOX_UPDATE()
258 local newScan = addon:ScanMail()
259 local diff
260 for item, total in pairs(self.lastMailScan) do
261
262 if newScan[item] == nil then
263 newScan[item] = 0
264 end
265 diff = total - newScan[item]
266 if diff ~= 0 then
267 self:SaveValue(item, diff)
268 end
269
270 end
271
272 self.lastMailScan = newScan
273 end
274
275 function addon:SaveValue(item, value)
276 local item_account = self.db.factionrealm.item_account
277 if item_account[item] == nil then
278 item_account[item] = 0
279 end
280 item_account[item] = item_account[item] + value
281
282 if item_account[item] >= 0 then
283 item_account[item] = nil
284 end
285 end
286
287 function addon:OnEnable()
288 self:Debug("Hello, world! OnEnable")
289 end
290
291 function addon:Debug(msg)
292 if self.db.char.debug then
293 self:Print(msg)
294 end
295 end
296
297 function addon:WatchBags()
298 if self.watch_handle == nil then
299 self.lastInventory = self:GetCurrentInventory()
300 self.watch_handle = self:RegisterBucketEvent({"BAG_UPDATE", "PLAYER_MONEY"}, 0.2, "UpdateAudit")
301 end
302 end
303
304 function addon:UnwatchBags()
305 if self.watch_handle ~= nil then
306 self:UnregisterBucket(self.watch_handle)
307 self.watch_handle = nil
308 end
309 end
310
311 function addon:UpdateAudit()
312 self:Debug("UpdateAudit")
313 local currentInventory = self:GetCurrentInventory()
314 local diff = addon:GetInventoryDiff(self.lastInventory, currentInventory)
315 -- this is only here for debugging
316 self.lastdiff = diff
317
318 if abs(diff.money) > 0 and IA_tcount(diff.items) == 1 then
319 self:Debug("purchase or sale")
320
321 for itemName, count in pairs(diff.items) do
322 self:SaveValue(itemName, diff.money)
323 end
324 elseif IA_tcount(diff.items) > 1 then
325 local positive, negative = {}, {}
326 local positiveCount, negativeCount = 0, 0
327 for item, count in pairs(diff.items) do
328 if count > 0 then
329 positive[item] = count
330 positiveCount = positiveCount + count
331 elseif count < 0 then
332 negative[item] = count
333 negativeCount = negativeCount + abs(count)
334 end
335 end
336
337 if IA_tcount(positive) > 0 and IA_tcount(negative) > 0 then
338 -- we must have created/converted something
339 self:Debug("conversion")
340 local totalChange = 0
341 for itemName, change in pairs(negative) do
342 local _, itemCost, count = self:GetItemCost(itemName, change)
343 self:SaveValue(itemName, abs(itemCost * change))
344
345 totalChange = totalChange + abs(itemCost * change)
346 end
347
348 self:Debug("totalChange")
349 self:Debug(totalChange)
350
351 local valuePerItem = totalChange / positiveCount
352 self:Debug(valuePerItem )
353 for itemName, change in pairs(positive) do
354 self:Debug(itemName)
355 self:Debug(0-abs(valuePerItem * change))
356 self:SaveValue(itemName, 0-abs(valuePerItem * change))
357 end
358 end
359 end
360
361 self.lastInventory = currentInventory
362 end
363 -- /run ItemAuditor.db.factionrealm.item_account["Tiger Lily"] = -586625
364 -- /run ItemAuditor.db.factionrealm.item_account["Icy Pigment"] = -12303
365 -- /run ItemAuditor.db.factionrealm.item_account["Azure Pigment"] = -258357
366
367 function addon:GetItemCost(itemName, countModifier)
368 local invested = abs(self.db.factionrealm.item_account[itemName] or 0)
369
370 if invested > 0 then
371 local _, itemLink = GetItemInfo (itemName);
372 local _, _, _, _, Id = string.find(itemLink, "|?c?f?f?(%x*)|?H?([^:]*):?(%d+):?(%d*):?(%d*):?(%d*):?(%d*):?(%d*):?(%-?%d*):?(%-?%d*):?(%d*)|?h?%[?([^%[%]]*)%]?|?h?|?r?")
373 local count = Altoholic:GetItemCount(tonumber(Id))
374 if countModifier ~= nil then
375 count = count - countModifier
376 end
377 if count == 0 then
378 self.db.factionrealm.item_account[itemName] = nil
379 self:Print("You ran out of " .. itemName .. "and never recovered " .. self:FormatMoney(invested))
380 return 0, 0, 0
381 end
382 return ceil(invested), ceil(invested/count), count
383 end
384 return 0, 0, 0
385 end
386
387 function addon:ShowTooltip(tip, link, num)
388 if (link == nil) then
389 return;
390 end
391
392 local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, _, _, _, _, itemVendorPrice = GetItemInfo (link);
393 -- 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?")
394
395 local investedTotal, investedPerItem, count = self:GetItemCost(itemName)
396
397 local AHCut = 0.05
398 local keep = 1 - AHCut
399
400 if investedTotal > 0 then
401 tip:AddDoubleLine("\124cffffffffIA: Total Invested", self:FormatMoney(investedTotal));
402 tip:AddDoubleLine("\124cffffffffIA: Invested/Item (" .. count .. ")", self:FormatMoney(ceil(investedPerItem)));
403 tip:AddDoubleLine("\124cffffffffIA: Minimum faction AH Price: ", self:FormatMoney(ceil(investedPerItem/keep)))
404 tip:Show()
405 end
406 end
407
408 local function ShowTipWithPricing(tip, link, num)
409 addon:ShowTooltip(tip, link, num)
410 end
411
412 hooksecurefunc (GameTooltip, "SetBagItem",
413 function(tip, bag, slot)
414 local _, num = GetContainerItemInfo(bag, slot);
415 ShowTipWithPricing (tip, GetContainerItemLink(bag, slot), num);
416 end
417 );
418
419
420 hooksecurefunc (GameTooltip, "SetAuctionItem",
421 function (tip, type, index)
422 ShowTipWithPricing (tip, GetAuctionItemLink(type, index));
423 end
424 );
425
426 hooksecurefunc (GameTooltip, "SetAuctionSellItem",
427 function (tip)
428 local name, _, count = GetAuctionSellItemInfo();
429 local __, link = GetItemInfo(name);
430 ShowTipWithPricing (tip, link, num);
431 end
432 );
433
434
435 hooksecurefunc (GameTooltip, "SetLootItem",
436 function (tip, slot)
437 if LootSlotIsItem(slot) then
438 local link, _, num = GetLootSlotLink(slot);
439 ShowTipWithPricing (tip, link, num);
440 end
441 end
442 );
443
444 hooksecurefunc (GameTooltip, "SetLootRollItem",
445 function (tip, slot)
446 local _, _, num = GetLootRollItemInfo(slot);
447 ShowTipWithPricing (tip, GetLootRollItemLink(slot), num);
448 end
449 );
450
451
452 hooksecurefunc (GameTooltip, "SetInventoryItem",
453 function (tip, unit, slot)
454 ShowTipWithPricing (tip, GetInventoryItemLink(unit, slot), GetInventoryItemCount(unit, slot));
455 end
456 );
457
458 hooksecurefunc (GameTooltip, "SetGuildBankItem",
459 function (tip, tab, slot)
460 local _, num = GetGuildBankItemInfo(tab, slot);
461 ShowTipWithPricing (tip, GetGuildBankItemLink(tab, slot), num);
462 end
463 );
464
465 hooksecurefunc (GameTooltip, "SetTradeSkillItem",
466 function (tip, skill, id)
467 local link = GetTradeSkillItemLink(skill);
468 local num = GetTradeSkillNumMade(skill);
469 if id then
470 link = GetTradeSkillReagentItemLink(skill, id);
471 num = select (3, GetTradeSkillReagentInfo(skill, id));
472 end
473
474 ShowTipWithPricing (tip, link, num);
475 end
476 );
477
478 hooksecurefunc (GameTooltip, "SetTradePlayerItem",
479 function (tip, id)
480 local _, _, num = GetTradePlayerItemInfo(id);
481 ShowTipWithPricing (tip, GetTradePlayerItemLink(id), num);
482 end
483 );
484
485 hooksecurefunc (GameTooltip, "SetTradeTargetItem",
486 function (tip, id)
487 local _, _, num = GetTradeTargetItemInfo(id);
488 ShowTipWithPricing (tip, GetTradeTargetItemLink(id), num);
489 end
490 );
491
492 hooksecurefunc (GameTooltip, "SetQuestItem",
493 function (tip, type, index)
494 local _, _, num = GetQuestItemInfo(type, index);
495 ShowTipWithPricing (tip, GetQuestItemLink(type, index), num);
496 end
497 );
498
499 hooksecurefunc (GameTooltip, "SetQuestLogItem",
500 function (tip, type, index)
501 local num, _;
502 if type == "choice" then
503 _, _, num = GetQuestLogChoiceInfo(index);
504 else
505 _, _, num = GetQuestLogRewardInfo(index)
506 end
507
508 ShowTipWithPricing (tip, GetQuestLogItemLink(type, index), num);
509 end
510 );
511
512 hooksecurefunc (GameTooltip, "SetInboxItem",
513 function (tip, index, attachIndex)
514 local _, _, num = GetInboxItem(index, attachIndex);
515 ShowTipWithPricing (tip, GetInboxItemLink(index, attachIndex), num);
516 end
517 );
518
519 hooksecurefunc (GameTooltip, "SetSendMailItem",
520 function (tip, id)
521 local name, _, num = GetSendMailItem(id)
522 local name, link = GetItemInfo(name);
523 ShowTipWithPricing (tip, link, num);
524 end
525 );
526
527 hooksecurefunc (GameTooltip, "SetHyperlink",
528 function (tip, itemstring, num)
529 local name, link = GetItemInfo (itemstring);
530 ShowTipWithPricing (tip, link, num);
531 end
532 );
533
534 hooksecurefunc (ItemRefTooltip, "SetHyperlink",
535 function (tip, itemstring)
536 local name, link = GetItemInfo (itemstring);
537 ShowTipWithPricing (tip, link);
538 end
539 );