BloxdAura

KillAura for bloxd.io

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==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)); }
    };

})();