Auto Claim Battle Mine Reward - Optimized

Tự động nhận phần thưởng Battle Mine - Phiên bản tối ưu hóa

当前为 2025-10-20 提交的版本,查看 最新版本

// ==UserScript==
// @name         Auto Claim Battle Mine Reward - Optimized
// @namespace    http://tampermonkey.net/
// @version      1.5
// @description  Tự động nhận phần thưởng Battle Mine - Phiên bản tối ưu hóa
// @author       Optimized by KeshiNguyen
// @match        *://*/*
// @run-at       document-idle
// @grant        GM.xmlHttpRequest
// @grant        GM_notification
// @connect      discord.com
// ==/UserScript==

(function() {
    'use strict';

    // Biến toàn cục để quản lý trạng thái
    const STATE = {
        isRunning: false,
        currentMineId: localStorage.getItem("cmanga_last_mine_id") || "",
        lastState: "",
        lastNotificationTime: 0,
        notificationCooldown: 30000, // 30 giây giữa các thông báo
        checkInterval: null,
        energyCheckInterval: null
    };

    const isGameDomain = () => {
        return /cmangax\d+\.com|cnovel/.test(location.hostname);
    };

    if (!isGameDomain()) return;

    // Hàm tiện ích để tạo delay
    const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

    // ======= QUẢN LÝ TIMEOUT VÀ INTERVAL =======
    const clearAllIntervals = () => {
        if (STATE.checkInterval) clearInterval(STATE.checkInterval);
        if (STATE.energyCheckInterval) clearInterval(STATE.energyCheckInterval);
        STATE.checkInterval = null;
        STATE.energyCheckInterval = null;
    };

    const RARE = {
        1: "Thường",
        2: "Hiếm",
        3: "Sử thi",
        4: "Truyền thuyết"
    };

    const NOTIFICATION_CONFIG = {
        DISCORD: {
            webhookUrl: 'https://discord.com/api/webhooks/1374401953374666864/sXgxVbDOPQDBK29JFfNqmBRs_K8ZRSxY5t-EQ9W7TAbzx6QWJKWmyp0ukbGVmMYwfqc6'
        }
    };

    // ======= TỐI ƯU HÓA GỬI THÔNG BÁO =======
    const shouldSendNotification = (type, scoreId) => {
        const now = Date.now();
        const currentState = `${type}_${scoreId || ''}`;

        // Kiểm tra trạng thái trùng lặp và thời gian làm mát
        if (currentState === STATE.lastState &&
            now - STATE.lastNotificationTime < STATE.notificationCooldown) {
            return false;
        }

        STATE.lastState = currentState;
        STATE.lastNotificationTime = now;
        return true;
    };

    const formatForDiscord = (result) => {
        if (!result) return null;

        const now = new Date();
        let embed = {
            title: 'Thông báo khai thác mới',
            color: 0x00ff00,
            timestamp: now.toISOString()
        };

        if (result.type === "miner") {
            if (!shouldSendNotification("mining", result.score_id)) return null;

            embed.description = `📊 **NGỒI KHOÁNG LÚC ${now.toLocaleString('vi-VN')}**\n\n` +
                `Vị trí::: Tầng ${result.area} loại ${result.rare} score_id: ${result.score_id}`;
        }
        else if (result.type === "is_kicked") {
            if (!shouldSendNotification("is_kicked")) return null;

            embed.description = `📊 **BỊ TẤN CÔNG KHOÁNG LÚC ${now.toLocaleString('vi-VN')}**\n\n` +
                `Bị tấn công bởi ${result.attacker ? `${result.attacker} với id ${result.id}` : 'ẩn danh'}`;
        }
        else {
            return null;
        }

        return embed;
    };

    const sendToDiscord = async (message) => {
        try {
            const embed = formatForDiscord(message);
            if (!embed) return;

            // Sử dụng fetch thay vì GM.xmlHttpRequest để giảm phụ thuộc
            const response = await fetch(NOTIFICATION_CONFIG.DISCORD.webhookUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ embeds: [embed] })
            });

            if (!response.ok) {
                console.error('Lỗi Discord:', await response.text());
            }
        } catch (error) {
            console.error('Lỗi khi gửi thông báo:', error);
        }
    };

    // ======= TỐI ƯU HÓA REQUEST =======
    const cachedFetch = (() => {
        const cache = new Map();
        return async (url, options = {}, cacheKey = url, ttl = 60000) => {
            const now = Date.now();
            const cached = cache.get(cacheKey);

            if (cached && now - cached.timestamp < ttl) {
                return cached.response.clone();
            }

            const response = await fetch(url, options);
            cache.set(cacheKey, {
                response: response.clone(),
                timestamp: now
            });

            return response;
        };
    })();

    // ======= PHẦN CHÍNH ĐƯỢC TỐI ƯU =======
    function startAutoClaim() {
        if (STATE.isRunning) return;
        STATE.isRunning = true;

        const SCORE_URL = `/api/score_list?type=battle_mine_target&target=${window.my_character}`;
        const CLAIM_URL = `/assets/ajax/character_activity.php`;
        const ENERGY_URL = `/api/character_energy_mine?character=${window.my_character}`;
        const CHARACTER_ACTIVITY_URL = `/assets/ajax/character_activity.php`;
        const OTHER_URL = `/api/get_data_by_id?table=game_character&data=other&id=${window.my_character}&v=${Date.now()}`;
        const NOTIFICATION_URL = `/api/user_notification?page=1&limit=50&user=${window.token_user}`;

        async function fetchScore() {
            try {
                const res = await cachedFetch(SCORE_URL, {}, SCORE_URL, 10000); // Cache 10 giây
                const json = await res.json();
                return Array.isArray(json) && json.length > 0 ? json[0] : null;
            } catch (err) {
                console.error('[x] Lỗi fetchScore:', err);
                return null;
            }
        }

        async function sendRequest(url, action) {
            try {
                const response = await fetch(url, {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/x-www-form-urlencoded",
                        "X-Requested-With": "XMLHttpRequest"
                    },
                    body: `action=${action}`
                });

                const responseText = await response.text();
                if (/alertify\.error/.test(responseText)) {
                    return { success: false, message: `Fail when sign activity with action ${action}` };
                } else if (/alertify\.success/.test(responseText)) {
                    return { success: true, message: `Sign activity with action ${action} successfully`, data: responseText };
                }

                return { success: false, message: "Unknown response" };
            } catch (err) {
                console.error("❌ Lỗi mạng khi gửi request:", err);
                return { success: false, message: `Network error: ${err}` };
            }
        }

        async function attack(mine_id) {
            if (!mine_id) {
                console.warn('[!] mine_id rỗng khi cố gắng tấn công. Bỏ qua.');
                return false;
            }

            try {
                const attack_res = await sendRequest(CHARACTER_ACTIVITY_URL, `battle_mine_challenge&mine_id=${mine_id}&target=public`);
                return attack_res.success;
            } catch (e) {
                console.error("Lỗi trong quá trình khiêu chiến:", e);
                return false;
            }
        }

        async function claimReward() {
            try {
                const res = await fetch(CLAIM_URL, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams({
                        action: 'battle_mine_take_reward',
                        target: 'public'
                    })
                });

                const result = await res.json();
                console.log('[✓] Nhận thưởng:', result);

                // Lập lịch kiểm tra lại sau 5 phút thay vì 1 phút
                setTimeout(checkAndClaimReward, 300000);
            } catch (err) {
                console.error('[x] Lỗi claimReward:', err);
                setTimeout(checkAndClaimReward, 60000);
            }
        }

        async function checkAndClaimReward() {
            if (!STATE.isRunning) return;

            try {
                let score_res = await fetchScore();

                if (!score_res) {
                    await handleNoScoreSituation();
                    return;
                }

                await handleScoreSituation(score_res);
            } catch (err) {
                console.error('[x] Lỗi checkAndClaim:', err);
                setTimeout(checkAndClaimReward, 60000);
            }
        }

        async function handleNoScoreSituation() {
            console.log('[!] Đã bị sút khỏi hmk');

            // Kiểm tra thông báo chỉ khi cần thiết
            const notifications = await fetchNotifications();
            if (!notifications || notifications.length === 0) {
                console.log('Không có thông báo nào');
                setTimeout(checkAndClaimReward, 300000); // Kiểm tra lại sau 5 phút
                return;
            }

            // Lấy thông tin bị tấn công
            const otherData = await fetchOtherData();
            const battle_mine_info = otherData?.battle_mine?.war?.info;
            const message = {
                id: battle_mine_info?.id,
                attacker: battle_mine_info?.name,
                type: "is_kicked"
            };

            await sendToDiscord(message);
            console.log("Đã gửi tới discord");

            // Kiểm tra năng lượng và tấn công lại nếu đủ
            const energy = await checkEnergy();
            if (parseInt(energy) > 6 && STATE.currentMineId) {
                const attackSuccess = await attack(STATE.currentMineId);
                if (attackSuccess) {
                    // Nếu tấn công thành công, kiểm tra lại ngay
                    setTimeout(checkAndClaimReward, 5000);
                } else {
                    setTimeout(checkAndClaimReward, 300000);
                }
            } else {
                setTimeout(checkAndClaimReward, 300000);
            }
        }

        async function handleScoreSituation(score_res) {
            STATE.currentMineId = score_res.id_score;
            localStorage.setItem("cmanga_last_mine_id", STATE.currentMineId);

            let data = JSON.parse(score_res.data);
            let miner = data?.miner;

            console.log(`[i] Thời gian hiện tại: ${miner.times} phút`);

            const message = {
                type: 'miner',
                rare: RARE[data?.rare],
                area: data?.area,
                score_id: score_res?.id_score
            };

            await sendToDiscord(message);
            console.log("Đã gửi tới discord");

            if (miner.times >= 60) {
                await claimReward();
            } else {
                const waitMinutes = 60 - miner.times;
                const waitMs = waitMinutes * 60000;
                console.log(`[~] Đợi ${waitMinutes} phút`);
                setTimeout(checkAndClaimReward, waitMs);

                // Thiết lập kiểm tra năng lượng mỗi 5 phút
                if (!STATE.energyCheckInterval) {
                    STATE.energyCheckInterval = setInterval(checkEnergy, 300000);
                }
            }
        }

        async function fetchNotifications() {
            try {
                const res = await cachedFetch(NOTIFICATION_URL, {}, NOTIFICATION_URL, 30000);
                return await res.json();
            } catch (err) {
                console.error('Lỗi fetch notifications:', err);
                return null;
            }
        }

        async function fetchOtherData() {
            try {
                const res = await cachedFetch(OTHER_URL, {}, OTHER_URL, 30000);
                const json = await res.json();
                return JSON.parse(json.other);
            } catch (err) {
                console.error('Lỗi fetch other data:', err);
                return null;
            }
        }

        async function checkEnergy() {
            try {
                const res = await cachedFetch(ENERGY_URL, {}, ENERGY_URL, 60000);
                const json = await res.json();
                console.log("current energy:::", json.current);
                return json.current;
            } catch (err) {
                console.error('Lỗi check energy:', err);
                return 0;
            }
        }

        // Bắt đầu kiểm tra
        console.log('🚀 Bắt đầu tự động nhận thưởng Battle Mine');
        checkAndClaimReward();

        // Thiết lập interval kiểm tra mỗi 5 phút để đảm bảo script vẫn chạy
        STATE.checkInterval = setInterval(checkAndClaimReward, 300000);
    }

    // Khởi động script khi trang tải xong
    window.addEventListener('load', async () => {
        try {
            // Tìm thông tin game
            const scripts = document.getElementsByTagName('script');
            let player_id, token_character, token_user;

            for (const script of scripts) {
                const playerMatch = script.textContent.match(/my_character\s*=\s*['"]?(\d+)['"]?/);
                const tokenUserMatch = script.textContent.match(/token_user\s*=\s*['"]?(\d+)['"]?/);
                const tokenCharMatch = script.textContent.match(/token_character\s*=\s*['"]?([a-zA-Z0-9]+)['"]?/);

                if (playerMatch && tokenCharMatch) {
                    player_id = parseInt(playerMatch[1], 10);
                    token_character = tokenCharMatch[1];
                    token_user = tokenUserMatch ? parseInt(tokenUserMatch[1], 10) : 0;
                    break;
                }
            }

            if (!player_id || !token_character) {
                console.error('Không tìm thấy thông tin player/token');
                return;
            }

            window.my_character = player_id;
            window.token_character = token_character;
            window.token_user = token_user;

            startAutoClaim();
        } catch (error) {
            console.error('Lỗi khi khởi động script:', error);
        }
    });

    // Dọn dẹp khi trang đóng hoặc reload
    window.addEventListener('beforeunload', () => {
        STATE.isRunning = false;
        clearAllIntervals();
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址