您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
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 }) }) })