// ==UserScript== // @name 【免费】贵州省人才大市场专业技术人员继续教育基地|如需自动下一集、自动换课程、秒过等高级功能见收费版本:http://doc.zhanyc.cn/pages/gzsrcdsc/ // @namespace free // @version 1.0 // @description 当前是免费版本,包含了视频页面自动播放、解除播放暂停限制、考试全部选A功能。如需自动下一集、自动换课程、秒过、全自动无人值守高级功能可升级付费版本|接各类脚本开发、代挂工作,微信:zhanyc_cn 个人网站:http://doc.zhanyc.cn // @author zfk // @include *://*gzjxjy.org.cn* // @include *://*.gzjxjy.org.cn/* // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // @grant GM_deleteValue // @grant GM_registerMenuCommand // @run-at document-end // @require http://libs.baidu.com/jquery/2.0.0/jquery.min.js // @license Creative Commons // ==/UserScript== (function () { let $jq = $; unsafeWindow.$jq = $; let docUrl = "http://doc.zhanyc.cn/pages/gzsrcdsc/"; let free = { pageData: { video: { index: null }, waitOfIndexArr: [] }, async init() { console.log("%c 【免费版】init", "background:rgb(0,0,0);color:#fff"); free.addStyle(); free.createFloatingPanel(); free.registerMenuCommand(); if (location.href.includes("/course/detail/")) { free.page_video(); } free.autoExam(); let lastUrl = location.href; setInterval(() => { if (lastUrl != location.href) { lastUrl = location.href; free.onUrlChange(location.href); } }, 500); }, onUrlChange(url) { clearInterval(free.pageData.video.index); free.pageData.video.index = null; if (url.includes("/course/detail/")) { free.page_video(); } else { free.autoExam(); } }, // ====== 悬浮面板 ====== createFloatingPanel() { if ($("#freeFloatingPanel").length > 0) return; let html = `
脚本运行中
💡
温馨提示:考试全部选A就能及格😂
视频功能:
等待检测页面...
如需使用全功能版本(自动下一集、自动换课程、秒过、全自动无人值守),请通过下方地址安装付费版本购买授权后可使用
接各类脚本开发、代挂、网站小程序开发工作,微信:zhanyc_cn
`; $("body").append(html); // 可拖拽 free.dragPanel(); }, dragPanel() { let panel = $("#freeFloatingPanel")[0]; let header = panel.querySelector(".free-panel-header"); let isDragging = false, startX, startY, origX, origY; header.addEventListener("mousedown", function (e) { isDragging = true; let rect = panel.getBoundingClientRect(); startX = e.clientX; startY = e.clientY; origX = rect.left; origY = rect.top; panel.style.left = origX + "px"; panel.style.top = origY + "px"; panel.style.right = "auto"; panel.style.bottom = "auto"; document.addEventListener("mousemove", onMouseMove); document.addEventListener("mouseup", onMouseUp); e.preventDefault(); }); function onMouseMove(e) { if (!isDragging) return; panel.style.left = (origX + e.clientX - startX) + "px"; panel.style.top = (origY + e.clientY - startY) + "px"; } function onMouseUp() { isDragging = false; document.removeEventListener("mousemove", onMouseMove); document.removeEventListener("mouseup", onMouseUp); } }, closePanel() { $("#freeFloatingPanel").remove(); }, updateVideoStatus(status, progressText) { let $status = $("#freeVideoStatus"); let $progress = $("#freeVideoProgress"); let $progressText = $("#freeProgressText"); if (status === "running") { $status.text("运行中").removeClass("free-status-waiting free-status-done").addClass("free-status-running"); $progress.show(); if (progressText) $progressText.text(progressText); } else if (status === "done") { $status.text("已完成").removeClass("free-status-waiting free-status-running").addClass("free-status-done"); $progress.hide(); } else { $status.text(status || "等待中...").removeClass("free-status-running free-status-done").addClass("free-status-waiting"); $progress.hide(); } }, updateExamStatus(status, msg) { $("#freeExamInfo").show(); let $status = $("#freeExamStatus"); if (status === "done") { $status.text(msg || "已完成,请手动交卷").removeClass("free-status-waiting free-status-running").addClass("free-status-done"); } else if (status === "running") { $status.text(msg || "执行中...").removeClass("free-status-waiting free-status-done").addClass("free-status-running"); } else { $status.text(msg || "等待检测...").removeClass("free-status-running free-status-done").addClass("free-status-waiting"); } }, // ====== 视频自动播放 ====== async page_video() { console.log("%c 【免费版】page_video", "background:rgb(0,0,0);color:#fff"); if (free.pageData.video.index != null) return; // 点击"进入学习模式" free.waitOf(() => free.getElByText($("button"), "进入学习模式") != null).then(() => { free.getElByText($("button"), "进入学习模式").click(); }); free.pageData.video.index = setInterval(async () => { try { if (!free.getVideo()) { console.log("%c no video", "background:rgb(0,0,0);color:#fff"); return; } let curTime = free.getCurTime(); let totalTime = free.getTotalTime(); let progressText = `${Math.floor(curTime)}/${Math.floor(totalTime)}秒`; free.getVideo().volume = 0; $("title").text(`进度:${progressText}`); free.updateVideoStatus("running", progressText); let isFinish = free.isPlayFinish(); if (isFinish) { free.updateVideoStatus("done"); return; } let isPlay = await free.videoIsPlay(); if (!isPlay && !isFinish) { free.play(); } } catch (e) { console.error("视频页面定时器出错", e); } }, 2000); }, play() { try { free.getVideo().volume = 0; setTimeout(() => { free.getVideo().play(); }, 200); } catch (e) { console.error(e); } }, getVideo() { return $("video")[0]; }, getCurTime() { try { return free.getVideo().currentTime; } catch (e) { return 0; } }, getTotalTime() { try { return free.getVideo().duration; } catch (e) { return 0; } }, isPlayFinish() { try { return free.getTotalTime() > 0 && free.getCurTime() + 5 >= free.getTotalTime(); } catch (e) { return false; } }, async videoIsPlay() { return new Promise((resolve) => { try { let curTime = free.getCurTime(); setTimeout(() => { let time1 = free.getCurTime(); if (time1 > curTime) { setTimeout(() => { let time2 = free.getCurTime(); resolve(time2 > time1); }, 100); } else { resolve(false); } }, 100); } catch (e) { resolve(false); } }); }, // ====== 考试全部选A ====== async autoExam() { console.log("%c 【免费版】autoExam", "background:rgb(0,0,0);color:#fff"); // 先检测页面是否有考试题目 let examDetected = await free.waitOf(() => $(".exam-question").length > 0, 1000, 15).catch(() => false); if (!examDetected) return; free.updateExamStatus("running", "正在全部选A..."); await free.waitTimeout(500); await free.examSelectAllA(); free.updateExamStatus("done"); }, async examSelectAllA() { let $elArr = []; $(".exam-question").each((i, el) => { $elArr.push($(el).find('label').eq(0)); }); for (let i = 0; i < $elArr.length; i++) { const $el = $elArr[i]; $el.click(); await free.waitTimeout(100); } }, // ====== 菜单命令 ====== registerMenuCommand() { GM_registerMenuCommand("答题:全部选A", free.examSelectAllA); GM_registerMenuCommand("使用说明", () => window.open(docUrl)); }, // ====== 样式 ====== addStyle() { GM_addStyle(` #freeFloatingPanel { position: fixed; left: 10px; top: 10px; z-index: 2147483647; width: 300px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.3); color: #fff; font-size: 13px; line-height: 1.6; user-select: none; overflow: hidden; } #freeFloatingPanel .free-panel-header { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; background: rgba(0,0,0,0.2); cursor: move; font-weight: bold; font-size: 14px; } #freeFloatingPanel .free-panel-close { background: none; border: none; color: #fff; font-size: 22px; cursor: pointer; padding: 0 4px; line-height: 1; opacity: 0.8; } #freeFloatingPanel .free-panel-close:hover { opacity: 1; } #freeFloatingPanel .free-panel-body { padding: 10px 12px 12px; } #freeFloatingPanel .free-tips { display: flex; align-items: center; background: rgba(255,255,255,0.15); border-radius: 6px; padding: 8px 10px; margin-bottom: 6px; border: 1px solid rgba(255,255,255,0.2); } #freeFloatingPanel .free-tips-icon { font-size: 20px; margin-right: 6px; flex-shrink: 0; } #freeFloatingPanel .free-tips-text { font-size: 14px; font-weight: bold; color: #ffeb3b; } #freeFloatingPanel .free-divider { height: 1px; background: rgba(255,255,255,0.2); margin: 8px 0; } #freeFloatingPanel .free-status-section { padding: 4px 0; } #freeFloatingPanel .free-status-label { font-weight: bold; font-size: 13px; margin-bottom: 2px; } #freeFloatingPanel .free-status-value { display: inline-block; padding: 1px 8px; border-radius: 3px; font-size: 12px; font-weight: bold; } #freeFloatingPanel .free-status-waiting { background: #f39c12; color: #fff; } #freeFloatingPanel .free-status-running { background: #27ae60; color: #fff; animation: freePulse 1s infinite; } #freeFloatingPanel .free-status-done { background: #2980b9; color: #fff; } @keyframes freePulse { 0% { opacity: 1; } 50% { opacity: 0.7; } 100% { opacity: 1; } } #freeFloatingPanel .free-video-progress { margin-top: 4px; font-size: 12px; color: #a8e6cf; } #freeFloatingPanel .free-msg { font-size: 12px; opacity: 0.9; } #freeFloatingPanel .free-link { margin-top: 4px; color: #ffeb3b; text-decoration: underline; cursor: pointer; word-break: break-all; font-size: 12px; } #freeFloatingPanel .free-link:hover { color: #fff; } #freeFloatingPanel .free-contact { font-size: 12px; opacity: 0.85; padding: 2px 0; } `); }, // ====== 工具函数 ====== waitOf(fun, interval = 1000, timeout = 30) { return new Promise((resolve, reject) => { let _timeOut = timeout * 1000; try { if (fun()) return resolve(); } catch (e) { } let index = setInterval(() => { try { if (timeout != -1) { _timeOut -= interval; if (_timeOut < 0) { clearInterval(index); return reject(new Error("Timeout")); } } if (fun()) { clearInterval(index); return resolve(); } } catch (e) { } }, interval); free.pageData.waitOfIndexArr.push(index); }); }, waitTimeout(timeout) { return new Promise((resolve) => { setTimeout(resolve, timeout); }); }, getElByText(query, text, mode = "eq", visible = true) { let $el = null; text = text.trim(); $(query).each((i, el) => { if (visible && !$(el).is(":visible")) return true; if (mode == "eq" && $(el).text().trim() == text) { $el = $(el); return false; } else if (mode == "startsWith" && $(el).text().trim().startsWith(text)) { $el = $(el); return false; } else if (mode == "endsWith" && $(el).text().trim().endsWith(text)) { $el = $(el); return false; } else if (mode == "like" && $(el).text().trim().includes(text)) { $el = $(el); return false; } }); return $el; } }; free.init(); unsafeWindow.free = free; })();