You've already forked tf2wikipricing
feat: add support for festive weapon variants
on schema update, festive variants are linked. on content injection, if if finds a festive variant, it adds price rows for Festive and Strange Festive.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, test, mock } from "bun:test";
|
import { describe, expect, test, mock } from "bun:test";
|
||||||
import { ItemSchema, ItemSlot, getItemIndexByName, getTradableStatusByDefindex, getTradableStatusByName, prepareSchema } from '../src/content/schemaService'
|
import { ItemSchema, ItemSlot, getItemIndexByName, getTradableStatusByDefindex, getTradableStatusByName, linkFestiveVariants, prepareSchema } from '../src/content/schemaService'
|
||||||
|
|
||||||
// Mock the storage and log functions
|
// Mock the storage and log functions
|
||||||
mock.module('../src/content/storage', () => ({
|
mock.module('../src/content/storage', () => ({
|
||||||
@@ -19,35 +19,48 @@ const mockSchema: ItemSchema = {
|
|||||||
slot: ItemSlot.Primary,
|
slot: ItemSlot.Primary,
|
||||||
tradable: false,
|
tradable: false,
|
||||||
hasAustraliumVariant: false,
|
hasAustraliumVariant: false,
|
||||||
canKillstreakify: true
|
canKillstreakify: true,
|
||||||
|
festiveVariant: null
|
||||||
},
|
},
|
||||||
'208': {
|
'208': {
|
||||||
name: 'Flame Thrower',
|
name: 'Flame Thrower',
|
||||||
slot: ItemSlot.Primary,
|
slot: ItemSlot.Primary,
|
||||||
tradable: true,
|
tradable: true,
|
||||||
hasAustraliumVariant: true,
|
hasAustraliumVariant: true,
|
||||||
canKillstreakify: true
|
canKillstreakify: true,
|
||||||
|
festiveVariant: 659
|
||||||
|
},
|
||||||
|
'659': {
|
||||||
|
name: 'Festive Flame Thrower',
|
||||||
|
slot: ItemSlot.Primary,
|
||||||
|
tradable: true,
|
||||||
|
hasAustraliumVariant: false,
|
||||||
|
canKillstreakify: true,
|
||||||
|
festiveVariant: null
|
||||||
},
|
},
|
||||||
'5021': {
|
'5021': {
|
||||||
name: 'Mann Co. Supply Crate Key',
|
name: 'Mann Co. Supply Crate Key',
|
||||||
slot: ItemSlot.Tool,
|
slot: ItemSlot.Tool,
|
||||||
tradable: true,
|
tradable: true,
|
||||||
hasAustraliumVariant: false,
|
hasAustraliumVariant: false,
|
||||||
canKillstreakify: false
|
canKillstreakify: false,
|
||||||
|
festiveVariant: null
|
||||||
},
|
},
|
||||||
'15141': {
|
'15141': {
|
||||||
name: 'Flame Thrower',
|
name: 'Flame Thrower',
|
||||||
slot: ItemSlot.Primary,
|
slot: ItemSlot.Primary,
|
||||||
tradable: true,
|
tradable: true,
|
||||||
hasAustraliumVariant: false,
|
hasAustraliumVariant: false,
|
||||||
canKillstreakify: true
|
canKillstreakify: true,
|
||||||
|
festiveVariant: null
|
||||||
},
|
},
|
||||||
'69420': {
|
'69420': {
|
||||||
name: 'Non-Tradable Item',
|
name: 'Non-Tradable Item',
|
||||||
slot: ItemSlot.Misc,
|
slot: ItemSlot.Misc,
|
||||||
tradable: false,
|
tradable: false,
|
||||||
hasAustraliumVariant: false,
|
hasAustraliumVariant: false,
|
||||||
canKillstreakify: false
|
canKillstreakify: false,
|
||||||
|
festiveVariant: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,4 +130,75 @@ describe('Schema Service', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('linkFestiveVariants', () => {
|
||||||
|
test('should link festive variants to their original counterparts', () => {
|
||||||
|
const testSchema = {
|
||||||
|
'21': { // Stock (should be ignored)
|
||||||
|
name: 'Flame Thrower',
|
||||||
|
slot: ItemSlot.Primary,
|
||||||
|
tradable: false,
|
||||||
|
hasAustraliumVariant: false,
|
||||||
|
canKillstreakify: false,
|
||||||
|
festiveVariant: null
|
||||||
|
},
|
||||||
|
'208': { // Original Flame Thrower
|
||||||
|
name: 'Flame Thrower',
|
||||||
|
slot: ItemSlot.Primary,
|
||||||
|
tradable: true,
|
||||||
|
hasAustraliumVariant: true,
|
||||||
|
canKillstreakify: true,
|
||||||
|
festiveVariant: null
|
||||||
|
},
|
||||||
|
'659': { // Festive Flame Thrower (should be detected)
|
||||||
|
name: 'Festive Flame Thrower',
|
||||||
|
slot: ItemSlot.Primary,
|
||||||
|
tradable: true,
|
||||||
|
hasAustraliumVariant: false,
|
||||||
|
canKillstreakify: true,
|
||||||
|
festiveVariant: null
|
||||||
|
},
|
||||||
|
'15141': { // Decorated (should be ignored)
|
||||||
|
name: 'Flame Thrower',
|
||||||
|
slot: ItemSlot.Primary,
|
||||||
|
tradable: true,
|
||||||
|
hasAustraliumVariant: false,
|
||||||
|
canKillstreakify: true,
|
||||||
|
festiveVariant: null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const mockResponseItems = [
|
||||||
|
{ item_class: 'tf_weapon_flamethrower', defindex: 21, item_name: 'Flame Thrower' }, // Incorrect; stock
|
||||||
|
{ item_class: 'tf_weapon_flamethrower', defindex: 208, item_name: 'Flame Thrower' }, // Original
|
||||||
|
{ item_class: 'tf_weapon_flamethrower', defindex: 659, item_name: 'Festive Flame Thrower' }, // Festive
|
||||||
|
{ item_class: 'tf_weapon_flamethrower', defindex: 15141, item_name: 'Flame Thrower' }, // Incorrect; decorated
|
||||||
|
];
|
||||||
|
linkFestiveVariants(mockResponseItems, testSchema)
|
||||||
|
expect(testSchema['21'].festiveVariant).toBeNull()
|
||||||
|
expect(testSchema['208'].festiveVariant).toBe(659)
|
||||||
|
expect(testSchema['659'].festiveVariant).toBeNull();
|
||||||
|
expect(testSchema['15141'].festiveVariant).toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should not link if no festive variant exists', () => {
|
||||||
|
const testSchema = {
|
||||||
|
'163': {
|
||||||
|
name: 'Crit-a-Cola',
|
||||||
|
slot: ItemSlot.Secondary,
|
||||||
|
tradable: true,
|
||||||
|
hasAustraliumVariant: false,
|
||||||
|
canKillstreakify: false,
|
||||||
|
festiveVariant: null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockResponseItems = [
|
||||||
|
{ item_class: 'tf_weapon_lunchbox_drink', defindex: 163, item_name: 'Crit-a-Cola' }
|
||||||
|
];
|
||||||
|
|
||||||
|
linkFestiveVariants(mockResponseItems, testSchema);
|
||||||
|
|
||||||
|
expect(testSchema['163'].festiveVariant).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
})
|
})
|
||||||
@@ -237,6 +237,42 @@ async function inject() {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check item schema for Festive variant of current defindex
|
||||||
|
if(itemSchema[itemIndex].festiveVariant != null) {
|
||||||
|
promises.push(new Promise(async (resolve) => {
|
||||||
|
logDebug(`Fetching price for Festive ${itemName}`)
|
||||||
|
var data: ItemPriceData | null
|
||||||
|
try {
|
||||||
|
data = await fetchPrice(token, `${itemSchema[itemIndex].festiveVariant};6`, currentTime);
|
||||||
|
updateTime = new Date(data.update)
|
||||||
|
} catch {
|
||||||
|
log(`Festive ${itemName} is unpriced or unavailable, skipping...`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const priceRow = createPriceRow($T("Festive"), data, keyPrice, locale, "https://wiki.teamfortress.com/wiki/Festive_weapons")
|
||||||
|
|
||||||
|
priceRows.push({quality: 97, row: priceRow})
|
||||||
|
resolve()
|
||||||
|
return
|
||||||
|
}))
|
||||||
|
promises.push(new Promise(async (resolve) => {
|
||||||
|
logDebug(`Fetching price for Strange Festive ${itemName}`)
|
||||||
|
var data: ItemPriceData | null
|
||||||
|
try {
|
||||||
|
data = await fetchPrice(token, `${itemSchema[itemIndex].festiveVariant};11`, currentTime);
|
||||||
|
updateTime = new Date(data.update)
|
||||||
|
} catch {
|
||||||
|
log(`Strange Festive ${itemName} is unpriced or unavailable, skipping...`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const priceRow = createPriceRow($T("Strange Festive"), data, keyPrice, locale, "https://wiki.teamfortress.com/wiki/Festive_weapons")
|
||||||
|
|
||||||
|
priceRows.push({quality: 98, row: priceRow})
|
||||||
|
resolve()
|
||||||
|
return
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
Promise.all(promises).then(() => {
|
Promise.all(promises).then(() => {
|
||||||
priceRows.sort((a, b) => {
|
priceRows.sort((a, b) => {
|
||||||
// Sort 6 first always, then numerically
|
// Sort 6 first always, then numerically
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export class ItemSchema {
|
|||||||
slot: ItemSlot,
|
slot: ItemSlot,
|
||||||
tradable: Boolean,
|
tradable: Boolean,
|
||||||
hasAustraliumVariant: Boolean,
|
hasAustraliumVariant: Boolean,
|
||||||
|
festiveVariant: number | null
|
||||||
canKillstreakify: Boolean
|
canKillstreakify: Boolean
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -70,6 +71,25 @@ export function getTradableStatusByName(schema: ItemSchema, name: string, exclud
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function linkFestiveVariants(items: Array<{item_class: string, defindex: number, item_name: string}>, schema: ItemSchema): void {
|
||||||
|
if(!schema) return
|
||||||
|
items.filter(item =>
|
||||||
|
item.item_class != null &&
|
||||||
|
item.item_class.startsWith('tf_weapon') &&
|
||||||
|
item.item_name.startsWith('Festive ')
|
||||||
|
).forEach(festive => {
|
||||||
|
const originalName = festive.item_name.slice(8); // "Festive " is 8 chars
|
||||||
|
const original = items.find(item => item.item_name === originalName && item.defindex > 30 && (item.defindex < 15000 || item.defindex >= 16000));
|
||||||
|
|
||||||
|
if (original) {
|
||||||
|
if(schema[original.defindex]) {
|
||||||
|
schema[original.defindex].festiveVariant = festive.defindex;
|
||||||
|
console.log(`original:${original.defindex},festive:${festive.defindex}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function wipeSchema(): Promise<void> {
|
export async function wipeSchema(): Promise<void> {
|
||||||
await setStorageValue(storage_version, __VERSION__)
|
await setStorageValue(storage_version, __VERSION__)
|
||||||
await setStorageValue(storage_schema, null)
|
await setStorageValue(storage_schema, null)
|
||||||
@@ -149,6 +169,8 @@ export async function prepareSchema(): Promise<ItemSchema> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
linkFestiveVariants(responseItems, cacheItems)
|
||||||
|
|
||||||
await setStorageValue(storage_schema, (cacheItems));
|
await setStorageValue(storage_schema, (cacheItems));
|
||||||
itemSchema = cacheItems
|
itemSchema = cacheItems
|
||||||
await setStorageValue(storage_version, __VERSION__);
|
await setStorageValue(storage_version, __VERSION__);
|
||||||
|
|||||||
Reference in New Issue
Block a user