From e7f639b5acb906bc88cd3e2587ed64eae0438843 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Sun, 26 Jul 2026 23:45:48 +0300 Subject: [PATCH 1/4] Add support for 3.29 vestigial and intangibility parsing --- src/Classes/Item.lua | 11 ++++++++++- src/Classes/ItemsTab.lua | 5 +++++ src/Data/Global.lua | 4 +++- src/Modules/ItemTools.lua | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index 5498d2aace..0cfef8a6c6 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -125,6 +125,7 @@ local lineFlags = { -- in poe2. this is currently only added as a hack for cane of kulemak and -- should be added based on mod tags after matching a mod in the future ["unveiled"] = true, + ["vestigial"] = true, } -- Special function to store unique instances of modifier on specific item slots @@ -734,6 +735,8 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) end elseif specName == "CatalystQuality" then self.catalystQuality = specToNumber(specVal) + elseif specName == "Intangibility" then + self.intangibility = specToNumber(specVal) elseif specName == "Note" then self.note = specVal elseif specName == "Str" or specName == "Strength" or specName == "Dex" or specName == "Dexterity" or @@ -835,7 +838,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.name = self.name:gsub(" %(.+%)","") end if not baseName then - baseName = line:gsub("^Superior ", ""):gsub("^Synthesised ","") + baseName = line:gsub("^Superior ", ""):gsub("^Synthesised ", ""):gsub("^Vestigial ", "") end if baseName == "Two-Toned Boots" then baseName = "Two-Toned Boots (Armour/Energy Shield)" @@ -1580,6 +1583,9 @@ function ItemClass:BuildRaw() end end end + if self.intangibility then + t_insert(rawLines, string.format("Intangibility: %d%%", self.intangibility)) + end if self.uniqueID then t_insert(rawLines, "Unique ID: " .. self.uniqueID) end @@ -1680,6 +1686,9 @@ function ItemClass:BuildRaw() if modLine.unscalable then line = "{unscalable}" .. line end + if modLine.vestigial then + line = "{vestigial}" .. line + end if modLine.variantList then local varSpec for varId in pairs(modLine.variantList) do diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index 69fb8ef80b..b92cec6abf 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -4322,6 +4322,11 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) tooltip:AddSeparator(10) end + if item.intangibility then + tooltip:AddLine(fontSizeBig, colorCodes.INTANGIBILITY .. s_format("Intangibility: ^7%d%%", item.intangibility), "FONTIN SC") + tooltip:AddSeparator(10) + end + -- Requirements self.build:AddRequirementsToTooltip(tooltip, item.requirements.level, item.requirements.strMod, item.requirements.dexMod, item.requirements.intMod, diff --git a/src/Data/Global.lua b/src/Data/Global.lua index 7a07f9a8e4..b33de85d79 100644 --- a/src/Data/Global.lua +++ b/src/Data/Global.lua @@ -57,7 +57,9 @@ colorCodes = { SAPBG = "^x261500", SCOURGE = "^xFF6E25", CRUCIBLE = "^xFFA500", - SPLITPERSONALITY = "^xFFD62A" + SPLITPERSONALITY = "^xFFD62A", + VESTIGIAL = "^xCBA5F1", + INTANGIBILITY = "^x9BF4BD", } colorCodes.STRENGTH = colorCodes.MARAUDER colorCodes.DEXTERITY = colorCodes.RANGER diff --git a/src/Modules/ItemTools.lua b/src/Modules/ItemTools.lua index cf8707c384..5a099ef9cc 100644 --- a/src/Modules/ItemTools.lua +++ b/src/Modules/ItemTools.lua @@ -366,7 +366,7 @@ function itemLib.formatModLine(modLine, dbMode) line = line .. " ^1'" .. modLine.extra .. "'" end else - colorCode = (modLine.fractured and colorCodes.FRACTURED) or (modLine.crafted and colorCodes.CRAFTED) or (modLine.mutated and colorCodes.MUTATED) or (modLine.scourge and colorCodes.SCOURGE) or (modLine.custom and colorCodes.CUSTOM) or (modLine.crucible and colorCodes.CRUCIBLE) or colorCodes.MAGIC + colorCode = (modLine.fractured and colorCodes.FRACTURED) or (modLine.crafted and colorCodes.CRAFTED) or (modLine.mutated and colorCodes.MUTATED) or (modLine.scourge and colorCodes.SCOURGE) or (modLine.custom and colorCodes.CUSTOM) or (modLine.crucible and colorCodes.CRUCIBLE) or (modLine.vestigial and colorCodes.VESTIGIAL) or colorCodes.MAGIC end return colorCode..line end From 19a101333038f9ca8faf5aa64a86530a785bbb70 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Wed, 29 Jul 2026 19:23:50 +0300 Subject: [PATCH 2/4] Also remove prefix from import typeline --- src/Classes/ImportTab.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Classes/ImportTab.lua b/src/Classes/ImportTab.lua index 39ffb7d081..03a2afadc0 100644 --- a/src/Classes/ImportTab.lua +++ b/src/Classes/ImportTab.lua @@ -1460,7 +1460,7 @@ function ImportTabClass:ImportItem(itemData, slotName, ignoreWeaponSwap) item.rarity = rarityMap[itemData.frameType] if #itemData.name > 0 then item.title = sanitiseText(itemData.name) - item.baseName = sanitiseText(itemData.typeLine):gsub("Synthesised ","") + item.baseName = sanitiseText(itemData.typeLine):gsub("Synthesised ", ""):gsub("^Vestigial ", "") item.name = item.title .. ", " .. item.baseName if item.baseName == "Two-Toned Boots" then -- Hack for Two-Toned Boots From f95ed12236e3febf51f9b5a35f45e24642a17224 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Thu, 30 Jul 2026 23:18:01 +0300 Subject: [PATCH 3/4] Fix trader parsing --- src/Classes/Item.lua | 2 + src/Classes/TradeQueryRequests.lua | 75 +++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index 0cfef8a6c6..ef2c2603b9 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -737,6 +737,8 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.catalystQuality = specToNumber(specVal) elseif specName == "Intangibility" then self.intangibility = specToNumber(specVal) + elseif specName == "Memory Strands" then + -- ignored elseif specName == "Note" then self.note = specVal elseif specName == "Str" or specName == "Strength" or specName == "Dex" or specName == "Dexterity" or diff --git a/src/Classes/TradeQueryRequests.lua b/src/Classes/TradeQueryRequests.lua index 4bdc5e3372..3bda7452a4 100644 --- a/src/Classes/TradeQueryRequests.lua +++ b/src/Classes/TradeQueryRequests.lua @@ -290,13 +290,86 @@ function TradeQueryRequestsClass:FetchResultBlock(url, callback) end local items = {} for _, trade_entry in pairs(response.result) do + local item = trade_entry.item + local t_insert = table.insert + + local rawLines = {} + t_insert(rawLines, "Rarity: " .. item.rarity) + -- item.name is empty when magic and full magic name is in typeLine but typeLine == baseType when rare. + if item.name ~= "" then + t_insert(rawLines, item.name) + end + t_insert(rawLines, item.typeLine) + -- note that PoB MUST parse these properties, or otherwise item + -- parsing will consider anything after a non-matching property + -- an explicit mod line + if item.properties then + for _, property in ipairs(item.properties) do + local name = escapeGGGString(property.name) + if property.values[1] then + t_insert(rawLines, string.format("%s: %s", name, property.values[1][1])) + else + t_insert(rawLines, name) + end + end + end + + if item.ilvl then + t_insert(rawLines, "Item Level: " .. item.ilvl) + end + if item.sockets then + local socketString = "" + local colours = {} + for _, socket in ipairs(item.sockets) do + table.insert(colours, socket.sColour) + end + socketString = table.concat(colours, "-") + t_insert(rawLines, "Sockets: " .. socketString) + end + + + -- TODO: crucible mods + for _, field in ipairs({ "enchantMods", "implicitMods", "scourgeMods", "explicitMods" }) do + if not item[field] then + item[field] = {} + end + end + + local function processLine(modLine) + local s = "" + for flagName, flag in pairs(modLine.flags or {}) do + if flag then + s = s .. string.format("{%s}", flagName) + end + end + return s .. escapeGGGString(modLine.description) + end + t_insert(rawLines, "Implicits: " .. (#item.enchantMods + #item.scourgeMods + #item.implicitMods)) + for _, modLine in ipairs(item.enchantMods) do + t_insert(rawLines, "{enchant}" .. processLine(modLine)) + end + for _, modLine in ipairs(item.scourgeMods) do + t_insert(rawLines, "{scourge}" .. processLine(modLine)) + end + for _, modLine in ipairs(item.implicitMods) do + t_insert(rawLines, processLine(modLine)) + end + for _, modLine in ipairs(item.explicitMods) do + t_insert(rawLines, processLine(modLine)) + end + if item.duplicated then + t_insert(rawLines, "Mirrored") + end + if item.corrupted then + t_insert(rawLines, "Corrupted") + end local pseudoMod = trade_entry.item.pseudoMods and trade_entry.item.pseudoMods[1] local pseudoModLine = pseudoMod and (pseudoMod.description or pseudoMod) table.insert(items, { amount = trade_entry.listing.price.amount, currency = trade_entry.listing.price.currency, priceType = trade_entry.listing.price.type, - item_string = escapeGGGString(common.base64.decode(trade_entry.item.extended.text)), + item_string = table.concat(rawLines, "\n"), whisper = trade_entry.listing.whisper, trader = trade_entry.listing.account.name, weight = pseudoModLine and pseudoModLine:match("Sum: (.+)") or "0", From fbc16b0cbeb0fde5d19c0ad7a5e4bfbb402bc8d8 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Fri, 31 Jul 2026 19:49:50 +0300 Subject: [PATCH 4/4] Fix test --- spec/System/TestTradeQueryRequests_spec.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/System/TestTradeQueryRequests_spec.lua b/spec/System/TestTradeQueryRequests_spec.lua index fb3ffd9a57..f8e53ea5e7 100644 --- a/spec/System/TestTradeQueryRequests_spec.lua +++ b/spec/System/TestTradeQueryRequests_spec.lua @@ -204,8 +204,10 @@ Strict-Transport-Security: max-age=63115200; includeSubDomains; preload]] account = { name = "seller" }, }, item = { - extended = { text = "VGVzdCBJdGVt" }, pseudoMods = pseudoMods, + rarity = "Rare", + name = "Test Subject", + typeLine = "Astral Plate", }, } end