farmbuyer@10
|
1 -- This file is one gigantic exercise in abusing the garbage collector via
|
farmbuyer@10
|
2 -- string manipulation. A real XML-handling library would be cleaner, alas,
|
farmbuyer@10
|
3 -- we can't load third-party .so/.dll inside the WoW client. Life is hard.
|
farmbuyer@10
|
4
|
farmbuyer@1
|
5 local addon = select(2,...)
|
farmbuyer@10
|
6 local pairs, ipairs, tinsert, tremove, tconcat = pairs, ipairs, table.insert, table.remove, table.concat
|
farmbuyer@10
|
7 local tostring, tonumber = tostring, tonumber
|
farmbuyer@10
|
8
|
farmbuyer@10
|
9 local banner_formatted = "Formatted version (scroll down for unformatted):"
|
farmbuyer@10
|
10 local banner_unformatted = "Unformatted version:"
|
farmbuyer@10
|
11 local banner_sep = "==========================="
|
farmbuyer@1
|
12
|
farmbuyer@1
|
13 -- We keep some local state bundled up rather than trying to pass it around
|
farmbuyer@1
|
14 -- as paramters (which would have entailed creating a ton of closures).
|
farmbuyer@1
|
15 local state = {}
|
farmbuyer@1
|
16 local tag_lookup_handlers = {}
|
farmbuyer@1
|
17 local do_tag_lookup_handler
|
farmbuyer@1
|
18
|
farmbuyer@1
|
19
|
farmbuyer@1
|
20 --[[
|
farmbuyer@10
|
21 This is based on CT_RaidTracker 1.7.32, reconstructing the output from
|
farmbuyer@1
|
22 code inspection. No official format documents are available on the web
|
farmbuyer@1
|
23 without downloading and installing the EQDKP webserver package. Bah.
|
farmbuyer@1
|
24
|
farmbuyer@1
|
25 Case of tag names shouldn't matter, but is preserved here from CT_RaidTracker
|
farmbuyer@1
|
26 code for comparison of generated output.
|
farmbuyer@1
|
27
|
farmbuyer@1
|
28 There is some waste adding newlines between elements here only to strip them
|
farmbuyer@1
|
29 out later, but it's worth the extra cycles for debugging and verification.
|
farmbuyer@1
|
30
|
farmbuyer@1
|
31 $TIMESTAMP,$ENDTIME MM/DD/YY HH:mm:ss except we don't have seconds available
|
farmbuyer@1
|
32 $REALM GetRealmName()
|
farmbuyer@1
|
33 $ZONE raw name, not snarky
|
farmbuyer@1
|
34 $RAIDNOTE arbitrary text for the raid event
|
farmbuyer@1
|
35 $PHAT_LEWTS all accumulated loot entries
|
farmbuyer@1
|
36 ]]
|
farmbuyer@1
|
37 local XML = ([====[
|
farmbuyer@1
|
38 <RaidInfo>
|
farmbuyer@1
|
39 <Version>1.4</Version> {In live output, this is missing due to scoping bug in ct_raidtracker.lua:3471}
|
farmbuyer@1
|
40 <key>$TIMESTAMP</key>
|
farmbuyer@1
|
41 <realm>$REALM</realm>
|
farmbuyer@1
|
42 <start>$TIMESTAMP</start> {Same as the key, apparently?}
|
farmbuyer@10
|
43 <end>$ENDTIME</end> {Set by the "end the raid" command in CTRT, here it is just the final entry time}
|
farmbuyer@1
|
44 <zone>$ZONE</zone> {may be optional. first one on the list in case of multiple zones?}
|
farmbuyer@1
|
45 {<difficulty>$DIFFICULTY</difficulty> {this scales badly in places like ICC. may be optional?}}
|
farmbuyer@1
|
46
|
farmbuyer@10
|
47 <PlayerInfos>
|
farmbuyer@10
|
48 $PLAYER_INFOS
|
farmbuyer@10
|
49 </PlayerInfos>
|
farmbuyer@1
|
50
|
farmbuyer@1
|
51 <BossKills>
|
farmbuyer@1
|
52 $BOSS_KILLS
|
farmbuyer@1
|
53 </BossKills>
|
farmbuyer@1
|
54
|
farmbuyer@10
|
55 <Wipes>
|
farmbuyer@10
|
56 $WIPES
|
farmbuyer@10
|
57 </Wipes>
|
farmbuyer@10
|
58 {<NextBoss>Baron Steamroller</NextBoss> {only one "next boss" for the whole
|
farmbuyer@10
|
59 raid event? presumably where to pick up next time?}}
|
farmbuyer@1
|
60
|
farmbuyer@1
|
61 <note><![CDATA[$RAIDNOTE - Zone: $ZONE]]></note>
|
farmbuyer@1
|
62
|
farmbuyer@10
|
63 <Join>
|
farmbuyer@10
|
64 $JOINS
|
farmbuyer@10
|
65 </Join>
|
farmbuyer@10
|
66 <Leave>
|
farmbuyer@10
|
67 $LEAVES
|
farmbuyer@10
|
68 </Leave>
|
farmbuyer@1
|
69
|
farmbuyer@1
|
70 <Loot>
|
farmbuyer@1
|
71 $PHAT_LEWTS
|
farmbuyer@1
|
72 </Loot>
|
farmbuyer@1
|
73 </RaidInfo>]====]):gsub('%b{}', "")
|
farmbuyer@1
|
74
|
farmbuyer@1
|
75 --[[
|
farmbuyer@10
|
76 See the loot markup below.
|
farmbuyer@1
|
77 ]]
|
farmbuyer@1
|
78 local boss_kills_xml = ([====[
|
farmbuyer@1
|
79 <key$N>
|
farmbuyer@1
|
80 <name>$BOSS_NAME</name>
|
farmbuyer@1
|
81 <time>$BOSS_TIME</time>
|
farmbuyer@1
|
82 <attendees></attendees> {this is actually empty in the working example...}
|
farmbuyer@1
|
83 <difficulty>$DIFFICULTY</difficulty>
|
farmbuyer@1
|
84 </key$N>
|
farmbuyer@1
|
85 ]====]):gsub('%b{}', "")
|
farmbuyer@1
|
86
|
farmbuyer@1
|
87 local function boss_kills_tag_lookup (tag)
|
farmbuyer@1
|
88 if tag == 'N' then
|
farmbuyer@1
|
89 return tostring(state.key)
|
farmbuyer@1
|
90 elseif tag == 'BOSS_NAME' then
|
farmbuyer@1
|
91 return state.entry.bosskill
|
farmbuyer@1
|
92 elseif tag == 'BOSS_TIME' then
|
farmbuyer@1
|
93 return do_tag_lookup_handler (state.index, state.entry, 'TIME')
|
farmbuyer@1
|
94 else
|
farmbuyer@1
|
95 return do_tag_lookup_handler (state.index, state.entry, tag) or 'NYI'
|
farmbuyer@1
|
96 end
|
farmbuyer@1
|
97 end
|
farmbuyer@1
|
98
|
farmbuyer@1
|
99 --[[
|
farmbuyer@10
|
100 Handles the PlayerInfo, Join, and Leave tags.
|
farmbuyer@10
|
101 ]]
|
farmbuyer@10
|
102 local joinleave_xml
|
farmbuyer@10
|
103 local player_info_xml = ([====[
|
farmbuyer@10
|
104 <key$N>
|
farmbuyer@10
|
105 $PLAYER_GRUNTWORK
|
farmbuyer@10
|
106 </key$N>
|
farmbuyer@10
|
107 ]====]):gsub('%b{}', "")
|
farmbuyer@10
|
108
|
farmbuyer@10
|
109 local function player_info_tag_lookup (tag)
|
farmbuyer@10
|
110 if tag == 'N' then
|
farmbuyer@10
|
111 return tostring(state.key)
|
farmbuyer@10
|
112 elseif tag == 'NAME' then
|
farmbuyer@10
|
113 return state.index
|
farmbuyer@10
|
114 elseif tag == 'TIME' then
|
farmbuyer@10
|
115 return state.time
|
farmbuyer@10
|
116 end
|
farmbuyer@10
|
117 local ltag = tag:lower()
|
farmbuyer@10
|
118 if state.entry[ltag] then
|
farmbuyer@10
|
119 -- handles race, guild, sex, class, level
|
farmbuyer@10
|
120 return state.entry[ltag]
|
farmbuyer@10
|
121 end
|
farmbuyer@10
|
122 return "?"
|
farmbuyer@10
|
123 end
|
farmbuyer@10
|
124
|
farmbuyer@10
|
125 do
|
farmbuyer@10
|
126 local pi_xml_save = player_info_xml
|
farmbuyer@10
|
127 local gruntwork_tags = {
|
farmbuyer@10
|
128 "name", "race", "guild", "sex", "class", "level"
|
farmbuyer@10
|
129 }
|
farmbuyer@10
|
130 for i,tag in ipairs(gruntwork_tags) do
|
farmbuyer@10
|
131 gruntwork_tags[i] = (" <%s>$%s</%s>"):format(tag,tag:upper(),tag)
|
farmbuyer@10
|
132 end
|
farmbuyer@10
|
133 player_info_xml = player_info_xml:gsub('$PLAYER_GRUNTWORK', table.concat(gruntwork_tags,'\n'))
|
farmbuyer@10
|
134
|
farmbuyer@10
|
135 -- The join/leave blocks use "player" instead of "name". They don't have a
|
farmbuyer@10
|
136 -- guild tag, but they do have a time tag.
|
farmbuyer@10
|
137 gruntwork_tags[1] = " <player>$NAME</player>"
|
farmbuyer@10
|
138 gruntwork_tags[3] = " <time>$TIME</time>"
|
farmbuyer@10
|
139 joinleave_xml = pi_xml_save:gsub('$PLAYER_GRUNTWORK', table.concat(gruntwork_tags,'\n'))
|
farmbuyer@10
|
140 end
|
farmbuyer@10
|
141
|
farmbuyer@10
|
142 --[[
|
farmbuyer@1
|
143 $N 1-based loop variable for key element
|
farmbuyer@10
|
144 $ITEMNAME Without The Square Brackets of the Whale
|
farmbuyer@10
|
145 $ITEMID Not the numeric ID, actually a full itemstring without the leading "item:"
|
farmbuyer@1
|
146 $ICON Last component of texture path?
|
farmbuyer@1
|
147 $CLASS,$SUBCLASS ItemType
|
farmbuyer@1
|
148 $COLOR GetItemQualityColor, full 8-digit string
|
farmbuyer@1
|
149 $COUNT,$BOSS,$ZONE,
|
farmbuyer@1
|
150 $PLAYER all self-explanatory
|
farmbuyer@1
|
151 $COSTS in DKP points... hmmm
|
farmbuyer@1
|
152 $ITEMNOTE take the notes field for this one
|
farmbuyer@1
|
153 $TIME another formatted timestamp
|
farmbuyer@1
|
154 ]]
|
farmbuyer@1
|
155 local phat_lewt_xml = ([====[
|
farmbuyer@1
|
156 <key$N>
|
farmbuyer@1
|
157 $LEWT_GRUNTWORK
|
farmbuyer@1
|
158 <zone>$ZONE</zone> {may be optional}
|
farmbuyer@1
|
159 <difficulty>$DIFFICULTY</difficulty> {this scales badly in places like ICC. may be optional?}
|
farmbuyer@1
|
160 <Note><![CDATA[$ITEMNOTE - Zone: $ZONE - Boss: $BOSS - $COSTS DKP]]></Note> {zone can be followed by difficulty}
|
farmbuyer@1
|
161 </key$N>
|
farmbuyer@1
|
162 ]====]):gsub('%b{}', "")
|
farmbuyer@1
|
163
|
farmbuyer@1
|
164 local function phat_lewt_tag_lookup (tag)
|
farmbuyer@1
|
165 if tag == 'N' then
|
farmbuyer@1
|
166 return tostring(state.key)
|
farmbuyer@1
|
167 elseif tag == 'COSTS'
|
farmbuyer@1
|
168 then return '1'
|
farmbuyer@1
|
169 else
|
farmbuyer@1
|
170 return do_tag_lookup_handler (state.index, state.entry, tag) or 'NYI'
|
farmbuyer@1
|
171 end
|
farmbuyer@1
|
172 end
|
farmbuyer@1
|
173
|
farmbuyer@1
|
174 do
|
farmbuyer@1
|
175 local gruntwork_tags = {
|
farmbuyer@1
|
176 "ItemName", "ItemID", "Icon", "Class", "SubClass", "Color", "Count",
|
farmbuyer@1
|
177 "Player", "Costs", "Boss", "Time",
|
farmbuyer@1
|
178 }
|
farmbuyer@1
|
179 for i,tag in ipairs(gruntwork_tags) do
|
farmbuyer@1
|
180 gruntwork_tags[i] = (" <%s>$%s</%s>"):format(tag,tag:upper(),tag)
|
farmbuyer@1
|
181 end
|
farmbuyer@1
|
182 phat_lewt_xml = phat_lewt_xml:gsub('$LEWT_GRUNTWORK', table.concat(gruntwork_tags,'\n'))
|
farmbuyer@1
|
183 end
|
farmbuyer@1
|
184
|
farmbuyer@1
|
185
|
farmbuyer@1
|
186 local function format_EQDKP_timestamp (day_entry, time_entry)
|
farmbuyer@1
|
187 --assert(day_entry.kind == 'time', day_entry.kind .. " passed to MLEQDKP timestamp")
|
farmbuyer@1
|
188 return addon:format_timestamp ("$M/$D/$Y $h:$m:00", day_entry, time_entry)
|
farmbuyer@1
|
189 end
|
farmbuyer@1
|
190
|
farmbuyer@1
|
191
|
farmbuyer@1
|
192 -- Look up tag strings for a particular item, given index and entry table.
|
farmbuyer@1
|
193 tag_lookup_handlers.ITEMNAME =
|
farmbuyer@1
|
194 function (i, e)
|
farmbuyer@1
|
195 return e.itemname
|
farmbuyer@1
|
196 end
|
farmbuyer@1
|
197
|
farmbuyer@1
|
198 tag_lookup_handlers.ITEMID =
|
farmbuyer@1
|
199 function (i, e)
|
farmbuyer@1
|
200 return e.itemlink:match("^|c%x+|H(item[%d:]+)|h%[")
|
farmbuyer@1
|
201 end
|
farmbuyer@1
|
202
|
farmbuyer@1
|
203 tag_lookup_handlers.ICON =
|
farmbuyer@1
|
204 function (i, e)
|
farmbuyer@1
|
205 local str = e.itexture
|
farmbuyer@1
|
206 repeat
|
farmbuyer@1
|
207 local s = str:find('\\')
|
farmbuyer@1
|
208 if s then str = str:sub(s+1) end
|
farmbuyer@1
|
209 until not s
|
farmbuyer@1
|
210 return str
|
farmbuyer@1
|
211 end
|
farmbuyer@1
|
212
|
farmbuyer@1
|
213 tag_lookup_handlers.CLASS =
|
farmbuyer@1
|
214 function (i, e)
|
farmbuyer@1
|
215 return state.class
|
farmbuyer@1
|
216 end
|
farmbuyer@1
|
217
|
farmbuyer@1
|
218 tag_lookup_handlers.SUBCLASS =
|
farmbuyer@1
|
219 function (i, e)
|
farmbuyer@1
|
220 return state.subclass
|
farmbuyer@1
|
221 end
|
farmbuyer@1
|
222
|
farmbuyer@1
|
223 tag_lookup_handlers.COLOR =
|
farmbuyer@1
|
224 function (i, e)
|
farmbuyer@1
|
225 local q = select(4, GetItemQualityColor(e.quality))
|
farmbuyer@12
|
226 return q -- skip leading |c (no longer returned by GIQC after 4.2)
|
farmbuyer@1
|
227 end
|
farmbuyer@1
|
228
|
farmbuyer@1
|
229 tag_lookup_handlers.COUNT =
|
farmbuyer@1
|
230 function (i, e)
|
farmbuyer@1
|
231 return e.count and e.count:sub(2) or "1" -- skip the leading "x"
|
farmbuyer@1
|
232 end
|
farmbuyer@1
|
233
|
farmbuyer@10
|
234 -- should combine these next two
|
farmbuyer@1
|
235 tag_lookup_handlers.BOSS =
|
farmbuyer@1
|
236 function (i, e)
|
farmbuyer@1
|
237 while i > 0 and state.loot[i].kind ~= 'boss' do
|
farmbuyer@1
|
238 i = i - 1
|
farmbuyer@1
|
239 end
|
farmbuyer@1
|
240 if i == 0 then return "No Boss Entry Found, Unknown Boss" end
|
farmbuyer@1
|
241 return state.loot[i].bosskill
|
farmbuyer@1
|
242 end
|
farmbuyer@1
|
243
|
farmbuyer@1
|
244 tag_lookup_handlers.ZONE =
|
farmbuyer@1
|
245 function (i, e)
|
farmbuyer@1
|
246 while i > 0 and state.loot[i].kind ~= 'boss' do
|
farmbuyer@1
|
247 i = i - 1
|
farmbuyer@1
|
248 end
|
farmbuyer@1
|
249 if i == 0 then return "No Boss Entry Found, Unknown Zone" end
|
farmbuyer@1
|
250 return state.loot[i].instance
|
farmbuyer@1
|
251 end
|
farmbuyer@1
|
252
|
farmbuyer@1
|
253 tag_lookup_handlers.DIFFICULTY =
|
farmbuyer@1
|
254 function (i, e)
|
farmbuyer@1
|
255 local tag = tag_lookup_handlers.ZONE(i,e)
|
farmbuyer@1
|
256 local N,h = tag:match("%((%d+)(h?)%)")
|
farmbuyer@1
|
257 if not N then return "1" end -- maybe signal an error instead?
|
farmbuyer@1
|
258 N = tonumber(N)
|
farmbuyer@1
|
259 N = ( (N==10) and 1 or 2 ) + ( (h=='h') and 2 or 0 )
|
farmbuyer@1
|
260 return tostring(N)
|
farmbuyer@1
|
261 end
|
farmbuyer@1
|
262
|
farmbuyer@1
|
263 tag_lookup_handlers.PLAYER =
|
farmbuyer@1
|
264 function (i, e)
|
farmbuyer@1
|
265 return state.player
|
farmbuyer@1
|
266 end
|
farmbuyer@1
|
267
|
farmbuyer@1
|
268 tag_lookup_handlers.ITEMNOTE =
|
farmbuyer@1
|
269 function (i, e)
|
farmbuyer@1
|
270 return state.itemnote
|
farmbuyer@1
|
271 end
|
farmbuyer@1
|
272
|
farmbuyer@1
|
273 tag_lookup_handlers.TIME =
|
farmbuyer@1
|
274 function (i, e)
|
farmbuyer@1
|
275 local ti,tl = addon:find_previous_time_entry(i)
|
farmbuyer@1
|
276 return format_EQDKP_timestamp(tl,e)
|
farmbuyer@1
|
277 end
|
farmbuyer@1
|
278
|
farmbuyer@1
|
279
|
farmbuyer@1
|
280 function do_tag_lookup_handler (index, entry, tag)
|
farmbuyer@1
|
281 local h = tag_lookup_handlers[tag]
|
farmbuyer@1
|
282 if h then
|
farmbuyer@1
|
283 return h(index,entry)
|
farmbuyer@1
|
284 else
|
farmbuyer@1
|
285 error(("MLDKP tag lookup (index %d) on tag %s with no handler"):format(index,tag))
|
farmbuyer@1
|
286 end
|
farmbuyer@1
|
287 end
|
farmbuyer@1
|
288
|
farmbuyer@10
|
289
|
farmbuyer@1
|
290 local function generator (ttype, loot, last_printed, generated, cache)
|
farmbuyer@1
|
291 -- Because it's XML, generated text is "grown" by shoving more crap into
|
farmbuyer@1
|
292 -- the middle instead of appending to the end. Only easy way of doing that
|
farmbuyer@1
|
293 -- here is regenerating it from scratch each time.
|
farmbuyer@1
|
294 generated[ttype] = nil
|
farmbuyer@1
|
295
|
farmbuyer@1
|
296 local _
|
farmbuyer@1
|
297 local text = XML
|
farmbuyer@1
|
298 state.loot = loot
|
farmbuyer@1
|
299
|
farmbuyer@1
|
300 -- TIMESTAMPs
|
farmbuyer@1
|
301 do
|
farmbuyer@1
|
302 local f,l -- first and last timestamps in the table
|
farmbuyer@1
|
303 for i = 1, #loot do
|
farmbuyer@1
|
304 if loot[i].kind == 'time' then
|
farmbuyer@1
|
305 f = format_EQDKP_timestamp(loot[i])
|
farmbuyer@1
|
306 break
|
farmbuyer@1
|
307 end
|
farmbuyer@1
|
308 end
|
farmbuyer@1
|
309 _,l = addon:find_previous_time_entry(#loot) -- latest timestamp
|
farmbuyer@1
|
310 l = format_EQDKP_timestamp(l,loot[#loot])
|
farmbuyer@1
|
311 text = text:gsub('$TIMESTAMP', f):gsub('$ENDTIME', l)
|
farmbuyer@1
|
312 end
|
farmbuyer@1
|
313
|
farmbuyer@1
|
314 -- Loot
|
farmbuyer@1
|
315 do
|
farmbuyer@1
|
316 local all_lewts = {}
|
farmbuyer@1
|
317 local lewt_template = phat_lewt_xml
|
farmbuyer@1
|
318
|
farmbuyer@1
|
319 state.key = 1
|
farmbuyer@1
|
320 for i,e in addon:filtered_loot_iter('loot') do
|
farmbuyer@1
|
321 state.index, state.entry = i, e
|
farmbuyer@1
|
322 -- no sense doing repeated getiteminfo calls
|
farmbuyer@1
|
323 state.class, state.subclass = select(6, GetItemInfo(e.id))
|
farmbuyer@1
|
324
|
farmbuyer@1
|
325 -- similar logic as text_tabs.lua:
|
farmbuyer@1
|
326 -- assuming nobody names a toon "offspec" or "gvault"
|
farmbuyer@1
|
327 local P, N
|
farmbuyer@1
|
328 local disp = e.disposition or e.person
|
farmbuyer@1
|
329 if disp == 'offspec' then
|
farmbuyer@1
|
330 P,N = e.person, "offspec"
|
farmbuyer@1
|
331 elseif disp == 'gvault' then
|
farmbuyer@1
|
332 P,N = "guild vault", e.person
|
farmbuyer@1
|
333 else
|
farmbuyer@1
|
334 P,N = disp, ""
|
farmbuyer@1
|
335 end
|
farmbuyer@1
|
336 if e.extratext_byhand then
|
farmbuyer@1
|
337 N = N .. " -- " .. e.extratext
|
farmbuyer@1
|
338 end
|
farmbuyer@1
|
339 state.player, state.itemnote = P, N
|
farmbuyer@1
|
340
|
farmbuyer@1
|
341 all_lewts[#all_lewts+1] = lewt_template:gsub('%$([%w_]+)',
|
farmbuyer@1
|
342 phat_lewt_tag_lookup)
|
farmbuyer@1
|
343 state.key = state.key + 1
|
farmbuyer@1
|
344 end
|
farmbuyer@1
|
345
|
farmbuyer@10
|
346 text = text:gsub('$PHAT_LEWTS', tconcat(all_lewts, '\n'))
|
farmbuyer@1
|
347 end
|
farmbuyer@1
|
348
|
farmbuyer@10
|
349 -- Player info, join times, leave times
|
farmbuyer@1
|
350 do
|
farmbuyer@10
|
351 local all_players, all_joins, all_leaves = {}, {}, {}
|
farmbuyer@10
|
352 local player_template, joinleave_template = player_info_xml, joinleave_xml
|
farmbuyer@10
|
353 local date = date
|
farmbuyer@10
|
354
|
farmbuyer@10
|
355 state.key = 1
|
farmbuyer@10
|
356 if type(loot.raiders) == 'table' then for name,r in pairs(loot.raiders) do
|
farmbuyer@10
|
357 state.index, state.entry = name, r
|
farmbuyer@10
|
358 all_players[#all_players+1] = player_template:gsub('%$([%w_]+)', player_info_tag_lookup)
|
farmbuyer@10
|
359 state.time = date ("%m/%d/%y %H:%M:00", r.join)
|
farmbuyer@10
|
360 all_joins[#all_joins+1] = joinleave_template:gsub('%$([%w_]+)', player_info_tag_lookup)
|
farmbuyer@10
|
361 state.time = date ("%m/%d/%y %H:%M:00", r.leave)
|
farmbuyer@10
|
362 all_leaves[#all_leaves+1] = joinleave_template:gsub('%$([%w_]+)', player_info_tag_lookup)
|
farmbuyer@10
|
363 state.key = state.key + 1
|
farmbuyer@10
|
364 end end
|
farmbuyer@10
|
365 text = text:gsub('$PLAYER_INFOS', tconcat(all_players, '\n'))
|
farmbuyer@10
|
366 :gsub('$JOINS', tconcat(all_joins, '\n'))
|
farmbuyer@10
|
367 :gsub('$LEAVES', tconcat(all_leaves, '\n'))
|
farmbuyer@10
|
368 end
|
farmbuyer@10
|
369
|
farmbuyer@10
|
370 -- Bosses and wipes (does anybody really use the latter?)
|
farmbuyer@10
|
371 do
|
farmbuyer@10
|
372 local all_bosses, all_wipes = {}, {}
|
farmbuyer@1
|
373 local boss_template = boss_kills_xml
|
farmbuyer@1
|
374
|
farmbuyer@1
|
375 state.key = 1
|
farmbuyer@1
|
376 for i,e in addon:filtered_loot_iter('boss') do
|
farmbuyer@10
|
377 if e.reason == 'kill' then
|
farmbuyer@1
|
378 state.index, state.entry = i, e
|
farmbuyer@1
|
379 all_bosses[#all_bosses+1] = boss_template:gsub('%$([%w_]+)',
|
farmbuyer@1
|
380 boss_kills_tag_lookup)
|
farmbuyer@1
|
381 state.key = state.key + 1
|
farmbuyer@10
|
382 elseif e.reason == 'wipe' then
|
farmbuyer@10
|
383 all_wipes[#all_wipes+1] = ('<Wipe>%d</Wipe>'):format(e.stamp)
|
farmbuyer@1
|
384 end
|
farmbuyer@1
|
385 end
|
farmbuyer@1
|
386
|
farmbuyer@10
|
387 text = text:gsub('$BOSS_KILLS', tconcat(all_bosses, '\n'))
|
farmbuyer@10
|
388 :gsub('$WIPES', tconcat(all_wipes, '\n'))
|
farmbuyer@1
|
389 end
|
farmbuyer@1
|
390
|
farmbuyer@1
|
391 -- In addition to doing the top-level zone, this will also catch any
|
farmbuyer@1
|
392 -- leftover $ZONE tags. There could be multiple places in the raid, so
|
farmbuyer@1
|
393 -- we default to the first one we saw.
|
farmbuyer@1
|
394 do
|
farmbuyer@1
|
395 local iter = addon:filtered_loot_iter() -- HACK
|
farmbuyer@1
|
396 local first_boss = iter('boss',0)
|
farmbuyer@1
|
397 local zone = first_boss and loot[first_boss].instance or "Unknown"
|
farmbuyer@1
|
398 text = text:gsub('$ZONE', zone)
|
farmbuyer@1
|
399 end
|
farmbuyer@1
|
400
|
farmbuyer@1
|
401 -- Misc
|
farmbuyer@1
|
402 text = text:gsub('$REALM', (GetRealmName()))
|
farmbuyer@1
|
403 --text = text:gsub('$DIFFICULTY', )
|
farmbuyer@1
|
404 text = text:gsub('$RAIDNOTE', "")
|
farmbuyer@1
|
405
|
farmbuyer@10
|
406 cache[#cache+1] = banner_formatted
|
farmbuyer@10
|
407 cache[#cache+1] = banner_sep
|
farmbuyer@1
|
408 cache[#cache+1] = text
|
farmbuyer@1
|
409 cache[#cache+1] = '\n'
|
farmbuyer@1
|
410
|
farmbuyer@10
|
411 cache[#cache+1] = banner_unformatted
|
farmbuyer@10
|
412 cache[#cache+1] = banner_sep
|
farmbuyer@1
|
413 text = text:gsub('>%s+<', "><")
|
farmbuyer@1
|
414 cache[#cache+1] = text
|
farmbuyer@1
|
415 cache[#cache+1] = '\n'
|
farmbuyer@1
|
416
|
farmbuyer@1
|
417 wipe(state)
|
farmbuyer@1
|
418 return true
|
farmbuyer@1
|
419 end
|
farmbuyer@1
|
420
|
farmbuyer@1
|
421 local function specials (_, editbox, container, mkbutton)
|
farmbuyer@10
|
422 local b = mkbutton("Highlight",
|
farmbuyer@1
|
423 [[Highlight the unformatted copy for copy-and-pasting.]])
|
farmbuyer@10
|
424 b:SetFullWidth(true)
|
farmbuyer@10
|
425 b:SetCallback("OnClick", function(_b)
|
farmbuyer@10
|
426 local _,start,finish
|
farmbuyer@1
|
427 local txt = editbox:GetText()
|
farmbuyer@10
|
428 _,start = txt:find(banner_unformatted..'\n'..banner_sep..'\n')
|
farmbuyer@10
|
429 _,finish = txt:find("</RaidInfo>", start)
|
farmbuyer@1
|
430 editbox.editBox:HighlightText(start,finish)
|
farmbuyer@1
|
431 editbox.editBox:SetCursorPosition(start)
|
farmbuyer@1
|
432 end)
|
farmbuyer@10
|
433 container:AddChild(b)
|
farmbuyer@10
|
434
|
farmbuyer@10
|
435 local b = mkbutton("Re-Unformat",
|
farmbuyer@10
|
436 [[Regenerate only the unformatted copy at the bottom <*from*> the formatted copy at the top.]])
|
farmbuyer@10
|
437 b:SetFullWidth(true)
|
farmbuyer@10
|
438 b:SetCallback("OnClick", function(_b)
|
farmbuyer@10
|
439 local _,start,finish
|
farmbuyer@10
|
440 local txt = editbox:GetText()
|
farmbuyer@10
|
441 _,start = txt:find(banner_formatted..'\n'..banner_sep..'\n', --[[init=]]1, --[[plain=]]true)
|
farmbuyer@10
|
442 _,finish = txt:find("</RaidInfo>", start, true)
|
farmbuyer@10
|
443 txt = txt:sub(start+1,finish)
|
farmbuyer@10
|
444 txt = banner_formatted .. '\n'
|
farmbuyer@10
|
445 .. banner_sep .. '\n'
|
farmbuyer@10
|
446 .. txt .. '\n\n\n'
|
farmbuyer@10
|
447 .. banner_unformatted .. '\n'
|
farmbuyer@10
|
448 .. banner_sep .. '\n'
|
farmbuyer@10
|
449 .. txt:gsub('>%s+<', "><") .. '\n'
|
farmbuyer@10
|
450 -- This would normally screw up the cached version, but we're regenerating
|
farmbuyer@10
|
451 -- everything on each new display for this tab anyhow.
|
farmbuyer@10
|
452 editbox.editBox:SetText(txt)
|
farmbuyer@10
|
453 _,start = txt:find(banner_unformatted..'\n'..banner_sep..'\n', --[[init=]]1, --[[plain=]]true)
|
farmbuyer@10
|
454 editbox.editBox:SetCursorPosition(start)
|
farmbuyer@10
|
455 end)
|
farmbuyer@10
|
456 container:AddChild(b)
|
farmbuyer@1
|
457 end
|
farmbuyer@1
|
458
|
farmbuyer@1
|
459 addon:register_text_generator ("mleqdkp", [[ML/EQ-DKP]], [[MLdkp 1.1 EQDKP format]], generator, specials)
|
farmbuyer@1
|
460
|
farmbuyer@1
|
461 -- vim:noet
|