minehackV2

Scaffold + Legit KillAura + AdBypass (original logic) - Menu mở bằng Z

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

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

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

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

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)


// ==UserScript==
// @name         minehackV2
// @namespace    *://minefun.io/*
// @version      1.0
// @author       duc hanh pham
// @description  Scaffold + Legit KillAura + AdBypass (original logic) - Menu mở bằng Z
// @match        *://minefun.io/*
// @grant        none
// @license      MIT
// ==/UserScript==

(() => {
    // ------------------------------ Event bus ------------------------------
    var c = {
        listeners: {},
        activeKeys: new Set,
        on: function (e, t) { (this.listeners[e] || (this.listeners[e] = [])).push(t) },
        remove: function (e, t) { if (this.listeners[e]) this.listeners[e] = this.listeners[e].filter(i => i !== t) },
        emit: function (e, t) { if (this.listeners[e]) this.listeners[e].forEach(i => i(t)) },
        trackKey: function (e, t, i) {
            if (e === "keydown") h.handleKeyPress(i);
            if (e === "keydown" && !this.activeKeys.has(t)) {
                this.activeKeys.add(t);
                this.emit("keyPress", { key: t, code: i });
            }
            if (e === "keyup" && this.activeKeys.has(t)) {
                this.activeKeys.delete(t);
                this.emit("keyRelease", { key: t, code: i });
            }
        }
    };

    // ------------------------------ Notification ------------------------------
    var notificationContainer = null;
    function showNotification(e, t) {
        if (!notificationContainer) {
            notificationContainer = document.createElement("div");
            notificationContainer.style.cssText = "position:fixed;bottom:20px;right:20px;z-index:10000;display:flex;flex-direction:column;align-items:flex-end;gap:8px;pointer-events:none;";
            document.body.appendChild(notificationContainer);
        }
        let i = document.createElement("div");
        i.className = "NexMini-notification";
        i.style.cssText = `background:rgba(0,0,0,0.85);backdrop-filter:blur(8px);color:white;padding:8px 16px;border-radius:8px;font-family:sans-serif;font-size:14px;border-left:4px solid ${t ? "#4ade80" : "#ff5555"};box-shadow:0 4px 12px rgba(0,0,0,0.3);transform:translateX(120%);transition:transform 0.3s cubic-bezier(0.2,0.9,0.4,1.1);pointer-events:none;max-width:280px;white-space:nowrap;`;
        i.textContent = `${t ? "✅ Enabled" : "❌ Disabled"} : ${e}`;
        notificationContainer.appendChild(i);
        setTimeout(() => { i.style.transform = "translateX(0)" }, 10);
        setTimeout(() => {
            i.style.transform = "translateX(120%)";
            setTimeout(() => { if (i.parentNode) i.parentNode.removeChild(i) }, 300);
        }, 2500);
    }

    // ------------------------------ Base Module ------------------------------
    var a = class {
        constructor(e, t, i, n) {
            this.name = e;
            this.category = t;
            this.options = i || {};
            this.keybind = n || null;
            this.waitingForBind = false;
            this.isEnabled = false;
            this.toggle = this.toggle.bind(this);
        }
        onEnable() {}
        onDisable() {}
        onRender() {}
        onSettingUpdate() {}
        enable() {
            this.isEnabled = true;
            c.emit("module.update", this);
            this.onEnable();
        }
        disable() {
            this.isEnabled = false;
            c.emit("module.update", this);
            this.onDisable();
        }
        toggle() {
            if (this.isEnabled) {
                this.disable();
                showNotification(this.name, false);
            } else {
                this.enable();
                showNotification(this.name, true);
            }
        }
    };

    // ------------------------------ Game hooks ------------------------------
    var o = {
        get stores() {
            if (this._stores) return this._stores;
            try {
                let e = app._vnode.component.appContext.provides;
                let t = e[Object.getOwnPropertySymbols(e).find(i => e[i]._s)];
                return this._stores = t._s;
            } catch (err) {
                return null;
            }
        },
        get gameWorld() {
            try {
                return this.stores.get("gameState").gameWorld;
            } catch (err) {
                return null;
            }
        }
    };

    // ------------------------------ Packet helper (needed by some modules) ------------------------------
    var p = {
        toServer: {
            TIME_STEP_INFO: 1,
            REQUEST_RESPAWN: 4,
            GOT_DAMAGE: 27,
            PARKOUR_REQUEST_RESPAWN: 1004,
            ONE_BLOCK_REQUEST_RESPAWN: 1552,
            BED_WARS_REQUEST_RESPAWN: 1600,
            SANDBOX_REQUEST_RESPAWN: 1700
        },
        toClient: {
            SET_WALK_MODE: 41,
            SET_INVISIBLE_MODE: 42
        },
        listeners: {},
        packetListener(e, t) {
            Object.values(this.listeners).forEach(i => {
                let n = i(e, t);
                if (n != null) t = n;
            });
            o.gameWorld.server.msgsToSend.push(e, t);
        },
        init() {
            c.on("render", () => {
                if (o?.gameWorld?.server?.sendData && o.gameWorld.server.sendData !== this.packetListener) {
                    this._ogSend = o.gameWorld.server.sendData;
                    o.gameWorld.server.sendData = this.packetListener.bind(this);
                }
            });
        }
    };

    // ================== MODULES (ORIGINAL FROM NEXMINEVIP - KHÔNG CHẾ) ==================

    // ---------- Scaffold (original) ----------
    var ModScaffold = class extends a {
        constructor() {
            super("Scaffold", "Movement");
            this.desc = "Auto place blocks for you , helpful for bridging!";

            this.SC_SCAN_MS = 50;
            this.SC_AHEAD = 0.7;
            this.SC_SAME_TARGET_MS = 50;
            this.SC_IDLE_RESTORE_MS = 400;

            this.scData = null;
            this.scFloorY = null;
            this.scLastTarget = null;
            this.scLastPlace = 0;
            this.scIdleTimer = null;
            this.scKsOrigLookAt = null;
            this.scScanTimer = null;
        }

        log(msg) {
            try { console.log('[Scaffold] ' + msg); } catch (err) {}
        }

        getCtx() {
            try {
                const appEl = document.getElementById('app');
                const app = appEl && appEl.__vue_app__;
                const pinia = app && app.config && app.config.globalProperties && app.config.globalProperties.$pinia;
                if (!pinia || !pinia._s) return null;
                const gs = pinia._s.get('gameState');
                const gw = gs && gs.gameWorld;
                if (!gs || !gw || !gw.player || !gw.chunkManager || !gw.systemsManager) return null;
                return { gs: gs, gw: gw };
            } catch (err) {
                return null;
            }
        }

        findKSystem(gw) {
            try {
                const sm = gw.systemsManager;
                if (!sm) return null;
                const pools = [sm.activeSystems, sm.notActiveSystems];
                for (let i = 0; i < pools.length; i++) {
                    const arr = pools[i];
                    if (!arr || !Array.isArray(arr)) continue;
                    for (let j = 0; j < arr.length; j++) {
                        const s = arr[j];
                        if (s && s.model && s.animationsManager && s.playerModelRotationTo !== void 0 && s.config) return s;
                    }
                }
            } catch (err) {}
            return null;
        }

        setModelBackward(ks, yaw) {
            if (!ks) return;
            try {
                if (this.scKsOrigLookAt === null) this.scKsOrigLookAt = !!ks.config.modelAlwaysLookAtCurrRotation;
                ks.config.modelAlwaysLookAtCurrRotation = false;
                const bw = (typeof yaw === 'number' ? yaw : 0) + Math.PI;
                if (ks.model) ks.model.rotation.y = bw;
                if (typeof ks.playerModelRotationTo === 'number') ks.playerModelRotationTo = bw;
            } catch (err) {}
        }

        restoreModel(ks) {
            if (!ks) return;
            try {
                if (this.scKsOrigLookAt !== null) ks.config.modelAlwaysLookAtCurrRotation = this.scKsOrigLookAt;
                this.scKsOrigLookAt = null;
            } catch (err) {}
        }

        place(gw, ks, bx, by, bz, bid, yaw) {
            try {
                const cm = gw.chunkManager;
                if (!cm || !cm.blocks || !cm.blocks[bid]) return;
                if (cm.getBlock(bx, by, bz)) return;
                cm.setBlock(bx, by, bz, bid, true, true);
                this.setModelBackward(ks, yaw);
                if (ks && ks.animationsManager) {
                    try { ks.animationsManager.updateInput('Put', 1); } catch (err) {}
                }
                const ee = gw.eventEmitter;
                if (ee) {
                    try { ee.emit(50); } catch (err) {}
                    try { ee.emit(4, 'placed'); } catch (err) {}
                }
                if (this.scIdleTimer) clearTimeout(this.scIdleTimer);
                this.scIdleTimer = setTimeout(() => {
                    this.scIdleTimer = null;
                    this.restoreModel(ks);
                }, this.SC_IDLE_RESTORE_MS);
            } catch (err) {}
        }

        getMoveDir(p) {
            try {
                const v = p.velocity && p.velocity.velVec3;
                if (v && typeof v.x === 'number' && typeof v.z === 'number') {
                    const len = Math.sqrt(v.x * v.x + v.z * v.z);
                    if (len > 0.01) return { dx: v.x / len, dz: v.z / len };
                }
                const yaw = (p.rotation && typeof p.rotation.y === 'number') ? p.rotation.y : 0;
                return { dx: -Math.sin(yaw), dz: -Math.cos(yaw) };
            } catch (err) {
                return { dx: 0, dz: 0 };
            }
        }

        isValidBlock(def) {
            if (!def) return false;
            if (def.physTransp) return false;
            const n = typeof def.name === 'string' ? def.name.toLowerCase() : '';
            if (/rope|string|thread|cobweb|^web$|ladder|torch|flower|sapling|seed|button|lever|pressure|rail|carpet|slab|stair|door|trap|fence|gate|sign|banner|bed|skull|head|piston|observer|hopper|dropper|dispenser|chest|furnace|anvil|enchant|brewing|cauldron|beacon|jukebox|note|repeater|comparator|daylight|tripwire|redstone|torch|lever|button/i.test(n)) return false;
            return true;
        }

        tick() {
            if (!this.isEnabled) {
                this.onDisable();
                return;
            }
            const ctx = this.getCtx();
            if (!ctx) {
                this.scScanTimer = setTimeout(() => this.tick(), this.SC_SCAN_MS);
                return;
            }
            const gw = ctx.gw;
            const p = gw.player;
            const now = Date.now();

            if (!this.scData || !this.scData.ks) {
                const ks = this.findKSystem(gw);
                if (ks) this.scData = { ks: ks };
            }

            const cm = gw.chunkManager;
            if (!cm || !p) {
                this.scScanTimer = setTimeout(() => this.tick(), this.SC_SCAN_MS);
                return;
            }

            let bid = p.currentInventoryItemId;
            if (!(typeof bid === 'number' && bid > 0)) {
                this.scScanTimer = setTimeout(() => this.tick(), this.SC_SCAN_MS);
                return;
            }
            const def = (typeof bid === 'number' && bid > 0) ? (cm.blocks[bid] || (gw.items && gw.items[bid])) : null;
            if (!this.isValidBlock(def)) {
                this.scScanTimer = setTimeout(() => this.tick(), this.SC_SCAN_MS);
                return;
            }
            const pos = p.position;
            if (!pos || typeof pos.x !== 'number' || typeof pos.y !== 'number' || typeof pos.z !== 'number') {
                this.scScanTimer = setTimeout(() => this.tick(), this.SC_SCAN_MS);
                return;
            }
            const bx = Math.floor(pos.x);
            const by = Math.floor(pos.y) - 1;
            const bz = Math.floor(pos.z);
            if (this.scFloorY === null) this.scFloorY = by;
            if (cm.getBlock(bx, by, bz)) this.scFloorY = by;
            const dir = this.getMoveDir(p);
            const moving = Math.abs(dir.dx) > 0.05 || Math.abs(dir.dz) > 0.05;
            let tx = bx, tz = bz;
            if (moving) {
                tx = Math.floor(pos.x + dir.dx * this.SC_AHEAD);
                tz = Math.floor(pos.z + dir.dz * this.SC_AHEAD);
            }
            const ty = this.scFloorY;
            const targetKey = tx + '|' + ty + '|' + tz;
            if (targetKey === this.scLastTarget && now - this.scLastPlace < this.SC_SAME_TARGET_MS) {
                this.scScanTimer = setTimeout(() => this.tick(), this.SC_SCAN_MS);
                return;
            }
            if (!cm.getBlock(tx, ty, tz)) {
                this.place(gw, this.scData && this.scData.ks, tx, ty, tz, bid, (p.rotation && typeof p.rotation.y === 'number') ? p.rotation.y : 0);
                this.scLastTarget = targetKey;
                this.scLastPlace = now;
            }
            this.scScanTimer = setTimeout(() => this.tick(), this.SC_SCAN_MS);
        }

        onEnable() {
            this.onDisable();
            this.log('enabled');
            this.scData = null;
            this.scFloorY = null;
            this.scLastTarget = null;
            this.scLastPlace = 0;
            this.tick();
        }

        onDisable() {
            if (this.scScanTimer) {
                clearTimeout(this.scScanTimer);
                this.scScanTimer = null;
            }
            if (this.scIdleTimer) {
                clearTimeout(this.scIdleTimer);
                this.scIdleTimer = null;
            }
            this.restoreModel(this.scData && this.scData.ks);
            this.scData = null;
            this.scFloorY = null;
            this.scLastTarget = null;
            this.scLastPlace = 0;
            this.scKsOrigLookAt = null;
            this.log('disabled');
        }

        onSettingsChange() {}
    };

    // ---------- Legit KillAura (original) ----------
    var ModLegitKillAura = class extends a {
        constructor() {
            super("Legit KillAura", "Combat");
            this.desc = "Auto Hit Players , Mobs near you";

            this.set = {
                range: 4,
                rotation: 'Fast',
                targetPlayers: true,
                targetMobs: true
            };

            this.settings = [
                { type: 'slider', id: 'range', label: 'Range', min: 3, max: 6, step: 1 },
                { type: 'mode', id: 'rotation', label: 'Rotation', options: ['None', 'Fast'] },
                { type: 'bool', id: 'targetPlayers', label: 'Target Players' },
                { type: 'bool', id: 'targetMobs', label: 'Target Mobs' }
            ];

            this.LKA_TICK_BASE_MS = 40;
            this.LKA_TICK_JITTER_MS = 4;
            this.LKA_FAR_EPS = 0.1;
            this.LKA_OVERLAP_EPS = 0.01;
            this.LKA_OVERLAP_FAR = 0.5;
            this.LKA_FACE_EPS = 0.03;
            this.LKA_VIS_TURN = 0.5;
            this.LKA_VIS_HEAD_MIN = -0.95;
            this.LKA_VIS_HEAD_MAX = 1.2;
            this.LKA_THIRD_SCAN_TICKS = 5;
            this.LKA_OCC_LEAD = 0.05;
            this.LKA_PLAYER_HALF = { x: 0.3, y: 0.9, z: 0.3 };
            this.LKA_AIM_UP = 0.6;
            this.LKA_AIM_DOWN = 0.5;
            this.LKA_AIM_TOP = 0.9;
            this.LKA_AIM_STEEP_UP = 0.4;
            this.LKA_RANGE_EPS = 0.001;
            this.LKA_OCC_GUARD = 128;

            this.LKA_STYLE_SLAB = 2; this.LKA_STYLE_CUBE = 4; this.LKA_STYLE_CROSS = 5; this.LKA_STYLE_GARDEN = 6;
            this.LKA_STYLE_CARPET = 7; this.LKA_STYLE_LADDER = 8; this.LKA_STYLE_STAIRS = 9; this.LKA_STYLE_ARBITARY = 10;
            this.LKA_STYLE_GLASS = 11; this.LKA_STYLE_FLUID = 12; this.LKA_STYLE_FOLIAGE = 13; this.LKA_STYLE_INVIS_CUBE = 14;
            this.LKA_STYLE_TRAP_DOOR = 15; this.LKA_STYLE_DOOR = 16; this.LKA_STYLE_TUBULAR = 17; this.LKA_STYLE_VARIABLE = 18;

            this.LKA_STYLE_CROSS_AABBS = [[0.15, 0, 0.15, 0.85, 0.75, 0.85]];
            this.LKA_STYLE_GARDEN_AABBS = [[0.15, 0, 0.15, 0.85, 0.8, 0.85]];
            this.LKA_STYLE_CARPET_AABBS = [[0, 0, 0, 1, 2 / 32, 1]];
            this.LKA_STYLE_FULL_AABBS = [[0, 0, 0, 1, 1, 1]];

            this.LKA_STAIRS_AABBS = [[[0,0,0,1,0.5,1],[0,0.5,0,1,1,0.5]],[[0,0,0,1,0.5,1],[0,0.5,0,0.5,1,1]],[[0,0,0,1,0.5,1],[0,0.5,0.5,1,1,1]],[[0,0,0,1,0.5,1],[0.5,0.5,0,1,1,1]],[[0,0.5,0,1,1,1],[0,0,0,1,0.5,0.5]],[[0,0.5,0,1,1,1],[0,0,0,0.5,0.5,1]],[[0,0.5,0,1,1,1],[0,0,0.5,1,0.5,1]],[[0,0.5,0,1,1,1],[0.5,0,0,1,0.5,1]],[[0,0,0,1,0.5,1],[0,0.5,0,0.5,1,0.5]],[[0,0,0,1,0.5,1],[0,0.5,0.5,0.5,1,1]],[[0,0,0,1,0.5,1],[0.5,0.5,0.5,1,1,1]],[[0,0.5,0,1,1,1],[0.5,0,0,1,0.5,0.5]],[[0,0.5,0,1,1,1],[0,0,0,0.5,0.5,0.5]],[[0,0.5,0,1,1,1],[0,0,0.5,0.5,0.5,1]],[[0,0.5,0,1,1,1],[0.5,0,0.5,1,0.5,1]],[[0,0,0,1,0.5,1],[0,0.5,0,1,1,0.5],[0,0.5,0.5,0.5,1,1]],[[0,0,0,1,0.5,1],[0,0.5,0,0.5,1,1],[0.5,0.5,0.5,1,1,1]],[[0,0,0,1,0.5,1],[0,0.5,0.5,1,1,1],[0.5,0.5,0,1,1,0.5]],[[0,0,0,1,0.5,1],[0.5,0.5,0,1,1,1],[0,0.5,0,0.5,1,0.5]],[[0,0.5,0,1,1,1],[0,0,0,1,0.5,0.5],[0,0,0.5,0.5,0.5,1]],[[0,0.5,0,1,1,1],[0,0,0,0.5,0.5,1],[0.5,0,0.5,1,0.5,1]],[[0,0.5,0,1,1,1],[0,0,0.5,1,0.5,1],[0.5,0,0,1,0.5,0.5]],[[0,0.5,0,1,1,1],[0.5,0,0,1,0.5,1],[0,0,0,0.5,0.5,0.5]],[[0,0,0,1,0.5,1],[0,0.5,0,1,1,0.5],[0.5,0.5,0.5,1,1,1]],[[0,0,0,1,0.5,1],[0,0.5,0,0.5,1,1],[0.5,0.5,0,1,1,0.5]],[[0,0,0,1,0.5,1],[0,0.5,0.5,1,1,1],[0,0.5,0,0.5,1,0.5]],[[0,0,0,1,0.5,1],[0.5,0.5,0,1,1,1],[0,0.5,0.5,0.5,1,1]],[[0,0.5,0,1,1,1],[0,0,0,1,0.5,0.5],[0.5,0,0.5,1,0.5,1]],[[0,0.5,0,1,1,1],[0,0,0,0.5,0.5,1],[0.5,0,0,1,0.5,0.5]],[[0,0.5,0,1,1,1],[0,0,0.5,1,0.5,1],[0,0,0,0.5,0.5,0.5]],[[0,0.5,0,1,1,1],[0.5,0,0,1,0.5,1],[0,0,0.5,0.5,0.5,1]]];
            this.LKA_LADDER_AABBS = [[[0,0,0,1,1,0.0625]],[[0,0,0,0.0625,1,1]],[[0,0,0.9375,1,1,1]],[[0.9375,0,0,1,1,1]]];
            this.LKA_SLAB_AABBS = [[[0,0,0,1,0.5,1]],[[0,0.5,0,1,1,1]],[[0,0,0,0.5,1,1]],[[0.5,0,0,1,1,1]],[[0,0,0,1,1,0.5]],[[0,0,0.5,1,1,1]]];
            this.lkaOccBox = { min: { x: 0, y: 0, z: 0 }, max: { x: 0, y: 0, z: 0 } };

            this.lkaTimer = null;
            this.lkaTarget = null;
            this.lkaFaceYaw = null;
            this.lkaFacePitch = null;
            this.lkaFaceRealYaw = null;
            this.lkaFaceRealPitch = null;
            this.lkaSender = null;
            this.lkaSenderGw = null;
            this.lkaVisYaw = null;
            this.lkaVisPitch = null;
            this.lkaThirdSys = null;
            this.lkaThirdOrigExec = null;
            this.lkaThirdTick = 0;
        }

        log(msg) { console.log('[Legit KillAura] ' + msg); }

        getCtx() {
            try {
                const appEl = document.getElementById('app');
                const app = appEl && appEl.__vue_app__;
                const pinia = app && app.config && app.config.globalProperties && app.config.globalProperties.$pinia;
                if (!pinia || !pinia._s) return null;
                const gs = pinia._s.get('gameState');
                const gw = gs && gs.gameWorld;
                if (!gs || !gw || !gw.player || !gw.server || typeof gw.server.sendData !== 'function') return null;
                return { gs: gs, gw: gw };
            } catch (err) {
                return null;
            }
        }

        getEffectiveRange(ctx) {
            let r = this.set.range;
            if (typeof r !== 'number' || r < 3) r = 3;
            if (r > 6) r = 6;
            return r;
        }

        isRotationFast() {
            return this.set.rotation === 'Fast';
        }

        getEye(gw, p) {
            try {
                const comp = p && p.physicsPosComp;
                const lp = comp && comp.lerpPosTo;
                if (lp && typeof lp.x === 'number' && typeof lp.y === 'number' && typeof lp.z === 'number') {
                    return { x: lp.x, y: lp.y + ((p && p.collision && p.collision.height) || 1.8), z: lp.z };
                }
            } catch (err) {}
            try {
                const cam = gw.threeScene && (gw.threeScene.camera || gw.threeScene.activeCamera);
                const r = cam && cam.userData && cam.userData.raycastStartV3;
                if (r && typeof r.x === 'number' && typeof r.y === 'number' && typeof r.z === 'number') {
                    return { x: r.x, y: r.y, z: r.z };
                }
            } catch (err) {}
            try {
                const pos = p && p.position;
                if (pos && typeof pos.x === 'number' && typeof pos.y === 'number' && typeof pos.z === 'number') {
                    return { x: pos.x, y: pos.y + ((p && p.collision && p.collision.height) || 1.8), z: pos.z };
                }
            } catch (err) {}
            return null;
        }

        getPlayerPos(p) {
            try {
                if (p.model && p.model.position) return p.model.position;
                if (p.position) return p.position;
            } catch (err) {}
            return null;
        }

        getMobPos(m) {
            try {
                if (m.model && m.model.position) return m.model.position;
                if (m.position) return m.position;
            } catch (err) {}
            return null;
        }

        getHalfExtents(m) {
            try {
                if (m.collision && m.collision.halfExtents) return m.collision.halfExtents;
                if (m.halfExtents) return m.halfExtents;
            } catch (err) {}
            return { x: 0.3, y: 0.9, z: 0.3 };
        }

        getMobAimYOffset(m) {
            try {
                const half = this.getHalfExtents(m);
                return half.y * 0.6;
            } catch (err) {
                return 0.9;
            }
        }

        checkBoxPre(eye, center, half, reach) {
            const dx = Math.abs(center.x - eye.x) - half.x;
            const dy = Math.abs(center.y - eye.y) - half.y;
            const dz = Math.abs(center.z - eye.z) - half.z;
            const dist = Math.sqrt(Math.max(0, dx) ** 2 + Math.max(0, dy) ** 2 + Math.max(0, dz) ** 2);
            return dist <= reach + 0.5;
        }

        getEntry(eye, center, half, dir) {
            let tmin = -Infinity, tmax = Infinity;
            const axes = ['x', 'y', 'z'];
            for (let i = 0; i < 3; i++) {
                const a = axes[i];
                const o = eye[a], d = dir[a];
                const min = center[a] - half[a], max = center[a] + half[a];
                if (Math.abs(d) < 1e-8) {
                    if (o < min || o > max) return -1;
                } else {
                    let t1 = (min - o) / d;
                    let t2 = (max - o) / d;
                    if (t1 > t2) { const tmp = t1; t1 = t2; t2 = tmp; }
                    tmin = Math.max(tmin, t1);
                    tmax = Math.min(tmax, t2);
                    if (tmin > tmax) return -1;
                }
            }
            return tmin >= 0 ? tmin : (tmax >= 0 ? 0 : -1);
        }

        rankTarget(gw, eye, t, reach) {
            try {
                const c = t.center;
                const a = t.aim || c;
                const dx = a.x - eye.x, dy = a.y - eye.y, dz = a.z - eye.z;
                const len = Math.sqrt(dx * dx + dy * dy + dz * dz);
                if (len < 0.001) return { far: this.LKA_OVERLAP_FAR, aim: a };
                const dir = { x: dx / len, y: dy / len, z: dz / len };
                const entry = this.getEntry(eye, c, t.half, dir);
                if (entry < 0) return null;
                let far = Math.max(entry, this.LKA_FAR_EPS);
                if (dy / len > this.LKA_AIM_STEEP_UP) far = Math.min(len, reach);
                if (far > reach + this.LKA_RANGE_EPS) return null;
                return { far: far, aim: a };
            } catch (err) {
                return null;
            }
        }

        pickTarget(ctx, eye, reach) {
            let best = null, bestFar = Infinity;
            const gw = ctx.gw;
            try {
                if (this.set.targetPlayers !== false && gw.server && gw.server.players) {
                    gw.server.players.forEach((p, sid) => {
                        if (!p || p.isAlive === false || (gw.player && p.sessionId === gw.player.sessionId)) return;
                        const pos = this.getPlayerPos(p);
                        if (!pos) return;
                        const half = this.LKA_PLAYER_HALF;
                        const center = { x: pos.x, y: pos.y + half.y, z: pos.z };
                        const aim = { x: pos.x, y: center.y + half.y * this.LKA_AIM_UP, z: pos.z };
                        if (!this.checkBoxPre(eye, center, half, reach)) return;
                        const r = this.rankTarget(gw, eye, { center: center, half: half, aim: aim, kind: 'player' }, reach);
                        if (r && r.far < bestFar) { bestFar = r.far; best = { kind: 'player', id: sid, ref: p, center: center, half: half, aim: r.aim }; }
                    });
                }
                if (this.set.targetMobs !== false && gw.chunkManager && gw.chunkManager.mobsManagerSystem &&
                    gw.chunkManager.mobsManagerSystem.allMobs && gw.chunkManager.mobsManagerSystem.allMobs.forEach) {
                    gw.chunkManager.mobsManagerSystem.allMobs.forEach((m, id) => {
                        if (!m || m.isDying) return;
                        const pos = this.getMobPos(m);
                        if (!pos) return;
                        const half = this.getHalfExtents(m);
                        const center = { x: pos.x, y: pos.y + this.getMobAimYOffset(m), z: pos.z };
                        const aim = { x: pos.x, y: center.y + half.y * this.LKA_AIM_UP, z: pos.z };
                        if (!this.checkBoxPre(eye, center, half, reach)) return;
                        const r = this.rankTarget(gw, eye, { center: center, half: half, aim: aim, kind: 'mob' }, reach);
                        if (r && r.far < bestFar) { bestFar = r.far; best = { kind: 'mob', id: id, ref: m, center: center, half: half, aim: r.aim }; }
                    });
                }
            } catch (err) {}
            return best;
        }

        getTargetGeo(ctx, t) {
            try {
                if (t.kind === 'player') {
                    const p = ctx.gw.server.players && ctx.gw.server.players.get(t.id);
                    if (!p || p.isAlive === false) return null;
                    const pos = this.getPlayerPos(p);
                    if (!pos) return null;
                    const half = this.LKA_PLAYER_HALF;
                    const center = { x: pos.x, y: pos.y + half.y, z: pos.z };
                    const aim = { x: pos.x, y: center.y + half.y * this.LKA_AIM_UP, z: pos.z };
                    return { center: center, aim: aim, half: half, ref: p };
                }
                const mobs = ctx.gw.chunkManager && ctx.gw.chunkManager.mobsManagerSystem &&
                    ctx.gw.chunkManager.mobsManagerSystem.allMobs;
                const m = mobs && mobs.get(t.id);
                if (!m || m.isDying) return null;
                const pos = this.getMobPos(m);
                if (!pos) return null;
                const half = this.getHalfExtents(m);
                const center = { x: pos.x, y: pos.y + this.getMobAimYOffset(m), z: pos.z };
                const aim = { x: pos.x, y: center.y + half.y * this.LKA_AIM_UP, z: pos.z };
                return { center: center, aim: aim, half: half, ref: m };
            } catch (err) { return null; }
        }

        normYaw(y) {
            const r = y % (2 * Math.PI);
            return r < 0 ? r + 2 * Math.PI : r;
        }

        shortArc(a) {
            return (((a + Math.PI) % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI) - Math.PI;
        }

        faceTarget(gw, p, yaw, pitch) {
            try {
                const targetYaw = this.normYaw(yaw);
                const realYaw = p && p.rotation ? this.normYaw(p.rotation.y) : targetYaw;
                const realPitch = p && p.rotation ? p.rotation.x : pitch;

                const realYawMoved = this.lkaFaceRealYaw !== null &&
                    Math.abs(this.shortArc(realYaw - this.lkaFaceRealYaw)) > this.LKA_FACE_EPS;
                const realPitchMoved = this.lkaFaceRealPitch !== null &&
                    Math.abs(realPitch - this.lkaFaceRealPitch) > this.LKA_FACE_EPS;
                const realMoved = realYawMoved || realPitchMoved;
                const facingLost = realMoved && this.lkaFaceYaw !== null &&
                    Math.abs(this.shortArc(realYaw - this.lkaFaceYaw)) > this.LKA_FACE_EPS;
                const pitchLost = realMoved && this.lkaFacePitch !== null &&
                    Math.abs(realPitch - this.lkaFacePitch) > this.LKA_FACE_EPS;
                const need = this.lkaFaceYaw === null ||
                    facingLost || pitchLost ||
                    Math.abs(this.shortArc(targetYaw - this.lkaFaceYaw)) > this.LKA_FACE_EPS ||
                    Math.abs(pitch - this.lkaFacePitch) > this.LKA_FACE_EPS;

                if (!need) return;
                gw.server.sendData(1, { r: [Number(pitch.toFixed(3)), Number(targetYaw.toFixed(3))] });
                this.lkaFaceYaw = targetYaw;
                this.lkaFacePitch = pitch;
                this.lkaFaceRealYaw = realYaw;
                this.lkaFaceRealPitch = realPitch;
            } catch (err) {}
        }

        thirdPersonFrame(sys) {
            if (this.lkaVisYaw === null || !sys || !sys.model) return;
            const m = sys.model;
            const d = (((this.lkaVisYaw - m.rotation.y) + Math.PI) % (2 * Math.PI) + (2 * Math.PI)) % (2 * Math.PI) - Math.PI;
            m.rotation.y = m.rotation.y + d * this.LKA_VIS_TURN;
            const head = sys.headObj3D;
            if (head && this.lkaVisPitch !== null) {
                head.rotation.x = Math.max(this.LKA_VIS_HEAD_MIN, Math.min(this.LKA_VIS_HEAD_MAX, this.lkaVisPitch));
            }
        }

        wrapThirdPerson(gw) {
            try {
                const systems = gw.systemsManager && gw.systemsManager.activeSystems;
                if (!systems || !Array.isArray(systems)) return null;
                for (let i = 0; i < systems.length; i++) {
                    const s = systems[i];
                    if (s && s.gameWorld === gw && s.execute && typeof s.execute === 'function' &&
                        /PLAYER_ROTATION_SPEED_MULTIPLIER/.test(s.execute.toString())) {
                        if (s.execute.name === 'lkaThirdWrappedExecute') { this.lkaThirdSys = s; return s; }
                        const orig = s.execute;
                        const self = this;
                        s.execute = function lkaThirdWrappedExecute() {
                            const r = orig.apply(this, arguments);
                            try { self.thirdPersonFrame(this); } catch (err) {}
                            return r;
                        };
                        this.lkaThirdSys = s;
                        this.lkaThirdOrigExec = orig;
                        return s;
                    }
                }
                return null;
            } catch (err) { return null; }
        }

        unwrapThirdPerson() {
            try {
                if (this.lkaThirdSys && this.lkaThirdOrigExec && this.lkaThirdSys.execute &&
                    this.lkaThirdSys.execute.name === 'lkaThirdWrappedExecute') {
                    this.lkaThirdSys.execute = this.lkaThirdOrigExec;
                }
            } catch (err) {}
            this.lkaThirdSys = null;
            this.lkaThirdOrigExec = null;
        }

        ensureThirdPerson(gw) {
            if (!this.isEnabled || !gw) { this.unwrapThirdPerson(); return; }
            if (!this.wrapThirdPerson(gw)) this.unwrapThirdPerson();
        }

        findSender(gw) {
            try {
                if (this.lkaSender && this.lkaSenderGw === gw && this.lkaSender.physDataToSend) return this.lkaSender;
                const systems = gw.systemsManager && gw.systemsManager.activeSystems;
                if (!systems || !Array.isArray(systems)) return null;
                for (let i = 0; i < systems.length; i++) {
                    const s = systems[i];
                    if (s && s.server && s.server.sendData && Array.isArray(s.physDataToSend) &&
                        typeof s.accumulator === 'number' && typeof s.prevLeftMB === 'boolean') {
                        this.lkaSender = s;
                        this.lkaSenderGw = gw;
                        return s;
                    }
                }
                return null;
            } catch (err) { return null; }
        }

        swing(gw) {
            try {
                if (gw.eventEmitter && typeof gw.eventEmitter.emit === 'function') gw.eventEmitter.emit(409);
                const sender = this.findSender(gw);
                if (!sender) return false;
                gw.server.sendData(1, { l: 1 });
                sender.prevLeftMB = true;
                return true;
            } catch (err) { return false; }
        }

        sendHit(ctx, target, eye, dir, far) {
            try {
                const gw = ctx.gw;
                const t = Number(gw.time && gw.time.localServerTimeMs) || 0;
                const s = t - 130;
                if (target.kind === 'player') {
                    gw.server.sendData(13, [s, eye.x, eye.y, eye.z, dir.x, dir.y, dir.z, far, target.id]);
                } else {
                    const m = target.ref;
                    const rotY = m && m.model && typeof m.model.rotation.y === 'number' ? m.model.rotation.y : 0;
                    gw.server.sendData(522, [eye.x, eye.y, eye.z, dir.x, dir.y, dir.z, s, Number(target.id), rotY]);
                }
            } catch (err) {}
        }

        step(ctx) {
            const gw = ctx.gw;
            const p = gw.player;
            const eye = this.getEye(gw, p);
            if (!eye) { this.lkaVisYaw = null; this.lkaVisPitch = null; return; }
            const reach = this.getEffectiveRange(ctx);

            this.lkaVisYaw = null;
            this.lkaVisPitch = null;
            let target = null;

            if (this.lkaTarget) {
                const kindOn = (this.lkaTarget.kind === 'player')
                    ? (this.set.targetPlayers !== false)
                    : (this.set.targetMobs !== false);
                if (kindOn) {
                    const geo = this.getTargetGeo(ctx, this.lkaTarget);
                    const r = geo && this.rankTarget(gw, eye, { center: geo.center, half: geo.half, aim: geo.aim, kind: this.lkaTarget.kind }, reach);
                    if (r) {
                        target = { kind: this.lkaTarget.kind, id: this.lkaTarget.id, ref: geo.ref, center: geo.center, half: geo.half, aim: r.aim };
                    } else {
                        this.lkaTarget = null;
                    }
                } else {
                    this.lkaTarget = null;
                }
            }

            if (!target) {
                const picked = this.pickTarget(ctx, eye, reach);
                if (!picked) { this.lkaTarget = null; return; }
                this.lkaTarget = { kind: picked.kind, id: picked.id };
                target = picked;
            }

            const c = target.center;
            const a = target.aim || c;
            const ccx = c.x - eye.x, ccy = c.y - eye.y, ccz = c.z - eye.z;
            const cLen = Math.sqrt(ccx * ccx + ccy * ccy + ccz * ccz);
            const dx = a.x - eye.x, dy = a.y - eye.y, dz = a.z - eye.z;
            const len = Math.sqrt(dx * dx + dy * dy + dz * dz);
            let dir, far;

            if (cLen < this.LKA_OVERLAP_EPS) {
                const ry = p.rotation ? p.rotation.y : 0;
                dir = { x: -Math.sin(ry), y: 0, z: -Math.cos(ry) };
                far = this.LKA_OVERLAP_FAR;
            } else {
                dir = { x: dx / len, y: dy / len, z: dz / len };
                const entry = this.getEntry(eye, c, target.half, dir);
                if (entry < 0) return;
                far = Math.max(entry, this.LKA_FAR_EPS);
                if (dy / len > this.LKA_AIM_STEEP_UP) {
                    far = Math.min(len, reach);
                }
            }

            const yaw = Math.atan2(-dir.x, -dir.z);
            const pitch = Math.asin(dir.y);

            if (this.isRotationFast()) {
                this.faceTarget(gw, p, yaw, pitch);
                this.lkaVisYaw = yaw;
                this.lkaVisPitch = pitch;
            }

            this.swing(gw);
            this.sendHit(ctx, target, eye, dir, far);
        }

        tick() {
            if (!this.isEnabled) return;
            const ctx = this.getCtx();
            if (ctx) {
                this.lkaThirdTick++;
                if (this.lkaThirdTick >= this.LKA_THIRD_SCAN_TICKS) {
                    this.lkaThirdTick = 0;
                    this.ensureThirdPerson(ctx.gw);
                }
                this.step(ctx);
            }
            const delay = this.LKA_TICK_BASE_MS + Math.floor(Math.random() * this.LKA_TICK_JITTER_MS);
            this.lkaTimer = setTimeout(() => this.tick(), delay);
        }

        onEnable() {
            this.onDisable();
            this.log('enabled');
            const ctx = this.getCtx();
            if (ctx) this.ensureThirdPerson(ctx.gw);
            this.tick();
        }

        onDisable() {
            if (this.lkaTimer) {
                clearTimeout(this.lkaTimer);
                this.lkaTimer = null;
            }
            this.lkaTarget = null;
            this.lkaFaceYaw = null;
            this.lkaFacePitch = null;
            this.lkaFaceRealYaw = null;
            this.lkaFaceRealPitch = null;
            this.lkaVisYaw = null;
            this.lkaVisPitch = null;
            this.unwrapThirdPerson();
            this.log('disabled');
        }

        onSettingsChange() {}
    };

    // ---------- AdBypass (original) ----------
    var ModAdBypass = class extends a {
        constructor() {
            super("AdBypass", "Misc");
        }
        onEnable() {
            this._reward = this._reward || o.stores.get("adsStore").rewardCommercialVideoWrapper;
            o.stores.get("adsStore").rewardCommercialVideoWrapper = () => true;
        }
        onDisable() {
            if (this._reward) {
                o.stores.get("adsStore").rewardCommercialVideoWrapper = this._reward;
            }
        }
    };

    // ================== SIMPLE GUI (mở bằng Z) ==================
    var menuOpen = false;
    var menuEl = null;

    function createMenu() {
        if (menuEl) return;
        menuEl = document.createElement("div");
        menuEl.id = "nexmini-menu";
        menuEl.style.cssText = `
            position: fixed;
            top: 80px;
            left: 80px;
            width: 220px;
            background: rgba(12, 10, 18, 0.95);
            border: 1px solid rgba(168, 85, 247, 0.7);
            border-radius: 10px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.6), 0 0 20px rgba(168,85,247,0.25);
            z-index: 999999;
            font-family: system-ui, sans-serif;
            color: #e9d5ff;
            display: none;
            overflow: hidden;
            user-select: none;
        `;

        menuEl.innerHTML = `
            <div style="padding:10px 12px;background:rgba(48,16,72,0.95);font-weight:700;font-size:14px;letter-spacing:1px;text-align:center;border-bottom:1px solid rgba(168,85,247,0.5);cursor:move;">
                NexMini • Z
            </div>
            <div id="nexmini-buttons" style="padding:6px;"></div>
        `;

        document.body.appendChild(menuEl);

        // Drag
        let dragging = false, ox = 0, oy = 0;
        const header = menuEl.firstElementChild;
        header.addEventListener("mousedown", e => {
            dragging = true;
            ox = e.clientX - menuEl.offsetLeft;
            oy = e.clientY - menuEl.offsetTop;
        });
        document.addEventListener("mousemove", e => {
            if (dragging) {
                menuEl.style.left = (e.clientX - ox) + "px";
                menuEl.style.top = (e.clientY - oy) + "px";
            }
        });
        document.addEventListener("mouseup", () => dragging = false);

        updateButtons();
    }

    function updateButtons() {
        const container = document.getElementById("nexmini-buttons");
        if (!container) return;
        container.innerHTML = "";

        Object.values(h.modules).forEach(mod => {
            const btn = document.createElement("div");
            btn.style.cssText = `
                padding: 8px 12px;
                margin: 3px 0;
                border-radius: 6px;
                cursor: pointer;
                font-size: 13px;
                font-weight: 600;
                transition: 0.15s;
                background: ${mod.isEnabled ? "linear-gradient(90deg, rgba(124,58,237,0.7), rgba(45,16,65,0.9))" : "rgba(30,25,40,0.8)"};
                border-left: 3px solid ${mod.isEnabled ? "#a855f7" : "transparent"};
                color: ${mod.isEnabled ? "#fff" : "#ccc"};
            `;
            btn.textContent = mod.name + (mod.isEnabled ? "  ●" : "");
            btn.addEventListener("click", () => {
                mod.toggle();
                updateButtons();
            });
            btn.addEventListener("mouseenter", () => {
                if (!mod.isEnabled) btn.style.background = "rgba(60,40,90,0.7)";
            });
            btn.addEventListener("mouseleave", () => {
                if (!mod.isEnabled) btn.style.background = "rgba(30,25,40,0.8)";
            });
            container.appendChild(btn);
        });
    }

    function toggleMenu() {
        createMenu();
        menuOpen = !menuOpen;
        menuEl.style.display = menuOpen ? "block" : "none";
        if (menuOpen) {
            if (document.pointerLockElement) document.exitPointerLock();
            updateButtons();
        }
    }

    // ================== Module Manager ==================
    var h = {
        modules: {},
        addModules(...classes) {
            for (let cls of classes) {
                let mod = new cls();
                this.modules[mod.name] = mod;
            }
        },
        handleKeyPress(code) {
            // Z = mở/đóng menu
            if (code === "KeyZ") {
                toggleMenu();
                return;
            }
            for (let name in this.modules) {
                let mod = this.modules[name];
                if (mod.waitingForBind) {
                    mod.keybind = code === "Escape" ? null : code;
                    mod.waitingForBind = false;
                } else if (mod.keybind === code) {
                    mod.toggle();
                    if (menuOpen) updateButtons();
                }
            }
        },
        init() {
            this.addModules(ModScaffold, ModLegitKillAura, ModAdBypass);

            c.on("render", () => {
                for (let name in this.modules) {
                    let mod = this.modules[name];
                    if (mod.isEnabled && mod.onRender) mod.onRender();
                }
            });

            c.on("keydown", this.handleKeyPress.bind(this));

            // Render loop
            setInterval(() => { c.emit("render"); }, 1000 / 60);

            window.addEventListener("keydown", e => {
                c.emit("keydown", e.code);
            }, { capture: true });

            p.init();

            console.log("%c[NexMini] Scaffold + LegitKillAura + AdBypass loaded | Press Z to open menu", "color:#a855f7;font-weight:bold");
        }
    };

    // Start
    function start() {
        if (document.readyState === "complete" || document.readyState === "interactive") {
            setTimeout(() => h.init(), 800);
        } else {
            document.addEventListener("DOMContentLoaded", () => setTimeout(() => h.init(), 800));
        }
    }
    start();
})();