您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
5-sec space spam & guaranteed unique names via locking. F7 arms for auto-start. F6 toggles spam.
当前为
// ==UserScript== // @name Territorial.io Auto-Join & Play (Final Polish) // @namespace Violentmonkey Scripts // @version 12.0 // @description 5-sec space spam & guaranteed unique names via locking. F7 arms for auto-start. F6 toggles spam. // @author Assistant // @match https://territorial.io/* // @match https://*.croxyproxy.com/*territorial.io* // @match https://*/*?__cpo=* // @grant none // @run-at document-end // @license MIT // ==/UserScript== (function() { 'use strict'; // --- Configuration: Username List --- const usernames = [ '[Anti-og]Strategist', 'Ironclad[Anti-og]', 'Vanguard[ANTI-OG]', '[Anti-og]Tactician', 'Swiftstrike[Anti-og]', '[ANTI-OG]Commander', 'Sentinel[Anti-og]', 'Echo[ANTI-OG]', 'Shadow[Anti-og]', 'Apex[ANTI-OG]', 'Overwatch[Anti-og]', '[Anti-og]Pioneer', 'Horizon[ANTI-OG]', 'Maverick[Anti-og]', '[ANTI-OG]Pathfinder', 'Siege[Anti-og]', 'Rampart[ANTI-OG]', 'Nexus[Anti-og]', '[Anti-og]Warden', 'Beacon[ANTI-OG]', '[Anti-og]Vengeance', 'Fury[ANTI-OG]', 'Razor[Anti-og]', '[ANTI-OG]Annihilator', 'WreckingBall[Anti-og]', '[Anti-og]Slayer', 'Berserker[ANTI-OG]', 'Havoc[Anti-og]', '[ANTI-OG]Destroyer', 'Venom[Anti-og]', 'Overlord[ANTI-OG]', '[Anti-og]Executioner', 'Dominator[ANTI-OG]', 'Reaper[Anti-og]', '[ANTI-OG]Conqueror', 'Thunder[Anti-og]', 'Juggernaut[ANTI-OG]', '[Anti-og]Warlord', 'Avalanche[ANTI-OG]', 'Brutal[Anti-og]', 'Phantom[Anti-og]', '[ANTI-OG]Specter', 'Cipher[Anti-og]', '[Anti-og]Rogue', 'Enigma[ANTI-OG]', 'Obscure[Anti-og]', '[ANTI-OG]Whisper', 'Nomad[Anti-og]', '[Anti-og]Drifter', 'Wanderer[ANTI-OG]', 'Cryptic[Anti-og]', '[ANTI-OG]Illusionist', 'Abyss[Anti-og]', 'Void[ANTI-OG]', '[Anti-og]Stalker', 'Echo[ANTI-OG]', 'Wraith[Anti-og]', '[ANTI-OG]Shade', 'Mirage[Anti-og]', 'Eclipse[ANTI-OG]', 'Pixel[Anti-og]', '[ANTI-OG]Ninja', 'Quasar[Anti-og]', '[Anti-og]Goblin', 'Sparky[ANTI-OG]', '[Anti-og]Unicorn', 'GummyBear[ANTI-OG]', 'Captain[Anti-og]', '[ANTI-OG]Phoenix', 'Fuzzy[Anti-og]', '[Anti-og]Whiz', 'Zoom[ANTI-OG]', 'Giggle[Anti-og]', '[ANTI-OG]Panda', 'Retro[Anti-og]', '[Anti-og]Waffle', 'Disco[ANTI-OG]', 'Cosmic[Anti-og]', '[ANTI-OG]Jellyfish', 'BubbleGum[Anti-og]', '[Anti-og]Player', '[ANTI-OG]Gamer', 'Pro[Anti-og]', '[Anti-og]Warrior', 'Legend[ANTI-OG]', 'Elite[Anti-og]', '[ANTI-OG]Ace', '[Anti-og]Ruler', 'Master[ANTI-OG]', 'Chief[Anti-og]', '[ANTI-OG]Hunter', 'Zealot[Anti-og]', '[Anti-og]Crusader', 'Guardian[ANTI-OG]', '[ANTI-OG]Knight', 'Sentinel[Anti-og]', '[Anti-og]Baron', 'Duke[ANTI-OG]', 'King[Anti-og]', 'Queen[ANTI-OG]' ]; // --- State Variables --- let isAutomationRunning = false; let isSpammingActive = false; let spaceSpamIntervalId = null; let isArmed = sessionStorage.getItem('territorialAutoStartArmed') === 'true'; // Stop immediately if this isn't a territorial.io page. if (!isTerritorialPage()) return; console.log(`[Auto-Play] Script ready. Auto-start is ${isArmed ? 'ARMED' : 'DISARMED'}. Press F7 to toggle. Press F6 to control spam.`); // --- Event Listeners --- document.addEventListener('keydown', (event) => { if (event.key === 'F6') { event.preventDefault(); toggleManualSequence(); } if (event.key === 'F7') { event.preventDefault(); toggleArmedState(); } }); document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible' && isArmed && !isAutomationRunning && !isSpammingActive) { isAutomationRunning = true; startAutomation(); } }); // --- Control Functions --- function toggleManualSequence() { if (isSpammingActive) { stopSpaceSpam(); } else if (!isAutomationRunning) { isAutomationRunning = true; startAutomation(); } } function toggleArmedState() { isArmed = !isArmed; sessionStorage.setItem('territorialAutoStartArmed', isArmed); console.log(`[Auto-Play] Auto-start on focus is now ${isArmed ? 'ARMED' : 'DISARMED'}.`); } function startAutomation() { console.log('[Auto-Play] Starting automation sequence...'); autoFillUsername() .then(() => waitForElementAndClick(findMultiplayerButton, "'Multiplayer' button")) .then(() => waitForElementAndClick(findReadyButton, "'Ready' button")) .then(() => { isAutomationRunning = false; startSpaceSpam(); }) .catch(error => { console.error(error); isAutomationRunning = false; }); } /** * Acquires a lock, then finds the name input, fills it, and confirms the change. * This prevents multiple tabs from using the same name. */ function autoFillUsername() { const tabId = Date.now() + Math.random(); // Unique ID for this tab's attempt const lockKey = 'territorialUsernameLock'; const indexKey = 'territorialUsernameIndex'; return new Promise((resolve, reject) => { let attempts = 0; const maxAttempts = 300; // Wait up to 15 seconds to acquire a lock const tryAcquireLock = setInterval(() => { if (attempts++ >= maxAttempts) { clearInterval(tryAcquireLock); localStorage.removeItem(lockKey); // Clean up a potentially stale lock reject(new Error('[Auto-Play] Timed out waiting to acquire username lock.')); return; } const currentLock = localStorage.getItem(lockKey); if (currentLock === null || currentLock === '') { // Lock is free, try to claim it localStorage.setItem(lockKey, tabId); // MUST check if we actually got it, another tab could have set it in the same moment if (localStorage.getItem(lockKey) == tabId) { clearInterval(tryAcquireLock); // We have the lock! console.log('[Auto-Play] Username lock acquired by this tab.'); // --- CRITICAL SECTION: Only one tab can be here at a time --- const nameInput = document.getElementById('input0'); if (!nameInput) { localStorage.removeItem(lockKey); // Release lock on error reject(new Error('[Auto-Play] Could not find username input field.')); return; } let currentIndex = parseInt(localStorage.getItem(indexKey) || '0', 10); const username = usernames[currentIndex % usernames.length]; console.log(`[Auto-Play] Setting username to #${currentIndex + 1}: ${username}.`); nameInput.value = username; nameInput.dispatchEvent(new Event('input', { bubbles: true, cancelable: true })); nameInput.focus(); nameInput.blur(); // Increment the index for the next tab and release the lock localStorage.setItem(indexKey, currentIndex + 1); localStorage.removeItem(lockKey); console.log('[Auto-Play] Username set and lock released.'); // --- END CRITICAL SECTION --- setTimeout(resolve, 200); // Brief pause before continuing } } // If lock is held by another tab, just wait for the next interval. }, 50); // Check for lock availability every 50ms }); } function startSpaceSpam() { if (isSpammingActive) return; isSpammingActive = true; console.log('[Auto-Play] Starting spacebar spam every 5 seconds. Press F6 to stop.'); spaceSpamIntervalId = setInterval(() => { console.log('[Auto-Play] Pressing Spacebar...'); document.dispatchEvent(new KeyboardEvent('keydown', { 'key': ' ', 'code': 'Space', 'keyCode': 32, 'bubbles': true })); }, 5000); // 5000 milliseconds = 5 seconds } function stopSpaceSpam() { if (!isSpammingActive) return; clearInterval(spaceSpamIntervalId); isSpammingActive = false; console.log('[Auto-Play] Spacebar spam stopped.'); } // --- Helper Functions --- function isTerritorialPage() { const href = window.location.href; if (href.includes('territorial.io')) return true; if (href.includes('?__cpo=')) { try { return atob(new URLSearchParams(window.location.search).get('__cpo')).includes('territorial.io'); } catch (e) { return false; } } return false; } function waitForElementAndClick(findFunction, description) { return new Promise((resolve, reject) => { let attempts = 0; const maxAttempts = (15 * 1000) / 200; console.log(`[Auto-Play] Searching for: ${description}`); const interval = setInterval(() => { if (attempts >= maxAttempts) { clearInterval(interval); reject(new Error(`[Auto-Play] Timed out: ${description}`)); return; } const element = findFunction(); if (element) { clearInterval(interval); element.click(); resolve(); } attempts++; }, 200); }); } const findMultiplayerButton = () => Array.from(document.querySelectorAll('button')).find(btn => btn.innerText.includes('Multiplayer')); const findReadyButton = () => Array.from(document.querySelectorAll('button')).find(btn => btn.innerText.trim().startsWith('Ready')); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址