// ==UserScript== // @name 高校邦刷课脚本 // @namespace https://github.com/Wu557666/gaoxiaobang // @version 2.4.4 // @description 极速刷视频/页面+讨论批量回复,修改一手通配符,xmut是可以的,不清楚其他行不行 // @author wu某人 (优化 by Deepseek) // @icon https://favicon.im/xmut.gaoxiaobang.com?size=128 // @match https://xmut.class.gaoxiaobang.com/* // @match https://*.class.gaoxiaobang.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant unsafeWindow // @run-at document-idle // ==/UserScript== (function() { 'use strict'; const resetBtn = document.createElement('button'); resetBtn.innerText = '🔄 没反应?点我试试'; resetBtn.style.cssText = 'position:fixed;bottom:100px;right:20px;z-index:9999;background:#f44;color:#fff;border:none;padding:10px 15px;border-radius:5px;cursor:pointer;font-size:14px'; resetBtn.onclick = () => { GM_deleteValue('gb_auto_step'); GM_deleteValue('gb_processed_topics'); alert('状态已重置,刷新页面后脚本将重新运行。'); location.reload(); }; document.body.appendChild(resetBtn); const originalConsoleError = console.error; console.error = function(...args) { const msg = args.join(' '); if (msg.includes('JSON.parse error') || msg.includes('MEDIA_ERR_SRC_NOT_SUPPORTED') || msg.includes('Failed to load resource')) { return; } originalConsoleError.apply(console, args); }; const $ = unsafeWindow.$ || window.$; const wait = ms => new Promise(r => setTimeout(r, ms)); const STATE_KEY = 'gb_auto_step'; const PROCESSED_TOPICS_KEY = 'gb_processed_topics'; const isChapterPage = !!(unsafeWindow.classinfo?.classId && (unsafeWindow.unitList || unsafeWindow.chapterList)); const isDiscussPage = () => !!document.querySelector('a[content_type="Topic"]'); let discussRunning = false; function showCompletionNotice() { if (document.getElementById('gb-completion-notice')) return; const notice = document.createElement('div'); notice.id = 'gb-completion-notice'; const courseTitle = document.title || '当前课程'; notice.innerHTML = `
${content.replace(/\n/g, '
')}
`; body.dispatchEvent(new Event('input', { bubbles: true })); console.log(' ✅ 通过 iframe body 填入'); return true; } } catch(e) {} } return false; }, getLongestComment() { const texts = []; document.querySelectorAll('.reply-content').forEach(el => { const p = el.querySelector('p'); const text = p ? p.innerText.trim() : el.innerText.trim(); if (text) texts.push(text); }); if (!texts.length) { document.querySelectorAll('.reply-content-container .reply-content').forEach(el => { const p = el.querySelector('p'); const text = p ? p.innerText.trim() : el.innerText.trim(); if (text) texts.push(text); }); } return texts.length ? texts.reduce((a, b) => a.length > b.length ? a : b) : ''; }, hasSubmitted() { const editBtn = document.querySelector('i.post-submit-edit'); if (!editBtn) return false; return editBtn.offsetParent !== null && window.getComputedStyle(editBtn).display !== 'none'; }, findReplyBtn() { const candidates = document.querySelectorAll('i.post-submit, i, button, .btn'); for (let el of candidates) { const text = el.innerText.trim(); if ((text === '回复' || text.includes('回复')) && !text.includes('编辑')) { if (el.offsetParent !== null && window.getComputedStyle(el).display !== 'none') { return el; } } } return null; }, enableButton(btn) { if (!btn) return; btn.classList.remove('disabled', 'btn-disabled', 'ban-click'); btn.style.pointerEvents = 'auto'; btn.style.opacity = '1'; btn.disabled = false; } }; const getTopicChapters = () => { return Array.from(document.querySelectorAll('a[content_type="Topic"]')).map(a => ({ chapterId: a.getAttribute('chapter_id'), title: a.querySelector('.title')?.innerText?.trim() || a.innerText.trim() })); }; const switchToChapter = chapterId => { location.hash = location.hash.replace(/chapterId=\d+/, `chapterId=${chapterId}`); }; const topics = getTopicChapters(); if (!topics.length) { console.error('❌ 未找到任何专题,请检查页面'); discussRunning = false; return; } const processedIds = getProcessedTopicIds(); const remainingTopics = topics.filter(t => !processedIds.includes(t.chapterId)); console.log(`🎯 总共 ${topics.length} 个专题,已完成 ${processedIds.length} 个,剩余 ${remainingTopics.length} 个`); if (remainingTopics.length === 0) { console.log('%c🎉 所有专题已处理完毕!', 'color:green;font-size:16px'); clearProcessedTopics(); GM_setValue(STATE_KEY, 'completed'); discussRunning = false; return; } for (let i = 0; i < remainingTopics.length; i++) { const t = remainingTopics[i]; console.log(`\n📌 [${processedIds.length + i + 1}/${topics.length}] 处理专题: ${t.title}`); switchToChapter(t.chapterId); await wait(4000); if (Editor.hasSubmitted()) { console.warn(' ⏭️ 该专题已提交过,标记为已处理'); markTopicAsProcessed(t.chapterId); continue; } const comment = Editor.getLongestComment(); if (!comment) { console.warn(' ⚠️ 未找到可复制评论,跳过并标记'); markTopicAsProcessed(t.chapterId); continue; } console.log(` 📋 复制评论 (${comment.length}字)`); if (!Editor.setContent(comment)) { console.error(' ❌ 填充内容失败,跳过并标记'); markTopicAsProcessed(t.chapterId); continue; } console.log(' ✅ 内容已填入'); await wait(1000); const btn = Editor.findReplyBtn(); if (!btn) { console.warn(' ❌ 未找到“回复”按钮,跳过并标记'); markTopicAsProcessed(t.chapterId); continue; } Editor.enableButton(btn); console.log(` 🚀 点击提交: ${btn.innerText}`); btn.click(); markTopicAsProcessed(t.chapterId); console.log(` 💾 已标记专题 ${t.chapterId} 为已处理`); await wait(2000); } console.log('%c🎉🎉🎉 所有专题评论完成!刷新页面即可查看结果。 🎉🎉🎉', 'color:green;font-size:20px;background:#f0f0f0;padding:8px;border-radius:4px'); clearProcessedTopics(); GM_setValue(STATE_KEY, 'completed'); discussRunning = false; } // ========== 主控逻辑 ========== (async function main() { const step = GM_getValue(STATE_KEY, 'progress'); if (step === 'completed') { console.log('%c✅ 所有任务已完成,脚本停止运行。如需重新开始,请点击右下角红色按钮。', 'color:green;font-size:14px'); showCompletionNotice(); // 👈 新增:显示网页提示 return; } console.log(`🔍 状态: ${step} | 课程页: ${isChapterPage} | 讨论页: ${isDiscussPage()}`); if (isChapterPage) { if (step === 'discuss') { console.log('重置状态为进度模式'); GM_setValue(STATE_KEY, 'progress'); } await runProgress(); return; } if (isDiscussPage() && step === 'discuss') { if (!discussRunning) { await runDiscuss(); } return; } if (isDiscussPage() && step === 'progress') { console.log('已在讨论页,直接执行评论'); GM_setValue(STATE_KEY, 'discuss'); if (!discussRunning) { await runDiscuss(); } return; } if (step === 'discuss') { startPollingForDiscuss(); console.log('⏳ 等待进入讨论区...(将自动检测)'); } else { console.log('当前页面无需自动操作'); } })(); })();