TerriX Executor v2.3

Roblox-style Executor. Now recommends the pre-hooked TerriX-Client on GitHub Pages.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

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

Tendrás que instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Tendrás que instalar una extensión como Tampermonkey antes de poder instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         TerriX Executor v2.3
// @namespace    http://tampermonkey.net/
// @version      10.3
// @description  Roblox-style Executor. Now recommends the pre-hooked TerriX-Client on GitHub Pages.
// @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. THE TRAP ---
    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 = (ag) => {
        if (leakedAd && typeof leakedAd.ep !== 'undefined') return leakedAd.ep;
        const input = document.getElementById('input0');
        const myName = input ? input.value.trim() : "";
        if (myName && ag && ag.zU) {
            for (let i = 0; i < 512; i++) if (ag.zU[i] === myName && ag.mz[i] !== 0) return i;
        }
        return myDetectedId;
    };

    // --- 2. 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: 600px; height: 420px;
            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; text-transform: uppercase; letter-spacing: 1px; }
        #tx-body { display: flex; flex: 1; overflow: hidden; }
        #tx-sidebar { width: 140px; 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; }
        #tx-editor { flex: 1; background: rgba(10, 10, 10, 1); 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-btn.client-btn { background: #3a47ff; border-color: #777; font-size: 9px; animation: glow 2s infinite; }

        @keyframes glow { 0% {box-shadow: 0 0 5px #3a47ff;} 50% {box-shadow: 0 0 15px #3a47ff;} 100% {box-shadow: 0 0 5px #3a47ff;} }

        #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 { display: none; flex: 1; flex-direction: column; gap: 4px; overflow-y: auto; }
        .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: 120px; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #ddd; }
        .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; text-shadow: 1px 1px 1px black;}
        .me-row .bar-name { color: #ffd700; }
        .me-row .bar-fill { background: #ffd700; border: 1px solid white; }
        .me-row .bar-val { color: black; text-shadow: none; }
    `;
    document.documentElement.appendChild(style);

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

    const render = () => {
        wrapper.innerHTML = `
            <div id="tx-toggle">TERRIX EXECUTOR</div>
            <div id="tx-gui">
                <div id="tx-header"><span>TERRIX <span style="color:#3a47ff">CLIENT</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>
                        <a href="${CLIENT_URL}" target="_blank" style="text-decoration:none">
                            <button class="tx-btn client-btn">🚀 USE TERRIX CLIENT</button>
                        </a>
                        <button class="tx-btn hook-btn" id="tx-hook">INJECT HOOK</button>
                    </div>
                    <div id="tx-main">
                        <textarea id="tx-editor" spellcheck="false">/* TerriX 2.3 Ready */
// Pre-hooked Client detected: window.G is fully available.</textarea>
                        <div id="tx-chart"></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 style="font-size: 10px; color: #888;">
                        SCOPE: <span id="tx-stat" style="color:#f33">UNHOOKED</span>
                    </div>
                </div>
            </div>
        `;
        setupLogic();
    };

    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 hookBtn = document.getElementById('tx-hook');
        const stat = document.getElementById('tx-stat');

        // Auto-Hook if on TerriX-Client (Github Pages)
        if (window.location.hostname.includes("github.io") || window.l) {
            setTimeout(() => {
                if (window.l && window.aD) {
                    window.G = { l, aD, ag, bS, b8, bf, al, ad, t, bC };
                    hookBtn.innerText = "CLIENT CONNECTED";
                    hookBtn.style.background = "#228B22";
                    stat.innerText = "TERRIX-CLIENT";
                    stat.style.color = "#00ff00";
                }
            }, 1000);
        }

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

        document.getElementById('nav-editor').onclick = function() {
            this.classList.add('active'); document.getElementById('nav-chart').classList.remove('active');
            editor.style.display = 'block'; chart.style.display = 'none';
        };
        document.getElementById('nav-chart').onclick = function() {
            this.classList.add('active'); document.getElementById('nav-editor').classList.remove('active');
            editor.style.display = 'none'; chart.style.display = 'flex';
        };

        hookBtn.onclick = function() {
            if (window.G) return;
            if (leakedAg) {
                window.G = { ag: leakedAg, aD: leakedAd || { f2: 512, ep: myDetectedId } };
                this.innerText = "HOOKED";
                this.style.background = "#228B22";
                stat.innerText = "INJECTED";
                stat.style.color = "#00ff00";
            } else {
                const choice = confirm("IIFE Hook failed on this domain.\n\nWould you like to switch to the TerriX Pro Client? (Supports all features & God Mode)");
                if (choice) window.open(CLIENT_URL, "_blank");
            }
        };

        document.getElementById('tx-execute').onclick = () => {
            if (!window.G) return alert("You must Hook or use TerriX Client first.");
            try { eval(editor.value); } catch(e) { alert(e); }
        };

        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();

    // --- 4. CHART ENGINE ---
    const barCache = {};
    setInterval(() => {
        const chart = document.getElementById('tx-chart');
        if (!chart || chart.style.display !== 'flex' || !window.G) return;

        const { ag } = window.G;
        const myActualId = resolveMyId(ag);

        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] || "Unknown", val: score, isMe: i === myActualId });
            }
        }
        players.sort((a, b) => b.val - a.val);
        const top = players.slice(0, 14);
        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);

})();