From 6f5342d71c92a326ae2ab58602d62fa7407a81c4 Mon Sep 17 00:00:00 2001 From: rxl211 Date: Mon, 29 Jun 2026 00:11:52 -0700 Subject: [PATCH 1/4] populating itemInfo.full_item_name to fix float rank hyperlinks for Souvenirs and StatTraks --- src/lib/components/inventory/selected_item_info.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/components/inventory/selected_item_info.ts b/src/lib/components/inventory/selected_item_info.ts index a76bf0c6..f146b89b 100644 --- a/src/lib/components/inventory/selected_item_info.ts +++ b/src/lib/components/inventory/selected_item_info.ts @@ -265,6 +265,7 @@ export class SelectedItemInfo extends FloatElement { asset_id: this.asset.assetid, link: this.inspectLink, }); + this.itemInfo.full_item_name = this.asset.description.market_hash_name; } catch (e: any) { console.error(`Failed to fetch float for ${this.asset.assetid}: ${e.toString()}`); } From 28c14a9edc61b97a0874835ee9dff95ec1e49fba Mon Sep 17 00:00:00 2001 From: rxl211 Date: Mon, 29 Jun 2026 00:39:20 -0700 Subject: [PATCH 2/4] Avoid stale full_item_name assignment across selected item changes --- .../inventory/selected_item_info.ts | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/lib/components/inventory/selected_item_info.ts b/src/lib/components/inventory/selected_item_info.ts index f146b89b..cafd7049 100644 --- a/src/lib/components/inventory/selected_item_info.ts +++ b/src/lib/components/inventory/selected_item_info.ts @@ -261,13 +261,27 @@ export class SelectedItemInfo extends FloatElement { (isCharm(this.asset.description) && !isHighlightCharm(this.asset.description))) ) { try { - this.itemInfo = await gFloatFetcher.fetch({ - asset_id: this.asset.assetid, - link: this.inspectLink, + const asset = this.asset; + if (!asset) return; + + const inspectLink = this.inspectLink; + if (!inspectLink) return; + + const fetched = await gFloatFetcher.fetch({ + asset_id: asset.assetid, + link: inspectLink, }); - this.itemInfo.full_item_name = this.asset.description.market_hash_name; + + if (this.asset?.assetid !== asset.assetid) { + return; + } + + this.itemInfo = { + ...fetched, + full_item_name: asset.description.market_hash_name, + }; } catch (e: any) { - console.error(`Failed to fetch float for ${this.asset.assetid}: ${e.toString()}`); + console.error(`Failed to fetch float for ${this.asset?.assetid}: ${e.toString()}`); } // Fetch bluegem data if needed From 86d248f4ebceac12e0466069fb094c9a1e6a140e Mon Sep 17 00:00:00 2001 From: rxl211 Date: Tue, 30 Jun 2026 09:35:02 -0700 Subject: [PATCH 3/4] Use decoded inspect links in getFloatDbCategory --- .../inventory/selected_item_info.ts | 25 +++----------- src/lib/components/market/item_row_wrapper.ts | 2 +- src/lib/utils/skin.ts | 34 +++++++++++++------ 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/lib/components/inventory/selected_item_info.ts b/src/lib/components/inventory/selected_item_info.ts index cafd7049..9eeef40d 100644 --- a/src/lib/components/inventory/selected_item_info.ts +++ b/src/lib/components/inventory/selected_item_info.ts @@ -125,7 +125,7 @@ export class SelectedItemInfo extends FloatElement { if (isSkin(this.asset.description) && this.itemInfo) { containerChildren.push(this.renderFloatBar()); containerChildren.push( - html`
Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo)}
` + html`
Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo, this.inspectLink)}
` ); containerChildren.push(html`
Paint Seed: ${formatSeed(this.itemInfo)}
`); @@ -261,27 +261,12 @@ export class SelectedItemInfo extends FloatElement { (isCharm(this.asset.description) && !isHighlightCharm(this.asset.description))) ) { try { - const asset = this.asset; - if (!asset) return; - - const inspectLink = this.inspectLink; - if (!inspectLink) return; - - const fetched = await gFloatFetcher.fetch({ - asset_id: asset.assetid, - link: inspectLink, + this.itemInfo = await gFloatFetcher.fetch({ + asset_id: this.asset.assetid, + link: this.inspectLink, }); - - if (this.asset?.assetid !== asset.assetid) { - return; - } - - this.itemInfo = { - ...fetched, - full_item_name: asset.description.market_hash_name, - }; } catch (e: any) { - console.error(`Failed to fetch float for ${this.asset?.assetid}: ${e.toString()}`); + console.error(`Failed to fetch float for ${this.asset.assetid}: ${e.toString()}`); } // Fetch bluegem data if needed diff --git a/src/lib/components/market/item_row_wrapper.ts b/src/lib/components/market/item_row_wrapper.ts index c78a87aa..f144122a 100644 --- a/src/lib/components/market/item_row_wrapper.ts +++ b/src/lib/components/market/item_row_wrapper.ts @@ -253,7 +253,7 @@ export class ItemRowWrapper extends FloatElement {
${this.renderFloatBar()} - Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo)} + Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo, this.inspectLink)} Paint Seed: ${formatSeed(this.itemInfo)}${fadePercentage !== undefined diff --git a/src/lib/utils/skin.ts b/src/lib/utils/skin.ts index c6408969..4c5f03b3 100644 --- a/src/lib/utils/skin.ts +++ b/src/lib/utils/skin.ts @@ -3,6 +3,7 @@ import {ItemInfo} from '../bridge/handlers/fetch_inspect_info'; import {getDopplerPhase, hasDopplerPhase} from './dopplers'; import {html, TemplateResult} from 'lit'; import {AcidFadeCalculator, AmberFadeCalculator, FadeCalculator} from 'csgo-fade-percentage-calculator'; +import {decodeLink, CEconItemPreviewDataBlock} from '@csfloat/cs2-inspect-serializer'; export function rangeFromWear(wear: number): [number, number] | null { const wearRanges: [number, number][] = [ @@ -72,32 +73,45 @@ enum OrderType { * @param info item properties dict * @param order 1 for low float, -1 for high float ordering */ -function getFloatDbLink(info: ItemInfo, order: OrderType): string { - function getFloatDbCategory(item: ItemInfo): number { - if (item.full_item_name?.includes('StatTrak')) { +function getFloatDbLink(info: ItemInfo, order: OrderType, inspectLink: string | undefined): string { + function getFloatDbCategory(item: ItemInfo, inspectLink: string | undefined): number { + if (!inspectLink) { + return 0; //unfiltered + } + + let decoded: CEconItemPreviewDataBlock; + try { + decoded = decodeLink(inspectLink); + } catch (error) { + return 0; //unfiltered + } + + const stattrak = decoded.killeaterscoretype !== undefined; + const souvenir = decoded.quality === 12; + + if (stattrak) { return 2; - } else if (item.full_item_name?.includes('Souvenir')) { + } else if (souvenir) { return 3; } else { - // "Normal" - return 1; + return 1; // "Normal"" } } return `https://csfloat.com/db?defIndex=${info.defindex}&paintIndex=${ info.paintindex - }&order=${order}&category=${getFloatDbCategory(info)}`; + }&order=${order}&category=${getFloatDbCategory(info, inspectLink)}`; } -export function renderClickableRank(info: ItemInfo): TemplateResult<1> { +export function renderClickableRank(info: ItemInfo, inspectLink: string | undefined): TemplateResult<1> { const parsedRank = parseRank(info); if (!parsedRank) { return html``; } - + return html` (Rank #${parsedRank.rank}) From 86d9c5c13f61df3cad646e7a4215db3d0d372a95 Mon Sep 17 00:00:00 2001 From: rxl211 Date: Tue, 30 Jun 2026 17:01:05 -0700 Subject: [PATCH 4/4] Add is_souvenir and is_stattrak to ItemInfo --- src/lib/bridge/handlers/fetch_inspect_info.ts | 4 +++ .../inventory/selected_item_info.ts | 2 +- src/lib/components/market/item_row_wrapper.ts | 2 +- src/lib/utils/skin.ts | 29 +++++-------------- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/lib/bridge/handlers/fetch_inspect_info.ts b/src/lib/bridge/handlers/fetch_inspect_info.ts index 748298a8..3c5c3a44 100644 --- a/src/lib/bridge/handlers/fetch_inspect_info.ts +++ b/src/lib/bridge/handlers/fetch_inspect_info.ts @@ -40,6 +40,8 @@ export interface ItemInfo { full_item_name?: string; low_rank?: number; high_rank?: number; + is_souvenir?: boolean; + is_stattrak?: boolean; } export interface FetchInspectInfoRequest { @@ -127,6 +129,8 @@ async function processInspectItem(req: FetchInspectInfoRequest, schema: ItemSche item_name: itemName, rarity_name: rarityName, wear_name: getWearName(floatvalue), + is_souvenir: decoded.quality === 12, + is_stattrak: decoded.killeaterscoretype !== undefined, }; try { diff --git a/src/lib/components/inventory/selected_item_info.ts b/src/lib/components/inventory/selected_item_info.ts index 9eeef40d..a76bf0c6 100644 --- a/src/lib/components/inventory/selected_item_info.ts +++ b/src/lib/components/inventory/selected_item_info.ts @@ -125,7 +125,7 @@ export class SelectedItemInfo extends FloatElement { if (isSkin(this.asset.description) && this.itemInfo) { containerChildren.push(this.renderFloatBar()); containerChildren.push( - html`
Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo, this.inspectLink)}
` + html`
Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo)}
` ); containerChildren.push(html`
Paint Seed: ${formatSeed(this.itemInfo)}
`); diff --git a/src/lib/components/market/item_row_wrapper.ts b/src/lib/components/market/item_row_wrapper.ts index f144122a..c78a87aa 100644 --- a/src/lib/components/market/item_row_wrapper.ts +++ b/src/lib/components/market/item_row_wrapper.ts @@ -253,7 +253,7 @@ export class ItemRowWrapper extends FloatElement {
${this.renderFloatBar()} - Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo, this.inspectLink)} + Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo)} Paint Seed: ${formatSeed(this.itemInfo)}${fadePercentage !== undefined diff --git a/src/lib/utils/skin.ts b/src/lib/utils/skin.ts index 4c5f03b3..139213f4 100644 --- a/src/lib/utils/skin.ts +++ b/src/lib/utils/skin.ts @@ -3,7 +3,6 @@ import {ItemInfo} from '../bridge/handlers/fetch_inspect_info'; import {getDopplerPhase, hasDopplerPhase} from './dopplers'; import {html, TemplateResult} from 'lit'; import {AcidFadeCalculator, AmberFadeCalculator, FadeCalculator} from 'csgo-fade-percentage-calculator'; -import {decodeLink, CEconItemPreviewDataBlock} from '@csfloat/cs2-inspect-serializer'; export function rangeFromWear(wear: number): [number, number] | null { const wearRanges: [number, number][] = [ @@ -73,25 +72,13 @@ enum OrderType { * @param info item properties dict * @param order 1 for low float, -1 for high float ordering */ -function getFloatDbLink(info: ItemInfo, order: OrderType, inspectLink: string | undefined): string { - function getFloatDbCategory(item: ItemInfo, inspectLink: string | undefined): number { - if (!inspectLink) { +function getFloatDbLink(info: ItemInfo, order: OrderType): string { + function getFloatDbCategory(item: ItemInfo): number { + if (item.is_souvenir == null || item.is_stattrak == null) { return 0; //unfiltered - } - - let decoded: CEconItemPreviewDataBlock; - try { - decoded = decodeLink(inspectLink); - } catch (error) { - return 0; //unfiltered - } - - const stattrak = decoded.killeaterscoretype !== undefined; - const souvenir = decoded.quality === 12; - - if (stattrak) { + } else if (item.is_stattrak) { return 2; - } else if (souvenir) { + } else if (item.is_souvenir) { return 3; } else { return 1; // "Normal"" @@ -100,10 +87,10 @@ function getFloatDbLink(info: ItemInfo, order: OrderType, inspectLink: string | return `https://csfloat.com/db?defIndex=${info.defindex}&paintIndex=${ info.paintindex - }&order=${order}&category=${getFloatDbCategory(info, inspectLink)}`; + }&order=${order}&category=${getFloatDbCategory(info)}`; } -export function renderClickableRank(info: ItemInfo, inspectLink: string | undefined): TemplateResult<1> { +export function renderClickableRank(info: ItemInfo): TemplateResult<1> { const parsedRank = parseRank(info); if (!parsedRank) { return html``; @@ -111,7 +98,7 @@ export function renderClickableRank(info: ItemInfo, inspectLink: string | undefi return html` (Rank #${parsedRank.rank})