// ==UserScript== // @name 2026年5月广东省教师继续教育-自动学习答题 // @namespace auto-study-gds // @version 12.4 // @description 自动播放视频、自动切换下一节、自动答题、防挂机检测、AI考核 // @match https://jsxx.gds.edu.cn/study/course/* // @match https://jsglpt.gds.edu.cn/study/course/* // @match https://jsxx.gds.edu.cn/*/study/course/* // @match https://jsglpt.gds.edu.cn/*/study/course/* // @grant GM_xmlhttpRequest // @run-at document-idle // ==/UserScript== (function () { 'use strict'; var CFG = { CHECK_MS: 5000, MOUSE_MS: 15000, SCROLL_MS: 25000, CLICK_MS: 45000, QUIZ_MS: 2000, COMPLETE_WAIT: 60000, INIT_MS: 3000, MAX_LOG: 200, DQ_TIMEOUT: 60000, DQ_INTERVAL: 1500, }; var CID = (function () { var m = location.pathname.match(/c_([a-f0-9]{32})/i); return m ? 'c_' + m[1] : null; })(); var STKEY = '_as9_' + (CID || 'unk'); var _db = {}; function loadDB() { try { var s = localStorage.getItem(STKEY); if (s) _db = JSON.parse(s); if (!_db || typeof _db !== 'object') _db = {}; } catch (e) { _db = {}; } if (!_db.items) _db.items = {}; } function saveDB() { try { localStorage.setItem(STKEY, JSON.stringify(_db)); } catch (e) { } } function setStatus(aid, wat, req, done, name) { if (!_db.items[aid]) _db.items[aid] = {}; _db.items[aid].wat = wat; _db.items[aid].req = req; _db.items[aid].done = done; _db.items[aid].name = name || ''; _db.items[aid].ts = Date.now(); saveDB(); } function getStatus(aid) { return _db.items[aid] || null; } function isKnownDone(aid) { var s = getStatus(aid); return s && s.done === true; } function allDBItems() { return _db.items || {}; } function getProgress() { var items = _db.items || {}; var keys = Object.keys(items); var total = 0, done = 0; for (var i = 0; i < keys.length; i++) { if (keys[i].indexOf('a_') !== 0) continue; total++; if (items[keys[i]].done) done++; } return { total: total, done: done }; } var LOG = []; function log(msg, t) { t = t || 'info'; var ts = new Date().toLocaleTimeString(); var p = { info: 'INF', warn: 'WRN', error: 'ERR', quiz: 'Q', vid: 'V', exam: 'E' }; var line = '[' + ts + '][' + (p[t] || 'INF') + '] ' + msg; console.log('[AS] ' + line); LOG.push(line); if (LOG.length > CFG.MAX_LOG) LOG.shift(); refreshLogUI(); } var _paused = false; var _panel = false; var _collapsed = false; function makePanel() { if (_panel || document.getElementById('_asP')) return; _panel = true; var css = document.createElement('style'); css.textContent = '#_asP{position:fixed;top:12px;right:12px;z-index:999999;width:320px;' + 'font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;' + 'user-select:none;transition:all .35s cubic-bezier(.4,0,.2,1);overflow:hidden;border-radius:14px;' + 'box-shadow:0 8px 32px rgba(0,0,0,.35),0 0 0 1px rgba(255,255,255,.06);}' + '#_asP._coll{width:52px;border-radius:26px;}' + '#_asH{padding:14px 16px 10px;background:linear-gradient(135deg,#1a1a2e 0%,#16213e 50%,#0f3460 100%);' + 'cursor:pointer;display:flex;align-items:center;justify-content:space-between;position:relative;overflow:hidden;}' + '#_asP._coll #_asH{padding:12px;border-radius:26px;justify-content:center;}' + '#_asH::before{content:"";position:absolute;top:-50%;left:-50%;width:200%;height:200%;' + 'background:conic-gradient(from 0deg,transparent,rgba(0,255,200,.06),transparent,rgba(100,100,255,.06),transparent);' + 'animation:_asSpin 8s linear infinite;}@keyframes _asSpin{to{transform:rotate(360deg)}}' + '#_asHT{display:flex;flex-direction:column;gap:4px;position:relative;z-index:1;transition:opacity .2s;}' + '#_asP._coll #_asHT{display:none;}' + '#_asH1{font-size:14px;font-weight:700;color:#e0e0e0;letter-spacing:.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px;}' + '#_asH2{font-size:11px;color:rgba(255,255,255,.5);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px;}' + '#_asToggle{position:relative;z-index:1;width:28px;height:28px;border-radius:50%;border:1.5px solid rgba(255,255,255,.25);' + 'background:rgba(255,255,255,.08);display:flex;align-items:center;justify-content:center;flex-shrink:0;' + 'transition:transform .35s cubic-bezier(.4,0,.2,1);cursor:pointer;}' + '#_asToggle svg{width:14px;height:14px;fill:none;stroke:rgba(255,255,255,.7);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:transform .35s;}' + '#_asP._coll #_asToggle{transform:rotate(180deg);}' + '#_asBody{max-height:600px;overflow:hidden;transition:max-height .4s cubic-bezier(.4,0,.2,1),opacity .25s;opacity:1;background:#1e1e2e;}' + '#_asP._coll #_asBody{max-height:0;opacity:0;}' + '#_asProgWrap{padding:10px 16px 6px;background:rgba(0,0,0,.2);}' + '#_asProgTop{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:8px;}' + '#_asProgTxt{font-size:13px;font-weight:600;color:#e0e0e0;}' + '#_asProgPct{font-size:11px;color:rgba(255,255,255,.45);font-weight:500;}' + '#_asProgBar{width:100%;height:6px;background:rgba(255,255,255,.08);border-radius:3px;overflow:hidden;position:relative;}' + '#_asProgFill{height:100%;border-radius:3px;transition:width .6s ease;position:relative;' + 'background:linear-gradient(90deg,#00d2ff,#3a7bd5);' + 'box-shadow:0 0 8px rgba(0,210,255,.4);}' + '#_asProgFill::after{content:"";position:absolute;top:0;right:0;width:20px;height:100%;' + 'background:linear-gradient(90deg,transparent,rgba(255,255,255,.4));border-radius:3px;animation:_asShim 1.5s infinite;}' + '@keyframes _asShim{0%{opacity:0}50%{opacity:1}100%{opacity:0}}' + '#_asVidWrap{padding:10px 16px;display:flex;align-items:center;gap:14px;border-bottom:1px solid rgba(255,255,255,.05);}' + '#_asRing{width:48px;height:48px;flex-shrink:0;position:relative;}' + '#_asRing svg{width:48px;height:48px;transform:rotate(-90deg);}' + '#_asRingBg{fill:none;stroke:rgba(255,255,255,.08);stroke-width:3.5;}' + '#_asRingFg{fill:none;stroke-width:3.5;stroke-linecap:round;transition:stroke-dashoffset .8s ease,stroke .3s;' + 'filter:drop-shadow(0 0 4px rgba(0,255,136,.3));}' + '#_asRingTxt{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:10px;font-weight:700;color:#e0e0e0;}' + '#_asVidInfo{flex:1;min-width:0;}' + '#_asVidTitle{font-size:12px;color:rgba(255,255,255,.8);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom:4px;}' + '#_asVidTime{font-size:11px;color:rgba(255,255,255,.45);font-family:Consolas,monospace;}' + '#_asStudyRow{padding:6px 16px 10px;border-bottom:1px solid rgba(255,255,255,.05);}' + '#_asStudyBar{width:100%;height:4px;background:rgba(255,255,255,.06);border-radius:2px;overflow:hidden;margin-top:4px;}' + '#_asStudyFill{height:100%;border-radius:2px;transition:width .6s ease;background:linear-gradient(90deg,#f7971e,#ffd200);}' + '#_asStudyTxt{font-size:11px;color:rgba(255,255,255,.5);}' + '#_asTabs{display:flex;padding:0 16px;border-bottom:1px solid rgba(255,255,255,.05);}' + '#_asTabs button{flex:1;padding:8px 0;background:none;border:none;color:rgba(255,255,255,.35);font-size:11px;font-weight:600;' + 'cursor:pointer;position:relative;transition:color .2s;}' + '#_asTabs button:hover{color:rgba(255,255,255,.6);}' + '#_asTabs button._act{color:#00d2ff;}' + '#_asTabs button._act::after{content:"";position:absolute;bottom:0;left:20%;right:20%;height:2px;' + 'background:#00d2ff;border-radius:1px;box-shadow:0 0 6px rgba(0,210,255,.5);}' + '#_asPanels{max-height:200px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.1) transparent;}' + '#_asPanels::-webkit-scrollbar{width:4px;}' + '#_asPanels::-webkit-scrollbar-thumb{background:rgba(255,255,255,.12);border-radius:2px;}' + '#_asPanel{display:none;padding:8px 16px 10px;}' + '#_asPanel._act{display:block;}' + '#_asList ._asItem{display:flex;align-items:center;gap:8px;padding:5px 0;border-bottom:1px solid rgba(255,255,255,.03);font-size:11px;}' + '#_asList ._asItem:last-child{border-bottom:none;}' + '#_asDot{width:8px;height:8px;border-radius:50%;flex-shrink:0;}' + '#_asDot.ok{background:#00ff88;box-shadow:0 0 6px rgba(0,255,136,.4);}' + '#_asDot.ing{background:#ffd200;box-shadow:0 0 6px rgba(255,210,0,.4);}' + '#_asDot.no{background:rgba(255,255,255,.15);}' + '#_asDot.cur{background:#00d2ff;box-shadow:0 0 6px rgba(0,210,255,.5);animation:_asPulse 1.5s infinite;}' + '@keyframes _asPulse{0%,100%{box-shadow:0 0 4px rgba(0,210,255,.3)}50%{box-shadow:0 0 10px rgba(0,210,255,.6)}}' + '#_asINm{flex:1;color:rgba(255,255,255,.7);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}' + '#_asINm.cur{color:#00d2ff;font-weight:600;}' + '#_asITm{font-size:10px;color:rgba(255,255,255,.3);font-family:Consolas,monospace;flex-shrink:0;}' + '#_asLogLine{font-size:10px;color:rgba(255,255,255,.4);font-family:Consolas,monospace;padding:2px 0;border-bottom:1px solid rgba(255,255,255,.02);line-height:1.5;word-break:break-all;}' + '#_asLogLine .t{color:rgba(255,255,255,.2);margin-right:6px;}' + '#_asLogLine .tag{color:#00d2ff;}' + '#_asLogLine .w{color:#ffd200;}' + '#_asLogLine .e{color:#ff5555;}' + '#_asLogLine .q{color:#c084fc;}' + '#_asLogLine .v{color:#00ff88;}' + '#_asLogLine .ex{color:#ff9f43;}' + '#_asBtns{display:flex;gap:8px;padding:10px 16px 14px;background:rgba(0,0,0,.15);}' + '#_asBtns button{flex:1;padding:7px 0;border:none;border-radius:8px;font-size:12px;font-weight:600;cursor:pointer;' + 'transition:all .2s;position:relative;overflow:hidden;}' + '#_asBtns button:active{transform:scale(.96);}' + '#_asB1{background:rgba(255,255,255,.08);color:#e0e0e0;}' + '#_asB1:hover{background:rgba(255,255,255,.14);}' + '#_asB1._paused{background:linear-gradient(135deg,#3a7bd5,#00d2ff);color:#fff;}' + '#_asB2{background:rgba(0,210,255,.12);color:#00d2ff;}' + '#_asB2:hover{background:rgba(0,210,255,.22);}' + '#_asB4{background:rgba(0,255,136,.12);color:#00ff88;}' + '#_asB4:hover{background:rgba(0,255,136,.22);}' + '#_asExam{padding:10px 16px 14px;border-top:1px solid rgba(255,255,255,.08);background:rgba(100,50,200,.08);}' + '#_asExamKey{padding:6px 16px 8px;border-bottom:1px solid rgba(255,255,255,.08);background:rgba(0,0,0,.1);}' + '#_asExamKeyH{font-size:11px;color:rgba(255,255,255,.5);margin-bottom:4px;}' + '#_asExamKey input{width:100%;box-sizing:border-box;padding:6px 10px;border-radius:6px;border:1px solid rgba(255,255,255,.15);' + 'background:rgba(0,0,0,.3);color:#e0e0e0;font-size:11px;font-family:Consolas,monospace;outline:none;transition:border-color .2s;}' + '#_asExamKey input:focus{border-color:#c084fc;}' + '#_asExamKey input::placeholder{color:rgba(255,255,255,.2);}' + '#_asExamKeyBtns{display:flex;gap:6px;margin-top:6px;}' + '#_asExamKeyBtns button{flex:1;padding:4px 0;border:none;border-radius:4px;font-size:10px;font-weight:600;cursor:pointer;transition:all .2s;}' + '#_asExamKeyBtns button:active{transform:scale(.96);}' + '#_asK1{background:rgba(0,255,136,.15);color:#00ff88;}' + '#_asK1:hover{background:rgba(0,255,136,.25);}' + '#_asK2{background:rgba(255,255,255,.06);color:rgba(255,255,255,.5);}' + '#_asK2:hover{background:rgba(255,255,255,.12);}' + '#_asExamH{margin-bottom:8px;}' + '#_asExamH1{font-size:13px;font-weight:700;color:#c084fc;}' + '#_asExamH2{font-size:11px;color:rgba(255,255,255,.5);margin-top:2px;}' + '#_asExamQ{font-size:11px;color:rgba(255,255,255,.8);margin:8px 0;max-height:60px;overflow:hidden;line-height:1.5;}' + '#_asExamOpts{margin:6px 0;}' + '#_asExamOpts button{display:block;width:100%;padding:5px 8px;margin:3px 0;border:1px solid rgba(255,255,255,.1);border-radius:6px;' + 'background:rgba(255,255,255,.04);color:rgba(255,255,255,.7);font-size:11px;text-align:left;cursor:pointer;transition:all .15s;}' + '#_asExamOpts button:hover{background:rgba(255,255,255,.08);}' + '#_asExamOpts button._sel{background:rgba(100,50,200,.25);border-color:#c084fc;color:#fff;}' + '#_asExamAct{display:flex;gap:6px;margin-top:8px;}' + '#_asExamAct button{flex:1;padding:6px 0;border:none;border-radius:6px;font-size:11px;font-weight:600;cursor:pointer;transition:all .2s;}' + '#_asExamAct button:active{transform:scale(.96);}' + '#_asEB1{background:rgba(100,50,200,.2);color:#c084fc;}' + '#_asEB1:hover{background:rgba(100,50,200,.35);}' + '#_asEB2{background:rgba(255,255,255,.08);color:#e0e0e0;}' + '#_asEB2:hover{background:rgba(255,255,255,.14);}' + '#_asEB3{background:rgba(0,255,136,.15);color:#00ff88;}' + '#_asEB3:hover{background:rgba(0,255,136,.25);}' + '#_asEB4{background:rgba(255,100,50,.15);color:#ff6432;}' + '#_asEB4:hover{background:rgba(255,100,50,.25);}' + '#_asExamProg{width:100%;height:4px;background:rgba(255,255,255,.06);border-radius:2px;margin-top:8px;overflow:hidden;}' + '#_asExamProgFill{height:100%;border-radius:2px;background:linear-gradient(90deg,#c084fc,#ff6b9d);transition:width .4s ease;}'; document.head.appendChild(css); var d = document.createElement('div'); d.id = '_asP'; d.innerHTML = '
' + '
' + '
AutoStudy v12.0
' + '
自动学习中...
' + '
' + '
' + '
' + '
' + '
' + '
0 / 0 已完成0%
' + '
' + '
' + '
' + '
0%
' + '
等待视频...
--:-- / --:--
' + '
' + '
学习时长: -- / -- min
' + '
' + '' + '' + '
' + '
' + '
' + '
' + '
' + '
' + '' + '' + '' + '' + '
' + '
' + '
获取硅基流动 API 免费额度
硅基流动 API Key
' + '' + '
' + '
考核模式
就绪
' + '
' + '
' + '
' + '' + '' + '' + '' + '
' + '
' + '
' + '
'; document.body.appendChild(d); document.getElementById('_asToggle').onclick = function () { _collapsed = !_collapsed; var p = document.getElementById('_asP'); if (_collapsed) { p.classList.add('_coll'); } else { p.classList.remove('_coll'); } }; document.getElementById('_asB1').onclick = function () { _paused = !_paused; if (_paused) { this.textContent = '继续'; this.classList.add('_paused'); } else { this.textContent = '暂停'; this.classList.remove('_paused'); } log(_paused ? '已暂停' : '已继续', 'warn'); }; document.getElementById('_asB2').onclick = function () { log('手动下一节', 'warn'); _switching = false; _promptDone = false; nextVideo(); }; document.getElementById('_asB4').onclick = function () { switchTab('log'); }; document.getElementById('_asB5').onclick = function () { goToExam(); }; document.getElementById('_asEB3').onclick = function () { startAutoExam(); }; document.getElementById('_asEB1').onclick = function () { enterManualExamMode(); }; document.getElementById('_asEB4').onclick = function () { stopAutoExam(); }; document.getElementById('_asEB2').onclick = function () { exitExamMode(); }; document.getElementById('_asTab1').onclick = function () { switchTab('list'); }; document.getElementById('_asTab2').onclick = function () { switchTab('log'); }; var keyInput = document.getElementById('_asKeyInput'); var savedKey = getApiKey(); if (savedKey) keyInput.value = savedKey.substring(0, 8) + '***'; document.getElementById('_asK1').onclick = function () { var val = keyInput.value.trim(); if (val && !val.endsWith('***')) { setApiKey(val); log('API Key 已保存', 'warn'); keyInput.value = val.substring(0, 8) + '***'; } else { log('请输入有效的 Key', 'error'); } }; document.getElementById('_asK2').onclick = function () { setApiKey(''); keyInput.value = ''; log('API Key 已清除', 'warn'); }; keyInput.onfocus = function () { var realKey = getApiKey(); if (realKey) keyInput.value = realKey; }; log('API Key: ' + (savedKey ? '已设置' : '未设置'), savedKey ? 'warn' : 'warn'); } function switchTab(name) { var btns = document.querySelectorAll('#_asTabs button'); for (var i = 0; i < btns.length; i++) { if (btns[i].getAttribute('data-p') === name) btns[i].classList.add('_act'); else btns[i].classList.remove('_act'); } var panels = document.querySelectorAll('#_asPanels ._asPanel'); for (var i = 0; i < panels.length; i++) { if (panels[i].id === '_asPanel' + name.charAt(0).toUpperCase() + name.slice(1)) panels[i].classList.add('_act'); else panels[i].classList.remove('_act'); } if (name === 'list') refreshListUI(); if (name === 'log') refreshLogUI(); } function refreshLogUI() { var el = document.getElementById('_asPanelLog'); if (!el || !el.classList.contains('_act')) return; var html = ''; for (var i = LOG.length - 30; i < LOG.length; i++) { if (i < 0) continue; var line = LOG[i]; var cls = '_asLogLine'; line = line.replace(/\[ERR\]/g, '[ERR]'); line = line.replace(/\[WRN\]/g, '[WRN]'); line = line.replace(/\[Q\]/g, '[Q]'); line = line.replace(/\[E\]/g, '[E]'); line = line.replace(/\[V\]/g, '[V]'); line = line.replace(/\[INF\]/g, '[INF]'); html += '
' + line + '
'; } el.innerHTML = html; el.scrollTop = el.scrollHeight; } function refreshVideoUI() { var v = vid(); var ringFg = document.getElementById('_asRingFg'); var ringTxt = document.getElementById('_asRingTxt'); var vidTitle = document.getElementById('_asVidTitle'); var vidTime = document.getElementById('_asVidTime'); var studyTxt = document.getElementById('_asStudyTxt'); var studyFill = document.getElementById('_asStudyFill'); var h1 = document.getElementById('_asH1'); var h2 = document.getElementById('_asH2'); if (!v || !v.duration) { if (ringTxt) ringTxt.textContent = '--'; if (vidTitle) vidTitle.textContent = '等待视频...'; if (vidTime) vidTime.textContent = '--:-- / --:--'; if (h2) h2.textContent = '等待视频加载...'; refreshProgUI(); return; } var cur = fmt(v.currentTime), dur = fmt(v.duration); var pct = v.duration > 0 ? v.currentTime / v.duration * 100 : 0; var circ = 125.66; var offset = circ - (circ * pct / 100); if (ringFg) { ringFg.setAttribute('stroke-dashoffset', offset); var col = pct >= 99.5 ? '#00ff88' : pct > 50 ? '#00d2ff' : '#ffd200'; ringFg.setAttribute('stroke', col); } if (ringTxt) ringTxt.textContent = Math.round(pct) + '%'; if (vidTitle) { var nm = curName(); vidTitle.textContent = nm || '未知视频'; } if (vidTime) { var st = v.paused ? ' ||' : v.ended ? ' END' : ' >>'; vidTime.textContent = cur + ' / ' + dur + st; } if (h1) h1.textContent = 'AutoStudy v12.0'; if (h2) { var nm2 = curName(); h2.textContent = nm2 ? nm2.substring(0, 30) : '自动学习中...'; } var si = studyInfo(); if (si && si.req >= 0 && si.wat >= 0) { if (studyTxt) studyTxt.textContent = '学习时长: ' + si.wat + ' / ' + si.req + ' min' + (si.wat >= si.req ? ' ✓' : ''); if (studyFill) { var sp = Math.min(si.wat / si.req * 100, 100); studyFill.style.width = sp + '%'; studyFill.style.background = sp >= 100 ? 'linear-gradient(90deg,#00ff88,#00cc6a)' : 'linear-gradient(90deg,#f7971e,#ffd200)'; } } else { if (studyTxt) studyTxt.textContent = '学习时长: 计算中...'; if (studyFill) studyFill.style.width = '0%'; } refreshProgUI(); } function refreshProgUI() { var txt = document.getElementById('_asProgTxt'); var pct = document.getElementById('_asProgPct'); var fill = document.getElementById('_asProgFill'); if (!txt) return; var pg = getProgress(); var p = pg.total > 0 ? Math.round(pg.done / pg.total * 100) : 0; txt.textContent = pg.done + ' / ' + pg.total + ' 已完成'; if (pct) pct.textContent = p + '%'; if (fill) fill.style.width = p + '%'; } function refreshListUI() { var el = document.getElementById('_asPanelList'); if (!el) return; var aids = allAids(); var cur = curAid(); var html = ''; for (var i = 0; i < aids.length; i++) { var aid = aids[i]; var nm = nameById(aid) || aid.substring(0, 12); var st = getStatus(aid); var isCur = aid === cur; var dotCls, nmCls; if (isCur) { dotCls = 'cur'; nmCls = ' cur'; } else if (st && st.done) { dotCls = 'ok'; nmCls = ''; } else if (st && st.wat >= 0 && st.wat < st.req) { dotCls = 'ing'; nmCls = ''; } else { dotCls = 'no'; nmCls = ''; } var tm = ''; if (st && st.wat >= 0 && st.req >= 0) tm = st.wat + '/' + st.req + 'm'; html += '
' + '
' + nm + '
' + '
' + tm + '
'; } el.innerHTML = html; } function spoofVis() { try { Object.defineProperty(document, 'hidden', { get: function () { return false; }, configurable: true }); } catch (e) { } try { Object.defineProperty(document, 'visibilityState', { get: function () { return 'visible'; }, configurable: true }); } catch (e) { } ['visibilitychange', 'webkitvisibilitychange'].forEach(function (n) { document.addEventListener(n, function (e) { e.stopImmediatePropagation(); }, true); }); window.addEventListener('blur', function (e) { e.stopImmediatePropagation(); }, true); } function fakeMouse(x, y) { try { var el = document.elementFromPoint(x, y); ['mouseenter', 'mouseover', 'mousemove'].forEach(function (t) { try { var ev = new MouseEvent(t, { bubbles: true, cancelable: true }); try { ev = new MouseEvent(t, { clientX: x, clientY: y, bubbles: true, cancelable: true }); } catch (e2) {} if (el) el.dispatchEvent(ev); document.dispatchEvent(ev); } catch (e3) {} }); } catch (e) {} } function fakeClick(x, y) { try { var el = document.elementFromPoint(x, y); if (!el) return; var tg = el.tagName.toLowerCase(); if (['video', 'input', 'select', 'textarea', 'a', 'button'].indexOf(tg) >= 0) return; if (el.closest('video,input,select,textarea,a.btn,button')) return; ['mousedown', 'mouseup', 'click'].forEach(function (t) { try { var ev = new MouseEvent(t, { bubbles: true, cancelable: true, button: 0 }); try { ev = new MouseEvent(t, { clientX: x, clientY: y, bubbles: true, cancelable: true, button: 0 }); } catch (e2) {} el.dispatchEvent(ev); } catch (e3) {} }); } catch (e) {} } function vid() { return document.querySelector('video'); } function ckp() { if (window.player) return window.player; try { var f = document.querySelector('iframe'); if (f && f.contentWindow && f.contentWindow.player) return f.contentWindow.player; } catch (e) { } return null; } function studyInfo() { var vt = document.getElementById('viewTimeTxt'); if (!vt) return null; var wat = parseInt(vt.textContent, 10); if (isNaN(wat)) wat = -1; var p = vt.closest('.g-study-prompt'); if (!p) return { req: -1, wat: wat }; var spans = p.querySelectorAll('span'); var req = -1; for (var i = 0; i < spans.length; i++) { if (spans[i] === vt) continue; var n = parseInt(spans[i].textContent, 10); if (!isNaN(n)) { req = n; break; } } if (req < 0) { var hi = p.querySelector('input[type="hidden"]'); if (hi) { var hv = parseInt(hi.value, 10); if (!isNaN(hv)) req = hv; } } return { req: req, wat: wat }; } function resume() { var v = vid(); if (!v || v.ended) return false; if (!v.paused) return true; var ck = ckp(); if (ck) { try { if (typeof ck.videoPlay === 'function') { ck.videoPlay(); return true; } } catch (e) { } try { if (typeof ck.play === 'function') { ck.play(); return true; } } catch (e) { } } try { var r = v.play(); if (r && typeof r.catch === 'function') r.catch(function () { }); return true; } catch (e) { } return false; } function fmt(s) { var m = Math.floor(s / 60), sec = Math.floor(s % 60); return m + ':' + (sec < 10 ? '0' : '') + sec; } var _quizDone = false, _quizHash = ''; function checkQuiz() { if (_paused) return; var qd = document.getElementById('questionDiv'); var ly = document.querySelector('.mylayer-layer'); if (!ly || !qd) { _quizDone = false; _quizHash = ''; return; } if (ly.style.display === 'none') return; if (ly.offsetWidth === 0 && ly.style.width === '0px') return; var h = qd.textContent.length + '|' + (qd.querySelector('.qs-type') || {}).textContent; if (_quizDone && h === _quizHash) return; var ans = extractAns(qd); if (!ans || ans.length === 0) { log('答案提取失败,重试中', 'error'); return; } _quizDone = true; _quizHash = h; log('答案: ' + ans.join(','), 'quiz'); selectAndSubmit(qd, ans); } function extractAns(qd) { var sc = findScripts(qd); if (sc.length === 0) { log('无script', 'error'); return null; } for (var i = 0; i < sc.length; i++) { var c = sc[i].textContent; var m1 = c.match(/var\s+answerList;\s*if\s*\('([^']+)'\.includes\('/); if (m1) { var r = m1[1]; if (r.indexOf(',') >= 0) { try { return JSON.parse(r); } catch (e) { } } return [r]; } var m2 = c.match(/answerList\s*=\s*\[([^\]]+)\]/); if (m2) { return m2[1].replace(/'/g, '').split(',').map(function (v) { return v.trim(); }); } var m3 = c.match(/answerList\s*=\s*JSON\.parse\('([^']+)'\)/); if (m3) { try { return JSON.parse(m3[1]); } catch (e) { } } } return null; } function findScripts(qd) { var p = qd.parentElement; if (p) { var s = p.querySelectorAll('script'); if (s.length > 0) return s; } var g = qd.closest('.mylayer-layer'); if (g) return g.querySelectorAll('script'); var all = document.querySelectorAll('script'); var res = []; for (var i = 0; i < all.length; i++) { if (all[i].textContent.indexOf('finishTest') >= 0) res.push(all[i]); } return res; } function selectAndSubmit(qd, ans) { var ins = qd.querySelectorAll('input[name="response"]'); ins.forEach(function (inp) { inp.checked = false; var lb = inp.closest('label'); if (lb) { var st = lb.querySelector('strong'); if (st) st.className = ''; } }); ans.forEach(function (a) { ins.forEach(function (inp) { if (inp.value === a) { inp.checked = true; var lb = inp.closest('label'); if (lb) { var st = lb.querySelector('strong'); if (st) st.className = 'on'; } var sp = lb ? lb.querySelector('span') : null; log('选: ' + a + ' ' + (sp ? sp.textContent.trim() : ''), 'quiz'); } }); }); setTimeout(function () { submit(qd); }, 500); } function submit(qd) { if (typeof window.finishTest === 'function') { try { window.finishTest(); log('finishTest() OK', 'quiz'); setTimeout(function () { var ly = document.querySelector('.mylayer-layer'); if (ly && ly.style.display !== 'none' && ly.offsetWidth > 0) { _quizDone = false; } else { log('答题弹窗关闭', 'quiz'); setTimeout(resume, 1000); } }, 2000); return; } catch (e) { log('finishTest err: ' + e.message, 'error'); } } var btn = qd.querySelector('.u-main-btn'); if (btn) { btn.click(); setTimeout(function () { var ly = document.querySelector('.mylayer-layer'); if (ly && ly.style.display !== 'none' && ly.offsetWidth > 0) { _quizDone = false; } else { setTimeout(resume, 1000); } }, 2000); return; } _quizDone = false; } function checkCompletePopup() { if (_paused) return; var lys = document.querySelectorAll('.mylayer-layer'); for (var i = 0; i < lys.length; i++) { var ly = lys[i]; if (ly.style.display === 'none' || ly.offsetWidth === 0) continue; var ct = ly.querySelector('.mylayer-content'); if (!ct) continue; var tx = ct.textContent || ''; if (tx.indexOf('已完成这个活动') >= 0 || tx.indexOf('已完成此活动') >= 0) { log('"已完成活动"弹窗', 'warn'); var aid = curAid(); var nm = curName() || ''; var si = studyInfo(); if (aid) setStatus(aid, si ? si.wat : -1, si ? si.req : -1, true, nm); var ob = ly.querySelector('.mylayer-btn.type1') || ly.querySelector('button.mylayer-btn'); if (ob) { ob.click(); log('点击确定'); if (_examMode || _autoExamRunning) { log('考核模式,不自动切换', 'exam'); } else { setTimeout(function () { _promptDone = false; nextVideo(); }, 2000); } } else { var cb = ly.querySelector('.mylayer-closeico'); if (cb) cb.click(); } return; } } } var _promptDone = false; var _completeTimer = null; function checkStudyProgress() { if (_paused) return; if (_examMode || isExamPage()) return; var si = studyInfo(); if (!si || si.req < 0 || si.wat < 0) return; var aid = curAid(); var nm = curName() || ''; if (!aid) return; setStatus(aid, si.wat, si.req, si.wat >= si.req, nm); if (_promptDone) return; if (isKnownDone(aid)) { _promptDone = true; log('已知完成: ' + nm + ' (' + si.wat + '>=' + si.req + ') 切下一节(等60秒)', 'vid'); if (_completeTimer) clearTimeout(_completeTimer); _completeTimer = setTimeout(function () { _promptDone = false; nextVideo(); }, CFG.COMPLETE_WAIT); return; } if (si.wat >= si.req) { _promptDone = true; setStatus(aid, si.wat, si.req, true, nm); log('学习达标 ' + si.wat + '>=' + si.req + 'min 切下一节(等60秒)', 'vid'); if (_completeTimer) clearTimeout(_completeTimer); _completeTimer = setTimeout(function () { _promptDone = false; nextVideo(); }, CFG.COMPLETE_WAIT); } } function curAid() { var m = location.pathname.match(/a_([a-f0-9]{32})/i); if (m) return 'a_' + m[1]; var c = document.querySelector('a.section.z-crt'); if (c) { var dd = c.closest('dd[childsectionactivitieid]'); if (dd) return dd.getAttribute('childsectionactivitieid'); } return null; } function curName() { var c = document.querySelector('a.section.z-crt'); if (c) { var sp = c.querySelector('.txt'); if (sp) return sp.textContent.trim(); return c.textContent.trim(); } var h = document.querySelector('.g-studyAct-box h3'); return h ? h.textContent.trim() : null; } function nameById(aid) { var dd = document.querySelector('dd[childsectionactivitieid="' + aid + '"]'); if (dd) { var sp = dd.querySelector('.txt'); if (sp) return sp.textContent.trim(); var a = dd.querySelector('a.section'); if (a) return a.textContent.trim(); } return null; } function allAids() { var ids = []; document.querySelectorAll('dd[childsectionactivitieid]').forEach(function (dd) { var id = dd.getAttribute('childsectionactivitieid'); var a = dd.querySelector('a.section'); if (a && a.textContent.indexOf('考核') < 0) ids.push(id); }); return ids; } function nextAid(cur) { var ids = allAids(); var idx = ids.indexOf(cur); return idx >= 0 && idx < ids.length - 1 ? ids[idx + 1] : null; } function findFirstIncomplete() { var aids = allAids(); for (var i = 0; i < aids.length; i++) { if (!isKnownDone(aids[i])) return aids[i]; } return null; } var _switching = false; function nextVideo() { if (_switching) return false; if (isExamPage() || _examMode) { _switching = false; log('考核页面,停止自动切换', 'exam'); return false; } _switching = true; _promptDone = false; var btns = document.querySelectorAll('a.btn.next'); for (var i = 0; i < btns.length; i++) { if (btns[i].classList.contains('disable') || btns[i].classList.contains('disabled')) continue; if (btns[i].offsetWidth === 0) continue; btns[i].click(); log('"下一个活动"按钮', 'vid'); schedResume(); return true; } var c = curAid(), n = nextAid(c); if (n && CID && typeof studyCourse === 'function') { studyCourse(CID, '', n); log('studyCourse -> ' + n.substring(0, 12), 'vid'); schedResume(); return true; } _switching = false; log('没有下一节了', 'warn'); return false; } function schedResume() { [4000, 7000, 11000, 18000].forEach(function (d) { setTimeout(function () { if (d === 4000) { var si = studyInfo(); var aid = curAid(); var nm = curName() || ''; if (si && si.req >= 0 && si.wat >= 0 && si.wat >= si.req) { if (aid) setStatus(aid, si.wat, si.req, true, nm); if (isKnownDone(aid)) { log('新活动已完成,跳过', 'vid'); _promptDone = true; setTimeout(function () { _promptDone = false; nextVideo(); }, CFG.COMPLETE_WAIT); return; } } } var v = vid(); if (v && v.paused && !v.ended) { resume(); if (d < 11000) log('恢复播放 ' + d + 'ms', 'vid'); } if (d >= 11000) _switching = false; }, d); }); } var _endDone = false; function onEnd() { if (_endDone) return; if (_examMode || isExamPage()) return; _endDone = true; var v = vid(); if (!v) return; var si = studyInfo(); if (si && si.req >= 0 && si.wat >= 0 && si.wat < si.req) { log('视频播完但学习时间不够 ' + si.wat + '/' + si.req + ' 重新播放', 'warn'); _endDone = false; setTimeout(function () { v.currentTime = 0; var ck = ckp(); if (ck && typeof ck.videoPlay === 'function') ck.videoPlay(); else if (ck && typeof ck.play === 'function') ck.play(); else v.play(); }, 3000); return; } log('视频结束,学习达标', 'vid'); var aid = curAid(); var nm = curName() || ''; if (aid) setStatus(aid, si ? si.wat : -1, si ? si.req : -1, true, nm); _promptDone = true; setTimeout(function () { _promptDone = false; nextVideo(); _endDone = false; }, CFG.COMPLETE_WAIT); } function isExamPage() { var c = document.querySelector('a.section.z-crt'); if (c && c.textContent.indexOf('考核') >= 0) return true; var aid = curAid(); if (aid === getExamAid()) return true; var nm = curName() || ''; if (nm === '考核' || nm === '考试') return true; return false; } function videoLoop() { if (_paused) return; if (_examMode || isExamPage()) return; if (location.href.indexOf('/study/course/') < 0) return; var v = vid(); if (!v) return; refreshVideoUI(); if (v.paused && !v.ended) { for (var i = 0; i < 3; i++) { if (!v.paused) break; resume(); } } if (v.ended || (v.duration > 0 && v.currentTime >= v.duration - 3)) onEnd(); } var _examMode = false; var _autoExamRunning = false; var _autoExamIdx = 0; var _autoExamQuestions = []; var _examTimer = null; var _examHash = ''; var _examSelected = []; var _examMulti = false; var _examDoc = null; var _manualExam = false; var _dqAnswerTimer = null; function getApiKey() { return localStorage.getItem('_as_si_key') || ''; } function setApiKey(k) { try { localStorage.setItem('_as_si_key', k); } catch (e) { } } var SI_API_URL = 'https://api.siliconflow.cn/v1/chat/completions'; var SI_MODEL = 'deepseek-ai/DeepSeek-V4-Pro'; function getExamAid() { var els = document.querySelectorAll('dd[childsectionactivitieid]'); for (var i = 0; i < els.length; i++) { var a = els[i].querySelector('a.section'); if (a && a.textContent.indexOf('考核') >= 0) return els[i].getAttribute('childsectionactivitieid'); } return null; } function getExamDoc() { var iframes = document.querySelectorAll('iframe'); for (var i = 0; i < iframes.length; i++) { try { var doc = iframes[i].contentDocument || iframes[i].contentWindow.document; if (doc && doc.body && doc.body.innerHTML.length > 50) { if (doc.querySelector('.m-topic-item') || doc.querySelector('.g-topic-lst')) return doc; } } catch (e) { } } if (document.querySelector('.m-topic-item') || document.querySelector('.g-topic-lst')) return document; return null; } function goToExam() { var eid = getExamAid(); if (!eid) { log('未找到考核活动', 'error'); return; } if (CID && typeof studyCourse === 'function') { studyCourse(CID, '', eid); log('跳转考核', 'warn'); } } function enterExamMode() { if (_examMode) return; _examMode = true; _examHash = ''; _examSelected = []; _manualExam = false; var el = document.getElementById('_asExam'); if (el) el.classList.add('_show'); log('进入考核模式', 'warn'); } function enterManualExamMode() { _manualExam = true; if (_examTimer) { clearInterval(_examTimer); _examTimer = null; } _examTimer = setInterval(scanExamQuestion, 3000); setTimeout(scanExamQuestion, 1000); log('手动答题模式', 'exam'); updateExamStatus('手动答题 - 题目加载中...'); } function exitExamMode() { stopAutoExam(); _examMode = false; if (_examTimer) { clearInterval(_examTimer); _examTimer = null; } var el = document.getElementById('_asExam'); if (el) el.classList.remove('_show'); log('退出考核模式', 'warn'); } function stopAutoExam() { _autoExamRunning = false; if (_dqAnswerTimer) { clearTimeout(_dqAnswerTimer); _dqAnswerTimer = null; } if (_dqSafetyTimer) { clearTimeout(_dqSafetyTimer); _dqSafetyTimer = null; } if (_examTimer) { clearInterval(_examTimer); _examTimer = null; } log('停止自动答题', 'exam'); updateExamStatus('已停止'); } function parseAllExamQuestions(doc) { var questions = []; var items = doc.querySelectorAll('.m-topic-item'); if (items.length === 0) { var topicList = doc.getElementById('topicList'); if (topicList) items = topicList.querySelectorAll('li'); } for (var i = 0; i < items.length; i++) { var item = items[i]; var titleEl = item.querySelector('.title'); if (!titleEl) continue; var typeEl = titleEl.querySelector('.qs-type'); var typeText = typeEl ? typeEl.textContent.trim() : ''; var qText = titleEl.textContent.replace(typeEl ? typeEl.textContent : '', '').replace(/^\d+[、.]\s*/, '').trim(); var isMulti = typeText.indexOf('多选') >= 0; var isJudge = typeText.indexOf('是非') >= 0 || typeText.indexOf('判断') >= 0; var options = []; var inputs = item.querySelectorAll('input[type="radio"], input[type="checkbox"]'); for (var j = 0; j < inputs.length; j++) { var label = inputs[j].closest('label'); var text = ''; if (label) { var span = label.querySelector('span'); text = span ? span.textContent.trim() : label.textContent.trim(); } options.push({ value: inputs[j].value, text: text, input: inputs[j] }); } if (options.length > 0) { questions.push({ index: questions.length, text: qText, type: typeText, multi: isMulti || isJudge, judge: isJudge, options: options, item: item }); } } return questions; } var _examRetryCount = 0; var _examGoCount = 0; var _dqSafetyTimer = null; function startAutoExam() { if (_autoExamRunning) { log('自动答题已在运行', 'warn'); return; } if (!getApiKey()) { log('请先在面板填写硅基流动 API Key!', 'error'); updateExamStatus('请填写 API Key'); return; } var doc = getExamDoc(); if (!doc) { _examRetryCount++; if (_examRetryCount > 10) { log('考核页面加载失败,已重试10次,放弃', 'error'); _examRetryCount = 0; _examGoCount = 0; return; } log('等待考核题目加载(' + _examRetryCount + '/10)', 'exam'); if (_examGoCount < 1) { _examGoCount = 1; goToExam(); } setTimeout(startAutoExam, 5000); return; } _examRetryCount = 0; _examGoCount = 0; _autoExamQuestions = parseAllExamQuestions(doc); if (_autoExamQuestions.length === 0) { _examRetryCount++; if (_examRetryCount > 10) { log('未找到考核题目,已重试10次,放弃', 'error'); _examRetryCount = 0; return; } log('考核题目解析中(' + _examRetryCount + '/10)', 'exam'); setTimeout(startAutoExam, 5000); return; } _examRetryCount = 0; _examGoCount = 0; _autoExamRunning = true; _autoExamIdx = 0; _manualExam = false; log('开始自动答题,共' + _autoExamQuestions.length + '题', 'exam'); updateExamStatus('硅基流动就绪'); updateExamProg(0, _autoExamQuestions.length); setTimeout(processNextExamQ, 2000); } function callSiliconFlow(prompt, callback) { log('调用硅基流动 API...', 'exam'); GM_xmlhttpRequest({ method: 'POST', url: SI_API_URL, headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + getApiKey() }, data: JSON.stringify({ model: SI_MODEL, messages: [ { role: 'system', content: '你是一个考试答题助手。请只回答选项字母(如A、BC、ABD),不要任何解释。' }, { role: 'user', content: prompt } ], temperature: 0.1, max_tokens: 50 }), timeout: CFG.DQ_TIMEOUT, onload: function (resp) { try { var data = JSON.parse(resp.responseText); var answer = data.choices && data.choices[0] && data.choices[0].message ? data.choices[0].message.content.trim() : ''; log('API返回: ' + answer, 'exam'); callback(answer); } catch (e) { log('解析API响应失败: ' + e.message, 'error'); callback(''); } }, onerror: function () { log('API请求失败', 'error'); callback(''); }, ontimeout: function () { log('API超时', 'error'); callback(''); } }); } function processNextExamQ() { if (!_autoExamRunning) return; if (_dqSafetyTimer) { clearTimeout(_dqSafetyTimer); _dqSafetyTimer = null; } if (_autoExamIdx >= _autoExamQuestions.length) { log('全部 ' + _autoExamQuestions.length + ' 题已答完,提交中...', 'exam'); submitExamForm(); return; } var q = _autoExamQuestions[_autoExamIdx]; var num = _autoExamIdx + 1; var total = _autoExamQuestions.length; updateExamStatus('第' + num + '/' + total + '题: API调用中...'); updateExamProg(num - 1, total); showExamQ(q); var optTexts = []; var optLetters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']; for (var i = 0; i < q.options.length; i++) { optTexts.push(optLetters[i] + '. ' + q.options[i].text); } var prompt = '[' + q.type + '] ' + q.text + '\n\n' + optTexts.join('\n'); var answered = false; var doneOnce = function () { if (answered) return; answered = true; if (_dqSafetyTimer) { clearTimeout(_dqSafetyTimer); _dqSafetyTimer = null; } }; // 安全兜底:20秒后如果API还没回来,跳过此题 _dqSafetyTimer = setTimeout(function () { if (!_autoExamRunning) return; if (!answered) { log('第' + num + '题 API 超时(安全兜底),跳过', 'error'); doneOnce(); _autoExamIdx++; updateExamProg(_autoExamIdx, total); setTimeout(processNextExamQ, 1000); } }, 20000); callSiliconFlow(prompt, function (answer) { if (!_autoExamRunning) return; doneOnce(); var choices = parseAnswer(answer, q.options); if (choices && choices.length > 0) { fillExamQ(q, choices); log('第' + num + '题答案: ' + choices.join(','), 'exam'); } else { log('第' + num + '题解析失败: ' + answer + ',跳过', 'error'); } _autoExamIdx++; updateExamProg(_autoExamIdx, total); setTimeout(processNextExamQ, 2000); }); } function fillExamQ(q, choices) { for (var i = 0; i < q.options.length; i++) { var opt = q.options[i]; var checked = choices.indexOf(opt.value) >= 0; try { opt.input.checked = checked; } catch (e) { } var label = opt.input.closest('label'); if (label) { var strong = label.querySelector('strong'); if (strong) strong.className = checked ? 'on' : ''; } } } function submitExamForm() { var doc = getExamDoc(); if (!doc) { log('考核文档丢失', 'error'); return; } try { if (typeof window.finishTest === 'function') { window.finishTest(); log('finishTest() 提交', 'exam'); _autoExamRunning = false; updateExamStatus('已提交'); return; } } catch (e) { } try { if (doc.defaultView && doc.defaultView.finishTest) { doc.defaultView.finishTest(); log('iframe finishTest() 提交', 'exam'); _autoExamRunning = false; updateExamStatus('已提交'); return; } } catch (e) { } var form = doc.getElementById('testForm'); if (form) { var btn = form.querySelector('button[type="submit"]') || form.querySelector('.u-main-btn') || form.querySelector('input[type="submit"]') || form.querySelector('button'); if (btn) { btn.click(); log('点击提交按钮', 'exam'); } else { try { form.submit(); log('提交表单', 'exam'); } catch (e) { } } } _autoExamRunning = false; updateExamStatus('已提交'); } function showExamQ(q) { var qEl = document.getElementById('_asExamQ'); var optsEl = document.getElementById('_asExamOpts'); if (qEl) qEl.textContent = q.text.substring(0, 80); if (optsEl) { var html = ''; for (var i = 0; i < q.options.length; i++) { html += ''; } optsEl.innerHTML = html; } } function updateExamStatus(msg) { var el = document.getElementById('_asExamH2'); if (el) el.textContent = msg; } function updateExamProg(current, total) { var fill = document.getElementById('_asExamProgFill'); if (fill && total > 0) { fill.style.width = (current / total * 100) + '%'; } } function scanExamQuestion() { if (!_examMode || _paused || !_manualExam) return; var doc = getExamDoc(); if (!doc) return; var items = doc.querySelectorAll('.m-topic-item'); if (items.length === 0) items = doc.querySelectorAll('#topicList li'); if (items.length === 0) { updateExamStatus('等待题目加载...'); return; } var qs = parseAllExamQuestions(doc); if (qs.length === 0) return; var q = qs[0]; var h = q.text; if (h === _examHash) return; _examHash = h; _examSelected = []; _examMulti = q.multi; _examDoc = doc; showExamQ(q); try { if (navigator.clipboard && navigator.clipboard.writeText) navigator.clipboard.writeText(q.text).catch(function () { }); } catch (e) { } } function init() { if (window._asRun) return; window._asRun = true; window._asPaused = false; log('v12.0 启动 | ' + (CID || '?')); loadDB(); spoofVis(); makePanel(); if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', startAll); else startAll(); } function startAll() { log('启动定时器'); refreshProgUI(); setInterval(videoLoop, CFG.CHECK_MS); setInterval(function () { var x = 400 + Math.floor(Math.random() * 500); var y = 200 + Math.floor(Math.random() * 400); fakeMouse(x, y); var v = vid(); if (v) { var r = v.getBoundingClientRect(); if (r.width > 0) fakeMouse(r.left + Math.random() * r.width, r.top + Math.random() * r.height); } }, CFG.MOUSE_MS + Math.random() * 10000); setInterval(function () { var dy = Math.floor(Math.random() * 30) - 15; window.scrollBy(0, dy); setTimeout(function () { window.scrollBy(0, -dy); }, 3000); }, CFG.SCROLL_MS + Math.random() * 15000); setInterval(function () { var areas = [ function () { return { x: 100 + Math.random() * 200, y: 300 + Math.random() * 200 }; }, function () { return { x: 500 + Math.random() * 300, y: 600 + Math.random() * 100 }; }, function () { return { x: 800 + Math.random() * 200, y: 100 + Math.random() * 200 }; } ]; var pos = areas[Math.floor(Math.random() * areas.length)](); fakeClick(pos.x, pos.y); }, CFG.CLICK_MS + Math.random() * 20000); setInterval(refreshVideoUI, 3000); setInterval(checkQuiz, CFG.QUIZ_MS); setInterval(checkCompletePopup, 3000); setInterval(checkStudyProgress, CFG.CHECK_MS); setTimeout(function () { if (_examMode || _autoExamRunning) { log('考核模式活跃,跳过初始化导航', 'exam'); return; } var v = vid(); var si = studyInfo(); var aid = curAid(); var nm = curName() || ''; if (v && si && si.req >= 0 && si.wat >= 0) { var done = si.wat >= si.req; setStatus(aid, si.wat, si.req, done, nm); if (done && isKnownDone(aid)) { log('当前已标记完成: ' + nm + ' 切下一节(等60秒)', 'vid'); _promptDone = true; setTimeout(function () { _promptDone = false; nextVideo(); }, CFG.COMPLETE_WAIT); } else if (done) { log('当前已完成: ' + nm + ' 切下一节(等60秒)', 'vid'); _promptDone = true; setStatus(aid, si.wat, si.req, true, nm); setTimeout(function () { _promptDone = false; nextVideo(); }, CFG.COMPLETE_WAIT); } else { log('当前未完成: ' + nm + ' (' + si.wat + '/' + si.req + 'min) 开始播放', 'vid'); resume(); } } else if (!v && !si) { if (isExamPage() || _examMode) { log('考核页面,等待手动操作', 'exam'); return; } var firstAid = findFirstIncomplete(); if (firstAid && CID && typeof studyCourse === 'function') { log('课程列表页,自动开始: ' + (nameById(firstAid) || firstAid.substring(0, 12)), 'vid'); studyCourse(CID, '', firstAid); schedResume(); } else if (aid && CID && typeof studyCourse === 'function') { log('课程列表页,点击第一节', 'vid'); studyCourse(CID, '', aid); schedResume(); } else { log('未找到活动ID,等待手动操作', 'warn'); } } else { resume(); } }, CFG.INIT_MS); var origSC = window.studyCourse; if (origSC && typeof origSC === 'function') { window.studyCourse = function (cid, p2, aid) { log('切换: ' + aid, 'vid'); _switching = true; _endDone = false; _promptDone = false; if (_completeTimer) { clearTimeout(_completeTimer); _completeTimer = null; } if (_examMode && aid !== getExamAid()) exitExamMode(); if (aid === getExamAid()) enterExamMode(); var ret = origSC(cid, p2, aid); schedResume(); return ret; }; log('劫持 studyCourse()'); } setInterval(function () { if (_paused) return; var v = vid(); if (!v || !v.duration) return; var ci = curAid(), ids = allAids(), idx = ids.indexOf(ci); log(fmt(v.currentTime) + '/' + fmt(v.duration) + ' | ' + (idx + 1) + '/' + ids.length + '节', 'vid'); }, 60000); log('就绪'); } init(); function parseAnswer(text, options) { text = text.toUpperCase(); var letters = []; var re = /\\b([A-E])\\b/g; var m; while ((m = re.exec(text)) !== null) { letters.push(m[1]); } if (letters.length === 0) { if (text.indexOf('正确') >= 0 && text.indexOf('错误') < 0) letters.push('A'); if (text.indexOf('错误') >= 0 && text.indexOf('正确') < 0) letters.push('B'); } if (letters.length === 0) { var shortMatch = text.match(/^([A-E]{1,5})$/); if (shortMatch) letters = shortMatch[1].split(''); } var choices = []; var seen = {}; for (var i = 0; i < letters.length; i++) { var l = letters[i]; if (seen[l]) continue; seen[l] = true; var idx = l.charCodeAt(0) - 65; if (idx < options.length) { choices.push('Choice' + idx); } } return choices; } })();