TerriX Executor v2.4

Advanced Script Hub for Territorial.io. Automation, ESP, and Strategy Testing.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         TerriX Executor v2.4
// @namespace    http://tampermonkey.net/
// @version      2.4
// @description  Advanced Script Hub for Territorial.io. Automation, ESP, and Strategy Testing.
// @author       Assistant
// @match        *://territorial.io/*
// @match        *://everythingtt.github.io/TerriX-Client/*
// @match        file:///*/*.html
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    const CLIENT_URL = "https://everythingtt.github.io/TerriX-Client/Territorial.io.html";

    // --- 1. CORE HOOK LOGIC ---
    let leakedAg = null, leakedAd = null, myDetectedId = -1;
    Object.defineProperty(Object.prototype, 'h7', {
        set: function(v) { this._h7 = v; if (this.gt && this.zU && !leakedAg) leakedAg = this; },
        get: function() { return this._h7; },
        configurable: true
    });
    Object.defineProperty(Object.prototype, 'ep', {
        set: function(v) { this._ep = v; myDetectedId = v; if (this.f2 === 512 && !leakedAd) leakedAd = this; },
        get: function() { return this._ep; },
        configurable: true
    });

    const resolveMyId = () => {
        if (window.G && window.G.aD) return window.G.aD.ep;
        return myDetectedId;
    };

    // --- 2. SCRIPT LIBRARY ---
    const SCRIPT_LIB = {
        AutoColonize: `/* Auto-Colonizer: Expands to neutral land automatically */
if(!window.tx_loop) {
    window.tx_loop = setInterval(() => {
        const { ag, aD, b8 } = window.G;
        const myId = aD.ep;
        const neutral = aD.f2;
        // Expand if troops > 2000 and we have territory
        if (ag.h7[myId] > 2000 && ag.gt[myId] > 0) {
            console.log("TerriX: Auto-Expanding...");
            b8.hV.hc(250, neutral); // Send 25% (250/1024)
        }
    }, 1500);
    alert("Auto-Colonizer Active");
} else { clearInterval(window.tx_loop); window.tx_loop = null; alert("Auto-Colonizer Disabled"); }`,

        FullESP: `/* Fog of War ESP: Log all enemy stats to console */
const { ag, aD } = window.G;
console.log("--- FOG OF WAR BYPASS ---");
for(let i=0; i<aD.f2; i++) {
    if(ag.mz[i] !== 0 && i !== aD.ep) {
        console.log(\`[#\${i}] \${ag.zU[i]} | Troops: \${ag.h7[i]} | Pixels: \${ag.gt[i]}\`);
    }
}
alert("Enemy data dumped to Console (F12)");`,

        SpeedHack: `/* Game Speed Modifier (Single Player) */
const val = prompt("Enter tick speed in MS (Default 56):", "10");
window.G.bf.aCP = parseInt(val);`
    };

    // --- 3. UI STYLES ---
    const style = document.createElement('style');
    style.innerHTML = `
        #tx-wrapper { position: fixed; top: 0; left: 0; width: 0; height: 0; z-index: 2147483647; font-family: 'system-ui', sans-serif; }
        #tx-gui {
            position: fixed; top: 100px; left: 100px; width: 650px; height: 450px;
            background: rgba(0, 0, 0, 0.9); border: 1.8px solid white; 
            display: none; flex-direction: column; color: white; overflow: hidden;
            box-shadow: 10px 10px 0px rgba(0,0,0,0.5);
        }
        #tx-header { padding: 8px 15px; background: rgba(40, 40, 40, 0.9); display: flex; justify-content: space-between; cursor: move; border-bottom: 1.8px solid white; font-weight: bold; font-size: 14px; }
        #tx-body { display: flex; flex: 1; overflow: hidden; }
        #tx-sidebar { width: 150px; background: rgba(20, 20, 20, 0.9); border-right: 1.8px solid white; padding: 10px; display: flex; flex-direction: column; gap: 8px; }
        #tx-main { flex: 1; display: flex; flex-direction: column; padding: 12px; background: black; position: relative; }
        #tx-editor { flex: 1; background: #050505; color: #00ff00; border: 1.8px solid #444; padding: 10px; font-family: monospace; resize: none; outline: none; font-size: 12px; }
        
        .tx-btn { padding: 6px; background: rgba(60, 60, 60, 0.85); border: 1.8px solid white; color: white; cursor: pointer; font-size: 10px; font-weight: bold; text-align: center; }
        .tx-btn:hover { background: rgba(100, 100, 100, 0.9); }
        .tx-btn.active { background: rgb(0, 100, 0); }
        .tx-btn.hook-btn { background: rgb(70, 50, 20); margin-top: auto; }
        .tx-btn.exec-btn { background: rgb(0, 80, 0); padding: 10px; font-size: 13px; }
        
        #tx-toggle { position: fixed; top: 0; left: 50%; transform: translateX(-50%); padding: 4px 20px; background: rgba(0, 80, 0, 0.9); color: white; border: 1.8px solid white; border-top: none; border-radius: 0 0 5px 5px; cursor: pointer; font-weight: bold; font-size: 12px; z-index: 1000002; }

        #tx-chart, #tx-scripts { display: none; flex: 1; flex-direction: column; gap: 4px; overflow-y: auto; }
        .script-card { background: #111; border: 1.2px solid #555; padding: 10px; margin-bottom: 5px; display: flex; justify-content: space-between; align-items: center; }
        .script-title { font-weight: bold; font-size: 12px; color: #3a47ff; }

        .bar-row { display: flex; align-items: center; gap: 8px; height: 24px; width: 100%; flex-shrink: 0; }
        .bar-rank { width: 30px; font-size: 11px; color: #aaa; text-align: right; font-weight: bold; }
        .bar-name { width: 130px; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .bar-track { flex: 1; background: #222; height: 14px; border: 1px solid #444; position: relative; }
        .bar-fill { height: 100%; width: 0%; background: #228B22; transition: width 0.3s ease; }
        .bar-val { position: absolute; right: 5px; top: 0px; font-size: 9px; color: white; line-height: 14px; font-weight: bold;}
        .me-row .bar-name { color: #ffd700; }
        .me-row .bar-fill { background: #ffd700; border: 1px solid white; }
    `;
    document.documentElement.appendChild(style);

    // --- 4. UI CONSTRUCTION ---
    const wrapper = document.createElement('div');
    wrapper.id = 'tx-wrapper';
    document.documentElement.appendChild(wrapper);

    const render = () => {
        wrapper.innerHTML = `
            <div id="tx-toggle">TERRIX MENU</div>
            <div id="tx-gui">
                <div id="tx-header"><span>TERRIX <span style="color:#3a47ff">CONTROL</span></span> <span id="tx-close" style="cursor:pointer">✕</span></div>
                <div id="tx-body">
                    <div id="tx-sidebar">
                        <button class="tx-btn active" id="nav-editor">EDITOR</button>
                        <button class="tx-btn" id="nav-chart">POWER INDEX</button>
                        <button class="tx-btn" id="nav-scripts">SCRIPTS</button>
                        <button class="tx-btn hook-btn" id="tx-hook">INJECT HOOK</button>
                    </div>
                    <div id="tx-main">
                        <textarea id="tx-editor" spellcheck="false">/* TerriX Advanced Executor */</textarea>
                        <div id="tx-chart"></div>
                        <div id="tx-scripts">
                            <div class="script-card"><span class="script-title">Auto-Colonizer</span><button class="tx-btn" onclick="tx_load('AutoColonize')">LOAD</button></div>
                            <div class="script-card"><span class="script-title">Fog-of-War ESP</span><button class="tx-btn" onclick="tx_load('FullESP')">LOAD</button></div>
                            <div class="script-card"><span class="script-title">Speed Hack</span><button class="tx-btn" onclick="tx_load('SpeedHack')">LOAD</button></div>
                        </div>
                    </div>
                </div>
                <div style="padding: 10px 20px; background: rgba(20,20,20,1); display: flex; justify-content: space-between; align-items: center; border-top: 1.8px solid white;">
                    <button class="tx-btn exec-btn" id="tx-execute">EXECUTE</button>
                    <div id="tx-info" style="font-size: 10px; color: #888;">ID: <span id="tx-id-val">?</span></div>
                </div>
            </div>
        `;
        setupLogic();
    };

    window.tx_load = (key) => {
        document.getElementById('tx-editor').value = SCRIPT_LIB[key];
        document.getElementById('nav-editor').click();
    };

    const setupLogic = () => {
        const gui = document.getElementById('tx-gui');
        const toggle = document.getElementById('tx-toggle');
        const editor = document.getElementById('tx-editor');
        const chart = document.getElementById('tx-chart');
        const scriptTab = document.getElementById('tx-scripts');
        const hookBtn = document.getElementById('tx-hook');

        toggle.onclick = () => gui.style.display = gui.style.display === 'flex' ? 'none' : 'flex';
        document.getElementById('tx-close').onclick = () => gui.style.display = 'none';

        const tabs = [editor, chart, scriptTab];
        const buttons = ['nav-editor', 'nav-chart', 'nav-scripts'];

        buttons.forEach((btnId, i) => {
            document.getElementById(btnId).onclick = function() {
                buttons.forEach(id => document.getElementById(id).classList.remove('active'));
                tabs.forEach(t => t.style.display = 'none');
                this.classList.add('active');
                tabs[i].style.display = 'flex';
                if(i===0) tabs[i].style.display = 'block';
            };
        });

        hookBtn.onclick = function() {
            if (leakedAg) {
                window.G = { ag: leakedAg, aD: leakedAd || { f2: 512, ep: myDetectedId }, b8: window.b8, bf: window.bf };
                this.innerText = "HOOKED";
                this.style.background = "#228B22";
            } else {
                alert("Game engine not detected. If on Official site, switch to TerriX Client on GitHub.");
            }
        };

        document.getElementById('tx-execute').onclick = () => {
            try { eval(editor.value); } catch(e) { alert(e); }
        };

        // Draggable
        let drag = false, x, y;
        document.getElementById('tx-header').onmousedown = (e) => { drag = true; x = e.clientX - gui.offsetLeft; y = e.clientY - gui.offsetTop; };
        window.onmousemove = (e) => { if (drag) { gui.style.left = (e.clientX - x) + 'px'; gui.style.top = (e.clientY - y) + 'px'; } };
        window.onmouseup = () => drag = false;
    };

    render();

    // --- 5. LEADERBOARD ENGINE ---
    const barCache = {};
    setInterval(() => {
        const chart = document.getElementById('tx-chart');
        if (!chart || chart.style.display !== 'flex' || !window.G) return;
        const { ag } = window.G;
        const myId = resolveMyId();
        document.getElementById('tx-id-val').innerText = myId;

        let players = [];
        for (let i = 0; i < 512; i++) {
            if (ag.gt[i] > 0) {
                const score = (ag.gt[i] * 10) + (ag.h7[i] / 50);
                players.push({ id: i, name: ag.zU[i] || "Bot", val: score, isMe: i === myId });
            }
        }
        players.sort((a, b) => b.val - a.val);
        const top = players.slice(0, 15);
        const max = top[0]?.val || 1;

        top.forEach((p, idx) => {
            if (!barCache[p.id]) {
                const row = document.createElement('div');
                row.className = 'bar-row';
                row.innerHTML = `<div class="bar-rank"></div><div class="bar-name"></div><div class="bar-track"><div class="bar-fill"></div><span class="bar-val"></span></div>`;
                chart.appendChild(row);
                barCache[p.id] = row;
            }
            const row = barCache[p.id];
            row.style.display = 'flex';
            row.style.order = idx;
            if (p.isMe) row.classList.add('me-row'); else row.classList.remove('me-row');
            row.querySelector('.bar-rank').innerText = `#${idx + 1}`;
            row.querySelector('.bar-name').innerText = p.name;
            row.querySelector('.bar-fill').style.width = (p.val / max * 100) + '%';
            row.querySelector('.bar-val').innerText = Math.floor(p.val).toLocaleString();
        });
        Object.keys(barCache).forEach(id => { if (!top.find(p => p.id == id)) barCache[id].style.display = 'none'; });
    }, 500);

})();