/
JuggyCompare.lua
315 lines (261 loc) · 8.17 KB
/
JuggyCompare.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
-------------------------------------------------------------------------------
-- Locals --
-------------------------------------------------------------------------------
-- Takes the JuggyCompare_Data tables and stores it in a format we want
local data = {}
-- This table value gets wiped out later, so store it locally
local updated = JuggyCompare_Data.updated
-- This addon's public now, so only accept comparison tells from very specific people!
local officers = {
'tsigo', 'kamien',
'sebudai',
'souai',
'duskshadow',
'baud', 'baudz',
'ruhntar', 'parawon'
}
local pairs, getmetatable, setmetatable = _G.pairs, _G.getmetatable, _G.setmetatable
-- Copy a table value to a new table
local function tcopy(t)
local new = {}
for key, value in pairs(t) do
new[ key ] = value
end
local m = getmetatable(t)
if m then setmetatable(new,m) end
return new
end
-------------------------------------------------------------------------------
-- AddOn Declaration --
-------------------------------------------------------------------------------
local mod = LibStub("AceAddon-3.0"):NewAddon("JuggyCompare", "AceConsole-3.0", "AceEvent-3.0")
function mod:OnInitialize()
self:RegisterChatCommand('jcomp', 'PrintInfo')
self:RegisterChatCommand('compare', 'OnCompare')
self.display = {} -- Temporary table that gets sorted and printed
JuggyCompare_Data.updated = nil
for _,t in pairs(JuggyCompare_Data) do
local v = {
name = t.NAME,
raids_30 = t.RAIDS_30,
raids_90 = t.RAIDS_90,
raids_lt = t.RAIDS_LT,
lastloot = t.LASTLOOT,
lf = t.LF,
slf = t.SLF,
bislf = t.BISLF,
sortlf = t.LF,
}
table.insert(data, v)
end
end
function mod:OnEnable()
self.display = {}
self:RegisterEvent("CHAT_MSG_WHISPER", "OnWhisper")
end
function mod:OnDisable()
self.display = nil
self:UnregisterEvent("CHAT_MSG_WHISPER")
end
function mod:PrintInfo(args)
if args == "" or args == 'updated' then
self:Print("Data updated: " .. updated)
end
end
-------------------------------------------------------------------------------
-- Events --
-------------------------------------------------------------------------------
function mod:OnCompare(msg)
msg = "compare " .. msg
self:OnWhisper("CHAT_MSG_WHISPER", msg, UnitName("player"))
end
function mod:OnWhisper(event, msg, sender)
self.display = {}
if not self:ValidateSender(sender) then return end
if string.find(msg, '^compare') then
local args = string.gsub(msg, "^compare ", "")
local list = old_strsplit(",%s*", args)
if table.getn(list) == 0 then return end
-- Print the header
local _,_, itemId = string.find(list[1], "item:(%d+):")
if itemId == nil and string.find(list[1], "^%[(.+)%]$") then
itemId = list[1]
end
if itemId ~= nil then
self:PrintHeader(sender, itemId)
list[1] = nil
else
self:PrintHeader(sender)
end
-- Populate self.display table with member data
for k,v in pairs(list) do
self:ParseArgument(v)
end
-- Sort and print the display rows
self:DoCompare()
end
end
-------------------------------------------------------------------------------
-- AddOn Methods --
-------------------------------------------------------------------------------
function mod:PrintHeader(sender, item)
local str = "--"
-- Insert the sender into the header
sender = (sender == nil) and UnitName("player") or sender
str = str .. string.format(" %s -", sender)
-- Insert the item name into the header
local itemName = nil
if item ~= nil then
if string.find(item, "^%[(.+)%]$") then
itemName = select(3, item:find("^%[(.+)%]$"))
else
itemName = GetItemInfo(item)
end
if itemName ~= nil then
str = str .. string.format(" %s -", itemName)
end
end
str = pad(str, 60, "-")
self:Message(str)
end
function mod:ParseArgument(arg)
local split = {}
-- Split by words; [1] = name, [[2] = telltype]
string.gsub(arg, "(%w+)", function(w) table.insert(split, w) end)
if table.getn(split) == 0 then return end
local member = self:PlayerExists(split[1])
if member >= 0 then
local row = tcopy(data[member])
if split[2] ~= nil then
row.telltype = string.upper(split[2])
if row.telltype == "BES" or row.telltype == "BIS" or row.telltype == "BISROT" then
row.sortlf = tonumber(row.bislf) - 500 -- Sort BiS before everything
elseif row.telltype == "ROT" then
row.sortlf = tonumber(row.lf) + 500 -- Sort rot after normal
elseif row.telltype == "SIT" then
row.sortlf = tonumber(row.slf) + 999 -- Sort sit after rot
elseif row.telltype == "NOR" then
row.sortlf = tonumber(row.lf) -- Normal is normal!
row.telltype = nil
else
row.sortlf = tonumber(row.lf) + 1500 -- ?
end
else
row.sortlf = row.lf
row.telltype = nil
end
table.insert(self.display, row)
else
-- Insert an error'd data[member] to be output later, using a high LF so the sort doesn't get messed up
table.insert(self.display, { name = split[1], err = "Not found", lf = "0.00", sortlf = 99999 })
end
end
function mod:DoCompare()
table.sort(self.display, function(a, b) return tonumber(a.sortlf) < tonumber(b.sortlf) end)
for _, row in pairs(self.display) do
local str = nil
if type(row) ~= "table" then return end
if row.lf == nil then return end
if row.err == nil then
str = pad(row.name, 15) ..
pad(row.raids_30, -4) ..
pad(row.lastloot, -13) ..
""
if row.telltype == "BES" or row.telltype == "BIS" then
str = str .. pad(row.bislf, -8)
str = str .. pad("BiS", -8)
elseif row.telltype == "BISROT" then
str = str .. pad(row.bislf, -8)
str = str .. pad("BiSROT", -8)
elseif row.telltype == "SIT" then
str = str .. pad(row.slf, -8)
str = str .. pad("SIT", -8)
else
str = str .. pad(row.lf, -8)
-- Show ROT/FERAL/etc.?
if row.telltype ~= nil then
str = str .. pad(row.telltype, -8)
end
end
else
str = pad(row.name, 15) .. row.err
end
self:Message(str)
end
end
function mod:PlayerExists(player)
for i=1, #data do
if string.lower(data[i].name) == string.lower(player) then
return i
end
end
-- Wasn't found in the main table, check nicknames
for nick, full in pairs(JuggyCompare_Nicks) do
if string.lower(nick) == string.lower(player) then
-- Found their nickname, recurse with the full name
return self:PlayerExists(full)
end
end
-- Still no match, attempt to match the start of a string
-- Must be at least three characters long to check for a match
if string.len(player) >= 3 then
for i=1, #data do
if string.find(string.lower(data[i].name), "^" .. string.lower(player)) then
return i
end
end
end
return -1
end
function mod:Message(msg)
SendChatMessage(msg, "OFFICER")
--self:Print(msg)
end
function mod:ValidateSender(arg1)
return tcontains(officers, arg1)
end
-------------------------------------------------------------------------------
-- Convenience Functions --
-------------------------------------------------------------------------------
-- Check if a table contains a value
function tcontains(t, value)
for k,v in pairs(t) do
if v == value or string.lower(v) == string.lower(value) then
return true
end
end
return false
end
-- Justify a string
-- s: string to justify
-- width: width to justify to (+ve means right-justify; negative
-- means left-justify)
-- [padder]: string to pad with (" " if omitted)
-- returns
-- s: justified string
function pad(s, width, padder)
padder = string.rep(padder or " ", math.abs(width))
if width < 0 then return string.sub(padder .. s, width) end
return string.sub(s .. padder, 1, width)
end
-- Split text into a list consisting of the strings in text,
-- separated by strings matching delimiter (which may be a pattern).
-- example: strsplit(",%s*", "Anna, Bob, Charlie,Dolores")
function old_strsplit(delimiter, text)
local list = {}
local pos = 1
if strfind("", delimiter, 1) then -- this would result in endless loops
error("delimiter matches empty string!")
end
while 1 do
local first, last = strfind(text, delimiter, pos)
if first then -- found?
table.insert(list, strsub(text, pos, first-1))
pos = last+1
else
table.insert(list, strsub(text, pos))
break
end
end
return list
end