File Flowerpicker.lua changed (mode: 100644) (index 3f5c528..dbb5427) |
|
1 |
|
--[[ begin http://lua-users.org/wiki/TimeZone ]]-- |
|
2 |
|
-- Compute the difference in seconds between local time and UTC. |
|
3 |
|
local function get_timezone() |
|
4 |
|
local now = time() |
|
5 |
|
return difftime(now, time(date("!*t", now))) |
|
6 |
|
end |
|
7 |
|
-- timezone = get_timezone() |
|
8 |
|
|
|
9 |
|
-- Return a timezone string in ISO 8601:2000 standard form (+hhmm or -hhmm) |
|
10 |
|
local function get_tzoffset(timezone) |
|
11 |
|
local h, m = math.modf(timezone / 3600) |
|
12 |
|
return string.format("%+.4d", 100 * h + 60 * m) |
|
13 |
|
end |
|
14 |
|
-- tzoffset = get_tzoffset(timezone) |
|
15 |
|
|
|
16 |
|
|
|
17 |
|
--[[ debugging |
|
18 |
|
for _, tz in ipairs(arg) do |
|
19 |
|
if tz == '-' then |
|
20 |
|
tz = timezone |
|
21 |
|
else |
|
22 |
|
tz = 0 + tz |
|
23 |
|
end |
|
24 |
|
print(tz, get_tzoffset(tz)) |
|
25 |
|
end |
|
26 |
|
--]] |
|
27 |
|
|
|
28 |
|
-- return the timezone offset in seconds, as it was on the time given by ts |
|
29 |
|
-- Eric Feliksik |
|
30 |
|
local function get_timezone_offset(ts) |
|
31 |
|
local utcdate = date("!*t", ts) |
|
32 |
|
local localdate = date("*t", ts) |
|
33 |
|
localdate.isdst = false -- this is the trick |
|
34 |
|
return difftime(time(localdate), time(utcdate)) |
|
35 |
|
end |
|
36 |
|
--[[ end http://lua-users.org/wiki/TimeZone ]]-- |
|
37 |
|
|
1 |
38 |
--[[ Security, reliability. ]]-- |
--[[ Security, reliability. ]]-- |
2 |
39 |
|
|
3 |
40 |
local function sanitiseShort(supposedNumber) |
local function sanitiseShort(supposedNumber) |
|
... |
... |
local function sanitiseTimestamp(supposedTimestamp) |
16 |
53 |
local sane = nil |
local sane = nil |
17 |
54 |
if nil == supposedTimestamp then |
if nil == supposedTimestamp then |
18 |
55 |
elseif 'string' == type(supposedTimestamp) then |
elseif 'string' == type(supposedTimestamp) then |
19 |
|
sane = string.sub(strtrim(supposedTimestamp), 1, 19) |
|
|
56 |
|
sane = string.sub(strtrim(supposedTimestamp), 1, 24) |
20 |
57 |
else |
else |
21 |
58 |
sane = nil |
sane = nil |
22 |
59 |
end |
end |
|
... |
... |
local function validateAnyName(supposedName, lengthMin, lengthMax) |
71 |
108 |
end |
end |
72 |
109 |
|
|
73 |
110 |
local len = string.len(supposedName) |
local len = string.len(supposedName) |
74 |
|
isValid = (len >= lengthMin or len <= lengthMax) and isValid |
|
|
111 |
|
isValid = (len >= lengthMin and len <= lengthMax) and isValid |
75 |
112 |
if not isValid then |
if not isValid then |
76 |
113 |
errorMsg = string.format('String length %d not in [%d, %d].', len, lengthMin, lengthMax) |
errorMsg = string.format('String length %d not in [%d, %d].', len, lengthMin, lengthMax) |
77 |
114 |
return isValid, errorMsg |
return isValid, errorMsg |
|
... |
... |
local function validateTimestamp(t) |
84 |
121 |
local isValid = true |
local isValid = true |
85 |
122 |
local errorMsg = nil |
local errorMsg = nil |
86 |
123 |
|
|
87 |
|
isValid, errorMsg = validateAnyName(t, 19, 19) |
|
|
124 |
|
isValid, errorMsg = validateAnyName(t, 24, 24) |
88 |
125 |
if not isValid then |
if not isValid then |
89 |
126 |
return isValid, errorMsg |
return isValid, errorMsg |
90 |
127 |
end |
end |
91 |
128 |
|
|
92 |
129 |
--[[ |
--[[ |
93 |
|
-- os.date('%Y-%m-%d %H:%M:%S', os.time()) |
|
94 |
|
-- ex, 2019-11-05 14:28:30 |
|
|
130 |
|
-- os.date('%Y-%m-%d %H:%M:%S%z', os.time()) |
|
131 |
|
-- ex, 2019-11-05 14:28:30+0200 |
95 |
132 |
]]-- |
]]-- |
96 |
|
isValid = t == string.match(t, '%d%d%d%d--%d%d--%d%d %d%d:%d%d:%d%d') and isValid |
|
|
133 |
|
isValid = t == string.match(t, '%d%d%d%d--%d%d--%d%d %d%d:%d%d:%d%d++%d%d%d%d') and isValid |
97 |
134 |
if not isVallid then |
if not isVallid then |
98 |
135 |
errorMsg = 'Is not a timestamp.' |
errorMsg = 'Is not a timestamp.' |
99 |
136 |
return isValid, errorMsg |
return isValid, errorMsg |
|
... |
... |
local function isPermissibleSpellToProduceLoot(spellName) |
178 |
215 |
return result |
return result |
179 |
216 |
end |
end |
180 |
217 |
|
|
181 |
|
local function createEventHarvest(harvestTypeDesignation, realmName, harvesterName, sourceName, harvestTimestamp, harvestedItemName, harvestedItemQuantity) |
|
182 |
|
local d = sanitiseAnyName(harvestTypeDesignation) |
|
|
218 |
|
local function createEventHarvest(realmName, harvesterName, zoneName, subzoneName, harvestTimestamp, harvestTypeDesignation, sourceName, harvestedItemName, harvestedItemQuantity) |
183 |
219 |
local r = sanitiseAnyName(realmName) |
local r = sanitiseAnyName(realmName) |
184 |
220 |
local c = sanitiseAnyName(harvesterName) |
local c = sanitiseAnyName(harvesterName) |
185 |
|
local s = sanitiseAnyName(sourceName) |
|
|
221 |
|
local z = sanitiseAnyName(zoneName) |
|
222 |
|
local sz = sanitiseAnyName(subzoneName) |
186 |
223 |
local t = sanitiseTimestamp(harvestTimestamp) |
local t = sanitiseTimestamp(harvestTimestamp) |
|
224 |
|
local d = sanitiseAnyName(harvestTypeDesignation) |
|
225 |
|
local s = sanitiseAnyName(sourceName) |
187 |
226 |
local i = sanitiseAnyName(harvestedItemName) |
local i = sanitiseAnyName(harvestedItemName) |
188 |
227 |
local q = sanitiseShort(harvestedItemQuantity) |
local q = sanitiseShort(harvestedItemQuantity) |
189 |
|
assert (validateEnum(d, getPermissibleHarvestTypeSet())) |
|
190 |
228 |
assert (validateAnyName(r)) |
assert (validateAnyName(r)) |
191 |
229 |
assert (validateAnyName(c)) |
assert (validateAnyName(c)) |
192 |
|
assert (validateAnyName(s)) |
|
|
230 |
|
assert (validateAnyName(z)) |
|
231 |
|
assert (validateAnyName(sz)) |
193 |
232 |
assert (validateTimestamp(t)) |
assert (validateTimestamp(t)) |
|
233 |
|
assert (validateEnum(d, getPermissibleHarvestTypeSet())) |
|
234 |
|
assert (validateAnyName(s)) |
194 |
235 |
assert (validateAnyName(i)) |
assert (validateAnyName(i)) |
195 |
236 |
assert (validatePositiveAndNonZero(q)) |
assert (validatePositiveAndNonZero(q)) |
196 |
237 |
|
|
197 |
238 |
local event = { |
local event = { |
198 |
|
d, r, c, s, t, i, q |
|
|
239 |
|
r, c, z, sz, t, d, s, i, q |
199 |
240 |
} |
} |
200 |
241 |
|
|
201 |
242 |
assert (event ~= nil) |
assert (event ~= nil) |
|
... |
... |
local function updateLootCache() |
243 |
284 |
end |
end |
244 |
285 |
end |
end |
245 |
286 |
|
|
|
287 |
|
local function processLoot(slotId, lastSpellCastName, lootedCorpseGuessedName) |
|
288 |
|
local spellName = sanitiseAnyName(lastSpellCastName) |
|
289 |
|
local d |
|
290 |
|
local s |
|
291 |
|
if isPermissibleSpellToProduceLoot(spellName) then |
|
292 |
|
assert (validateAnyName(spellName)) |
|
293 |
|
d = mapSpellNameToHarvestTypeDesignation(spellName) |
|
294 |
|
else |
|
295 |
|
d = 'LOOTCORPSE' |
|
296 |
|
s = sanitiseAnyName(lootedCorpseGuessedName) |
|
297 |
|
assert (validateAnyName(s)) |
|
298 |
|
end |
|
299 |
|
assert (validateEnum(d, getPermissibleHarvestTypeSet())) |
|
300 |
|
local r = sanitiseAnyName(GetRealmName()) |
|
301 |
|
assert (validateAnyName(r)) |
|
302 |
|
local p = sanitiseAnyName(UnitName('player')) |
|
303 |
|
assert (validateAnyName(p)) |
|
304 |
|
local t = date('%Y-%m-%d %H:%M:%S', time()) .. get_tzoffset(get_timezone()) |
|
305 |
|
local lootCache = FlowerpickerLootCache |
|
306 |
|
assert (lootCache ~= nil) |
|
307 |
|
assert ('table' == type(lootCache)) |
|
308 |
|
local lootedItem = lootCache[slotId] |
|
309 |
|
assert (lootedItem ~= nil) |
|
310 |
|
assert ('table' == type(lootedItem)) |
|
311 |
|
local i = sanitiseAnyName(lootedItem[2]) |
|
312 |
|
assert (validateAnyName(i)) |
|
313 |
|
local q = sanitiseShort(lootedItem[3]) |
|
314 |
|
assert (validatePositiveAndNonZero(q)) |
|
315 |
|
local z = sanitiseAnyName(GetZoneText()) |
|
316 |
|
if nil == z or string.len(z) <= 0 then |
|
317 |
|
z = 'Unknown Zone' |
|
318 |
|
end |
|
319 |
|
local sz = sanitiseAnyName(GetSubZoneText()) |
|
320 |
|
if nil == sz or string.len(sz) <= 0 then |
|
321 |
|
sz = 'Unknown Subzone' |
|
322 |
|
end |
|
323 |
|
local e = createEventHarvest(r, p, z, sz, t, d, s, i, q) |
|
324 |
|
table.insert(FlowerpickerSavedVariables, e) |
|
325 |
|
end |
|
326 |
|
|
246 |
327 |
local function main(self, event, arg1, arg2, arg3, arg4, arg5) |
local function main(self, event, arg1, arg2, arg3, arg4, arg5) |
247 |
328 |
assert (self ~= nil) |
assert (self ~= nil) |
248 |
329 |
assert ('table' == type(self)) |
assert ('table' == type(self)) |
|
... |
... |
local function main(self, event, arg1, arg2, arg3, arg4, arg5) |
264 |
345 |
local slotId = sanitiseShort(arg1) |
local slotId = sanitiseShort(arg1) |
265 |
346 |
assert (slotId ~= nil) |
assert (slotId ~= nil) |
266 |
347 |
assert ('number' == type(slotId)) |
assert ('number' == type(slotId)) |
267 |
|
local spellName = sanitiseAnyName(self.api.lastSpellCastName) |
|
268 |
|
local d |
|
269 |
|
local s |
|
270 |
|
if isPermissibleSpellToProduceLoot(spellName) then |
|
271 |
|
assert (validateAnyName(spellName)) |
|
272 |
|
d = mapSpellNameToHarvestTypeDesignation(spellName) |
|
273 |
|
else |
|
274 |
|
d = 'LOOTCORPSE' |
|
275 |
|
s = sanitiseAnyName(self.api.lootedCorpseGuessedName) |
|
276 |
|
assert (validateAnyName(s)) |
|
277 |
|
end |
|
278 |
|
assert (validateEnum(d, getPermissibleHarvestTypeSet())) |
|
279 |
|
local r = sanitiseAnyName(GetRealmName()) |
|
280 |
|
assert (validateAnyName(r)) |
|
281 |
|
local p = sanitiseAnyName(UnitName('player')) |
|
282 |
|
assert (validateAnyName(p)) |
|
283 |
|
local t = date('%Y-%m-%d %H:%M:%S', time()) |
|
284 |
|
local lootCache = FlowerpickerLootCache |
|
285 |
|
assert (lootCache ~= nil) |
|
286 |
|
assert ('table' == type(lootCache)) |
|
287 |
|
local lootedItem = lootCache[slotId] |
|
288 |
|
assert (lootedItem ~= nil) |
|
289 |
|
assert ('table' == type(lootedItem)) |
|
290 |
|
local i = sanitiseAnyName(lootedItem[2]) |
|
291 |
|
assert (validateAnyName(i)) |
|
292 |
|
local q = sanitiseShort(lootedItem[3]) |
|
293 |
|
assert (validatePositiveAndNonZero(q)) |
|
294 |
|
local e = createEventHarvest(d, r, p, s, t, i, q) |
|
295 |
|
table.insert(FlowerpickerSavedVariables, e) |
|
296 |
|
print(d, r, p, s, t, i, q) |
|
297 |
|
--updateLootCache() |
|
298 |
|
--[[local flowerpickerEvent = createEventHarvest( |
|
299 |
|
) |
|
300 |
|
FlowerpickerSavedVariables[] = flowerpickerEvent]]-- |
|
301 |
|
elseif 'LOOT_SLOT_CHANGED' == event then |
|
302 |
|
print(event, arg1, arg2, arg3) |
|
|
348 |
|
local lastSpellCastName = sanitiseAnyName(self.api.lastSpellCastName) |
|
349 |
|
local corpseName = sanitiseAnyName(self.api.lootedCorpseGuessedName) |
|
350 |
|
processLoot(slotId, lastSpellCastName, corpseName) |
303 |
351 |
elseif 'LOOT_CLOSED' == event then |
elseif 'LOOT_CLOSED' == event then |
304 |
352 |
FlowerpickerLootCache = {} |
FlowerpickerLootCache = {} |
305 |
353 |
self.api.lootedCorpseGuessedName = nil |
self.api.lootedCorpseGuessedName = nil |
|
... |
... |
local function init() |
337 |
385 |
local api = { |
local api = { |
338 |
386 |
['createEventHarvest'] = createEventHarvest, |
['createEventHarvest'] = createEventHarvest, |
339 |
387 |
['lootCache'] = lootCache, |
['lootCache'] = lootCache, |
|
388 |
|
['lootedCorpseGuessedName'] = nil, |
340 |
389 |
['lastSpellCastName'] = nil |
['lastSpellCastName'] = nil |
341 |
390 |
} |
} |
342 |
391 |
addonFrame.api = api |
addonFrame.api = api |