A userscript
当前为
// ==UserScript==
// @name Inventory Market Value
// @license MIT
// @namespace Violentmonkey Scripts
// @match https://www.torn.com/item*
// @grant none
// @version 1.00
// @author BillyBourbon/Bilbosaggings[2323763]
// @description A userscript
// ==/UserScript==
// ================================
// Input your apikey inbetween the quote marks ''
const apikey = ''
// ================================
function formatToCurrency(n){
n = Number(n)
return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0 }).format(n)
}
async function loadTornItems() {
const cacheKey = 'tornItemsCache';
const cacheExpiryKey = 'tornItemsCacheExpiry';
const cacheDuration = 60 * 60 * 1000; // 1 hour in milliseconds
const cachedData = localStorage.getItem(cacheKey);
const cachedExpiry = localStorage.getItem(cacheExpiryKey);
if (cachedData && cachedExpiry && Date.now() < cachedExpiry) {
console.log('Using cached data');
return JSON.parse(cachedData);
}
let attempt = 0;
let jsonResponse = null;
while (attempt < 3) {
try {
const call = await fetch(`https://api.torn.com/v2/torn/items`, {
method: 'GET',
contentType: 'application/json',
muteHttpExceptions: true,
headers: {
Authorization: `ApiKey ${apikey}`,
},
});
if (!call.ok) {
throw new Error(`API request failed with status: ${call.status}`);
}
jsonResponse = await call.json();
console.log(jsonResponse);
localStorage.setItem(cacheKey, JSON.stringify(jsonResponse));
localStorage.setItem(cacheExpiryKey, Date.now() + cacheDuration);
return jsonResponse;
} catch (error) {
attempt++;
console.error(`Attempt ${attempt} failed: ${error.message}`);
if (attempt < 3) {
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
}
console.error('Failed to fetch data after 3 attempts.');
return null;
}
function findTornItem(itemId, tornItems){
const item = tornItems.find(o=> o.id.toString() === itemId.toString())
return item
}
async function insertMarketValues(itemList){
let counter = 0
const { items:tornItems } = await loadTornItems()
for(let child of itemList.querySelectorAll('li')){
const itemId = child.getAttribute('data-item')
if(itemId !== null && itemId > 0 && child.querySelector('.name-wrap .name') !== null) {
const itemNameSpan = child.querySelector('.name-wrap .name')
const itemQuantitySpan = child.querySelector('.name-wrap .qty')
const itemQuantity = itemQuantitySpan.innerHTML.length ===0?1:Number(itemQuantitySpan.innerHTML.substring(1))
const { value: { market_price } } = findTornItem(itemId, tornItems)
itemNameSpan.innerHTML += ` (${formatToCurrency(market_price)} | ${formatToCurrency(market_price * itemQuantity)})`
counter++
}
}
return counter
}
const callback = async (mutationList, observer) => {
for (const mutation of mutationList) {
if (mutation.type === 'childList') {
if(mutation.addedNodes.length === 0) return
const editedElementCount = await insertMarketValues(mutation.target)
if(editedElementCount > 0) observer.disconnect()
}
}
}
window.addEventListener('load', async ()=>{
document.querySelectorAll('.items-cont').forEach(container=>{
const observer = new MutationObserver(callback)
observer.observe(container, { attributes: true, childList: true, subtree: true })
})
})