您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Track player status, hospital time, and attack links in Torn with persistent data, enhanced UI. Adds players by user ID.
当前为
// ==UserScript== // @name Torn Player Tracker // @namespace https://www.torn.com/ // @version 1.8 // @description Track player status, hospital time, and attack links in Torn with persistent data, enhanced UI. Adds players by user ID. // @author Xenocide [2216313] // @match https://www.torn.com/* // @grant GM_xmlhttpRequest // @grant GM_addStyle // @connect api.torn.com // ==/UserScript== (function () { "use strict"; // === Configuration === const API_KEY = "your_api_key_here"; // Replace with your Torn API key const UPDATE_INTERVAL = 30000; // Update interval in milliseconds (30 seconds) // Retrieve tracked players from localStorage or initialize default IDs let trackedPlayers = JSON.parse(localStorage.getItem("trackedPlayers")) || [123456, 654321, 789012]; // === Create the Floating Box === const box = document.createElement("div"); box.id = "statusTracker"; box.innerHTML = ` <h3>Player Tracker</h3> <ul id="statusList">Loading...</ul> <div id="userControls"> <hr> <input type="text" id="addPlayerInput" placeholder="Add Player ID" /> <button id="addPlayerButton">Add</button> <ul id="trackedPlayersList"></ul> </div> <button id="toggleUI">Hide Add Section</button> `; document.body.appendChild(box); // Add some styles for the box GM_addStyle(` #statusTracker { position: fixed; top: 10px; right: 10px; width: 350px; background-color: #333; color: white; border: 2px solid #555; border-radius: 8px; padding: 10px; z-index: 10000; font-family: Arial, sans-serif; } #statusTracker h3 { margin: 0 0 10px 0; font-size: 16px; text-align: center; } #statusTracker ul { list-style-type: none; padding: 0; margin: 0; } #statusTracker li { margin: 5px 0; } #statusTracker li span { font-weight: bold; } #statusTracker input { width: calc(100% - 60px); margin-right: 5px; padding: 5px; } #statusTracker button { padding: 5px; cursor: pointer; } #statusTracker hr { margin: 10px 0; border: 0.5px solid #555; } `); // === Function to Format Time in Minutes and Seconds === function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; return `${minutes}m ${remainingSeconds}s`; } // === Function to Fetch Player Info by ID === function fetchPlayerStatus(playerId) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: `https://api.torn.com/user/${playerId}?selections=basic,profile&key=${API_KEY}`, onload: (response) => { if (response.status === 200) { const data = JSON.parse(response.responseText); // Check for API errors if (data.error) { console.error(`Error fetching player ${playerId}:`, data.error); return resolve({ playerId, name: `Error: ${data.error.error}`, status: "Unknown", hospitalTimeLeft: 0, attackLink: "", }); } // Extract data from API response const name = data.name || `ID ${playerId}`; const status = data.status?.state || "Unknown"; const hospitalTimeLeft = data.status?.until ? Math.max(0, Math.ceil((data.status.until * 1000 - Date.now()) / 1000)) : 0; const attackLink = `https://www.torn.com/attack.php?XID=${playerId}`; resolve({ playerId, name, status, hospitalTimeLeft, attackLink }); } else { console.error(`Error fetching status for player ${playerId}:`, response.status); reject(`Error fetching status for player ${playerId}`); } }, onerror: (error) => { console.error(`Error fetching status for player ${playerId}:`, error); reject(`Error fetching status for player ${playerId}`); }, }); }); } // === Function to Update the Status List === async function updateStatusList() { const statusList = document.getElementById("statusList"); statusList.innerHTML = "Updating..."; try { const statusPromises = trackedPlayers.map((id) => fetchPlayerStatus(id)); const statuses = await Promise.all(statusPromises); statusList.innerHTML = ""; statuses.forEach(({ playerId, name, status, hospitalTimeLeft, attackLink }) => { const color = status === "Okay" ? "green" : status === "Hospital" ? "red" : status === "Traveling" ? "blue" : "gray"; const hospitalText = status === "Hospital" ? ` (Time left: ${formatTime(hospitalTimeLeft)})` : ""; const listItem = document.createElement("li"); listItem.innerHTML = ` <span style="color: ${color};">${status}</span> - <a href="${attackLink}" target="_blank" style="color: yellow;">${name}</a> (ID: ${playerId})${hospitalText}`; statusList.appendChild(listItem); }); } catch (error) { console.error("Error updating statuses:", error); statusList.innerHTML = "Error updating statuses."; } } // === Function to Update Tracked Players List === function updateTrackedPlayersList() { const trackedPlayersList = document.getElementById("trackedPlayersList"); trackedPlayersList.innerHTML = ""; trackedPlayers.forEach((playerId) => { const listItem = document.createElement("li"); listItem.innerHTML = `Player ID: ${playerId} <button data-id="${playerId}" class="removePlayerButton">Remove</button>`; trackedPlayersList.appendChild(listItem); }); // Add event listeners to remove buttons document.querySelectorAll(".removePlayerButton").forEach((button) => { button.addEventListener("click", (event) => { const playerId = parseInt(event.target.getAttribute("data-id")); trackedPlayers = trackedPlayers.filter((id) => id !== playerId); localStorage.setItem("trackedPlayers", JSON.stringify(trackedPlayers)); // Save to localStorage updateTrackedPlayersList(); updateStatusList(); }); }); } // === Add Player by ID from Input === document.getElementById("addPlayerButton").addEventListener("click", () => { const input = document.getElementById("addPlayerInput"); const playerId = parseInt(input.value); if (!isNaN(playerId) && !trackedPlayers.includes(playerId)) { trackedPlayers.push(playerId); localStorage.setItem("trackedPlayers", JSON.stringify(trackedPlayers)); // Save to localStorage input.value = ""; updateTrackedPlayersList(); updateStatusList(); } else if (isNaN(playerId)) { alert("Please enter a valid player ID."); } else { alert("This player is already tracked."); } }); // === Hide/Show Add Section === document.getElementById("toggleUI").addEventListener("click", () => { const userControls = document.getElementById("userControls"); if (userControls.style.display === "none") { userControls.style.display = "block"; document.getElementById("toggleUI").innerText = "Hide Add Section"; } else { userControls.style.display = "none"; document.getElementById("toggleUI").innerText = "Show Add Section"; } }); // === Periodic Updates === setInterval(updateStatusList, UPDATE_INTERVAL); updateStatusList(); // Initial update updateTrackedPlayersList(); // Initial tracked players list })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址