fix: prioritize non-stock/non-decorated items

Changed schema lookups to prioritize non-stock/non-decorated item defindexes when names collide
Modified unit tests to include example (stock Flame Thrower)
This commit is contained in:
xenticore
2025-03-27 15:32:45 -04:00
parent b24cda98ad
commit 967a32fc83
3 changed files with 35 additions and 20 deletions

View File

@@ -2,24 +2,30 @@ import { describe, expect, test } from "bun:test";
import { ItemSchema, getItemIndexByName, getTradableStatusByDefindex, getTradableStatusByName} from '../src/content/schemaService' import { ItemSchema, getItemIndexByName, getTradableStatusByDefindex, getTradableStatusByName} from '../src/content/schemaService'
const mockSchema: ItemSchema = { const mockSchema: ItemSchema = {
'21': { name: 'Flame Thrower', tradable: false },
'208': { name: 'Flame Thrower', tradable: true },
'5021': { name: 'Mann Co. Supply Crate Key', tradable: true }, '5021': { name: 'Mann Co. Supply Crate Key', tradable: true },
'15013': { name: 'Non-Tradable Item', tradable: false } '15141': { name: 'Flame Thrower', tradable: true },
'69420': { name: 'Non-Tradable Item', tradable: false }
} }
describe('Schema Service', () => { describe('Schema Service', () => {
test('getItemIndexByName returns correct defindex', () => { test('getItemIndexByName returns correct defindex', () => {
expect(getItemIndexByName(mockSchema, 'Flame Thrower')).toBe(208)
expect(getItemIndexByName(mockSchema, 'Mann Co. Supply Crate Key')).toBe(5021) expect(getItemIndexByName(mockSchema, 'Mann Co. Supply Crate Key')).toBe(5021)
expect(getItemIndexByName(mockSchema, 'Non-Existent Item')).toBeNull() expect(getItemIndexByName(mockSchema, 'Non-Existent Item')).toBeNull()
}) })
test('getTradableStatusByDefindex returns correct status', () => { test('getTradableStatusByDefindex returns correct status', () => {
expect(getTradableStatusByDefindex(mockSchema, 208)).toBe(true)
expect(getTradableStatusByDefindex(mockSchema, 5021)).toBe(true) expect(getTradableStatusByDefindex(mockSchema, 5021)).toBe(true)
expect(getTradableStatusByDefindex(mockSchema, 15013)).toBe(false) expect(getTradableStatusByDefindex(mockSchema, 69420)).toBe(false)
expect(() => getTradableStatusByDefindex(mockSchema, 999)).toThrow() expect(() => getTradableStatusByDefindex(mockSchema, 999)).toThrow()
}) })
test('getTradableStatusByName returns correct status', () => { test('getTradableStatusByName returns correct status', () => {
expect(getTradableStatusByName(mockSchema, 'Flame Thrower')).toBe(true)
expect(getTradableStatusByName(mockSchema, 'Mann Co. Supply Crate Key')).toBe(true) expect(getTradableStatusByName(mockSchema, 'Mann Co. Supply Crate Key')).toBe(true)
expect(getTradableStatusByName(mockSchema, 'Non-Tradable Item')).toBe(false) expect(getTradableStatusByName(mockSchema, 'Non-Tradable Item')).toBe(false)
expect(getTradableStatusByName(mockSchema, 'Non-Existent Item')).toBe(true) expect(getTradableStatusByName(mockSchema, 'Non-Existent Item')).toBe(true)

View File

@@ -35,24 +35,10 @@ async function inject() {
var itemIndex: number | null = null; var itemIndex: number | null = null;
var itemName: string | null = null; var itemName: string | null = null;
// Try using buy buttons, if they exist // Find buy buttons
const buyButton = findFirstChildElement('.btn_buynow', itemInfobox); const buyButton = findFirstChildElement('.btn_buynow', itemInfobox);
const marketButton = findFirstChildElement('.btn_buynow_market', itemInfobox); const marketButton = findFirstChildElement('.btn_buynow_market', itemInfobox);
if(buyButton) {
const link = (buyButton.parentElement as HTMLLinkElement);
if(link && link.href) {
itemIndex = parseInt(link.href.replace('https://store.steampowered.com/buyitem/440/', ''));
}
}
if(!itemIndex && marketButton) {
const link = (marketButton.parentElement as HTMLLinkElement);
if(link && link.href) {
itemIndex = parseInt(link.href.replace('https://steamcommunity.com/market/search/?q=appid:440+prop_def_index:', ''));
}
}
// Try using item name // Try using item name
const header = findFirstChildElement('.infobox-header', itemInfobox); const header = findFirstChildElement('.infobox-header', itemInfobox);
if (!itemIndex && header) { if (!itemIndex && header) {
@@ -72,6 +58,23 @@ async function inject() {
} }
} }
// Try using buy buttons, if they exist
if(!itemIndex) {
if(buyButton) {
const link = (buyButton.parentElement as HTMLLinkElement);
if(link && link.href) {
itemIndex = parseInt(link.href.replace('https://store.steampowered.com/buyitem/440/', ''));
}
}
if(!itemIndex && marketButton) {
const link = (marketButton.parentElement as HTMLLinkElement);
if(link && link.href) {
itemIndex = parseInt(link.href.replace('https://steamcommunity.com/market/search/?q=appid:440+prop_def_index:', ''));
}
}
}
if (!itemIndex) { if (!itemIndex) {
// Cannot continue without index // Cannot continue without index
logError(itemName ? `Could not find defindex for ${itemName}` : `Could not determine item defindex or name`); logError(itemName ? `Could not find defindex for ${itemName}` : `Could not determine item defindex or name`);

View File

@@ -16,10 +16,13 @@ function isDateAfterOneDay(date1: Date, date2: Date): boolean {
export class ItemSchema { [key: string]: {name: string, tradable: Boolean}; } export class ItemSchema { [key: string]: {name: string, tradable: Boolean}; }
export function getItemIndexByName(schema: ItemSchema, name: string) { export function getItemIndexByName(schema: ItemSchema, name: string, excludeStock: Boolean = true, excludeDecorated: Boolean = true) {
for (const [defindex, value] of Object.entries(schema)) { for (const [defindex, value] of Object.entries(schema)) {
if (value['name'] == name) { if (value['name'] == name) {
return parseInt(defindex) const index = parseInt(defindex)
if(excludeStock && index <= 30) continue
if(excludeDecorated && (index >= 15000 && index < 16000)) continue
return index
} }
} }
return null return null
@@ -29,9 +32,12 @@ export function getTradableStatusByDefindex(schema: ItemSchema, defindex: number
return schema[defindex.toString()].tradable return schema[defindex.toString()].tradable
} }
export function getTradableStatusByName(schema: ItemSchema, name: string) { export function getTradableStatusByName(schema: ItemSchema, name: string, excludeStock: Boolean = true, excludeDecorated = true,) {
for (const [defindex, value] of Object.entries(schema)) { for (const [defindex, value] of Object.entries(schema)) {
if (value['name'] == name) { if (value['name'] == name) {
const index = parseInt(defindex)
if(excludeStock && index <= 30) continue
if(excludeDecorated && (index >= 15000 && index < 16000)) continue
return value.tradable return value.tradable
} }
} }