您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Replace greyed-out Attack spans with actual clickable in Torn City.
// ==UserScript== // @name Force War Attack Links Clickable // @namespace http://tampermonkey.net/ // @version Alpha1.1 // @description Replace greyed-out Attack spans with actual clickable in Torn City. // @author YouMe // @match https://www.torn.com/factions.php* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; let debug = false; let mutationTimeout = null; let scriptEnabled = true; function log(...args) { if (debug) console.log('[TornScript]', ...args); } function replaceDisabledAttackButtons() { const attackElements = Array.from(document.querySelectorAll('span.t-gray-9, a.custom-attack-button')); for (const el of attackElements) { const parentEnemy = el.closest('.enemy'); if (!parentEnemy) continue; const profileLink = parentEnemy.querySelector('a[href^="/profiles.php?XID="]'); if (!profileLink) continue; const match = profileLink.href.match(/XID=(\d+)/); if (!match) continue; const userId = match[1]; if (scriptEnabled) { // If it's already a custom link, leave it alone if (el.tagName === 'A' && el.classList.contains('custom-attack-button')) continue; // If it's a span that says Attack, replace with a link if (el.tagName === 'SPAN' && el.textContent.trim() === 'Attack') { const attackUrl = `https://www.torn.com/loader.php?sid=attack&user2ID=${userId}`; const attackLink = document.createElement('a'); attackLink.href = attackUrl; attackLink.textContent = 'Attack'; attackLink.className = 'custom-attack-button'; attackLink.dataset.injected = 'true'; el.replaceWith(attackLink); } } else { // If it's a custom-injected link, revert it to a span if (el.tagName === 'A' && el.classList.contains('custom-attack-button')) { const span = document.createElement('span'); span.textContent = 'Attack'; span.className = 't-gray-9'; span.dataset.injected = 'true'; // marks it as previously injected attackLink.target = '_blank'; el.replaceWith(span); } } } } const observer = new MutationObserver(() => { if (mutationTimeout) clearTimeout(mutationTimeout); mutationTimeout = setTimeout(replaceDisabledAttackButtons, 300); }); observer.observe(document.body, { childList: true, subtree: true }); setTimeout(replaceDisabledAttackButtons, 1000); function createToggleButton() { const button = document.createElement('button'); button.textContent = 'Attack Script: ON'; button.style.position = 'fixed'; button.style.bottom = '5%'; button.style.right = '10px'; button.style.zIndex = '9999'; button.style.padding = '6px 10px'; button.style.backgroundColor = '#008CBA'; button.style.color = 'white'; button.style.border = 'none'; button.style.borderRadius = '5px'; button.style.cursor = 'pointer'; button.style.fontSize = '14px'; button.style.boxShadow = '0px 0px 5px rgba(0,0,0,0.3)'; button.addEventListener('click', () => { scriptEnabled = !scriptEnabled; button.textContent = `Attack Script: ${scriptEnabled ? 'ON' : 'OFF'}`; button.style.backgroundColor = scriptEnabled ? '#008CBA' : '#777'; replaceDisabledAttackButtons(); }); document.body.appendChild(button); } function addCustomStyles() { const style = document.createElement('style'); style.textContent = ` a.custom-attack-button { color: white !important; background-color: blue !important; padding: 2px 3px; border-radius: 4px; font-weight: normal; text-decoration: none; cursor: pointer; margin-left: 10px; } `; document.head.appendChild(style); } createToggleButton(); addCustomStyles(); })();