vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | ------------------------------------------------------ |
2 | -- Linkerator.lua |
||
3 | -- Link scanning code based on LootLink 1.9. Thanks Telo! |
||
4 | ------------------------------------------------------ |
||
5 | FLT_VERSION = "11000.2"; |
||
6 | ------------------------------------------------------ |
||
7 | |||
8 | FLT_ItemLinks = { }; |
||
9 | |||
10 | local ChatMessageTypes = { |
||
11 | "CHAT_MSG_SYSTEM", |
||
12 | "CHAT_MSG_SAY", |
||
13 | "CHAT_MSG_TEXT_EMOTE", |
||
14 | "CHAT_MSG_YELL", |
||
15 | "CHAT_MSG_WHISPER", |
||
16 | "CHAT_MSG_PARTY", |
||
17 | "CHAT_MSG_GUILD", |
||
18 | "CHAT_MSG_OFFICER", |
||
19 | "CHAT_MSG_CHANNEL", |
||
20 | "CHAT_MSG_RAID", |
||
21 | "CHAT_MSG_LOOT", |
||
22 | }; |
||
23 | |||
24 | local INVENTORY_SLOT_LIST = { |
||
25 | { name = "HeadSlot" }, |
||
26 | { name = "NeckSlot" }, |
||
27 | { name = "ShoulderSlot" }, |
||
28 | { name = "BackSlot" }, |
||
29 | { name = "ChestSlot" }, |
||
30 | { name = "ShirtSlot" }, |
||
31 | { name = "TabardSlot" }, |
||
32 | { name = "WristSlot" }, |
||
33 | { name = "HandsSlot" }, |
||
34 | { name = "WaistSlot" }, |
||
35 | { name = "LegsSlot" }, |
||
36 | { name = "FeetSlot" }, |
||
37 | { name = "Finger0Slot" }, |
||
38 | { name = "Finger1Slot" }, |
||
39 | { name = "Trinket0Slot" }, |
||
40 | { name = "Trinket1Slot" }, |
||
41 | { name = "MainHandSlot" }, |
||
42 | { name = "SecondaryHandSlot" }, |
||
43 | { name = "RangedSlot" }, |
||
44 | }; |
||
45 | |||
46 | -- Anti-freeze code borrowed from ReagentInfo (in turn, from Quest-I-On): |
||
47 | -- keeps WoW from locking up if we try to scan the tradeskill window too fast. |
||
48 | FLT_TradeSkillLock = { }; |
||
49 | FLT_TradeSkillLock.NeedScan = false; |
||
50 | FLT_TradeSkillLock.Locked = false; |
||
51 | FLT_TradeSkillLock.EventTimer = 0; |
||
52 | FLT_TradeSkillLock.EventCooldown = 0; |
||
53 | FLT_TradeSkillLock.EventCooldownTime = 1; |
||
54 | FLT_CraftLock = { }; |
||
55 | FLT_CraftLock.NeedScan = false; |
||
56 | FLT_CraftLock.Locked = false; |
||
57 | FLT_CraftLock.EventTimer = 0; |
||
58 | FLT_CraftLock.EventCooldown = 0; |
||
59 | FLT_CraftLock.EventCooldownTime = 1; |
||
60 | |||
61 | function FLT_OnLoad() |
||
62 | --GFWUtils.Debug = 1; |
||
63 | -- Register Slash Commands |
||
64 | SLASH_FLT1 = "/linkerator"; |
||
65 | SLASH_FLT2 = "/link"; |
||
66 | SlashCmdList["FLT"] = function(msg) |
||
67 | FLT_ChatCommandHandler(msg); |
||
68 | end |
||
69 | |||
70 | for index, value in ChatMessageTypes do |
||
71 | this:RegisterEvent(value); |
||
72 | end |
||
73 | |||
74 | for index = 1, getn(INVENTORY_SLOT_LIST), 1 do |
||
75 | INVENTORY_SLOT_LIST[index].id = GetInventorySlotInfo(INVENTORY_SLOT_LIST[index].name); |
||
76 | end |
||
77 | |||
78 | this:RegisterEvent("PLAYER_ENTERING_WORLD"); |
||
79 | this:RegisterEvent("PLAYER_LEAVING_WORLD"); |
||
80 | this:RegisterEvent("PLAYER_TARGET_CHANGED"); |
||
81 | this:RegisterEvent("BANKFRAME_OPENED"); |
||
82 | this:RegisterEvent("MERCHANT_SHOW"); |
||
83 | this:RegisterEvent("TRADE_SKILL_SHOW"); |
||
84 | this:RegisterEvent("TRADE_SKILL_UPDATE"); |
||
85 | this:RegisterEvent("CRAFT_SHOW"); |
||
86 | this:RegisterEvent("CRAFT_UPDATE"); |
||
87 | this:RegisterEvent("QUEST_COMPLETE"); |
||
88 | this:RegisterEvent("QUEST_DETAIL"); |
||
89 | this:RegisterEvent("QUEST_FINISHED"); |
||
90 | this:RegisterEvent("QUEST_PROGRESS"); |
||
91 | this:RegisterEvent("QUEST_GREETING"); |
||
92 | this:RegisterEvent("AUCTION_ITEM_LIST_UPDATE"); |
||
93 | |||
94 | GFWUtils.Print("Fizzwidget Linkerator "..FLT_VERSION.." initialized!"); |
||
95 | |||
96 | end |
||
97 | |||
98 | function FLT_OnUpdate(elapsed) |
||
99 | -- If it's been more than a second since our last tradeskill update, |
||
100 | -- we can allow the event to process again. |
||
101 | FLT_TradeSkillLock.EventTimer = FLT_TradeSkillLock.EventTimer + elapsed; |
||
102 | if (FLT_TradeSkillLock.Locked) then |
||
103 | FLT_TradeSkillLock.EventCooldown = FLT_TradeSkillLock.EventCooldown + elapsed; |
||
104 | if (FLT_TradeSkillLock.EventCooldown > FLT_TradeSkillLock.EventCooldownTime) then |
||
105 | |||
106 | FLT_TradeSkillLock.EventCooldown = 0; |
||
107 | FLT_TradeSkillLock.Locked = false; |
||
108 | end |
||
109 | end |
||
110 | FLT_CraftLock.EventTimer = FLT_CraftLock.EventTimer + elapsed; |
||
111 | if (FLT_CraftLock.Locked) then |
||
112 | FLT_CraftLock.EventCooldown = FLT_CraftLock.EventCooldown + elapsed; |
||
113 | if (FLT_CraftLock.EventCooldown > FLT_CraftLock.EventCooldownTime) then |
||
114 | |||
115 | FLT_CraftLock.EventCooldown = 0; |
||
116 | FLT_CraftLock.Locked = false; |
||
117 | end |
||
118 | end |
||
119 | |||
120 | if (FLT_TradeSkillLock.NeedScan) then |
||
121 | FLT_TradeSkillLock.NeedScan = false; |
||
122 | FLT_ScanTradeSkill(); |
||
123 | end |
||
124 | if (FLT_CraftLock.NeedScan) then |
||
125 | FLT_CraftLock.NeedScan = false; |
||
126 | FLT_ScanCraft(); |
||
127 | end |
||
128 | end |
||
129 | |||
130 | function FLT_OnEvent(event) |
||
131 | if( event == "PLAYER_TARGET_CHANGED" ) then |
||
132 | if( UnitIsUnit("target", "player") ) then |
||
133 | return; |
||
134 | elseif( UnitIsPlayer("target") ) then |
||
135 | FLT_Inspect("target"); |
||
136 | end |
||
137 | elseif( event == "PLAYER_ENTERING_WORLD" ) then |
||
138 | FLT_ScanInventory(); |
||
139 | FLT_Inspect("player"); |
||
140 | this:RegisterEvent("UNIT_INVENTORY_CHANGED"); |
||
141 | elseif( event == "PLAYER_LEAVING_WORLD" ) then |
||
142 | this:UnregisterEvent("UNIT_INVENTORY_CHANGED"); |
||
143 | elseif( event == "UNIT_INVENTORY_CHANGED" ) then |
||
144 | if( arg1 == "player" ) then |
||
145 | FLT_ScanInventory(); |
||
146 | FLT_Inspect("player"); |
||
147 | end |
||
148 | elseif( event == "MERCHANT_SHOW" ) then |
||
149 | for i=1, GetMerchantNumItems() do |
||
150 | local link = GetMerchantItemLink(i); |
||
151 | if ( link ) then |
||
152 | FLT_ProcessLinks(link); |
||
153 | end |
||
154 | end |
||
155 | elseif( event == "BANKFRAME_OPENED" ) then |
||
156 | FLT_ScanBank(); |
||
157 | elseif( event == "AUCTION_ITEM_LIST_UPDATE" ) then |
||
158 | FLT_ScanAuction(); |
||
159 | elseif ( event == "QUEST_COMPLETE" or event == "QUEST_DETAIL" or event == "QUEST_FINISHED" or event == "QUEST_PROGRESS" or event == "QUEST_GREETING") then |
||
160 | FLT_ScanQuestgiver(); |
||
161 | elseif ( event == "TRADE_SKILL_SHOW" or event == "TRADE_SKILL_UPDATE" ) then |
||
162 | FLT_ScanTradeSkill(); |
||
163 | elseif ( event == "CRAFT_SHOW" or event == "CRAFT_UPDATE" ) then |
||
164 | FLT_ScanCraft(); |
||
165 | elseif (event == "CHAT_MSG_CHANNEL") then |
||
166 | --DevTools_Dump({event=event, args={arg1=arg1,arg2=arg2,arg3=arg3,arg4=arg4,arg5=arg5,arg6=arg6,arg7=arg7,arg8=arg8,arg9=arg9,}}); |
||
167 | if (FLT_Debug) then |
||
168 | debugprofilestart(); |
||
169 | end |
||
170 | local gotLink = FLT_ProcessLinks(arg1); |
||
171 | if (FLT_Debug) then |
||
172 | local parseTime = debugprofilestop(); |
||
173 | if (gotLink) then |
||
174 | FLT_MaxFoundTime = math.max((FLT_MaxFoundTime or 0), parseTime); |
||
175 | else |
||
176 | FLT_MaxNotFoundTime = math.max((FLT_MaxNotFoundTime or 0), parseTime); |
||
177 | end |
||
178 | end |
||
179 | else |
||
180 | FLT_ProcessLinks(arg1); |
||
181 | end |
||
182 | end |
||
183 | |||
184 | function FLT_ChatCommandHandler(msg) |
||
185 | |||
186 | -- Print Help |
||
187 | if ( msg == "help" ) or ( msg == "" ) then |
||
188 | GFWUtils.Print("Fizzwidget Linkerator "..FLT_VERSION..":"); |
||
189 | GFWUtils.Print("/linkerator (or /link) <command>"); |
||
190 | GFWUtils.Print("- "..GFWUtils.Hilite("help").." - Print this helplist."); |
||
191 | GFWUtils.Print("- "..GFWUtils.Hilite("<item name>").." - Print a hyperlink to the chat window for an item known by name."); |
||
192 | GFWUtils.Print("- "..GFWUtils.Hilite("<item id #>").." - Print a hyperlink to the chat window for a generic item whose ID number is known."); |
||
193 | GFWUtils.Print("- "..GFWUtils.Hilite("<code>").." - Print a hyperlink to the chat window for an item whose complete link code is known."); |
||
194 | return; |
||
195 | end |
||
196 | |||
197 | if (msg == "version") then |
||
198 | GFWUtils.Print("Fizzwidget Linkerator "..FLT_VERSION); |
||
199 | return; |
||
200 | end |
||
201 | |||
202 | if (msg == "list") then |
||
203 | local totalCount, knownCount = 0, 0; |
||
204 | for name, linkInfo in FLT_ItemLinks do |
||
205 | if (type(linkInfo) == "string") then |
||
206 | totalCount = totalCount + 1; |
||
207 | local link = FLT_GetItemLink(linkInfo); |
||
208 | if (link) then |
||
209 | GFWUtils.Print(link); |
||
210 | knownCount = knownCount + 1; |
||
211 | else |
||
212 | GFWUtils.Print(name.." ("..linkInfo.."; not cached)"); |
||
213 | end |
||
214 | elseif (type(linkInfo) == "table") then |
||
215 | for _, linkID in linkInfo do |
||
216 | totalCount = totalCount + 1; |
||
217 | local link = FLT_GetItemLink(linkID); |
||
218 | if (link) then |
||
219 | GFWUtils.Print(link); |
||
220 | knownCount = knownCount + 1; |
||
221 | else |
||
222 | GFWUtils.Print(name.." ("..linkID.."; not cached)"); |
||
223 | end |
||
224 | end |
||
225 | end |
||
226 | end |
||
227 | GFWUtils.Print(GFWUtils.Hilite(totalCount).." items in history, "..GFWUtils.Hilite(knownCount).." known to client."); |
||
228 | return; |
||
229 | end |
||
230 | |||
231 | if (msg == "count") then |
||
232 | local totalCount, knownCount = 0, 0; |
||
233 | for name, linkInfo in FLT_ItemLinks do |
||
234 | if (type(linkInfo) == "string") then |
||
235 | totalCount = totalCount + 1; |
||
236 | local link = FLT_GetItemLink(linkInfo); |
||
237 | if (link) then |
||
238 | knownCount = knownCount + 1; |
||
239 | end |
||
240 | elseif (type(linkInfo) == "table") then |
||
241 | for _, linkID in linkInfo do |
||
242 | totalCount = totalCount + 1; |
||
243 | local link = FLT_GetItemLink(linkID); |
||
244 | if (link) then |
||
245 | knownCount = knownCount + 1; |
||
246 | end |
||
247 | end |
||
248 | end |
||
249 | end |
||
250 | GFWUtils.Print(GFWUtils.Hilite(totalCount).." items in history, "..GFWUtils.Hilite(knownCount).." known to client."); |
||
251 | return; |
||
252 | end |
||
253 | |||
254 | if (FLT_Debug and msg == "time") then |
||
255 | GFWUtils.Print(string.format("Max parse time "..GFWUtils.Hilite("%.2f").." ms (no links found)", FLT_MaxNotFoundTime * 1000)); |
||
256 | GFWUtils.Print(string.format("Max parse time "..GFWUtils.Hilite("%.2f").." ms (links found)", FLT_MaxFoundTime * 1000)); |
||
257 | return; |
||
258 | end |
||
259 | |||
260 | if (msg == "debug") then |
||
261 | if (FLT_Debug) then |
||
262 | FLT_Debug = nil; |
||
263 | GFWUtils.Print("Linkerator debugging messages off."); |
||
264 | else |
||
265 | FLT_Debug = 1; |
||
266 | GFWUtils.Print("Linkerator debugging messages on."); |
||
267 | end |
||
268 | return; |
||
269 | end |
||
270 | |||
271 | if (msg == "import") then |
||
272 | local lootLinkCount = 0; |
||
273 | if (ItemLinks and type(ItemLinks) == "table") then |
||
274 | for itemName, lootLinkInfo in ItemLinks do |
||
275 | if (lootLinkInfo.i and type(lootLinkInfo.i) == "string") then |
||
276 | local itemLink = "item:"..lootLinkInfo.i; |
||
277 | local addedLink = FLT_AddLink(itemName, itemLink); |
||
278 | if (addedLink) then |
||
279 | lootLinkCount = lootLinkCount + 1; |
||
280 | end |
||
281 | end |
||
282 | end |
||
283 | end |
||
284 | GFWUtils.Print(GFWUtils.Hilite(lootLinkCount).. " items imported from LootLink."); |
||
285 | end |
||
286 | |||
287 | local itemLink; |
||
288 | if (msg and msg ~= "") then |
||
289 | _, _, itemLink = string.find(msg, "(item:%d+:%d+:%d+:%d+)"); |
||
290 | end |
||
291 | if (tonumber(msg)) then |
||
292 | --DevTools_Dump({msg=msg}); |
||
293 | local link = FLT_GetItemLink(msg, 1); |
||
294 | if (link) then |
||
295 | GFWUtils.Print("Item ID "..msg..": "..link); |
||
296 | else |
||
297 | GFWUtils.Print("Item ID "..msg.." is unknown to this WoW client."); |
||
298 | end |
||
299 | return; |
||
300 | elseif (itemLink) then |
||
301 | --DevTools_Dump({msg=msg, itemLink=itemLink}); |
||
302 | local link = FLT_GetItemLink(itemLink, 1); |
||
303 | if (link) then |
||
304 | GFWUtils.Print(itemLink..": "..link); |
||
305 | else |
||
306 | GFWUtils.Print(itemLink.." is unknown to this WoW client."); |
||
307 | end |
||
308 | return; |
||
309 | elseif (msg and msg ~= "") then |
||
310 | local foundLinks = FLT_GetLinkByName(msg, true); |
||
311 | if (foundLinks) then |
||
312 | if (type(foundLinks) == "string") then |
||
313 | if (FLT_Debug) then |
||
314 | local _, _, linkInfo = string.find(foundLinks, "(item:%d+:%d+:%d+:%d+)"); |
||
315 | GFWUtils.Print(foundLinks.." ("..linkInfo..")"); |
||
316 | else |
||
317 | GFWUtils.Print(foundLinks); |
||
318 | end |
||
319 | elseif (type(foundLinks) == "table") then |
||
320 | for _, aLink in foundLinks do |
||
321 | if (FLT_Debug) then |
||
322 | local _, _, linkInfo = string.find(aLink, "(item:%d+:%d+:%d+:%d+)"); |
||
323 | GFWUtils.Print(aLink.." ("..linkInfo..")"); |
||
324 | else |
||
325 | GFWUtils.Print(aLink); |
||
326 | end |
||
327 | end |
||
328 | else |
||
329 | GFWUtils.Print(GFWUtils.Red("Linkerator error: ").."Unexpected result from FLT_GetLinkByName()."); |
||
330 | end |
||
331 | else |
||
332 | local foundCount = 0; |
||
333 | msg = string.lower(msg); |
||
334 | for itemName, linkInfo in FLT_ItemLinks do |
||
335 | if (string.find(itemName, msg)) then |
||
336 | if (type(linkInfo) == "string") then |
||
337 | local link = FLT_GetItemLink(linkInfo); |
||
338 | if (link) then |
||
339 | if (FLT_Debug) then |
||
340 | GFWUtils.Print(link.." ("..linkInfo..")"); |
||
341 | else |
||
342 | GFWUtils.Print(link); |
||
343 | end |
||
344 | foundCount = foundCount + 1; |
||
345 | end |
||
346 | elseif (type(linkInfo) == "table") then |
||
347 | for _, aLink in linkInfo do |
||
348 | local link = FLT_GetItemLink(aLink); |
||
349 | if (link) then |
||
350 | if (FLT_Debug) then |
||
351 | GFWUtils.Print(link.." ("..aLink..")"); |
||
352 | else |
||
353 | GFWUtils.Print(link); |
||
354 | end |
||
355 | foundCount = foundCount + 1; |
||
356 | end |
||
357 | end |
||
358 | end |
||
359 | end |
||
360 | end |
||
361 | if (foundCount > 0) then |
||
362 | GFWUtils.Print(GFWUtils.Hilite(foundCount).." links found for '"..GFWUtils.Hilite(msg).."'"); |
||
363 | else |
||
364 | GFWUtils.Print("Could not find '"..GFWUtils.Hilite(msg).."' in Linkerator's item history."); |
||
365 | end |
||
366 | end |
||
367 | return; |
||
368 | end |
||
369 | |||
370 | -- If we're this far, we probably have bad input. |
||
371 | FDP_ChatCommandHandler("help"); |
||
372 | end |
||
373 | |||
374 | function FLT_GetItemLink(linkInfo, shouldAdd) |
||
375 | local sName, sLink, iQuality, iLevel, sType, sSubType, iCount = GetItemInfo(linkInfo); |
||
376 | if (sName) then |
||
377 | local _, _, _, color = GetItemQualityColor(iQuality); |
||
378 | local linkFormat = "%s|H%s|h[%s]|h|r"; |
||
379 | if (shouldAdd) then |
||
380 | FLT_AddLink(sName, sLink); -- add it to our name index if we're getting it from another source |
||
381 | end |
||
382 | return string.format(linkFormat, color, sLink, sName); |
||
383 | else |
||
384 | return nil; |
||
385 | end |
||
386 | end |
||
387 | |||
388 | function FLT_GetLinkByName(text, returnAll) |
||
389 | local _, _, name, property = string.find(text, "(.+)%((.-)%)" ); |
||
390 | local linkInfo = FLT_ItemLinks[string.lower(text)]; |
||
391 | local allResults = {}; |
||
392 | if (linkInfo == nil and name and property) then |
||
393 | name = string.lower(string.gsub(name, " +$", "")); |
||
394 | property = string.lower(property); |
||
395 | linkInfo = FLT_ItemLinks[string.lower(name)]; |
||
396 | end |
||
397 | if (linkInfo) then |
||
398 | if (type(linkInfo) == "string") then |
||
399 | local link = FLT_GetItemLink(linkInfo); |
||
400 | if (link) then return link; end |
||
401 | elseif (type(linkInfo) == "table" and name and property) then |
||
402 | for _, itemLink in linkInfo do |
||
403 | local _, _, _, _, type, subType, _, equipLoc = GetItemInfo(itemLink); |
||
404 | if ((type and string.find(string.lower(type), property)) |
||
405 | or (subType and string.find(string.lower(subType), property)) |
||
406 | or (getglobal(equipLoc) and string.find(string.lower(getglobal(equipLoc)), property))) then |
||
407 | local link = FLT_GetItemLink(itemLink); |
||
408 | if (link and returnAll) then |
||
409 | table.insert(allResults, link); |
||
410 | elseif (link) then |
||
411 | return link; |
||
412 | end |
||
413 | end |
||
414 | end |
||
415 | for _, itemLink in linkInfo do |
||
416 | if (FLT_FindInItemTooltip(property, itemLink)) then |
||
417 | if (returnAll) then |
||
418 | table.insert(allResults, FLT_GetItemLink(itemLink)); |
||
419 | else |
||
420 | return FLT_GetItemLink(itemLink); |
||
421 | end |
||
422 | end |
||
423 | end |
||
424 | elseif (type(linkInfo) == "table") then |
||
425 | for _, itemLink in linkInfo do |
||
426 | local link = FLT_GetItemLink(itemLink); |
||
427 | if (link and returnAll) then |
||
428 | table.insert(allResults, link); |
||
429 | elseif (link) then |
||
430 | return link; |
||
431 | end |
||
432 | end |
||
433 | else |
||
434 | GFWUtils.Print(GFWUtils.Red("Linkerator error: ").."Corrupt table entry for "..GFWUtils.Hilite(name).."."); |
||
435 | end |
||
436 | elseif (string.find(text, "^(item:%d+:%d+:%d+:%d+)$")) then |
||
437 | local link = FLT_GetItemLink(text); |
||
438 | if (link) then return link; end |
||
439 | elseif (string.find(text, "^#%d+$")) then |
||
440 | local link = FLT_GetItemLink(string.sub(text,2)); |
||
441 | if (link) then return link; end |
||
442 | end |
||
443 | if (returnAll and table.getn(allResults) > 0) then |
||
444 | return allResults; |
||
445 | end |
||
446 | end |
||
447 | |||
448 | function FLT_ProcessLinks(text) |
||
449 | local lastLink; |
||
450 | if ( text ) then |
||
451 | local link, name; |
||
452 | for link, name in string.gfind(text, "|c%x+|H(item:%d+:%d+:%d+:%d+)|h%[(.-)%]|h|r") do |
||
453 | if (link and name and name ~= "") then |
||
454 | lastLink = FLT_AddLink(name, link); |
||
455 | end |
||
456 | end |
||
457 | end |
||
458 | return lastLink; |
||
459 | end |
||
460 | |||
461 | function FLT_AddLink(name, link) |
||
462 | local cleanLink = string.gsub(link, "item:(%d+):%d+:(%d+):%d+", "item:%1:0:%2:0"); -- strip uniqID, enchant |
||
463 | name = string.lower(name); -- so we can do case-insensitive lookups |
||
464 | local existingLink = FLT_ItemLinks[name]; |
||
465 | if (existingLink and existingLink ~= cleanLink) then |
||
466 | if (type(existingLink) == "string") then |
||
467 | FLT_ItemLinks[name] = {}; |
||
468 | table.insert(FLT_ItemLinks[name], existingLink); |
||
469 | table.insert(FLT_ItemLinks[name], cleanLink); |
||
470 | if (FLT_Debug) then GFWUtils.Print("Added "..(FLT_GetItemLink(cleanLink) or name).." ("..cleanLink.."); changed to table"); end |
||
471 | elseif (type(existingLink) == "table") then |
||
472 | if (GFWTable.KeyOf(existingLink, cleanLink) == nil) then |
||
473 | FLT_ItemLinks[name] = GFWTable.Merge(existingLink, {cleanLink}); |
||
474 | if (FLT_Debug) then GFWUtils.Print("Added "..(FLT_GetItemLink(cleanLink) or name).." ("..cleanLink.."); table count is now "..GFWTable.Count(FLT_ItemLinks[name])); end |
||
475 | end |
||
476 | else |
||
477 | GFWUtils.PrintOnce("Corrupt entry for "..GFWUtils.Hilite(name).."; replacing with "..FLT_GetItemLink(cleanLink)..".", 60); |
||
478 | FLT_ItemLinks[name] = cleanLink; |
||
479 | end |
||
480 | elseif (existingLink == nil) then |
||
481 | FLT_ItemLinks[name] = cleanLink; |
||
482 | if (FLT_Debug) then GFWUtils.Print("Added "..(FLT_GetItemLink(cleanLink) or name).." ("..cleanLink..")"); end |
||
483 | end |
||
484 | return cleanLink; |
||
485 | end |
||
486 | |||
487 | function FLT_InspectSlot(unit, id) |
||
488 | local link = GetInventoryItemLink(unit, id); |
||
489 | if ( link ) then |
||
490 | FLT_ProcessLinks(link); |
||
491 | end |
||
492 | end |
||
493 | |||
494 | function FLT_Inspect(who) |
||
495 | local index; |
||
496 | |||
497 | for index = 1, getn(INVENTORY_SLOT_LIST), 1 do |
||
498 | FLT_InspectSlot(who, INVENTORY_SLOT_LIST[index].id) |
||
499 | end |
||
500 | end |
||
501 | |||
502 | function FLT_ScanTradeSkill() |
||
503 | if (not TradeSkillFrame or not TradeSkillFrame:IsVisible() or FLT_TradeSkillLock.Locked) then return; end |
||
504 | -- This prevents further update events from being handled if we're already processing one. |
||
505 | -- This is done to prevent the game from freezing under certain conditions. |
||
506 | FLT_TradeSkillLock.Locked = true; |
||
507 | |||
508 | local skillLineName, skillLineRank, skillLineMaxRank = GetTradeSkillLine(); |
||
509 | if not (skillLineName) then |
||
510 | FLT_TradeSkillLock.NeedScan = true; |
||
511 | return; -- apparently sometimes we're called too early, this is nil, and all hell breaks loose. |
||
512 | end |
||
513 | |||
514 | for id = 1, GetNumTradeSkills() do |
||
515 | local skillName, skillType, numAvailable, isExpanded = GetTradeSkillInfo(id); |
||
516 | if ( skillType ~= "header" ) then |
||
517 | local itemLink = GetTradeSkillItemLink(id); |
||
518 | if (itemLink == nil) then |
||
519 | FLT_TradeSkillLock.NeedScan = true; |
||
520 | else |
||
521 | FLT_ProcessLinks(itemLink); |
||
522 | for i=1, GetTradeSkillNumReagents(id), 1 do |
||
523 | local link = GetTradeSkillReagentItemLink(id, i); |
||
524 | if (link == nil) then |
||
525 | FLT_TradeSkillLock.NeedScan = true; |
||
526 | break; |
||
527 | else |
||
528 | FLT_ProcessLinks(link); |
||
529 | end |
||
530 | end |
||
531 | end |
||
532 | end |
||
533 | end |
||
534 | |||
535 | end |
||
536 | |||
537 | function FLT_ScanCraft() |
||
538 | if (not CraftFrame or not CraftFrame:IsVisible() or FLT_CraftLock.Locked) then return; end |
||
539 | -- This prevents further update events from being handled if we're already processing one. |
||
540 | -- This is done to prevent the game from freezing under certain conditions. |
||
541 | FLT_CraftLock.Locked = true; |
||
542 | |||
543 | -- This is used only for Enchanting |
||
544 | local skillLineName, rank, maxRank = GetCraftDisplaySkillLine(); |
||
545 | if not (skillLineName) then |
||
546 | return; -- Hunters' Beast Training also uses the CraftFrame, but doesn't have a SkillLine. |
||
547 | end |
||
548 | |||
549 | for id = GetNumCrafts(), 1, -1 do |
||
550 | if ( craftType ~= "header" ) then |
||
551 | local itemLink = GetCraftItemLink(id); |
||
552 | if (itemLink == nil) then |
||
553 | FLT_TradeSkillLock.NeedScan = true; |
||
554 | else |
||
555 | FLT_ProcessLinks(itemLink); |
||
556 | |||
557 | for i=1, GetCraftNumReagents(id), 1 do |
||
558 | local link = GetCraftReagentItemLink(id, i); |
||
559 | if (link == nil) then |
||
560 | FLT_CraftLock.NeedScan = true; |
||
561 | break; |
||
562 | else |
||
563 | FLT_ProcessLinks(link); |
||
564 | end |
||
565 | end |
||
566 | end |
||
567 | end |
||
568 | end |
||
569 | end |
||
570 | |||
571 | function FLT_ScanQuestgiver() |
||
572 | local link; |
||
573 | for i = 1, GetNumQuestItems() do |
||
574 | link = GetQuestItemLink("required", i); |
||
575 | if (link) then |
||
576 | FLT_ProcessLinks(link); |
||
577 | end |
||
578 | end |
||
579 | for i = 1, GetNumQuestChoices() do |
||
580 | link = GetQuestItemLink("choice", i); |
||
581 | if (link) then |
||
582 | FLT_ProcessLinks(link); |
||
583 | end |
||
584 | end |
||
585 | for i = 1, GetNumQuestRewards() do |
||
586 | link = GetQuestItemLink("reward", i); |
||
587 | if (link) then |
||
588 | FLT_ProcessLinks(link); |
||
589 | end |
||
590 | end |
||
591 | end |
||
592 | |||
593 | function FLT_ScanInventory() |
||
594 | local bagid, size, slotid, link; |
||
595 | |||
596 | for bagid = 0, 4, 1 do |
||
597 | size = GetContainerNumSlots(bagid); |
||
598 | if( size ) then |
||
599 | for slotid = size, 1, -1 do |
||
600 | link = GetContainerItemLink(bagid, slotid); |
||
601 | if( link ) then |
||
602 | FLT_ProcessLinks(link); |
||
603 | end |
||
604 | end |
||
605 | end |
||
606 | end |
||
607 | end |
||
608 | |||
609 | function FLT_ScanAuction() |
||
610 | local numBatchAuctions, totalAuctions = GetNumAuctionItems("list"); |
||
611 | local auctionid, link; |
||
612 | |||
613 | if( numBatchAuctions > 0 ) then |
||
614 | for auctionid = 1, numBatchAuctions do |
||
615 | link = GetAuctionItemLink("list", auctionid); |
||
616 | if( link ) then |
||
617 | FLT_ProcessLinks(link); |
||
618 | end |
||
619 | end |
||
620 | end |
||
621 | end |
||
622 | |||
623 | function FLT_ScanBank() |
||
624 | local index, bagid, size, slotid, link; |
||
625 | local lBankBagIDs = { BANK_CONTAINER, 5, 6, 7, 8, 9, 10, }; |
||
626 | |||
627 | for index, bagid in lBankBagIDs do |
||
628 | size = GetContainerNumSlots(bagid); |
||
629 | if( size ) then |
||
630 | for slotid = size, 1, -1 do |
||
631 | link = GetContainerItemLink(bagid, slotid); |
||
632 | if( link ) then |
||
633 | FLT_ProcessLinks(link); |
||
634 | end |
||
635 | end |
||
636 | end |
||
637 | end |
||
638 | end |
||
639 | |||
640 | function FLT_LinkifyName(head, text, tail) |
||
641 | if (head ~= "|h" and tail ~= "|h") then -- only linkify things text that isn't linked already |
||
642 | local link = FLT_GetLinkByName(text); |
||
643 | if (link) then return link; end |
||
644 | end |
||
645 | return head.."["..text.."]"..tail; |
||
646 | end |
||
647 | |||
648 | function FLT_FindInItemTooltip(text, link) |
||
649 | LinkeratorTip:ClearLines(); |
||
650 | LinkeratorTip:SetHyperlink(link); |
||
651 | for lineNum = 1, LinkeratorTip:NumLines() do |
||
652 | local leftText = getglobal("LinkeratorTipTextLeft"..lineNum):GetText(); |
||
653 | if (leftText and string.find(string.lower(leftText), text)) then return true; end |
||
654 | local rightText = getglobal("LinkeratorTipTextRight"..lineNum):GetText(); |
||
655 | if (rightText and string.find(string.lower(rightText), text)) then return true; end |
||
656 | end |
||
657 | for lineNum = 1, LinkeratorTip:NumLines() do |
||
658 | -- for some reason ClearLines alone isn't clearing the right-side text |
||
659 | getglobal("LinkeratorTipTextLeft"..lineNum):SetText(nil); |
||
660 | getglobal("LinkeratorTipTextRight"..lineNum):SetText(nil); |
||
661 | end |
||
662 | end |
||
663 | |||
664 | function FLT_ParseChatMessage(text) |
||
665 | return string.gsub(text, "([|]?[h]?)%[(.-)%]([|]?[h]?)", FLT_LinkifyName); |
||
666 | end |
||
667 | |||
668 | -- Hooks |
||
669 | |||
670 | FLT_Orig_ChatEdit_OnTextChanged = ChatEdit_OnTextChanged; |
||
671 | function ChatEdit_OnTextChanged() |
||
672 | local text = this:GetText(); |
||
673 | if (string.find(text, "^/script") or string.find(text, "^/dump")) then |
||
674 | -- don't parse |
||
675 | else |
||
676 | text = FLT_ParseChatMessage(text); |
||
677 | this:SetText(text); |
||
678 | end |
||
679 | FLT_Orig_ChatEdit_OnTextChanged(this); |
||
680 | end |
||
681 | |||
682 | FLT_Orig_QuestLog_UpdateQuestDetails = QuestLog_UpdateQuestDetails; |
||
683 | function QuestLog_UpdateQuestDetails() |
||
684 | for i = 1, GetNumQuestLogChoices() do |
||
685 | link = GetQuestLogItemLink("choice", i); |
||
686 | if (link) then |
||
687 | FLT_ProcessLinks(link); |
||
688 | end |
||
689 | end |
||
690 | for i = 1, GetNumQuestLogRewards() do |
||
691 | link = GetQuestLogItemLink("reward", i); |
||
692 | if (link) then |
||
693 | FLT_ProcessLinks(link); |
||
694 | end |
||
695 | end |
||
696 | FLT_Orig_QuestLog_UpdateQuestDetails(); |
||
697 | end |