BloxdAura

KillAura for bloxd.io

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         BloxdAura
// @namespace    bloxd-aura
// @version      1.0.0
// @description  KillAura for bloxd.io
// @author       pentest
// @match        https://*.bloxd.io/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    let settings = {
        enabled: false,
        range: 6,
        attackSpeed: 150, // ms between attacks
        attackKey: 'R'    // toggle key
    };

    // UI
    let uiContainer = null;
    let statusDot = null;
    let toggleBtn = null;

    // Internal refs
    let gameAPI = null;
    let lastAttackTime = 0;
    let auraInterval = null;
    let targetScanInterval = null;
    let currentTarget = null;
    let initialized = false;

    // ─── Find game internals dynamically ────────────────────────────
    function findGameAPI() {
        // Try multiple paths to find the game's internal API
        // Using the bloxd global object that the game exposes
        if (window.bloxd && window.bloxd.noa) {
            let noa = window.bloxd.noa;
            // Check for entity system
            if (noa.entities) {
                return { noa, bloxd: window.bloxd };
            }
        }
        // Fallback: traverse game canvas
        if (window.gameInstance && window.gameInstance.noa) {
            return { noa: window.gameInstance.noa, bloxd: window.gameInstance };
        }
        return null;
    }

    // ─── Entity discovery ──────────────────────────────────────────
    function getOtherPlayers() {
        if (!gameAPI) return [];
        try {
            let players = [];
            let state = gameAPI.noa.entities.getState();
            if (!state) return [];

            let myId = gameAPI.bloxd.playerId || 1;

            for (let [eid, entity] of Object.entries(state)) {
                if (!entity || eid == myId) continue;
                
                // Check if it's a player (has position, is alive)
                if (entity.position && entity.breath !== undefined) {
                    players.push({
                        eid: parseInt(eid),
                        entity: entity,
                        pos: entity.position
                    });
                }
            }
            return players;
        } catch(e) {
            return [];
        }
    }

    function distanceTo(pos) {
        if (!gameAPI || !gameAPI.noa) return Infinity;
        try {
            let cam = gameAPI.noa.camera;
            if (!cam) return Infinity;
            let dx = pos[0] - cam[0],
                dy = pos[1] - cam[1],
                dz = pos[2] - cam[2];
            return Math.sqrt(dx*dx + dy*dy + dz*dz);
        } catch(e) {
            return Infinity;
        }
    }

    // ─── Attack ───────────────────────────────────────────────────
    function attackEntity(eid) {
        if (!gameAPI) return false;
        try {
            let noa = gameAPI.noa;
            
            // Method 1: Direct entity attack if available
            if (noa.entities && typeof noa.entities.doAttack === 'function') {
                noa.entities.doAttack(eid);
                return true;
            }
            
            // Method 2: Look for attack on the specific entity
            let state = noa.entities.getState();
            if (state && state[eid]) {
                let ent = state[eid];
                if (typeof ent.doAttack === 'function') {
                    ent.doAttack(eid);
                    return true;
                }
                // Check breakingItem chain
                if (ent.breakingItem && typeof ent.breakingItem.doAttack === 'function') {
                    ent.breakingItem.doAttack(eid);
                    return true;
                }
            }
            
            // Method 3: Try the game's internal attack method through the container
            if (noa.entities._eidData && noa.entities._eidData[eid]) {
                let data = noa.entities._eidData[eid];
                if (data.mesh && data.mesh.doAttack) {
                    data.mesh.doAttack(eid);
                    return true;
                }
            }

            // Method 4: Send through game container
            let ecs = noa.entities;
            if (ecs.attackEntity) {
                ecs.attackEntity(eid);
                return true;
            }

            return false;
        } catch(e) {
            return false;
        }
    }

    function findAndAttackBestTarget() {
        if (!gameAPI || !settings.enabled) return;
        
        let now = Date.now();
        if (now - lastAttackTime < settings.attackSpeed) return;

        let players = getOtherPlayers();
        if (!players.length) return;

        let best = null;
        let bestDist = settings.range;

        for (let p of players) {
            let d = distanceTo(p.pos);
            if (d < bestDist) {
                bestDist = d;
                best = p;
            }
        }

        if (best) {
            currentTarget = best;
            lastAttackTime = now;
            attackEntity(best.eid);
        } else {
            currentTarget = null;
        }
    }

    // ─── UI ────────────────────────────────────────────────────────
    function createUI() {
        if (uiContainer) return;

        uiContainer = document.createElement('div');
        uiContainer.id = 'bloxd-aura-ui';
        uiContainer.style.cssText = `
            position: fixed; top: 8px; right: 8px; z-index: 999999;
            font-family: 'Segoe UI', Arial, sans-serif;
            background: rgba(10,10,10,0.85);
            border: 1px solid rgba(255,255,255,0.1);
            border-radius: 8px;
            padding: 10px 14px;
            color: #eee;
            font-size: 13px;
            user-select: none;
            backdrop-filter: blur(4px);
            min-width: 160px;
            pointer-events: auto;
        `;

        // Header row
        let header = document.createElement('div');
        header.style.cssText = 'display:flex;align-items:center;gap:8px;margin-bottom:6px;font-weight:600;';

        statusDot = document.createElement('span');
        statusDot.style.cssText = `
            display:inline-block;width:10px;height:10px;border-radius:50%;
            background:#666;transition:background 0.2s;
        `;

        let title = document.createElement('span');
        title.textContent = 'Aura';

        let keyHint = document.createElement('span');
        keyHint.style.cssText = 'font-size:10px;color:#888;margin-left:auto;';
        keyHint.textContent = `[${settings.attackKey}]`;

        header.appendChild(statusDot);
        header.appendChild(title);
        header.appendChild(keyHint);

        // Info row
        let info = document.createElement('div');
        info.style.cssText = 'font-size:11px;color:#999;';
        info.textContent = '±' + settings.range + 'm';

        uiContainer.appendChild(header);
        uiContainer.appendChild(info);

        // Toggle on click
        uiContainer.addEventListener('click', function(e) {
            e.stopPropagation();
            toggle();
        });

        document.body.appendChild(uiContainer);
    }

    function updateUI() {
        if (!statusDot) return;
        if (settings.enabled) {
            statusDot.style.background = '#ff4444';
            statusDot.style.boxShadow = '0 0 6px #ff4444';
        } else {
            statusDot.style.background = '#666';
            statusDot.style.boxShadow = 'none';
        }
    }

    // ─── Control ───────────────────────────────────────────────────
    function enable() {
        settings.enabled = true;
        updateUI();
        
        if (targetScanInterval) clearInterval(targetScanInterval);
        if (auraInterval) clearInterval(auraInterval);

        // Scan for targets and attack on a timer
        auraInterval = setInterval(() => {
            findAndAttackBestTarget();
        }, Math.min(settings.attackSpeed, 100));
    }

    function disable() {
        settings.enabled = false;
        if (auraInterval) {
            clearInterval(auraInterval);
            auraInterval = null;
        }
        if (targetScanInterval) {
            clearInterval(targetScanInterval);
            targetScanInterval = null;
        }
        currentTarget = null;
        updateUI();
    }

    function toggle() {
        if (settings.enabled) {
            disable();
        } else {
            enable();
        }
    }

    // ─── Keybind ───────────────────────────────────────────────────
    function onKeyDown(e) {
        if (e.key.toUpperCase() === settings.attackKey && 
            !e.ctrlKey && !e.altKey && !e.metaKey &&
            !e.target.matches('input, textarea, [contenteditable]')) {
            e.preventDefault();
            toggle();
        }
    }

    // ─── Init ──────────────────────────────────────────────────────
    function init() {
        if (initialized) return;

        // Try to find game API immediately
        gameAPI = findGameAPI();

        if (!gameAPI) {
            // Wait for game to load — poll
            let attempts = 0;
            let h = setInterval(() => {
                attempts++;
                gameAPI = findGameAPI();
                if (gameAPI || attempts > 30) {
                    clearInterval(h);
                    if (gameAPI) {
                        initialized = true;
                        setup();
                    }
                }
            }, 500);
            return;
        }

        initialized = true;
        setup();
    }

    function setup() {
        createUI();
        updateUI();
        document.addEventListener('keydown', onKeyDown);
        console.log('[Aura] Ready — press ' + settings.attackKey + ' to toggle');
    }

    // Start
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

    // Expose for debugging
    window.__aura = {
        toggle,
        enable,
        disable,
        getSettings: () => ({...settings}),
        setRange: (r) => { settings.range = Math.max(1, Math.min(20, r)); },
        setSpeed: (s) => { settings.attackSpeed = Math.max(50, Math.min(1000, s)); }
    };

})();