// ==UserScript== // @name 联大学堂 全自动刷课+答题 // @namespace http://tampermonkey.net/ // @version 2.0 修复稳定版 // @description 视频页面跳过时间限制 // @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 // ==/UserScript== (function () { 'use strict'; let hasVideo = !!document.querySelector('video'); const hasExam = !!document.querySelector('.m-question'); // ============================================== // 功能1:视频刷课 + OCR答题(新版多选适配版) // ============================================== function initVideoModule() { // 强制解除时长限制 function unlockLimit() { try { if (typeof g_watchPercentage !== 'undefined') g_watchPercentage = 0; if (typeof g_totalAnwserTime !== 'undefined') g_totalAnwserTime = 0; if (typeof g_totalVideoDuration !== 'undefined' && g_totalVideoDuration > 0) { g_totalAnwserTime = Math.floor(g_totalVideoDuration * 0); } console.log("✅ 时长限制已强制解除"); } catch (e) {} } // 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'); text = text.replace(/©/g, 'C'); text = text.replace(/×/g, ''); text = text.replace(/条/g, '释'); text = text.replace(/可/g, '释'); text = text.replace(/了/g, 'B'); text = text.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:220px;max-height:80vh;overflow-y:auto;box-sizing:border-box; `; panel.innerHTML = `
🎯 全自动连刷
计时:00:00
总长:00:00
进度:0%
状态:等待启动
OCR状态:未获取
📋 题目&答案:
`; document.body.appendChild(panel); } let isRunning = false; let timer = 0; let total = 0; let interval = null; let jumped = false; 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)}%`); } function loop() { if (!isRunning || jumped) return; closePopups(); let video = document.querySelector('video'); if (!video) return; if (video.paused) video.play().catch(() => {}); if (!video.paused && !video.ended && video.readyState >= 4) { timer++; } updateInfo(); } // 下一课跳转 function goNext() { aiAlreadyCalled = false; $('#questionDisplay').text(''); $('#answerStatus').text('OCR状态:未获取'); let cur = $('dd.z-color.z-class-icon').first(); if (!cur.length) return; let next = cur.next('dd'); if (next.length) next.click(); else { let nextChap = cur.closest('.course-list-txt').next().find('dd').first(); if (nextChap.length) nextChap.click(); } setTimeout(() => { timer = 0; total = 0; jumped = false; loadDurationNow(); unlockLimit(); $('#status').text('状态:下一节加载中'); setTimeout(showQuestions, 1200); setTimeout(() => { if (isRunning && !aiAlreadyCalled) getAnswerOnce(); }, 2500); }, 4000); } function start() { isRunning = true; $('#status').text('状态:运行中(单选+多选已适配)'); clearInterval(interval); interval = setInterval(loop, 1000); setTimeout(() => { if (isRunning && !aiAlreadyCalled) getAnswerOnce(); }, 1500); } 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); } // 读取答案图片 + 提取全部ABCD 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(() => { jumped = true; goNext(); }, 1500); }, 1200); } // 核心:多选强制点击修复版 async function getAnswerOnce() { if (aiAlreadyCalled) 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:无有效答案'); } realSubmit(); } // 初始化绑定 $(function () { createPanel(); unlockLimit(); loadDurationNow(); setTimeout(showQuestions, 800); $('#startBtn').click(start); $('#stopBtn').click(stop); $('#showQBtn').click(showQuestions); $('#getAnswerBtn').click(getAnswerOnce); $('#unlockBtn').click(unlockLimit); }); } // ============================================== // 功能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) { opt2.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('✅ 脚本加载成功!支持单选+多选+简答+判断'); }); } // ============================================== // 自动监听视频 // ============================================== 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(); } }); })();