bloxd.io auto clicker, account gen (Draggable UI, Notifications, Right Default)

Auto clicker for bloxd.io with draggable UI (defaults top right), notifications, arraylist, and simultaneous modules

// ==UserScript==
// @name         bloxd.io auto clicker, account gen (Draggable UI, Notifications, Right Default)
// @namespace    https://bloxd.io
// @version      1.1
// @description  Auto clicker for bloxd.io with draggable UI (defaults top right), notifications, arraylist, and simultaneous modules
// @author       MakeItOrBreakIt
// @match        https://staging.bloxd.io/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
    const config = JSON.parse(localStorage.getItem('bloxdConfig')) || {
        leftClickKey: 'KeyR',
        rightClickKey: 'KeyF'
    };

    let minCPS = 10, maxCPS = 15;
    let leftClickActive = false, rightClickActive = false;
    let leftClickInterval, rightClickInterval;

    let arraylistVisible = true;
    let arraylist = [];

    // Notification system
    function showNotification(msg, duration = 1800) {
        let notif = document.createElement("div");
        notif.className = "bloxd-notification";
        notif.textContent = msg;
        document.body.appendChild(notif);
        setTimeout(() => {
            notif.style.opacity = "0";
            setTimeout(() => notif.remove(), 400);
        }, duration);
    }

    // Original click simulation: dispatchEvent on canvas
    const TARGET_SELECTOR = "#noa-canvas";
    function simulateClick(button) {
        const element = document.querySelector(TARGET_SELECTOR);
        if (!element) return;
        element.dispatchEvent(new MouseEvent("mousedown", { button, bubbles: true }));
        element.dispatchEvent(new MouseEvent("mouseup", { button, bubbles: true }));
        if (button === 0) element.dispatchEvent(new MouseEvent("click", { button, bubbles: true }));
        if (button === 2) element.dispatchEvent(new MouseEvent("contextmenu", { button, bubbles: true }));
    }

    function randomInterval() {
        return 1000 / (Math.random() * (maxCPS - minCPS) + minCPS);
    }

    function startLeftClick() {
        if (leftClickActive) return;
        leftClickActive = true;
        function loop() {
            if (!leftClickActive) return;
            simulateClick(0);
            leftClickInterval = setTimeout(loop, randomInterval());
        }
        loop();
        updateArraylist();
    }
    function stopLeftClick() {
        leftClickActive = false;
        clearTimeout(leftClickInterval);
        updateArraylist();
    }
    function toggleLeftClick() {
        leftClickActive ? stopLeftClick() : startLeftClick();
    }

    function startRightClick() {
        if (rightClickActive) return;
        rightClickActive = true;
        function loop() {
            if (!rightClickActive) return;
            simulateClick(2);
            rightClickInterval = setTimeout(loop, randomInterval());
        }
        loop();
        updateArraylist();
    }
    function stopRightClick() {
        rightClickActive = false;
        clearTimeout(rightClickInterval);
        updateArraylist();
    }
    function toggleRightClick() {
        rightClickActive ? stopRightClick() : startRightClick();
    }

    function saveConfig() {
        localStorage.setItem('bloxdConfig', JSON.stringify(config));
    }

    function clearCookies() {
        document.cookie.split(";").forEach(cookie => {
            document.cookie = cookie.split("=")[0] + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
        });
        setTimeout(() => location.reload(), 1000);
    }

    function updateArraylist() {
        arraylist = [];
        if (leftClickActive) arraylist.push("Auto Left Click");
        if (rightClickActive) arraylist.push("Auto Right Click");
        renderArraylist();
    }

    function renderArraylist() {
        const arrDiv = document.getElementById("bloxd-arraylist");
        arrDiv.innerHTML = arraylist.length
            ? arraylist.map(f => `<span class="arraylist-item">${f}</span>`).join("<br>")
            : `<span style="color:#888;">No features active</span>`;
        arrDiv.style.display = arraylistVisible ? "block" : "none";
    }

    function createUI() {
        // Load saved position or use default (right: 10px, top: 10px)
        let saved = JSON.parse(localStorage.getItem('bloxdUIPos') || '{}');
        let useCustom = typeof saved.x === "number" && typeof saved.y === "number";
        let startX = saved.x || 0, startY = saved.y || 10;

        // Main UI container
        let ui = document.createElement("div");
        ui.id = "bloxd-ui-container";
        if (useCustom) {
            ui.setAttribute("style", `position: fixed; top: ${startY}px; left: ${startX}px; right: auto; background: rgba(0,0,0,0.8); color: white; padding: 10px; border-radius: 8px; z-index: 9999; font-size: 14px; min-width: 320px; max-width: 440px; box-shadow: 0 2px 8px #0008; cursor: move;`);
        } else {
            ui.setAttribute("style", `position: fixed; top: 10px; right: 10px; left: auto; background: rgba(0,0,0,0.8); color: white; padding: 10px; border-radius: 8px; z-index: 9999; font-size: 14px; min-width: 320px; max-width: 440px; box-shadow: 0 2px 8px #0008; cursor: move;`);
        }
        ui.innerHTML = `
            <div style="display: flex; flex-direction: row; gap: 10px; margin-bottom: 8px; cursor: move;">
                <button id="leftClickToggle" class="action-button">Left Click</button>
                <button id="rightClickToggle" class="action-button">Right Click</button>
                <button id="clearCookies" class="action-button">Gen Account</button>
                <button id="arraylistToggle" class="action-button">Arraylist</button>
            </div>
            <div style="display: flex; flex-direction: row; gap: 8px;">
                <label class="cps-label">Min CPS: <input type="number" id="minCPS" value="${minCPS}" min="1" max="50"></label>
                <label class="cps-label">Max CPS: <input type="number" id="maxCPS" value="${maxCPS}" min="1" max="50"></label>
                <label class="key-label">Left Key: <input id="keyLeft" type="text" value="${config.leftClickKey}" size="8"></label>
                <label class="key-label">Right Key: <input id="keyRight" type="text" value="${config.rightClickKey}" size="8"></label>
                <button id="saveKeys" class="action-button">Save Keys</button>
            </div>
        `;
        document.body.appendChild(ui);

        // Arraylist display
        let arrDiv = document.createElement("div");
        arrDiv.id = "bloxd-arraylist";
        arrDiv.className = "arraylist-container";
        if (useCustom) {
            arrDiv.setAttribute("style", `position: fixed; top: ${startY+140}px; left: ${startX}px; right: auto; background: rgba(30,30,30,0.97); color: #00ffb0; padding: 10px 22px; border-radius: 8px; z-index: 10000; font-size: 16px; min-width: 120px; text-align: left; box-shadow: 0 2px 8px #0008; user-select: none; margin-top: 10px;`);
        } else {
            arrDiv.setAttribute("style", `position: fixed; top: 150px; right: 10px; left: auto; background: rgba(30,30,30,0.97); color: #00ffb0; padding: 10px 22px; border-radius: 8px; z-index: 10000; font-size: 16px; min-width: 120px; text-align: left; box-shadow: 0 2px 8px #0008; user-select: none; margin-top: 10px;`);
        }
        document.body.appendChild(arrDiv);

        // Drag logic
        let isDragging = false, dragOffsetX = 0, dragOffsetY = 0;
        ui.addEventListener('mousedown', function(e) {
            if (e.target.tagName === "INPUT" || e.target.tagName === "BUTTON") return;
            isDragging = true;
            dragOffsetX = e.clientX - ui.getBoundingClientRect().left;
            dragOffsetY = e.clientY - ui.getBoundingClientRect().top;
            document.body.style.userSelect = "none";
        });
        document.addEventListener('mousemove', function(e) {
            if (!isDragging) return;
            let x = e.clientX - dragOffsetX;
            let y = e.clientY - dragOffsetY;
            // Clamp to window
            x = Math.max(0, Math.min(window.innerWidth - ui.offsetWidth, x));
            y = Math.max(0, Math.min(window.innerHeight - ui.offsetHeight, y));
            ui.style.left = x + "px";
            ui.style.top = y + "px";
            ui.style.right = "auto";
            // Move arraylist too
            arrDiv.style.left = x + "px";
            arrDiv.style.top = (y + 140) + "px";
            arrDiv.style.right = "auto";
        });
        document.addEventListener('mouseup', function(e) {
            if (isDragging) {
                isDragging = false;
                document.body.style.userSelect = "";
                // Save position
                localStorage.setItem('bloxdUIPos', JSON.stringify({
                    x: parseInt(ui.style.left),
                    y: parseInt(ui.style.top)
                }));
            }
        });

        // Event listeners
        document.getElementById("leftClickToggle").onclick = () => { toggleLeftClick(); };
        document.getElementById("rightClickToggle").onclick = () => { toggleRightClick(); };
        document.getElementById("clearCookies").onclick = clearCookies;

        document.getElementById("minCPS").onchange = e => { minCPS = parseInt(e.target.value); };
        document.getElementById("maxCPS").onchange = e => { maxCPS = parseInt(e.target.value); };

        document.getElementById("saveKeys").onclick = () => {
            config.leftClickKey = document.getElementById("keyLeft").value;
            config.rightClickKey = document.getElementById("keyRight").value;
            saveConfig();
            showNotification("Keybinds saved!");
        };

        document.getElementById("arraylistToggle").onclick = () => {
            arraylistVisible = !arraylistVisible;
            renderArraylist();
        };

        // Initial render
        updateArraylist();
    }

    // Keybinds for toggling features
    document.addEventListener("keydown", (event) => {
        if (event.repeat || ["INPUT", "TEXTAREA"].includes(event.target.tagName) || event.target.isContentEditable) return;
        if (event.code === config.leftClickKey) toggleLeftClick();
        if (event.code === config.rightClickKey) toggleRightClick();
    });

    if (!/Mobi|Android/i.test(navigator.userAgent)) {
        createUI();
    }

    // Extra CSS for buttons/inputs and notifications
    const styles = `
        #bloxd-ui-container .action-button {
            background-color: #444;
            color: white;
            border: none;
            padding: 9px 18px;
            border-radius: 6px;
            margin: 0 2px;
            cursor: pointer;
            font-size: 15px;
            transition: background-color 0.3s;
        }
        #bloxd-ui-container .action-button:hover {
            background-color: #888;
        }
        #bloxd-ui-container .action-button:active {
            background-color: #333;
        }
        #bloxd-ui-container .cps-label, #bloxd-ui-container .key-label {
            margin: 0 4px;
            font-size: 13px;
        }
        #bloxd-ui-container input[type="number"], #bloxd-ui-container input[type="text"] {
            padding: 4px 7px;
            font-size: 13px;
            width: 55px;
            margin-left: 2px;
            border-radius: 3px;
            border: 1px solid #333;
            background: #222;
            color: #fff;
        }
        #bloxd-arraylist .arraylist-item {
            color: #00ffb0;
            font-weight: bold;
        }
        .bloxd-notification {
            position: fixed;
            top: 20px;
            right: 20px;
            background: #222d;
            color: #fff;
            padding: 12px 24px;
            border-radius: 8px;
            font-size: 16px;
            z-index: 10001;
            box-shadow: 0 2px 8px #0008;
            opacity: 1;
            transition: opacity 0.4s;
            pointer-events: none;
        }
    `;
    let styleSheet = document.createElement("style");
    styleSheet.type = "text/css";
    styleSheet.innerText = styles;
    document.head.appendChild(styleSheet);
})();