@@ -51,6 +51,7 @@ local setmetatable = _G.setmetatable
51
51
local strjoin = _G .strjoin
52
52
local strmatch = _G .strmatch
53
53
local strsplit = _G .strsplit
54
+ local strsplittable = _G .strsplittable
54
55
local tonumber = _G .tonumber
55
56
local tostring = _G .tostring
56
57
local type = _G .type
@@ -170,6 +171,88 @@ function addon.IsValidItemLink(link)
170
171
end
171
172
end
172
173
174
+ -- ParseItemLink parses an item link for it's distinct attributes and
175
+ -- returns a table with every attribute. Updated as of retail 9.2.7.
176
+ function addon .ParseItemLink (link )
177
+ -- Parse the first elements that have no variable length
178
+ local _ , itemID , enchantID , gemID1 , gemID2 , gemID3 , gemID4 ,
179
+ suffixID , uniqueID , linkLevel , specializationID , modifiersMask ,
180
+ itemContext , rest = strsplit (" :" , link , 14 )
181
+
182
+ -- The next several link items have a variable length and must be parsed
183
+ -- out one by one. There is definitely a more clever way of doing this,
184
+ -- but we want to optimize for readability. Blizzard has upended item links
185
+ -- before, which would make this code diffcult to update if it's too "clever".
186
+ local numBonusIDs
187
+ local bonusIDs
188
+ numBonusIDs , rest = strsplit (" :" , rest , 2 )
189
+ if numBonusIDs ~= " " then
190
+ local splits = (tonumber (numBonusIDs ))+ 1
191
+ bonusIDs = strsplittable (" :" , rest , splits )
192
+ rest = table.remove (bonusIDs , splits )
193
+ end
194
+
195
+ local numModifiers
196
+ local modifierIDs
197
+ numModifiers , rest = strsplit (" :" , rest , 2 )
198
+ if numModifiers ~= " " then
199
+ local splits = (tonumber (numModifiers )* 2 )+ 1
200
+ modifierIDs = strsplittable (" :" , rest , splits )
201
+ rest = table.remove (modifierIDs , splits )
202
+ end
203
+
204
+ local relic1NumBonusIDs
205
+ local relic1BonusIDs
206
+ relic1NumBonusIDs , rest = strsplit (" :" , rest , 2 )
207
+ if relic1NumBonusIDs ~= " " then
208
+ local splits = (tonumber (relic1NumBonusIDs ))+ 1
209
+ relic1BonusIDs = strsplittable (" :" , rest , splits )
210
+ rest = table.remove (relic1BonusIDs , splits )
211
+ end
212
+
213
+ local relic2NumBonusIDs
214
+ local relic2BonusIDs
215
+ relic2NumBonusIDs , rest = strsplit (" :" , rest , 2 )
216
+ if relic2NumBonusIDs ~= " " then
217
+ local splits = (tonumber (relic2NumBonusIDs ))+ 1
218
+ relic2BonusIDs = strsplittable (" :" , rest , (tonumber (relic2NumBonusIDs ))+ 1 )
219
+ rest = table.remove (relic2BonusIDs , splits )
220
+ end
221
+
222
+ local relic3NumBonusIDs
223
+ local relic3BonusIDs
224
+ relic3NumBonusIDs , rest = strsplit (" :" , rest , 2 )
225
+ if relic3NumBonusIDs ~= " " then
226
+ local splits = (tonumber (relic3NumBonusIDs ))+ 1
227
+ relic3BonusIDs = strsplittable (" :" , rest , (tonumber (relic3NumBonusIDs ))+ 1 )
228
+ rest = table.remove (relic3BonusIDs , splits )
229
+ end
230
+
231
+ local crafterGUID , extraEnchantID = strsplit (" :" , rest , 3 )
232
+
233
+ return {
234
+ itemID = itemID ,
235
+ enchantID = enchantID ,
236
+ gemID1 = gemID1 ,
237
+ gemID2 = gemID2 ,
238
+ gemID3 = gemID3 ,
239
+ gemID4 = gemID4 ,
240
+ suffixID = suffixID ,
241
+ uniqueID = uniqueID ,
242
+ linkLevel = linkLevel ,
243
+ specializationID = specializationID ,
244
+ modifiersMask = modifiersMask ,
245
+ itemContext = itemContext ,
246
+ bonusIDs = bonusIDs or {},
247
+ modifierIDs = modifierIDs or {},
248
+ relic1BonusIDs = relic1BonusIDs or {},
249
+ relic2BonusIDs = relic2BonusIDs or {},
250
+ relic3BonusIDs = relic3BonusIDs or {},
251
+ crafterGUID = crafterGUID ,
252
+ extraEnchantID = extraEnchantID
253
+ }
254
+ end
255
+
173
256
---- ----------------------------------------------------------------------------
174
257
-- Get distinct item IDs from item links
175
258
---- ----------------------------------------------------------------------------
@@ -179,15 +262,29 @@ local function __GetDistinctItemID(link)
179
262
if strmatch (link , " battlepet:" ) or strmatch (link , " keystone:" ) then
180
263
return link
181
264
else
182
- local itemString , id , enchant , gem1 , gem2 , gem3 , gem4 , suffix , reforge = strmatch (link , ' (item:(%-?%d+):(%-?%d+):(%-?%d+):(%-?%d+):(%-?%d+):(%-?%d+):(%-?%d+):%-?%d+:%-?%d+:(%-?%d+))' )
183
- if not id then return end
184
- id = tonumber (id )
265
+ local itemData = addon .ParseItemLink (link )
266
+ if not itemData then return end
267
+ local newLink
268
+ local id = tonumber (itemData .itemID )
185
269
local equipSlot = select (9 , GetItemInfo (id ))
186
270
if equipSlot and equipSlot ~= " " and equipSlot ~= " INVTYPE_BAG" then
187
- -- Rebuild an item link without noise
188
- id = strjoin (' :' , ' item' , id , enchant , gem1 , gem2 , gem3 , gem4 , suffix , " 0" , " 0" , reforge )
271
+ -- Rebuild an item link without any unique identifiers that are out of the player's control.
272
+ newLink = strjoin (' :' , ' |Hitem' ,
273
+ itemData .itemID , itemData .enchantID , itemData .gemID1 , itemData .gemID2 , itemData .gemID3 , itemData .gemID4 ,
274
+ itemData .suffixID , itemData .uniqueID , itemData .linkLevel , itemData .specializationID ,
275
+ itemData .modifiersMask , itemData .itemContext ,
276
+ # itemData .bonusIDs ,
277
+ table.concat (itemData .bonusIDs , " :" ),
278
+ # itemData .modifierIDs ,
279
+ table.concat (itemData .modifierIDs ),
280
+ " " , -- Relic 1
281
+ " " , -- Relic 2
282
+ " " , -- Relic 3
283
+ " " , -- Crafter GUID
284
+ itemData .extraEnchantID or " " -- Fix for non-retail.
285
+ )
189
286
end
190
- return id
287
+ return newLink
191
288
end
192
289
end
193
290
0 commit comments