// ==UserScript== // @name 智能刷课助手 // @namespace http://tampermonkey.net/ // @version 1.3 // @description 使用须知:目前版本只适用于超星学习通,支持自动播放视频、倍数播放和自动跳章;脚本暂不支持章节测试,不支持窗口页面最小化运行;⚠️⚠️在运行脚本时务必将笔记本电脑的睡眠模式关闭,防止电脑息屏。 // @author 天天 // @match https://mooc1.chaoxing.com/mycourse/studentstudy* // @grant GM_addStyle // @grant GM_log // @grant GM_xmlhttpRequest // @license MIT // @run-at document-end // @downloadURL https://update.greasyfork.icu/scripts/524824/%E6%99%BA%E8%83%BD%E5%88%B7%E8%AF%BE%E5%8A%A9%E6%89%8B.user.js // @updateURL https://update.greasyfork.icu/scripts/524824/%E6%99%BA%E8%83%BD%E5%88%B7%E8%AF%BE%E5%8A%A9%E6%89%8B.meta.js // ==/UserScript== (function() { 'use strict'; // 检查是否已存在控制窗口 if (document.querySelector('.course-helper')) { return; } // 创建样式 const style = document.createElement('style'); style.textContent = ` .course-helper { position: fixed; top: 20px; right: 20px; width: 320px; min-height: 220px; background: #1e1e1e; /* 深灰色背景 */ border: 1px solid #444; border-radius: 10px; box-shadow: 0 4px 20px rgba(0,0,0,0.3); z-index: 9999; resize: both; overflow: auto; font-family: 'Roboto', sans-serif; /* 现代字体 */ color: #f0f0f0; /* 浅色文字 */ } .helper-header { padding: 15px; background: #2b2b2b; /* 深色头部 */ border-bottom: 1px solid #444; cursor: move; border-radius: 10px 10px 0 0; user-select: none; display: flex; justify-content: space-between; align-items: center; } .helper-content { padding: 20px; /* 增加内边距 */ } .control-group { margin-bottom: 20px; /* 增加底部间距 */ } .control-label { display: block; margin-bottom: 10px; font-weight: bold; color: #e0e0e0; } .control-input { width: 100%; padding: 10px; /* 增加内边距 */ margin-bottom: 12px; border: 1px solid #555; border-radius: 5px; background: #2b2b2b; /* 深色输入框 */ color: #f0f0f0; } .btn { padding: 10px 20px; /* 增加按钮内边距 */ background-color: #4CAF50; /* 绿色按钮 */ color: white; border: none; border-radius: 5px; cursor: pointer; margin-right: 10px; /* 增加右边距 */ transition: background-color 0.3s ease; } .btn:hover { background-color: #45a049; /* 深绿色 */ } .btn-danger { background-color: #dc3545; /* 红色按钮 */ } .btn-danger:hover { background-color: #c82333; /* 深红色 */ } .log-area { width: 100%; height: 120px; border: 1px solid #555; border-radius: 5px; padding: 10px; font-size: 12px; font-family: 'Consolas', monospace; resize: vertical; background: #1a1a1a; /* 深色日志区域 */ color: #ffffff; overflow-y: auto; } .progress-bar { width: 100%; height: 20px; background-color: #2b2b2b; /* 深灰色进度条 */ border-radius: 5px; margin-bottom: 10px; overflow: hidden; } .progress-fill { height: 100%; background-color: #4CAF50; /* 绿色进度 */ width: 0%; transition: width 0.3s ease; } .status-text { font-size: 12px; color: #e0e0e0; margin-bottom: 10px; } del { position: relative; color: #666; font-style: italic; font-weight: bold; } del::after { content: ''; position: absolute; left: 0; right: 0; top: 50%; border-bottom: 2px solid #ff4444; } .support-text { color: #fff; font-weight: normal; font-style: normal; } .content { padding: 20px; background-color: #1e1e1e;; } .content img:hover { transform: scale(1.05); } `; document.head.appendChild(style); // 创建助手窗口 const helperWindow = document.createElement('div'); helperWindow.className = 'course-helper'; helperWindow.innerHTML = `
✨刷课助手
您的支持是我躺平前进的动力!!🥳
等待开始...
`; document.body.appendChild(helperWindow); // 状态变量 let isPlaying = false; let currentVideoIndex = 0; let totalVideos = 0; // 窗口拖拽功能 let isDragging = false; let offsetX, offsetY; helperWindow.querySelector('.helper-header').addEventListener('mousedown', (e) => { isDragging = true; offsetX = e.clientX - helperWindow.offsetLeft; offsetY = e.clientY - helperWindow.offsetTop; }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; let newX = e.clientX - offsetX; let newY = e.clientY - offsetY; const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; const helperWidth = helperWindow.offsetWidth; const helperHeight = helperWindow.offsetHeight; newX = Math.max(0, Math.min(newX, windowWidth - helperWidth)); newY = Math.max(0, Math.min(newY, windowHeight - helperHeight)); helperWindow.style.left = `${newX}px`; helperWindow.style.top = `${newY}px`; }); document.addEventListener('mouseup', () => { isDragging = false; }); // 日志功能 function log(message) { const logArea = document.getElementById('logArea'); if (!logArea) return; const timestamp = new Date().toLocaleTimeString(); const logEntry = document.createElement('div'); logEntry.textContent = `[${timestamp}] ${message}`; logArea.appendChild(logEntry); logArea.scrollTop = logArea.scrollHeight; } // 更新状态显示 function updateStatus(message) { const statusText = document.getElementById('statusText'); if (statusText) { statusText.textContent = message; } } // 更新进度条 function updateProgress(current, total) { const progressBar = document.getElementById('progressBar'); if (progressBar) { const percentage = (current / total) * 100; progressBar.style.width = `${percentage}%`; } } // 获取iframe元素 function getIframes() { try { const mainFrame = document.getElementById("iframe"); if (!mainFrame) { log("未找到主iframe"); return []; } const iframeDoc = mainFrame.contentWindow.document; return Array.from(iframeDoc.getElementsByTagName('iframe')); } catch (error) { log("获取iframe失败: " + error.message); return []; } } // 控制单个视频 function controlVideo(video, playbackRate) { return new Promise((resolve) => { const handleVideoEnd = () => { video.removeEventListener('ended', handleVideoEnd); log("视频播放完成"); resolve(); }; video.addEventListener('ended', handleVideoEnd); video.muted = true; video.playbackRate = playbackRate; video.play().catch(error => { log("播放失败: " + error.message); resolve(); // 即使失败也继续下一个 }); }); } // 视频控制主函数 async function controlAllVideos(action, params = {}) { const iframes = getIframes(); const videos = []; for (let iframe of iframes) { try { const iframeVideos = Array.from(iframe.contentWindow.document.getElementsByTagName('video')); videos.push(...iframeVideos); } catch (error) { log(`获取视频失败: ${error.message}`); } } totalVideos = videos.length; if (totalVideos === 0) { log("未找到可播放的视频"); // 如果没有视频,直接跳转下一章 skipChapter(); return; } for (let i = 0; i < videos.length && isPlaying; i++) { currentVideoIndex = i; updateStatus(`正在播放第 ${i + 1}/${totalVideos} 个视频`); updateProgress(i + 1, totalVideos); try { const video = videos[i]; switch(action) { case 'play': await controlVideo(video, params.playbackRate); break; case 'setPlaybackRate': video.playbackRate = params.playbackRate; log(`设置播放速度: ${params.playbackRate}x`); break; } } catch (error) { log(`控制视频失败: ${error.message}`); } } if (currentVideoIndex >= totalVideos - 1) { log("所有视频播放完成"); isPlaying = false; updateStatus("播放完成"); document.getElementById('autoPlayBtn').textContent = "开始播放"; // 增加延时确保视频完全结束 setTimeout(() => { log("准备跳转到下一章节"); skipChapter(); }, 3000); // 等待3秒后跳转 } } function skipChapter() { try { log("尝试跳转到下一章节"); const nextButton = window.top.document.querySelector("#prevNextFocusNext"); if (nextButton) { nextButton.click(); log("已点击下一章节按钮"); // 第一次延时:等待完成提示出现 setTimeout(() => { try { const tip = window.top.document.querySelector(".maskDiv.jobFinishTip.maskFadeOut"); if (tip) { const nextChapterBtn = window.top.document.querySelector(".jb_btn.jb_btn_92.fr.fs14.nextChapter"); if (nextChapterBtn) { nextChapterBtn.click(); log("已确认进入下一章节"); // 第二次延时:等待新页面加载 setTimeout(() => { log("等待新页面加载完成..."); // 第三次延时:确保新页面完全加载 setTimeout(() => { try { // 重新初始化视频播放 isPlaying = false; // 重置播放状态 currentVideoIndex = 0; // 重置视频索引 const autoPlayBtn = document.getElementById('autoPlayBtn'); if (autoPlayBtn) { log("触发自动播放"); autoPlayBtn.click(); } else { log("未找到播放按钮,可能需要刷新页面"); } } catch (error) { log(`自动播放失败: ${error.message}`); } }, 2000); }, 2000); } else { log("未找到确认下一章节按钮"); } } else { log("未找到任务点完成提示,直接尝试开始播放"); setTimeout(() => { const autoPlayBtn = document.getElementById('autoPlayBtn'); if (autoPlayBtn) { isPlaying = false; currentVideoIndex = 0; autoPlayBtn.click(); log("直接开始播放新章节"); } }, 3000); } } catch (error) { log(`处理完成提示时出错: ${error.message}`); } }, 1500); } else { log("未找到下一章节按钮"); } } catch (error) { log(`跳转章节失败: ${error.message}`); } } //暂停函数 function pauseVideo(){ const iframes = getIframes(); for (let iframe of iframes) { try { const videos = iframe.contentWindow.document.getElementsByTagName('video'); for (let video of videos) { video.pause(); } } catch (error) { log(`暂停视频失败: ${error.message}`); } } log('已暂停所有视频'); } //更新播放速度的函数 function updatePlaybackRate(rate) { try { const iframes = getIframes(); for (let iframe of iframes) { try { const videos = Array.from(iframe.contentWindow.document.getElementsByTagName('video')); videos.forEach(video => { video.playbackRate = rate; }); } catch (error) { log(`设置视频速度失败: ${error.message}`); } } } catch (error) { log(`更新播放速度失败: ${error.message}`); } } // 事件监听 document.getElementById('autoPlayBtn').addEventListener('click', () => { const button = document.getElementById('autoPlayBtn'); if (!isPlaying) { isPlaying = true; button.textContent = "停止播放"; const rate = parseFloat(document.getElementById('playbackRate').value); controlAllVideos('play', { playbackRate: rate }); log('开始自动播放'); } else { isPlaying = false; button.textContent = "开始播放"; log('停止播放'); pauseVideo(); } }); document.getElementById('playbackRate').addEventListener('change', () => { const rate = parseFloat(document.getElementById('playbackRate').value); updatePlaybackRate(rate); log(`播放速度已调整为 ${rate}x`); }); // 初始化 setTimeout(() => { try { log('刷课助手已加载'); const iframes = getIframes(); log(`当前页面任务点数量:${iframes.length}`); } catch (error) { log(`初始化失败: ${error.message}`); } }, 1000); // 延迟1秒执行 })();