Minefun Advanced Auto-Scaffold Engine

Hệ thống Scaffold tự động bắt điểm, hook Three.js/WebSocket và dự đoán quỹ đạo di chuyển

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Minefun Advanced Auto-Scaffold Engine
// @namespace    http://tampermonkey.net/
// @version      2.5
// @description  Hệ thống Scaffold tự động bắt điểm, hook Three.js/WebSocket và dự đoán quỹ đạo di chuyển
// @match        https://minefun.io/*
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';

    // ==========================================
    // 1. CẤU HÌNH & TRẠNG THÁI HỆ THỐNG
    // ==========================================
    const CONFIG = {
        enabled: true,
        toggleKey: 'KeyB',
        slotKey: '1',               // Ô chứa block trên Hotbar
        cps: 20,                    // Tốc độ đặt block tối đa (lần/giây)
        reachDistance: 4.5,         // Khoảng cách tầm với tối đa
        aheadPrediction: 0.8,       // Hệ số dự đoán bước đi phía trước
        downOffset: 1.1,            // Độ sâu phát hiện lỗ hổng dưới chân
        autoExpand: true,           // Tự mở rộng sàn nếu đang chạy nhanh
        debugHUD: true              // Hiển thị bảng thông số kỹ thuật trên màn hình
    };

    const EngineState = {
        scene: null,
        camera: null,
        player: null,
        world: null,
        webSocket: null,
        playerPos: { x: 0, y: 0, z: 0 },
        playerVel: { x: 0, y: 0, z: 0 },
        playerRotation: { yaw: 0, pitch: 0 },
        lastPlaceTime: 0,
        blocksPlaced: 0
    };

    // ==========================================
    // 2. HOOK WEBSOCKET & CORE THREE.JS
    // ==========================================
    const NativeWebSocket = window.WebSocket;
    window.WebSocket = function (...args) {
        const ws = new NativeWebSocket(...args);
        EngineState.webSocket = ws;

        const originalSend = ws.send;
        ws.send = function (data) {
            // Phân tích gói tin gửi lên server (Position / Rotation / Block Place)
            try {
                if (typeof data === 'string' && data.startsWith('{')) {
                    const parsed = JSON.parse(data);
                    if (parsed.type === 'move' || parsed.type === 'position') {
                        if (parsed.x !== undefined) EngineState.playerPos = { x: parsed.x, y: parsed.y, z: parsed.z };
                    }
                }
            } catch (e) {}
            return originalSend.apply(this, arguments);
        };

        ws.addEventListener('message', (event) => {
            // Phân tích gói tin server trả về để đồng bộ thế giới
            try {
                if (typeof event.data === 'string' && event.data.startsWith('{')) {
                    const parsed = JSON.parse(event.data);
                    if (parsed.type === 'init' || parsed.type === 'world') {
                        console.log('[Scaffold Engine] Đồng bộ dữ liệu Thế giới thành công!');
                    }
                }
            } catch (e) {}
        });

        return ws;
    };

    // Intercept Three.js Scene & Camera thông qua Prototype
    const originalAdd = Object.prototype.add;
    let sceneCaptured = false;

    Object.defineProperty(Object.prototype, 'isScene', {
        get() {
            if (this.type === 'Scene' && !sceneCaptured) {
                EngineState.scene = this;
                sceneCaptured = true;
                console.log('[Scaffold Engine] Captured Three.js Scene Context:', this);
            }
            return this._isScene;
        },
        set(v) { this._isScene = v; },
        configurable: true
    });

    // ==========================================
    // 3. TOÁN HỌC VECTOR & RAYCASTING
    // ==========================================
    class Vector3D {
        constructor(x = 0, y = 0, z = 0) {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        add(v) { return new Vector3D(this.x + v.x, this.y + v.y, this.z + v.z); }
        sub(v) { return new Vector3D(this.x - v.x, this.y - v.y, this.z - v.z); }
        multiplyScalar(s) { return new Vector3D(this.x * s, this.y * s, this.z * s); }
        floor() { return new Vector3D(Math.floor(this.x), Math.floor(this.y), Math.floor(this.z)); }
        distanceTo(v) { return Math.sqrt((this.x - v.x) ** 2 + (this.y - v.y) ** 2 + (this.z - v.z) ** 2); }
    }

    function getLookingDirection(yaw, pitch) {
        const cosPitch = Math.cos(pitch);
        return new Vector3D(
            -Math.sin(yaw) * cosPitch,
            Math.sin(pitch),
            -Math.cos(yaw) * cosPitch
        );
    }

    // ==========================================
    // 4. BẮT ĐIỂM VÀ TÌM VỊ TRÍ ĐẶT BLOCK
    // ==========================================
    function scanForAirHole() {
        const rawPos = getPlayerPosition();
        if (!rawPos) return null;

        const vel = getPlayerVelocity();
        
        // Tính toán vị trí dự đoán tương lai dựa trên tốc độ di chuyển
        const predictedX = rawPos.x + vel.x * CONFIG.aheadPrediction;
        const predictedZ = rawPos.z + vel.z * CONFIG.aheadPrediction;
        const targetY = rawPos.y - CONFIG.downOffset;

        const checkPos = new Vector3D(predictedX, targetY, predictedZ).floor();

        // Kiểm tra xem vị trí mục tiêu có phải là không khí không
        if (isBlockEmpty(checkPos.x, checkPos.y, checkPos.z)) {
            // Tìm block hàng xóm gần nhất để tựa vào khi đặt
            const neighbor = findSolidNeighbor(checkPos);
            return {
                target: checkPos,
                neighbor: neighbor
            };
        }

        return null;
    }

    function isBlockEmpty(x, y, z) {
        // Trích xuất dữ liệu World từ Global hoặc Raycast qua Scene
        const world = EngineState.world || window.world || (window.game && window.game.world);
        if (world && typeof world.getBlock === 'function') {
            const block = world.getBlock(x, y, z);
            return !block || block === 0 || block.id === 0 || block.type === 'air';
        }

        // Phương án dự phòng Raycast thủ công qua Mesh trong Three.js
        if (EngineState.scene) {
            let foundSolid = false;
            EngineState.scene.traverse((obj) => {
                if (obj.isMesh && obj.position) {
                    const mx = Math.floor(obj.position.x);
                    const my = Math.floor(obj.position.y);
                    const mz = Math.floor(obj.position.z);
                    if (mx === x && my === y && mz === z) {
                        foundSolid = true;
                    }
                }
            });
            return !foundSolid;
        }

        return true;
    }

    function findSolidNeighbor(pos) {
        const offsets = [
            { x: 0, y: -1, z: 0, face: 'top' },
            { x: 1, y: 0, z: 0, face: 'west' },
            { x: -1, y: 0, z: 0, face: 'east' },
            { x: 0, y: 0, z: 1, face: 'north' },
            { x: 0, y: 0, z: -1, face: 'south' }
        ];

        for (const off of offsets) {
            const nx = pos.x + off.x;
            const ny = pos.y + off.y;
            const nz = pos.z + off.z;
            if (!isBlockEmpty(nx, ny, nz)) {
                return { x: nx, y: ny, z: nz, face: off.face };
            }
        }
        return null;
    }

    // ==========================================
    // 5. TRÍCH XUẤT THÔNG TIN PLAYER
    // ==========================================
    function getPlayerPosition() {
        if (EngineState.playerPos.x !== 0) return new Vector3D(EngineState.playerPos.x, EngineState.playerPos.y, EngineState.playerPos.z);
        
        const player = window.localPlayer || (window.game && window.game.player) || window.player;
        if (player && player.position) {
            return new Vector3D(player.position.x, player.position.y, player.position.z);
        }

        if (EngineState.scene) {
            // Tìm Camera trong Scene
            let camPos = null;
            EngineState.scene.traverse((child) => {
                if (child.isCamera || child.type === 'PerspectiveCamera') {
                    EngineState.camera = child;
                    camPos = child.position;
                }
            });
            if (camPos) return new Vector3D(camPos.x, camPos.y, camPos.z);
        }

        return null;
    }

    function getPlayerVelocity() {
        const player = window.localPlayer || (window.game && window.game.player) || window.player;
        if (player && player.velocity) {
            return new Vector3D(player.velocity.x, player.velocity.y, player.velocity.z);
        }
        return new Vector3D(EngineState.playerVel.x, EngineState.playerVel.y, EngineState.playerVel.z);
    }

    // ==========================================
    // 6. HỆ THỐNG THỰC THI THAO TÁC (INPUT SPOOFING)
    // ==========================================
    function executeBlockPlacement(holeData) {
        // Step 1: Chuyển Hotbar sang ô đặt Block
        selectHotbarSlot(CONFIG.slotKey);

        // Step 2: Đặt block trực tiếp qua gọi hàm nội bộ hoặc giả lập gói tin/chuột
        const game = window.game || window.Client;
        if (game && typeof game.placeBlock === 'function') {
            game.placeBlock(holeData.target.x, holeData.target.y, holeData.target.z);
            EngineState.blocksPlaced++;
            return;
        }

        // Gọi trực tiếp qua WebSocket nếu đã bắt được kết nối
        if (EngineState.webSocket && EngineState.webSocket.readyState === WebSocket.OPEN) {
            const packet = JSON.stringify({
                type: 'place',
                x: holeData.target.x,
                y: holeData.target.y,
                z: holeData.target.z,
                slot: parseInt(CONFIG.slotKey) - 1
            });
            EngineState.webSocket.send(packet);
            EngineState.blocksPlaced++;
        }

        // Giả lập sự kiện chuột phải chuẩn WebGL Canvas
        dispatchMouseEvents();
    }

    function selectHotbarSlot(slotChar) {
        const eventDown = new KeyboardEvent('keydown', {
            key: slotChar,
            code: `Digit${slotChar}`,
            keyCode: 48 + parseInt(slotChar),
            which: 48 + parseInt(slotChar),
            bubbles: true,
            cancelable: true
        });
        const eventUp = new KeyboardEvent('keyup', {
            key: slotChar,
            code: `Digit${slotChar}`,
            keyCode: 48 + parseInt(slotChar),
            which: 48 + parseInt(slotChar),
            bubbles: true,
            cancelable: true
        });

        window.dispatchEvent(eventDown);
        document.dispatchEvent(eventDown);
        setTimeout(() => {
            window.dispatchEvent(eventUp);
            document.dispatchEvent(eventUp);
        }, 5);
    }

    function dispatchMouseEvents() {
        const canvas = document.querySelector('canvas') || document.body;
        const rect = canvas.getBoundingClientRect();
        const cx = rect.left + rect.width / 2;
        const cy = rect.top + rect.height / 2;

        const mouseDown = new MouseEvent('mousedown', {
            button: 2, // Chuột phải
            buttons: 2,
            clientX: cx,
            clientY: cy,
            bubbles: true,
            cancelable: true
        });

        const mouseUp = new MouseEvent('mouseup', {
            button: 2,
            buttons: 0,
            clientX: cx,
            clientY: cy,
            bubbles: true,
            cancelable: true
        });

        canvas.dispatchEvent(mouseDown);
        setTimeout(() => canvas.dispatchEvent(mouseUp), 10);
    }

    // ==========================================
    // 7. GIAO DIỆN HIỂN THỊ TRẠNG THÁI (HUD OVERLAY)
    // ==========================================
    let hudElement = null;

    function createHUD() {
        if (!CONFIG.debugHUD || hudElement) return;

        hudElement = document.createElement('div');
        hudElement.style.position = 'fixed';
        hudElement.style.top = '15px';
        hudElement.style.left = '15px';
        hudElement.style.padding = '10px 14px';
        hudElement.style.backgroundColor = 'rgba(0, 0, 0, 0.75)';
        hudElement.style.color = '#00FFCC';
        hudElement.style.fontFamily = 'monospace';
        hudElement.style.fontSize = '12px';
        hudElement.style.borderRadius = '6px';
        hudElement.style.zIndex = '999999';
        hudElement.style.border = '1px solid #00FFCC';
        hudElement.style.pointerEvents = 'none';
        hudElement.style.boxShadow = '0 0 8px rgba(0,255,204,0.3)';
        document.body.appendChild(hudElement);
    }

    function updateHUD(targetInfo) {
        if (!hudElement) return;

        const pos = getPlayerPosition() || new Vector3D(0, 0, 0);
        hudElement.innerHTML = `
            <b style="color:#FFF;">[MINEFUN SCAFFOLD ENGINE]</b><br>
            Trạng thái: <span style="color:${CONFIG.enabled ? '#00FF00' : '#FF0000'}">${CONFIG.enabled ? 'ĐÃ BẬT [Phím B]' : 'ĐÃ TẮT [Phím B]'}</span><br>
            Vị trí Player: ${pos.x.toFixed(1)}, ${pos.y.toFixed(1)}, ${pos.z.toFixed(1)}<br>
            Lỗ hổng gần nhất: ${targetInfo ? `${targetInfo.target.x}, ${targetInfo.target.y}, ${targetInfo.target.z}` : 'Không phát hiện'}<br>
            Hotbar Slot: ${CONFIG.slotKey}<br>
            Blocks Đã Đặt: ${EngineState.blocksPlaced}
        `;
    }

    // ==========================================
    // 8. VÒNG LẶP CHÍNH (MAIN ENGINE LOOP)
    // ==========================================
    window.addEventListener('keydown', (e) => {
        if (e.code === CONFIG.toggleKey) {
            CONFIG.enabled = !CONFIG.enabled;
        }
    });

    function mainLoop() {
        requestAnimationFrame(mainLoop);

        if (CONFIG.debugHUD) createHUD();

        const holeData = scanForAirHole();
        updateHUD(holeData);

        if (!CONFIG.enabled) return;

        const now = Date.now();
        const minInterval = 1000 / CONFIG.cps;

        if (now - EngineState.lastPlaceTime < minInterval) return;

        if (holeData) {
            executeBlockPlacement(holeData);
            EngineState.lastPlaceTime = now;
        }
    }

    // Khởi chạy Engine khi trang tải xong
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => setTimeout(mainLoop, 1000));
    } else {
        setTimeout(mainLoop, 1000);
    }

})();