Minefun Advanced Control & UI Mod

Bảng bàn phím ảo, Tâm nhắm tùy chỉnh (30 loại, 20 màu, 8 hiệu ứng), Text Galaxy, và Auto-loot nhanh cho Minefun.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Minefun Advanced Control & UI Mod
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Bảng bàn phím ảo, Tâm nhắm tùy chỉnh (30 loại, 20 màu, 8 hiệu ứng), Text Galaxy, và Auto-loot nhanh cho Minefun.
// @author       You
// @match        *://*.minefun.io/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // ==========================================
    // 1. CÀI ĐẶT CSS TỔNG HỢP VÀ HIỆU ỨNG
    // ==========================================
    const style = document.createElement('style');
    style.innerHTML = `
        /* Các class hệ thống */
        .no-select { user-select: none; }
        .hidden { display: none !important; }

        /* Bảng điều khiển nút Mở */
        #mod-toggle-btn {
            position: fixed; top: 10px; right: 10px; z-index: 10000;
            background: linear-gradient(45deg, #1a0033, #4d0099); color: white;
            border: 2px solid #8a2be2; padding: 5px 10px; border-radius: 5px;
            cursor: pointer; font-weight: bold; font-family: sans-serif;
            box-shadow: 0 0 10px #8a2be2;
        }

        /* Menu Cài Đặt */
        #mod-control-panel {
            position: fixed; top: 50px; right: 10px; z-index: 10000;
            background: rgba(10, 0, 20, 0.9); border: 2px solid #8a2be2;
            padding: 15px; border-radius: 8px; color: white;
            font-family: sans-serif; width: 250px; max-height: 80vh; overflow-y: auto;
            box-shadow: 0 0 20px #8a2be2;
        }
        #mod-control-panel h3 { margin-top: 0; text-align: center; color: #d896ff; }
        .panel-section { margin-bottom: 15px; }
        .panel-section select, .panel-section button {
            width: 100%; padding: 5px; margin-top: 5px;
            background: #2a004d; color: white; border: 1px solid #8a2be2;
            border-radius: 3px;
        }

        /* Bảng Bàn Phím Ảo (Có thể di chuyển) */
        #virtual-kb-container {
            position: fixed; top: 20px; left: 20px; z-index: 9998;
            background: transparent; pointer-events: none; /* Tránh lỗi click vào người chơi */
        }
        #kb-drag-handle {
            background: linear-gradient(90deg, #1a0033, #330066);
            color: #d896ff; text-align: center; font-size: 10px; padding: 3px;
            cursor: grab; pointer-events: auto; border: 1px solid #8a2be2;
            border-bottom: none; border-radius: 5px 5px 0 0;
        }
        #virtual-kb {
            display: flex; flex-direction: column; gap: 2px;
            background: rgba(10, 0, 30, 0.6); padding: 5px;
            border: 1px solid #8a2be2; border-radius: 0 0 5px 5px;
            pointer-events: auto; /* Cho phép click phím nếu cần, nhưng chủ yếu là hiển thị */
        }
        .kb-row {
            display: grid; gap: 2px;
        }
        /* Căn thẳng hàng các nút (sử dụng grid auto) */
        .kb-row-1 { grid-template-columns: repeat(9, 1fr); }
        .kb-row-2 { grid-template-columns: repeat(12, 1fr); }
        .kb-row-3 { grid-template-columns: repeat(22, 1fr); }

        .kb-key {
            background: linear-gradient(135deg, #10002b, #3c096c);
            color: #e0b1cb; text-align: center; padding: 4px 2px;
            font-size: 9px; font-weight: bold; border: 1px solid #5a189a;
            border-radius: 3px; transition: all 0.1s;
        }
        .kb-key.active {
            background: white !important; color: black !important;
            box-shadow: 0 0 10px white; transform: scale(0.95);
        }

        /* Tâm Nhắm (Crosshair) */
        #custom-crosshair {
            position: fixed; top: 50%; left: 50%;
            transform: translate(-50%, -50%);
            z-index: 9999; pointer-events: none;
            font-size: 24px; font-weight: bold;
            display: flex; justify-content: center; align-items: center;
        }

        /* Hiệu ứng Tâm Nhắm (8 Hiệu ứng) */
        .xh-effect-1 { animation: pulse 1.5s infinite; }
        .xh-effect-2 { animation: spin 4s linear infinite; }
        .xh-effect-3 { animation: shake 0.5s infinite; }
        .xh-effect-4 { animation: glowBreathe 2s infinite; }
        .xh-effect-5 { animation: fastSpin 1s linear infinite; }
        .xh-effect-6 { animation: bounce 1s infinite; }
        .xh-effect-7 { animation: rainbowGlow 3s infinite; }
        .xh-effect-8 { transform: translate(-50%, -50%) scale(1.5) rotate(45deg); }

        /* Hiệu ứng Bàn Phím (6 Hiệu ứng khi tĩnh) */
        .kb-effect-1 .kb-key { animation: kbBreathe 3s infinite; }
        .kb-effect-2 .kb-key { border-color: #ff00ff; }
        .kb-effect-3 .kb-key { box-shadow: inset 0 0 5px #00ffff; }
        .kb-effect-4 .kb-key { filter: hue-rotate(90deg); }
        .kb-effect-5 .kb-key { text-shadow: 0 0 5px white; }
        .kb-effect-6 .kb-key { opacity: 0.8; }

        /* Text Galaxy */
        .galaxy-text-mode {
            background: linear-gradient(to right, #ff0000, #ff7f00, #ffff00, #00ff00, #0000ff, #4b0082, #9400d3);
            -webkit-background-clip: text !important;
            color: transparent !important;
            animation: galaxyTextMove 5s linear infinite;
            background-size: 200% auto;
        }

        /* Animations */
        @keyframes pulse { 0% { transform: translate(-50%, -50%) scale(1); } 50% { transform: translate(-50%, -50%) scale(1.3); } 100% { transform: translate(-50%, -50%) scale(1); } }
        @keyframes spin { 100% { transform: translate(-50%, -50%) rotate(360deg); } }
        @keyframes fastSpin { 100% { transform: translate(-50%, -50%) rotate(-360deg); } }
        @keyframes shake { 0%, 100% { transform: translate(-50%, -50%) translateX(0); } 25% { transform: translate(-50%, -50%) translateX(-2px); } 75% { transform: translate(-50%, -50%) translateX(2px); } }
        @keyframes glowBreathe { 0%, 100% { text-shadow: 0 0 5px currentColor; } 50% { text-shadow: 0 0 20px currentColor, 0 0 30px currentColor; } }
        @keyframes bounce { 0%, 100% { transform: translate(-50%, -50%) translateY(0); } 50% { transform: translate(-50%, -60%) translateY(-5px); } }
        @keyframes rainbowGlow { 0% { filter: hue-rotate(0deg); } 100% { filter: hue-rotate(360deg); } }
        @keyframes kbBreathe { 0%, 100% { box-shadow: 0 0 2px #8a2be2; } 50% { box-shadow: 0 0 8px #d896ff; } }
        @keyframes galaxyTextMove { to { background-position: 200% center; } }
    `;
    document.head.appendChild(style);

    // ==========================================
    // 2. CƠ SỞ DỮ LIỆU TÙY CHỌN
    // ==========================================
    const keysRow1 = ['1','2','3','4','5','6','7','8','9'];
    const keysRow2 = ['W','Q','R','T','P','A','S','D','X','C','M','Shift'];
    const keysRow3 = ['Enter','Backspace','!','@','#','$','%','^','&','*','(',')','_','+','{','}','|',':','"','<','>','?'];

    const crosshairs = [
        "+", "x", "✛", "✜", "✥", "✦", "✧", "✩", "✪", "✫", 
        "✬", "✭", "✮", "✯", "✰", "✱", "✲", "✳", "✴", "✵", 
        "✶", "✷", "✸", "✹", "✺", "✻", "✼", "✽", "✾", "🖕"
    ];

    const colors = [
        {name: "Đỏ", val: "#ff0000"}, {name: "Xanh dương", val: "#0000ff"}, {name: "Xanh lá", val: "#00ff00"},
        {name: "Vàng", val: "#ffff00"}, {name: "Tím", val: "#800080"}, {name: "Lục lam", val: "#00ffff"},
        {name: "Cam", val: "#ffa500"}, {name: "Hồng", val: "#ffc0cb"}, {name: "Xanh chanh", val: "#00ff00"},
        {name: "Xanh cổ vịt", val: "#008080"}, {name: "Đỏ tươi", val: "#ff00ff"}, {name: "Nâu", val: "#a52a2a"},
        {name: "Trắng", val: "#ffffff"}, {name: "Đen", val: "#000000"}, {name: "Xám", val: "#808080"},
        {name: "Bạc", val: "#c0c0c0"}, {name: "Vàng kim", val: "#ffd700"},
        {name: "Galaxy 1", val: "linear-gradient(45deg, #ff00ff, #00ffff)"},
        {name: "Galaxy 2", val: "linear-gradient(90deg, #1a0033, #d896ff)"},
        {name: "Galaxy 3", val: "linear-gradient(to right, #ff7f00, #8a2be2)"}
    ];

    // Cài đặt mặc định
    let config = JSON.parse(localStorage.getItem('minefunModConfig')) || {
        kbX: 20, kbY: 20,
        xhChar: "+", xhColor: "#00ffff", xhEffect: "0", kbEffect: "0",
        galaxyText: false
    };

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

    // ==========================================
    // 3. TẠO GIAO DIỆN NGƯỜI DÙNG (UI)
    // ==========================================

    // Nút Bật/Tắt
    const toggleBtn = document.createElement('button');
    toggleBtn.id = 'mod-toggle-btn';
    toggleBtn.innerText = 'Bảng điều khiển';
    document.body.appendChild(toggleBtn);

    // Menu Điều Khiển
    const panel = document.createElement('div');
    panel.id = 'mod-control-panel';
    panel.className = 'hidden';
    panel.innerHTML = `
        <h3>⚙️ CÀI ĐẶT MOD</h3>
        <div class="panel-section">
            <label>Tâm nhắm (30 loại):</label>
            <select id="xh-select">${crosshairs.map((c, i) => `<option value="${i}">${c}</option>`).join('')}</select>
        </div>
        <div class="panel-section">
            <label>Màu tâm nhắm (20 màu):</label>
            <select id="xh-color-select">${colors.map((c, i) => `<option value="${i}">${c.name}</option>`).join('')}</select>
        </div>
        <div class="panel-section">
            <label>Hiệu ứng tâm nhắm (8 loại):</label>
            <select id="xh-effect-select">
                <option value="0">Không có</option>
                ${[1,2,3,4,5,6,7,8].map(i => `<option value="${i}">Hiệu ứng ${i}</option>`).join('')}
            </select>
        </div>
        <div class="panel-section">
            <label>Hiệu ứng bàn phím (6 loại):</label>
            <select id="kb-effect-select">
                <option value="0">Mặc định</option>
                ${[1,2,3,4,5,6].map(i => `<option value="${i}">Phong cách ${i}</option>`).join('')}
            </select>
        </div>
        <div class="panel-section">
            <button id="galaxy-text-btn">Chữ Galaxy: ĐANG TẮT</button>
        </div>
    `;
    document.body.appendChild(panel);

    // Tâm Nhắm (Crosshair Element)
    const crosshairEl = document.createElement('div');
    crosshairEl.id = 'custom-crosshair';
    document.body.appendChild(crosshairEl);

    // Bảng Bàn Phím
    const kbContainer = document.createElement('div');
    kbContainer.id = 'virtual-kb-container';
    kbContainer.style.left = config.kbX + 'px';
    kbContainer.style.top = config.kbY + 'px';

    const kbHandle = document.createElement('div');
    kbHandle.id = 'kb-drag-handle';
    kbHandle.innerText = '☰ Kéo để di chuyển';
    kbContainer.appendChild(kbHandle);

    const kbEl = document.createElement('div');
    kbEl.id = 'virtual-kb';
    
    function createRow(keys, rowClass) {
        let rowDiv = document.createElement('div');
        rowDiv.className = `kb-row ${rowClass}`;
        keys.forEach(k => {
            let keyDiv = document.createElement('div');
            keyDiv.className = 'kb-key';
            keyDiv.setAttribute('data-key', k.toLowerCase());
            keyDiv.innerText = k;
            rowDiv.appendChild(keyDiv);
        });
        return rowDiv;
    }

    kbEl.appendChild(createRow(keysRow1, 'kb-row-1'));
    kbEl.appendChild(createRow(keysRow2, 'kb-row-2'));
    kbEl.appendChild(createRow(keysRow3, 'kb-row-3'));
    kbContainer.appendChild(kbEl);
    document.body.appendChild(kbContainer);

    // ==========================================
    // 4. LOGIC XỬ LÝ (SỰ KIỆN & RÀNG BUỘC)
    // ==========================================

    // Cập nhật giao diện từ config
    function applyConfig() {
        // Cập nhật tâm nhắm
        crosshairEl.innerText = crosshairs[config.xhChar] || config.xhChar; // Fallback
        
        let colorObj = colors[config.xhColor] || colors[0];
        if(colorObj.val.includes('gradient')) {
            crosshairEl.style.background = colorObj.val;
            crosshairEl.style.webkitBackgroundClip = 'text';
            crosshairEl.style.color = 'transparent';
        } else {
            crosshairEl.style.background = 'none';
            crosshairEl.style.webkitBackgroundClip = 'border-box';
            crosshairEl.style.color = colorObj.val;
        }

        crosshairEl.className = config.xhEffect !== "0" ? `xh-effect-${config.xhEffect}` : '';
        kbEl.className = config.kbEffect !== "0" ? `kb-effect-${config.kbEffect}` : '';
        
        // Cập nhật UI Selectors
        document.getElementById('xh-select').value = crosshairs.indexOf(config.xhChar) !== -1 ? crosshairs.indexOf(config.xhChar) : 0;
        document.getElementById('xh-color-select').value = colors.findIndex(c => c.name === colorObj.name) !== -1 ? colors.findIndex(c => c.name === colorObj.name) : 0;
        document.getElementById('xh-effect-select').value = config.xhEffect;
        document.getElementById('kb-effect-select').value = config.kbEffect;

        // Xử lý Galaxy Text
        const textBtn = document.getElementById('galaxy-text-btn');
        if (config.galaxyText) {
            textBtn.innerText = "Chữ Galaxy: ĐANG BẬT";
            textBtn.style.background = "linear-gradient(45deg, #ff00ff, #00ffff)";
            enableGalaxyText(true);
        } else {
            textBtn.innerText = "Chữ Galaxy: ĐANG TẮT";
            textBtn.style.background = "#2a004d";
            enableGalaxyText(false);
        }
    }

    // Toggle Panel
    toggleBtn.addEventListener('click', () => {
        panel.classList.toggle('hidden');
    });

    // Lắng nghe thay đổi từ Panel
    document.getElementById('xh-select').addEventListener('change', (e) => { config.xhChar = crosshairs[e.target.value]; saveConfig(); applyConfig(); });
    document.getElementById('xh-color-select').addEventListener('change', (e) => { config.xhColor = e.target.value; saveConfig(); applyConfig(); });
    document.getElementById('xh-effect-select').addEventListener('change', (e) => { config.xhEffect = e.target.value; saveConfig(); applyConfig(); });
    document.getElementById('kb-effect-select').addEventListener('change', (e) => { config.kbEffect = e.target.value; saveConfig(); applyConfig(); });
    
    document.getElementById('galaxy-text-btn').addEventListener('click', () => {
        config.galaxyText = !config.galaxyText;
        saveConfig(); applyConfig();
    });

    // Kéo thả bàn phím
    let isDragging = false;
    let dragOffsetX, dragOffsetY;

    kbHandle.addEventListener('mousedown', (e) => {
        isDragging = true;
        dragOffsetX = e.clientX - kbContainer.offsetLeft;
        dragOffsetY = e.clientY - kbContainer.offsetTop;
    });

    document.addEventListener('mousemove', (e) => {
        if (!isDragging) return;
        let newX = e.clientX - dragOffsetX;
        let newY = e.clientY - dragOffsetY;
        kbContainer.style.left = newX + 'px';
        kbContainer.style.top = newY + 'px';
    });

    document.addEventListener('mouseup', () => {
        if (isDragging) {
            isDragging = false;
            config.kbX = kbContainer.offsetLeft;
            config.kbY = kbContainer.offsetTop;
            saveConfig();
        }
    });

    // Bắt sự kiện phím vật lý chớp trắng nút ảo
    const keyMap = {};
    document.querySelectorAll('.kb-key').forEach(el => {
        keyMap[el.getAttribute('data-key')] = el;
    });

    window.addEventListener('keydown', (e) => {
        let keyStr = e.key.toLowerCase();
        if (keyStr === ' ') keyStr = 'space'; // Xử lý nếu có phím cách
        if (keyMap[keyStr]) {
            keyMap[keyStr].classList.add('active');
        }
    });

    window.addEventListener('keyup', (e) => {
        let keyStr = e.key.toLowerCase();
        if (keyMap[keyStr]) {
            keyMap[keyStr].classList.remove('active');
        }
    });

    // Hàm áp dụng Text Galaxy
    function enableGalaxyText(enable) {
        // Sử dụng MutationObserver để áp dụng class galaxy cho các thẻ text phổ biến
        if (enable) {
            document.body.classList.add('global-galaxy-mode');
            if(!document.getElementById('galaxy-css')) {
                let s = document.createElement('style');
                s.id = 'galaxy-css';
                // Nhắm mục tiêu vào các thẻ chứa chữ thông dụng trong game (span, p, h1-h6, div có class text)
                s.innerHTML = `
                    span, p, h1, h2, h3, h4, h5, h6, a, label, .text, .name {
                        background: linear-gradient(to right, #ff0000, #ff7f00, #ffff00, #00ff00, #0000ff, #4b0082, #9400d3);
                        -webkit-background-clip: text !important;
                        color: transparent !important;
                        animation: galaxyTextMove 5s linear infinite;
                        background-size: 200% auto;
                    }
                `;
                document.head.appendChild(s);
            }
        } else {
            document.body.classList.remove('global-galaxy-mode');
            let s = document.getElementById('galaxy-css');
            if(s) s.remove();
        }
    }

    // ==========================================
    // 5. AUTO-LOOT (TỰ ĐỘNG NHẶT ĐỒ GỌN LẸ)
    // ==========================================
    // Tính năng chạy ngầm tự động 100%, không cần nút tắt/bật
    // Cách thức: Lắng nghe thao tác click vào các item drop trên màn hình (hoặc DOM)
    // và mô phỏng tổ hợp phím/click để chuyển nhanh vào Balo.
    document.addEventListener('mousedown', function(e) {
        // Giả sử các item trong minefun có class hoặc thuộc tính cụ thể,
        // Dưới đây là logic bắt click chuột trái (button 0)
        if (e.button === 0) {
            let target = e.target;
            
            // Nếu click trúng UI của bản mod thì bỏ qua (tránh xung đột)
            if (target.closest('#virtual-kb-container') || target.closest('#mod-control-panel') || target.closest('#mod-toggle-btn')) {
                return;
            }

            // Logic nhận diện Item (Thay đổi class tương ứng với cấu trúc DOM của Minefun nếu cần)
            // Đa số game web dùng class chứa từ 'item', 'slot', 'loot'
            let isItem = target.className && typeof target.className === 'string' && 
                         (target.className.toLowerCase().includes('item') || 
                          target.className.toLowerCase().includes('loot'));

            // Nếu không xác định rõ qua DOM, ta gửi phím tắt tự động (vd: Shift+Click) 
            // để hỗ trợ thao tác chuyển đổi nhanh của game.
            if(isItem || !target.className) {
                // Mô phỏng Double Click hoặc tổ hợp phím nếu game hỗ trợ quick-loot
                let eventClick = new MouseEvent('dblclick', {
                    bubbles: true, cancelable: true, view: window
                });
                target.dispatchEvent(eventClick);
            }
        }
    }, true); // Use capture phase để chạy trước các event khác

    // Khởi chạy
    applyConfig();

})();