// ==UserScript== // @name HistoryCollUser - 自动下载完整版 // @namespace http://tampermonkey.net/ // @version 3.1 // @description 监控协作者变化,并自动触发下载以保存完整项目文件 // @author Argon // @match *://kitten4.codemao.cn/* // @match *://creation.codemao.cn/* // @grant none // @run-at document-idle // ==/UserScript== (function() { 'use strict'; const CONFIG = { AUTO_DOWNLOAD_INTERVAL: 10000, // 自动下载间隔(毫秒),默认60秒 SAVE_ON_NEW_USER: true, // 发现新协作者时自动下载 DEBUG_MODE: true }; function log(message) { if (CONFIG.DEBUG_MODE) console.log('[自动下载]', message); } // ==================== 核心功能:自动触发下载 ==================== function triggerDownload() { // 方法1:查找下载按钮并点击 const downloadBtn = findDownloadButton(); if (downloadBtn) { log('找到下载按钮,准备点击...'); downloadBtn.click(); log('已触发下载,文件将保存到浏览器默认下载目录'); return true; } // 方法2:如果没有找到按钮,尝试查找并触发保存函数 if (triggerSaveFunction()) { log('通过内部函数触发下载'); return true; } log('未找到下载按钮或保存函数', 'warn'); return false; } function findDownloadButton() { // 常见的下载按钮选择器 const selectors = [ '[title*="下载"]', '[title*="导出"]', 'button:contains("下载")', 'button:contains("导出")', '.download-btn', '.export-btn', '[aria-label*="下载"]', '[aria-label*="导出"]' ]; // 遍历所有可能的元素 const allElements = document.querySelectorAll('button, a, div, span, i'); for (const el of allElements) { const text = (el.innerText || el.title || '').toLowerCase(); if (text.includes('下载') || text.includes('导出') || text.includes('export') || text.includes('download')) { log(`找到潜在下载按钮: "${el.innerText}"`); return el; } } return null; } function triggerSaveFunction() { // 尝试查找全局保存函数 if (window.saveWork && typeof window.saveWork === 'function') { window.saveWork(); return true; } if (window.exportProject && typeof window.exportProject === 'function') { window.exportProject(); return true; } if (window.downloadProject && typeof window.downloadProject === 'function') { window.downloadProject(); return true; } return false; } // ==================== 协作者监控(原有功能) ==================== async function fetchJSON(url, options = {}) { try { const response = await fetch(url, { credentials: "include", headers: { "Content-Type": "application/json", ...options.headers }, ...options, }); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); return await response.json(); } catch (error) { log(`获取失败: ${error.message}`, 'error'); return null; } } let previousUserList = []; let currentWorkId = null; let monitorTimer = null; let downloadTimer = null; async function monitor() { if (!currentWorkId) return; try { const collUrl = `https://socketcoll.codemao.cn/coll/kitten/collaborator/${currentWorkId}?current_page=1&page_size=100`; const nowCollList = await fetchJSON(collUrl); const collUserList = nowCollList?.data?.items || []; const currentUserList = collUserList.map(u => u.nickname).filter(Boolean); const newUsers = currentUserList.filter(user => !previousUserList.includes(user)); if (newUsers.length > 0) { log(`发现新协作者: ${newUsers.join(", ")}`); if (CONFIG.SAVE_ON_NEW_USER) { log('发现新协作者,触发自动下载...'); setTimeout(() => triggerDownload(), 1000); } } previousUserList = currentUserList; } catch (error) { log(`监控出错: ${error.message}`, 'error'); } } function startMonitoring() { if (monitorTimer) clearInterval(monitorTimer); if (downloadTimer) clearInterval(downloadTimer); const hash = window.location.hash; const match = hash.match(/#(\d+)/); currentWorkId = match ? match[1] : null; if (!currentWorkId) { log("未找到作品ID", 'warn'); return; } log(`========================================`); log(`作品ID: ${currentWorkId}`); log(`协作者监控间隔: 5秒`); log(`自动下载间隔: ${CONFIG.AUTO_DOWNLOAD_INTERVAL / 1000}秒`); log(`💡 脚本将自动触发下载,文件会保存到浏览器默认目录`); log(`========================================`); monitor(); monitorTimer = setInterval(monitor, 5000); // 定时自动下载 if (CONFIG.AUTO_DOWNLOAD_INTERVAL > 0) { downloadTimer = setInterval(() => { log('定时自动下载...'); triggerDownload(); }, CONFIG.AUTO_DOWNLOAD_INTERVAL); } } // ==================== 全局控制台命令 ==================== window.HCUAuto = { download: triggerDownload, stop: () => { if (monitorTimer) clearInterval(monitorTimer); if (downloadTimer) clearInterval(downloadTimer); log('已停止所有定时任务'); }, config: CONFIG }; // ==================== 启动 ==================== window.addEventListener("hashchange", () => { log("检测到作品切换,重新初始化"); startMonitoring(); }); // 延迟启动,确保页面完全加载 setTimeout(startMonitoring, 3000); log("脚本已加载,输入 HCUAuto.download() 手动触发下载", 'info'); })();