您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Always show Attack column for your faction; toggle all grey "Attack" labels into real links (both teams).
// ==UserScript== // @name FreeForAll - AttackButtons // @namespace http://tampermonkey.net/ // @version 5.2 // @description Always show Attack column for your faction; toggle all grey "Attack" labels into real links (both teams). // @match https://www.torn.com/factions.php* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; // --- settings --- const DEBUG = true; // toggle state: when true, convert grey Attack spans to real links; when false, revert to grey spans let linksEnabled = true; const log = (...a) => DEBUG && console.log('[AttackToggle]', ...a); // --- CSS: keep your-faction Attack column visible; style our links --- (function addStyles() { const css = ` /* Force show Attack column in your-faction (header + cells) */ .tab-menu-cont.your-faction .attack, .tab-menu-cont.your-faction .attack.left, .tab-menu-cont.your-faction .attack___wBWp2 { display: inline-block !important; visibility: visible !important; opacity: 1 !important; pointer-events: auto !important; } /* Make sure header keeps space for Attack */ .tab-menu-cont.your-faction .members-cont > .white-grad .attack { display: inline-block !important; } /* Our injected attack link */ a.custom-attack-button { text-decoration: none !important; padding: 0px 2px; border-radius: 2px; cursor: pointer; margin-left: 4px; color: white !important; background: #0078d4 !important; display: inline-block; } `; const s = document.createElement('style'); s.textContent = css; document.head.appendChild(s); })(); function fixYourFactionWidth() { const faction = document.querySelector('.tab-menu-cont.your-faction'); if (!faction) return; // Shrink the container width to leave room for the Attack column //faction.style.width = 'calc(50%)'; // tweak 40px as needed //faction.style.boxSizing = 'border-box'; faction.querySelectorAll(`div[class*="points"]`).forEach(cell => { cell.style.width = '10%'; // adjust % as needed cell.style.minWidth = '0'; // allow shrinking }); faction.querySelectorAll(`div[class*="attack"]`).forEach(cell => { cell.style.width = '3%'; // adjust % as needed cell.style.minWidth = '0'; // allow shrinking }); faction.querySelectorAll(`div[class*="level"]`).forEach(cell => { cell.style.width = '8%'; // adjust % as needed cell.style.minWidth = '0'; // allow shrinking }); } // --- helpers --- function showElementHard(el) { if (!el) return; el.style.setProperty('display', 'inline-block', 'important'); el.style.setProperty('visibility', 'visible', 'important'); el.style.setProperty('opacity', '1', 'important'); el.style.setProperty('pointer-events', 'auto', 'important'); } function ensureYourFactionHeader() { const root = document.querySelector('.tab-menu-cont.your-faction'); if (!root) return; const header = root.querySelector('.members-cont > .white-grad'); if (!header) return; let attackHeader = header.querySelector('.attack'); if (!attackHeader) { attackHeader = document.createElement('div'); attackHeader.className = 'attack left attack___wBWp2 tab___UztMc'; attackHeader.textContent = 'Attack'; header.appendChild(attackHeader); log('Created Attack header for your faction'); } showElementHard(attackHeader); } function ensureYourFactionCells() { // Make sure each teammate row has an attack cell so the column keeps shape. const yourRows = document.querySelectorAll('.tab-menu-cont.your-faction ul.members-list li.your'); yourRows.forEach(li => { let attackCell = li.querySelector('.attack'); if (!attackCell) { attackCell = document.createElement('div'); attackCell.className = 'attack left attack___wBWp2'; // Insert near the end like Torn usually does const clearEl = li.querySelector('.clear'); li.insertBefore(attackCell, clearEl || null); } showElementHard(attackCell); }); } function xidFromRow(li) { const profileLink = li.querySelector('a[href^="/profiles.php?XID="]'); if (!profileLink) return null; const m = profileLink.href.match(/XID=(\d+)/); return m ? m[1] : null; } // Convert the attack cell for a single row according to linksEnabled function transformAttackCellForRow(li) { let attackCell = li.querySelector('.attack'); if (!attackCell) return; // Always keep the cell visible if (li.classList.contains('your')) showElementHard(attackCell); // Only create the link once let link = attackCell.querySelector('a.custom-attack-button'); if (!link && linksEnabled) { const xid = xidFromRow(li); if (!xid) return; link = document.createElement('a'); link.href = `https://www.torn.com/loader.php?sid=attack&user2ID=${xid}`; link.textContent = 'Attack'; link.className = 'custom-attack-button'; link.target = '_blank'; link.rel = 'noopener noreferrer'; attackCell.appendChild(link); // Hide the grey span if present attackCell.querySelectorAll('span.t-gray-9').forEach(s => s.style.display = 'none'); } // Instead of removing/adding nodes, just show/hide via style if (link) link.style.display = linksEnabled ? 'inline-block' : 'none'; attackCell.querySelectorAll('span.t-gray-9').forEach(span => { span.style.display = linksEnabled ? 'none' : 'inline-block'; }); } function transformAllRows() { // Always keep your-faction column visible fixYourFactionWidth(); ensureYourFactionHeader(); ensureYourFactionCells(); // Apply toggle behavior to ALL rows (both teams) const rows = document.querySelectorAll('ul.members-list > li'); rows.forEach(transformAttackCellForRow); } // --- toggle button --- function createToggleButton() { const button = document.createElement('button'); button.textContent = 'Attack Links: ON'; button.style.position = 'fixed'; button.style.bottom = '5%'; button.style.right = '10px'; button.style.zIndex = '2147483647'; 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 = '0 0 5px rgba(0,0,0,0.3)'; button.addEventListener('click', () => { linksEnabled = !linksEnabled; button.textContent = `Attack Links: ${linksEnabled ? 'ON' : 'OFF'}`; button.style.backgroundColor = linksEnabled ? '#008CBA' : '#777'; // This now only toggles visibility, no DOM removal transformAllRows(); }); document.body.appendChild(button); } // --- observers / boot --- let debounce; const mo = new MutationObserver(() => { clearTimeout(debounce); debounce = setTimeout(transformAllRows, 200); }); function start() { createToggleButton(); transformAllRows(); mo.observe(document.body, { childList: true, subtree: true }); log('Initialized'); } // Delay a touch to let Torn render setTimeout(start, 600); })();