// ==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();
}
})();