TriX Executor for Territorial.io

TriX is a powerful, command-driven script executor designed to enhance your territorial.io experience. It features a modular interface with a command prompt for quick automation, a 'Featured Scripts' section for loading complex modules like the F-key controlled Auto-Join & Play script, and a dedicated JavaScript Executor for running your own custom code. ⚠️ The JS Executor is a powerful tool; never run code from untrusted sources. Take control of your game with TriX.

目前為 2025-07-02 提交的版本,檢視 最新版本

// ==UserScript==
// @name         TriX Executor for Territorial.io
// @namespace    Violentmonkey Scripts
// @version      32.0.7
// @description  TriX is a powerful, command-driven script executor designed to enhance your territorial.io experience. It features a modular interface with a command prompt for quick automation, a 'Featured Scripts' section for loading complex modules like the F-key controlled Auto-Join & Play script, and a dedicated JavaScript Executor for running your own custom code. ⚠️ The JS Executor is a powerful tool; never run code from untrusted sources. Take control of your game with TriX.
// @author       Painsel & Assistant
// @match        https://*/*
// @grant        none
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- Configuration & State ---
    const tabId = sessionStorage.getItem('trixTabId') || Date.now() + Math.random();
    sessionStorage.setItem('trixTabId', tabId);
    let isMaster = false;

    const baseNames = ['Strategist','Ironclad','Vanguard','Tactician','Swiftstrike','Commander','Sentinel','Echo','Shadow','Apex','Overwatch','Pioneer','Horizon','Maverick','Pathfinder','Siege','Rampart','Nexus','Warden','Beacon','Vengeance','Fury','Razor','Annihilator','Slayer','Berserker','Havoc','Destroyer','Venom','Overlord','Executioner','Dominator','Reaper','Conqueror','Thunder','Juggernaut','Warlord','Avalanche','Brutal','Phantom','Specter','Cipher','Rogue','Enigma','Obscure','Whisper','Nomad','Drifter','Wanderer','Cryptic','Illusionist','Abyss','Void','Stalker','Wraith','Shade','Mirage','Eclipse','Pixel','Ninja','Quasar','Goblin','Sparky','Unicorn','GummyBear','Captain','Phoenix','Fuzzy','Whiz','Zoom','Giggle','Panda','Retro','Waffle','Disco','Cosmic','Jellyfish','BubbleGum','Player','Gamer','Pro','Warrior','Legend','Elite','Ace','Ruler','Master','Chief','Hunter','Zealot','Crusader','Guardian','Knight','Baron','Duke','King','Queen','Aegis','Alpha','Amazon','Ambush','Android','Apollo','Arcane','Archer','Arctic','Argon','Argus','Ares','Armada','Arrow','Artillery','Asgard','Ash','Assassin','Asteroid','Astra','Atlas','Atom','Aurora','Avatar','Avenger','Axiom','Azrael','Azure','Ballista','Bandit','Banshee','Barbarian','Barrage','Basilisk','Bastion','Battalion','Bear','Behemoth','Biscuit','Blackout','Blade','Blaster','Blaze','Blitz','Blizzard','Blockade','Bolt','Bomber','Boop','Borealis','Breaker','Brigade','Bullet','Button','Cabal','Cadet','Caliber','Canyon','Cascade','Cataclysm','Catalyst','Catapult','Cavalry','Centurion','Cerberus','Chaos','Charger','Chimera','Cinder','Citadel','Cleric','Cliff','Cobra'];
    let trixAutomationRunning = false, trixSpammingActive = false, trixSpaceSpamIntervalId = null;
    let autoJoinScriptExecuted = false;

    if (!isTerritorialPage()) return;


    // --- UI CREATION AND MANAGEMENT ---

    function createExecutorUI() {
        if (document.getElementById('trix-frame')) return;
        const frame = document.createElement('div'); frame.id = 'trix-frame';
        Object.assign(frame.style, { position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', background: '#111', border: '1px solid #444', borderRadius: '6px', zIndex: '100000', boxShadow: '0 0 15px rgba(0,0,0,0.5)', padding: '8px', cursor: 'move', animation: 'trix-fade-in 0.3s ease-out' });
        const executor = document.createElement('div'); executor.id = 'trix-executor';
        Object.assign(executor.style, { width: '600px', backgroundColor: '#1e1e1e', display: 'flex', flexDirection: 'column', fontFamily: 'Consolas, "Courier New", monospace', cursor: 'default' });
        const header = document.createElement('div'); header.id = 'trix-header';
        Object.assign(header.style, { backgroundColor: '#111', color: 'white', padding: '8px', borderTopLeftRadius: '5px', borderTopRightRadius: '5px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' });
        header.innerHTML = `<div><img src="https://i.postimg.cc/pVhYV8kL/image.png" style="height: 20px; margin-right: 10px; vertical-align: middle;"> TriX <span style="font-size: 0.7em; color: #888;">by Painsel</span></div>`;
        const headerControls = document.createElement('div'); Object.assign(headerControls.style, { display: 'flex', alignItems: 'center', gap: '8px' });
        const tabCounter = document.createElement('span'); tabCounter.id = "trix-tab-counter"; tabCounter.title = "Active territorial.io tabs"; Object.assign(tabCounter.style, { color: '#ccc', fontSize: '12px', marginRight: '8px', background: '#252526', padding: '3px 6px', borderRadius: '4px' }); tabCounter.textContent = "Tabs: 0";
        const toggleButton = document.createElement('button'); toggleButton.innerHTML = "−"; Object.assign(toggleButton.style, { background: '#555', border: 'none', color: 'white', borderRadius: '4px', cursor: 'pointer', width: '22px', height: '22px', fontSize: '16px', lineHeight: '1', padding: '0' });
        const fileMenuContainer = document.createElement('div'); fileMenuContainer.className = 'trix-menu-container';
        const fileButton = document.createElement('button'); fileButton.className = 'trix-menu-button'; fileButton.textContent = 'File';
        const fileDropdown = document.createElement('div'); fileDropdown.className = 'trix-dropdown-content';
        fileDropdown.innerHTML = `<a href="#" id="trix-inject-btn">Inject</a><a href="#" id="trix-open-btn">Open...</a><a href="#" id="trix-save-btn">Save As...</a>`;
        fileMenuContainer.appendChild(fileButton); fileMenuContainer.appendChild(fileDropdown);
        fileButton.addEventListener('click', (e) => { e.stopPropagation(); fileDropdown.style.display = fileDropdown.style.display === 'block' ? 'none' : 'block'; });
        document.addEventListener('click', () => { fileDropdown.style.display = 'none'; });
        headerControls.appendChild(tabCounter); headerControls.appendChild(toggleButton); headerControls.appendChild(fileMenuContainer); header.appendChild(headerControls);
        const body = document.createElement('div'); body.id = 'trix-body'; Object.assign(body.style, { display: 'flex', overflow: 'hidden', height: '420px', transition: 'height 0.3s ease-out' });
        const sidebar = document.createElement('div'); Object.assign(sidebar.style, { width: '160px', backgroundColor: '#252526', padding: '10px 0', borderRight: '1px solid #444' });
        sidebar.innerHTML = `<button class="trix-nav-button active" data-page="cmd">Command Prompt</button><button class="trix-nav-button" data-page="scripts">Featured Scripts</button><button class="trix-nav-button" id="trix-executor-nav-btn" data-page="executor" disabled>Script Executor</button><button class="trix-nav-button" id="trix-server-log-nav-btn" data-page="serverlog" disabled>Server Logs</button><button class="trix-nav-button" data-page="changelog">Changelog</button>`;
        const content = document.createElement('div'); Object.assign(content.style, { flexGrow: '1', display: 'flex', flexDirection: 'column' });
        const cmdPage = document.createElement('div'); cmdPage.id = 'trix-page-cmd'; cmdPage.className = 'trix-page'; Object.assign(cmdPage.style, { display: 'flex', flexDirection: 'column', height: '100%' });
        cmdPage.innerHTML = `<div id="trix-history" style="flex-grow: 1; padding: 10px; overflow-y: auto; font-size: 13px;"></div><div style="display: flex; border-top: 1px solid #444; align-items: center;"><input type="text" id="trix-cmd-input" placeholder="Type a command..." style="flex-grow: 1; background: #333; border: none; color: white; padding: 8px; outline: none;"><button id="trix-send-btn" style="background: #0e639c; color: white; border: none; padding: 0 15px; cursor: pointer; align-self: stretch;">Send</button></div>`;
        const scriptsPage = document.createElement('div'); scriptsPage.id = 'trix-page-scripts'; scriptsPage.className = 'trix-page'; Object.assign(scriptsPage.style, { display: 'none', padding: '15px', overflowY: 'auto' });
        const executorPage = document.createElement('div'); executorPage.id = 'trix-page-executor'; executorPage.className = 'trix-page'; Object.assign(executorPage.style, { display: 'none', flexDirection: 'column', height: '100%', padding: '10px' });
        executorPage.innerHTML = `<div style="margin-bottom: 5px; color: #ffeb3b;">⚠️ JS Executor. End with 'return { ... }' to manage it in the F12 console.</div><textarea id="trix-script-input" placeholder="let myVar = 10;\\nfunction myFunc(){...}\\n\\nreturn { myVar, myFunc };" style="flex-grow: 1; background: #111; color: #e0e0e0; border: 1px solid #444; resize: none; width: 100%; box-sizing: border-box; font-family: inherit;"></textarea><div style="display: flex; gap: 10px; margin-top: 10px;"><button id="trix-execute-script-btn" style="background: #c62828; color: white; border: none; padding: 10px; cursor: pointer; flex-grow: 1;">Execute</button><button id="trix-clear-script-btn" style="background: #555; color: white; border: none; padding: 10px; cursor: pointer;">Clear</button></div>`;
        const changelogPage = document.createElement('div'); changelogPage.id = 'trix-page-changelog'; changelogPage.className = 'trix-page'; Object.assign(changelogPage.style, { display: 'none', padding: '15px', overflowY: 'auto', color: '#ccc', fontSize: '13px' });
        const serverLogPage = document.createElement('div'); serverLogPage.id = 'trix-page-serverlog'; serverLogPage.className = 'trix-page'; Object.assign(serverLogPage.style, { display: 'none', padding: '15px', overflowY: 'auto', color: '#ccc', fontSize: '13px' });
        serverLogPage.innerHTML = `<h3 style="color: white; margin-top: 0;">Simulated Server Logs</h3><div id="trix-server-log-content"></div>`;
        content.appendChild(cmdPage); content.appendChild(scriptsPage); content.appendChild(executorPage); content.appendChild(changelogPage); content.appendChild(serverLogPage);
        body.appendChild(sidebar); body.appendChild(content);
        executor.appendChild(header); executor.appendChild(body);
        frame.appendChild(executor); document.body.appendChild(frame);
        addGlobalStyles(); makeDraggable(frame); setupCommandPrompt(); setupSidebarNavigation(); populateFeaturedScripts(); populateChangelog(changelogPage); setupExecutorInjection(); logToHistory("Welcome to TriX Executor. Type /help for commands.");
        toggleButton.onclick = () => { const isMinimized = body.style.display === 'none'; body.style.display = isMinimized ? 'flex' : 'none'; frame.style.padding = isMinimized ? '8px' : '0'; toggleButton.innerHTML = isMinimized ? '−' : '+'; };
    }

    // --- SCRIPT EXECUTOR & FILE MENU ---
    function setupExecutorInjection() {
        document.getElementById('trix-inject-btn').addEventListener("click", e => { e.preventDefault(); const injectButton = e.target; injectButton.textContent = 'Injecting...'; injectButton.style.pointerEvents = 'none'; logToHistory("Injecting JavaScript Runtime..."); setTimeout(() => { logToHistory("Injection successful. Script Executor is now online.", "success"); document.getElementById("trix-executor-nav-btn").disabled = false; document.getElementById("trix-server-log-nav-btn").disabled = false; injectButton.textContent = 'Injected ✔'; injectButton.style.color = '#4caf50'; document.getElementById("trix-execute-script-btn").addEventListener("click", () => executeCustomScript()); document.getElementById("trix-clear-script-btn").addEventListener("click", () => { document.getElementById("trix-script-input").value = ""; }); }, 1500); });
        document.getElementById('trix-save-btn').addEventListener("click", e => { e.preventDefault(); saveScriptToFile(); });
        document.getElementById('trix-open-btn').addEventListener("click", e => { e.preventDefault(); openScriptFromFile(); });
    }

    // --- COMMAND & EXECUTION LOGIC ---
    function handleCommand(command) {
        logToHistory(`> ${command}`);
        const [cmd, ...args] = command.trim().toLowerCase().split(" ");
        const commandName = cmd.substring(1);
        sendCommandToAgents(commandName, args, 999);
    }
    function executeReceivedCommand(payload) {
        logToHistory(`Executing command: ${payload.cmd}`);
        if (payload.cmd === "auto-join") { if (!trixAutomationRunning) { trixAutomationRunning = true; startTrixAutomation(); } }
        else if (payload.cmd === "spam") { const interval = parseTimeInterval(payload.args[0]); if (interval) startTrixSpaceSpam(interval); }
        else if (payload.cmd === "stop") { stopTrixSpaceSpam(); }
        else if (payload.cmd === "detach") { if (window.trixHandle) { delete window.trixHandle; logToHistory("Handle detached."); } }
        else if (payload.cmd === "execute-legacy") { if (!autoJoinScriptExecuted) { executeAutoJoinAndPlayScript(); } }
        else if (payload.cmd === "execute-custom") { executeCustomScript(payload.args[0]); }
        else if (payload.cmd === 'help' && isMaster) {
            logToHistory("Available Commands:");
            logToHistory("/auto-join - Starts the auto-join sequence.");
            logToHistory("/spam [interval] - Starts space spam (e.g., /spam 5s).");
            logToHistory("/stop - Stops the space spam.");
            logToHistory("/detach - Removes custom script handle from the F12 console.");
        }
    }

    // --- CROSS-TAB COMMUNICATION ---
    function sendCommandToAgents(command, args = [], targetCount = 999) { const payload = { cmd: command, args, targetCount, commandId: Date.now() }; localStorage.setItem('trix-command', JSON.stringify(payload)); }
    function setupStorageListener() { window.addEventListener('storage', e => { if (e.key === 'trix-master-heartbeat') { if (isMaster && e.newValue) { console.log("[TriX] Another Master detected. Becoming Agent."); isMaster = false; const frame = document.getElementById('trix-frame'); if (frame) frame.style.display = 'none'; } } if (e.key === 'trix-command' && e.newValue) { const payload = JSON.parse(e.newValue); shouldIExecute(payload).then(doExecute => { if (doExecute) executeReceivedCommand(payload); }); } }); }
    function setupTabCounter() { setInterval(() => { const heartbeats = JSON.parse(localStorage.getItem('trix-agent-heartbeats') || '{}'); heartbeats[tabId] = Date.now(); localStorage.setItem('trix-agent-heartbeats', JSON.stringify(heartbeats)); }, 2000); window.addEventListener('beforeunload', () => { const heartbeats = JSON.parse(localStorage.getItem('trix-agent-heartbeats') || '{}'); delete heartbeats[tabId]; localStorage.setItem('trix-agent-heartbeats', JSON.stringify(heartbeats)); }); if (isMaster) { setInterval(() => { localStorage.setItem('trix-master-heartbeat', Date.now()); }, 2000); setInterval(() => { const heartbeats = JSON.parse(localStorage.getItem('trix-agent-heartbeats') || '{}'); let activeCount = 0; for (const id in heartbeats) { if (Date.now() - heartbeats[id] < 5000) activeCount++; else delete heartbeats[id]; } localStorage.setItem('trix-agent-heartbeats', JSON.stringify(heartbeats)); const counterEl = document.getElementById('trix-tab-counter'); if(counterEl) counterEl.textContent = `Tabs: ${activeCount}`; }, 1000); window.addEventListener('beforeunload', () => { localStorage.removeItem('trix-master-heartbeat'); }); } }
    function shouldIExecute(payload) { return new Promise(resolve => { let attempts = 0; const tryLock = setInterval(() => { if (attempts++ > 100) { clearInterval(tryLock); return resolve(false); } if (localStorage.getItem('trix-exec-lock')) return; localStorage.setItem('trix-exec-lock', 'true'); const counterKey = `trix-exec-count-${payload.commandId}`; let count = parseInt(localStorage.getItem(counterKey) || '0', 10); if (count < payload.targetCount) { localStorage.setItem(counterKey, count + 1); localStorage.removeItem('trix-exec-lock'); clearInterval(tryLock); resolve(true); } else { localStorage.removeItem('trix-exec-lock'); clearInterval(tryLock); resolve(false); } }, 50); }); }
    
    // --- FEATURED SCRIPT LOADER ---
    function executeAutoJoinAndPlayScript() {
        autoJoinScriptExecuted = true;
        logToHistory("Executing Auto-Join & Play script...", "success");
        let isLegacyAutomationRunning = false, isLegacySpammingActive = false, legacySpaceSpamIntervalId = null;
        let isLegacyArmed = sessionStorage.getItem("territorialAutoStartArmed") === 'true';
        createLegacyDashboard();
        updateLegacyDashboardStatus(`Auto-start ${isLegacyArmed ? "ARMED" : "DISARMED"}.`);
        document.addEventListener("keydown", event => { if ("F6" === event.key) { event.preventDefault(); toggleLegacyManualSequence(); } if ("F7" === event.key) { event.preventDefault(); toggleLegacyArmedState(); } });
        document.addEventListener("visibilitychange", () => { if ("visible" === document.visibilityState && isLegacyArmed && !isLegacyAutomationRunning && !isLegacySpammingActive) { isLegacyAutomationRunning = true; startLegacyAutomation(); } });
        function toggleLegacyManualSequence() { isLegacySpammingActive ? stopLegacySpaceSpam() : (isLegacyAutomationRunning || (isLegacyAutomationRunning = true, startLegacyAutomation())); }
        function toggleLegacyArmedState() { isLegacyArmed = !isLegacyArmed; sessionStorage.setItem("territorialAutoStartArmed", isLegacyArmed); updateLegacyDashboardStatus(`Auto-start ${isLegacyArmed ? "ARMED" : "DISARMED"}.`); }
        function startLegacyAutomation() {
            updateLegacyDashboardStatus("Running sequence...");
            autoFillUsername(baseNames)
                .then(() => waitForElementAndClick(findMultiplayerButton, "'Multiplayer' button")) // <-- FIXED
                .then(() => waitForElementAndClick(findReadyButton, "'Ready' button")) // <-- FIXED
                .then(() => { isLegacyAutomationRunning = false; startLegacySpaceSpam(); })
                .catch(error => { isLegacyAutomationRunning = false; updateLegacyDashboardStatus("Error!"); logToHistory(error.message, "error"); });
        }
        function startLegacySpaceSpam() { if (isLegacySpammingActive) return; isLegacySpammingActive = true; updateLegacyDashboardStatus("Spamming Space key every 5s..."); legacySpaceSpamIntervalId = setInterval(() => { document.dispatchEvent(new KeyboardEvent("keydown", { key: " ", code: "Space", keyCode: 32, bubbles: true })); }, 5000); }
        function stopLegacySpaceSpam() { if (!isLegacySpammingActive) return; clearInterval(legacySpaceSpamIntervalId); isLegacySpammingActive = false; updateLegacyDashboardStatus("Idle."); }
        function createLegacyDashboard() { const dashboard = document.createElement("div"); Object.assign(dashboard.style, { position: "fixed", top: "150px", left: "20px", zIndex: "99998", backgroundColor: "rgba(0, 0, 0, 0.75)", color: "white", border: "1px solid #888", borderRadius: "8px", fontFamily: "sans-serif", fontSize: "14px", minWidth: "280px", userSelect: "none" }); const header = document.createElement("div"); Object.assign(header.style, { padding: "8px 12px", backgroundColor: "#333", cursor: "move", borderRadius: "8px 8px 0 0", display: "flex", justifyContent: "space-between" }); header.innerHTML = "<strong>Legacy Auto-Play</strong>"; const content = document.createElement("div"); content.innerHTML = '<ul style="margin: 12px 0 12px 20px; padding: 0; list-style-type: \'» \';"><li><code>F7</code> to arm/disarm auto-start.</li><li><code>F6</code> to start/stop script.</li><li><strong>Status:</strong> <span id="legacy-dashboard-status">Idle</span></li></ul>'; dashboard.appendChild(header); dashboard.appendChild(content); document.body.appendChild(dashboard); makeDraggable(dashboard); }
        function updateLegacyDashboardStatus(text) { const el = document.getElementById("legacy-dashboard-status"); if (el) el.textContent = text; updateStatusInStorage("legacy-dashboard", text); }
    }
    
    // --- GENERIC HELPERS & UTILITIES ---
    function addGlobalStyles(){const style=document.createElement("style");style.textContent=`@keyframes trix-fade-in{from{opacity:0;transform:translate(-50%,-50%) scale(.95)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}#trix-executor-nav-btn:disabled,#trix-server-log-nav-btn:disabled{color:#666;cursor:not-allowed}.trix-nav-button{background:0 0;border:none;color:#ccc;display:block;width:100%;text-align:left;padding:10px 15px;cursor:pointer;font-family:inherit;font-size:14px}.trix-nav-button:hover:not(:disabled){background:#333}.trix-nav-button.active{background:#0e639c;color:#fff}#trix-history .trix-log,#trix-server-log-content .trix-log{margin-bottom:5px}#trix-history .trix-error,#trix-server-log-content .trix-error{color:#f44336}#trix-history .trix-success,#trix-server-log-content .trix-success{color:#4caf50}.featured-script-card{background-color:#2a2d2e;border:1px solid #444;border-radius:4px;padding:15px;display:flex;align-items:center;gap:15px}.featured-script-card img{width:64px;height:64px;border-radius:4px}.featured-script-card .info p{margin:5px 0 10px;font-size:13px;color:#ccc}.featured-script-card button{background:#4caf50;color:#fff;border:none;padding:8px 12px;border-radius:4px;cursor:pointer}.featured-script-card button:disabled{background:#555;cursor:not-allowed}.trix-menu-container{position:relative;display:inline-block;}.trix-menu-button{background:#555;color:white;border:none;padding:4px 10px;border-radius:4px;cursor:pointer;font-family:inherit;}.trix-dropdown-content{display:none;position:absolute;right:0;background-color:#2a2d2e;min-width:120px;box-shadow:0 8px 16px 0 rgba(0,0,0,0.2);z-index:1;border:1px solid #444;border-radius:4px;}.trix-dropdown-content a{color:#ccc;padding:8px 12px;text-decoration:none;display:block;font-size:13px;}.trix-dropdown-content a:hover{background-color:#333;}.trix-menu-button:focus + .trix-dropdown-content, .trix-menu-container:hover .trix-dropdown-content{display:block;}.trix-menu-container:hover .trix-menu-button{background-color:#666;}`,document.head.appendChild(style)}
    function populateChangelog(container){container.innerHTML=`<h3 style="color:white;margin-top:0">Changelog</h3><h4>v32.0.6 - Command System Fix</h4><ul><li>Fixed a critical bug where the Master tab would not execute its own commands.</li></ul><h4>v32.0.5 - Declaration Fix</h4><ul><li>Fixed a 'Identifier has already been declared' error that prevented the Featured Script from running.</li></ul><h4>v32.0.4 - Command System Fix</h4><ul><li>Removed "Targets" input to simplify the UI; all commands target all tabs.</li><li>Fixed the File Menu to be a more reliable, clickable dropdown.</li></ul>`}
    function populateFeaturedScripts(){const container=document.getElementById("trix-page-scripts"),scriptCard=document.createElement("div");scriptCard.className="featured-script-card",scriptCard.innerHTML=`<img src="https://i.postimg.cc/P5w5PX9Z/image.png" alt="Script Logo"><div class="info"><h3>Auto-Join & Play</h3><p>Loads a script with F-key controls, multi-tab "arming", and its own status dashboard.</p><button id="execute-auto-join">Execute</button></div>`,container.appendChild(scriptCard),document.getElementById("execute-auto-join").addEventListener("click",(()=>{if(autoJoinScriptExecuted)return logToHistory("Auto-Join & Play script already running.","error");sendCommandToAgents("execute-legacy",[],999),document.getElementById("execute-auto-join").textContent="Executed ✔",document.getElementById("execute-auto-join").disabled=!0}))}
    function createStatusDashboard(id,title){if(document.getElementById(id))return;const dashboard=document.createElement("div");dashboard.id=id,Object.assign(dashboard.style,{position:"fixed",top:"20px",left:"20px",zIndex:"99999",display:"none",backgroundColor:"rgba(0, 0, 0, 0.75)",color:"white",border:"1px solid #888",borderRadius:"8px",fontFamily:"sans-serif",fontSize:"14px",minWidth:"280px",userSelect:"none"}),dashboard.innerHTML=`<div id="${id}-header" style="padding: 8px 12px; background-color: #333; cursor: move; border-radius: 8px 8px 0 0;"><strong>${title}</strong></div><div style="padding: 12px;"><strong>Status:</strong> <span id="${id}-text">Idle</span></div>`,document.body.appendChild(dashboard),makeDraggable(dashboard)}
    function setupCommandPrompt(){const input=document.getElementById("trix-cmd-input"),sendBtn=document.getElementById("trix-send-btn"),handler=()=>{input.value.trim()&&(handleCommand(input.value),input.value="")};input.addEventListener("keydown",(e=>{if("Enter"===e.key)handler()})),sendBtn.addEventListener("click",handler)}
    function setupSidebarNavigation(){document.querySelectorAll(".trix-nav-button").forEach(button=>{button.addEventListener("click",()=>{if(button.disabled)return;document.querySelectorAll(".trix-nav-button").forEach(btn=>btn.classList.remove("active")),button.classList.add("active");const pageId=`trix-page-${button.dataset.page}`;document.querySelectorAll(".trix-page").forEach(page=>{page.style.display=page.id===pageId?(page.id.includes("cmd")||page.id.includes("executor")?"flex":"block"):"none"})})})}
    function logToServerPanel(message,type="log"){if(!isMaster)return;const logContent=document.getElementById("trix-server-log-content");if(!logContent)return;const entry=document.createElement("div");entry.className=`trix-${type}`;const timestamp=(new Date).toLocaleTimeString();entry.innerHTML=`<span style="color: #888;">[${timestamp}]</span> ${message}`,logContent.appendChild(entry),logContent.scrollTop=logContent.scrollHeight}
    function autoFillUsername(nameList = baseNames) { return new Promise((resolve, reject) => { waitForElement(findUsernameInput, "Username Input Field").then(nameInput => { const username = nameList[Math.floor(Math.random() * nameList.length)]; updateStatusInStorage("trix-status-dashboard", `Setting name: ${username}`); nameInput.value = username; nameInput.dispatchEvent(new Event("input", { bubbles: true, cancelable: true })); nameInput.focus(); nameInput.blur(); setTimeout(resolve, 200); }).catch(reject); }); }
    function logToHistory(message, type = "log") { const history = document.getElementById("trix-history"); if (!history) return; const entry = document.createElement("div"); entry.className = `trix-${type}`; entry.textContent = message; history.appendChild(entry); history.scrollTop = history.scrollHeight; }
    function updateStatusInStorage(dashboardId, text) { localStorage.setItem("trix-status", JSON.stringify({ id: dashboardId, text: text, ts: Date.now() })); }
    function parseTimeInterval(timeString) { if (!timeString) return null; const match = timeString.match(/^(\d+)(s|min)$/); if (!match) return null; let seconds = parseInt(match[1], 10); if (match[2] === 'min') { seconds *= 60; } return (seconds > 599 || seconds <= 0) ? null : seconds * 1000; }
    function makeDraggable(element) { let isDragging = false, offsetX, offsetY; const handle = element; handle.onmousedown = e => { if (e.target !== handle && !e.target.closest("#trix-header")) return; e.preventDefault(); isDragging = true; offsetX = e.clientX - element.offsetLeft; offsetY = e.clientY - element.offsetTop; document.onmousemove = e => { if (isDragging) { element.style.left = `${e.clientX - offsetX}px`; element.style.top = `${e.clientY - offsetY}px`; } }; document.onmouseup = () => { isDragging = false; document.onmousemove = document.onmouseup = null; }; }; }
    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 document.title.toLowerCase().includes("territorial.io"); }
    function waitForElement(findFunction, description) { return new Promise((resolve, reject) => { let attempts = 0, maxAttempts = 75; const interval = setInterval(() => { if (attempts++ >= maxAttempts) { clearInterval(interval); reject(new Error(`Timed out: ${description}`)); } const element = findFunction(); if (element) { clearInterval(interval); resolve(element); } }, 200); }); }
    function waitForElementAndClick(findFunction, description) { return waitForElement(findFunction, description).then(element => element.click()); } // <-- RESTORED
    const findUsernameInput = () => document.getElementById("input0");
    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"));
    function startTrixAutomation() { updateStatusInStorage("trix-status-dashboard", "Running sequence..."); autoFillUsername().then(() => waitForElementAndClick(findMultiplayerButton, "'Multiplayer' button")).then(() => waitForElementAndClick(findReadyButton, "'Ready' button")).then(() => { trixAutomationRunning = false; updateStatusInStorage("trix-status-dashboard", "Sequence Complete."); }).catch(error => { trixAutomationRunning = false; updateStatusInStorage("trix-status-dashboard", "Error!"); logToHistory(error.message, "error"); }); }
    function startTrixSpaceSpam(intervalMs) { if (trixSpammingActive) return; trixSpammingActive = true; updateStatusInStorage("trix-status-dashboard", `Spamming...`); trixSpaceSpamIntervalId = setInterval(() => { document.dispatchEvent(new KeyboardEvent("keydown", { key: " ", code: "Space", keyCode: 32, bubbles: true })); }, intervalMs); }
    function stopTrixSpaceSpam() { if (!trixSpammingActive) return; clearInterval(trixSpaceSpamIntervalId); trixSpammingActive = false; updateStatusInStorage("trix-status-dashboard", "Spam Stopped."); }
    function initialize() { waitForElement(findUsernameInput, "Game UI to load", 50).then(() => { isMasterTab() ? becomeMaster() : becomeAgent(); }).catch(() => {}); }
    function isMasterTab() { const heartbeat = localStorage.getItem("trix-master-heartbeat"); return !heartbeat || (Date.now() - heartbeat > 4000); }
    function becomeAgent() { console.log("[TriX] Master detected. Initializing as Agent."); setupStorageListener(); setupTabCounter(); }
    function becomeMaster() { console.log("[TriX] No master detected. Initializing as Master."); isMaster = true; createExecutorUI(); createStatusDashboard("trix-status-dashboard", "TriX Automation Status"); setupStorageListener(); setupTabCounter(); }
    initialize();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址