forked from doorknob6/Inspector
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscanner.lua
More file actions
254 lines (224 loc) · 8 KB
/
scanner.lua
File metadata and controls
254 lines (224 loc) · 8 KB
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
Inspector.scanner = {
Tooltip = CreateFrame("GameTooltip", "Inspector.scannerTip", UIParent, "GameTooltipTemplate"),
ItemLinkPattern = "^.+|H(item:[^|]+)|h%[.+$",
SetNamePattern = "^(.+) %(%d/(%d)%)$",
Slots = {
"HeadSlot",
"NeckSlot",
"ShoulderSlot",
"BackSlot",
"ChestSlot",
"ShirtSlot",
"TabardSlot",
"WristSlot",
"HandsSlot",
"WaistSlot",
"LegsSlot",
"FeetSlot",
"Finger0Slot",
"Finger1Slot",
"Trinket0Slot",
"Trinket1Slot",
"MainHandSlot",
"SecondaryHandSlot",
"RangedSlot"
},
};
Inspector.scanner.Tooltip:SetFrameStrata("TOOLTIP");
-- Gets the item slot button item link
function Inspector.scanner:GetItemSlotButtonLink(button, unit)
local link = GetInventoryItemLink(unit, button:GetID());
return self:CleanItemLink(link);
end
-- cleans the item link
function Inspector.scanner:CleanItemLink(link)
if (link) then
local _, _, linkMatch = string.find(link, self.ItemLinkPattern);
if (linkMatch) then
link = linkMatch;
end
end
return link;
end
-- Scan all items and set bonuses on given `unit` (Make sure the tables are reset)
function Inspector.scanner:ScanUnitItems(unit, statTable, setTable)
if (not unit) or (not UnitExists(unit)) then
return;
end
-- Check all item slots
for _, slotName in ipairs(self.Slots) do
self:ScanItemSlot(slotName, unit, statTable, setTable);
end
end
-- Scans the `itemSlotButton` for the `unit`. Adds stats to the `statTable` and any new set items to `setTable`.
-- Returns the itemLink.
function Inspector.scanner:ScanItemSlotButton(itemSlotButton, unit, statTable, setTable)
local link = self:GetItemSlotButtonLink(itemSlotButton, unit);
return self:ScanItemLink(link, statTable, setTable);
end
-- Scans a single item given by `itemLink`. Adds stats to the `statTable` and any new set items to `setTable`.
-- Returns the itemLink.
function Inspector.scanner:ScanItemLink(itemLink, statTable, setTable)
if (itemLink) then
-- Set Link
self.Tooltip:SetOwner(UIParent, "ANCHOR_NONE");
self.Tooltip:SetHyperlink(itemLink);
self:ScanTooltip(self.Tooltip, statTable, setTable);
end
return itemLink;
end
-- Scans a single `tooltip`, stats and sets are added to the `statTable` and `setTable` variable
function Inspector.scanner:ScanTooltip(tooltip, statTable, setTable)
local setName = nil;
-- Check Lines
for i = 2, tooltip:NumLines() do
if (self:DoLineNeedScan(getglobal("Inspector.scannerTipTextLeft" .. i), true)) then
-- Check if current line is an item set header
setName = self:HandleItemSetHeader(setTable) or setName;
-- check if the line is a set bonus, else add it
if (not Inspector.scanner:HandleSetBonus(setName, setTable, statTable)) then
self:ScanLineForPatterns(self.text, statTable);
end
end
end
end
-- compares the given tooltip to the tooltip generated by the given itemLink
function Inspector.scanner:CompareTooltipToItemLink(tooltip, itemLink, linesToCompare)
-- Set New Item Tip
self.Tooltip:SetOwner(UIParent, "ANCHOR_NONE");
self.Tooltip:SetHyperlink(itemLink);
local check;
for i = 1, (linesToCompare or self.Tooltip:NumLines()) do
check = self:CompareTooltipLine(tooltip, self.Tooltip, i);
if (not check) then return false; end
end
return true;
end
-- compares the given tooltips at the requested linenumber
function Inspector.scanner:CompareTooltipLine(tooltip, checkTooltip, lineNumber)
local tooltipLine = getglobal(tooltip:GetName() .. "TextLeft" .. lineNumber):GetText();
local checkTooltipLine = getglobal(checkTooltip:GetName() .. "TextLeft" .. lineNumber):GetText();
return (tooltipLine == checkTooltipLine);
end
-- Checks if a Line Needs to be Scanned for Patterns
function Inspector.scanner:DoLineNeedScan(tipLine, scanSetBonuses)
-- Init Line
self.text = string.gsub(tipLine:GetText(), "|c%x%x%x%x%x%x%x%x", "");
self.r, self.g, self.b = tipLine:GetTextColor();
self.r, self.g, self.b = ceil(self.r * 255), ceil(self.g * 255), ceil(self.b * 255);
if (self.r == 128 and self.g == 128 and self.b == 128) then -- Always *Skip* Gray Lines, except for unfilled set bonuses
if (scanSetBonuses and string.find(self.text, self.SetBonusToken)) then
return 1;
end
return;
elseif (not scanSetBonuses and string.find(self.text, self.SetBonusTokenActive)) then -- Active Set Bonuses (Must be checked before green color check)
return;
elseif (self.r == 0 and self.g == 255 and self.b == 0) then -- Always *Scan* Green Lines
return 1;
elseif (string.find(self.text, "^%+?%d+ %a")) then -- Should Match: Normal +Stat, Base Item Armor, Block Value on Shields
return 1;
elseif (scanSetBonuses and string.find(self.text, self.SetNamePattern)) then -- Set Names (Needed to Check Sets)
return 1;
else
return;
end
end
-- Handles scanning an itemset header line. returns (setName) if the current line is a header line, else nil.
function Inspector.scanner:HandleItemSetHeader(setTable)
local setName, setMax;
if (string.find(self.text, self.SetNamePattern)) then
_, _, setName, setMax = string.find(self.text, self.SetNamePattern);
if (setTable[setName]) then
setTable[setName].count = setTable[setName].count + 1;
else
setTable[setName] = { count = 1, max = tonumber(setMax) };
end
return setName;
end
return nil;
end
-- Handles scanning a set bonus line.
function Inspector.scanner:HandleSetBonus(setName, setTable, statTable)
if (not setName) then
return nil;
end
-- check if bonus may be added
local addBonus = false;
local bonusText;
if (string.find(self.text, self.SetBonusTokenActive)) then
_, _, bonusText = string.find(self.text, self.SetBonusTokenActive);
if (not self:HasSetBonus(bonusText, setName, setTable)) then
addBonus = true;
end
elseif (string.find(self.text, self.SetBonusToken)) then
local neededItems;
_, _, neededItems, bonusText = string.find(self.text, self.SetBonusToken);
neededItems = tonumber(neededItems);
if ((setTable[setName].count == neededItems) and (not self:HasSetBonus(bonusText, setName, setTable))) then
addBonus = true;
end
end
-- if bonusText is found - return line as handled
if (bonusText) then
-- if the bonus hasn't been added yet, add it
if (addBonus) then
self:ScanLineForPatterns(bonusText, statTable);
local index = self:GetNextSetBonusIndex(setName, setTable);
setTable[setName]["setBonus" .. index] = bonusText;
end
return 1;
end
return nil;
end
-- checks if the `bonusText` is present in the `setTable` under `setName`
function Inspector.scanner:HasSetBonus(bonusText, setName, setTable)
if (not setTable[setName]) then
return false;
end
local idx = 1;
local currentBonusText;
while (setTable[setName]["setBonus" .. idx]) do
currentBonusText = setTable[setName]["setBonus" .. idx];
if (currentBonusText == bonusText) then
return true;
end
idx = (idx + 1);
end
return false;
end
-- gets the next set bonus index
function Inspector.scanner:GetNextSetBonusIndex(setName, setTable)
local idx = 1;
while (setTable[setName]["setBonus" .. idx]) do
idx = (idx + 1);
end
return idx;
end
-- Checks a Single Line for Patterns, adds any found value to the given statTable
function Inspector.scanner:ScanLineForPatterns(text, statTable)
local addedValue = 0;
for _patternIndex, pattern in ipairs(self.Patterns) do
-- lua 5.0 implementation of string.match
if (string.find(text, pattern.p)) then
self.findPos, _, self.findValue = string.find(text, pattern.p);
else
self.findPos = nil;
self.findValue = nil;
end
if (self.findPos) and (self.findValue or pattern.v) then
if (type(pattern.s) == "string") then
addedValue = (self.findValue or pattern.v);
self:AddStatValue(pattern.s, addedValue, statTable);
elseif (type(pattern.s) == "table") then
for statIndex, statToken in ipairs(pattern.s) do
addedValue = (type(pattern.v) == "table" and pattern.v[statIndex] or self.findValue or pattern.v);
self:AddStatValue(statToken, addedValue, statTable);
end
end
end
end
end
-- adds the `addedValue` to the `statToken` in the `statTable`
function Inspector.scanner:AddStatValue(statToken, addedValue, statTable)
statTable[statToken] = (statTable[statToken] or 0) + addedValue;
end