// ==UserScript== // @name 🚀 学习通 DeepSeek模型ai自动答题与刷课助手终极版 // @namespace http://tampermonkey.net/ // @version 1.1.0 // @description 最新可用学习通自动答题、刷章节及章节测试,无需任何操作自动完成所有任务点。接入DeepSeek大模型,所有题目均可回答。 // @author Daniel // @match *://*.chaoxing.com/* // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_getResourceText // @resource typrMd5Lib https://116611.xyz/typr-md5.js // @resource fontTableData https://116611.xyz/table.json // @license CC-BY-NC-ND-4.0 // @antifeature payment 脚本存在第三方答题接口付费功能 // @icon data:image/png;base64,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dpokU6dMscY8tmn0io2t2VN57QObvE3qPZUsNcxMhnun1GYhbORFlzUjorxV5LmzYGqPud4pMgGKSnGGQBapVC8wpjM6Wl20yFi7atWqNx33prvvvvu/rr76Ix/5yO5Llz788MN5nl9//fVENG3atDzPH3jggYMOOmiPPfZYuXLlE088MWXKlHq9/sILL9x///2nnnrqb37zm5kzZw4NDW3evPnAAw/03j/44IMnnHBCtVrt7e0FcPnlly9YsGBwcPCuu+5697vfLSI33XRTq9WaPn26qj700EOLFi067LDD1q5de999902aNGnSpEk7duy45557Tj/9dGbOsizP856enqeffvqRRx6ZOXPms88+u3jJklPe+tatI6PPrRpac/P/2u0b+/75w/NqZECZoTQxgL48Xjw1mq/or3jR0q9qeywXqFVr2k3XaRRZPX0DxL0zGWLYeV+r1QBMnz79rLPOOv/88y+//HIiqtVqRHTLLbcsX758+fLl4eWdTufaa69NkuTJJ59817velWVZeP6hhx665ZZb5s6de8IJJwBoNBrB4oaGhm6++eYsy4ImfvnLX37hhRfmzJnzhS98AcDNN988bdq0Qw89tPvVrrrqqmnTpj300EMnn3zywMBAeHLVqlW3335btVpLkqTdbo+Ojj711FNnn322MebyK644+OCDG6LP1PoO3z9pzslm+3x+P556/oV1A9OSvkn9Pba/r5Ibf9360RX9lVICKNpFczyXtBKm8Wl8a+cf5PR3QgvOzoV7ziMQas+YMQNArVYLLnn58uWPPfbYggULrrzyyizLZs+e/T//8z+nnXZalmWf/OQnly1bNjY2dsABB6xfv957H7KwM84447jjjvPeT506dXBw8O677161apW1dsmSJccdd1yr1brssstWrVrVarUOPfTQ9evX77777l/+8pdVdZ999vnNb35z9NFHDwwMXHLJJQsWLFi9evXChQsbjebo6CgRee/vuuuuQw45xBjzzW9+c+7cuYcddtiT28bGGJ/eNf3x3tO+vKTvsOZLH+jbcdLmpye9uHL4mTXtF9bORPH4jk6j4wzH3XLjQ03xpMwWxiA1rdG8PdKu9ld1oi/gDYQlIpVKxTmnqmmaDQ+PBD9dFMXLL7/8oQ99SFVfeeWV/fbbL0kSERkdHWt3Oj09Pe122zm37777NpvNnp6eVqsVvPXKlSv32WefYI+Dg4PMfNRRR731rW/96le/esopp0yaNOmwww5bsGDBJZdc8t73vldV161bt8cee0yZMiV48aFt22bPnq2qw8PDBx54YKPREJE8L4IjY+bPfvazu+222/3333/vvffefPPN3vsDB2oH9TpDhGTycKt92T0PpiLfOPOdL7z08v1PPTujGGg6vrLTM5L7emaJqTPWbo16SRMFWyXybK2VsQ3NtJ6wtW+Y/xJRURTBy46PjyeJJUJzfLRWq6nqpk2bRsfGBwcHiej0008//fTTw7u2bduaJlZVrbX/+Z//2b3a9u3bK5VKML2TTjrJORcOY8OGDeecc87UqVMvuuiib3zjG1/84hfPOuusmTNn7hgdzbKMiA455JDrrrsuXGR0dIcvCqiKyNe//vXuxcdGtg30zw/6fuCBB4rIvffee/7552dZ5pyz1sJaAVR0oF777gfPvva+B9aNN/c7YL/eKVMeeOjRfikGvZuUWQ+4wo1uGAcZz0aYWAjKrIktchpdN1buUH3dI6wyKPI8rD1vNZvbR0afWLv15nv+umjhbkT00GNPvNiqBart29/+9qJFi5csXbrH8uVf+tJX6wODqjo8PHLAAQcsXrx46dKly5cvX7NmzdSpUwG0Wi1mHhoa6uvrI6Jnn3/+t7/97cKFC2+99dYLL7zwySefDEIcGd4eMME111wTL75s2Xvec5ZWJ4Ws860nn7xo8eKlS5ctX7788hvuqQzMAPDUypVf/NKXmPncc8/dsWNHOPKY/qsyoZ3nGfScNx212/RBUQxOG5xUrz+zrXXijJ6e1Bh4s2m405ERtsawJ1hhJUZBRJltjXTM2h298/p3lpeWv2VivN1xEqJybdr0mXffffdh++29YLeFcPnPf/u/Y1OWb1y7au7uex588CEPPfLYlCmT99tjyX/+dejRV4aZua+v78QTT3z++ecXLVpU7+np6emx1gLo7e298847jzjiiEql8vhjj7741GNvPemktWvXPvHEE3Pnzj399NOJaOOG9bf+9bkPbdqyZMmSPfbYY8W++6VpesCK5f/7wvjTw55IjTHHH3+8senC3RbMGJzyvSeso8Q5l+f5NVf91/vPOWfBgt2SJHn88cf33mefwvmQRRmmRie/5HfXvf/NJ8zfZSZ8sWbV88q6+8wpb148/ZVRfWF9vnJ95cmi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 // ==/UserScript== const systemConfig = { buildTime: new Date().toISOString(), environment: 'production' }; class Logger { constructor(prefix) { this.prefix = prefix || 'System'; this.levels = ['DEBUG', 'INFO', 'WARN', 'ERROR']; } log(level, message) { if (this.levels.includes(level)) { const timestamp = new Date().toISOString(); } } debug(msg) { this.log('DEBUG', msg); } info(msg) { this.log('INFO', msg); } warn(msg) { this.log('WARN', msg); } error(msg) { this.log('ERROR', msg); } } const logger = new Logger('CXHelper'); const browserCheck = { isChrome: () => /Chrome/.test(navigator.userAgent), isFirefox: () => /Firefox/.test(navigator.userAgent), isEdge: () => /Edge/.test(navigator.userAgent), isSafari: () => /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) }; class PerformanceMonitor { constructor() { this.metrics = new Map(); this.startTimes = new Map(); } start(name) { this.startTimes.set(name, performance.now()); } end(name) { const startTime = this.startTimes.get(name); if (startTime) { const duration = performance.now() - startTime; this.metrics.set(name, duration); this.startTimes.delete(name); return duration; } return 0; } getMetric(name) { return this.metrics.get(name) || 0; } } const perfMonitor = new PerformanceMonitor(); const utils = { generateId: (length = 8) => { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; for (let i = 0; i < length; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)); } return result; }, deepClone: (obj) => { if (obj === null || typeof obj !== 'object') return obj; if (obj instanceof Date) return new Date(obj.getTime()); if (obj instanceof Array) return obj.map(item => utils.deepClone(item)); if (typeof obj === 'object') { const cloned = {}; Object.keys(obj).forEach(key => { cloned[key] = utils.deepClone(obj[key]); }); return cloned; } }, debounce: (func, wait) => { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; }, throttle: (func, limit) => { let inThrottle; return function() { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } } } }; class CacheManager { constructor(maxSize = 100) { this.cache = new Map(); this.maxSize = maxSize; } set(key, value, ttl = 300000) { // 默认5分钟过期 if (this.cache.size >= this.maxSize) { const firstKey = this.cache.keys().next().value; this.cache.delete(firstKey); } const item = { value: value, expiry: Date.now() + ttl }; this.cache.set(key, item); } get(key) { const item = this.cache.get(key); if (!item) return null; if (Date.now() > item.expiry) { this.cache.delete(key); return null; } return item.value; } clear() { this.cache.clear(); } } const cacheManager = new CacheManager(); logger.info('System initialization completed'); (function() { 'use strict'; (function(){ function _b64ToBytes(b64){ const bin = atob(b64); const out = new Uint8Array(bin.length); for(let i=0;ic-1); const __SALT = String.fromCharCode.apply(null, __S); const __ENC = "idiM9YBNCEBSu80fAcWJtglB3UgCOQSNSUCG2EFbmlWW7AyIJkSb/kgNWgCHsoEA"; function __getDSK(){ try { const step1 = __ENC.split('').reverse().join(''); const xored = _b64ToBytes(step1); const plainB64Bytes = _xor(xored, _strToBytes(__SALT)); const plainB64 = _bytesToStr(plainB64Bytes); return atob(plainB64); } catch (e) { return ''; } } window.__getDeepseekKey = __getDSK; })(); const DEEPSEEK_API_KEY = (typeof window!=='undefined' && window.__getDeepseekKey) ? window.__getDeepseekKey() : ''; const DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions'; let isAnswering = false; let isStudyingChapters = false; let studyIntervalId = null; const STUDY_PERSIST_KEY = 'cx_helper_study_on_v2'; const PANEL_REG_KEY = 'cx_helper_active_panel_v2'; const PANEL_INSTANCE_ID = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`; const FRAME_DEPTH = (() => { let d = 0; try { let w = window; while (w !== w.top) { d++; w = w.parent; } } catch { d = 999; } return d; })(); let isActiveOwner = false; let createdPanelEl = null; const HEARTBEAT_INTERVAL_MS = 2000; const STALE_MS = 7000; let heartbeatTimerId = null; let lastAutoSkipTs = 0; let emptyChecksCount = 0; let lastEmptySectionKey = ''; let recoveryTimerId = null; const API_BASE = 'https://116611.xyz'; const MONEY_YUAN = '5.00'; const PAY_NAME = 'CXHelper 解锁/赞助'; const DEFAULT_PAY = 'wxpay'; const LS_KEY_DEV_ID = 'cxhelper_device_id'; const LS_KEY_FREE = 'cxhelper_free_used'; const LS_KEY_LICENSED = 'cxhelper_licensed'; const POLL_MS_PAY = 3000; const POLL_MAX_PAY = 100; const getFreeLimit = (() => { let cached = null; return function() { if (cached != null) return cached; try { const b64 = 'JDEw'; const decoded = atob(b64); const n = parseInt(decoded.replace(/\D/g, ''), 10); cached = Number.isFinite(n) ? n : 10; } catch { cached = 10; } return cached; }; })(); function getDeviceIdPaid() { try { let id = localStorage.getItem(LS_KEY_DEV_ID); if (!id) { id = ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)); localStorage.setItem(LS_KEY_DEV_ID, id); } return id; } catch { return 'dev_' + Math.random().toString(36).slice(2); } } const DEVICE_ID_PAID = getDeviceIdPaid(); function isLocallyLicensed() { try { return localStorage.getItem(LS_KEY_LICENSED) === '1'; } catch { return false; } } function setLocallyLicensed() { try { localStorage.setItem(LS_KEY_LICENSED, '1'); } catch {} } function getFreeUsedCount() { try { return parseInt(localStorage.getItem(LS_KEY_FREE) || '0', 10) || 0; } catch { return 0; } } function incFreeUsedCount() { try { const n = getFreeUsedCount() + 1; localStorage.setItem(LS_KEY_FREE, String(n)); return n; } catch { return 0; } } async function checkLicensePaid() { if (isLocallyLicensed()) return true; try { const r = await fetch(`${API_BASE}/api/license/status?deviceId=${encodeURIComponent(DEVICE_ID_PAID)}`, { credentials: 'omit' }); const ct = (r.headers.get('content-type') || '').toLowerCase(); const data = ct.includes('application/json') ? await r.json() : await r.text(); const ok = !!(data && data.licensed); if (ok) setLocallyLicensed(); try { updateTrialBadge(); } catch {} return ok; } catch { return false; } } async function startPaymentPaid(payType) { const win = window.open('', '_blank'); try { const resp = await fetch(`${API_BASE}/api/create`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: PAY_NAME, money: MONEY_YUAN, type: payType || DEFAULT_PAY, param: DEVICE_ID_PAID }) }); const html = await resp.text(); win.document.open(); win.document.write(html); win.document.close(); return true; } catch (e) { if (win) win.close(); alert('发起支付失败:' + e.message); return false; } } async function pollUntilLicensedPaid(onProgress) { for (let i = 0; i < POLL_MAX_PAY; i++) { if (onProgress) { try { onProgress(i); } catch {} } const ok = await checkLicensePaid(); if (ok) { setLocallyLicensed(); return true; } await new Promise(r => setTimeout(r, POLL_MS_PAY)); } return false; } function showPayModalPaid(messageText) { return new Promise(resolve => { const mask = document.createElement('div'); mask.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:999998;'; const box = document.createElement('div'); box.style.cssText = 'position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);width:420px;background:#fff;border-radius:12px;box-shadow:0 12px 40px rgba(0,0,0,.2);overflow:hidden;z-index:999999;font-family:system-ui,Segoe UI,Arial;'; const msg = messageText || '试用已用完,打赏5元永久解锁哦'; box.innerHTML = ( '
解锁全部功能(永久)
' + '
' + '
' + msg + '
' + '
' + '' + '' + '
若支付方式不可用请尝试其他支付方式
' + '
' + '
点击"去支付"将打开收银台,完成后此处会自动检测。
' + '
' + '
' + '' + '' + '
' ); document.body.appendChild(mask); document.body.appendChild(box); const tip = box.querySelector('#cx_tip_paid'); const btnPay = box.querySelector('#cx_go_pay'); const btnCancel = box.querySelector('#cx_cancel_paid'); function close() { try { box.remove(); mask.remove(); } catch {} } btnCancel.onclick = () => { close(); resolve(false); }; btnPay.onclick = async () => { btnPay.disabled = true; btnPay.textContent = '打开收银台...'; const payType = (box.querySelector('input[name="cx_pay"]:checked') || {}).value || DEFAULT_PAY; const ok = await startPaymentPaid(payType); if (!ok) { btnPay.disabled = false; btnPay.textContent = '去支付'; return; } btnPay.textContent = '检测支付中...'; if (tip) tip.textContent = '已打开收银台,请完成支付,完成后此处会自动解锁...'; const done = await pollUntilLicensedPaid(); if (done) { if (tip) tip.textContent = '支付成功,正在解锁...'; setLocallyLicensed(); try { updateTrialBadge(); } catch {} setTimeout(() => { close(); resolve(true); }, 500); } else { btnPay.disabled = false; btnPay.textContent = '去支付'; if (tip) tip.textContent = '未检测到支付完成,可重试或稍后再次打开本面板。'; } }; }); } async function ensureAccessAllowed() { if (await checkLicensePaid()) return true; const used = getFreeUsedCount(); if (used < getFreeLimit()) { incFreeUsedCount(); try { updateTrialBadge(); } catch {} return true; } const ok = await showPayModalPaid(); if (ok) { setLocallyLicensed(); try { updateTrialBadge(); } catch {} return true; } throw new Error('试用已用完,请解锁后继续使用'); } function getActivePanelRecord() { try { const raw = localStorage.getItem(PANEL_REG_KEY); return raw ? JSON.parse(raw) : null; } catch { return null; } } function setActivePanelRecord(rec) { try { localStorage.setItem(PANEL_REG_KEY, JSON.stringify(rec)); } catch {} } function clearActivePanelRecordIfOwner() { try { const cur = getActivePanelRecord(); if (cur && cur.id === PANEL_INSTANCE_ID) { localStorage.removeItem(PANEL_REG_KEY); } } catch {} } function shouldWeOwn(current) { const nowTs = Date.now(); if (!current) return { own: true, ts: nowTs }; if (!current.aliveTs || nowTs - current.aliveTs > STALE_MS) return { own: true, ts: nowTs }; try { if (current.url && current.url !== location.href) return { own: true, ts: nowTs }; } catch {} if (FRAME_DEPTH > (current.depth || 0)) return { own: true, ts: nowTs }; if (FRAME_DEPTH === (current.depth || 0) && nowTs > (current.ts || 0)) return { own: true, ts: nowTs }; return { own: false, ts: nowTs }; } function claimOwnership() { const cur = getActivePanelRecord(); const decision = shouldWeOwn(cur); if (decision.own) { setActivePanelRecord({ id: PANEL_INSTANCE_ID, depth: FRAME_DEPTH, ts: decision.ts, aliveTs: Date.now(), url: location.href }); isActiveOwner = true; } else { isActiveOwner = false; } return isActiveOwner; } function startHeartbeat() { if (heartbeatTimerId) return; heartbeatTimerId = setInterval(() => { if (!isActiveOwner) return; const cur = getActivePanelRecord(); if (!cur || cur.id !== PANEL_INSTANCE_ID) { stopHeartbeat(); return; } cur.aliveTs = Date.now(); try { cur.url = location.href; } catch {} setActivePanelRecord(cur); }, HEARTBEAT_INTERVAL_MS); } function stopHeartbeat() { if (heartbeatTimerId) { clearInterval(heartbeatTimerId); heartbeatTimerId = null; } } const cleanupOwnership = () => { stopHeartbeat(); clearActivePanelRecordIfOwner(); }; window.addEventListener('beforeunload', cleanupOwnership); window.addEventListener('pagehide', cleanupOwnership); function destroyPanelAndStop() { try { if (studyIntervalId) { clearInterval(studyIntervalId); studyIntervalId = null; } isStudyingChapters = false; isAnswering = false; stopHeartbeat(); const panel = document.getElementById('answer-helper-panel'); if (panel && panel.parentNode) panel.parentNode.removeChild(panel); createdPanelEl = null; } catch {} } window.addEventListener('storage', (e) => { if (e.key !== PANEL_REG_KEY) return; const rec = getActivePanelRecord(); if (!rec) return; if (rec.id === PANEL_INSTANCE_ID) { if (!createdPanelEl) { try { createdPanelEl = createPanel(); bindPanelEvents(); } catch {} } isActiveOwner = true; startHeartbeat(); } else { isActiveOwner = false; destroyPanelAndStop(); } }); GM_addStyle(` #answer-helper-panel { position: fixed; top: 20px; left: 20px; width: 320px; background: #ffffff; border-radius: 12px; padding: 0; z-index: 9999; box-shadow: 0 4px 24px rgba(0, 0, 0, 0.1); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; user-select: none; } #answer-helper-header { cursor: move; background: #f5f7fa; border-radius: 12px 12px 0 0; padding: 0 15px; height: 44px; display: flex; align-items: center; justify-content: space-between; font-size: 16px; font-weight: 600; color: #333; } #answer-helper-header .status-badge { margin-left: 8px; } #answer-helper-header .collapse-btn { width: 32px; height: 32px; border-radius: 8px; background: #e0e0e0; border: none; font-size: 22px; cursor: pointer; color: #666; margin-left: 10px; display: flex; align-items: center; justify-content: center; box-shadow: 0 1px 2px rgba(0,0,0,0.04); transition: background 0.2s, color 0.2s; } #answer-helper-header .collapse-btn:hover { background: #1677ff; color: #fff; } .collapse-icon-bar { display: block; background: currentColor; border-radius: 2px; margin: 0 auto; } .collapse-icon-bar.horizontal { width: 16px; height: 3px; } .collapse-icon-bar.vertical { width: 3px; height: 16px; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } .collapse-btn-inner { position: relative; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; } #answer-helper-content { padding: 15px; } #answer-helper-panel.collapsed #answer-helper-content { display: none; } #answer-helper-panel.collapsed { width: 180px; min-width: 120px; } #no-task-toast { position: fixed; top: 20px; right: 20px; background: rgba(0, 0, 0, 0.8); color: white; padding: 12px 24px; border-radius: 8px; font-size: 14px; z-index: 10000; animation: fadeInOut 3s ease-in-out forwards; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; } @keyframes fadeInOut { 0% { opacity: 0; transform: translateY(-20px); } 10% { opacity: 1; transform: translateY(0); } 90% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; transform: translateY(-20px); } } #answer-helper-panel h3 { margin: 0 0 15px 0; color: #333; font-size: 16px; font-weight: 600; display: flex; align-items: center; justify-content: space-between; } #answer-log { height: 240px; overflow-y: auto; border: 1px solid #eef0f5; border-radius: 8px; padding: 12px; margin: 10px 0; font-size: 13px; background: #f8f9fa; } #answer-log::-webkit-scrollbar { width: 6px; } #answer-log::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 3px; } #answer-log::-webkit-scrollbar-thumb { background: #c1c1c1; border-radius: 3px; } .log-item { margin-bottom: 8px; padding: 8px; border-radius: 6px; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); } .success { color: #00a854; border-left: 3px solid #00a854; } .error { color: #f5222d; border-left: 3px solid #f5222d; } .debug { color: #1890ff; border-left: 3px solid #1890ff; } .info { color: #666; border-left: 3px solid #666; } .button-group { display: flex; gap: 8px; } .helper-button { flex: 1; padding: 8px 12px; border: none; border-radius: 6px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; gap: 6px; } .primary-button { background: #1890ff; color: white; } .primary-button:hover { background: #40a9ff; } .danger-button { background: #ff4d4f; color: white; } .danger-button:hover { background: #ff7875; } .secondary-button { background: #f0f0f0; color: #666; } .secondary-button:hover { background: #d9d9d9; } .success-button { background: #00a854; color: #fff; } .success-button:hover { background: #36c06a; } .status-badge { padding: 4px 8px; border-radius: 4px; font-size: 12px; font-weight: normal; } .status-running { background: #e6f7ff; color: #1890ff; } .status-stopped { background: #fff1f0; color: #ff4d4f; } .button-icon { font-size: 14px; line-height: 1; } #debug-page{ display:none !important; } #answer-helper-panel .cx-trial-badge{ position: absolute; left: 12px; bottom: 8px; color: #888; font-size: 12px; pointer-events: none; } #answer-helper-content { padding-bottom: 30px; } `); function createPanel() { const panel = document.createElement('div'); panel.id = 'answer-helper-panel'; panel.innerHTML = `
学习通AI自动答题与刷课助手
检测中...
`; document.body.appendChild(panel); let isDragging = false, offsetX = 0, offsetY = 0; const header = panel.querySelector('#answer-helper-header'); header.addEventListener('mousedown', function(e) { if (e.target.classList.contains('collapse-btn')) return; isDragging = true; const rect = panel.getBoundingClientRect(); offsetX = e.clientX - rect.left; offsetY = e.clientY - rect.top; document.body.style.userSelect = 'none'; }); document.addEventListener('mousemove', function(e) { if (!isDragging) return; panel.style.left = (e.clientX - offsetX) + 'px'; panel.style.top = (e.clientY - offsetY) + 'px'; panel.style.right = 'auto'; }); document.addEventListener('mouseup', function() { isDragging = false; document.body.style.userSelect = ''; }); const collapseBtn = panel.querySelector('.collapse-btn'); const collapseBtnInner = collapseBtn.querySelector('.collapse-btn-inner'); collapseBtn.addEventListener('click', function() { panel.classList.toggle('collapsed'); collapseBtnInner.innerHTML = ''; if (panel.classList.contains('collapsed')) { const h = document.createElement('span'); h.className = 'collapse-icon-bar horizontal'; const v = document.createElement('span'); v.className = 'collapse-icon-bar vertical'; collapseBtnInner.appendChild(h); collapseBtnInner.appendChild(v); } else { const h = document.createElement('span'); h.className = 'collapse-icon-bar horizontal'; collapseBtnInner.appendChild(h); } }); return panel; } function bindPanelEvents() { document.getElementById('start-answer')?.addEventListener('click', () => { addLog('本助手仅供学习研究,请遵守课程与平台规则。', 'info'); addLog('开始自动答题...'); autoAnswer(); }); document.getElementById('pause-answer')?.addEventListener('click', () => { isAnswering = false; addLog('正在暂停自动答题...', 'info'); }); const startStudyBtn = document.getElementById('start-study'); const pauseStudyBtn = document.getElementById('pause-study'); if (startStudyBtn && pauseStudyBtn) { startStudyBtn.addEventListener('click', () => { addLog('本助手仅供学习研究,请遵守课程与平台规则。', 'info'); startStudyChapters(); }); pauseStudyBtn.addEventListener('click', () => { stopStudyChapters(); }); } const buyBtn = document.getElementById('buy-license'); if (buyBtn) { buyBtn.addEventListener('click', async () => { try { await showPayModalPaid('免费试用,打赏5元永久解锁哦'); } catch (e) { addLog('打开支付弹窗失败: ' + (e && e.message ? e.message : e), 'error'); } }); } document.getElementById('debug-page')?.addEventListener('click', () => { debugPageStructure(); }); setTimeout(updateTrialBadge, 0); } function safeClick(el) { try { if (!el) return false; el.click(); el.dispatchEvent(new MouseEvent('click', { bubbles: true })); return true; } catch { return false; } } function forEachSameOriginFrame(callback) { const visit = (win) => { for (let i = 0; i < win.frames.length; i++) { const f = win.frames[i]; try { const doc = f.document || f.contentDocument; if (doc && doc.location && doc.location.href.includes('.chaoxing.com')) { callback(doc); visit(f); } } catch { } } }; try { callback(document); } catch {} try { visit(window); } catch {} } function forEachAllSameOriginDocs(callback) { const seen = new Set(); const visit = (win) => { if (!win || seen.has(win)) return; seen.add(win); try { const doc = win.document || win.contentDocument; if (doc) callback(doc); } catch {} try { const len = win.frames ? win.frames.length : 0; for (let i = 0; i < len; i++) { try { visit(win.frames[i]); } catch {} } } catch {} }; try { visit(window.top); } catch { visit(window); } } async function waitForQuestionsRenderAny(timeoutMs = 8000) { const end = Date.now() + timeoutMs; const selector = '.question, .questionLi, .subject_item, .examPaper_subject, .questionContainer, .q-item, .subject_node, [class*="question"], .ti-item, .exam-item'; while (Date.now() < end) { let hit = null; forEachAllSameOriginDocs((doc) => { if (hit) return; try { const qs = doc.querySelectorAll(selector); if (qs && qs.length > 0) hit = doc; } catch {} }); if (hit) return hit; await new Promise(r => setTimeout(r, 300)); } return null; } function gotoNextSection(contextDoc) { const docsToTry = []; if (contextDoc) docsToTry.push(contextDoc); try { if (window.top && window.top.document) docsToTry.push(window.top.document); } catch {} docsToTry.push(document); const textNextRegex = /下一(节|章|单元|页|个)|继续|下一步|下一个|Next/i; const nextBtnSelectors = [ '.next', '.vc-next', '.reader-next', 'a[title="下一页"]', '.btn-next', '#next', '.prev_next .right a', '.switch-btn.next', '.icon-arrow-right', '.right-btn .next' ]; const currentNodeSelectors = ['.cur', '.curr', 'li.active', 'li.selected', '.posCatalog_active']; try { if (isStudyingChapters) localStorage.setItem(STUDY_PERSIST_KEY, '1'); } catch {} for (const doc of docsToTry) { try { for (const sel of nextBtnSelectors) { const btn = doc.querySelector(sel); if (btn && !btn.getAttribute('disabled') && !String(btn.className).includes('disabled')) { if (safeClick(btn)) { addLog('检测到下一节按钮,已点击', 'success'); return true; } } } for (const curSel of currentNodeSelectors) { const cur = doc.querySelector(curSel); if (cur && cur.nextElementSibling) { const link = cur.nextElementSibling.querySelector('a'); if (link && safeClick(link)) { addLog('目录定位到下一小节', 'success'); return true; } } } const links = Array.from(doc.querySelectorAll('a[href*="knowledgeId"], a[href*="chapterId"], a[href*="studentstudy"]')); if (links.length > 1) { const hrefNow = (location && location.href) || ''; const idx = links.findIndex(a => (a.href || '').includes('knowledgeId') && hrefNow.includes('knowledgeId') && a.href.split('knowledgeId')[1] === hrefNow.split('knowledgeId')[1]); const next = idx >= 0 ? links[idx + 1] : null; if (next && safeClick(next)) { addLog('通过目录链接顺序跳转下一小节', 'success'); return true; } } const clickable = Array.from(doc.querySelectorAll('a, button, .btn, .el-button, .next')); for (const el of clickable) { const txt = (el.textContent || '').trim(); if (textNextRegex.test(txt)) { const excludeClasses = ['close', 'cancel', 'delete', 'remove', 'back', 'prev', 'disabled', 'popup', 'modal']; const hasExcludeClass = excludeClasses.some(cls => el.className.toLowerCase().includes(cls) || el.id.toLowerCase().includes(cls) ); const isVisible = el.offsetWidth > 0 && el.offsetHeight > 0 && window.getComputedStyle(el).display !== 'none' && window.getComputedStyle(el).visibility !== 'hidden'; const isValidNavigationElement = ( (el.tagName === 'A' && (el.href || el.onclick)) || (el.tagName === 'BUTTON' && el.onclick) || el.className.includes('btn') || el.className.includes('next') ) && !el.closest('.popup, .modal, .dialog, .alert'); const isNavigationText = /^(下一节|下一章|下一个|下一页|继续|Next)$/i.test(txt); if (!hasExcludeClass && isVisible && isValidNavigationElement && isNavigationText) { if (safeClick(el)) { addLog(`通过文本匹配跳转: ${txt}`, 'success'); return true; } } else { addLog(`跳过不合适的文本匹配元素: ${txt} (类名: ${el.className})`, 'debug'); } } } } catch {} } addLog('未能自动跳转到下一小节', 'error'); return false; } function handleVideosInDocument(doc) { try { const videos = doc.querySelectorAll('video, .video-js video'); if (videos.length === 0) return false; let any = false; videos.forEach(v => { try { v.muted = true; if (!Number.isNaN(v.playbackRate)) v.playbackRate = 1.0; const p = v.play(); if (p && typeof p.catch === 'function') p.catch(() => {}); v.loop = false; if (!v.dataset.autonextBind) { v.dataset.autonextBind = '1'; v.addEventListener('ended', () => { if (v.dataset.disableAutoNext === '1' || !isStudyingChapters) return; addLog('视频播放结束,进行完成度检测', 'success'); setTimeout(() => ensureSectionCompletedAndAdvance(doc), 300); }, { passive: true }); let nearingFired = false; const onTimeUpdate = () => { if (v.dataset.disableAutoNext === '1' || !isStudyingChapters) return; try { const d = v.duration || 0; const t = v.currentTime || 0; if (d > 0 && (d - t) <= 1.0 && !nearingFired) { nearingFired = true; addLog('检测到视频即将结束,进行完成度检测', 'debug'); setTimeout(() => ensureSectionCompletedAndAdvance(doc), 800); } } catch {} }; v.addEventListener('timeupdate', onTimeUpdate, { passive: true }); } any = true; } catch {} }); const popBtns = doc.querySelectorAll('.ans-job-icon, .popBtn, .dialog-footer .btn, .ans-modal .btn, .vjs-big-play-button'); popBtns.forEach(b => safeClick(b)); return any; } catch { return false; } } function handlePPTInDocument(doc) { try { const nextSelectors = ['.next', '.vc-next', '.reader-next', 'a[title="下一页"]', '.btn-next', '#next']; for (const sel of nextSelectors) { const btn = doc.querySelector(sel); if (btn && !btn.className.includes('disabled') && !btn.getAttribute('disabled')) { if (safeClick(btn)) { addLog('PPT自动下一页', 'debug'); return true; } } } const container = doc.scrollingElement || doc.body; if (container) container.scrollTop = container.scrollHeight; return false; } catch { return false; } } function findChapterQuizTab(doc) { try { const byTitle = doc.querySelector('li[title*="章节测验"], li[title*="测验"], a[title*="章节测验"], a[title*="测验"]'); if (byTitle) return byTitle; const byOnClick = Array.from(doc.querySelectorAll('li[onclick], a[onclick], button[onclick]')).find(el => { const oc = (el.getAttribute('onclick') || '').toString(); return oc.includes('changeDisplayContent') && (oc.includes('(2,2') || oc.includes(',2)')); }); if (byOnClick) return byOnClick; const candidates = Array.from(doc.querySelectorAll('li, a, button, [role="tab"], [role="option"]')); const textEl = candidates.find(el => /章节测验|测验/.test(((el.textContent || el.getAttribute('title') || '') + '').trim())); if (textEl) return textEl; } catch {} return null; } async function waitForQuestionsRender(doc, timeoutMs = 6000) { const end = Date.now() + timeoutMs; while (Date.now() < end) { try { const qs = doc.querySelectorAll('.question, .questionLi, .subject_item, .examPaper_subject, .questionContainer, .q-item, .subject_node, [class*="question"], .ti-item, .exam-item'); if (qs.length > 0) return true; } catch {} await new Promise(r => setTimeout(r, 300)); } return false; } let TYPR_MD5_LIB, FONT_TABLE_DATA; try { TYPR_MD5_LIB = GM_getResourceText('typrMd5Lib'); FONT_TABLE_DATA = GM_getResourceText('fontTableData'); if (TYPR_MD5_LIB) { window.TYPR_MD5_LIB = TYPR_MD5_LIB; } if (FONT_TABLE_DATA) { window.FONT_TABLE_DATA = FONT_TABLE_DATA; } } catch (e) { console.error('加载外部资源失败:', e); TYPR_MD5_LIB = ''; FONT_TABLE_DATA = '{}'; } function injectConsoleDecryptCode(doc, timeoutMs = 3000) { return new Promise((resolve) => { try { const consoleCode = ` if (!window.Typr || !window.md5) { ${TYPR_MD5_LIB || window.TYPR_MD5_LIB || ''} } if (!window.chaoXingFontTable) { window.chaoXingFontTable = ${FONT_TABLE_DATA || window.FONT_TABLE_DATA || '{}'}; } const decryptChaoXingFont = async () => { const { Typr, md5, chaoXingFontTable: table } = window; const base64ToUint8Array = (base64) => { const data = atob(base64); const buffer = new Uint8Array(data.length); for (let i = 0; i < data.length; i++) { buffer[i] = data.charCodeAt(i); } return buffer; }; const styleElements = [...document.querySelectorAll('style')]; const cxStyle = styleElements.find(el => el.textContent.includes('font-cxsecret') ); if (!cxStyle) { return; } const fontData = cxStyle.textContent.match(/base64,([\\w\\W]+?)'/)[1]; const parsedFont = Typr.parse(base64ToUint8Array(fontData))[0]; const charMap = {}; for (let charCode = 19968; charCode < 40870; charCode++) { const glyph = Typr.U.codeToGlyph(parsedFont, charCode); if (!glyph) continue; const path = Typr.U.glyphToPath(parsedFont, glyph); const pathHash = md5(JSON.stringify(path)).slice(24); charMap[String.fromCharCode(charCode)] = String.fromCharCode(table[pathHash]); } document.querySelectorAll('.font-cxsecret').forEach(element => { let htmlContent = element.innerHTML; Object.entries(charMap).forEach(([encryptedChar, decryptedChar]) => { const regex = new RegExp(encryptedChar, 'g'); htmlContent = htmlContent.replace(regex, decryptedChar); }); element.innerHTML = htmlContent; element.classList.remove('font-cxsecret'); }); }; decryptChaoXingFont().catch(console.error); `; const beforeCnt = (() => { try { return doc.querySelectorAll('.font-cxsecret').length; } catch { return -1; } })(); let script = doc.createElement('script'); script.type = 'text/javascript'; let blobUrl = ''; try { const blob = new Blob([consoleCode], { type: 'text/javascript' }); blobUrl = (doc.defaultView || window).URL.createObjectURL(blob); script.src = blobUrl; } catch { script.textContent = consoleCode; } (doc.head || doc.documentElement).appendChild(script); script.onload = () => { try { if (blobUrl) (doc.defaultView || window).URL.revokeObjectURL(blobUrl); } catch {} }; const start = Date.now(); const timer = setInterval(() => { try { const cnt = doc.querySelectorAll('.font-cxsecret').length; if (cnt === 0 || (beforeCnt >= 0 && cnt < beforeCnt)) { clearInterval(timer); resolve(); return; } } catch {} if (Date.now() - start > timeoutMs) { clearInterval(timer); resolve(); } }, 200); } catch { resolve(); } }); } async function tryEnterQuizAndAnswer(contextDoc) { try { if (!isStudyingChapters) return false; let targetDoc = null; let tabEl = null; forEachAllSameOriginDocs((doc) => { if (tabEl) return; const el = findChapterQuizTab(doc); if (el) { tabEl = el; targetDoc = doc; } }); if (!tabEl || !targetDoc) return false; addLog('检测到章节测验入口,正在进入...', 'info'); await new Promise((r) => { let pending = 0; let done = false; forEachAllSameOriginDocs((doc) => { pending++; injectConsoleDecryptCode(doc).finally(() => { if (--pending === 0 && !done) { done = true; r(); } }); }); if (pending === 0) r(); }); try { tabEl.scrollIntoView({ block: 'center', behavior: 'smooth' }); } catch {} const clicked = safeClick(tabEl); const oc = (tabEl.getAttribute('onclick') || '').toString(); const m = oc.match(/changeDisplayContent\(([^)]*)\)/); if (!clicked && m && m[1]) { try { const ownerWin = (tabEl.ownerDocument && tabEl.ownerDocument.defaultView) || null; const topWin = (function(){ try { return window.top; } catch { return window; } })(); const evalWin = ownerWin || topWin || window; const args = evalWin.eval('[' + m[1] + ']'); const fn = (ownerWin && ownerWin.changeDisplayContent) || (topWin && topWin.changeDisplayContent) || window.changeDisplayContent; if (typeof fn === 'function') { fn.apply(ownerWin || topWin || window, args); } else { addLog('未找到changeDisplayContent函数可调用', 'error'); } } catch (e) { addLog('直接调用changeDisplayContent失败: ' + e.message, 'error'); } } const qDoc = await waitForQuestionsRenderAny(10000); if (!isStudyingChapters) return false; if (!qDoc) { addLog('进入章节测验后未检测到题目,自动跳转下一节', 'info'); try { gotoNextSection(targetDoc || document); } catch {} return true; } await injectConsoleDecryptCode(qDoc); if (!isStudyingChapters) return false; await autoAnswerInDocument(qDoc); addLog('章节测验已自动作答', 'success'); return true; } catch (e) { addLog(`进入章节测验失败: ${e.message}`, 'error'); return false; } } function hasActionableStudyContent(doc) { try { if (doc.querySelector('video, .video-js video')) return true; const docSelectors = [ '.ans-attach-ct', '.reader', '.ppt', '.ppt-play', '.vjs-control', '.vjs-big-play-button', '.catalog', '.course_section', '.posCatalog', '.posCatalog_active', '.catalogTree' ]; if (docSelectors.some(sel => !!doc.querySelector(sel))) return true; const nextSelectors = ['.next', '.vc-next', '.reader-next', 'a[title="下一页"]', '.btn-next', '#next']; if (nextSelectors.some(sel => !!doc.querySelector(sel))) return true; if (doc.querySelector('.question, .questionLi, .subject_item, .examPaper_subject, .questionContainer, .q-item, .subject_node, [class*="question"], .ti-item, .exam-item')) return true; if (doc.querySelector('input[type="radio"], input[type="checkbox"], textarea, select')) return true; if (doc.querySelector('[id^="answerEditor"], iframe[id^="ueditor_"], div[contenteditable="true"]')) return true; const iframes = Array.from(doc.querySelectorAll('iframe')); if (iframes.some(f => { const src = (f.getAttribute('src') || '').toLowerCase(); return src.includes('mooc-ans') || src.includes('document') || src.includes('ppt') || src.includes('video') || src.includes('knowledgeid'); })) return true; if (doc.querySelector('.cur, .curr, li.active, li.selected, .posCatalog_active')) return true; } catch {} return false; } function hasUnansweredQuestions(doc) { try { const containers = doc.querySelectorAll('.question, .questionLi, .subject_item, .examPaper_subject, .questionContainer, .q-item, .subject_node, [class*="question"], .ti-item, .exam-item'); for (const q of containers) { try { if (!isQuestionAnswered(q)) return true; } catch {} } const radios = Array.from(doc.querySelectorAll('input[type="radio"]')); if (radios.length > 0) { const groups = new Map(); radios.forEach(r => { const k = r.name || `__radio_${Math.random()}`; if (!groups.has(k)) groups.set(k, []); groups.get(k).push(r); }); for (const [, list] of groups) { if (!list.some(r => r.checked)) return true; } } const texts = Array.from(doc.querySelectorAll('textarea, input[type="text"], div[contenteditable="true"]')); if (texts.length > 0) { if (texts.some(el => { if (el.tagName && el.tagName.toLowerCase() === 'div') return ((el.innerText || el.textContent || '').trim().length === 0); return ((el.value || '').trim().length === 0); })) return true; } } catch {} return false; } function tryAutoSkipEmptySection() { if (!isStudyingChapters) return false; const now = Date.now(); if (now - lastAutoSkipTs < 4000) return false; const href = (location && location.href) || ''; const key = href.split('?')[0] + (href.includes('knowledgeId') ? ('?k=' + href.split('knowledgeId')[1]) : ''); if (key !== lastEmptySectionKey) { lastEmptySectionKey = key; emptyChecksCount = 0; } let found = false; forEachSameOriginFrame((doc) => { if (found) return; if (hasActionableStudyContent(doc)) { found = true; return; } if (hasUnansweredQuestions(doc)) { found = true; return; } }); if (!found) { emptyChecksCount += 1; addLog(`小节判空第${emptyChecksCount}次`, 'debug'); if (emptyChecksCount >= 2) { lastAutoSkipTs = now; emptyChecksCount = 0; addLog('检测到空白小节(已二次确认),自动跳转下一小节', 'info'); gotoNextSection(document); return true; } } else { emptyChecksCount = 0; } return false; } async function autoAnswerInDocument(rootDoc) { try { if (!isStudyingChapters) return false; if (isQuizPageDoc(rootDoc)) { if (!isStudyingChapters) return false; const ok = await autoAnswerQuizInDocument(rootDoc); if (ok) return true; } const possibleSelectors = ['.question', '.questionLi', '.subject_item', '.examPaper_subject', '.questionContainer', '.q-item', '.subject_node', '[class*="question"]', '[class*="subject"]', '.ti-item', '.exam-item']; let questions = []; for (let selector of possibleSelectors) { questions = rootDoc.querySelectorAll(selector); if (questions.length > 0) break; } if (questions.length === 0) return false; addLog(`章节内发现 ${questions.length} 个题目,自动作答...`, 'info'); for (let q of questions) { if (!isStudyingChapters) { addLog('已暂停刷章节,停止小测作答', 'info'); return false; } const info = getQuestionInfo(q); if (!info || !info.question) continue; const ans = await getAnswer(info); if (ans) { fillAnswer(ans, q, info.type); await new Promise(r => setTimeout(r, 800)); } } return true; } catch (e) { addLog(`章节答题出错: ${e.message}`, 'error'); return false; } } function isStudyPage() { return /mycourse\/studentstudy|mooc2-ans|knowledgeId|chapterId/.test(location.href); } function hasStudyContentDeep() { let found = false; const tryDoc = (doc) => { try { if (doc.querySelector('video, .video-js, .ans-attach-ct, .reader, .ppt, .ppt-play, .catalog, .vjs-play-control')) { found = true; return; } if (doc.querySelector('.question, .questionLi, .subject_item, .examPaper_subject, .questionContainer, .q-item, .subject_node, [class*="question"], .ti-item, .exam-item')) { found = true; return; } } catch {} }; forEachSameOriginFrame(tryDoc); return found; } function updateStudyButtons(running) { const startBtn = document.getElementById('start-study'); const pauseBtn = document.getElementById('pause-study'); if (!startBtn || !pauseBtn) return; if (running) { startBtn.style.display = 'none'; pauseBtn.style.display = 'flex'; } else { startBtn.style.display = 'flex'; pauseBtn.style.display = 'none'; } } function startStudyChapters() { if (isStudyingChapters) { addLog('刷章节已在运行', 'info'); return; } isStudyingChapters = true; try { localStorage.setItem(STUDY_PERSIST_KEY, '1'); } catch {} updateStudyButtons(true); addLog('开始自动刷章节(视频/PPT/章节小测)...', 'success'); forEachSameOriginFrame((doc) => { try { doc.querySelectorAll('video, .video-js video').forEach(v => { delete v.dataset.disableAutoNext; }); } catch {} handleVideosInDocument(doc); handlePPTInDocument(doc); autoAnswerInDocument(doc); }); tryAutoSkipEmptySection(); studyIntervalId = setInterval(() => { if (!isStudyingChapters) return; forEachSameOriginFrame((doc) => { handleVideosInDocument(doc); handlePPTInDocument(doc); }); tryAutoSkipEmptySection(); }, 3000); } function stopStudyChapters() { if (!isStudyingChapters) return; isStudyingChapters = false; if (studyIntervalId) { clearInterval(studyIntervalId); studyIntervalId = null; } try { localStorage.removeItem(STUDY_PERSIST_KEY); } catch {} forEachSameOriginFrame((doc) => { try { doc.querySelectorAll('video, .video-js video').forEach(v => { v.dataset.disableAutoNext = '1'; try { v.pause(); } catch {} }); } catch {} }); updateStudyButtons(false); addLog('已暂停刷章节', 'info'); } const LOG_SHOW_DEBUG = false; const LOG_MAX_ITEMS = 120; function addLog(message, type = 'info') { try { if (type === 'debug' && !LOG_SHOW_DEBUG) return; const logContainer = document.getElementById('answer-log'); if (!logContainer) return; const text = String(message || '') .replace(/\s+/g, ' ') .slice(0, 140); const logItem = document.createElement('div'); logItem.className = `log-item ${type}`; logItem.textContent = `${new Date().toLocaleTimeString()} - ${text}`; logContainer.appendChild(logItem); const items = logContainer.querySelectorAll('.log-item'); if (items.length > LOG_MAX_ITEMS) { const removeCount = items.length - LOG_MAX_ITEMS; for (let i = 0; i < removeCount; i++) { const n = logContainer.firstElementChild; if (n) logContainer.removeChild(n); } } logContainer.scrollTop = logContainer.scrollHeight; } catch {} } async function updateTrialBadge() { try { const el = document.getElementById('cx_trial_badge'); if (!el) return; const licensed = await checkLicensePaid(); const buyBtn = document.getElementById('buy-license'); if (buyBtn) { const group = buyBtn.closest('.button-group'); if (licensed) { if (group) group.style.display = 'none'; else buyBtn.style.display = 'none'; } else { if (group) group.style.display = 'flex'; else buyBtn.style.display = 'flex'; } } if (licensed) { el.textContent = '永久激活,感谢赞助'; return; } const used = getFreeUsedCount(); const remain = Math.max(0, getFreeLimit() - used); el.textContent = `试用剩余:${remain}/${getFreeLimit()}`; } catch {} } function getQuestionInfo(questionElement) { try { addLog('题目元素HTML结构:' + questionElement.outerHTML.substring(0, 200) + '...', 'debug'); const questionId = questionElement.id || ''; addLog(`题目ID: ${questionId}`, 'debug'); const possibleTypeSelectors = [ '.type_title', '.mark_name', '.questionType', 'div[class*="type"]', 'div[class*="Type"]', '.subject_type', '.q-type', 'div[class*="questionType"]', '.stem_type' ]; const possibleQuestionSelectors = [ '.subject_describe', '.mark_name', '.questionContent', '.title', 'div[class*="title"]', '.subject_stem', '.q-body', '.question-content', '.stem-content', '.stem_txt' ]; let typeText = ''; for (let selector of possibleTypeSelectors) { const element = questionElement.querySelector(selector); if (element) { typeText = element.textContent.trim(); addLog(`找到题目类型: ${typeText},使用选择器: ${selector}`, 'debug'); break; } } let type = ''; if (typeText.includes('单选题')) type = 'single'; else if (typeText.includes('多选题')) type = 'multiple'; else if (typeText.includes('判断题')) type = 'judge'; else if (typeText.includes('填空题')) type = 'blank'; else if (typeText.includes('简答题')) type = 'short'; else if (typeText.includes('名词解释')) type = 'term'; else if (typeText.includes('论述题')) type = 'essay'; else if (typeText.includes('计算题')) type = 'calculation'; else if (typeText.includes('完形填空')) type = 'cloze'; else if (typeText.includes('写作题')) type = 'writing'; else if (typeText.includes('连线题')) type = 'matching'; else if (typeText.includes('分录题')) type = 'accounting'; let questionText = ''; for (let selector of possibleQuestionSelectors) { const element = questionElement.querySelector(selector); if (element) { questionText = element.textContent.trim(); addLog(`找到题目内容: ${questionText.substring(0, 30)}...,使用选择器: ${selector}`, 'debug'); break; } } const optionSelectors = [ '.stem_answer > div', '.stem_answer div[class*="option"]', 'div.stem_answer > div', `#${questionId} > div.stem_answer > div`, '.answer_p', '.subject_node', '.answer_options', '.options div' ]; let options = []; let foundSelector = ''; for (let selector of optionSelectors) { const elements = questionElement.querySelectorAll(selector); if (elements.length > 0) { options = Array.from(elements).map((option, index) => { const text = option.textContent.trim(); const letter = String.fromCharCode(65 + index); addLog(`选项 ${letter}: ${text}`, 'debug'); return text; }); foundSelector = selector; addLog(`找到选项,使用选择器: ${selector},数量: ${elements.length}`, 'debug'); break; } } if (options.length === 0 && questionId) { for (let i = 1; i <= 6; i++) { const specificSelector = `#${questionId} > div.stem_answer > div:nth-child(${i})`; const element = document.querySelector(specificSelector); if (element) { options.push(element.textContent.trim()); addLog(`使用nth-child选择器找到选项 ${i}: ${element.textContent.trim()}`, 'debug'); } } } if (!type || !questionText) { addLog('未能完全识别题目信息', 'error'); } return { type, question: questionText, options, foundSelector, questionId }; } catch (error) { addLog(`解析题目失败: ${error.message}`, 'error'); return null; } } function getModelParams(questionType) { const preciseTypes = ['single', 'multiple', 'blank', 'cloze', 'judge', 'term']; if (preciseTypes.includes(questionType)) { return { temperature: 0.1, max_tokens: 100, top_p: 0.1, frequency_penalty: 0.1, presence_penalty: 0.1 }; } else { return { temperature: 0.5, max_tokens: 500, top_p: 0.8, frequency_penalty: 0.3, presence_penalty: 0.3 }; } } async function getAnswer(questionInfo) { try { await ensureAccessAllowed(); } catch (e) { addLog(String(e && e.message ? e.message : e), 'error'); return null; } const prompt = generatePrompt(questionInfo); addLog(`发送到DeepSeek的提示词:\n${prompt}`, 'debug'); try { const modelParams = getModelParams(questionInfo.type); addLog(`使用模型参数: ${JSON.stringify(modelParams)}`, 'debug'); const response = await fetch(DEEPSEEK_API_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${DEEPSEEK_API_KEY}` }, body: JSON.stringify({ model: "deepseek-chat", messages: [{ role: "user", content: prompt }], ...modelParams }) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); if (!data.choices || !data.choices[0] || !data.choices[0].message) { throw new Error('Invalid API response format'); } const answer = data.choices[0].message.content.trim(); return answer; } catch (error) { addLog(`API调用失败: ${error.message}`, 'error'); return null; } } function generatePrompt(questionInfo) { let prompt = `直接给出答案不要解释 \n题目:${questionInfo.question}\n`; if (questionInfo.type === 'single' || questionInfo.type === 'multiple' || questionInfo.type === 'judge') { if (questionInfo.options && questionInfo.options.length > 0) { prompt += '选项:\n'; questionInfo.options.forEach((option, index) => { const letter = String.fromCharCode(65 + index); const cleanOption = option.replace(/^[A-Z][\s.、.。]+|^\d+[\s.、.。]+/, '').trim(); prompt += `${letter}. ${cleanOption}\n`; }); if (questionInfo.type === 'single') { prompt += '\n请直接回答选项字母(A/B/C/D/...)'; } else if (questionInfo.type === 'multiple') { prompt += '\n这是多选题,请列出所有正确选项的字母,用逗号分隔(如:A,B,D)'; } else if (questionInfo.type === 'judge') { prompt += '\n这是判断题,请回答A表示正确,B表示错误'; } } } else if (questionInfo.type === 'blank') { prompt += '\n这是填空题,请按顺序给出每个空的答案,用逗号分隔'; } return prompt; } function fillAnswer(answer, questionElement, type) { try { addLog(`开始填写答案: ${type}类型`, 'debug'); addLog('题目元素类名: ' + questionElement.className, 'debug'); let filled = false; const questionId = questionElement.id; addLog(`处理题目ID: ${questionId}`, 'debug'); switch (type) { case 'blank': case 'cloze': { const answers = answer.split(/[,,;;、]\s*/).map(a => a.trim()).filter(a => a); addLog(`解析到的答案数量: ${answers.length}`, 'debug'); answers.forEach((ans, idx) => addLog(`第${idx + 1}个答案: ${ans}`, 'debug')); const editorElements = questionElement.querySelectorAll('[id^="answerEditor"]'); if (editorElements.length > 0) { addLog(`找到UEditor元素数量: ${editorElements.length}`, 'debug'); editorElements.forEach((editorElement, index) => { const editorId = editorElement.id; addLog(`处理第${index + 1}个编辑器: ${editorId}`, 'debug'); if (index < answers.length) { const currentAnswer = answers[index]; try { if (typeof UE !== 'undefined' && UE.getEditor) { const editor = UE.getEditor(editorId); if (editor) { if (editor.ready) { editor.ready(() => { editor.setContent(currentAnswer); addLog(`通过UEditor API设置第${index + 1}个空的内容: ${currentAnswer}`, 'debug'); if (typeof editor.fireEvent === 'function') { editor.fireEvent('contentChange'); } }); filled = true; } } } if (!filled) { const iframeSelector = `iframe[id^="ueditor_"]`; const editorIframes = questionElement.querySelectorAll(iframeSelector); const editorIframe = editorIframes[index]; if (editorIframe) { try { const iframeDoc = editorIframe.contentDocument || editorIframe.contentWindow.document; const editorBody = iframeDoc.body; if (editorBody) { editorBody.innerHTML = currentAnswer; editorBody.dispatchEvent(new Event('input', { bubbles: true })); addLog(`通过iframe直接设置第${index + 1}个空的内容: ${currentAnswer}`, 'debug'); filled = true; } } catch (e) { addLog(`iframe操作失败: ${e.message}`, 'error'); } } } const textarea = document.getElementById(editorId); if (textarea) { textarea.value = currentAnswer; textarea.dispatchEvent(new Event('change', { bubbles: true })); textarea.dispatchEvent(new Event('input', { bubbles: true })); addLog(`设置第${index + 1}个空的textarea值: ${currentAnswer}`, 'debug'); } } catch (e) { addLog(`处理第${index + 1}个空时出错: ${e.message}`, 'error'); } } else { addLog(`警告:第${index + 1}个空没有对应的答案`, 'error'); } }); } if (!filled) { const blankInputs = [ ...questionElement.querySelectorAll('input[type="text"]'), ...questionElement.querySelectorAll('.blank'), ...questionElement.querySelectorAll('.fill-blank'), ...questionElement.querySelectorAll('[class*="blank"]'), ...questionElement.querySelectorAll('[class*="fill"]'), ...questionElement.querySelectorAll('textarea') ]; if (blankInputs.length > 0) { addLog(`找到 ${blankInputs.length} 个普通输入框`, 'debug'); blankInputs.forEach((input, index) => { if (index < answers.length) { try { input.value = answers[index]; input.dispatchEvent(new Event('input', { bubbles: true })); input.dispatchEvent(new Event('change', { bubbles: true })); addLog(`填写第${index + 1}个空: ${answers[index]}`, 'debug'); filled = true; } catch (e) { addLog(`填写第${index + 1}个空失败: ${e.message}`, 'error'); } } else { addLog(`警告:第${index + 1}个输入框没有对应的答案`, 'error'); } }); } } break; } case 'short': case 'term': case 'essay': case 'writing': case 'calculation': case 'matching': case 'accounting': { const textInputs = [ ...questionElement.querySelectorAll('textarea'), ...questionElement.querySelectorAll('.answer-area'), ...questionElement.querySelectorAll('.writing-area'), ...questionElement.querySelectorAll('[class*="answer"]'), ...questionElement.querySelectorAll('[class*="text-area"]'), ...questionElement.querySelectorAll('div[contenteditable="true"]') ]; if (textInputs.length > 0) { textInputs.forEach(input => { try { if (input.tagName.toLowerCase() === 'textarea' || input.tagName.toLowerCase() === 'input') { input.value = answer; input.dispatchEvent(new Event('input', { bubbles: true })); input.dispatchEvent(new Event('change', { bubbles: true })); } else if (input.getAttribute('contenteditable') === 'true') { input.innerHTML = answer; input.dispatchEvent(new Event('input', { bubbles: true })); } addLog(`填写答案到${input.tagName.toLowerCase()}`, 'debug'); filled = true; } catch (e) { addLog(`填写答案失败: ${e.message}`, 'error'); } }); } const editors = [ ...questionElement.querySelectorAll('.editor'), ...questionElement.querySelectorAll('[class*="editor"]'), ...questionElement.querySelectorAll('iframe') ]; editors.forEach(editor => { try { if (editor.tagName.toLowerCase() === 'iframe') { const iframeDoc = editor.contentDocument || editor.contentWindow.document; const editorBody = iframeDoc.body; if (editorBody) { editorBody.innerHTML = answer; editorBody.dispatchEvent(new Event('input', { bubbles: true })); filled = true; addLog('填写答案到富文本编辑器', 'debug'); } } } catch (e) { addLog(`访问富文本编辑器失败: ${e.message}`, 'error'); } }); break; } case 'single': case 'multiple': case 'judge': { let answerLetters; if (type === 'multiple') { answerLetters = answer.toUpperCase().split(/[,,、\s]+/).map(l => l.trim()); } else { answerLetters = [answer.toUpperCase().trim()]; } addLog(`识别到的选项字母: ${answerLetters.join(', ')}`, 'debug'); for (const letter of answerLetters) { if (!/^[A-Z]$/.test(letter)) { addLog(`跳过无效的选项字母: ${letter}`, 'error'); continue; } const index = letter.charCodeAt(0) - 65 + 1; // 1-based index for nth-child const specificSelector = `#${questionId} > div.stem_answer > div:nth-child(${index})`; const optionElement = document.querySelector(specificSelector); if (optionElement) { try { optionElement.click(); addLog(`点击选项元素: ${specificSelector}`, 'debug'); const input = optionElement.querySelector('input'); if (input) { input.click(); input.checked = true; input.dispatchEvent(new Event('change', { bubbles: true })); addLog(`点击选项input元素`, 'debug'); } const label = optionElement.querySelector('label'); if (label) { label.click(); addLog(`点击选项label元素`, 'debug'); } filled = true; } catch (e) { addLog(`点击选项 ${letter} 失败: ${e.message}`, 'error'); } } else { addLog(`未找到选项元素: ${specificSelector}`, 'error'); } } break; } default: break; } if (filled) { addLog(`答案填写成功`, 'success'); } else { addLog(`答案可能未成功填写,请检查`, 'error'); } try { const submitButtons = [ ...questionElement.querySelectorAll('button[type="submit"]'), ...questionElement.querySelectorAll('input[type="submit"]'), ...questionElement.querySelectorAll('.submit-btn'), ...questionElement.querySelectorAll('.save-btn'), ...questionElement.querySelectorAll('[class*="submit"]'), ...questionElement.querySelectorAll('[class*="save"]') ]; if (submitButtons.length > 0) { submitButtons[0].click(); addLog('触发了提交按钮', 'debug'); } } catch (e) { addLog(`触发提交按钮失败: ${e.message}`, 'debug'); } } catch (error) { addLog(`答案填写失败: ${error.message}`, 'error'); } } function debugPageStructure() { addLog('开始调试页面结构...', 'debug'); addLog('页面URL: ' + window.location.href, 'debug'); addLog('页面标题: ' + document.title, 'debug'); const possibleContainers = [ '.question', '.questionLi', '.subject_item', '.examPaper_subject', '.questionContainer', '.q-item', '.subject_node', '[class*="question"]', '[class*="subject"]' ]; for (let selector of possibleContainers) { const elements = document.querySelectorAll(selector); addLog(`使用选择器 ${selector} 找到 ${elements.length} 个元素`, 'debug'); if (elements.length > 0) { addLog(`第一个元素HTML结构:${elements[0].outerHTML.substring(0, 200)}...`, 'debug'); } } const allElements = document.querySelectorAll('*'); const relevantElements = Array.from(allElements).filter(el => { const className = el.className || ''; const id = el.id || ''; return (className + id).toLowerCase().includes('question') || (className + id).toLowerCase().includes('answer') || (className + id).toLowerCase().includes('option') || (className + id).toLowerCase().includes('subject'); }); addLog(`找到 ${relevantElements.length} 个可能相关的元素`, 'debug'); relevantElements.forEach(el => { addLog(`发现元素: ${el.tagName.toLowerCase()}.${el.className}#${el.id}`, 'debug'); addLog(`元素HTML: ${el.outerHTML.substring(0, 100)}...`, 'debug'); }); const inputs = document.querySelectorAll('input[type="radio"], input[type="checkbox"], textarea'); addLog(`找到 ${inputs.length} 个输入元素`, 'debug'); inputs.forEach(input => { addLog(`输入元素: type=${input.type}, name=${input.name}, class=${input.className}`, 'debug'); }); } function updateStatus(running) { const startButton = document.getElementById('start-answer'); const pauseButton = document.getElementById('pause-answer'); if (running) { startButton.style.display = 'none'; pauseButton.style.display = 'flex'; } else { startButton.style.display = 'flex'; pauseButton.style.display = 'none'; } } function hasQuestions() { const possibleSelectors = [ '.question', '.questionLi', '.subject_item', '.examPaper_subject', '.questionContainer', '.q-item', '.subject_node', '[class*="question"]', '[class*="subject"]', '.ti-item', '.exam-item' ]; for (let selector of possibleSelectors) { const questions = document.querySelectorAll(selector); if (questions.length > 0) { return true; } } const allElements = document.querySelectorAll('*'); const possibleQuestions = Array.from(allElements).filter(el => { const className = el.className || ''; const id = el.id || ''; const text = el.textContent || ''; return (className + id + text).toLowerCase().includes('题目') || (className + id).toLowerCase().includes('question') || (className + id).toLowerCase().includes('subject') || /^\d+[\.。]/.test(text.trim()); }); return possibleQuestions.length > 0; } function showNoTaskToast() { const toast = document.createElement('div'); toast.id = 'no-task-toast'; toast.textContent = '该页面无任务'; document.body.appendChild(toast); setTimeout(() => { if (toast && toast.parentNode) { toast.parentNode.removeChild(toast); } }, 3000); } let advanceInProgress = false; function isQuestionAnswered(q) { try { const choiceInputs = q.querySelectorAll('input[type="radio"], input[type="checkbox"]'); if (choiceInputs.length > 0) { return Array.from(choiceInputs).some(i => i.checked); } const textInputs = q.querySelectorAll('input[type="text"], textarea'); if (textInputs.length > 0) { if (Array.from(textInputs).some(t => (t.value || '').trim().length > 0)) return true; } const editableDivs = q.querySelectorAll('[contenteditable="true"]'); if (editableDivs.length > 0) { if (Array.from(editableDivs).some(d => (d.innerText || d.textContent || '').trim().length > 0)) return true; } const ueTextareas = q.querySelectorAll('[id^="answerEditor"]'); for (const ta of ueTextareas) { const id = ta.id; try { if (typeof UE !== 'undefined' && UE.getEditor) { const ed = UE.getEditor(id); if (ed && ed.getContentTxt && ed.getContentTxt().trim().length > 0) return true; } } catch {} if ((ta.value || '').trim().length > 0) return true; } const ifr = q.querySelector('iframe[id^="ueditor_"]'); if (ifr) { try { const doc = ifr.contentDocument || ifr.contentWindow.document; const txt = (doc && doc.body && (doc.body.innerText || doc.body.textContent)) || ''; if (txt.trim().length > 0) return true; } catch {} } } catch {} return false; } function isSectionDone(contextDoc) { const doc = contextDoc || document; try { const videos = doc.querySelectorAll('video, .video-js video'); for (const v of videos) { try { const d = v.duration || 0; const t = v.currentTime || 0; if (!(v.ended || (d > 0 && t / d >= 0.985))) { return false; } } catch { return false; } } const questions = doc.querySelectorAll('.question, .questionLi, .subject_item, .examPaper_subject, .questionContainer, .q-item, .subject_node, [class*="question"], .ti-item, .exam-item'); for (const q of questions) { if (!isQuestionAnswered(q)) { return false; } } return true; } catch { return false; } } async function ensureSectionCompletedAndAdvance(contextDoc) { if (!isStudyingChapters) { addLog('刷章节已暂停,跳过跳转检测', 'info'); return; } if (advanceInProgress) { addLog('跳转检测进行中,忽略重复触发', 'debug'); return; } advanceInProgress = true; try { const doc = contextDoc || document; await autoAnswerInDocument(doc); await tryEnterQuizAndAnswer(doc); let tries = 3; while (tries-- > 0) { if (!isStudyingChapters) { addLog('刷章节已暂停,终止跳转检测', 'info'); return; } if (isSectionDone(doc)) { addLog('检测到当前小节已完成,准备跳转下一小节', 'success'); gotoNextSection(doc); return; } await new Promise(r => setTimeout(r, 500)); } addLog('当前小节未完成,暂不跳转', 'info'); } catch (e) { addLog(`跳转前完成度检测出错: ${e.message}`, 'error'); } finally { advanceInProgress = false; } } async function autoAnswer() { if (isAnswering) { addLog('自动答题已经在运行中...', 'info'); return; } isAnswering = true; updateStatus(true); addLog('开始查找题目...', 'debug'); try { addLog('当前页面URL: ' + window.location.href, 'debug'); addLog('当前页面标题: ' + document.title, 'debug'); const possibleSelectors = [ '.question', '.questionLi', '.subject_item', '.examPaper_subject', '.questionContainer', '.q-item', '.subject_node', '[class*="question"]', '[class*="subject"]', '.ti-item', '.exam-item' ]; let questions = []; let foundSelector = ''; for (let selector of possibleSelectors) { questions = document.querySelectorAll(selector); if (questions.length > 0) { foundSelector = selector; addLog(`使用选择器 ${selector} 找到 ${questions.length} 个题目`, 'debug'); break; } } if (questions.length === 0) { addLog('使用常规选择器未找到题目,尝试查找可能的题目容器...', 'debug'); const allElements = document.querySelectorAll('*'); const possibleQuestions = Array.from(allElements).filter(el => { const className = el.className || ''; const id = el.id || ''; const text = el.textContent || ''; return (className + id + text).toLowerCase().includes('题目') || (className + id).toLowerCase().includes('question') || (className + id).toLowerCase().includes('subject') || /^\d+[\.。]/.test(text.trim()); // 匹配数字开头的内容 }); if (possibleQuestions.length > 0) { questions = possibleQuestions; addLog(`通过内容分析找到 ${questions.length} 个可能的题目`, 'debug'); } } if (questions.length === 0) { addLog('未找到任何题目,请确保页面已完全加载', 'error'); addLog('页面主要内容:' + document.body.innerHTML.substring(0, 500) + '...', 'debug'); return; } addLog(`共找到 ${questions.length} 个题目`, 'info'); Array.from(questions).forEach((q, idx) => { addLog(`题目 ${idx + 1} 类名: ${q.className}, ID: ${q.id}`, 'debug'); }); for (let question of questions) { if (!isAnswering) { addLog('自动答题已暂停', 'info'); break; } const questionInfo = getQuestionInfo(question); if (!questionInfo) { addLog('题目信息获取失败,跳过当前题目', 'error'); continue; } addLog(`正在处理题目: ${questionInfo.question.substring(0, 30)}...`); addLog(`题目类型: ${questionInfo.type}`, 'debug'); addLog(`选项数量: ${questionInfo.options.length}`, 'debug'); const answer = await getAnswer(questionInfo); if (answer) { addLog(`获取到答案: ${answer}`); fillAnswer(answer, question, questionInfo.type); } if (isAnswering) { await new Promise(resolve => setTimeout(resolve, 2000)); } } } catch (error) { addLog(`自动答题过程出错: ${error.message}`, 'error'); } finally { isAnswering = false; updateStatus(false); addLog('答题过程结束', 'success'); } } function init() { let persistedStudy = false; try { persistedStudy = localStorage.getItem(STUDY_PERSIST_KEY) === '1'; } catch {} const pageTitle = document.title || ''; const currentUrl = location.href || ''; if (pageTitle.includes('课程') || pageTitle === '课程' || pageTitle.includes('课表') || pageTitle === '课表') { addLog(`检测到${pageTitle.includes('课表') ? '课表' : '课程'}页面,不展现脚本面板`, 'info'); return; } const isCourseDetailPage = () => { if (currentUrl.includes('/mooc2-ans/mycourse/stu') || currentUrl.includes('/mycourse/studentcourse') || currentUrl.includes('course/') && !currentUrl.includes('knowledge')) { const hasNavigationMenu = document.querySelector('.nav-content ul, .stuNavigationList ul'); const hasModuleLinks = document.querySelectorAll('a[title="章节"], a[title="作业"], a[title="考试"], a[title="资料"]').length >= 3; const hasCourseInfo = document.querySelector('.classDl, .sideCon, .nav_side'); const hasCourseId = document.querySelector('#courseid, input[name="courseid"]'); if ((hasNavigationMenu || hasModuleLinks) && hasCourseInfo && hasCourseId) { return true; } } return false; }; if (isCourseDetailPage()) { addLog('检测到课程详情页面,不展现脚本面板', 'info'); return; } const isChapterListPage = () => { const hasChapterList = document.querySelector('.fanyaChapter, .chapter_body, .xs_table'); const hasChapterItems = document.querySelectorAll('.chapter_unit, .chapter_item').length > 0; const hasChapterStructure = document.querySelector('.chapter_th, .chapter_td'); const hasProgressInfo = document.querySelector('.catalog_points_yi, .chapter_head'); const hasSearchBox = document.querySelector('#searchChapterListByName, .dataSearch'); const hasTypicalStructure = hasChapterList && hasChapterStructure && hasProgressInfo; const hasChapterTitles = document.querySelectorAll('.catalog_name, .newCatalog_name').length > 2; const urlIndicatesChapterList = currentUrl.includes('/mycourse/studentcourse') || currentUrl.includes('/studentstudy') && !currentUrl.includes('chapterId='); const hasNoLearningContent = !document.querySelector('video, .video-js, iframe[src*="chaoxing"], .questionLi, .TiMu'); return hasTypicalStructure && hasChapterItems && hasChapterTitles && urlIndicatesChapterList && hasNoLearningContent; }; if (isChapterListPage()) { addLog('检测到章节列表页面,不展现脚本面板', 'info'); return; } if (!persistedStudy && !hasQuestions() && !hasStudyContentDeep() && !isStudyPage()) { showNoTaskToast(); return; } if (!claimOwnership()) { if (persistedStudy && !recoveryTimerId) { recoveryTimerId = setInterval(() => { if (claimOwnership()) { clearInterval(recoveryTimerId); recoveryTimerId = null; createdPanelEl = createPanel(); bindPanelEvents(); startHeartbeat(); if (!isStudyingChapters) startStudyChapters(); } }, 1000); } return; } createdPanelEl = createPanel(); bindPanelEvents(); startHeartbeat(); if (persistedStudy) { startStudyChapters(); setTimeout(() => tryAutoSkipEmptySection(), 600); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } function isQuizPageDoc(doc) { try { if (doc.getElementById('form1') && doc.querySelector('#RightCon .newTestTitle')) return true; if (doc.querySelector('.newTestCon form#form1') && doc.querySelector('.ans-cc')) return true; } catch {} return false; } function collectQuizQuestions(doc) { const questions = []; try { const typeInputs = doc.querySelectorAll('input[id^="answertype"]'); typeInputs.forEach((inp) => { try { const id = inp.id.replace('answertype', ''); const qid = id.trim(); const block = doc.querySelector(`.singleQuesId[data="${qid}"]`) || inp.closest('.TiMu') || doc; const typeVal = (inp.value || '').trim(); let type = ''; if (typeVal === '0') type = 'single'; else if (typeVal === '1') type = 'multiple'; else if (typeVal === '3') type = 'judge'; else if (typeVal === '2') type = 'blank'; else if (typeVal === '4') type = 'short'; else { const hasTextInput = block.querySelector('input[type="text"], textarea, [contenteditable="true"], [id^="answerEditor"], iframe[id^="ueditor_"]'); type = hasTextInput ? 'short' : 'text'; } const opts = []; const lis = block.querySelectorAll(`ul.Zy_ulTop li[onclick][qid="${qid}"]`); lis.forEach((li, idx) => { const span = li.querySelector('.num_option, .num_option_dx'); const letter = span?.getAttribute('data') || String.fromCharCode(65 + idx); const txt = (li.querySelector('a.after')?.textContent || '').trim(); opts.push(`${letter}. ${txt}`); }); let qtext = ''; const label = block.querySelector('.Zy_TItle .fontLabel'); if (label) qtext = label.textContent.replace(/\s+/g, ' ').trim(); questions.push({ qid, type, question: qtext, options: opts }); } catch {} }); } catch {} return questions; } function fillQuizAnswer(doc, qid, type, answer) { try { const block = doc.querySelector(`.singleQuesId[data="${qid}"]`) || doc; if (!block) return false; if (type === 'single' || type === 'multiple' || type === 'judge') { let letters = []; if (type === 'multiple') { letters = (answer || '').toUpperCase().split(/[,,、\s]+/).filter(Boolean); } else if (type === 'judge') { const val = String(answer || '').trim().toLowerCase(); if (/^a$|对|true|正确/.test(val)) letters = ['A']; else if (/^b$|错|false|错误/.test(val)) letters = ['B']; else if (/^t$/.test(val)) letters = ['A']; else if (/^f$/.test(val)) letters = ['B']; else letters = [(val.match(/[ab]/i) || ['A'])[0].toUpperCase()]; } else { const m = String(answer || '').toUpperCase().match(/[A-Z]/g); letters = m ? m : []; } const ul = block.querySelector('ul.Zy_ulTop'); if (!ul) return false; letters.forEach((L) => { let target = null; if (type === 'judge') { const dataVal = (L === 'A') ? 'true' : 'false'; target = ul.querySelector(`li .num_option[data='${dataVal}'], li .num_option_dx[data='${dataVal}']`) || ul.querySelector(`li .num_option[data='${L}'], li .num_option_dx[data='${L}']`); } else { target = ul.querySelector(`li .num_option[data='${L}'], li .num_option_dx[data='${L}']`); } if (target) { const li = target.closest('li'); safeClick(li); } }); const hidden = doc.getElementById(`answer${qid}`); if (hidden) { const want = (type === 'judge') ? (letters[0] === 'A' ? 'true' : 'false') : letters.join(''); if (!hidden.value || (type !== 'multiple' && hidden.value.toLowerCase() !== want)) { hidden.value = want; const spans = ul.querySelectorAll(`.choice${qid}`); spans.forEach(s => s.classList.remove('check_answer', 'check_answer_dx')); letters.forEach((L) => { let sel = null; if (type === 'judge') { const dv = (L === 'A') ? 'true' : 'false'; sel = ul.querySelector(`.choice${qid}[data='${dv}']`) || ul.querySelector(`.choice${qid}[data='${L}']`); } else { sel = ul.querySelector(`.choice${qid}[data='${L}']`); } if (sel) { const isMulti = !!ul.querySelector('.num_option_dx'); sel.classList.add(isMulti ? 'check_answer_dx' : 'check_answer'); const li = sel.closest('li'); if (li) { li.setAttribute('aria-checked', 'true'); li.setAttribute('aria-pressed', 'true'); } } }); } } return true; } else if (type === 'blank') { // 多空填空:按分隔符拆分并逐个填入 const answers = String(answer || '').split(/[,,;;、]\s*/).map(s => s.trim()).filter(Boolean); const ueAreas = block.querySelectorAll('[id^="answerEditor"]'); ueAreas.forEach((ta, i) => { const val = answers[i] || ''; if (!val) return; try { if (typeof UE !== 'undefined' && UE.getEditor) { const ed = UE.getEditor(ta.id); if (ed) { ed.ready(() => { ed.setContent(val); if (typeof ed.fireEvent === 'function') ed.fireEvent('contentChange'); }); } } else { ta.value = val; ta.dispatchEvent(new Event('input', { bubbles: true })); ta.dispatchEvent(new Event('change', { bubbles: true })); } } catch {} }); const ifrs = block.querySelectorAll('iframe[id^="ueditor_"]'); ifrs.forEach((ifr, i) => { const val = answers[i] || ''; if (!val) return; try { const d = ifr.contentDocument || ifr.contentWindow?.document; const body = d && d.body; if (body) { body.innerHTML = val; body.dispatchEvent(new Event('input', { bubbles: true })); } } catch {} }); const inputs = [ ...block.querySelectorAll('input[type="text"]'), ...block.querySelectorAll('textarea'), ...block.querySelectorAll('[contenteditable="true"]') ]; inputs.forEach((el, i) => { const val = answers[i] || ''; if (!val) return; try { const tag = (el.tagName || '').toLowerCase(); if (tag === 'input' || tag === 'textarea') { el.value = val; el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); } else if (el.getAttribute('contenteditable') === 'true') { el.innerHTML = val; el.dispatchEvent(new Event('input', { bubbles: true })); } } catch {} }); const hidden = doc.getElementById(`answer${qid}`); if (hidden) hidden.value = answers.join(' '); return true; } else if (type === 'text' || type === 'short' || type === 'essay' || type === 'writing') { // 简答题:整体写入,不做分割 const val = String(answer || '').trim(); if (!val) return false; const ueAreas = block.querySelectorAll('[id^="answerEditor"]'); ueAreas.forEach((ta) => { try { if (typeof UE !== 'undefined' && UE.getEditor) { const ed = UE.getEditor(ta.id); if (ed) { ed.ready(() => { ed.setContent(val); if (typeof ed.fireEvent === 'function') ed.fireEvent('contentChange'); }); } } else { ta.value = val; ta.dispatchEvent(new Event('input', { bubbles: true })); ta.dispatchEvent(new Event('change', { bubbles: true })); } } catch {} }); const ifrs = block.querySelectorAll('iframe[id^="ueditor_"]'); ifrs.forEach((ifr) => { try { const d = ifr.contentDocument || ifr.contentWindow?.document; const body = d && d.body; if (body) { body.innerHTML = val; body.dispatchEvent(new Event('input', { bubbles: true })); } } catch {} }); const inputs = [ ...block.querySelectorAll('textarea'), ...block.querySelectorAll('input[type="text"]'), ...block.querySelectorAll('[contenteditable="true"]') ]; inputs.forEach((el) => { try { const tag = (el.tagName || '').toLowerCase(); if (tag === 'input' || tag === 'textarea') { el.value = val; el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); } else if (el.getAttribute('contenteditable') === 'true') { el.innerHTML = val; el.dispatchEvent(new Event('input', { bubbles: true })); } } catch {} }); const hidden = doc.getElementById(`answer${qid}`); if (hidden) hidden.value = val; return true; } return false; } catch { return false; } } function findAndClickQuizSubmitButton(doc) { try { const targetWindow = doc.defaultView || window; const chaoxingSubmitMethods = [ () => { if (typeof targetWindow.btnBlueSubmit === 'function') { targetWindow.btnBlueSubmit(); addLog('使用 btnBlueSubmit() 方法提交', 'success'); return true; } return false; }, () => { if (typeof targetWindow.submitCheckTimes === 'function') { targetWindow.submitCheckTimes(); addLog('使用 submitCheckTimes() 方法提交', 'success'); return true; } return false; }, () => { if (typeof targetWindow.submitWork === 'function') { targetWindow.submitWork(); addLog('使用 submitWork() 方法提交', 'success'); return true; } return false; }, () => { const forms = doc.querySelectorAll('form'); for (const form of forms) { const formAction = form.action || ''; if (formAction.includes('work') || formAction.includes('quiz') || formAction.includes('submit')) { try { form.submit(); addLog('使用表单 submit() 方法提交', 'success'); return true; } catch (e) { addLog(`表单提交失败: ${e.message}`, 'error'); } } } return false; } ]; for (const method of chaoxingSubmitMethods) { try { if (method()) return true; } catch (e) { addLog(`提交方法执行失败: ${e.message}`, 'error'); } } const submitSelectors = [ 'input[type="submit"][value*="提交"]', 'button[type="submit"]', 'input[value="提交答案"]', 'input[value="提交"]', 'button[onclick*="submit"]', 'button[onclick*="btnBlueSubmit"]', 'button[onclick*="submitCheckTimes"]', '.submit-btn', '.btn-submit', '#submit', '.submit', 'input[id*="submit"]', 'button[id*="submit"]', 'a[onclick*="submit"]', 'input[onclick*="tijiao"]', 'button[onclick*="tijiao"]' ]; for (const selector of submitSelectors) { const submitBtn = doc.querySelector(selector); if (submitBtn && !submitBtn.disabled && !submitBtn.classList.contains('disabled')) { try { submitBtn.scrollIntoView({ block: 'center', behavior: 'smooth' }); const onclick = submitBtn.getAttribute('onclick'); if (onclick) { try { const func = new targetWindow.Function(onclick); func.call(submitBtn); addLog(`通过onclick执行提交: ${onclick}`, 'success'); return true; } catch (e) { addLog(`onclick执行失败: ${e.message}`, 'error'); } } if (safeClick(submitBtn)) { addLog(`成功点击提交按钮: ${selector}`, 'success'); return true; } } catch (e) { addLog(`点击提交按钮失败: ${e.message}`, 'error'); } } } const clickableElements = Array.from(doc.querySelectorAll('input, button, a, span, div')); for (const el of clickableElements) { const text = (el.textContent || el.value || '').trim(); if (/^(提交|提交答案|完成|确认提交)$/.test(text)) { try { el.scrollIntoView({ block: 'center', behavior: 'smooth' }); const onclick = el.getAttribute('onclick'); if (onclick) { try { const func = new targetWindow.Function(onclick); func.call(el); addLog(`通过文本匹配和onclick执行提交: ${text}`, 'success'); return true; } catch (e) { addLog(`文本匹配onclick执行失败: ${e.message}`, 'error'); } } if (safeClick(el)) { addLog(`通过文本匹配点击提交按钮: ${text}`, 'success'); return true; } } catch (e) { addLog(`通过文本匹配点击提交按钮失败: ${e.message}`, 'error'); } } } addLog('未找到章节测验提交按钮', 'error'); return false; } catch (e) { addLog(`查找提交按钮时出错: ${e.message}`, 'error'); return false; } } function validateAndFixSubmitParams(doc) { try { const targetWindow = doc.defaultView || window; if (typeof targetWindow.workRelationId === 'undefined') { const workIdInputs = doc.querySelectorAll('input[name*="workRelationId"], input[id*="workRelationId"]'); if (workIdInputs.length > 0) { targetWindow.workRelationId = workIdInputs[0].value; addLog(`设置workRelationId: ${targetWindow.workRelationId}`, 'debug'); } } if (typeof targetWindow.courseId === 'undefined') { const courseIdInputs = doc.querySelectorAll('input[name*="courseId"], input[id*="courseId"]'); if (courseIdInputs.length > 0) { targetWindow.courseId = courseIdInputs[0].value; addLog(`设置courseId: ${targetWindow.courseId}`, 'debug'); } } if (typeof targetWindow.classId === 'undefined') { const classIdInputs = doc.querySelectorAll('input[name*="classId"], input[id*="classId"]'); if (classIdInputs.length > 0) { targetWindow.classId = classIdInputs[0].value; addLog(`设置classId: ${targetWindow.classId}`, 'debug'); } } const questions = doc.querySelectorAll('[class*="TiMu"], [class*="timu"]'); questions.forEach((q, index) => { const qid = q.getAttribute('id') || `question_${index}`; let answerInput = doc.querySelector(`input[name="answer${qid}"], input[id="answer${qid}"]`); if (!answerInput) { answerInput = doc.createElement('input'); answerInput.type = 'hidden'; answerInput.name = `answer${qid}`; answerInput.id = `answer${qid}`; q.appendChild(answerInput); addLog(`为题目${qid}创建答案input`, 'debug'); } }); addLog('提交参数验证完成', 'debug'); return true; } catch (e) { addLog(`提交参数验证失败: ${e.message}`, 'error'); return false; } } async function handleSubmitConfirmDialog(doc, timeoutMs = 3000) { const startTime = Date.now(); while (Date.now() - startTime < timeoutMs) { try { const confirmDialogSelectors = [ '.popDiv', '.modal', '.dialog', '.alert', '.layui-layer', '.confirm-dialog', '.submit-confirm', '[class*="confirm"]', '[class*="dialog"]', '[class*="modal"]' ]; for (const selector of confirmDialogSelectors) { const dialog = doc.querySelector(selector); if (dialog && dialog.style.display !== 'none' && (dialog.textContent.includes('确认提交') || dialog.textContent.includes('提交') || dialog.textContent.includes('确定'))) { addLog('检测到提交确认弹窗', 'info'); const confirmButtonSelectors = [ 'button[onclick*="submit"]', 'button[value*="提交"]', 'button[value*="确定"]', 'button[value*="确认"]', 'input[type="button"][value*="提交"]', 'input[type="button"][value*="确定"]', 'input[type="button"][value*="确认"]', '.confirm-btn', '.submit-btn', '.ok-btn', 'button:contains("提交")', 'button:contains("确定")', 'button:contains("确认")', 'a[onclick*="submit"]' ]; for (const btnSelector of confirmButtonSelectors) { const confirmBtn = dialog.querySelector(btnSelector) || doc.querySelector(`${selector} ${btnSelector}`); if (confirmBtn && !confirmBtn.disabled) { try { const onclick = confirmBtn.getAttribute('onclick'); if (onclick) { const targetWindow = doc.defaultView || window; const func = new targetWindow.Function(onclick); func.call(confirmBtn); addLog(`通过onclick执行确认提交: ${onclick}`, 'success'); return true; } if (safeClick(confirmBtn)) { addLog(`点击确认提交按钮: ${btnSelector}`, 'success'); return true; } } catch (e) { addLog(`点击确认按钮失败: ${e.message}`, 'error'); } } } const allButtons = dialog.querySelectorAll('button, input[type="button"], a'); for (const btn of allButtons) { const text = (btn.textContent || btn.value || '').trim(); if (/^(提交|确定|确认|OK)$/.test(text)) { try { if (safeClick(btn)) { addLog(`通过文本匹配点击确认按钮: ${text}`, 'success'); return true; } } catch (e) { addLog(`文本匹配点击确认按钮失败: ${e.message}`, 'error'); } } } } } } catch (e) { } await new Promise(r => setTimeout(r, 200)); } return false; } async function waitForQuizSubmitCompletion(doc, timeoutMs = 5000) { const startTime = Date.now(); const originalUrl = doc.location.href; while (Date.now() - startTime < timeoutMs) { try { const successIndicators = [ '.success', '.alert-success', '.msg-success', '[class*="success"]', '[class*="complete"]', '*[text()*="提交成功"]', '*[text()*="完成"]' ]; for (const selector of successIndicators) { const indicator = doc.querySelector(selector); if (indicator && indicator.textContent.includes('成功')) { addLog('检测到提交成功提示', 'success'); return true; } } if (doc.location.href !== originalUrl) { addLog('检测到页面跳转,提交可能已完成', 'info'); return true; } const nextStepSelectors = [ 'button[onclick*="next"]', 'a[onclick*="next"]', 'input[value*="下一"]', 'button[value*="下一"]', '.next-btn', '.btn-next', '#next' ]; for (const selector of nextStepSelectors) { if (doc.querySelector(selector)) { addLog('检测到下一步按钮,提交可能已完成', 'info'); return true; } } } catch (e) { } await new Promise(r => setTimeout(r, 200)); } addLog('等待提交完成超时', 'error'); return false; } async function autoAnswerQuizInDocument(doc) { try { if (!isStudyingChapters) return false; if (!isQuizPageDoc(doc)) return false; await injectConsoleDecryptCode(doc); const qs = collectQuizQuestions(doc); if (!qs || qs.length === 0) return false; addLog(`检测到章节测验,共 ${qs.length} 题,开始作答...`, 'info'); for (const q of qs) { if (!isStudyingChapters) { addLog('已暂停刷章节,停止测验作答', 'info'); return false; } const promptInfo = { type: q.type, question: q.question || `题目 ${q.qid}`, options: q.options || [] }; const ans = await getAnswer(promptInfo); if (ans) { fillQuizAnswer(doc, q.qid, q.type, ans); } await new Promise(r => setTimeout(r, 500)); } addLog('章节测验答题完成,准备提交...', 'success'); await new Promise(r => setTimeout(r, 1000)); addLog('验证提交参数...', 'info'); validateAndFixSubmitParams(doc); let submitSuccess = false; const targetWindow = doc.defaultView || window; try { const originalAlert = targetWindow.alert; targetWindow.alert = function(msg) { addLog(`阻止弹窗: ${msg}`, 'debug'); if (msg && msg.includes('code-1')) { addLog('检测到code-1错误,尝试其他提交方式', 'info'); return; } return originalAlert.call(this, msg); }; if (typeof targetWindow.btnBlueSubmit === 'function') { addLog('使用学习通标准提交流程', 'info'); targetWindow.btnBlueSubmit(); await new Promise(r => setTimeout(r, 1000)); if (typeof targetWindow.submitCheckTimes === 'function') { targetWindow.submitCheckTimes(); addLog('执行submitCheckTimes完成', 'success'); } if (typeof targetWindow.noSubmit === 'function') { addLog('检测到noSubmit函数,跳过自动提交以避免错误', 'info'); } submitSuccess = true; addLog('学习通标准提交流程执行完成', 'success'); } else if (typeof targetWindow.submitWork === 'function') { addLog('使用submitWork提交', 'info'); targetWindow.submitWork(); submitSuccess = true; } else { submitSuccess = findAndClickQuizSubmitButton(doc); } // 恢复原始alert targetWindow.alert = originalAlert; } catch (e) { addLog(`提交流程执行失败: ${e.message}`, 'error'); submitSuccess = findAndClickQuizSubmitButton(doc); } if (submitSuccess) { addLog('已执行提交操作,等待确认弹窗...', 'info'); await new Promise(r => setTimeout(r, 500)); const confirmHandled = await handleSubmitConfirmDialog(doc, 3000); if (confirmHandled) { addLog('已处理提交确认弹窗', 'success'); } else { addLog('未检测到确认弹窗或处理失败', 'info'); } const submitCompleted = await waitForQuizSubmitCompletion(doc, 8000); if (submitCompleted) { addLog('章节测验提交完成,准备跳转下一节...', 'success'); await new Promise(r => setTimeout(r, 2000)); if (isStudyingChapters) { const jumpSuccess = gotoNextSection(doc); if (jumpSuccess) { addLog('已自动跳转到下一节', 'success'); } else { addLog('自动跳转失败,请手动切换到下一节', 'error'); } } } else { addLog('等待提交完成超时,但将继续尝试跳转', 'info'); await new Promise(r => setTimeout(r, 1500)); if (isStudyingChapters) gotoNextSection(doc); } } else { addLog('未找到提交按钮,跳过提交直接尝试跳转', 'info'); await new Promise(r => setTimeout(r, 1000)); if (isStudyingChapters) gotoNextSection(doc); } return true; } catch (e) { addLog(`章节测验自动作答失败: ${e.message}`, 'error'); return false; } } })();