您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Attack timer for Torn with a new button
// ==UserScript== // @name Torn Attack Timer // @namespace http://tampermonkey.net/ // @version 1.27 // @description Attack timer for Torn with a new button // @author You // @match https://www.torn.com/loader.php?sid=attack* // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @license MIT // ==/UserScript== (function() { 'use strict'; // Check if the URL includes "attackLog" if (window.location.href.includes("attackLog")) { return; // Exit the script if the URL includes "attackLog" } // Define the API key storage key const apiKeyStorageKey = 'tornApiKey'; // Create and style div elements const coverDiv = createDiv('tornCoverDiv', 'fixed', '25%', '51%', '280px', '400px'); const infoDiv = createDiv('tornInfoDiv', 'fixed', '12%', '0', '100%', null); // Create and style button element const newButton = createButton('tornNewButton', 'fixed', coverDiv.style.top, coverDiv.style.left); // Initialize script initializeScript(); // Function to create and style a div element function createDiv(id, position, top, left, width, height) { const div = document.createElement('div'); div.id = id; div.style.position = position; div.style.top = top; div.style.left = left; div.style.backgroundColor = 'black'; div.style.color = 'white'; div.style.padding = '10px'; div.style.zIndex = '9998'; div.style.width = width; div.style.height = height; div.style.textAlign = 'center'; document.body.insertBefore(div, document.body.firstChild); return div; } // Function to create and style a button element function createButton(id, position, top, left) { const button = document.createElement('button'); button.id = id; button.classList = 'torn-btn'; button.style.position = position; button.style.top = top; button.style.left = left; button.style.transform = 'translate(80px,350px)'; button.style.width = '170px'; button.style.color = 'white'; button.style.zIndex = '9999'; button.textContent = 'WAIT for Counter'; button.disabled = true; document.body.insertBefore(button, document.body.firstChild); return button; } // Function to initialize the script function initializeScript() { const userId = getUserIdFromUrl(); if (!userId) { console.error('User ID not found in the URL.'); return; } const apiKey = getApiKey(); const apiEndpoint = `https://api.torn.com/user/${userId}?selections=basic,personalstats,profile&key=${apiKey}`; const apiEndpoint2 = `https://api.torn.com/user/?selections=basic,bars&key=${apiKey}`; fetchUser(apiEndpoint2); // Store dynamic data in the div for later use infoDiv.dataset.apiEndpoint = apiEndpoint; } // Function to fetch user data function fetchUser(apiEndpoint2) { GM_xmlhttpRequest({ method: 'GET', url: apiEndpoint2, onload: function(response) { const data2 = JSON.parse(response.responseText); if (data2.status.state === "Okay" && data2.energy.current>=25) { newButton.addEventListener("click", async () => { const url = window.location.href; const x = url.indexOf("ID="); const ID = url.substring(x + 3); const step = `step=startFight&user2ID=${ID}`; await fetch("/loader.php?sid=attackData&mode=json", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "x-requested-with": "XMLHttpRequest", }, body: step, }); }); fetchData(infoDiv.dataset.apiEndpoint, infoDiv, coverDiv); } else { endAll(); } } }); } // Function to fetch data from the API function fetchData(apiEndpoint, infoDiv, coverDiv) { const maxRetries = 60; let retryCount = 0; function fetchWithRetry() { GM_xmlhttpRequest({ method: 'GET', url: apiEndpoint, onload: function(response) { const data = JSON.parse(response.responseText); displayData(data, infoDiv, coverDiv); }, onerror: function(error) { console.error('API Request Failed', error); if (retryCount < maxRetries) { console.log('Retrying in 1 second...'); setTimeout(fetchWithRetry, 1000); // Retry after 1 second retryCount++; } else { alert('API problem - cannot get data from API since 60 seconds - please refresh page'); } } }); } // Start the initial fetch attempt fetchWithRetry(); } // Function to display data in the div function displayData(data, infoDiv, coverDiv) { const currentTime = Math.floor(Date.now() / 1000); const timeDifference = calculateTimeDifference(currentTime, data.status.until); infoDiv.innerHTML = `<strong style="font-size: 20px;">Hosp-Out: ${timeDifference}</strong>`; coverDiv.innerHTML = ` <div style="text-align: left; margin-bottom: 3%;">Name: ${data.name}</div> <div style="text-align: left; margin-bottom: 3%;">ID: ${data.player_id}</div> <div style="text-align: left; margin-bottom: 3%;">Level: ${data.level}</div> <div style="text-align: left; margin-bottom: 3%;">Age: ${data.age}</div> <div style="text-align: left;margin-bottom: 6%;">Status: ${data.status.state}</div> <div style="text-align: left; margin-bottom: 3%;">Attacks Won: ${data.personalstats.attackswon}</div> <div style="text-align: left; margin-bottom: 3%;">Time Played: ${data.personalstats.useractivity.toLocaleString('en-US')}</div> <div style="text-align: left; margin-bottom: 3%;">Best Damage: ${data.personalstats.bestdamage}</div> <div style="text-align: left; margin-bottom: 3%;">Highest Level Beaten: ${data.personalstats.highestbeaten}</div> <div style="text-align: left; margin-bottom: 3%;">Stat Enhancers Used: ${data.personalstats.statenhancersused}</div> <div style="text-align: left; margin-bottom: 3%;">Networth: ${data.personalstats.networth}</div> <div style="text-align: left; margin-bottom: 3%;">Xanax Used: ${data.personalstats.xantaken}</div> <div style="text-align: left; margin-bottom: 3%;">Energy Drink Used: ${data.personalstats.energydrinkused}</div> <div style="text-align: left; margin-bottom: 3%;">Energy Refills: ${data.personalstats.refills}</div> `; if (data.status.until <= currentTime) { newButton.disabled = false; newButton.textContent = 'ATTACK'; newButton.style.color = 'red'; newButton.style.zIndex = '100000'; } else { setTimeout(() => fetchData(infoDiv.dataset.apiEndpoint, infoDiv, coverDiv), 1000); } } // Function to end the script function endAll() { coverDiv.style.display = 'none'; infoDiv.style.display = 'none'; newButton.style.display = 'none'; } // Function to get the API key function getApiKey() { let apiKey = GM_getValue(apiKeyStorageKey); alert ("API key= "+apiKey) if (!apiKey) { apiKey = prompt('Enter your Torn API key:'); GM_setValue(apiKeyStorageKey, apiKey); } return apiKey; } // Function to get the user ID from the URL function getUserIdFromUrl() { const userIdMatch = window.location.href.match(/user2ID=(\d+)/); return userIdMatch ? userIdMatch[1] : null; } // Function to calculate time difference between two timestamps in HH:mm:ss format function calculateTimeDifference(currentTime, targetTime) { const timeDifference = Math.max(targetTime - currentTime, 0); // Ensure non-negative value const hours = Math.floor(timeDifference / 3600); const minutes = Math.floor((timeDifference % 3600) / 60); const seconds = timeDifference % 60; return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; } })();