Tự động chủ động gọi API không cần click giao diện
// ==UserScript==
// @name Mine Manager - Auto Proactive
// @namespace http://tampermonkey.net/
// @version 1.2.1
// @description Tự động chủ động gọi API không cần click giao diện
// @author Gemini
// @match *://*/*
// @match *://*.cnovel.com/*
// @grant unsafeWindow
// @grant GM_setValue
// @grant GM_getValue
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
const isGameDomain = () => {
return /cmangax\d+\.com|cnovel|cmangapi/.test(location.hostname);
};
if (!isGameDomain()) return;
// ==================== CẤU HÌNH ====================
const CHECK_INTERVAL = 1 * 60 * 1000; // 5 phút check 1 lần
const HARVEST_THRESHOLD = 60; // Ngưỡng thu hoạch 60 phút
console.log('%c[Auto Mine] Script đã nạp. Chế độ: CHỦ ĐỘNG (Proactive)', 'color: #00ff00; font-weight: bold;');
// 1. Hàm lấy bảo mật từ window của game
const getGameWindow = () => {
return typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
}
const callGameFunc = (funcName, args = []) => {
const targetWindow = getGameWindow();
if (typeof targetWindow[funcName] === 'function') {
try {
return targetWindow[funcName](...args);
} catch (e) {
console.error(`Lỗi khi thực thi hàm ${funcName}:`, e);
return null;
}
}
return null;
}
function getSecurity() {
if (typeof unsafeWindow.send_user_security === 'function') {
return unsafeWindow.send_user_security();
}
return null;
}
let user_data = callGameFunc('get_user_security')
let currentTarget = user_data.character
// 2. HÀM QUAN TRỌNG: Tự gọi API score_list
async function checkMineStatus() {
console.log(`[Auto Mine] [${new Date().toLocaleTimeString()}] Đang tự động gửi request tới API...`);
const url = `/api/score_list?type=battle_mine_target&target=${currentTarget}&_=${Date.now()}`;
try {
const response = await fetch(url, {
method: 'GET',
credentials: 'include',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept': 'application/json'
}
});
const data = await response.json();
if (data && data.status === 1) {
console.log('[Auto Mine] Đã nhận dữ liệu API thành công.');
handleResponse(data);
} else {
console.warn('[Auto Mine] API trả về trạng thái lỗi (có thể do session hết hạn).');
}
} catch (error) {
console.error('[Auto Mine] Lỗi khi chủ động thực hiện fetch:', error);
}
}
function handleResponse(responseData) {
if (!responseData.data || responseData.data.length === 0) {
console.log('[Auto Mine] Không có dữ liệu ngồi mỏ. Đang chiếm lại mỏ cũ...');
const savedId = GM_getValue('lastMineId');
if (savedId) challengeMine(savedId);
return;
}
const mineEntry = responseData.data[0];
try {
const mineData = JSON.parse(mineEntry.data);
// Lấy "times" ở cấp ngoài của object miner như bạn yêu cầu
const times = mineData.miner.times || 0;
const mineId = mineEntry.id_score;
console.log(`[Auto Mine] Target: ${currentTarget} | Score_od: ${mineId} |Đã ngồi: ${times}/${HARVEST_THRESHOLD} phút`);
// Lưu dữ liệu để dùng lần sau (khi F5 trang)
GM_setValue('lastMineId', mineId);
GM_setValue('lastMineTarget', currentTarget);
if (times >= HARVEST_THRESHOLD) {
console.log('%c[Auto Mine] Đủ thời gian! Thực hiện thu hoạch ngay...', 'color: orange; font-weight: bold;');
takeMineReward();
}
} catch (e) {
console.error('[Auto Mine] Lỗi phân tích JSON từ API:', e);
}
}
// 4. Hàm Thu hoạch
async function takeMineReward() {
const security = getSecurity();
if (!security) return;
const formData = new FormData();
formData.append('action', 'battle_mine_take_reward');
formData.append('target', 'public');
if (typeof security === 'object') {
for (const key in security) {
formData.append(`user_security[${key}]`, security[key]);
}
}
try {
const res = await fetch('/assets/ajax/character_activity.php', {
method: 'POST',
body: formData,
credentials: 'include'
});
const result = await res.json();
console.log('[Auto Mine] Kết quả thu hoạch:', result);
} catch (e) { console.error('[Auto Mine] Lỗi thu hoạch:', e); }
}
// 5. Hàm Chiếm mỏ
async function challengeMine( mineId) {
const security = getSecurity();
if (!security) return;
const formData = new FormData();
formData.append('action', 'battle_mine_challenge');
formData.append('target', 'public');
formData.append('mine_id', mineId);
if (typeof security === 'object') {
for (const key in security) {
formData.append(`user_security[${key}]`, security[key]);
}
}
try {
const res = await fetch('/assets/ajax/character_activity.php', {
method: 'POST',
body: formData,
credentials: 'include'
});
const result = await res.json();
console.log('[Auto Mine] Kết quả chiếm mỏ:', result);
} catch (e) { console.error('[Auto Mine] Lỗi chiếm mỏ:', e); }
}
// ==================== KHỞI CHẠY ====================
function start() {
// Chạy lần đầu ngay lập tức khi load trang
checkMineStatus();
// Thiết lập lặp lại
setInterval(checkMineStatus, CHECK_INTERVAL);
console.log(`[Auto Mine] Hệ thống tự động đã bắt đầu. Chu kỳ: ${CHECK_INTERVAL/60000} phút.`);
}
// Đợi 3 giây sau khi trang load để đảm bảo các hàm của game đã sẵn sàng
window.addEventListener('load', () => {
setTimeout(start, 3000);
});
})();