Territorial.io Auto-Join & Play (Reliable Naming)

Ensures usernames are set reliably. F7 arms for auto-start on focus. F6 toggles space-spam.

当前为 2025-06-30 提交的版本,查看 最新版本

// ==UserScript==
// @name         Territorial.io Auto-Join & Play (Reliable Naming)
// @namespace    Violentmonkey Scripts
// @version      9.0
// @description  Ensures usernames are set reliably. F7 arms for auto-start on focus. F6 toggles space-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'}.`);
    }

    /**
     * The main automation sequence. Now properly chained.
     */
    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;
            });
    }

    /**
     * Waits for the name input, fills it, dispatches an event, and waits briefly.
     */
    function autoFillUsername() {
        return new Promise((resolve, reject) => {
            const findFunction = () => document.getElementById('input0');
            const description = 'Username Input Field';
            let attempts = 0;
            const maxAttempts = (15 * 1000) / 200;

            const interval = setInterval(() => {
                if (attempts >= maxAttempts) {
                    clearInterval(interval);
                    reject(new Error(`[Auto-Play] Timed out waiting for: ${description}`));
                    return;
                }
                const nameInput = findFunction();
                if (nameInput) {
                    clearInterval(interval);
                    // 1. Get the next username
                    let currentIndex = parseInt(localStorage.getItem('territorialUsernameIndex') || '0', 10);
                    localStorage.setItem('territorialUsernameIndex', currentIndex + 1);
                    const username = usernames[currentIndex % usernames.length];

                    // 2. Set the value and log it
                    console.log(`[Auto-Play] Setting username to #${currentIndex + 1}: ${username}.`);
                    nameInput.value = username;

                    // 3. CRITICAL: Dispatch an 'input' event to make the game recognize the change.
                    nameInput.dispatchEvent(new Event('input', { bubbles: true, cancelable: true }));

                    // 4. Wait a moment for the game to process the event before continuing.
                    setTimeout(() => {
                        resolve(); // Success!
                    }, 100); // 100ms is a safe, small delay.
                }
                attempts++;
            }, 200);
        });
    }

    function startSpaceSpam() {
        if (isSpammingActive) return;
        isSpammingActive = true;
        console.log('[Auto-Play] Starting spacebar spam. Press F6 to stop.');
        spaceSpamIntervalId = setInterval(() => document.dispatchEvent(new KeyboardEvent('keydown', { 'key': ' ', 'code': 'Space', 'keyCode': 32, 'bubbles': true })), 150);
    }
    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 waiting for: ${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或关注我们的公众号极客氢云获取最新地址