Skip to content

Commit 7e8ab46

Browse files
committed
Adds Bugged Skin Count to Utility Belt
1 parent 1b61cdb commit 7e8ab46

3 files changed

Lines changed: 82 additions & 25 deletions

File tree

src/lib/components/market/item_row_wrapper.ts

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
isCharm,
1818
isBlueSkin,
1919
isHighlightCharm,
20+
isBuggedSkin,
2021
} from '../../utils/skin';
2122
import {gFilterService} from '../../services/filter';
2223
import {AppId, ContextId, Currency} from '../../types/steam_constants';
@@ -118,28 +119,6 @@ export class ItemRowWrapper extends FloatElement {
118119
}
119120
}
120121

121-
/**
122-
* As part of the March 2/2026 update, skins listed on SCM get moved into the trade protected inventory context
123-
* so the user can still use them in-game while listed. However, Valve introduced a bug where these skins
124-
* can't be inspected in game.
125-
*
126-
* Detect and skip these skins to prevent overloaded errors to the user and browser request throttling.
127-
*/
128-
get isBuggedSkin(): boolean {
129-
if (!this.asset || !isSkin(this.asset)) {
130-
return false;
131-
}
132-
133-
if (this.asset.unowned_contextid !== "16") {
134-
// Only applies for trade protected inventory context
135-
return false;
136-
}
137-
138-
const fv = (this.asset.asset_properties || []).find((prop) => prop.propertyid === 2);
139-
// Has no FV
140-
return !fv;
141-
}
142-
143122
@state()
144123
private itemInfo: ItemInfo | undefined;
145124
@state()
@@ -165,7 +144,7 @@ export class ItemRowWrapper extends FloatElement {
165144
return;
166145
}
167146

168-
if (this.isBuggedSkin) {
147+
if (isBuggedSkin(this.asset)) {
169148
return;
170149
}
171150

@@ -262,7 +241,7 @@ export class ItemRowWrapper extends FloatElement {
262241
return nothing;
263242
}
264243

265-
if (this.isBuggedSkin) {
244+
if (isBuggedSkin(this.asset)) {
266245
return nothing;
267246
}
268247

src/lib/components/market/utility_belt.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
import {FloatElement} from '../custom';
22
import {CustomElement, InjectBefore, InjectionMode} from '../injectors';
3-
import {css, html, HTMLTemplateResult} from 'lit';
3+
import {css, html, HTMLTemplateResult, nothing} from 'lit';
4+
import {state} from 'lit/decorators.js';
45
import '../common/ui/steam-button';
56
import './page_size';
67
import './sort_listings';
78
import '../filter/filter_container';
9+
import {Observe} from '../../utils/observers';
10+
import {isBuggedSkin} from '../../utils/skin';
11+
import {AppId, ContextId} from '../../types/steam_constants';
812

913
@CustomElement()
1014
@InjectBefore('#searchResultsRows', InjectionMode.ONCE)
1115
export class UtilityBelt extends FloatElement {
16+
@state()
17+
private buggedSkinCount = 0;
18+
1219
get marketHashName(): string {
1320
return (document.querySelector('.market_listing_nav a:nth-child(2)') as HTMLElement).innerText;
1421
}
@@ -31,6 +38,16 @@ export class UtilityBelt extends FloatElement {
3138
text-decoration: underline;
3239
font-family: 'Motiva Sans', sans-serif;
3340
}
41+
42+
.bugged-skin-warning {
43+
padding: 8px 12px;
44+
margin-top: 10px;
45+
background-color: rgba(255, 152, 0, 0.15);
46+
border: 1px solid rgba(255, 152, 0, 0.4);
47+
border-radius: 4px;
48+
color: #ffb74d;
49+
font-size: 13px;
50+
}
3451
`,
3552
];
3653

@@ -45,12 +62,53 @@ export class UtilityBelt extends FloatElement {
4562
?hidden="${!this.marketHashName}"
4663
.key="${this.marketHashName}"
4764
></csfloat-filter-container>
65+
${this.renderBuggedSkinWarning()}
4866
</div>
4967
<csfloat-ad-banner></csfloat-ad-banner>
5068
`;
5169
}
5270

71+
private countBuggedSkins(): number {
72+
try {
73+
const assets = g_rgAssets?.[AppId.CSGO]?.[ContextId.PRIMARY];
74+
if (!assets) return 0;
75+
76+
return Object.values(assets).filter((asset) => isBuggedSkin(asset)).length;
77+
} catch {
78+
return 0;
79+
}
80+
}
81+
82+
private renderBuggedSkinWarning(): HTMLTemplateResult | typeof nothing {
83+
if (this.buggedSkinCount === 0) {
84+
return nothing;
85+
}
86+
87+
return html`
88+
<div class="bugged-skin-warning">
89+
<b>${this.buggedSkinCount} skin${this.buggedSkinCount > 1 ? 's' : ''}</b> on this page
90+
cannot display float data since they're not inspectable in-game (March 4, 2026 update). Valve pls fix.
91+
</div>
92+
`;
93+
}
94+
5395
async connectedCallback() {
5496
super.connectedCallback();
97+
98+
this.buggedSkinCount = this.countBuggedSkins();
99+
100+
Observe(
101+
() => {
102+
try {
103+
return Object.keys(g_rgAssets?.[AppId.CSGO]?.[ContextId.PRIMARY] || {}).join(',');
104+
} catch {
105+
return '';
106+
}
107+
},
108+
() => {
109+
this.buggedSkinCount = this.countBuggedSkins();
110+
},
111+
100
112+
);
55113
}
56114
}

src/lib/utils/skin.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,23 @@ export function floor(n: number, precision?: number) {
230230

231231
return Math.floor(n * p) / p;
232232
}
233+
234+
/**
235+
* As part of the March 4/2026 update, skins listed on SCM get moved into the trade protected inventory context
236+
* so the user can still use them in-game while listed. However, Valve introduced a bug where these skins
237+
* can't be inspected in game.
238+
*
239+
* Detect and skip these skins to prevent overloaded errors to the user and browser request throttling.
240+
*/
241+
export function isBuggedSkin(asset: rgAsset | undefined): boolean {
242+
if (!asset || !isSkin(asset)) {
243+
return false;
244+
}
245+
246+
if (asset.unowned_contextid !== '16') {
247+
return false;
248+
}
249+
250+
const fv = (asset.asset_properties || []).find((prop) => prop.propertyid === 2);
251+
return !fv;
252+
}

0 commit comments

Comments
 (0)