x-RedDragon Client

R=InstaNormal | T=ReverseInsta | Y=BoostInsta | G=BoostSpike | B=4Traps/Boost | Z=4Spikes | ,=AntiTrap | M=AutoMills | F=Trap/BoostPad | V=Spike | N=Mill | H=Teleport/Turret | AutoBiomeHat | Esc=MenuGoldbot/Music | ClickRight=FastBreak | AutoHeal | AutoGG | AntiInstas | Visual Mods.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         x-RedDragon Client
// @namespace    http://youtube.com/@x-RedDragonYT
// @version      1.5.4.1
// @description  R=InstaNormal | T=ReverseInsta | Y=BoostInsta | G=BoostSpike | B=4Traps/Boost | Z=4Spikes | ,=AntiTrap | M=AutoMills | F=Trap/BoostPad | V=Spike | N=Mill | H=Teleport/Turret | AutoBiomeHat | Esc=MenuGoldbot/Music | ClickRight=FastBreak | AutoHeal | AutoGG | AntiInstas | Visual Mods.
// @icon         https://i.imgur.com/AFJt4iq.png
// @author       x-RedDragonYT
// @match        *://moomoo.io/*
// @match        *://*.moomoo.io/*
// @match        *://sandbox.moomoo.io/*
// @match        *://dev.moomoo.io/*
// @grant        none
// @require      https://update.greasyfork.org/scripts/423602/1005014/msgpack.js
// @require      https://update.greasyfork.org/scripts/480301/1322984/CowJS.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/fontfaceobserver.standalone.min.js
// @license      MIT
// ==/UserScript==

//Utility
(function () {
    'use strict';

    let ws;
    const msgpack5 = window.msgpack;

    let boostType, spikeType, turretType = null, windmillType = null, foodType;
    let width, height, mouseX, mouseY;
    let myPlayer = {
        id: null, x: null, y: null, dir: null, object: null,
        weapon: null, clan: null, isLeader: null,
        hat: null, accessory: null, isSkull: null
    };
    let myPlayeroldx, myPlayeroldy;
    let automillx = 10, automilly = 10;
    let walkmillhaha = false;
    let healToggle = true;
    const keysPressed = {};
    const placementIntervals = {};
    let gInterval = null;

    const ID_BullHelmet = 7;
    const ID_TurretGear = 53;
    const ID_SoldierHelmet = 6;
    const ID_TankGear = 40;

    let autoaim = false;
    let nearestEnemy = null, nearestEnemyAngle = 0, enemiesNear = [];


    let gameTick = 0, lastDamageTick = 0, damageTimes = 0, shame = 0, shameTime = 0, HP = 100;
    let anti = true;
    let hitBack = true;
    let primary = null;

    function storeEquip(id, index) {
        doNewSend(["c", [0, id, index]]);
    }

    const cvs = document.getElementById("gameCanvas");
    if (!cvs) return;

    cvs.addEventListener("mousemove", e => {
        mouseX = e.clientX;
        mouseY = e.clientY;
        width = e.target.clientWidth;
        height = e.target.clientHeight;
    });

    function doNewSend(sender) {
        if (ws && msgpack5) ws.send(new Uint8Array(Array.from(msgpack5.encode(sender))));
    }

    function place(id, angle = Math.atan2(mouseY - height / 2, mouseX - width / 2)) {
        if (id == null) return;
        doNewSend(["z", [id, null]]);
        doNewSend(["F", [1, angle]]);
        doNewSend(["F", [0, angle]]);
        doNewSend(["z", [myPlayer.weapon, true]]);
    }

    function isVisible(el) {
        return el && el.offsetParent !== null;
    }

    function updateItems() {
        for (let i = 31; i < 33; i++) if (isVisible(document.getElementById("actionBarItem" + i))) boostType = i - 16;
        for (let i = 22; i < 26; i++) if (isVisible(document.getElementById("actionBarItem" + i))) spikeType = i - 16;
        for (let i = 26; i <= 28; i++) if (isVisible(document.getElementById("actionBarItem" + i))) windmillType = i - 16;
        for (let i = 33; i <= 38; i++) if (i !== 36 && isVisible(document.getElementById("actionBarItem" + i))) turretType = i - 16;
        for (let i = 16; i <= 18; i++) if (isVisible(document.getElementById("actionBarItem" + i))) foodType = i - 16;
    }
    setInterval(updateItems, 250);

    function toRad(degrees) {
        return degrees * 0.01745329251;
    }

    function getSecondaryWeaponIndex() {
        for (let i = 9; i <= 15; i++) {
            if (isVisible(document.getElementById("actionBarItem" + i)) && i !== myPlayer.weapon) {
                return i;
            }
        }
        return myPlayer.weapon;
    }

    // === INSTAKILL NORMAL ===
function relogueoFinal() {
    const primary = myPlayer.weapon;
    const secondary = getSecondaryWeaponIndex();

    if (secondary === 15) {
        doNewSend(["z", [secondary, true]]);
        setTimeout(() => doNewSend(["z", [primary, true]]), 1500);
    } else if (secondary === 12) {
        doNewSend(["z", [secondary, true]]);
        setTimeout(() => doNewSend(["z", [primary, true]]), 1000);
    } else if (secondary === 13) {
        doNewSend(["z", [secondary, true]]);
        setTimeout(() => doNewSend(["z", [primary, true]]), 400);
    }
}

function sequenceInstaKill() {
    storeEquip(0, 1);
    setTimeout(() => {
        autoaim = true;
        const primary = myPlayer.weapon;
        const secondary = getSecondaryWeaponIndex();

        doNewSend(["z", [primary, true]]);
        doNewSend(["c", [0, ID_BullHelmet, 0]]);
        doNewSend(["F", [1]]);
        setTimeout(() => doNewSend(["F", [0]]), 25);

        setTimeout(() => {
            doNewSend(["z", [secondary, true]]);
            doNewSend(["c", [0, ID_TurretGear, 0]]);
            doNewSend(["F", [1]]);
            setTimeout(() => doNewSend(["F", [0]]), 25);

            setTimeout(() => {
                doNewSend(["z", [primary, true]]);
                doNewSend(["z", [primary, true]]);
                doNewSend(["c", [0, ID_SoldierHelmet, 0]]);
                autoaim = false;

                setTimeout(() => {
                    storeEquip(11, 1);

                    relogueoFinal();

                }, 170);

            }, 170);

        }, 120);

    }, 120);
}

    // === INSTAKILL REVERSO ===
function reverseInstaKill() {
    storeEquip(0, 1);
    setTimeout(() => {
        autoaim = true;
        const primary = myPlayer.weapon;
        const secondary = getSecondaryWeaponIndex();

        doNewSend(["z", [secondary, true]]);
        doNewSend(["z", [secondary, true]]);
        doNewSend(["c", [0, ID_TurretGear, 0]]);
        doNewSend(["F", [1]]);
        setTimeout(() => doNewSend(["F", [0]]), 25);

        setTimeout(() => {
            doNewSend(["z", [primary, true]]);
            doNewSend(["c", [0, ID_BullHelmet, 0]]);
            doNewSend(["F", [1]]);
            setTimeout(() => doNewSend(["F", [0]]), 25);
        }, 90);

        setTimeout(() => {
            doNewSend(["z", [primary, true]]);
            doNewSend(["z", [primary, true]]);
            doNewSend(["c", [0, ID_SoldierHelmet, 0]]);
            autoaim = false;

            setTimeout(() => {
                storeEquip(11, 1);

                relogueoFinal();

            }, 200);

        }, 500);
    }, 120);
}

    // === boostTick ===
    function boostTick() {
    storeEquip(0, 1);
    place(boostType, nearestEnemyAngle);

    setTimeout(() => {
        const primary = myPlayer.weapon;
        const secondary = getSecondaryWeaponIndex();


        doNewSend(["z", [secondary, true]]);
        doNewSend(["c", [0, ID_TurretGear, 0]]);
        doNewSend(["F", [1]]);
        setTimeout(() => doNewSend(["F", [0]]), 25);


        setTimeout(() => {
            doNewSend(["z", [primary, true]]);
            doNewSend(["c", [0, ID_BullHelmet, 0]]);


            if (nearestEnemy) {
                place(spikeType, nearestEnemyAngle);
            } else {
                place(foodType);
            }

            doNewSend(["F", [1]]);
            setTimeout(() => doNewSend(["F", [0]]), 25);


            setTimeout(() => {
                doNewSend(["c", [0, ID_SoldierHelmet, 0]]);
                setTimeout(() => {
                    storeEquip(11, 1);


                    if (secondary === 15) {
                        doNewSend(["z", [secondary, true]]);
                        setTimeout(() => {
                            doNewSend(["z", [primary, true]]);
                        }, 1500);
                    } else if (secondary === 12) {
                        doNewSend(["z", [secondary, true]]);
                        setTimeout(() => {
                            doNewSend(["z", [primary, true]]);
                        }, 1000);
                    } else if (secondary === 13) {
                        doNewSend(["z", [secondary, true]]);
                        setTimeout(() => {
                            doNewSend(["z", [primary, true]]);
                        }, 400);
                    }

                    doNewSend(["z", [primary, true]]);
                    doNewSend(["z", [secondary, true]]);
                }, 170);
            }, 170);

        }, 110);
    }, 100);
}

    function startPlacingStructure(key, itemId) {
        if (!placementIntervals[key]) placementIntervals[key] = setInterval(() => place(itemId), 50);
    }
    function stopPlacingStructure(key) {
        clearInterval(placementIntervals[key]);
        delete placementIntervals[key];
    }

function performGSequence() {
    if (!nearestEnemy) return;


    const dx = myPlayer.x - nearestEnemy[1];
    const dy = myPlayer.y - nearestEnemy[2];
    const distance = Math.sqrt(dx * dx + dy * dy);


    doNewSend(["9", [nearestEnemyAngle]]);


    place(spikeType, nearestEnemyAngle + Math.PI / 2);
    place(spikeType, nearestEnemyAngle - Math.PI / 2);


    if (distance <= 150) {
        place(spikeType, nearestEnemyAngle - Math.PI / 4);
        place(spikeType, nearestEnemyAngle + Math.PI / 4);
    }


    place(boostType, nearestEnemyAngle);
}

function performBPlacement() {
    const base = myPlayer.dir;
    place(boostType, base);
    place(boostType, base + Math.PI / 2);
    place(boostType, base - Math.PI / 2);
    place(boostType, base + Math.PI);
}

function placeFourSpikesUp() {
    const firstAngle = -Math.PI / 2;
    place(spikeType, firstAngle);
    place(spikeType, firstAngle + toRad(90));
    place(spikeType, firstAngle + toRad(180));
    place(spikeType, firstAngle + toRad(270));
}

document.addEventListener("keydown", e => {
    if (document.activeElement.id.toLowerCase() === 'chatbox') return;
    const k = e.key.toLowerCase();
    if (keysPressed[k]) return;
    keysPressed[k] = true;

    if (k === 'r') sequenceInstaKill();
    if (k === 't') reverseInstaKill();
    if (k === 'y') boostTick();
    if (k === 'm') {
        walkmillhaha = !walkmillhaha;
        doNewSend(["6", ["AutoMills : " + walkmillhaha]]);
    }
    if (k === 'f') startPlacingStructure(k, boostType);
    if (k === 'v') startPlacingStructure(k, spikeType);
    if (k === 'n') startPlacingStructure(k, windmillType);
    if (k === 'h') startPlacingStructure(k, turretType);


    if (k === 'g' && !gInterval) {
        performGSequence();
        gInterval = setInterval(performGSequence, 80);
    }

    if (k === 'b') performBPlacement();
    if (k === 'z') placeFourSpikesUp();
});

document.addEventListener("keyup", e => {
    const k = e.key.toLowerCase();
    keysPressed[k] = false;
    stopPlacingStructure(k);

    if (k === 'g' && gInterval) {
        clearInterval(gInterval);
        gInterval = null;


        doNewSend(["9", [myPlayer.dir]]);


        if (nearestEnemy) {
            place(spikeType, nearestEnemyAngle - Math.PI / 4);
            place(spikeType, nearestEnemyAngle + Math.PI / 4);
        }
    }
});

    if (!WebSocket.prototype.__originalSend) {
        WebSocket.prototype.__originalSend = WebSocket.prototype.send;
        WebSocket.prototype.send = function (data) {
            if (!ws) {
                ws = this;
                document.ws = this;
                ws.addEventListener("message", handleMessage);
            }
            return this.__originalSend(data);
        };
    }

    function handleMessage(m) {
        let temp = msgpack5.decode(new Uint8Array(m.data));
        let data = (temp.length > 1) ? [temp[0], ...temp[1]] : temp;
        if (!data) return;

        if (data[0] === "C" && myPlayer.id == null) myPlayer.id = data[1];

        if (data[0] === "a") {
            for (let i = 0; i < data[1].length / 13; i++) {
                let obj = data[1].slice(13 * i, 13 * i + 13);
                if (obj[0] === myPlayer.id) {
                    [myPlayer.x, myPlayer.y, myPlayer.dir, myPlayer.object, myPlayer.weapon,
                        , myPlayer.clan, myPlayer.isLeader, myPlayer.hat, myPlayer.accessory,
                        myPlayer.isSkull] = [obj[1], obj[2], obj[3], obj[4],
                        obj[5], obj[7], obj[8], obj[9], obj[10], obj[11]];
                } else enemiesNear.push(obj);
            }

            if (enemiesNear.length > 0) {
                nearestEnemy = enemiesNear.sort(
                    (a, b) => Math.hypot(a[1] - myPlayer.x, a[2] - myPlayer.y) - Math.hypot(b[1] - myPlayer.x, b[2] - myPlayer.y)
                )[0];
                nearestEnemyAngle = Math.atan2(nearestEnemy[2] - myPlayer.y, nearestEnemy[1] - myPlayer.x);
            } else nearestEnemy = null;

            enemiesNear = [];

            if (automillx === false) automillx = myPlayer.x;
            if (automilly === false) automilly = myPlayer.y;

            if (myPlayeroldy !== myPlayer.y || myPlayeroldx !== myPlayer.x) {
                if (walkmillhaha) {
                    if (Math.sqrt(Math.pow(myPlayer.y - automilly, 2) + Math.pow(myPlayer.x - automillx, 2)) > 100) {
                        let angle = Math.atan2(myPlayeroldy - myPlayer.y, myPlayeroldx - myPlayer.x);
                        place(windmillType, angle + toRad(78));
                        place(windmillType, angle - toRad(78));
                        place(windmillType, angle);
                        doNewSend(["D", [Math.atan2(mouseY - height / 2, mouseX - width / 2)]]);
                        automillx = myPlayer.x;
                        automilly = myPlayer.y;
                    }
                }
                myPlayeroldx = myPlayer.x;
                myPlayeroldy = myPlayer.y;
            }
        }


        if (data[0] === "O" && data[1] === myPlayer.id) {
            gameTick = 0;
            lastDamageTick = 0;
            shame = 0;
            HP = 100;
            shameTime = 0;

            if (data[0] === "O" && data[1] === myPlayer.id) {
                let damage = HP - data[2];
                HP = data[2];
                if (damage <= -1) {
                    damageTimes++;
                    if (!lastDamageTick) return;
                    let healTime = gameTick - lastDamageTick;
                    lastDamageTick = 0;
                    if (healTime <= 1) {
                        shame = shame++;
                    } else {
                        shame = Math.max(0, shame - 2);
                    }
                } else {
                    lastDamageTick = gameTick;
                }
            }

            // Normal Heal
            if (data[2] < 100 && data[2] > 0 && healToggle == true) {
                console.log("normal healing");
                setTimeout(() => {
                    place(foodType);
                    place(foodType);
                    doNewSend(["c", [0, 6, 0]]);
                }, 115);
            }

            // Anti Insta
            if (data[2] < 48 && data[2] > 0 && anti == true && (nearestEnemy[5] == 5 || nearestEnemy[5] == 3)) {
                healToggle = false;
                console.log("no soldier anti - polearm");
                doNewSend(["c", [0, 22, 0]]);
                place(foodType);
                setTimeout(() => {
                    place(foodType);
                    doNewSend(["c", [0, 6, 0]]);
                    healToggle = true;
                }, 200);
                setTimeout(() => {
                    doNewSend(["c", [0, 7, 0]]);
                }, 700);
                setTimeout(() => {
                    doNewSend(["c", [0, 6, 0]]);
                }, 1900);
            }

            // Anti Insta
            if (data[2] < 62 && data[2] > 41 && anti == true && (nearestEnemy[5] == 5 || nearestEnemy[5] == 3)) {
                healToggle = false;
                console.log("anti insta - polearm");
                doNewSend(["c", [0, 22, 0]]);
                place(foodType);
                setTimeout(() => {
                    place(foodType);
                    doNewSend(["c", [0, 6, 0]]);
                    healToggle = true;
                }, 200);
                setTimeout(() => {
                    doNewSend(["c", [0, 7, 0]]);
                }, 700);
                setTimeout(() => {
                    doNewSend(["c", [0, 6, 0]]);
                }, 1900);
            }

            // Anti Bullspam
            if (data[2] < 56 && data[2] > 50) {
                healToggle = false;
                console.log("anti bullspam");
                setTimeout(() => {
                    place(foodType);
                    place(foodType);
                    doNewSend(["c", [0, 6, 0]]);
                    healToggle = true;
                }, 140);
            }

            // Hitback
            if (data[2] < 41 && data[2] > 0 && hitBack == true && nearestEnemy[5] == 4) {
                console.log("hitbacking");
                healToggle = false;
                autoaim = true;
                setTimeout(() => {
                    place(foodType);
                    place(foodType);
                }, 133);
                place(spikeType, nearestEnemyAngle);
                doNewSend(["n", [1]]);
                doNewSend(["c", [0, 7, 0]]);
                doNewSend(["z", [primary, true]]);
                setTimeout(() => {
                    doNewSend(["c", [0, 53, 0]]);
                    doNewSend(["n", [0]]);
                    healToggle = true;
                }, 150);
                setTimeout(() => {
                    doNewSend(["c", [0, 11, 0]]);
                    autoaim = false;
                }, 300);
            }
        }

    }

    setInterval(() => {
        if (autoaim && nearestEnemy) doNewSend(["D", [nearestEnemyAngle]]);
    }, 10);

    // 🧠 Anti-Rotación
    Object.defineProperty(Object.prototype, "turnSpeed", {
        get() { return 0; },
        set(_) {},
        configurable: true
    });

// === AUTO GG ===
let prevKillCount = 0;

function initAutoGG() {
    const killCounter = document.getElementById("killCounter");
    if (!killCounter) {
        setTimeout(initAutoGG, 500);
        return;
    }

    const observer = new MutationObserver(() => {
        const count = parseInt(killCounter.innerText, 10) || 0;
        if (count > prevKillCount) {
            prevKillCount = count;
            doNewSend(["6", ["<[GG]>x-RedDragon Client<[GG]>"]]);
            setTimeout(() => {
                doNewSend(["6", [`Kills : ${prevKillCount}`]]);
            }, 1500);
        }
    });

    observer.observe(killCounter, { childList: true, characterData: true, subtree: true });
}

initAutoGG();

// === FASTBREAK ===
let rightClickAttackInterval = null;
let rightClickHeld = false;
let isPlacingStructure = false;
let attackPausedForPlacement = false;

function ensureCorrectWeapon() {
    const primary = myPlayer.weapon;
    const secondary = getSecondaryWeaponIndex();

    let correctWeapon = (secondary === 10) ? secondary : primary;

    if (myPlayer.weapon !== correctWeapon) {
        doNewSend(["z", [correctWeapon, true]]);
    }
}

function startAttackLoop() {
    if (rightClickAttackInterval) return;

    rightClickAttackInterval = setInterval(() => {

        ensureCorrectWeapon();

        doNewSend(["c", [0, ID_TankGear, 0]]);
        doNewSend(["F", [1]]);
        setTimeout(() => doNewSend(["F", [0]]), 10);

    }, 60);
}

function stopAttackLoop() {
    clearInterval(rightClickAttackInterval);
    rightClickAttackInterval = null;
}

document.addEventListener("mousedown", function (e) {
    if (e.button === 2 && !rightClickHeld) {
        rightClickHeld = true;
        doNewSend(["c", [0, ID_TankGear, 0]]);

        setTimeout(() => {
            if (rightClickHeld && !isPlacingStructure) {
                startAttackLoop();
            }
        }, 60);
    }
});

document.addEventListener("mouseup", function (e) {
    if (e.button === 2 && rightClickHeld) {
        rightClickHeld = false;
        stopAttackLoop();
        doNewSend(["F", [0]]);
        setTimeout(() => doNewSend(["c", [0, ID_SoldierHelmet, 0]]), 100);
    }
});

const originalPlace = place;
place = function (...args) {
    isPlacingStructure = true;

    if (rightClickAttackInterval) {
        attackPausedForPlacement = true;
        stopAttackLoop();
    }

    originalPlace.apply(this, args);

    setTimeout(() => {
        isPlacingStructure = false;
        if (rightClickHeld && attackPausedForPlacement) {
            attackPausedForPlacement = false;
            startAttackLoop();
        }
    }, 100);
};

const oldStoreEquip = window.storeEquip;
window.storeEquip = function (id, slot) {
    oldStoreEquip.apply(this, arguments);

    if (rightClickHeld) {
        ensureCorrectWeapon();
    }
};

const oldEquipWeapon = window.equipWeapon;
window.equipWeapon = function (id) {
    oldEquipWeapon.apply(this, arguments);

    if (rightClickHeld) {
        ensureCorrectWeapon();
    }
};

// 🎩 AutoBiomeHatController
function autoBiomeHatController() {
    const ID_SoldierHelmet = 6;
    const ID_SnowHelmet = 15;
    const ID_SandHelmet = 31;
    const ID_GrassHelmet = 12;

    let normalHat = ID_GrassHelmet;
    let currentHat = null;
    let overridePause = false;
    let resumeTimeout = null;
    const movementKeys = new Set();
    const overrideKeys = new Set(["r", "t", " "]);

    function setHat(id) {
        if (id !== currentHat && myPlayer && myPlayer.id != null) {
            currentHat = id;
            doNewSend(["c", [0, id, 0]]);


            let accessoryId = null;
            if (id === ID_SoldierHelmet) {
                accessoryId = 0;
            } else if ([ID_SnowHelmet, ID_SandHelmet, ID_GrassHelmet].includes(id)) {
                accessoryId = 11;
            }


            if (accessoryId !== null) {
                [40, 80, 120].forEach(delay => {
                    setTimeout(() => {
                        storeEquip(accessoryId, 1);
                    }, delay);
                });
            }
        }
    }

    function updateBiomeHat() {
        if (!myPlayer || typeof myPlayer.y !== "number") return;
        if (myPlayer.y < 2400) normalHat = ID_SnowHelmet;
        else if (myPlayer.y > 6850 && myPlayer.y < 7550) normalHat = ID_SandHelmet;
        else normalHat = ID_GrassHelmet;
    }

    function updateHatLogic() {
        if (overridePause) return;
        updateBiomeHat();
        if (movementKeys.size > 0) {
            setHat(normalHat);
        } else {
            setHat(ID_SoldierHelmet);
        }
    }

    function pauseOverride() {
        overridePause = true;
        if (resumeTimeout) clearTimeout(resumeTimeout);
    }

    function resumeOverride() {
        if (resumeTimeout) clearTimeout(resumeTimeout);
        resumeTimeout = setTimeout(() => {
            overridePause = false;
            updateHatLogic();
        }, 360);
    }

    document.addEventListener("keydown", e => {
        const key = e.key.toLowerCase();
        if (["w", "a", "s", "d", "arrowup", "arrowdown", "arrowleft", "arrowright"].includes(key)) {
            if (!movementKeys.has(key)) {
                movementKeys.add(key);
                updateHatLogic();
            }
        }
        if (overrideKeys.has(key)) pauseOverride();
    });

    document.addEventListener("keyup", e => {
        const key = e.key.toLowerCase();
        if (movementKeys.delete(key)) updateHatLogic();
        if (overrideKeys.has(key)) resumeOverride();
    });

    document.addEventListener("mousedown", e => {
        if (e.button === 2) pauseOverride();
    });

    document.addEventListener("mouseup", e => {
        if (e.button === 2) resumeOverride();
    });

    setInterval(() => {
        if (!overridePause) updateHatLogic();
    }, 250);

    console.log("✅ AutoBiomeHatController V3 activado (con accesorios asegurados).");
}

autoBiomeHatController();

// === ANTI TRAP ===
let antiTrap = false;
let intrap = false;
let trapAngle = null;
let trapId = null;

document.addEventListener("keydown", e => {
    if (document.activeElement.id.toLowerCase() === 'chatbox') return;
    if (e.key === ",") {
        antiTrap = !antiTrap;
        doNewSend(["6", ["AntiTrap : " + (antiTrap ? "true" : "false")]]);
    }
});

function handleTrapData(node) {
    for (let i = 0; i < node[1].length / 8; i++) {
        let obj = node[1].slice(8 * i, 8 * i + 8);
        if (obj[6] === 15 && obj[7] !== myPlayer.id && obj[7] !== myPlayer.clan) { // trap enemiga
            let dx = obj[1] - myPlayer.x;
            let dy = obj[2] - myPlayer.y;
            let dist = Math.sqrt(dx * dx + dy * dy);
            if (dist < 90) {
                intrap = true;
                trapAngle = Math.atan2(dy, dx);
                trapId = obj[0];

                doNewSend(["6", ["Trap Detected"]]);
            }
        }
    }
}

const oldHandleMessage = handleMessage;
handleMessage = function (m) {
    let temp = msgpack5.decode(new Uint8Array(m.data));
    let data = (temp.length > 1) ? [temp[0], ...temp[1]] : temp;
    if (!data) return;

    if (data[0] === "H") handleTrapData(data);

    if (data[0] === "Q" && intrap && trapId === data[1]) {
        intrap = false;
        trapId = null;
        setTimeout(() => doNewSend(["c", [0, ID_SoldierHelmet, 0]]), 100);
        doNewSend(["6", ["Trap Cleared"]]);
    }

    oldHandleMessage(m);
};

function ensureCorrectWeapon() {
    const primary = myPlayer.weapon;
    const secondary = getSecondaryWeaponIndex();
    let correctWeapon = (secondary === 10) ? secondary : primary;

    if (myPlayer.weapon !== correctWeapon) {
        doNewSend(["z", [correctWeapon, true]]);
    }
}

function hookEquipFunctions() {
    if (typeof window.storeEquip === "function" && typeof window.equipWeapon === "function") {
        const oldStoreEquip = window.storeEquip;
        window.storeEquip = function (id, slot) {
            const result = oldStoreEquip.apply(this, arguments);
            if (antiTrap && intrap) ensureCorrectWeapon();
            return result;
        };

        const oldEquipWeapon = window.equipWeapon;
        window.equipWeapon = function (id) {
            const result = oldEquipWeapon.apply(this, arguments);
            if (antiTrap && intrap) ensureCorrectWeapon();
            return result;
        };
    } else {
        setTimeout(hookEquipFunctions, 100);
    }
}
hookEquipFunctions();

setInterval(() => {
    if (!antiTrap || !intrap) return;
    if (!ws || ws.readyState !== WebSocket.OPEN) return;

    let oppositeAngle = trapAngle + Math.PI;

    place(spikeType, oppositeAngle);
    ensureCorrectWeapon();

    doNewSend(["D", [trapAngle]]);
    doNewSend(["c", [0, ID_TankGear, 0]]);
    doNewSend(["F", [1, trapAngle]]);
    setTimeout(() => doNewSend(["F", [0, trapAngle]]), 15);

}, 300);
})();

//AntiGrid
(function() {
    'use strict';

    const GRID_ENABLED = false;

    function waitForConfig(callback) {
        if (window.config && window.config.maxScreenWidth && window.config.maxScreenHeight) {
            callback();
        } else {
            setTimeout(() => waitForConfig(callback), 100);
        }
    }

    waitForConfig(() => {
        const maxWidth = window.config.maxScreenWidth;
        const maxHeight = window.config.maxScreenHeight;

        const CELL_SIZE = 50;
        const tolerance = 1.5;

        function isGridLinePair(x1, y1, x2, y2) {
            const isStraight = (x1 === x2 || y1 === y2);
            const isNearGrid = (coord) =>
                (coord % CELL_SIZE <= tolerance) || (CELL_SIZE - (coord % CELL_SIZE) <= tolerance);
            return isStraight && (isNearGrid(x1) || isNearGrid(y1));
        }

        let lastMoveTo = null;

        const originalMoveTo = CanvasRenderingContext2D.prototype.moveTo;
        const originalLineTo = CanvasRenderingContext2D.prototype.lineTo;

        CanvasRenderingContext2D.prototype.moveTo = function(x, y) {
            lastMoveTo = [x, y];
            return originalMoveTo.call(this, x, y);
        };

        CanvasRenderingContext2D.prototype.lineTo = function(x, y) {
            if (!GRID_ENABLED && lastMoveTo) {
                const [x0, y0] = lastMoveTo;
                if (
                    x >= 0 && x <= maxWidth &&
                    y >= 0 && y <= maxHeight &&
                    isGridLinePair(x0, y0, x, y)
                ) {
                    return this;
                }
            }
            return originalLineTo.call(this, x, y);
        };
    });
})();

//Visuals
(function () {
    'use strict';

    const config = window.config || {};
    config.skinColors = [
        "#bf8f54", "#4c4c4c", "#896c4b",
        "#fadadc", "#ececec", "#c37373",
        "#000000", "#ecaff7", "#738cc3",
        "#8bc373", "#91b2db"
    ];
    window.config = config;

function addNamePrefix() {
    const input = document.querySelector('#nameInput');
    if (input && !input.value.trim().startsWith('x-')) {
        input.value = 'x-' + input.value.trim();
        pulseEffect(input);
    }
}

function pulseEffect(el) {
    el.style.transition = 'transform 0.2s ease';
    el.style.transform = 'scale(1.05)';
    setTimeout(() => el.style.transform = 'scale(1)', 200);
}

window.addEventListener('load', () => {
    addNamePrefix();
    const input = document.querySelector('#nameInput');
    if (input) {
        input.addEventListener('input', () => {
            input.value = 'x-' + input.value.replace(/^x-+/i, '');
        });

        input.addEventListener('blur', () => {
            if (!input.value.startsWith('x-')) {
                input.value = 'x-' + input.value;
                pulseEffect(input);
            }
        });
    }
});

    const css = `
    body {
        background: linear-gradient(135deg, rgba(15, 15, 15, 0.2), rgba(28, 28, 28, 0.2));
        font-family: 'Orbitron', sans-serif;
        color: white;
    }

    #mainMenu {
        background-color: black !important;
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
    }

    .menuButton {
        background-color: rgba(0, 0, 0, 0.6);
        border: 2px solid #ff3333;
        color: #ffffff;
        font-family: 'Orbitron', sans-serif;
        font-size: 18px;
        font-weight: bold;
        padding: 12px 28px;
        border-radius: 14px;
        cursor: pointer;
        box-shadow: 0 0 15px #ff0000;
        transition: all 0.4s ease-in-out;
        text-shadow: 0 0 6px #ff0000;
    }

    .menuButton.epic-hover:hover {
        background: linear-gradient(135deg, #ff1111, #ff0000, #cc0000);
        background-size: 300% 300%;
        animation: redPulse 3s infinite ease-in-out;
        box-shadow: 0 0 25px #ff0000, 0 0 50px #ff1111;
        color: #fff;
        transform: scale(1.1);
        border: 3px solid #ffffff;
    }

    @keyframes redPulse {
        0% { background-position: 0% 50%; }
        50% { background-position: 100% 50%; }
        100% { background-position: 0% 50%; }
    }

    #gameName {
        font-size: 80px !important;
        font-weight: bold;
        color: #ff2222 !important;
        text-shadow: 0 0 12px #ff0000, 0 0 30px #ff1111;
        animation: shimmer 3s infinite;
        font-family: 'Courier New', monospace !important;
        position: relative;
        top: -50px;
        text-align: center;
        transition: all 0.5s ease;
    }

    @keyframes shimmer {
        0% { text-shadow: 0 0 12px #ff0000, 0 0 30px #ff1111; }
        50% { text-shadow: 0 0 20px #ff3333, 0 0 40px #ff0000; }
        100% { text-shadow: 0 0 12px #ff0000, 0 0 30px #ff1111; }
    }

    #gameName::after {
        content: "𝕩-ℝ𝕖𝕕𝔻𝕣𝕒𝕘𝕠𝕟 ℂ𝕝𝕚𝕖𝕟𝕥";
        display: block;
        font-size: 1.1em;
        color: #ff4444;
        text-shadow: 0 0 25px #ff1111, 0 0 45px #ff0000;
        animation: glowtext 2s infinite alternate;
        position: relative;
        top: 10px;
        text-align: center;
    }

    @keyframes glowtext {
        0% { opacity: 1; }
        100% { opacity: 0.7; }
    }

    #loadingScreen {
        background: rgba(0, 0, 0, 0.2) !important;
        box-shadow: none !important;
        border: none !important;
    }

    #loadingScreen::before {
        content: "Cargando x-RedDragon Client...";
        font-size: 28px;
        color: #ff2222;
        text-shadow: 0 0 12px #ff0000;
        margin-bottom: 20px;
        animation: pulseText 2s infinite;
    }

    @keyframes pulseText {
        0% { opacity: 1; transform: scale(1); }
        50% { opacity: 0.8; transform: scale(1.05); }
        100% { opacity: 1; transform: scale(1); }
    }

    .menuCard, #bottomText, #storeHolder, #youtuberBtn, #adCard, .setNameContainer, .newsHolder {
        background-color: rgba(20, 20, 20, 0.2);
        padding: 20px;
        border: 2px solid #ff3333;
        box-shadow: 0 0 25px rgba(255, 0, 0, 0.8), 0 0 35px rgba(255, 50, 50, 0.6);
        color: #fff !important;
        animation: borderGlow 4s linear infinite;
        text-align: center;
    }

    @keyframes borderGlow {
        0% { box-shadow: 0 0 12px #ff0000; }
        50% { box-shadow: 0 0 25px #ff3333, 0 0 35px #ff1111; }
        100% { box-shadow: 0 0 12px #ff0000; }
    }

    #gameUI .joinAlBtn, a {
        animation: 5s infinite linear both normal redRainbow;
    }

    @keyframes redRainbow {
        0% { filter: brightness(1) hue-rotate(0deg); }
        100% { filter: brightness(1.2) hue-rotate(360deg); }
    }

    .resourceDisplay, #killCounter {
        width: 120px;
        margin: 0 auto;
        border: 3px solid #ff2222;
        border-radius: 12px;
        background-color: rgba(50, 0, 0, 0.3);
        color: #fff;
        padding: 8px;
        text-align: center;
        font-size: 14px;
        box-shadow: 0 0 10px #ff0000;
    }

    .uiElement {
        border: 2px solid #ff4444;
        background-color: rgba(40, 0, 0, 0.25);
        padding: 10px;
        color: #fff;
        font-size: 14px;
        text-align: center;
        box-shadow: 0 0 10px #ff1111;
    }

    .actionBarItem {
        border: 3px solid #ff4444;
        border-radius: 50%;
        width: 65px;
        height: 65px;
        background-position: center;
        background-size: 55px 55px;
        background-color: rgba(255, 0, 0, 0.2);
        box-shadow: 0 0 15px #ff0000;
        transition: transform 0.2s ease-in-out;
    }

    .actionBarItem:hover {
        transform: scale(1.1);
        box-shadow: 0 0 18px #ff6666;
        background-color: rgba(255, 70, 70, 0.35);
    }

    #itemInfoHolder {
        position: absolute;
        top: 25px;
        left: 50%;
        transform: translateX(-50%);
        width: 350px;
        background-color: rgba(0, 0, 0, 0.3);
        border: 2px solid #ff3333;
        border-radius: 12px;
        color: white;
        padding: 10px;
        font-size: 14px;
        text-align: center;
        box-shadow: 0 0 15px #ff0000;
    }

    ::-webkit-scrollbar {
        width: 12px;
    }

    ::-webkit-scrollbar-track {
        background: rgba(0,0,0,0.2);
        margin-top: 10px;
        margin-bottom: 10px;
    }

    ::-webkit-scrollbar-thumb {
        background: #ff3333;
        border-radius: 0px;
        box-shadow: 0 0 12px #ff3333;
    }
    `;

    const style = document.createElement('style');
    style.innerText = css;
    document.head.appendChild(style);

    const observer = new MutationObserver(() => {
        const gameName = document.getElementById('gameName');
        if (gameName && gameName.innerText !== '𝕩-ℝ𝕖𝕕𝔻𝕣𝕒𝕘𝕠𝕟 ℂ𝕝𝕚𝕖𝕟𝕥') {
            gameName.innerText = '';
        }
    });
    observer.observe(document.body, { childList: true, subtree: true });

    console.log("x-RedDragon Client Full Customization Applied.");

    const waitForMap = setInterval(() => {
        const map = document.getElementById("mapDisplay");
        if (map) {
            map.style.backgroundImage = "url('http://i.imgur.com/Qllo1mA.png')";
            map.style.backgroundSize = "cover";
            map.style.border = "3px solid #ff3333";
            map.style.boxShadow = "0 0 15px #ff0000";
            map.style.borderRadius = "8px";
            clearInterval(waitForMap);
        }
    }, 1);

    const title = "𝕩-ℝ𝕖𝕕𝔻𝕣𝕒𝕘𝕠𝕟 ℂ𝕝𝕚𝕖𝕟𝕥";
    let index = 0;
    function animateTitle() {
        document.title = title.slice(0, index + 1);
        index++;
        if (index <= title.length) {
            setTimeout(animateTitle, 150);
        }
    }
    animateTitle();

    const oldIcons = document.querySelectorAll("link[rel*='icon']");
    oldIcons.forEach(icon => icon.remove());
    const newFavicon = document.createElement("link");
    newFavicon.rel = "icon";
    newFavicon.type = "image/png";
    newFavicon.href = "https://i.imgur.com/vXgDJSp.png";
    document.head.appendChild(newFavicon);

    let frameCount = 0;
    let fps = 0;
    let ping = 0;
    let lastLoop = performance.now();
    let pingTimes = [];

    function updatePing() {
        const startTime = performance.now();
        fetch(window.location.href, { method: 'HEAD', cache: "no-store" })
            .then(() => {
                const endTime = performance.now();
                const latency = Math.round(endTime - startTime);
                pingTimes.push(latency);
                if (pingTimes.length > 10) pingTimes.shift();
                ping = Math.round(pingTimes.reduce((a, b) => a + b, 0) / pingTimes.length);
            })
            .catch(() => ping = 0);
        setTimeout(updatePing, 1000);
    }
    updatePing();

    function updateFPS() {
        const now = performance.now();
        frameCount++;
        if (now - lastLoop >= 1000) {
            fps = Math.round(frameCount / ((now - lastLoop) / 1000));
            frameCount = 0;
            lastLoop = now;
        }
        requestAnimationFrame(updateFPS);
    }
    updateFPS();

    const statsContainer = document.createElement('div');
    statsContainer.id = 'fpsPingDisplay';
    Object.assign(statsContainer.style, {
        position: 'fixed',
        top: '12px',
        left: '50%',
        transform: 'translateX(-50%)',
        fontSize: '22px',
        fontFamily: "'Orbitron', sans-serif",
        color: '#FFFFFF',
        textShadow: '0 0 3px #000000, 1px 1px 0 #000, -1px -1px 0 #000',
        background: 'none',
        padding: '0',
        borderRadius: '0',
        border: 'none',
        boxShadow: 'none',
        zIndex: '0',
        pointerEvents: 'none'
    });
    document.body.appendChild(statsContainer);

    function updateStatsDisplay() {
        statsContainer.textContent = `FPS: ${fps} | Ping: ${ping}ms`;
        setTimeout(updateStatsDisplay, 500);
    }
    updateStatsDisplay();

    window.getStats = function () {
        return { fps, ping };
    };
//Hats Texturas
    const textureMap = {
        // Tus texturas personalizadas
        "img/hats/hat_7.png": "https://i.imgur.com/vAOzlyY.png",
        "img/hats/hat_15.png": "https://i.imgur.com/YRQ8Ybq.png",
        "img/hats/hat_11.png": "https://i.imgur.com/yfqME8H.png",
        "img/hats/hat_12.png": "https://i.imgur.com/VSUId2s.png",
        "img/hats/hat_40.png": "https://i.imgur.com/Xzmg27N.png",
        "img/hats/hat_26.png": "https://i.imgur.com/I0xGtyZ.png",
        "img/hats/hat_6.png": "https://i.imgur.com/vM9Ri8g.png"
    };

    const originalImageSrc = Object.getOwnPropertyDescriptor(Image.prototype, 'src');

    Object.defineProperty(Image.prototype, 'src', {
        set: function (url) {
            for (const [key, newUrl] of Object.entries(textureMap)) {
                if (url.includes(key)) {
                    url = newUrl;
                    break;
                }
            }
            return originalImageSrc.set.call(this, url);
        }
    });
})();

//WeaponReloadPrediction
(function () {
    "use strict";

    let ws;
    const msgpack = window.msgpack;
    WebSocket.prototype._send = WebSocket.prototype.send;
    WebSocket.prototype.send = function (m) {
        if (!ws) {
            ws = this;
            window.ws = this;
        }
        this._send(m);
    };

    let hue = 0;

    function changeStyle() {
        const ageBarBody = document.getElementById("ageBarBody");
        if (ageBarBody) {
            hue = (hue + 2) % 360;
            const rgbColor = `hsl(${hue}, 100%, 50%)`;
            ageBarBody.style.backgroundColor = rgbColor;
            ageBarBody.style.border = `2px solid ${rgbColor}`;
            ageBarBody.style.transform = "translateY(-2px)";
        }
    }

    setInterval(changeStyle, 100);

    const previousReloadStates = new Map();
    const turretCooldown = 2500;
    let turretLastClickTime = null;
    let turretReady = true;

    window.Cow.setCodec(msgpack);
    CanvasRenderingContext2D.prototype._roundRect = CanvasRenderingContext2D.prototype.roundRect;

    window.addEventListener("mousedown", (e) => {
        if (e.button === 1 && turretReady) {
            turretLastClickTime = Date.now();
            turretReady = false;
        }
    });

    window.Cow.addRender("global", () => {
        const ctx = window.Cow.renderer.context;

        window.Cow.playersManager.eachVisible(player => {
            if (!player || !player.alive) return;

            const width = window.config.healthBarWidth / 2 - window.config.healthBarPad / 2;
            const yOffset = player.renderY + player.scale + window.config.nameY - 5;

            const primaryReload = Math.min(Math.max(player.reloads.primary.count / player.reloads.primary.max, 0), 1);
            const secondaryReload = Math.min(Math.max(player.reloads.secondary.count / player.reloads.secondary.max, 0), 1);

            const pad = window.config.healthBarPad;
            const height = 17;
            const radius = 8;

            // Barra primaria
            ctx.save();
            ctx.fillStyle = "#3d3f42";
            ctx.translate(player.renderX - width * 1.19, yOffset);
            ctx.beginPath();
            ctx._roundRect(-width - pad, -8.5, 2 * width + 2 * pad, height, radius);
            ctx.fill();
            ctx.restore();

            ctx.save();
            ctx.fillStyle = player.isAlly ? "#8ecc51" : "#cc5151";
            ctx.translate(player.renderX - width * 1.19, yOffset);
            ctx.beginPath();
            ctx._roundRect(-width, -8.5 + pad, 2 * width * primaryReload, height - 2 * pad, radius - 1);
            ctx.fill();
            ctx.restore();


            ctx.save();
            ctx.fillStyle = "#3d3f42";
            ctx.translate(player.renderX + width * 1.19, yOffset);
            ctx.beginPath();
            ctx._roundRect(-width - pad, -8.5, 2 * width + 2 * pad, height, radius);
            ctx.fill();
            ctx.restore();

            ctx.save();
            ctx.fillStyle = player.isAlly ? "#8ecc51" : "#cc5151";
            ctx.translate(player.renderX + width * 1.19, yOffset);
            ctx.beginPath();
            ctx._roundRect(-width, -8.5 + pad, 2 * width * secondaryReload, height - 2 * pad, radius - 1);
            ctx.fill();
            ctx.restore();

            // === Contador de HP ===
            const hpCurrent = Math.floor(player.health);
            const hpMax = Math.floor(player.maxHealth || 100);
            const hpText = `HP: ${hpCurrent}/${hpMax}`;

            ctx.save();
            ctx.font = "bold 20px GameFont";
            ctx.textAlign = "center";
            ctx.lineWidth = 3;
            ctx.strokeStyle = "black";
            ctx.fillStyle = "white";

            const textX = player.renderX;
            const textY = yOffset + 32;

            ctx.strokeText(hpText, textX, textY);
            ctx.fillText(hpText, textX, textY);
            ctx.restore();
        });
    });
})();

//HealBarsBuildings
// @require      https://update.greasyfork.org/scripts/480301/1283571/CowJS.js
// @require      https://update.greasyfork.org/scripts/480303/1282926/MooUI.js
(function () {
    "use strict";

    function init() {
        if (!window.Cow || !window.CowUtils) {
            setTimeout(init, 100);
            return;
        }

        const { Cow, CowUtils } = window;
        const settings = {
            "health-bars": true,
            "circle-bars": true,
            "in-look-dir": false,
            "friendly-color": "#56e319",
            "enemy-color": "#ff3333",
            "hit-counter": true
        };

        function isOwnBuilding(object) {
            if (object && Cow.player) {
                if (object.group !== undefined && Cow.player.group !== undefined) {
                    return object.group === Cow.player.group;
                }
                if (object.owner && Cow.player.sid) {
                    return object.owner.sid === Cow.player.sid;
                }
                if (object.team !== undefined && Cow.player.team !== undefined) {
                    return object.team === Cow.player.team;
                }
            }
            return false;
        }

        function drawHealthBar(context, object) {
            const healthBarWidth = 50;
            const healthBarPad = 5;
            const width = (window.config?.healthBarWidth ? window.config.healthBarWidth / 2 : healthBarWidth / 2) -
                         (window.config?.healthBarPad ? window.config.healthBarPad / 2 : healthBarPad / 2);
            const height = 17;
            const radius = 8;
            const barColor = isOwnBuilding(object) ? settings["friendly-color"] : settings["enemy-color"];

            context.save();
            context.translate(object.renderX || object.x, object.renderY || object.y);
            context.fillStyle = "#3d3f42";

            if (context.roundRect) {
                context.roundRect(-width - healthBarPad, -height / 2, 2 * width + 2 * healthBarPad, height, radius);
            } else {
                context.beginPath();
                context.moveTo(-width - healthBarPad + radius, -height / 2);
                context.arcTo(-width - healthBarPad + 2 * width + 2 * healthBarPad, -height / 2, -width - healthBarPad + 2 * width + 2 * healthBarPad, -height / 2 + height, radius);
                context.arcTo(-width - healthBarPad + 2 * width + 2 * healthBarPad, -height / 2 + height, -width - healthBarPad, -height / 2 + height, radius);
                context.arcTo(-width - healthBarPad, -height / 2 + height, -width - healthBarPad, -height / 2, radius);
                context.arcTo(-width - healthBarPad, -height / 2, -width - healthBarPad + radius, -height / 2, radius);
                context.closePath();
            }
            context.fill();

            context.fillStyle = barColor;
            const healthRatio = (object.health || object.hp || 100) / (object.maxHealth || object.maxHP || 100);

            if (context.roundRect) {
                context.roundRect(-width, -height / 2 + healthBarPad, 2 * width * healthRatio, height - 2 * healthBarPad, radius - 1);
            } else {
                context.beginPath();
                context.moveTo(-width + (radius - 1), -height / 2 + healthBarPad);
                context.arcTo(-width + 2 * width * healthRatio, -height / 2 + healthBarPad, -width + 2 * width * healthRatio, -height / 2 + height - 2 * healthBarPad, radius - 1);
                context.arcTo(-width + 2 * width * healthRatio, -height / 2 + height - 2 * healthBarPad, -width, -height / 2 + height - 2 * healthBarPad, radius - 1);
                context.arcTo(-width, -height / 2 + height - 2 * healthBarPad, -width, -height / 2 + healthBarPad, radius - 1);
                context.arcTo(-width, -height / 2 + healthBarPad, -width + (radius - 1), -height / 2 + healthBarPad, radius - 1);
                context.closePath();
            }
            context.fill();
            context.restore();
        }

        function drawCircleBar(context, object) {
            const barColor = isOwnBuilding(object) ? settings["friendly-color"] : settings["enemy-color"];
            const healthRatio = (object.health || object.hp || 100) / (object.maxHealth || object.maxHP || 100);
            const endAngle = healthRatio * Math.PI * 2;
            const width = 14;
            const scale = 22;

            context.save();
            context.translate(object.renderX || object.x, object.renderY || object.y);
            context.rotate(object.dir ?? object.dir2 ?? 0);

            context.strokeStyle = "#3d3f42";
            context.lineWidth = width;
            context.lineCap = "round";
            context.beginPath();
            context.arc(0, 0, scale, 0, Math.PI * 2);
            context.stroke();
            context.closePath();

            context.strokeStyle = barColor;
            context.lineWidth = width / 2.5;
            context.beginPath();
            context.arc(0, 0, scale, 0, endAngle);
            context.stroke();
            context.closePath();

            context.restore();
        }

        function drawHitCounter(context, object) {
            if (!Cow.player || !Cow.player.weapon) return;
            try {
                const damage = Cow.player.weapon.dmg * (Cow.items.variants[Cow.player.weaponVariant]?.val || 1);
                const damageAmount = damage * (Cow.player.weapon.sDmg || 1) * (Cow.player.skin?.id === 40 ? 3.3 : 1);
                const objectHealth = object.health || object.hp || 100;
                const hits = Math.ceil(objectHealth / damageAmount);
                const offsetY = settings["circle-bars"] ? 2 : 22;

                context.save();
                context.font = `18px Hammersmith One`;
                context.fillStyle = "#fff";
                context.textBaseline = "middle";
                context.textAlign = "center";
                context.lineWidth = 8;
                context.lineJoin = "round";
                context.translate(object.renderX || object.x, object.renderY || object.y);
                context.strokeText(hits, 0, offsetY);
                context.fillText(hits, 0, offsetY);
                context.restore();
            } catch (e) {}
        }

        function renderHealthBars() {
            if (!Cow.player) return;
            const { context } = Cow.renderer;
            try {
                Cow.objectsManager.eachVisible((object) => {
                    if (!object.isItem && !object.isStructure && !object.buildingType && !object.type) return;
                    if ((object.health === undefined && object.hp === undefined) ||
                        (object.maxHealth === undefined && object.maxHP === undefined)) return;

                    const angle = CowUtils.getDirection ?
                        CowUtils.getDirection(object, Cow.player) :
                        Math.atan2(object.y - Cow.player.y, object.x - Cow.player.x);

                    if (settings["in-look-dir"] &&
                        CowUtils.getAngleDist &&
                        CowUtils.getAngleDist(angle, Cow.player.lookAngle) > (Cow.config?.gatherAngle || Math.PI/2)) {
                        return;
                    }

                    if (settings["hit-counter"]) {
                        drawHitCounter(context, object);
                    }

                    if (settings["health-bars"]) {
                        if (settings["circle-bars"]) {
                            drawCircleBar(context, object);
                        } else {
                            drawHealthBar(context, object);
                        }
                    }
                });
            } catch (e) {}
        }

        if (Cow.addRender) {
            Cow.addRender("building-health-bars", renderHealthBars);
        } else {
            function renderLoop() {
                try {
                    if (Cow && Cow.player && Cow.renderer && Cow.renderer.context) {
                        renderHealthBars();
                    }
                } catch (e) {}
                requestAnimationFrame(renderLoop);
            }
            requestAnimationFrame(renderLoop);
        }
        console.log("[Building Ownership Health Bars + Circles] Script iniciado correctamente");
    }

    if (document.readyState === "complete") {
        init();
    } else {
        window.addEventListener("load", init);
    }
})();

//AutoVerifity
(function () {
    'use strict';

    let ws = null;
    let { msgpack } = window;
    let playerID = null;
    let myPlayer = {
        id: null, x: null, y: null, dir: null, object: null, weapon: null,
        clan: null, isLeader: null, maxXP: 300, XP: 0, age: 1,
        hat: null, accessory: null, isSkull: null, maxHealth: 100,
        health: 100
    };
    let players = [], enemy = [], nearestEnemy = {};
    let gameCanvas = document.getElementById("gameCanvas");
    let width = window.innerWidth;
    let height = window.innerHeight;
    let mouseX, mouseY;

    const sendPacket = (packet, ...data) => {
        if (ws && ws.readyState === WebSocket.OPEN) {
            ws.send(new Uint8Array(msgpack.encode([packet, data])));
        }
    };

    const updatePlayers = data => {
        players = [];
        for (let i = 0; i < data[1].length / 13; i++) {
            const playerInfo = data[1].slice(i * 13, i * 13 + 13);
            if (playerInfo[0] === myPlayer.id) {
                myPlayer.x = playerInfo[1];
                myPlayer.y = playerInfo[2];
                myPlayer.dir = playerInfo[3];
                myPlayer.object = playerInfo[4];
                myPlayer.weapon = playerInfo[5];
                myPlayer.clan = playerInfo[7];
                myPlayer.isLeader = playerInfo[8];
                myPlayer.hat = playerInfo[9];
                myPlayer.accessory = playerInfo[10];
                myPlayer.isSkull = playerInfo[11];
            } else {
                players.push({
                    id: playerInfo[0],
                    x: playerInfo[1],
                    y: playerInfo[2],
                    dir: playerInfo[3],
                    object: playerInfo[4],
                    weapon: playerInfo[5],
                    clan: playerInfo[7],
                    isLeader: playerInfo[8],
                    hat: playerInfo[9],
                    accessory: playerInfo[10],
                    isSkull: playerInfo[11]
                });
            }
        }
    };

    const updateHealth = (health, playerIDCheck) => {
        if (myPlayer.id === playerIDCheck) {
            myPlayer.health = health;
            console.log("[🩸 Salud actualizada]", health);
        }
    };

    const handleMessage = (message) => {
        const decoded = msgpack.decode(new Uint8Array(message.data));
        const data = Array.isArray(decoded) && decoded.length > 1 ? [decoded[0], ...decoded[1]] : decoded;
        if (!data) return;
        const type = data[0];
        if (type === "C" && myPlayer.id == null) {
            myPlayer.id = data[1];
            console.log("[✔️ Verificación] ID del jugador:", myPlayer.id);
        }
        if (type === "a") updatePlayers(data);
        if (type === "O") updateHealth(data[2], data[1]);
    };

    const socketFound = (sock) => {
        sock.addEventListener("message", handleMessage);
        if (gameCanvas) {
            gameCanvas.addEventListener("mousemove", ({ x, y }) => {
                mouseX = x;
                mouseY = y;
            });
        }
        window.addEventListener("resize", () => {
            width = window.innerWidth;
            height = window.innerHeight;
        });
    };

    WebSocket.prototype.oldSend = WebSocket.prototype.send;
    WebSocket.prototype.send = function (m) {
        if (!ws) {
            ws = this;
            document.websocket = this;
            socketFound(this);
            console.log("[🔌 WebSocket] Interceptado correctamente.");
        }
        this.oldSend(m);
    };

    const altchaCheck = setInterval(() => {
        let altcha = document.getElementById('altcha');
        let altchaBox = document.getElementById('altcha_checkbox');
        if (altcha && altchaBox) {
            altcha.style.display = 'none';
            altchaBox.checked = true;
            altchaBox.click();
            clearInterval(altchaCheck);
            console.log("[🚫 Altcha] Eliminado.");
        }
    }, 500);
})();

//AutoReloadWeb
(function() {
    "use strict";

    function delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    async function refreshPage() {
        await delay(1500);
        window.onbeforeunload = null;
        location.reload();
    }

    function interceptProperty(target, propName, onSetCallback) {
        const hiddenKey = Symbol(propName);
        Object.defineProperty(target, propName, {
            get() {
                return this[hiddenKey];
            },
            set(value) {
                onSetCallback(this, hiddenKey, value);
            },
            configurable: true
        });
    }

    function wrapFunction(originalFunc, wrapper) {
        return new Proxy(originalFunc, {
            apply(target, thisArg, args) {
                return wrapper.call(thisArg, target, args);
            }
        });
    }

    interceptProperty(Object.prototype, "errorCallback", (obj, key, val) => {
        obj[key] = val;
        if (typeof val !== "function") return;
        obj[key] = wrapFunction(val, (target, args) => {
            window.alert = () => {};
            refreshPage();
            return target.apply(this, args);
        });
    });

    ["onclose", "onerror"].forEach(eventName => {
        const descriptor = Object.getOwnPropertyDescriptor(WebSocket.prototype, eventName);
        if (!descriptor || !descriptor.set) return;
        Object.defineProperty(WebSocket.prototype, eventName, {
            set(handler) {
                const wrappedHandler = wrapFunction(handler, (target, args) => {
                    refreshPage();
                    return target.apply(this, args);
                });
                descriptor.set.call(this, wrappedHandler);
            }
        });
    });

})();

// === ESP Radar ===
localStorage.setItem("moofoll", true);

const players = [];
const property = "team";

Object.defineProperty(Object.prototype, property, {
    get() {
        if (this.isPlayer && !players.find(p => p.id === this.id)) {
            players.push(this);
        }
        return this[`_${property}`];
    },
    set(value) { this[`_${property}`] = value; },
    configurable: true
});

let ctx, owner, camX = 0, camY = 0;

const conf = {
    radar: { colorEnemy: "#ff0000", colorAlly: "#00ff00", w: 20, h: 20 },
    maxScreenWidth: 1920,
    maxScreenHeight: 1080
};

let arrowLayer = document.getElementById("radarArrowLayer");

function getUIZIndex() {
    const ids = ["gameUI", "mainMenu", "ageText", "storeHolder", "uiHolder"];
    let maxZ = 10;
    for (const id of ids) {
        const el = document.getElementById(id);
        if (!el) continue;
        const z = parseInt(getComputedStyle(el).zIndex || "0", 10);
        if (!Number.isNaN(z)) maxZ = Math.max(maxZ, z);
    }
    return maxZ;
}

function ensureArrowLayer() {
    if (!arrowLayer) {
        arrowLayer = document.createElement("div");
        arrowLayer.id = "radarArrowLayer";
        arrowLayer.style.position = "fixed";
        arrowLayer.style.left = "0";
        arrowLayer.style.top = "0";
        arrowLayer.style.width = "100vw";
        arrowLayer.style.height = "100vh";
        arrowLayer.style.pointerEvents = "none";
        document.body.appendChild(arrowLayer);
    }
    const uiZ = getUIZIndex();
    const targetZ = Math.max(1, uiZ - 1);
    arrowLayer.style.zIndex = String(targetZ);
}
ensureArrowLayer();

const createArrow = (id, color = conf.radar.colorEnemy) => {
    if (document.getElementById(`radarArrow-${id}`)) return;
    const el = document.createElement("div");
    el.id = `radarArrow-${id}`;
    el.style.position = "absolute";
    el.style.width = "0";
    el.style.height = "0";
    el.style.borderStyle = "solid";
    el.style.borderWidth = `10px 0 10px ${conf.radar.w}px`;
    el.style.borderColor = `transparent transparent transparent ${color}`;
    el.style.display = "none";
    el.style.opacity = "1";
    el.style.transformOrigin = "left center";
    el.style.willChange = "transform, left, top, opacity";
    el.style.zIndex = "inherit";
    arrowLayer.appendChild(el);
};

const updateArrow = (id, x, y, color = conf.radar.colorEnemy, opacity = 1, angle = 0) => {
    const arrow = document.getElementById(`radarArrow-${id}`);
    if (!arrow) return;
    arrow.style.left = `${x}px`;
    arrow.style.top = `${y}px`;
    arrow.style.display = "block";
    arrow.style.opacity = `${opacity}`;
    arrow.style.transform = `rotate(${angle}deg)`;
    arrow.style.borderColor = `transparent transparent transparent ${color}`;
};

const removeArrow = (id) => {
    const arrow = document.getElementById(`radarArrow-${id}`);
    if (arrow) arrow.remove();
};

const getDistance = (x1, y1, x2, y2) => Math.hypot(x2 - x1, y2 - y1);
const getDirection = (x1, y1, x2, y2) => Math.atan2(y2 - y1, x2 - x1);
const RtoD = r => r * 180 / Math.PI;

const radar = () => {
    if (!ctx) {
        const gameCanvas = document.getElementById("gameCanvas");
        if (!gameCanvas) return;
        ctx = gameCanvas.getContext("2d");
    }

    ensureArrowLayer();

    for (let i = players.length - 1; i >= 0; i--) {
        const p = players[i];
        if (!p || !p.visible || typeof p.x !== "number" || typeof p.y !== "number") {
            if (p && p.id != null) removeArrow(p.id);
            players.splice(i, 1);
        }
    }

    owner = players.find(p => p.visible && p.wood);
    if (!owner) return;

    const centerX = window.innerWidth / 2;
    const centerY = window.innerHeight / 2;

    camX += (owner.x - camX) * 0.1;
    camY += (owner.y - camY) * 0.1;

    for (let player of players) {
        if (!player.visible || player.id === owner.id) continue;

        const isAlly = player.team && player.team === owner.team;
        const color = isAlly ? conf.radar.colorAlly : conf.radar.colorEnemy;

        const rad = getDirection(owner.x, owner.y, player.x, player.y);
        const per = getDistance(0, 0, owner.x - player.x, (owner.y - player.y) * (16 / 9)) * 100 / (conf.maxScreenHeight / 2);
        const alpha = Math.min(per / centerY, 1);
        const dis = centerY * alpha;

        const tx = centerX + dis * Math.cos(rad) - conf.radar.w / 2;
        const ty = centerY + dis * Math.sin(rad) - conf.radar.h / 2;

        if (!document.getElementById(`radarArrow-${player.id}`)) createArrow(player.id, color);
        updateArrow(player.id, tx, ty, color, alpha, RtoD(rad));
    }
};

function gameLoop() {
    requestAnimationFrame(gameLoop);
    radar();
}
gameLoop();

addEventListener("resize", ensureArrowLayer);

//Goldbot/Music Menu
(function () {
    'use strict';

   const style = document.createElement('style');
    style.textContent = `
        #moddedMenu {
            position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.5);
            width: 360px; background: rgba(0,0,0,0.8); border: 4px solid #ff0000; border-radius: 15px;
            z-index: 9999; color: white; font-family: monospace; display: flex; flex-direction: column;
            align-items: center; padding: 15px; box-sizing: border-box; opacity: 0;
            transition: opacity 0.3s ease, transform 0.3s ease; pointer-events: none;
        }
        #moddedMenu.open { opacity:1; transform: translate(-50%, -50%) scale(1); pointer-events:auto; }
        #menuTabs { display:flex; justify-content:center; gap:6px; width:100%; margin-bottom:15px; }
        .tabButton { padding:5px 10px; border:1px solid #ff0000; border-radius:8px; background:#111;
            color:#ff0000; cursor:pointer; font-weight:bold; font-size:0.9em; transition: background 0.3s ease, transform 0.2s ease; }
        .tabButton.active { background:#cc0000; color:white; transform:scale(1.05); }
        .tabContent { display:none; width:100%; text-align:center; }
        .tabContent.active { display:block; }
        #menuTitle { font-size:1.4em; color:#ff0000; margin-bottom:12px; }
        .rd-select, .rd-button { font-family:monospace; width:85%; font-size:1em; padding:8px; margin:6px auto;
            border:1px solid #ff0000; border-radius:6px; background:#111; color:#ff0000; outline:none; display:block; text-align:center; }
        .rd-button { cursor:pointer; font-weight:bold; transition: background-color 0.3s ease, transform 0.2s ease; }
        .rd-button:hover { background-color:#cc0000; color:white; transform:scale(1.05); }
        #buttons { display:flex; justify-content:center; gap:12px; margin:8px 0; }
        .indicator { margin-top:6px; font-size:0.9em; color:#ff0000; }
        .indicator.active { color:#00ff00; }
    `;
    document.head.appendChild(style);

    const menu = document.createElement('div'); menu.id='moddedMenu';

    const tabBar = document.createElement('div'); tabBar.id='menuTabs';
    const tabMusic = document.createElement('button'); tabMusic.textContent="🎵 Music"; tabMusic.className="tabButton active";
    const tabBot = document.createElement('button'); tabBot.textContent="🤖 Bot"; tabBot.className="tabButton";
    tabBar.appendChild(tabMusic); tabBar.appendChild(tabBot);

    const musicContent = document.createElement('div'); musicContent.className="tabContent active";
    const musicTitle = document.createElement('div'); musicTitle.id='menuTitle'; musicTitle.textContent='Music Player';
    musicContent.appendChild(musicTitle);

const musicTracks = [
    {name:"Alan Walker - Faded",url:"https://files.catbox.moe/p9om0y.mp3"},
    {name:"Alan Walker - Alone",url:"https://files.catbox.moe/xptxat.mp3"},
    {name:"TheFatRat - Unity",url:"https://files.catbox.moe/cx5uyo.mp3"},
    {name:"TheFatRat - Monody",url:"https://files.catbox.moe/7fwpbl.mp3"},
    {name:"NEFFEX - Fight Back",url:"https://files.catbox.moe/iif5rx.mp3"},
    {name:"NEFFEX - Never Give Up",url:"https://files.catbox.moe/2pamid.mp3"},
    {name:"Alan Walker - Dust",url:"https://files.catbox.moe/w1sb9x.mp3"},
    {name:"Alan Walker - Catch Me",url:"https://files.catbox.moe/74b06c.mp3"},
    {name:"Alan Walker - Last Song",url:"https://files.catbox.moe/nuta1v.mp3"},
    {name:"Egzod - Royalty ft. Neoni",url:"https://files.catbox.moe/zlfc04.mp3"},
    {name:"Rival - Lonely Way", url:"https://files.catbox.moe/pvvol1.mp3"},
    {name:"Rival - Throne", url:"https://files.catbox.moe/1xptgl.mp3"},
    {name:"Rival - Be Gone", url:"https://files.catbox.moe/1b66yg.mp3"},
    {name:"Rival - Walls", url:"https://files.catbox.moe/9fts5y.mp3"},
    {name:"Rival - Control", url:"https://files.catbox.moe/gkd21e.mp3"},
    {name:"Egzod - No Rival", url:"https://files.catbox.moe/s6lw44.mp3"},
    {name:"do not resurrect - Necrotic Grip", url:"https://files.catbox.moe/12ndfn.mp3"},
    {name:"Witchouse 40k - Black Rainbow", url:"https://files.catbox.moe/41hpxf.mp3"},
    {name:"Grim Salvo - Feasting", url:"https://files.catbox.moe/rpicy8.mp3"},
    {name:"Initial D - Don't Stand so Close", url:"https://files.catbox.moe/mvt5vu.mp3"},
    {name:"Initial D - The Top", url:"https://files.catbox.moe/m05yul.mp3"},
    {name:"Initial D - Gas Gas Gas", url:"https://files.catbox.moe/i125jn.mp3"},
    {name:"Initial D - Running In The 90's", url:"https://files.catbox.moe/x9i2yf.mp3"},
    {name:"Initial D - No One Sleep In Tokyo", url:"https://files.catbox.moe/d7ma70.mp3"},
    {name:"UNSECRET & Noeni - Fallout", url:"https://files.catbox.moe/cz07sk.mp3"},
    {name:"V O E - Giants", url:"https://files.catbox.moe/a5hp0f.mp3"},
    {name:"Neoni - Champion", url:"https://files.catbox.moe/ptuaf6.mp3"},
    {name:"JPB & Mendum - Losing Control", url:"https://files.catbox.moe/1ta7n9.mp3"},
    {name:"Freddie Dredd - Limbo", url:"https://files.catbox.moe/vt686o.mp3"},
    {name:"xxxmanera - NFS", url:"https://files.catbox.moe/do69yr.mp3"},
    {name:"Take Me Home", url:"https://files.catbox.moe/t60gd6.mp3"},
    {name:"rarin - GTA", url:"https://files.catbox.moe/4h68o1.mp3"},
    {name:"Ghost", url:"https://files.catbox.moe/6kewnq.mp3"},
    {name:"Rico Story 1", url:"https://files.catbox.moe/h4jfhb.mp3"},
    {name:"xxxmanera - Loyalty Before Royalty", url:"https://files.catbox.moe/nlo77z.mp3"},
    {name:"xxxmanera - Sosa! Baby", url:"https://files.catbox.moe/6s1lnp.mp3"},
    {name:"xxxmanera - Dead Idol", url:"https://files.catbox.moe/pa14i1.mp3"},
    {name:"CRVN x Zack Merci - Nobody", url:"https://files.catbox.moe/lgjj6h.mp3"},
    {name:"Cheriimoya, Sierra Kidd - Living Life", url:"https://files.catbox.moe/hg93qr.mp3"},
    {name:"Adrenaline - ACE", url:"https://files.catbox.moe/1vr1px.mp3"}
];

    const musicSelect = document.createElement('select'); musicSelect.className='rd-select';
    musicTracks.forEach(track=>{ const o=document.createElement('option'); o.value=track.url; o.textContent=track.name; musicSelect.appendChild(o); });
    musicContent.appendChild(musicSelect);

    const buttonsDiv = document.createElement('div'); buttonsDiv.id='buttons';
    const playBtn = document.createElement('button'); playBtn.className='rd-button'; playBtn.textContent='▶ Play';
    const stopBtn = document.createElement('button'); stopBtn.className='rd-button'; stopBtn.textContent='■ Stop';
    buttonsDiv.appendChild(playBtn); buttonsDiv.appendChild(stopBtn);
    musicContent.appendChild(buttonsDiv);

    const modeSelect = document.createElement('select'); modeSelect.className='rd-select';
    modeSelect.innerHTML=`<option value="repeat">🔁 Repeat</option><option value="next">⏭️ Next</option>`;
    musicContent.appendChild(modeSelect);

    const audio = document.createElement('audio'); audio.id='audioPlayer'; musicContent.appendChild(audio);

    function playMusic(){ audio.src=musicSelect.value; audio.play(); }
    playBtn.addEventListener('click',()=>{ if(audio.src!==musicSelect.value) audio.src=musicSelect.value; audio.play(); });
    stopBtn.addEventListener('click',()=>{ audio.pause(); audio.currentTime=0; });
    musicSelect.addEventListener('change',()=>{ if(!audio.paused) playMusic(); });
    audio.addEventListener('ended',()=>{ if(modeSelect.value==='repeat'){audio.currentTime=0; audio.play();} else { const idx=(musicSelect.selectedIndex+1)%musicSelect.options.length; musicSelect.selectedIndex=idx; playMusic(); }});


    const botContent = document.createElement('div'); botContent.className='tabContent';
    const botTitle = document.createElement('div'); botTitle.id='menuTitle'; botTitle.textContent='🤖 Bot Config';
    botContent.appendChild(botTitle);

    const respawnBtn = document.createElement('button'); respawnBtn.className='rd-button'; respawnBtn.textContent='Disable Respawn';
    botContent.appendChild(respawnBtn);

    const chatToggleBtn = document.createElement('button'); chatToggleBtn.className='rd-button'; chatToggleBtn.textContent='Chat Spam: ON';
    botContent.appendChild(chatToggleBtn);

    const moveToggleBtn = document.createElement('button'); moveToggleBtn.className='rd-button'; moveToggleBtn.textContent='Bot Movement: ON';
    botContent.appendChild(moveToggleBtn);

    const respawnIndicator = document.createElement('div'); respawnIndicator.className='indicator active'; respawnIndicator.textContent='Respawn Enabled';
    botContent.appendChild(respawnIndicator);


    let chatEnabled = true;
    let movementEnabled = true;
    let respawnEnabled = true;

    respawnBtn.addEventListener('click', ()=>{ respawnEnabled=false; respawnIndicator.textContent='Respawn Disabled'; respawnIndicator.classList.remove('active'); });
    chatToggleBtn.addEventListener('click', ()=>{ chatEnabled=!chatEnabled; chatToggleBtn.textContent=`Chat Spam: ${chatEnabled?'ON':'OFF'}`; bots.forEach(b=>b.chatIndex=0); });
    moveToggleBtn.addEventListener('click', ()=>{ movementEnabled=!movementEnabled; moveToggleBtn.textContent=`Bot Movement: ${movementEnabled?'ON':'OFF'}`; bots.forEach(b=>b.autm.boolean=movementEnabled); });


    menu.appendChild(tabBar); menu.appendChild(musicContent); menu.appendChild(botContent); document.body.appendChild(menu);

    function switchTab(activeButton, activeContent){
        document.querySelectorAll(".tabButton").forEach(btn=>btn.classList.remove("active"));
        document.querySelectorAll(".tabContent").forEach(c=>c.classList.remove("active"));
        activeButton.classList.add("active"); activeContent.classList.add("active");
    }
    tabMusic.addEventListener("click",()=>switchTab(tabMusic,musicContent));
    tabBot.addEventListener("click",()=>switchTab(tabBot,botContent));

    document.addEventListener('keydown',e=>{ if(e.key==='Escape') menu.classList.toggle('open'); });


    const msgpackLite = window.msgpack;
    const NativeWebSocket = window.WebSocket;

    let mainSocket; let bots=[]; let ownPlayer={sid:null,x:0,y:0,dir:0,skinIndex:0,name:null};
    const chatMessages = [
    "Hello mooaddict",
    "I am hathu slave",
    "Watch out",
    "Run",
    "Attack",
    "Stay close",
    "Help me",
    "Gather wood",
    "Enemy here",
    "Follow me",
    "Build faster",
    "Need food",
    "Collect stone",
    "We are surrounded",
    "Stay alert",
    "Hide now",
    "Defend base",
    "Make weapons",
    "We need walls",
    "Get ready",
    "Nice job",
    "We got this",
    "Keep going",
    "Move quick",
    "Hold position",
    "Dont give up",
    "Im low health",
    "Im out of food",
    "Im out of wood",
    "They are coming",
    "Go left",
    "Go right",
    "Go back",
    "Go forward",
    "Stay behind me",
    "They are weak",
    "Im farming",
    "Need backup",
    "Keep distance",
    "Good teamwork",
    "We can win",
    "Nice defense",
    "Im crafting",
    "Wait for me",
    "Lets rush",
    "Lets raid",
    "Attack the base",
    "Protect me",
    "I need help",
    "Follow the plan",
    "Stay hidden",
    "Get gold",
    "Get food",
    "Get wood",
    "Get stone",
    "Im ready",
    "Im almost done",
    "Wait a second",
    "Come fast",
    "I see enemies",
    "They found us",
    "We lost it",
    "We won",
    "That was close",
    "That was easy",
    "They are strong",
    "We need towers",
    "Keep farming",
    "Stay near",
    "Dont move",
    "Im a pro trust me",
    "This base is art",
    "My spike is hungry",
    "I run faster scared",
    "No plan only chaos",
    "Im lag but I fight",
    "Cow squad on top",
    "We moo together",
    "Im speed in person",
    "Banana tactic go",
    "Im lost send help",
    "My brain left",
    "Build or cry",
    "They fear my hat",
    "Im not scared ok yes",
    "Run like your life",
    "Silent but deadly",
    "I see danger",
    "I smell danger",
    "Danger everywhere",
    "I believe in us",
    "Charge like heroes",
    "Focus target",
    "Keep pressure",
    "Break their hopes",
    "Moo power active",
    "Too many run",
    "My hand hurts",
    "Calm and destroy",
    "We fight proud",
    "Smart move",
    "Big brain plan",
    "Small brain moment",
    "Hit and run",
    "Push forward",
    "Retreat fast",
    "Hold the gate",
    "Guard the king",
    "Farm like beasts",
    "Never surrender",
    "Stay sharp",
    "Stay alive",
    "Almost victory",
    "We need magic",
    "Battle cry",
    "Keep the hype",
    "Trust the plan",
    "Plan is gone",
    "Hope is gone",
    "Im doing my best",
    "They are flanking",
    "Stay in group",
    "We lost the gate",
    "Hold strong",
    "I am defending",
    "I am attacking",
    "They push hard",
    "Watch the top",
    "Build traps",
    "Farm more",
    "More spikes needed",
    "Fix the gate",
    "Im watching mid",
    "Go defend bottom",
    "They hit base",
    "Rebuild walls",
    "Collect gold fast",
    "Upgrade base",
    "We need mills",
    "Hold the bridge",
    "Guard the side",
    "Farm zone clear",
    "Im leader now",
    "We go all in",
    "Stay hidden well",
    "They are camping",
    "Ambush them",
    "Flank right",
    "Flank left",
    "Charge now",
    "Defend the core",
    "They got traps",
    "Avoid spikes",
    "Place walls",
    "Keep crafting",
    "Push together",
    "Wait regroup",
    "We rebuild fast",
    "Dont panic",
    "Stay calm",
    "This is fun",
    "Nice teamwork",
    "We are legends",
    "They fear us",
    "We are unstoppable",
    "Base looks great",
    "That was smart",
    "My ping is bad",
    "I lag too much",
    "Im invisible now",
    "I am speed",
    "They cant stop me",
    "Im not dying",
    "Im eating berries",
    "Cow mode on",
    "Im building art",
    "Lag gives power",
    "Im peaceful",
    "They hit hard",
    "Ouch that hurt",
    "Im too good",
    "No mercy",
    "We moo again",
    "Respect the cow",
    "We rule this map",
    "Im born to win",
    "Sleep is for noobs",
    "Too easy",
    "One more fight",
    "This is chaos",
    "They panic now",
    "I see the base",
    "Charge now",
    "Move fast",
    "Keep running",
    "Dont look back",
    "Left side clear",
    "Right side safe",
    "We are hunters",
    "They are doomed",
    "Focus the king",
    "Guard the mills",
    "They rush mid",
    "Stay on hill",
    "We control map",
    "Hold for life",
    "They are lost",
    "Nice escape",
    "Close call",
    "Big fight ahead",
    "We can hold",
    "More traps needed",
    "That was intense",
    "We are still alive",
    "They rebuild fast",
    "Im low on gold",
    "Feed me wood",
    "Feed me stone",
    "Feed me food",
    "Feed me gold",
    "Base is safe",
    "Base is gone",
    "We are rich",
    "We are poor",
    "We can rebuild",
    "They failed attack",
    "We need allies",
    "We need cows",
    "We need spikes",
    "We need hope",
    "Im proud of us",
    "Good shot",
    "Nice hit",
    "Keep farming food",
    "Push the wall",
    "Reclaim land",
    "Moo gang rise",
    "No walls no fear",
    "I run circles",
    "I lag to win",
    "Im a builder cow",
    "We moo in peace",
    "They stole my mill",
    "Im chasing them",
    "We are raiders",
    "Cow army ready",
    "Attack formation",
    "Defend the herd",
    "Keep mooing",
    "Never stop mooing",
    "Stay focused",
    "Hold strong base",
    "Repair fast",
    "We hold line",
    "They broke gate",
    "Keep guard up",
    "They retreat",
    "Dont let escape",
    "Chase them all",
    "We take land",
    "I need tools",
    "Make gear fast",
    "Im collecting",
    "Build mill fast",
    "They spy us",
    "Hide mills",
    "Good strategy",
    "Big brain team",
    "Keep control",
    "Push line",
    "I got resources",
    "We share loot",
    "We are family",
    "We moo united",
    "Im not scared",
    "They are scared",
    "This is victory",
    "Easy claps",
    "Best team ever",
    "We are heroes",
    "The fight continues",
    "Stay with me",
    "We win again",
    "Lets end this",
    "Final push",
    "Stay in cover",
    "Watch tower up",
    "Collect fast",
    "Farm nonstop",
    "Never stop",
    "All good",
    "Nice plan",
    "Smart idea",
    "Lets chill",
    "We are cracked",
    "This is easy win",
    "We destroy all",
    "Hold the base",
    "Dont split up",
    "Together strong",
    "They rush us",
    "Stay quiet",
    "Prepare defense",
    "Final wave",
    "Dont lose hope",
    "Victory soon",
    "We stand tall",
    "Defend to end",
    "Time to strike",
    "Stay brave",
    "Go defend base",
    "Dont waste food",
    "Repair now",
    "Trap the gate",
    "Spike wall done",
    "Go raid now",
    "We can rebuild",
    "Stay together",
    "Im respawning",
    "They rush again"
];

    let randomHats=[28,29,30,36,37,38,42,43,44,49];

    async function safeDecode(event){
        try{
            let buf;
            if(event.data instanceof Blob) buf=new Uint8Array(await event.data.arrayBuffer());
            else if(event.data instanceof ArrayBuffer) buf=new Uint8Array(event.data);
            else return null;
            return msgpackLite.decode(buf);
        }catch{return null;}
    }

    function hookPacket(decoded){ if(!decoded) return null; return decoded.length>1 && Array.isArray(decoded[1]) ? [decoded[0], ...decoded[1]] : decoded; }

    class WebSocketProxy extends NativeWebSocket {
        constructor(...args){
            super(...args);
            if(!mainSocket){ mainSocket=this;
                this.addEventListener("message", async e=>{
                    let hooked=hookPacket(await safeDecode(e)); if(!hooked) return;
                    if(hooked[0]==="io-init"){ let region=mainSocket.url.split("/")[2]; const BOT_COUNT=3;
                        for(let i=0;i<BOT_COUNT;i++){ let token=await altSolver.generate(); bots.push(new BotClient(region,token)); }
                    }
                    if(hooked[0]==="C" && ownPlayer.sid==null) ownPlayer.sid=hooked[1];
                    if(hooked[0]==="D" && hooked[1][1]===ownPlayer.sid) ownPlayer.name=hooked[1][2];
                    if(hooked[0]==="a"){
                        for(let i=0;i<hooked[1].length/13;i++){ let p=hooked[1].slice(13*i,13*i+13); if(p[0]==ownPlayer.sid) [ownPlayer.x,ownPlayer.y,ownPlayer.dir,ownPlayer.skinIndex]=[p[1],p[2],p[3],p[9]]; }
                        for(let b of bots){ b.autm.x=ownPlayer.x; b.autm.y=ownPlayer.y; }
                    }
                });
            }
        }
    }
    window.WebSocket = WebSocketProxy;

    class BotClient {
        constructor(region, token){
            this.socket=new NativeWebSocket(`wss://${region}/?token=${token}`);
            this.sid=null; this.x=0; this.y=0; this.dir=0; this.weaponIndex=0; this.health=100; this.foodCount=100; this.packetCount=0;
            this.autm={x:0,y:0,boolean:true}; this.chatIndex=0; setInterval(()=>this.packetCount=0,1000);

            this.socket.addEventListener("open",()=>{
                setInterval(()=>{
                    if(this.sid && chatEnabled){ let msg=chatMessages[this.chatIndex]; this.sendMessage("6",msg); this.chatIndex=(this.chatIndex+1)%chatMessages.length; }
                },750);

                this.socket.addEventListener("message",async e=>{
                    let hooked=hookPacket(await safeDecode(e)); if(!hooked) return;
                    if(hooked[0]==="io-init" && respawnEnabled) this.spawn();
                    if(hooked[0]==="C" && this.sid==null) this.sid=hooked[1];
                    if(hooked[0]==="D" && hooked[1][1]===this.sid){ this.foodCount=100; this.health=100; }
                    if(hooked[0]==="a"){
                        for(let i=0;i<hooked[1].length/13;i++){ let p=hooked[1].slice(13*i,13*i+13); if(p[0]===this.sid) [this.x,this.y,this.dir,this.weaponIndex]=[p[1],p[2],p[3],p[5]]; }

                        this.equipIndex(0, randomHats[Math.floor(Math.random()*randomHats.length)],0);

                        if(this.autm.boolean){

                            let dx = this.autm.x - this.x;
                            let dy = this.autm.y - this.y;
                            let dist = Math.hypot(dx, dy);

                            if(dist > 5){
                                let ang = Math.atan2(dy, dx);
                                this.sendMessage("9", ang);
                            } else {
                                this.sendMessage("9", null);
                            }
                        }
                    }
                    if(hooked[0]==="P" && respawnEnabled) this.spawn();
                });
            });
        }

        spawn(){ if(!respawnEnabled) return; let randomSkin=Math.floor(Math.random()*15); this.sendMessage("M",{name:"goldbot",moofoll:true,skin:randomSkin}); }
        equipIndex(buy,id,index){ this.sendMessage("c",buy,id,index); }
        sendMessage(type,...args){ if(this.packetCount<120){ this.socket.send(new Uint8Array(msgpackLite.encode([type,args]))); this.packetCount++; } }
    }

    class AltSolver {
        constructor(){ this.core_count=Math.min(16,navigator.hardwareConcurrency||8); this.workers=[]; this.initialized=false; this.blobUrl=null; }

        initWorkerPool() {
            if(this.initialized) return;
            const workerCode = `
                importScripts('https://cdn.jsdelivr.net/npm/[email protected]/build/sha256.min.js');
                let challenge=null, salt=null;
                self.onmessage=function(e){
                    const data=e.data;
                    if(data.init){ challenge=data.challenge; salt=data.salt; self.postMessage({ready:true}); return; }
                    const {start,end}=data;
                    for(let i=start;i<=end;i++){ if(sha256(salt+i)===challenge){ self.postMessage({found:i}); return; } }
                    self.postMessage({done:true});
                };
            `;
            const blob=new Blob([workerCode],{type:"application/javascript"});
            this.blobUrl=URL.createObjectURL(blob);
            for(let i=0;i<this.core_count;i++) this.workers.push(new Worker(this.blobUrl));
            this.initialized=true;
        }

        async getChallenge(){
            const response=await fetch("https://api.moomoo.io/verify");
            return await response.json();
        }

        async solveChallenge(challengeData){
            this.initWorkerPool();
            const {challenge,salt,maxnumber}=challengeData;
            const segmentSize=Math.ceil(maxnumber/this.core_count);
            let solved=false, doneCount=0;

            return new Promise((resolve,reject)=>{
                const startTime=performance.now();
                const tasks=this.workers.map((worker,idx)=>({ start:idx*segmentSize, end:Math.min(maxnumber,(idx+1)*segmentSize-1) }));

                this.workers.forEach((worker,idx)=>{
                    worker.onmessage=e=>{
                        const msg=e.data;
                        if(msg.ready) worker.postMessage(tasks[idx]);
                        else if(msg.found!=null && !solved){
                            solved=true;
                            const number=msg.found;
                            const took=((performance.now()-startTime)/1000).toFixed(2);
                            resolve({challenge,salt,maxnumber,number,took});
                            this.cleanupWorkers();
                        } else if(msg.done){ doneCount++; if(!solved && doneCount===this.workers.length){ reject(new Error("Challenge not solved")); this.cleanupWorkers(); } }
                    };
                    worker.onerror=err=>{ if(!solved){ reject(err); this.cleanupWorkers(); } };
                    worker.postMessage({init:true,challenge,salt});
                });
            });
        }

        cleanupWorkers(){
            this.workers.forEach(w=>w.terminate());
            this.workers=[]; this.initialized=false;
            if(this.blobUrl){ URL.revokeObjectURL(this.blobUrl); this.blobUrl=null; }
        }

        static createPayload(Data,Date_){
            return btoa(JSON.stringify({
                algorithm:"SHA-256",
                challenge:Data.challenge,
                salt:Data.salt,
                number:Date_.number,
                signature:Data.signature||null,
                took:Date_.took
            }));
        }

        async generate(){
            const challengeData=await this.getChallenge();
            const solution=await this.solveChallenge(challengeData);
            this.code=`alt:${AltSolver.createPayload(challengeData,solution)}`;
            return this.code;
        }
    }

    let altSolver = new AltSolver();
})();