// ==UserScript== // @name 智慧树全自动刷课助手(自动获取课程+勾选刷课) // @namespace zhihuishu-auto-select // @version 8.0.0 // @description 自动获取所有课程+勾选刷课+言溪题库自动答题+25分钟自动切课+防检测 // @author 精准适配 // @match *://*.zhihuishu.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_xmlhttpRequest // @connect tk.enncy.cn // @run-at document-idle // ==/UserScript== (function() { 'use strict'; // ===================== 基础配置区(面板可修改) ===================== const DEFAULT_CONFIG = { watchTime: 25, // 每门课观看时长(分钟) playbackRate: 1.25, // 播放倍速(最高1.5,防检测) autoSwitch: true, // 看完自动切换下一门 autoPlay: true, // 自动播放视频 autoClosePopup: true, // 自动关闭普通弹窗 autoAnswer: true, // 自动答题(弹题) reviewCompleted: true, // 复看已100%完成的课程(默认开启) useOnlineBankFirst: true, // 优先使用在线言溪题库 }; // ===================== 言溪题库配置 ===================== const YANXI_BANK_CONFIG = { name: "言溪题库", homepage: "https://tk.enncy.cn/", url: "https://tk.enncy.cn/query", method: "GET", token: "0abc866e094c4714936e88a84ae3cb93", contentType: "json" }; // 存储键名 const CONFIG_KEY = 'zhs_full_config'; const STATE_KEY = 'zhs_full_state'; const SELECTED_COURSES_KEY = 'zhs_selected_courses'; // 选中的课程存储 const LOCAL_BANK_KEY = 'zhs_local_question_bank'; // 全局状态 let state = { currentCourseIndex: 0, currentTime: 0, isRunning: false, totalCourses: 0, }; let config = { ...DEFAULT_CONFIG }; let allCourseList = []; // 页面所有课程列表 let selectedCourseList = []; // 用户选中的课程列表 let localQuestionBank = {}; let timer = null; let popupTimer = null; let answerTimer = null; let panel = null; // ===================== 初始化 ===================== function init() { loadConfig(); loadState(); loadLocalBank(); loadSelectedCourses(); createPanel(); bindEvents(); startPopupMonitor(); startAnswerMonitor(); startHumanSimulate(); // 延迟加载课程列表 setTimeout(() => { autoDetectPage(); refreshCourseList(); }, 1500); } // ===================== 配置/状态/选中课程 加载&保存 ===================== function loadConfig() { try { const saved = GM_getValue(CONFIG_KEY); if (saved) config = { ...DEFAULT_CONFIG, ...saved }; } catch (e) { console.error('加载配置失败', e); } } function saveConfig() { try { GM_setValue(CONFIG_KEY, config); } catch (e) { console.error('保存配置失败', e); } } function loadState() { try { const saved = GM_getValue(STATE_KEY); if (saved) state = { ...state, ...saved }; } catch (e) { console.error('加载状态失败', e); } } function saveState() { try { GM_setValue(STATE_KEY, state); } catch (e) { console.error('保存状态失败', e); } } function loadSelectedCourses() { try { const saved = GM_getValue(SELECTED_COURSES_KEY); if (saved) selectedCourseList = JSON.parse(saved); } catch (e) { console.error('加载选中课程失败', e); } } function saveSelectedCourses() { try { GM_setValue(SELECTED_COURSES_KEY, JSON.stringify(selectedCourseList)); } catch (e) { console.error('保存选中课程失败', e); } } function loadLocalBank() { try { const saved = GM_getValue(LOCAL_BANK_KEY); if (saved) localQuestionBank = typeof saved === 'string' ? JSON.parse(saved) : saved; } catch (e) { console.error('加载本地题库失败', e); localQuestionBank = {}; } } function saveLocalBank(newBank) { try { localQuestionBank = newBank; GM_setValue(LOCAL_BANK_KEY, JSON.stringify(newBank)); addLog('本地题库保存成功,共' + Object.keys(newBank).length + '道题', 'success'); return true; } catch (e) { addLog('本地题库保存失败:' + e.message, 'error'); return false; } } // ===================== 言溪在线题库搜题 ===================== async function searchYanxiBank(title, options, type) { if (!config.useOnlineBankFirst) return []; return new Promise((resolve) => { const queryParams = new URLSearchParams({ token: YANXI_BANK_CONFIG.token, title: title.trim(), options: options.join('\n'), type: type }); const requestUrl = `${YANXI_BANK_CONFIG.url}?${queryParams.toString()}`; GM_xmlhttpRequest({ method: YANXI_BANK_CONFIG.method, url: requestUrl, timeout: 5000, onload: (res) => { try { const result = JSON.parse(res.responseText); if (result.code === 0 && result.data?.answer) { let answer = result.data.answer; answer = Array.isArray(answer) ? answer : [answer.toString().trim()]; addLog(`【言溪题库】搜题成功,答案:${answer.join('、')}`, 'success'); resolve(answer); } else { addLog(`【言溪题库】搜题失败:${result.message || '无结果'}`, 'error'); resolve([]); } } catch (e) { addLog(`【言溪题库】解析失败:${e.message}`, 'error'); resolve([]); } }, onerror: (err) => { addLog(`【言溪题库】请求失败:${err.message || '网络错误'}`, 'error'); resolve([]); }, ontimeout: () => { addLog('【言溪题库】请求超时', 'error'); resolve([]); } }); }); } // ===================== 【核心】自动获取页面所有课程 ===================== function getAllCourseCards() { // 精准适配你当前智慧树页面的课程选择器 const courseSelectors = [ '.shared-course-wrap .course-item', '.course-list .course-item', '.tab-content .course-item', '[class*="course"] [class*="item"]', ]; let courseList = []; courseSelectors.forEach(sel => { const cards = document.querySelectorAll(sel); cards.forEach((card, index) => { const titleEl = card.querySelector('h3, .course-title, .course-name, .title'); if (!titleEl) return; const title = titleEl.textContent.trim(); const isVisible = card.offsetParent !== null; if (!title || !isVisible) return; // 课程信息 courseList.push({ index: index, title: title, element: card, id: btoa(title) // 生成唯一ID }); }); }); // 去重 const uniqueList = Array.from(new Map(courseList.map(item => [item.id, item])).values()); allCourseList = uniqueList; return uniqueList; } // 刷新课程列表到面板 function refreshCourseList() { const courseList = getAllCourseCards(); const listContainer = document.getElementById('zhs-course-list'); if (!listContainer) return; if (courseList.length === 0) { listContainer.innerHTML = '
未找到课程,请确保在课程列表页
'; return; } // 生成课程勾选列表 let html = ''; courseList.forEach(course => { const isSelected = selectedCourseList.some(item => item.id === course.id); html += `
`; }); listContainer.innerHTML = html; addLog(`成功获取到${courseList.length}门课程`, 'success'); state.totalCourses = selectedCourseList.length; updateUI(); // 绑定勾选事件 bindCourseCheckEvents(); } // 绑定课程勾选事件 function bindCourseCheckEvents() { document.querySelectorAll('.zhs-course-checkbox').forEach(checkbox => { checkbox.onchange = (e) => { const courseId = e.target.dataset.id; const course = allCourseList.find(item => item.id === courseId); if (!course) return; if (e.target.checked) { // 选中,加入列表 if (!selectedCourseList.some(item => item.id === courseId)) { selectedCourseList.push(course); } } else { // 取消选中,移除 selectedCourseList = selectedCourseList.filter(item => item.id !== courseId); } saveSelectedCourses(); state.totalCourses = selectedCourseList.length; updateUI(); addLog(`${e.target.checked ? '选中' : '取消选中'}课程:${course.title}`); }; }); // 全选/反选 document.getElementById('zhs-select-all').onclick = (e) => { e.stopPropagation(); const allChecked = document.querySelectorAll('.zhs-course-checkbox:checked').length === allCourseList.length; document.querySelectorAll('.zhs-course-checkbox').forEach(checkbox => { checkbox.checked = !allChecked; checkbox.dispatchEvent(new Event('change')); }); }; } // ===================== 手动播放/暂停控制 ===================== function manualPlayVideo() { const video = document.querySelector('video'); const playBtn = document.querySelector('.vjs-big-play-button, .vjs-play-control.vjs-paused'); if (video && video.paused) { video.play().then(() => { addLog('视频已手动播放', 'success'); }).catch(() => { if (playBtn) playBtn.click(); addLog('已点击播放按钮', 'success'); }); } else if (playBtn) { playBtn.click(); addLog('已点击播放按钮', 'success'); } else { addLog('未找到可播放的视频', 'error'); } } function manualPauseVideo() { const video = document.querySelector('video'); const pauseBtn = document.querySelector('.vjs-play-control.vjs-playing'); if (video && !video.paused) { video.pause(); addLog('视频已手动暂停', 'success'); } else if (pauseBtn) { pauseBtn.click(); addLog('已点击暂停按钮', 'success'); } else { addLog('未找到正在播放的视频', 'error'); } } // ===================== 控制面板创建(新增课程选择区域) ===================== function createPanel() { const existing = document.getElementById('zhs-auto-panel'); if (existing) existing.remove(); panel = document.createElement('div'); panel.id = 'zhs-auto-panel'; panel.innerHTML = `
智慧树全自动刷课
📋 课程列表(勾选要刷的课程)
正在加载课程列表...
状态${state.isRunning ? '运行中' : '已停止'}
当前课程第${state.currentCourseIndex+1}/${state.totalCourses}门
计时${formatTime(state.currentTime)} / ${config.watchTime}分钟
单课时长(分钟)
播放倍速
优先在线搜题
自动播放
自动切课
自动关弹窗
自动答题
复看已完成课程
📚 本地兜底题库(点击展开)
脚本加载完成,自动获取课程中...
`; document.body.appendChild(panel); // 初始化本地题库文本框 document.getElementById('zhs-bank-text').value = JSON.stringify(localQuestionBank, null, 2); } // ===================== 最小化/恢复切换 ===================== function toggleMinimize() { panel.classList.toggle('minimized'); const minBtn = document.getElementById('zhs-min'); minBtn.textContent = panel.classList.contains('minimized') ? '+' : '-'; } // ===================== 事件绑定 ===================== function bindEvents() { // 最小化后点击整个面板恢复 panel.addEventListener('click', (e) => { if (e.target === panel && panel.classList.contains('minimized')) { toggleMinimize(); } }); // 右上角最小化按钮 document.getElementById('zhs-min').onclick = (e) => { e.stopPropagation(); toggleMinimize(); }; // 刷新课程按钮 document.getElementById('zhs-refresh').onclick = (e) => { e.stopPropagation(); refreshCourseList(); }; // 手动播放/暂停 document.getElementById('zhs-manual-play').onclick = (e) => { e.stopPropagation(); manualPlayVideo(); }; document.getElementById('zhs-manual-pause').onclick = (e) => { e.stopPropagation(); manualPauseVideo(); }; // 题库折叠 document.getElementById('zhs-bank-toggle').onclick = (e) => { e.stopPropagation(); const content = document.getElementById('zhs-bank-content'); content.classList.toggle('open'); document.querySelector('#zhs-bank-toggle span:last-child').textContent = content.classList.contains('open') ? '▲' : '▼'; }; // 保存本地题库 document.getElementById('zhs-bank-save').onclick = (e) => { e.stopPropagation(); try { const text = document.getElementById('zhs-bank-text').value; const newBank = JSON.parse(text); saveLocalBank(newBank); } catch (e) { addLog('题库格式错误,请检查JSON格式', 'error'); } }; // 自动刷课开始/暂停 document.getElementById('zhs-toggle').onclick = (e) => { e.stopPropagation(); toggleWatch(); }; // 重置进度 document.getElementById('zhs-reset').onclick = (e) => { e.stopPropagation(); if (confirm('确定重置所有进度和状态吗?')) resetWatch(); }; // 所有toggle开关通用绑定 const toggleMap = { 'zhs-use-online': 'useOnlineBankFirst', 'zhs-auto-play': 'autoPlay', 'zhs-auto-switch': 'autoSwitch', 'zhs-auto-popup': 'autoClosePopup', 'zhs-auto-answer': 'autoAnswer', 'zhs-review': 'reviewCompleted' }; Object.keys(toggleMap).forEach(id => { const key = toggleMap[id]; document.getElementById(id).onclick = (e) => { e.stopPropagation(); config[key] = !config[key]; e.target.classList.toggle('active', config[key]); saveConfig(); addLog(`${key === 'reviewCompleted' ? '复看已完成课程' : key}${config[key] ? '开启' : '关闭'}`); // 复看开关变化后刷新课程 if (key === 'reviewCompleted') { setTimeout(() => { refreshCourseList(); }, 500); } }; }); // 单课时长修改 document.getElementById('zhs-watch-time').onchange = (e) => { e.stopPropagation(); const val = parseInt(e.target.value); config.watchTime = (isNaN(val) || val < 1) ? 25 : val; saveConfig(); addLog(`单课时长设置为:${config.watchTime}分钟`); }; // 播放倍速修改 document.getElementById('zhs-rate').onchange = (e) => { e.stopPropagation(); const val = parseFloat(e.target.value); config.playbackRate = (isNaN(val) || val < 0.5 || val > 1.5) ? 1 : val; saveConfig(); applyPlaybackRate(); addLog(`播放倍速设置为:${config.playbackRate}x`); }; // 阻止内部元素冒泡 panel.querySelectorAll('.zhs-content, .zhs-header *').forEach(el => { el.addEventListener('click', (e) => e.stopPropagation()); }); } // ===================== 页面识别 ===================== function autoDetectPage() { const url = window.location.href; // 课程列表页(学堂页) if (url.includes('onlineweb.zhihuishu.com/onlinestuh')) { addLog('检测到课程列表页(学堂页)', 'success'); expandAllCourses(); } // 视频播放页 else if (url.includes('studyvideoh5') || url.includes('wisdom-mooc')) { addLog('检测到视频播放页', 'success'); startVideoDetect(); if (state.isRunning) { startTimer(); } } } // 展开全部课程 function expandAllCourses() { const viewMoreBtn = document.querySelector('.view-more, a[href*="查看更多"], .course-more'); if (viewMoreBtn && viewMoreBtn.offsetParent !== null) { viewMoreBtn.click(); addLog('已点击「查看更多」,展开全部课程', 'success'); } } // 打开目标课程 function openTargetCourse() { if (selectedCourseList.length === 0) { addLog('请先勾选要刷的课程', 'error'); pauseWatch(); return; } if (state.currentCourseIndex >= selectedCourseList.length) { addLog('全部课程已完成', 'success'); pauseWatch(); alert('✅ 全部选中的课程已刷完!'); return; } const targetCourse = selectedCourseList[state.currentCourseIndex]; if (!targetCourse || !targetCourse.element) { addLog('未找到目标课程', 'error'); return; } targetCourse.element.click(); addLog(`已打开课程:${targetCourse.title}`, 'success'); } // 视频检测&设置 function startVideoDetect() { let attempts = 0; const detectTimer = setInterval(() => { const video = document.querySelector('video'); if (video) { clearInterval(detectTimer); setupVideo(video); addLog('已找到视频,自动播放设置完成', 'success'); } else if (attempts > 30) { clearInterval(detectTimer); addLog('未找到视频元素,请手动刷新页面', 'error'); } attempts++; }, 500); } function setupVideo(video) { if (!video) return; video.playbackRate = config.playbackRate; if (config.autoPlay) { video.play().catch(() => { addLog('自动播放失败,请手动点击播放按钮', 'error'); }); } video.addEventListener('ended', () => { addLog('当前小节播放结束,自动播放下一节', 'success'); setTimeout(() => { const nextSection = document.querySelector('.next-btn, .nav-next, .catalog-item.active + .catalog-item'); if (nextSection) nextSection.click(); }, 1500); }); } function applyPlaybackRate() { document.querySelectorAll('video').forEach(v => { v.playbackRate = config.playbackRate; }); } // ===================== 自动答题功能 ===================== function startAnswerMonitor() { if (answerTimer) clearInterval(answerTimer); answerTimer = setInterval(() => { if (!config.autoAnswer) return; const popupSelectors = [ '.question-modal', '.test-popup', '.dialog-box:has(.question-stem)', '.el-dialog:has(.question-title)', '.popupsbox:has(.option-item)' ]; let answerPopup = null; for (const sel of popupSelectors) { const el = document.querySelector(sel); if (el && el.offsetParent !== null) { answerPopup = el; break; } } if (answerPopup) { handleAnswerPopup(answerPopup); } }, 1000); } async function handleAnswerPopup(popup) { if (popup.dataset.processed === 'true') return; popup.dataset.processed = 'true'; // 提取题干 const stemSelectors = ['.question-stem', '.question-title', '.stem', '.title h3']; let stem = ''; for (const sel of stemSelectors) { const el = popup.querySelector(sel); if (el) { stem = el.textContent.trim().replace(/\s+/g, ''); break; } } if (!stem) { addLog('未识别到题干,跳过答题', 'error'); popup.dataset.processed = 'false'; return; } addLog(`识别到题目:${stem}`); // 提取选项 const optionSelectors = ['.option-item', '.answer-option', '.option', '.el-radio', '.el-checkbox']; const options = Array.from(popup.querySelectorAll(optionSelectors)).filter(el => el.offsetParent !== null); if (options.length === 0) { addLog('未识别到选项,跳过答题', 'error'); popup.dataset.processed = 'false'; return; } const optionList = options.map(el => { const textEl = el.querySelector('.option-text, .label, span') || el; return { el: el, text: textEl.textContent.trim().replace(/\s+/g, '') }; }); const optionTextList = optionList.map(opt => opt.text); // 判断题型 const isMulti = popup.querySelector('.el-checkbox') !== null; const questionType = isMulti ? 'multi' : 'single'; addLog(`题型:${isMulti ? '多选题' : '单选题'}`); // 真人延迟 await new Promise(r => setTimeout(r, 1000 + Math.random() * 1000)); // 在线搜题 let correctAnswers = []; if (config.useOnlineBankFirst) { correctAnswers = await searchYanxiBank(stem, optionTextList, questionType); } // 本地题库兜底 if (correctAnswers.length === 0) { addLog('在线搜题无结果,使用本地题库匹配', 'info'); for (const key in localQuestionBank) { const cleanKey = key.replace(/\s+/g, ''); if (stem.includes(cleanKey) || cleanKey.includes(stem)) { correctAnswers = localQuestionBank[key]; addLog(`本地题库匹配成功,答案:${correctAnswers.join('、')}`, 'success'); break; } } } // 随机选择 let selected = []; if (correctAnswers.length > 0) { correctAnswers.forEach(answer => { const cleanAnswer = answer.replace(/\s+/g, ''); const targetOption = optionList.find(opt => opt.text.includes(cleanAnswer) || cleanAnswer.includes(opt.text)); if (targetOption) { targetOption.el.click(); selected.push(targetOption.text); } }); } else { addLog('无匹配答案,随机选择', 'info'); let randomCount = isMulti ? Math.floor(Math.random() * optionList.length) + 1 : 1; const randomOptions = [...optionList].sort(() => 0.5 - Math.random()).slice(0, randomCount); randomOptions.forEach(opt => { opt.el.click(); selected.push(opt.text); }); } addLog(`已选择选项:${selected.join('、')}`); // 提交答案 await new Promise(r => setTimeout(r, 800 + Math.random() * 500)); const submitBtns = popup.querySelectorAll('.submit-btn, .confirm-btn, .sure-btn, .el-button--primary, button:has-text("确定"), button:has-text("提交")'); submitBtns.forEach(btn => { if (btn.offsetParent !== null) btn.click(); }); addLog('已提交答案,关闭弹窗', 'success'); // 解锁 setTimeout(() => { popup.dataset.processed = 'false'; }, 2000); } // ===================== 切课&计时核心逻辑 ===================== function startTimer() { if (timer) clearInterval(timer); timer = setInterval(() => { if (!state.isRunning) return; state.currentTime++; saveState(); updateUI(); // 时长到了,切课 if (state.currentTime >= config.watchTime * 60) { clearInterval(timer); addLog(`第${state.currentCourseIndex+1}门课【${selectedCourseList[state.currentCourseIndex]?.title}】时长已满`, 'success'); // 全部完成 if (state.currentCourseIndex >= selectedCourseList.length - 1) { pauseWatch(); alert('✅ 全部选中的课程已刷完!'); addLog('全部课程学习完成', 'success'); return; } // 自动切课 if (config.autoSwitch) { setTimeout(() => { backToSchool(); }, 1500 + Math.random() * 1000); } else { pauseWatch(); } } }, 1000); } function backToSchool() { const backBtn = document.querySelector('a:has-text("返回学堂"), .back-btn, a[href*="onlinestuh5"], .header-left a'); if (backBtn && backBtn.offsetParent !== null) { backBtn.click(); addLog('已点击「返回学堂」,回到课程列表', 'success'); state.currentCourseIndex++; state.currentTime = 0; saveState(); // 回到列表后,延迟打开下一门 setTimeout(() => { openTargetCourse(); }, 2000 + Math.random() * 1000); } else { addLog('未找到「返回学堂」按钮,手动跳转', 'error'); window.location.href = 'https://onlineweb.zhihuishu.com/onlinestuh5'; state.currentCourseIndex++; state.currentTime = 0; saveState(); } } // ===================== 普通弹窗处理 ===================== function startPopupMonitor() { if (popupTimer) clearInterval(popupTimer); popupTimer = setInterval(() => { if (!config.autoClosePopup) return; // 挂机验证弹窗 const continueBtns = document.querySelectorAll('.dialog-footer .btn, .vjs-modal-dialog .vjs-close-button, .continue-btn, .confirm-btn, button[title="继续播放"]'); continueBtns.forEach(btn => { if (btn.offsetParent !== null) { btn.click(); addLog('已自动关闭挂机验证弹窗', 'success'); } }); // 普通关闭弹窗 const closeBtns = document.querySelectorAll('.close, .btn-close, .modal-close, .dialog-close, [class*="close"]'); closeBtns.forEach(btn => { if (btn.offsetParent !== null && !btn.closest('.video-js')) { btn.click(); addLog('已自动关闭弹窗', 'success'); } }); window.onbeforeunload = null; }, 2000); } // ===================== 防检测真人模拟 ===================== function startHumanSimulate() { setInterval(() => { if (!state.isRunning) return; document.dispatchEvent(new MouseEvent('mousemove', { clientX: Math.random() * 1000 + 200, clientY: Math.random() * 600 + 100 })); window.scrollBy(0, Math.random() > 0.5 ? 10 : -10); }, 30000 + Math.random() * 20000); } // ===================== 控制函数 ===================== function toggleWatch() { state.isRunning ? pauseWatch() : startWatch(); } function startWatch() { if (state.isRunning) return; // 检查是否选中课程 if (selectedCourseList.length === 0) { alert('请先勾选要刷的课程!'); addLog('请先勾选要刷的课程', 'error'); return; } state.isRunning = true; saveState(); updateUI(); addLog('开始自动刷课', 'success'); autoDetectPage(); // 如果在列表页,打开第一门选中的课程 if (window.location.href.includes('onlineweb.zhihuishu.com/onlinestuh')) { setTimeout(() => { openTargetCourse(); }, 1000); } } function pauseWatch() { state.isRunning = false; saveState(); updateUI(); if (timer) { clearInterval(timer); timer = null; } addLog('已暂停自动刷课'); } function resetWatch() { pauseWatch(); state = { currentCourseIndex: 0, currentTime: 0, isRunning: false, totalCourses: selectedCourseList.length }; saveState(); updateUI(); addLog('已重置所有进度和状态'); } // ===================== 工具函数 ===================== function formatTime(seconds) { const m = Math.floor(seconds / 60).toString().padStart(2, '0'); const s = (seconds % 60).toString().padStart(2, '0'); return `${m}:${s}`; } function addLog(msg, type = 'info') { const logBox = document.getElementById('zhs-log'); if (!logBox) return; const entry = document.createElement('div'); entry.className = `zhs-log-entry ${type}`; entry.textContent = `[${new Date().toLocaleTimeString()}] ${msg}`; logBox.appendChild(entry); logBox.scrollTop = logBox.scrollHeight; while (logBox.children.length > 50) logBox.removeChild(logBox.firstChild); } function updateUI() { const statusEl = document.getElementById('zhs-status'); const courseEl = document.getElementById('zhs-course'); const timeEl = document.getElementById('zhs-time'); const fillEl = document.getElementById('zhs-fill'); const toggleEl = document.getElementById('zhs-toggle'); if (statusEl) statusEl.textContent = state.isRunning ? '运行中' : '已停止'; if (courseEl) courseEl.textContent = `第${state.currentCourseIndex+1}/${state.totalCourses}门`; if (timeEl) timeEl.textContent = `${formatTime(state.currentTime)} / ${config.watchTime}分钟`; if (fillEl) fillEl.style.width = `${Math.min((state.currentTime/(config.watchTime*60))*100, 100)}%`; if (toggleEl) toggleEl.innerHTML = state.isRunning ? '⏸ 暂停自动刷课' : '▶ 开始自动刷课'; } // 油猴菜单 GM_registerMenuCommand('开始/暂停自动刷课', toggleWatch); GM_registerMenuCommand('播放视频', manualPlayVideo); GM_registerMenuCommand('暂停视频', manualPauseVideo); GM_registerMenuCommand('重置进度', resetWatch); // 启动脚本 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();