comparison Modules/Events.lua @ 144:03e108d12ef1

Ticket 45 - Added the ability suppress COD warnings when mailing to characters on other accounts in Altoholic/DataStore. Instead of sending COD, ItemAuditor will send tracking info in the message. Thanks to Zerotorescue for giving me the solution to detect whether or not Postal or MailOpener is processing. It was the last step holding this back from being released.
author Asa Ayers <Asa.Ayers@Gmail.com>
date Sat, 09 Oct 2010 00:21:06 -0700
parents 828cd9bf919e
children 47885ba83d38
comparison
equal deleted inserted replaced
143:4d7955b2d240 144:03e108d12ef1
103 totalStacks = totalStacks + 1 103 totalStacks = totalStacks + 1
104 attachedItems[newLink] = (attachedItems[newLink] or {stacks = 0, count = 0}) 104 attachedItems[newLink] = (attachedItems[newLink] or {stacks = 0, count = 0})
105 attachedItems[newLink].stacks = attachedItems[newLink].stacks + 1 105 attachedItems[newLink].stacks = attachedItems[newLink].stacks + 1
106 attachedItems[newLink].count = attachedItems[newLink].count + itemCount 106 attachedItems[newLink].count = attachedItems[newLink].count + itemCount
107 attachedItems[newLink].price = 0 -- This is a placeholder for below. 107 attachedItems[newLink].price = 0 -- This is a placeholder for below.
108 attachedItems[newLink].costEach = select(2, ItemAuditor:GetItemCost(newLink))
108 end 109 end
109 end 110 end
110 local attachedValue = 0 111 local attachedValue = 0
111 for link, data in pairs(attachedItems) do 112 for link, data in pairs(attachedItems) do
112 data.price = 30 * data.stacks 113 data.price = 30 * data.stacks
113 attachedValue = attachedValue + data.price + (select(2, ItemAuditor:GetItemCost(link)) * data.stacks) 114 attachedValue = attachedValue + data.price + (data.costEach * data.count)
114 end 115 end
115 116
116 local cross_account_mail = true 117 local destinationType = 'unknown'
117 for name, _ in pairs(DataStore:GetCharacters()) do 118 local realm = GetRealmName()
118 if strlower(recipient) == strlower(name) then 119 for account in pairs(DataStore:GetAccounts()) do
119 cross_account_mail = false 120 for character in pairs(DataStore:GetCharacters(realm, account)) do
120 break 121 if strlower(recipient) == strlower(character) then
121 end 122 destinationType = (account == 'Default') and 'same_account' or 'owned_account'
122 end 123 destinationType = 'owned_account'
123 if cross_account_mail and attachedValue > self.mailOutbox.COD and not skipCODCheck and ItemAuditor.db.char.cod_warnings then 124 break
125 end
126 end
127 end
128 self.mailOutbox.destinationType = destinationType
129 if destinationType == 'unknown' and attachedValue > self.mailOutbox.COD and not skipCODCheck and ItemAuditor.db.char.cod_warnings then
124 self:GenerateBlankOutbox() 130 self:GenerateBlankOutbox()
125 skipCODCheck = false; 131 skipCODCheck = false;
126 local vararg = ... 132 local vararg = ...
127 StaticPopupDialogs["ItemAuditor_Insufficient_COD"].OnAccept = function() 133 StaticPopupDialogs["ItemAuditor_Insufficient_COD"].OnAccept = function()
128 skipCODCheck = true 134 skipCODCheck = true
129 SendMail(recipient, subject, body, vararg) 135 SendMail(recipient, subject, body, vararg)
130 skipCODCheck = false 136 skipCODCheck = false
131 end 137 end
132 StaticPopup_Show ("ItemAuditor_Insufficient_COD", Utils.FormatMoney(attachedValue)); 138 StaticPopup_Show ("ItemAuditor_Insufficient_COD", Utils.FormatMoney(attachedValue));
133 return 139 return
140 elseif destinationType == 'owned_account' then
141 -- If we are mailing to an alt on a different account, a uniqueue tracking number
142 -- is generated and all of the needed data is attached to the message.
143 -- The tracking number is only used to make sure the other character doesn't count the
144 -- mail more than once.
145 local key = time()..":"..random(10000)
146 self.mailOutbox.attachedItems = attachedItems
147 body = body .. ItemAuditor.TRACKING_DATA_DIVIDER .. ItemAuditor:Serialize(key, attachedItems)
134 elseif self.mailOutbox.COD > 0 and skipCODTracking then 148 elseif self.mailOutbox.COD > 0 and skipCODTracking then
135 149
136 elseif self.mailOutbox.COD > 0 then 150 elseif self.mailOutbox.COD > 0 then
137 if self:tcount(attachedItems) > 1 then 151 if self:tcount(attachedItems) > 1 then
138 self:GenerateBlankOutbox() 152 self:GenerateBlankOutbox()
166 function ItemAuditor:MAIL_SUCCESS(event) 180 function ItemAuditor:MAIL_SUCCESS(event)
167 skipCODTracking = false 181 skipCODTracking = false
168 skipCODCheck = false 182 skipCODCheck = false
169 183
170 for link, data in pairs(attachedItems) do 184 for link, data in pairs(attachedItems) do
185 -- When mailing to an alt on a different account, we still
186 -- should add the price of postage, but need to subtract the
187 -- cost of the items. This will simulate CODing the mail and
188 -- getting the money back, except that postage is paid by the
189 -- sender
190 if self.mailOutbox.destinationType == 'owned_account' then
191 data.price = data.price - (data.costEach * data.count)
192 end
171 self:SaveValue(link, data.price, data.count) 193 self:SaveValue(link, data.price, data.count)
172 end 194 end
173 if self.mailOutbox.COD > 0 then 195 if self.mailOutbox.COD > 0 then
174 self:Debug(format("MAIL_SUCCESS %d [To: %s] [Subject: %s] [COD: %s]", self.mailOutbox.key, self.mailOutbox.to, self.mailOutbox.subject, self.mailOutbox.COD)) 196 self:Debug(format("MAIL_SUCCESS %d [To: %s] [Subject: %s] [COD: %s]", self.mailOutbox.key, self.mailOutbox.to, self.mailOutbox.subject, self.mailOutbox.COD))
175 197
188 self:UnregisterEvent("MAIL_INBOX_UPDATE") 210 self:UnregisterEvent("MAIL_INBOX_UPDATE")
189 self:RegisterEvent("MAIL_SHOW") 211 self:RegisterEvent("MAIL_SHOW")
190 self.mailOpen = nil 212 self.mailOpen = nil
191 end 213 end
192 214
215 local function CanMailBeDeleted(mailIndex)
216 local msgMoney, _, _, msgItem = select(5, GetInboxHeaderInfo(mailIndex))
217 local body = GetInboxText(mailIndex)
218 if msgMoney == 0 and msgItem == nil and body and body:find(ItemAuditor.TRACKING_DATA_DIVIDER) then
219 local serialized = body:gsub('.*'..ItemAuditor.TRACKING_DATA_DIVIDER, '')
220 local body = body:gsub(ItemAuditor.TRACKING_DATA_DIVIDER..'.*', '')
221 local success, trackingID, data = ItemAuditor:Deserialize(serialized)
222 if success and body == '' then
223 return true
224 end
225 end
226 return false
227 end
228
229 local Postal_L
230 local function blockMailOperations()
231 if MailAddonBusy == 'ItemAuditor' then
232 return false
233 end
234 if Postal_L == nil then
235 local locale = LibStub("AceLocale-3.0", true)
236 Postal_L = locale and locale:GetLocale("Postal", true)
237 end
238 return MailAddonBusy or PostalOpenAllButton and Postal_L and PostalOpenAllButton:GetText() == Postal_L["In Progress"]
239 end
240
193 local storedCountDiff 241 local storedCountDiff
194 function ItemAuditor:MAIL_INBOX_UPDATE() 242 function ItemAuditor:MAIL_INBOX_UPDATE()
195 self:Debug("MAIL_INBOX_UPDATE") 243 self:Debug("MAIL_INBOX_UPDATE")
196 local newScan = ItemAuditor:ScanMail() 244 self.deleteQueue = nil
245 local newScan = self:ScanMail()
197 local diff 246 local diff
198 247
199 for mailType, collection in pairs(self.lastMailScan) do 248 for mailType, collection in pairs(self.lastMailScan) do
200 newScan[mailType] = (newScan[mailType] or {}) 249 newScan[mailType] = (newScan[mailType] or {})
201 for itemName, data in pairs(collection) do 250 for itemName, data in pairs(collection) do
224 273
225 end 274 end
226 end 275 end
227 276
228 self.lastMailScan = newScan 277 self.lastMailScan = newScan
278
279 if self.deleteQueue and not self.deleteScheduled then
280 -- For some reason DeleteInboxItem will not trigger a MAIL_INBOX_UPDATE
281 -- if it is called from here, so I have to use a timer to get it
282 -- to run outside of this function.
283
284 -- If the mailbox is full of items to be deleted, this will speed up because
285 -- postal shouldn't be running at this point. Keeping at 0.1 breaks postal.
286 local delay = (GetInboxNumItems() > #(self.deleteQueue)) and 1 or 0.1
287 self:ScheduleTimer("ProcessDeleteQueue", delay)
288 self.deleteScheduled = true
289 elseif MailAddonBusy == 'ItemAuditor' then
290 MailAddonBusy = nil
291 end
292 end
293
294 function ItemAuditor:ProcessDeleteQueue()
295 if blockMailOperations() then
296 self:ScheduleTimer("ProcessDeleteQueue", 1)
297 return
298 end
299 self.deleteScheduled = false
300 if self.deleteQueue then
301 MailAddonBusy = 'ItemAuditor'
302 while #(self.deleteQueue) > 0 do
303 local mailIndex = table.remove(self.deleteQueue)
304 if CanMailBeDeleted(mailIndex) then
305 DeleteInboxItem(mailIndex)
306 -- This returns after the first item because you can't delete
307 -- all mail at once and this is in a loop so that if for some
308 -- reason CanMailBeDeleted returns false, we can delete the next
309 -- mail in the queue instead.
310 return
311 end
312 end
313 else
314 MailAddonBusy = nil
315 end
229 end 316 end
230 317
231 function ItemAuditor:UNIT_SPELLCAST_START(event, target, spell) 318 function ItemAuditor:UNIT_SPELLCAST_START(event, target, spell)
232 if target == "player" and spell == "Milling" or spell == "Prospecting" or spell == "Disenchanting" then 319 if target == "player" and spell == "Milling" or spell == "Prospecting" or spell == "Disenchanting" then
233 self:Debug(event .. " " .. spell) 320 self:Debug(event .. " " .. spell)