// ==UserScript== // @name iKuuu自动签到(ScriptCat版) // @namespace https://bbs.tampermonkey.net.cn/ // @version 1.0.0 // @description 每日执行自动签到,支持自动登录和网络检测 // @author d3f4ult // @crontab * * once * * // @grant GM_xmlhttpRequest // @grant GM_log // @grant GM_notification // @grant GM_openInTab // @grant GM_closeNotification // @homepage https://ikuuu.one // ==/UserScript== return new Promise((resolve, reject) => { const CONFIG = { AUTO_LOGIN: false, // 是否启用自动登录 USERNAME: "", // 你的用户名 PASSWORD: "", // 你的密码 DOMAIN: "https://ikuuu.one", MAX_RETRIES: 3, // 最大重试次数 NETWORK_CHECK_INTERVAL: 1800000, // 检查网络的间隔时间(毫秒) MAX_WAIT_TIME: 3600000 // 最大等待时间(1小时) }; let errorCount = 0; let timeoutCount = 0; let networkCheckTimer = null; let scriptStartTime = Date.now(); // 检查网络连接 function checkNetwork() { GM_log("=== 开始网络检测 ==="); return new Promise((resolve) => { GM_xmlhttpRequest({ method: "HEAD", url: CONFIG.DOMAIN, timeout: 5000, // 增加超时时间到5秒 onload: (response) => { GM_log(`网络检测响应状态: ${response.status}`); // 只要收到响应就认为网络正常 if (response.status >= 200 && response.status < 600) { GM_log("网络检测成功"); resolve(true); } else { GM_log(`网络检测失败,状态码: ${response.status}`); resolve(false); } }, onerror: (error) => { GM_log(`网络检测失败,错误信息: ${error}`); resolve(false); }, ontimeout: () => { GM_log("网络检测请求超时"); resolve(false); } }); }); } // 显示通知 function showNotification(title, text, options = {}) { GM_notification({ title: `iKuuu - ${title}`, text, timeout: options.timeout || 5000, highlight: options.highlight || false, onclick: options.onclick }); } // 等待网络连接 function waitForNetwork() { GM_log("=== 进入网络等待函数 ==="); return new Promise(async (resolveMain, rejectMain) => { let isFirstCheck = true; let checkCount = 0; // 检查是否超时 const checkTimeout = () => { const elapsed = Date.now() - scriptStartTime; GM_log(`已等待时间: ${elapsed}ms, 最大等待时间: ${CONFIG.MAX_WAIT_TIME}ms`); if (elapsed > CONFIG.MAX_WAIT_TIME) { GM_log("达到最大等待时间,终止执行"); if (networkCheckTimer) { clearInterval(networkCheckTimer); networkCheckTimer = null; } showNotification('执行超时', '脚本等待网络连接时间过长,已终止执行', { highlight: true }); rejectMain('等待网络连接超时'); return true; } return false; }; // 网络检查函数 const doNetworkCheck = async () => { checkCount++; GM_log(`=== 开始第 ${checkCount} 次网络检查 ===`); if (checkTimeout()) { GM_log("检测到超时,停止检查"); return; } const isOnline = await checkNetwork(); GM_log(`网络检查结果: ${isOnline ? '在线' : '离线'}`); if (isOnline) { GM_log("检测到网络恢复"); if (networkCheckTimer) { GM_log("清除定时器"); clearInterval(networkCheckTimer); networkCheckTimer = null; } showNotification('网络正常', '网络连接正常,继续执行操作'); resolveMain(true); } else { GM_log(`网络仍然离线,isFirstCheck=${isFirstCheck}, hasTimer=${!!networkCheckTimer}`); if (isFirstCheck || !networkCheckTimer) { showNotification('等待网络', '网络连接不可用,等待恢复后继续执行...', { timeout: CONFIG.NETWORK_CHECK_INTERVAL * 2 }); GM_log("显示等待网络通知"); if (!networkCheckTimer) { GM_log(`设置定期检查,间隔:${CONFIG.NETWORK_CHECK_INTERVAL}ms`); networkCheckTimer = setInterval(() => { GM_log("定时器触发新的检查"); doNetworkCheck(); }, CONFIG.NETWORK_CHECK_INTERVAL); } } isFirstCheck = false; } }; // 开始首次检查 GM_log("开始首次网络检查"); await doNetworkCheck(); }); } // 自动登录 async function doLogin() { if (!await waitForNetwork()) return; if (!CONFIG.USERNAME || !CONFIG.PASSWORD) { showNotification('登录失败', '请先配置用户名和密码', { highlight: true }); reject('未配置登录信息'); return; } GM_xmlhttpRequest({ method: "POST", url: `${CONFIG.DOMAIN}/auth/login`, headers: { "Content-Type": "application/x-www-form-urlencoded" }, data: `email=${encodeURIComponent(CONFIG.USERNAME)}&passwd=${encodeURIComponent(CONFIG.PASSWORD)}`, timeout: 5000, onload: function (response) { try { const result = JSON.parse(response.responseText); if (result.ret === 1) { GM_log("登录成功"); autoCheck(); } else { showNotification('登录失败', result.msg, { highlight: true }); reject(result.msg); } } catch (error) { reject('登录响应解析失败'); } }, onerror: function (error) { reject('登录请求失败:' + error); }, ontimeout: function () { reject('登录请求超时'); } }); } // 修改检查登录状态函数中的判断逻辑 async function checkLogin() { GM_log("=== 开始检查登录状态 ==="); try { GM_log("等待网络连接..."); const networkAvailable = await waitForNetwork(); GM_log(`网络连接状态: ${networkAvailable}`); if (!networkAvailable) { GM_log("网络不可用,退出登录检查"); return; } GM_log("开始发送登录检查请求"); GM_xmlhttpRequest({ method: "GET", url: `${CONFIG.DOMAIN}/user`, timeout: 5000, onload: function (response) { GM_log(`登录检查响应: ${response.finalUrl}`); // 修改域名判断逻辑 if (response.finalUrl.includes('/auth/login')) { if (CONFIG.AUTO_LOGIN) { doLogin(); } else { showNotification('未登录', '请点击登录后重新运行脚本', { onclick: (id) => { GM_openInTab(`${CONFIG.DOMAIN}/auth/login`); GM_closeNotification(id); } }); reject("未登录"); } } else if (response.finalUrl.includes('/user')) { // 只要包含 /user 路径就认为是已登录 autoCheck(); } else { GM_log(`未知的响应URL: ${response.finalUrl}`); reject("网页跳转向了一个未知的网址"); } }, // ... 其余代码保持不变 ... }); } catch (error) { GM_log(`检查登录出错:${error}`); reject(error); } } // 执行签到 async function autoCheck() { if (!await waitForNetwork()) return; GM_xmlhttpRequest({ method: "POST", url: `${CONFIG.DOMAIN}/user/checkin`, timeout: 5000, onload: function (response) { try { const result = JSON.parse(response.responseText); GM_log("签到结果: " + JSON.stringify(result, null, 2)); if (result.ret === 1) { showNotification('签到成功', result.msg); resolve('签到成功'); } else { showNotification('签到失败', result.msg, { highlight: true }); reject('签到失败: ' + result.msg); } } catch (error) { reject('签到响应解析失败'); } }, onerror: async function () { if (errorCount < CONFIG.MAX_RETRIES) { errorCount++; GM_log(`签到失败,第 ${errorCount} 次重试...`); if (await waitForNetwork()) { setTimeout(autoCheck, 3000); } } else { showNotification('签到失败', '请检查网络连接或登录状态', { highlight: true }); reject(`签到失败:已重试${CONFIG.MAX_RETRIES}次`); } }, ontimeout: async function () { if (timeoutCount < CONFIG.MAX_RETRIES) { timeoutCount++; if (await waitForNetwork()) { setTimeout(autoCheck, 3000); } } else { showNotification('签到超时', '无法连接到服务器,请检查网络设置', { highlight: true }); reject(`签到超时:已重试${CONFIG.MAX_RETRIES}次`); } } }); } // 开始执行 checkLogin(); });