Skip to content

Commit 6e1379d

Browse files
authored
Create Lesson-flashing-script.js
1 parent 6a54cbb commit 6e1379d

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed

Lesson-flashing-script.js

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
// ==UserScript==
2+
// @name 中南大学继续教育自动刷课(最终版)
3+
// @namespace http://tampermonkey.net/
4+
// @version 2.0
5+
// @description 自动播放视频、答题、切换课程
6+
// @match https://cws.edu-edu.com/*
7+
// @match https://zjpx.csu.edu.cn/*
8+
// @grant none
9+
// @run-at document-end
10+
// ==/UserScript==
11+
12+
(function() {
13+
// 防止网页检测失焦或切屏行为
14+
window.addEventListener('blur', function(e) {
15+
e.stopImmediatePropagation();
16+
console.log("🚫 阻止 window.blur 事件");
17+
}, true);
18+
19+
document.addEventListener('visibilitychange', function(e) {
20+
e.stopImmediatePropagation();
21+
if (document.visibilityState !== 'visible') {
22+
Object.defineProperty(document, 'visibilityState', {
23+
configurable: true,
24+
get: () => 'visible',
25+
});
26+
console.log("🚫 阻止 visibilitychange 事件");
27+
}
28+
}, true);
29+
30+
// 强制 document.hasFocus() 始终为 true
31+
Object.defineProperty(document, 'hasFocus', {
32+
configurable: true,
33+
value: () => true
34+
});
35+
36+
console.log("🟢 自动刷课脚本已启动 - 最终版");
37+
38+
// 状态变量
39+
let isHandling = false;
40+
let videoEnded = false;
41+
42+
// 主循环
43+
const mainLoop = setInterval(() => {
44+
if (isHandling) return;
45+
46+
// 1. 优先处理防挂机题目
47+
if (handleAntiIdleQuestion()) {
48+
return;
49+
}
50+
51+
// 2. 处理视频播放
52+
handleVideoPlayback();
53+
54+
// 3. 处理播放完成弹窗
55+
if(videoEnded){
56+
handleNextChapterModal();
57+
videoEnded = false;
58+
setTimeout(() => {
59+
location.reload(true); // 5秒后强制刷新
60+
}, 5000);
61+
}
62+
}, 5000);
63+
64+
// 处理防挂机题目
65+
function handleAntiIdleQuestion() {
66+
const questionBox = document.querySelector('.questionBox');
67+
if (!questionBox) return false;
68+
69+
isHandling = true;
70+
console.log("📢 检测到防挂机题目");
71+
72+
const questionText = questionBox.innerText.trim();
73+
const match = questionText.match(/(\d+)\s*([+\-*/])\s*(\d+)/);
74+
75+
if (match) {
76+
const [, a, op, b] = match;
77+
let answer;
78+
switch (op) {
79+
case '+': answer = +a + +b; break;
80+
case '-': answer = a - b; break;
81+
case '*': answer = a * b; break;
82+
case '/': answer = a / b; break;
83+
}
84+
85+
console.log(`✏️ 计算: ${a} ${op} ${b} = ${answer}`);
86+
87+
// 选择正确答案
88+
const options = document.querySelectorAll('.ivu-radio-wrapper');
89+
options.forEach(opt => {
90+
if (opt.innerText.trim() === String(answer)) {
91+
opt.click();
92+
console.log("✅ 已选择正确答案");
93+
}
94+
});
95+
96+
// 点击确定按钮
97+
setTimeout(() => {
98+
const confirmBtn = document.querySelector('.btnBox button');
99+
if (confirmBtn) {
100+
confirmBtn.click();
101+
console.log("🆗 已点击确定按钮");
102+
}
103+
// 添加延迟等待页面更新
104+
setTimeout(() => {
105+
isHandling = false;
106+
}, 3000); // 3秒后恢复检测
107+
isHandling = false;
108+
}, 1500);
109+
setTimeout(() => {
110+
location.reload(true); // 120秒后强制刷新
111+
}, 120000);
112+
return true;
113+
} else {
114+
console.warn("❌ 无法识别的题目格式");
115+
isHandling = false;
116+
return false;
117+
}
118+
}
119+
120+
// 处理视频播放
121+
function handleVideoPlayback() {
122+
const video = document.querySelector('video');
123+
if (!video) return;
124+
125+
// 检测视频是否结束
126+
if (!isNaN(video.duration) && video.currentTime >= video.duration - 1) {
127+
videoEnded = true;
128+
console.log("🏁 视频播放完毕");
129+
}
130+
131+
// 自动播放暂停的视频
132+
if (video.paused && !videoEnded) {
133+
video.play()
134+
.then(() => console.log("▶️ 视频已开始播放"))
135+
.catch(err => console.warn("⚠️ 播放失败:", err));
136+
}
137+
138+
139+
}
140+
141+
// 处理下一章节弹窗
142+
function handleNextChapterModal() {
143+
const modals = document.querySelectorAll('.ivu-modal-body');
144+
let targetModal = null;
145+
146+
modals.forEach(modal => {
147+
if (modal.textContent.includes('当前章节已经播放完毕')) {
148+
targetModal = modal;
149+
}
150+
});
151+
152+
isHandling = true;
153+
console.log("🔄 检测到播放完成弹窗");
154+
155+
// 更智能的按钮查找方式
156+
const buttons = targetModal.querySelectorAll('button');
157+
let playNextBtn = null;
158+
159+
buttons.forEach(btn => {
160+
if (btn.textContent.includes('播放')) {
161+
playNextBtn = btn;
162+
}
163+
});
164+
165+
if (playNextBtn) {
166+
console.log("⏭️ 找到播放下一章节按钮");
167+
// 模拟更真实的点击
168+
playNextBtn.focus();
169+
const clickEvent = new MouseEvent('click', {
170+
view: window,
171+
bubbles: true,
172+
cancelable: true
173+
});
174+
playNextBtn.dispatchEvent(clickEvent);
175+
176+
// 备用点击方式
177+
setTimeout(() => {
178+
console.log("✅ 已点击播放按钮");
179+
videoEnded = false;
180+
isHandling = false;
181+
}, 500);
182+
} else {
183+
console.warn("❌ 未找到播放按钮");
184+
isHandling = false;
185+
}
186+
}
187+
188+
// 页面卸载时清除定时器
189+
window.addEventListener('unload', () => {
190+
clearInterval(mainLoop);
191+
});
192+
})();

0 commit comments

Comments
 (0)