您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Tự động kiểm tra và thông báo kết quả khai thác
当前为
// ==UserScript== // @name Auto Mining Notifier // @namespace http://tampermonkey.net/ // @version 2.4 // @description Tự động kiểm tra và thông báo kết quả khai thác // @match https://cmangax2.com/* // @grant GM.xmlHttpRequest // @grant GM_notification // @connect api.telegram.org // @connect cmangax2.com // @connect discord.com // ==/UserScript== (function() { 'use strict'; const priorityItem = { "pet_heart_bag": "Túi thú tâm", "add_option": "Tinh Luyện Châu", "job_exp_3": "Thông Thạo Quyển Lv3", "job_exp_2": "Thông Thạo Quyển Lv2", "job_exp_1": "Thông Thạo Quyển Lv1", "medicinal_exp_1": "Tăng Ích Đan Lv1", "medicinal_exp_2": "Tăng Ích Đan Lv2", "medicinal_exp_3": "Tăng Ích Đan Lv3", "medicinal_exp_4": "Tăng Ích Đan Lv4", "equipment_upgrade_2": "Trung phẩm Thiên Mộc Thạch", "egg_super_fragment": "Mảnh trứng thần thú", "egg_rare": "Trứng hiếm", "pet_exp_chest" : "Rương thú đan" }; const priceInMarket = { "pet_heart_bag": 100, "add_option": 25, "job_exp_3": 3, "job_exp_2": 0.4, "job_exp_1": 0.1, "medicinal_exp_1": 1.2, "medicinal_exp_2": 2.4, "medicinal_exp_3": 5, "medicinal_exp_4": 8, "equipment_upgrade_2": 25, "egg_super_fragment": 5, "egg_rare": 35, "pet_exp_chest": 5 }; const RARE_COLORS = { 4: { name: '🔥 Truyền Thuyết', color: '#ff0000' }, 3: { name: '📜 Sử Thi', color: '#c700ff' }, 2: { name: '🛡️ Hiếm', color: '#0099ff' }, 1: { name: '⚔️ Thường', color: '#666666' }, 0: { name: '❌ Không xác định', color: '#000000' } }; const NOTIFICATION_CONFIG = { TELEGRAM: { token: 'Thay bằng token bằng cách tìm botfather rồi nhập /mybots rồi chọn token', chatId: 'Thay bằng chat id bằng cách tìm userinfo rồi start là xong' }, DISCORD: { webhookUrl: 'https://discord.com/api/webhooks/1374401953374666864/sXgxVbDOPQDBK29JFfNqmBRs_K8ZRSxY5t-EQ9W7TAbzx6QWJKWmyp0ukbGVmMYwfqc6' // Thay thế bằng webhook của bạn }, MIN_VALUE: 10 }; let lastAttackTime = 0; const attackCooldown = 5 * 60 * 1000; // 5 phút dưới dạng milliseconds let isAttackInProgress = false; let lastSentHash = ''; // Lưu trạng thái lần gửi cuối let isRunning = false; // Cờ kiểm soát quá trình chạy const BLACK_LIST = [] const baseUrl= "https://cmangax2.com" const getCharacterId = () => { const scripts = document.getElementsByTagName('script'); for (const script of scripts) { // Regex cải tiến: Bắt cả trường hợp có khoảng trắng và dấu nháy const match = script.textContent.match(/my_character\s*=\s*['"]?(\d+)['"]?/); if (match) return parseInt(match[1], 10); } console.error('Không tìm thấy my_character trong script'); return null; }; const getMineEnergy = async () => { try { const characterId = getCharacterId(); if (!characterId) { console.error('Không tìm thấy character ID'); return 0; } const response = await fetch( `${baseUrl}/api/character_energy_mine?character=${characterId}` ); const data = await response.json(); return data.current || 0; } catch (e) { console.error('Lỗi khi check lượt đánh:', e); return 0; } }; const calculateValue = (reward) => { let total = 0; const validItems = []; for (const itemKey in reward) { if (priorityItem[itemKey]) { const amount = reward[itemKey].amount || 0; const price = priceInMarket[itemKey] || 0; if (amount > 0 && price > 0) { const value = amount * price; total += value; validItems.push({ [priorityItem[itemKey]]: amount }); } } } return { total, validItems }; }; const processMiner = async (miner, area, index) => { try { const data = JSON.parse(miner.data); const reward = data.miner?.reward; //const isProtect = data.miner?.protect === true; const isProtect = !!data.miner?.protect; if (!reward || typeof reward !== 'object' || isProtect) return null; const { total, validItems } = calculateValue(reward); if (total <= 0) return null; return { area: area, rare: data.rare, stt: index + 1, mine_id: parseInt(miner.id_score, 10), character_id: parseInt(miner.target, 10), author: data.miner?.info?.name, total_value: total, valid_items: validItems, isProtect:false }; } catch (e) { console.error(`Error processing miner: ${e}`); return null; } }; const processArea = async (area) => { try { const response = await fetch( `https://cmangax2.com/api/score_list?type=battle_mine&area=${area}` ); const miners = await response.json(); const minersPromises = miners.map((miner, index) =>processMiner(miner, area, index)); const areaResults = await Promise.all(minersPromises); return areaResults.filter(item => item !== null); } catch (e) { console.error(`Error processing area ${area}: ${e}`); GM_notification(`Lỗi khi xử lý tầng ${area}: ${e.message}`, 'Lỗi'); return []; } }; const processBattle = async (mine_id, target) => { try { const response = await fetch( `${baseUrl}/assets/ajax/character_activity.php`, { method: 'POST', headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: `action=battle_mine_challenge&mine_id=${mine_id}&target=${target}` } ); const responseText = await response.text(); // [DEBUG] Log toàn bộ response console.log('[DEBUG] Raw response:', responseText); console.log('[DEBUG] Response status:', response.status); const parser = new DOMParser(); const doc = parser.parseFromString(responseText, "text/html"); const scripts = doc.getElementsByTagName('script'); let popupData = null; let isSuccess = false; let errorMessage = ''; // [DEBUG] Log danh sách scripts console.log('[DEBUG] Found scripts:', scripts.length); for (const script of scripts) { const scriptContent = script.textContent; console.log('[DEBUG] Script content:', scriptContent); if (scriptContent.includes("alertify.success('Khiêu chiến thành công')")) { isSuccess = true; console.log('[DEBUG] Detected success message'); } if (scriptContent.includes("alertify.error")) { const errorMatch = scriptContent.match(/alertify\.error\('([^']+)'/); errorMessage = errorMatch ? errorMatch[1] : 'Lỗi không xác định'; console.log('[DEBUG] Detected error message:', errorMessage); } if (scriptContent.startsWith('popup_data =')) { const dataString = scriptContent .replace('popup_data =', '') .replace(/;[\s\S]*$/, ''); console.log('[DEBUG] Raw popup_data string:', dataString); try { popupData = JSON.parse(dataString.trim()); console.log('[DEBUG] Parsed popup_data:', popupData); } catch (e) { console.error('[DEBUG] Lỗi parse popup_data:', e); } } } // [DEBUG] Log kết quả cuối cùng console.log('[DEBUG] Final result:', { success: isSuccess, popupData: popupData, error: errorMessage, rawResponse: responseText // Thêm cả response gốc để debug }); return { success: isSuccess, popupData: popupData, error: errorMessage, rawResponse: responseText // Trả về response gốc }; } catch (error) { console.error('[DEBUG] Lỗi processBattle:', { error: error, stack: error.stack }); return { success: false, error: error.message, rawResponse: null }; } }; const getHmkLevel = async () => { const areas = Array.from({ length: 11 }, (_, i) => i + 1); const areaPromises = areas.map(area => processArea(area)); const allResults = await Promise.all(areaPromises); return allResults .flatMap(arr => arr) .sort((a, b) => b.total_value - a.total_value); }; const sendToTelegram = async (message) => { const token = '8178445381:AAEL5AHPsPcsLYZa5qQvnWPI-3EQI3gMj04'; const chatId = '5709122878'; return new Promise((resolve) => { GM.xmlHttpRequest({ method: 'POST', url: `https://api.telegram.org/bot${token}/sendMessage`, headers: { 'Content-Type': 'application/json' }, data: JSON.stringify({ chat_id: chatId, text: message, parse_mode: 'HTML' }), onload: (response) => { if (response.status !== 200) { console.error('Lỗi Telegram:', response.responseText); } resolve(); }, onerror: (error) => { console.error('Lỗi kết nối Telegram:', error); resolve(); } }); }); }; const sendToDiscord = async (message) => { return new Promise((resolve) => { GM.xmlHttpRequest({ method: 'POST', url: NOTIFICATION_CONFIG.DISCORD.webhookUrl, headers: { 'Content-Type': 'application/json' }, data: JSON.stringify({ content: '📢 Thông báo khai thác mới', embeds: [{ title: 'Chi tiết kết quả', description: message, color: 0x00ff00, timestamp: new Date().toISOString() }] }), onload: (response) => { if (response.status < 200 || response.status >= 300) { console.error('Lỗi Discord:', response.responseText); } resolve(); }, onerror: (error) => { console.error('Lỗi kết nối Discord:', error); resolve(); } }); }); }; const formatForDiscord = (filtered) => { const now = new Date(); const options = { timeZone: 'Asia/Ho_Chi_Minh', hour12: false, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }; const vnTime = new Intl.DateTimeFormat('vi-VN', options) .format(now) .replace(/(\d+)\/(\d+)\/(\d+),/, '$1-$2-$3'); let message = `📊 **KẾT QUẢ KHAI THÁC MỚI LÚC ${vnTime}**\n\n`; filtered.slice(0, 15).forEach((item, index) => { const rare = parseInt(item.rare) || 0; const rareInfo = RARE_COLORS[rare] || RARE_COLORS[0]; message += `🏷 **#${index + 1}**\n` + `├ Tầng: ${item.area}\n` + `├ Rare: ${rareInfo.name}\n` + `├ Vị trí: ${item.stt}\n` + `├ Mine id: ${item.mine_id}\n` + `├ Tác giả: ${item.author || 'Ẩn danh'} (ID: ${item.character_id})\n` + `├ Giá trị: ${item.total_value.toFixed(2)}💰\n` + `└ Vật phẩm:\n${item.valid_items.map(i => ` ↪ ${Object.keys(i)[0]} x${Object.values(i)[0]}` ).join('\n')}\n\n`; }); //console.log("message to discord", message) return message; }; const formatResults = (filtered) => { const now = new Date(); const options = { timeZone: 'Asia/Ho_Chi_Minh', hour12: false, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }; const vnTime = new Intl.DateTimeFormat('vi-VN', options) .format(now) .replace(/(\d+)\/(\d+)\/(\d+),/, '$1-$2-$3'); let message = `📊 <b>KẾT QUẢ KHAI THÁC MỚI LÚC ${vnTime}</b>\n\n`; filtered.slice(0, 15).forEach((item, index) => { const rare = parseInt(item.rare) || 0; const rareInfo = RARE_COLORS[rare] || RARE_COLORS[0]; message += `🏷 <b>#${index + 1}</b>\n` + `┣ Tầng: ${item.area}\n` + `┣ Rare: ${rareInfo.name}\n` + `┣ Vị ttrí ${item.stt}\n` + `├ Mine id: ${item.mine_id}\n` + `┣ Tác giả: ${item.author || 'Ẩn danh'} id: ${item.character_id}\n` + `┣ Giá trị: ${item.total_value.toFixed(2)}💰\n` + `┗ Vật phẩm: ${item.valid_items.map(i => `${Object.values(i)[0]}x${Object.keys(i)[0]}`).join('\n')}\n\n`; }); //console.log("message for tele", message) return message; }; const formatAttackResult = (mine, result) => { const now = new Date(); const status = result.success ? '✅ THÀNH CÔNG' : '❌ THẤT BẠI'; let message = `⚔️ **KẾT QUẢ TẤN CÔNG MỎ ${mine.mine_id}** (${status})\n` + `⏰ Thời gian: ${now.toLocaleString('vi-VN')}\n` + `🏷 Tầng: ${mine.area} | Rare: ${RARE_COLORS[mine.rare].name}\n` + `🎯 Mục tiêu: ${mine.author || 'Ẩn danh'} (ID: ${mine.character_id})\n`; if (result.success) { const gained = {}; const lost = {}; // Xử lý vật phẩm nhận được if (result.popupData) { message += "\n📥 **Nhận được:**\n"; for (const [key, value] of Object.entries(result.popupData)) { if (key !== 'gold' && key !== 'mine_ore') { const itemName = priorityItem[key] || key; gained[itemName] = value.amount; message += `- ${itemName}: ${value.amount}\n`; } } } // Tính toán vật phẩm mất đi if (mine.valid_items) { message += "\n📤 **Mất đi:**\n"; let hasLoss = false; mine.valid_items.forEach(originalItem => { const itemName = Object.keys(originalItem)[0]; const originalAmount = Object.values(originalItem)[0]; const gainedAmount = gained[itemName] || 0; const lostAmount = originalAmount - gainedAmount; if (lostAmount > 0) { hasLoss = true; message += `- ${itemName}: ${lostAmount}\n`; } }); if (!hasLoss) message += "- Không mất vật phẩm\n"; } } else { message += `\n📛 Lý do: ${result.error || 'Không xác định'}\n`; } message += `\n⏳ Thời gian chờ tiếp theo: ${new Date(lastAttackTime + attackCooldown).toLocaleTimeString('vi-VN')}`; console.log("du lieuj tan cong") return message; }; const checkAndNotify = async () => { if (isRunning || isAttackInProgress) return; isRunning = true; try { const results = await getHmkLevel(); const filtered = results.filter(item => item.total_value >= NOTIFICATION_CONFIG.MIN_VALUE && item.isProtect === false && !BLACK_LIST.includes(item.character_id) ); // Kiểm tra lượt đánh còn lại const remainingAttacks = await getMineEnergy(); const canAttack = remainingAttacks > 0; if (filtered.length > 0 && canAttack) { isAttackInProgress = true; const targetMine = filtered[0]; const battleResult = await processBattle(targetMine.mine_id, 'private'); // Cập nhật thông báo dựa trên kết quả const message = formatAttackResult(targetMine, battleResult); await Promise.all([ sendToTelegram(message), sendToDiscord(message) ]); GM_notification( `Tấn công mỏ ${battleResult.success ? 'thành công' : 'thất bại'}!`, 'Kết quả tấn công' ); isAttackInProgress = false; } // Thêm thông tin lượt đánh vào log console.log(`Lượt đánh còn lại: ${remainingAttacks}`); // Phần thông báo cũ về các mỏ const currentHash = JSON.stringify(filtered); if (filtered.length > 0 && currentHash !== lastSentHash) { lastSentHash = currentHash; const telegramMessage = formatResults(filtered); const discordMessage = formatForDiscord(filtered); await Promise.all([ sendToTelegram(telegramMessage), sendToDiscord(discordMessage) ]); } } catch (e) { GM_notification(`Lỗi hệ thống: ${e.message}`, 'Lỗi'); isAttackInProgress = false; } finally { isRunning = false; } }; //Kiểm tra định kỳ setTimeout(function runner() { checkAndNotify(); setTimeout(runner, 30000); }, 1000); })();