// ==UserScript==
// @name TriX Executor for Territorial.io
// @namespace Violentmonkey Scripts
// @version 32.0.6
// @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="block"===fileDropdown.style.display?"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=!1,document.getElementById("trix-server-log-nav-btn").disabled=!1,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(" ");if("/help"===cmd)return 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."),void logToHistory("/detach - Removes custom script handle from the F12 console.");sendCommandToAgents(cmd.substring(1),args,999)}
function executeCustomScript(scriptText=null){scriptText=scriptText??document.getElementById("trix-script-input").value;if(""===scriptText.trim())return logToHistory("Script input is empty.","error");logToHistory("Executing custom script...");try{window.trixHandle=new Function(scriptText)(),logToHistory("Script attached. Use 'trixHandle' in F12 console to manage.","success"),logToServerPanel("[200 OK] Script attached to window.trixHandle.","success")}catch(e){logToServerPanel(`[500 ERROR] ${e.message}`,"error"),console.error("Custom Script Error:",e)}}
// --- CROSS-TAB COMMUNICATION ---
function sendCommandToAgents(command,args=[],targetCount=999){const payload={cmd:command,args:args,targetCount: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=!1;const frame=document.getElementById("trix-frame");frame&&(frame.style.display="none")}}if("trix-command"===e.key&&e.newValue){const payload=JSON.parse(e.newValue);shouldIExecute(payload).then(doExecute=>{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))}),2e3),window.addEventListener("beforeunload",(()=>{const heartbeats=JSON.parse(localStorage.getItem("trix-agent-heartbeats")||"{}");delete heartbeats[tabId],localStorage.setItem("trix-agent-heartbeats",JSON.stringify(heartbeats))})),isMaster&&(setInterval((()=>{localStorage.setItem("trix-master-heartbeat",Date.now())}),2e3),setInterval((()=>{const heartbeats=JSON.parse(localStorage.getItem("trix-agent-heartbeats")||"{}");let activeCount=0;for(const id in heartbeats)Date.now()-heartbeats[id]<5e3?activeCount++:delete heartbeats[id];localStorage.setItem("trix-agent-heartbeats",JSON.stringify(heartbeats));const counterEl=document.getElementById("trix-tab-counter");counterEl&&(counterEl.textContent=`Tabs: ${activeCount}`)}),1e3),window.addEventListener("beforeunload",(()=>{localStorage.removeItem("trix-master-heartbeat")})))}
function shouldIExecute(payload){return new Promise((resolve=>{let attempts=0;const tryLock=setInterval((()=>{if(attempts++>100)return clearInterval(tryLock),void resolve(!1);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);count<payload.targetCount?(localStorage.setItem(counterKey,count+1),localStorage.removeItem("trix-exec-lock"),clearInterval(tryLock),resolve(!0)):(localStorage.removeItem("trix-exec-lock"),clearInterval(tryLock),resolve(!1))}),50)}))}
function executeReceivedCommand(payload){logToHistory(`Executing command: ${payload.cmd}`);switch(payload.cmd){case"auto-join":trixAutomationRunning||(trixAutomationRunning=!0,startTrixAutomation());break;case"spam":startTrixSpaceSpam(payload.args[0]);break;case"stop":stopTrixSpaceSpam();break;case"detach":window.trixHandle&&(delete window.trixHandle,logToHistory("Handle detached."));break;case"execute-legacy":autoJoinScriptExecuted||executeAutoJoinAndPlayScript();break;case"execute-custom":executeCustomScript(payload.args[0]);break}}
// --- FEATURED SCRIPT LOADER ---
function executeAutoJoinAndPlayScript(){autoJoinScriptExecuted=!0,logToHistory("Executing Auto-Join & Play script...","success");let isLegacyAutomationRunning=!1,isLegacySpammingActive=!1,legacySpaceSpamIntervalId=null,isLegacyArmed="true"===sessionStorage.getItem("territorialAutoStartArmed");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=!0,startLegacyAutomation()}}));function toggleLegacyManualSequence(){isLegacySpammingActive?stopLegacySpaceSpam():isLegacyAutomationRunning||(isLegacyAutomationRunning=!0,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")).then(()=>waitForElementAndClick(findReadyButton,"'Ready' button")).then(()=>{isLegacyAutomationRunning=!1,startLegacySpaceSpam()}).catch((error=>{isLegacyAutomationRunning=!1,updateLegacyDashboardStatus("Error!"),logToHistory(error.message,"error")}))}function startLegacySpaceSpam(){if(isLegacySpammingActive)return;isLegacySpammingActive=!0,updateLegacyDashboardStatus("Spamming Space key every 5s...");legacySpaceSpamIntervalId=setInterval((()=>{document.dispatchEvent(new KeyboardEvent("keydown",{key:" ",code:"Space",keyCode:32,bubbles:!0}))}),5e3)}function stopLegacySpaceSpam(){if(!isLegacySpammingActive)return;clearInterval(legacySpaceSpamIntervalId),isLegacySpammingActive=!1,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");el&&(el.textContent=text);updateStatusInStorage("legacy-dashboard",text)}}
// --- GENERIC HELPERS & UTILITIES ---
function saveScriptToFile(){const scriptText=document.getElementById("trix-script-input").value;if(""===scriptText.trim())return logToHistory("Cannot save an empty script.","error");const blob=new Blob([scriptText],{type:"text/plain;charset=utf-8"}),now=new Date,pad=num=>num.toString().padStart(2,"0"),timestamp=`${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())}_${pad(now.getHours())}-${pad(now.getMinutes())}-${pad(now.getSeconds())}`,filename=`trix_script_${timestamp}.txt`,link=document.createElement("a");link.href=URL.createObjectURL(blob),link.download=filename,document.body.appendChild(link),link.click(),document.body.removeChild(link),URL.revokeObjectURL(link.href),logToHistory(`Script saved as ${filename}`,"success")}
function openScriptFromFile(){const input=document.createElement("input");input.type="file",input.accept=".txt,.js,.script",input.onchange=e=>{const file=e.target.files[0];if(!file)return;const reader=new FileReader;reader.onload=event=>{document.getElementById("trix-script-input").value=event.target.result,logToHistory(`Loaded script: ${file.name}`,"success")},reader.readAsText(file)},input.click()}
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 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 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 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 startTrixAutomation(){updateStatusInStorage("trix-status-dashboard","Running sequence..."),autoFillUsername().then(()=>waitForElementAndClick(findMultiplayerButton,"'Multiplayer' button")).then(()=>waitForElementAndClick(findReadyButton,"'Ready' button")).then(()=>{trixAutomationRunning=!1,updateStatusInStorage("trix-status-dashboard","Sequence Complete.")}).catch(error=>{trixAutomationRunning=!1,updateStatusInStorage("trix-status-dashboard","Error!"),logToHistory(error.message,"error")})}
function startTrixSpaceSpam(intervalMs){if(trixSpammingActive)return;trixSpammingActive=!0,updateStatusInStorage("trix-status-dashboard",`Spamming...`),trixSpaceSpamIntervalId=setInterval(()=>{document.dispatchEvent(new KeyboardEvent("keydown",{key:" ",code:"Space",keyCode:32,bubbles:!0}))},intervalMs)}
function stopTrixSpaceSpam(){if(!trixSpammingActive)return;clearInterval(trixSpaceSpamIntervalId),trixSpammingActive=!1,updateStatusInStorage("trix-status-dashboard","Spam Stopped.")}
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); }); }
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 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();
})();