Files
tf2wikipricing/src/content/schemaService.ts

161 lines
5.1 KiB
TypeScript

import { getStorageValue, setStorageValue } from './storage'
import { logDebug, log, logError } from './utils/log'
import './config'
declare function GM_fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>
import './GM_fetch'
import { storage_version, storage_schema, storage_lastUpdateTime } from './config'
import Australiums from '../resources/australiums.json'
const semver = require('semver')
export function checkAustraliumVariant(defindex: number): boolean {
return Object.prototype.hasOwnProperty.call(Australiums, defindex.toString());
}
export declare const __VERSION__: string;
function isDateAfterOneDay(date1: Date, date2: Date): boolean {
var diff = date2.getTime() - date1.getTime();
var diffDays = Math.round(diff / (1000 * 3600 * 24));
return diffDays > 1;
}
export enum ItemSlot {
Primary = "primary",
Secondary = "secondary",
Melee = "melee",
PDA = "pda",
PDA2 = "pda2",
Building = "building",
Misc = "misc",
Special = "special",
Taunt = "taunt",
Tool = "tool",
}
export class ItemSchema {
[key: string]: {
name: string,
slot: ItemSlot,
tradable: Boolean,
hasAustraliumVariant: Boolean,
canKillstreakify: Boolean
};
}
export function getItemIndexByName(schema: ItemSchema, name: string, excludeStock: Boolean = true, excludeDecorated: Boolean = true) {
for (const [defindex, value] of Object.entries(schema)) {
if (value['name'] == name) {
const index = parseInt(defindex)
if(excludeStock && index <= 30) continue
if(excludeDecorated && (index >= 15000 && index < 16000)) continue
return index
}
}
return null
}
export function getTradableStatusByDefindex(schema: ItemSchema, defindex: number) {
return schema[defindex.toString()].tradable
}
export function getTradableStatusByName(schema: ItemSchema, name: string, excludeStock: Boolean = true, excludeDecorated = true,) {
for (const [defindex, value] of Object.entries(schema)) {
if (value['name'] == name) {
const index = parseInt(defindex)
if(excludeStock && index <= 30) continue
if(excludeDecorated && (index >= 15000 && index < 16000)) continue
return value.tradable
}
}
return true
}
export async function wipeSchema(): Promise<void> {
await setStorageValue(storage_version, __VERSION__)
await setStorageValue(storage_schema, null)
await setStorageValue(storage_lastUpdateTime, new Date().toISOString())
logDebug(`Schema wiped`)
}
export async function prepareSchema(): Promise<ItemSchema> {
var needsUpdate: Boolean = false
var itemSchema: ItemSchema | null = null
const storedVersion: string | null = await getStorageValue(storage_version, null)
if(!storedVersion || !semver.valid(storedVersion)) {
log(`Cache is from an unknown version of the extension. Updating for version ${__VERSION__}`);
needsUpdate = true
} else if(semver.valid(storedVersion) && semver.lt(storedVersion, __VERSION__)) {
log(`Cache is from a previous version (${storedVersion}) of the extension. Updating for version ${__VERSION__}`);
needsUpdate = true
} else {
log(`Cache is from current version (${storedVersion}) of the extension.`);
itemSchema = await getStorageValue(storage_schema, null);
}
const update = await getStorageValue(storage_lastUpdateTime, null)
if (update) {
const lastUpdateTime = new Date(update);
log(`Item schema updated at ${lastUpdateTime}`);
if (itemSchema == null || Object.keys(itemSchema).length === 0 || isDateAfterOneDay(lastUpdateTime, new Date())) {
needsUpdate = true
}
}
if(needsUpdate) {
log("Item Schema out of Date. Rebuilding...");
const url = "https://raw.githubusercontent.com/danocmx/node-tf2-static-schema/master/static/items.json"
const response = await GM_fetch(url);
if (response.ok) {
await setStorageValue(storage_lastUpdateTime, new Date().getTime());
var cacheItems = {}
var responseItems: any[] = await response.json()
// We want to keep the keys `defindex`, `item_name`, and `attributes`
responseItems.forEach((item: any) => {
const defindex: number = item['defindex']
var tradable: Boolean = true
try {
if(item['attributes'] != null) {
if(item['attributes'].find((attribute: {}) => (attribute as any)['class'] == "cannot_trade")) {
tradable = false
}
}
} catch(error) {
logError(error)
log(item)
}
var canKillstreakify: Boolean = false
try {
if(item['capabilities'] != null) {
if(item['capabilities']['can_killstreakify'] != null && item['capabilities']['can_killstreakify'] == true) {
canKillstreakify = true
}
}
} catch(error) {
logError(error)
log(item)
}
(cacheItems as any)[defindex.toString()] = {
"name": item['item_name'],
"slot": item['item_slot'],
"tradable": tradable,
"canKillstreakify": canKillstreakify,
"hasAustraliumVariant": checkAustraliumVariant(defindex)
}
});
await setStorageValue(storage_schema, (cacheItems));
itemSchema = cacheItems
await setStorageValue(storage_version, __VERSION__);
logDebug(`Item schema updated at ${new Date()}`)
} else {
logError("Could not fetch item schema.");
}
}
return itemSchema
}