// ==UserScript== // @name 联大学堂函授 全自动刷课答题【播放1分钟自动填答案+自定义提交进度】 // @namespace http://tampermonkey.net/ // @version 2.7 视频播放满一分钟自动识别填写答案 // @description 1.15倍速、防验证、后台播放,视频累计播放60秒后自动填答案,达到设置进度才提交切换章节 // @match *://*.jxjypt.cn/* // @require https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1.min.js // @require https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js // @grant GM_xmlhttpRequest // @run-at document-end // @license All Rights Reserved // ==/UserScript== (function () { 'use strict'; // 环境校验,禁止Node.js运行 if (typeof window === 'undefined' || typeof document === 'undefined') { console.warn('该脚本仅支持浏览器Tampermonkey插件运行'); return; } console.log('✅ 联大优化版:播放满60秒自动填答案,达标进度再提交切课'); // 全局基础配置 const PLAYBACK_RATE = 1.15; const JUMP_DELAY = 2000; const AUTO_FILL_SECONDS = 60; // 播放满60秒自动填答案 let hasJumped = false; let currentBaseSection = null; // 达标提交进度 70/80/90/100 let targetProgress = 100; let hasVideo = !!document.querySelector('video'); const hasExam = !!document.querySelector('.m-question'); // ====================== 1. 人机行为模拟 防无操作检测 ====================== function simulateHumanActivity() { window.focus(); document.dispatchEvent(new MouseEvent('mousemove', { clientX: 300 + Math.random() * 80, clientY: 300 + Math.random() * 80, bubbles: true })); document.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true })); setTimeout(() => document.body.click(), 200); } setInterval(simulateHumanActivity, 15000); // ====================== 2. 自动关闭弹窗/AI助教/验证框 ====================== function autoCloseVerify() { const closeBtn = document.querySelector('.alipay-layer-close, .layui-layer-close, [class*="dialog"] button'); if (closeBtn) { closeBtn.click(); console.log('自动关闭验证/AI弹窗'); return; } $('button:contains("确定"),button:contains("继续"),button:contains("我知道了")').click(); } setInterval(autoCloseVerify, 800); // ====================== 3. 监听课程点击,记录基准课时 ====================== document.addEventListener('click', (e) => { const target = e.target.closest('dd'); if (target && target.textContent.includes('节') && target.querySelector('i')) { currentBaseSection = target; hasJumped = false; console.log(`更新基准课时:${currentBaseSection.textContent.trim()}`); } }, true); // ====================== 4. 后台保活:页面最小化持续播放 ====================== function keepAliveBackground() { document.addEventListener('visibilitychange', () => { const video = document.querySelector('video'); if (!video || !isRunning) return; if (document.hidden) { video.play().catch(() => {}); } }); setInterval(() => { if (!isRunning) return; const video = document.querySelector('video'); if (!video) return; video.muted = true; if (video.paused) video.play().catch(() => {}); video.onpause = function () { if (isRunning && document.hidden) this.play().catch(() => {}); }; }, 1200); } // ====================== 5. 视频统一处理:倍速+缓冲+静音 ====================== async function autoPlaySync() { const video = document.querySelector('video'); if (!video) return; if (video.readyState < 4) { await new Promise(resolve => { const check = () => video.readyState >= 4 ? resolve() : requestAnimationFrame(check); check(); }); } if (video.paused) try { await video.play(); } catch (e) {} if (video.playbackRate !== PLAYBACK_RATE) { video.playbackRate = PLAYBACK_RATE; } video.muted = true; } // ============================================== // 功能1:视频刷课 【播放满60秒自动填答案,达标进度才提交】 // ============================================== function initVideoModule() { // OCR识别处理 async function recognizeImage(file) { const { data } = await Tesseract.recognize(file, 'chi_sim+eng'); let text = data.text; if (text.includes('如')) text += 'AB'; text = text.replace(/4/g, 'A') .replace(/©/g, 'C') .replace(/×/g, '') .replace(/条/g, '释') .replace(/可/g, '释') .replace(/了/g, 'B') .toUpperCase(); return text; } // 悬浮控制面板 function createPanel() { let panel = document.createElement('div'); panel.id = 'autoStudyPanel'; panel.style.cssText = ` position:fixed;top:140px;right:20px;z-index:999999; background:#fff;padding:12px;border-radius:10px;box-shadow:0 0 10px rgba(0,0,0,0.2); width:240px;max-height:80vh;overflow-y:auto;box-sizing:border-box; `; panel.innerHTML = `
🎯 全自动连刷(播放1分钟自动填答案)
计时:00:00
总长:00:00
进度:0%
提交线:100%
状态:等待启动,播放满60秒自动填答案
OCR状态:未获取
📋 题目&答案:
`; document.body.appendChild(panel); // 切换提交进度阈值 $('#progressSelect').on('change', function () { targetProgress = Number($(this).val()); $('#status').text(`已设置提交进度:${targetProgress}%,播放满60秒自动填答案`); updateInfo(); }); } let isRunning = false; let timer = 0; // 视频累计播放秒数 let total = 0; let interval = null; let aiAlreadyCalled = false; // 标记是否已自动填过答案 function fmt(s) { let m = Math.floor(s / 60); let sec = Math.floor(s % 60); return `${String(m).padStart(2, '0')}:${String(sec).padStart(2, '0')}`; } function closePopups() { try { $("button:contains('确定'),button:contains('关闭'),.close,.layui-layer-close").click(); $(".layui-layer,.modal,.popup").hide(); } catch (e) {} } function loadDurationNow() { let checkVideo = setInterval(() => { let video = document.querySelector('video'); if (video && video.duration > 0) { total = video.duration; updateInfo(); clearInterval(checkVideo); } }, 100); } function updateInfo() { let percent = total > 0 ? (timer / total) * 100 : 0; $('#videoInfo').html(`计时:${fmt(timer)}
总长:${fmt(total)}
进度:${percent.toFixed(1)}%
提交线:${targetProgress}%`); } // 主循环:计时+满一分钟自动填答案,达标再提交 function loop() { if (!isRunning || hasJumped) return; closePopups(); autoPlaySync(); const video = document.querySelector('video'); if (!video) return; if (!video.paused && !video.ended && video.readyState >= 4) { timer++; } updateInfo(); // 新增:播放满60秒 自动填答案(仅执行一次) if (timer >= AUTO_FILL_SECONDS && !aiAlreadyCalled) { $('#status').text(`已播放满${AUTO_FILL_SECONDS}秒,自动识别填写答案`); getAnswerOnce(true); } // 进度达标才提交跳转 let percent = total > 0 ? (timer / total) * 100 : 0; if (percent >= targetProgress && aiAlreadyCalled) { $('#status').text(`进度达${targetProgress}%,准备提交答案跳转`); realSubmit(); } } // 精准跳转下一课,重置计时与填答案标记 function goNext() { aiAlreadyCalled = false; timer = 0; // 重置播放计时 $('#questionDisplay').text(''); $('#answerStatus').text('OCR状态:未获取'); const allSections = Array.from(document.querySelectorAll('dd')) .filter(dd => dd.textContent.includes('节') && dd.querySelector('i')); if (allSections.length === 0) return; let currentIdx = -1; if (currentBaseSection) { currentIdx = allSections.findIndex(sec => sec === currentBaseSection); } if (currentIdx === -1) { allSections.forEach((sec, idx) => { const icon = sec.querySelector('i, img'); if (icon && (icon.src?.includes('green') || sec.style.color === 'green')) { currentIdx = idx; currentBaseSection = sec; } }); } if (currentIdx === -1) currentIdx = 0; const nextIdx = currentIdx + 1; if (nextIdx >= allSections.length) { $('#status').text('状态:已全部课程刷完'); return; } const nextSec = allSections[nextIdx]; console.log(`跳转下一节:${nextSec.textContent.trim()}`); nextSec.click(); currentBaseSection = nextSec; setTimeout(() => { total = 0; hasJumped = false; loadDurationNow(); $('#status').text(`下一节加载,播放满${AUTO_FILL_SECONDS}秒自动填答案,${targetProgress}%提交`); setTimeout(showQuestions, 1200); autoPlaySync(); }, JUMP_DELAY); } function start() { isRunning = true; $('#status').text(`运行中:播放满${AUTO_FILL_SECONDS}秒自动填答案,${targetProgress}%进度提交切课`); clearInterval(interval); interval = setInterval(loop, 1000); keepAliveBackground(); } function stop() { isRunning = false; clearInterval(interval); $('#status').text('状态:已暂停'); let video = document.querySelector('video'); if (video) video.pause(); } function getExamQuestions() { const result = []; document.querySelectorAll('.m-question').forEach(el => { const q = {}; q.title = el.querySelector('.sub-dotitle pre')?.innerText.trim() || '无题目'; q.options = {}; el.querySelectorAll('.m-question-option').forEach(opt => { const k = opt.getAttribute('data-value'); const v = opt.innerText.trim().replace(/^[A-Z]\./, '').trim(); if (k && v && !v.includes('null')) q.options[k] = v; }); result.push(q); }); return result; } function showQuestions() { const qs = getExamQuestions(); let txt = ''; if (!qs.length) txt = '未检测到题目'; else qs.forEach((q, i) => { txt += `第${i+1}题:${q.title}\n`; Object.entries(q.options).forEach(([k, v]) => txt += `${k}. ${v}\n`); txt += `——————————\n`; }); $('#questionDisplay').text(txt); } async function getImageAnswer() { try { $('.zkjx').click(); const img = document.querySelector('.solution img'); if (!img) { $('#answerStatus').text('OCR:未找到答案图'); return null; } const response = await fetch(img.src); const blob = await response.blob(); const text = await recognizeImage(blob); let oldText = $('#questionDisplay').text(); $('#questionDisplay').text(oldText + `\n✅识别答案:${text}\n`); const matchAll = text.match(/[A-D]/g); if (matchAll && matchAll.length > 0) { return [...new Set(matchAll)]; } } catch (e) { $('#answerStatus').text('OCR:识别失败'); } return null; } // 提交逻辑(仅进度达标才执行) function realSubmit() { setTimeout(() => { let submitBtn = document.getElementById('submitSelfBtn'); if (submitBtn) { $('#status').text('✅ 答案已提交,跳转下一课'); submitBtn.click(); } setTimeout(() => { hasJumped = true; goNext(); }, JUMP_DELAY); }, 1200); } /** * @param isAuto true=播放满60秒自动填,只勾选不校验提交进度;false=手动点击 */ async function getAnswerOnce(isAuto = false) { if (aiAlreadyCalled && isAuto) return; aiAlreadyCalled = true; $('#answerStatus').text('OCR状态:识别中...'); const ans = await getImageAnswer(); if (ans && Array.isArray(ans)) { $('#answerStatus').text(`OCR状态:${ans.join("、")}`); // 直接勾选答案 for (let key of ans) { let opt = document.querySelector(`.m-question-option[data-value="${key}"]`); if (opt) { opt.dispatchEvent(new MouseEvent('mousedown', {bubbles: true})); opt.dispatchEvent(new MouseEvent('mouseup', {bubbles: true})); opt.click(); opt.classList.add('active'); } } } else { $('#answerStatus').text('OCR:无有效答案'); } // 手动点击才校验进度、允许提交 if (!isAuto) { let percent = total > 0 ? (timer / total) * 100 : 0; if (percent < targetProgress) { $('#answerStatus').text(`当前${percent.toFixed(1)}%,需${targetProgress}%才可提交`); return; } realSubmit(); } } $(function () { createPanel(); loadDurationNow(); setTimeout(showQuestions, 800); $('#startBtn').click(start); $('#stopBtn').click(stop); $('#showQBtn').click(showQuestions); $('#getAnswerBtn').click(()=>getAnswerOnce(false)); }); } // ============================================== // 功能2:试卷全自动答题(无改动) // ============================================== function initExamModule() { window.confirm = () => true; window.alert = () => {}; window.prompt = () => null; function createPanel() { if (document.getElementById('autoStudyPanel')) return; let panel = $('
'); panel.css({ position: 'fixed', top: '100px', right: '20px', zIndex: '999999', background: '#fff', padding: '12px', borderRadius: '10px', boxShadow: '0 0 12px rgba(0,0,0,0.25)', width: '260px', maxHeight: '80vh', overflowY: 'auto', fontSize: '14px' }); panel.html(`
🎯 联大学堂自动答题
状态:加载完成,就绪
📋 答案列表:
`); $('body').append(panel); } function closePopups() { try { $("button:contains('确定'),button:contains('关闭'),.close,.layui-layer-close,.modal-close").click(); $(".layui-layer,.modal,.popup").hide(); } catch (e) {} } function expandAllAnswers() { $('.zkjx').click(); $('.solution').show(); } function getAllAnswers() { expandAllAnswers(); const result = []; $('.m-question').each((i, el) => { const q = {}; q.title = $(el).find('.sub-dotitle pre').text().trim() || $(el).find('.sub-dotitle').text().trim(); q.answer = $(el).find('.da-list:first .wenzi').text().trim(); q.element = el; if ($(el).find('.sub-answer-double').length > 0) q.type = "多选题"; else if ($(el).find('dd[data-value]').length > 0) q.type = "单选题"; else if ($(el).find('textarea').length > 0) q.type = "简答题"; else q.type = "其他题型"; result.push(q); }); return result; } function showAllAnswers() { const list = getAllAnswers(); let txt = ''; list.forEach((q, i) => { txt += `【第${i+1}题】(${q.type})\n答案:${q.answer || '无'}\n---\n`; }); $('#answerDisplay').text(txt); $('#status').text(`状态:已显示 ${list.length} 题完整答案`); } function autoAnswerOne(questionEl, answer) { if (!answer || answer === '') return; const $el = $(questionEl); let ans = answer.trim(); if (ans === "对" || ans === "正确") ans = "A"; if (ans === "错" || ans === "错误") ans = "B"; for (let c of ans) { if (c >= 'A' && c <= 'Z') { const opt = $el.find(`dd[data-value="${c}"]`); if (opt.length) opt.click().css({ background: '#e6f7ff', border: '1px solid #1890ff' }); const optText = c === 'A' ? "正确" : "错误"; const opt2 = $el.find(`dd[data-value="${optText}"]`); if (opt2.length) opt.click().css({ background: '#e6f7ff', border: '1px solid #1890ff' }); } } const textarea = $el.find('textarea.e__textarea, textarea'); if (textarea.length) textarea.val(answer).trigger('input').trigger('change').css({ background: '#e6f7ff', border: '1px solid #1890ff' }); } function autoAnswerAll() { closePopups(); const list = getAllAnswers(); if (list.length === 0) { $('#status').text('❌ 未找到题目,请确认页面加载完成'); return; } let count = 0; list.forEach((q, i) => { setTimeout(() => { autoAnswerOne(q.element, q.answer); count++; $('#status').text(`状态:答题中 ${count}/${list.length} 题`); }, i * 300); }); setTimeout(() => $('#status').text(`✅ 全部答题完成!共 ${list.length} 题`), list.length * 300 + 600); } function submitPaper() { closePopups(); setTimeout(() => { const btn = $('#btn_submit')[0] || $("button:contains('交卷')")[0] || $("a:contains('交卷')")[0]; if (btn) { btn.click(); $('#status').text('✅ 已触发交卷'); } else { $('#status').text('❌ 未找到交卷按钮'); } }, 1000); } $(function () { createPanel(); $('#autoAllBtn').click(autoAnswerAll); $('#showAnswerBtn').click(showAllAnswers); $('#submitBtn').click(submitPaper); $('#status').text('✅ 试卷答题加载成功,支持单选多选简答判断'); }); } // 等待视频DOM加载完成 function waitForVideo() { const check = setInterval(() => { const video = document.querySelector('video'); if (video) { clearInterval(check); hasVideo = true; initVideoModule(); } }, 500); } window.addEventListener('load', () => { if (hasExam) initExamModule(); else waitForVideo(); setTimeout(autoPlaySync, 1500); }); })();