您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show hired/capacity for each company in Torn job list using user-provided API key
// ==UserScript== // @name Torn Job Capacity Viewer – ShAdOwCrEsT Edition // @namespace http://tampermonkey.net/ // @version 1.10 // @description Show hired/capacity for each company in Torn job list using user-provided API key // @match https://www.torn.com/joblist.php* // @connect api.torn.com // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @author ShAdOwCrEsT [3929345] – for feedback or issues feel free to reach out. Always accepting xanax donations haha 😎 // ==/UserScript== (function() { 'use strict'; function getKey() { return localStorage.getItem('torn_api_key'); } function setKey(newKey) { if (newKey) { localStorage.setItem('torn_api_key', newKey); alert("API key saved!"); } else { localStorage.removeItem('torn_api_key'); alert("API key cleared!"); } } function askKey() { const currentKey = getKey() || ""; const key = prompt("Enter your Torn Public API Key:", currentKey); if (key !== null) setKey(key.trim()); return getKey(); } // Initialize key let API_KEY = getKey(); if (!API_KEY) API_KEY = askKey(); if (!API_KEY) { alert("No API key provided. Script cannot run."); return; } // ========== Browser (GM menu) ========== if (typeof GM_registerMenuCommand !== "undefined") { GM_registerMenuCommand("Enter Public API Key", () => { API_KEY = askKey(); }); } else { // ========== PDA (inject button) ========== const btn = document.createElement("button"); btn.textContent = "⚙️ Enter Public API Key"; btn.style.cssText = "margin:6px;padding:4px 8px;font-size:12px;"; btn.onclick = () => { API_KEY = askKey(); }; document.body.prepend(btn); } // ========== Rest of your logic (unchanged) ========== function extractCompanyIdFromLink(link) { const href = link.getAttribute('href') || ''; const m = href.match(/ID=(\d+)/i); return m ? m[1] : null; } function addBadge(companyLi, text, color="black") { let badge = companyLi.querySelector('.tc-capacity-badge'); if (!badge) { badge = document.createElement('span'); badge.className = 'tc-capacity-badge'; badge.style.marginLeft = '6px'; badge.style.fontWeight = 'bold'; companyLi.appendChild(badge); } badge.textContent = text; badge.style.color = color; } function processItem(item, idx) { const viewLink = item.querySelector('a.view-icon'); const companyLi = item.querySelector('li.company'); if (!viewLink || !companyLi) return; const id = extractCompanyIdFromLink(viewLink); if (!id) return; addBadge(companyLi, `[loading#${idx}]`, "gray"); const url = `https://api.torn.com/company/${id}?selections=profile`; fetch(url, { method: 'GET', headers: { 'Authorization': `ApiKey ${API_KEY}` } }) .then(response => { if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); return response.json(); }) .then(json => { if (json.error || !json.company) { addBadge(companyLi, "err", "red"); console.error("API Error:", json.error, `for company ID ${id}`); return; } const hired = json.company.employees_hired; const cap = json.company.employees_capacity; const color = hired >= cap ? "red" : "green"; addBadge(companyLi, `${hired}/${cap}`, color); }) .catch(error => { addBadge(companyLi, "err", "red"); console.error("Fetch error:", error, `for company ID ${id}`); }); } function run() { const items = document.querySelectorAll('ul.item'); let idx = 1; items.forEach(item => processItem(item, idx++)); } const observer = new MutationObserver(() => { if (document.querySelector('ul.item')) { run(); observer.disconnect(); } }); observer.observe(document.body, { childList: true, subtree: true }); })();