vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
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