Mercurial > wow > ouroloot
comparison mleqdkp.lua @ 1:822b6ca3ef89
Import of 2.15, moving to wowace svn.
author | Farmbuyer of US-Kilrogg <farmbuyer@gmail.com> |
---|---|
date | Sat, 16 Apr 2011 06:03:29 +0000 |
parents | |
children | 67b8537e8432 |
comparison
equal
deleted
inserted
replaced
0:0f14a1e5364d | 1:822b6ca3ef89 |
---|---|
1 if UnitName"player" ~= "Farmbuyer" then return end | |
2 local addon = select(2,...) | |
3 | |
4 -- We keep some local state bundled up rather than trying to pass it around | |
5 -- as paramters (which would have entailed creating a ton of closures). | |
6 local state = {} | |
7 local tag_lookup_handlers = {} | |
8 local do_tag_lookup_handler | |
9 | |
10 | |
11 --[[ | |
12 This is taken from CT_RaidTracker 1.7.32, reconstructing the output from | |
13 code inspection. No official format documents are available on the web | |
14 without downloading and installing the EQDKP webserver package. Bah. | |
15 | |
16 Case of tag names shouldn't matter, but is preserved here from CT_RaidTracker | |
17 code for comparison of generated output. | |
18 | |
19 There is some waste adding newlines between elements here only to strip them | |
20 out later, but it's worth the extra cycles for debugging and verification. | |
21 | |
22 $TIMESTAMP,$ENDTIME MM/DD/YY HH:mm:ss except we don't have seconds available | |
23 $REALM GetRealmName() | |
24 $ZONE raw name, not snarky | |
25 $RAIDNOTE arbitrary text for the raid event | |
26 $PHAT_LEWTS all accumulated loot entries | |
27 ]] | |
28 local XML = ([====[ | |
29 <RaidInfo> | |
30 <Version>1.4</Version> {In live output, this is missing due to scoping bug in ct_raidtracker.lua:3471} | |
31 <key>$TIMESTAMP</key> | |
32 <realm>$REALM</realm> | |
33 <start>$TIMESTAMP</start> {Same as the key, apparently?} | |
34 <end>$ENDTIME</end> {Set by the "end the raid" command in the raid tracker, here just the final entry time} | |
35 <zone>$ZONE</zone> {may be optional. first one on the list in case of multiple zones?} | |
36 {<difficulty>$DIFFICULTY</difficulty> {this scales badly in places like ICC. may be optional?}} | |
37 | |
38 {<PlayerInfos>... {guh.}} | |
39 | |
40 <BossKills> | |
41 $BOSS_KILLS | |
42 </BossKills> | |
43 | |
44 {<Wipes> bleh} | |
45 {<NextBoss>Baron Steamroller</NextBoss> {only one "next boss" for the whole raid event? huh?}} | |
46 | |
47 <note><![CDATA[$RAIDNOTE - Zone: $ZONE]]></note> | |
48 | |
49 {<Join>...</Join><Leave>...</Leave> {specific timestamps per player. meh.}} | |
50 | |
51 <Loot> | |
52 $PHAT_LEWTS | |
53 </Loot> | |
54 </RaidInfo>]====]):gsub('%b{}', "") | |
55 | |
56 --[[ | |
57 See the loot markup, next block. | |
58 ]] | |
59 local boss_kills_xml = ([====[ | |
60 <key$N> | |
61 <name>$BOSS_NAME</name> | |
62 <time>$BOSS_TIME</time> | |
63 <attendees></attendees> {this is actually empty in the working example...} | |
64 <difficulty>$DIFFICULTY</difficulty> | |
65 </key$N> | |
66 ]====]):gsub('%b{}', "") | |
67 | |
68 local function boss_kills_tag_lookup (tag) | |
69 if tag == 'N' then | |
70 return tostring(state.key) | |
71 elseif tag == 'BOSS_NAME' then | |
72 return state.entry.bosskill | |
73 elseif tag == 'BOSS_TIME' then | |
74 return do_tag_lookup_handler (state.index, state.entry, 'TIME') | |
75 else | |
76 return do_tag_lookup_handler (state.index, state.entry, tag) or 'NYI' | |
77 end | |
78 end | |
79 | |
80 --[[ | |
81 $N 1-based loop variable for key element | |
82 $ITEMNAME Without The Brackets | |
83 $ITEMID Not the ID, actually a full itemstring without the leading "item:" | |
84 $ICON Last component of texture path? | |
85 $CLASS,$SUBCLASS ItemType | |
86 $COLOR GetItemQualityColor, full 8-digit string | |
87 $COUNT,$BOSS,$ZONE, | |
88 $PLAYER all self-explanatory | |
89 $COSTS in DKP points... hmmm | |
90 $ITEMNOTE take the notes field for this one | |
91 $TIME another formatted timestamp | |
92 ]] | |
93 local phat_lewt_xml = ([====[ | |
94 <key$N> | |
95 $LEWT_GRUNTWORK | |
96 <zone>$ZONE</zone> {may be optional} | |
97 <difficulty>$DIFFICULTY</difficulty> {this scales badly in places like ICC. may be optional?} | |
98 <Note><![CDATA[$ITEMNOTE - Zone: $ZONE - Boss: $BOSS - $COSTS DKP]]></Note> {zone can be followed by difficulty} | |
99 </key$N> | |
100 ]====]):gsub('%b{}', "") | |
101 | |
102 local function phat_lewt_tag_lookup (tag) | |
103 if tag == 'N' then | |
104 return tostring(state.key) | |
105 elseif tag == 'COSTS' | |
106 then return '1' | |
107 else | |
108 return do_tag_lookup_handler (state.index, state.entry, tag) or 'NYI' | |
109 end | |
110 end | |
111 | |
112 do | |
113 local gruntwork_tags = { | |
114 "ItemName", "ItemID", "Icon", "Class", "SubClass", "Color", "Count", | |
115 "Player", "Costs", "Boss", "Time", | |
116 } | |
117 for i,tag in ipairs(gruntwork_tags) do | |
118 gruntwork_tags[i] = (" <%s>$%s</%s>"):format(tag,tag:upper(),tag) | |
119 end | |
120 phat_lewt_xml = phat_lewt_xml:gsub('$LEWT_GRUNTWORK', table.concat(gruntwork_tags,'\n')) | |
121 end | |
122 | |
123 | |
124 local function format_EQDKP_timestamp (day_entry, time_entry) | |
125 --assert(day_entry.kind == 'time', day_entry.kind .. " passed to MLEQDKP timestamp") | |
126 return addon:format_timestamp ("$M/$D/$Y $h:$m:00", day_entry, time_entry) | |
127 end | |
128 | |
129 | |
130 -- Look up tag strings for a particular item, given index and entry table. | |
131 tag_lookup_handlers.ITEMNAME = | |
132 function (i, e) | |
133 return e.itemname | |
134 end | |
135 | |
136 tag_lookup_handlers.ITEMID = | |
137 function (i, e) | |
138 return e.itemlink:match("^|c%x+|H(item[%d:]+)|h%[") | |
139 end | |
140 | |
141 tag_lookup_handlers.ICON = | |
142 function (i, e) | |
143 local str = e.itexture | |
144 repeat | |
145 local s = str:find('\\') | |
146 if s then str = str:sub(s+1) end | |
147 until not s | |
148 return str | |
149 end | |
150 | |
151 tag_lookup_handlers.CLASS = | |
152 function (i, e) | |
153 return state.class | |
154 end | |
155 | |
156 tag_lookup_handlers.SUBCLASS = | |
157 function (i, e) | |
158 return state.subclass | |
159 end | |
160 | |
161 tag_lookup_handlers.COLOR = | |
162 function (i, e) | |
163 local q = select(4, GetItemQualityColor(e.quality)) | |
164 return q:sub(3) -- skip leading |c | |
165 end | |
166 | |
167 tag_lookup_handlers.COUNT = | |
168 function (i, e) | |
169 return e.count and e.count:sub(2) or "1" -- skip the leading "x" | |
170 end | |
171 | |
172 -- maybe combine these next two | |
173 tag_lookup_handlers.BOSS = | |
174 function (i, e) | |
175 while i > 0 and state.loot[i].kind ~= 'boss' do | |
176 i = i - 1 | |
177 end | |
178 if i == 0 then return "No Boss Entry Found, Unknown Boss" end | |
179 return state.loot[i].bosskill | |
180 end | |
181 | |
182 tag_lookup_handlers.ZONE = | |
183 function (i, e) | |
184 while i > 0 and state.loot[i].kind ~= 'boss' do | |
185 i = i - 1 | |
186 end | |
187 if i == 0 then return "No Boss Entry Found, Unknown Zone" end | |
188 return state.loot[i].instance | |
189 end | |
190 | |
191 tag_lookup_handlers.DIFFICULTY = | |
192 function (i, e) | |
193 local tag = tag_lookup_handlers.ZONE(i,e) | |
194 local N,h = tag:match("%((%d+)(h?)%)") | |
195 if not N then return "1" end -- maybe signal an error instead? | |
196 N = tonumber(N) | |
197 N = ( (N==10) and 1 or 2 ) + ( (h=='h') and 2 or 0 ) | |
198 return tostring(N) | |
199 end | |
200 | |
201 tag_lookup_handlers.PLAYER = | |
202 function (i, e) | |
203 return state.player | |
204 end | |
205 | |
206 tag_lookup_handlers.ITEMNOTE = | |
207 function (i, e) | |
208 return state.itemnote | |
209 end | |
210 | |
211 tag_lookup_handlers.TIME = | |
212 function (i, e) | |
213 local ti,tl = addon:find_previous_time_entry(i) | |
214 return format_EQDKP_timestamp(tl,e) | |
215 end | |
216 | |
217 | |
218 function do_tag_lookup_handler (index, entry, tag) | |
219 local h = tag_lookup_handlers[tag] | |
220 if h then | |
221 return h(index,entry) | |
222 else | |
223 error(("MLDKP tag lookup (index %d) on tag %s with no handler"):format(index,tag)) | |
224 end | |
225 end | |
226 | |
227 local function generator (ttype, loot, last_printed, generated, cache) | |
228 -- Because it's XML, generated text is "grown" by shoving more crap into | |
229 -- the middle instead of appending to the end. Only easy way of doing that | |
230 -- here is regenerating it from scratch each time. | |
231 generated[ttype] = nil | |
232 | |
233 local _ | |
234 local text = XML | |
235 state.loot = loot | |
236 | |
237 -- TIMESTAMPs | |
238 do | |
239 local f,l -- first and last timestamps in the table | |
240 for i = 1, #loot do | |
241 if loot[i].kind == 'time' then | |
242 f = format_EQDKP_timestamp(loot[i]) | |
243 break | |
244 end | |
245 end | |
246 _,l = addon:find_previous_time_entry(#loot) -- latest timestamp | |
247 l = format_EQDKP_timestamp(l,loot[#loot]) | |
248 text = text:gsub('$TIMESTAMP', f):gsub('$ENDTIME', l) | |
249 end | |
250 | |
251 -- Loot | |
252 do | |
253 local all_lewts = {} | |
254 local lewt_template = phat_lewt_xml | |
255 | |
256 state.key = 1 | |
257 for i,e in addon:filtered_loot_iter('loot') do | |
258 state.index, state.entry = i, e | |
259 -- no sense doing repeated getiteminfo calls | |
260 state.class, state.subclass = select(6, GetItemInfo(e.id)) | |
261 | |
262 -- similar logic as text_tabs.lua: | |
263 -- assuming nobody names a toon "offspec" or "gvault" | |
264 local P, N | |
265 local disp = e.disposition or e.person | |
266 if disp == 'offspec' then | |
267 P,N = e.person, "offspec" | |
268 elseif disp == 'gvault' then | |
269 P,N = "guild vault", e.person | |
270 else | |
271 P,N = disp, "" | |
272 end | |
273 if e.extratext_byhand then | |
274 N = N .. " -- " .. e.extratext | |
275 end | |
276 state.player, state.itemnote = P, N | |
277 | |
278 all_lewts[#all_lewts+1] = lewt_template:gsub('%$([%w_]+)', | |
279 phat_lewt_tag_lookup) | |
280 state.key = state.key + 1 | |
281 end | |
282 | |
283 text = text:gsub('$PHAT_LEWTS', table.concat(all_lewts, '\n')) | |
284 end | |
285 | |
286 -- Bosses | |
287 do | |
288 local all_bosses = {} | |
289 local boss_template = boss_kills_xml | |
290 | |
291 state.key = 1 | |
292 for i,e in addon:filtered_loot_iter('boss') do | |
293 if e.reason == 'kill' then -- oh, for a 'continue' statement... | |
294 state.index, state.entry = i, e | |
295 all_bosses[#all_bosses+1] = boss_template:gsub('%$([%w_]+)', | |
296 boss_kills_tag_lookup) | |
297 state.key = state.key + 1 | |
298 end | |
299 end | |
300 | |
301 text = text:gsub('$BOSS_KILLS', table.concat(all_bosses, '\n')) | |
302 end | |
303 | |
304 -- In addition to doing the top-level zone, this will also catch any | |
305 -- leftover $ZONE tags. There could be multiple places in the raid, so | |
306 -- we default to the first one we saw. | |
307 do | |
308 local iter = addon:filtered_loot_iter() -- HACK | |
309 local first_boss = iter('boss',0) | |
310 local zone = first_boss and loot[first_boss].instance or "Unknown" | |
311 text = text:gsub('$ZONE', zone) | |
312 end | |
313 | |
314 -- Misc | |
315 text = text:gsub('$REALM', (GetRealmName())) | |
316 --text = text:gsub('$DIFFICULTY', ) | |
317 text = text:gsub('$RAIDNOTE', "") | |
318 | |
319 cache[#cache+1] = "Formatted version (scroll down for unformatted):" | |
320 cache[#cache+1] = "===========================" | |
321 cache[#cache+1] = text | |
322 cache[#cache+1] = '\n' | |
323 | |
324 cache[#cache+1] = "Unformatted version:" | |
325 cache[#cache+1] = "===========================" | |
326 text = text:gsub('>%s+<', "><") | |
327 cache[#cache+1] = text | |
328 cache[#cache+1] = '\n' | |
329 | |
330 wipe(state) | |
331 return true | |
332 end | |
333 | |
334 local function specials (_, editbox, container, mkbutton) | |
335 local hl = mkbutton("Highlight", | |
336 [[Highlight the unformatted copy for copy-and-pasting.]]) | |
337 hl:SetFullWidth(true) | |
338 hl:SetCallback("OnClick", function(_hl) | |
339 local txt = editbox:GetText() | |
340 local _,start = txt:find("Unformatted version:\n=+\n") | |
341 local _,finish = txt:find("</RaidInfo>", start) | |
342 editbox.editBox:HighlightText(start,finish) | |
343 editbox.editBox:SetCursorPosition(start) | |
344 end) | |
345 container:AddChild(hl) | |
346 end | |
347 | |
348 addon:register_text_generator ("mleqdkp", [[ML/EQ-DKP]], [[MLdkp 1.1 EQDKP format]], generator, specials) | |
349 | |
350 -- vim:noet |