@@ -51,6 +51,7 @@ local setmetatable = _G.setmetatable
5151local strjoin = _G .strjoin
5252local strmatch = _G .strmatch
5353local strsplit = _G .strsplit
54+ local strsplittable = _G .strsplittable
5455local tonumber = _G .tonumber
5556local tostring = _G .tostring
5657local type = _G .type
@@ -170,6 +171,88 @@ function addon.IsValidItemLink(link)
170171 end
171172end
172173
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+
173256---- ----------------------------------------------------------------------------
174257-- Get distinct item IDs from item links
175258---- ----------------------------------------------------------------------------
@@ -179,15 +262,29 @@ local function __GetDistinctItemID(link)
179262 if strmatch (link , " battlepet:" ) or strmatch (link , " keystone:" ) then
180263 return link
181264 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 )
185269 local equipSlot = select (9 , GetItemInfo (id ))
186270 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+ )
189286 end
190- return id
287+ return newLink
191288 end
192289end
193290
0 commit comments