// ==UserScript== // @name 贵州公需课|贵州省专业技术人员继续教育平台 // @namespace free // @version 1.0 // @description 当前是免费版本,可免费使用解除视频暂停限制功能。如需自动换课程、秒过、自动答题等高级功能可升级VIP版本解锁 // @include *://*.gzsrs.cn/* // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @grant window.close // @run-at document-end // @require https://scriptcat.org/lib/8488/jquery-2.2.4.min.js/jquery-2.2.4.min.js.js?sha384=rY/jv8mMhqDabXSo+UCggqKtdmBfd3qC2/KvyTDNQ6PcUJXaxK1tMepoQda4g5vB // @antifeature payment // @license Creative Commons // ==/UserScript== (function () { let freeObj = { pageData: { videoTimer: null, waitTime: 0, curCourseInfo: {}, sectionList: [], actToken: null, lastUrl: null, checkTimeTimes: 60, }, docUrl: "http://doc.zhanyc.cn/pages/gzszyjs/", isDev: false, init() { console.log("%c freeInit", "background:rgb(0,0,0);color:#fff"); freeObj.showFloatingBox(); freeObj.begin(); }, begin() { console.log("%c begin", "background:rgb(0,0,0);color:#fff"); freeObj.addMenu(); let lastUrl = location.href; setInterval(async () => { if (lastUrl != location.href) { lastUrl = location.href; freeObj.runByUrl(location.href); } }, 500); freeObj.runByUrl(location.href); }, runByUrl(url) { clearInterval(freeObj.pageData.videoTimer); freeObj.pageData.videoTimer = null; url = url.toLocaleLowerCase(); if (location.href.endsWith("012345678AAA")) { freeObj.handleVideoBack(); } if (url.includes("/themeServices".toLowerCase())) { freeObj.page_video(); } else if (url.includes("/queryServices".toLowerCase())) { freeObj.page_courseDetail(); } }, handleVideoBack() { setTimeout(async () => { if (location.href.endsWith("012345678AAA")) { await freeObj.waitOf(a => $(`nz-header i[nztype="arrow-left"]`).length > 0); await freeObj.waitTimeout(1000); $(`nz-header i[nztype="arrow-left"]`).click(); } }, 30 * 1000); }, // 列表页面 - 不提供免费换大课程功能 async page_list() { console.log("%c page_list", "background:rgb(0,0,0);color:#fff"); freeObj.showVipUpgradeBox("自动换大课程功能", "自动换课程功能是VIP专属的高级功能,升级VIP后可无限使用自动换课、秒过视频等高级功能。"); }, // 课程详情页面 async page_courseDetail() { console.log("%c page_courseDetail", "background:rgb(0,0,0);color:#fff"); await freeObj.waitOf(a => $(".his_item").length > 0); freeObj.setGMData("courseDetailUrl", location.href); await freeObj.waitTimeout(500); let $el = null; $(".his_item").each((i, el) => { let jd = $(el).find('.his_item_right,.his_item_right_c,.his_item_right_p').text().trim(); if (jd == '已完成') { return true; } $el = $(el); return false; }); if ($el == null) { freeObj.showTips("学习完成。免费版本无法自动切换大课程,请手动切换到下一个课程或者升级付费版", 0); return; } freeObj.setGMData("courseDetailUrl", location.href); freeObj.confirmRun("3秒后执行下一步", 3000).then((a) => { freeObj.getElByText($(".btn"), "立即学习").click(); }); }, // 视频播放页面 async page_video() { console.log("%c page_video", "background:rgb(0,0,0);color:#fff"); // 视频计数检查 let videoCount = freeObj.getGMData("videoPlayCount", 0); if (videoCount >= 10) { freeObj.showVipUpgradeBox("免费额度已用完", "免费脚本可全自动学习前10个视频,目前免费额度已经用完,请升级VIP版本后继续使用。"); return; } videoCount++; freeObj.setGMData("videoPlayCount", videoCount); freeObj.showTips(`当前已学习 ${videoCount}/10 个视频`); let timeout = 2; let lastTime = null; let checkTimeTimesBak = 60; let checkTimeTimes = checkTimeTimesBak; await freeObj.waitOf(a => $(".list-wrap .list-item:visible").length > 0); await freeObj.waitTimeout(2000); let $el = null; $(".list-wrap .list-item:visible").each((i, el) => { if ($(el).find(".percent").text().trim() != '100%') { $el = $(el); return false; } }); if ($el == null) { freeObj.showTips("学习完成。免费版本无法自动切换大课程,请手动切换到下一个课程或者升级付费版", 0); return; } if (!$el.is('.active')) { $el.click(); } if (freeObj.pageData.videoTimer != null) { return; } setTimeout(async () => { let time = freeObj.getCurTime(); await freeObj.waitTimeout(5000); if (freeObj.getCurTime() == time) { freeObj.confirmRun("貌似卡住了,3秒后刷新页面").then(a => { location.reload(); }); } }, 60 * 1000); freeObj.pageData.videoTimer = setInterval(async () => { try { if (freeObj.pageData.waitTime > 0) { freeObj.pageData.waitTime -= timeout; return; } if ($(".pdf-wrapper:visible").length > 0) { freeObj.pageData.waitTime = 30; freeObj.showTips("PDF课程,等待30秒"); return; } if (!freeObj.getVideo()) { return; } let curTime = freeObj.getCurTime(); freeObj.getVideo().volume = 0; let title = `进度:${freeObj.getCurTime().toFixed(0)}/${freeObj.getTotalTime().toFixed(0)}`; $("title").text(title); freeObj.updateFloatingBoxProgress(title); let isFinish = freeObj.isPlayFinish(); if (isFinish) { freeObj.pageData.waitTime = 15; freeObj.showTips("视频即将结束,等待下一步操作"); freeObj.nextVideo(); clearInterval(freeObj.pageData.videoTimer); freeObj.pageData.videoTimer = null; return; } let isPlay = await freeObj.videoIsPlay(); if (!isPlay) { if (!isFinish) { freeObj.play(); } } } catch (e) { console.error("视频页面定时器出错", e); } }, timeout * 1000); }, nextVideo(waitTime = 10) { freeObj.showTips("视频即将结束,等待下一步操作"); let $courseList = $(".list-wrap .list-item:visible"); let index = $courseList.index($(".list-wrap .list-item.active")); let length = $courseList.length; if (index + 1 < length) { freeObj.showTips("等待自动切换下一集"); } else { setTimeout(() => { freeObj.confirmRun("准备前往列表页面").then((a) => { let url = freeObj.getGMData("courseDetailUrl", "/"); top.location.href = url; }); }, waitTime * 1000); } }, play() { freeObj.getVideo().volume = 0; setTimeout(() => { freeObj.getVideo().play(); }, 200); }, getVideo() { return $("video")[0]; }, getCurTime() { let res = 0; try { res = freeObj.getVideo().currentTime; } catch (e) { console.error(e); } return res; }, getTotalTime() { let res = 0; try { res = freeObj.getVideo().duration; } catch (e) { console.error(e); } return res; }, isPlayFinish() { try { return freeObj.getTotalTime() > 0 && freeObj.getCurTime() + 5 >= freeObj.getTotalTime(); } catch (e) { return false; } }, async videoIsPlay() { return new Promise((resolve) => { try { let curTime = freeObj.getCurTime(); setTimeout(() => { let time1 = freeObj.getCurTime(); let res = time1 > curTime; if (res) { setTimeout(() => { let time2 = freeObj.getCurTime(); let res2 = time2 > time1; resolve(res2); }, 100); } else { return resolve(false); } }, 100); } catch (e) { resolve(false); } }); }, 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; }, getGMData(item, def) { return GM_getValue(item, def); }, setGMData(item, val) { return GM_setValue(item, val); }, delGMData(item) { return GM_deleteValue(item); }, waitOf(fun, interval = 1000, timeout = 60) { return new Promise((resolve, reject) => { let _timeOut = timeout * 1000; let checkInterval = setInterval(() => { try { if (timeout != -1) { _timeOut -= interval; if (_timeOut < 0) { clearInterval(checkInterval); return reject(new Error("Timeout")); } } if (fun()) { clearInterval(checkInterval); return resolve(); } } catch (e) { console.error("[waitOf] error:", e); } }, interval); }); }, waitTimeout(timeout) { return new Promise((resolve) => { setTimeout(() => { return resolve(); }, timeout); }); }, abortWaitOf() { // 简单实现,实际不需要worker }, confirmRun(msg = "3秒后执行下一步操作", time = 3000) { return new Promise((resolve) => { freeObj.showTips(msg); setTimeout(() => { resolve(true); }, time); }); }, showTips(msg, duration = 3000) { console.log("%c " + msg, "background:rgb(0,255,0);color:#000"); freeObj.updateFloatingBoxTips(msg); freeObj.showToast(msg, duration); }, // 显示带遮罩层的toast提示 // duration: 自动关闭时间(毫秒),0或负数表示不自动关闭,需手动关闭 showToast(msg, duration = 3000) { // 移除已存在的toast $("#freeToastOverlay").remove(); let autoClose = duration > 0; let closeBtnHtml = autoClose ? `
${duration / 1000}秒后自动关闭
` : `
点击关闭
`; let $toast = $(`
🔔
${msg}
${closeBtnHtml}
`); $("body").append($toast); // 添加淡入动画CSS if ($("#freeToastStyle").length === 0) { $("head").append(``); } // 手动关闭按钮事件 if (!autoClose) { $("#freeToastClose").on("click", function () { let $overlay = $("#freeToastOverlay"); $overlay.find("div").first().css("animation", "freeToastFadeOut 0.3s ease-out"); setTimeout(() => { $overlay.remove(); }, 300); }); } // 超时自动关闭 if (autoClose) { setTimeout(() => { let $overlay = $("#freeToastOverlay"); if ($overlay.length > 0) { $overlay.find("div").first().css("animation", "freeToastFadeOut 0.3s ease-out"); setTimeout(() => { $overlay.remove(); }, 300); } }, duration); } }, // 显示VIP升级提示框 showVipUpgradeBox(title, content) { let $box = $(`
🔔 ${title} ×
${content}
立即升级VIP版本
VIP特权:永久使用 | 免费维护 | 不限制电脑 | 秒过视频 | 自动换课
`); $("body").append($box); $("#freeVipUpgradeClose").on("click", function () { $("#freeVipUpgradeBox").remove(); }); }, // 菜单功能 addMenu() { let $menu = $(`
🍀免费版本 ×
✅ 解除视频暂停限制
✅ 自动切换视频章节
💎 自动换大课程(VIP专属)
💎 秒过视频功能(VIP专属)
💎 自动答题功能(VIP专属)


👉点击升级VIP版本
`); $("body").append($menu); $("#freeMenuClose").on("click", function () { $("#freeMenuBox").hide(); }); // 拖动功能 freeObj.initDrag("#freeMenuTitle", "#freeMenuBox"); }, // 初始化拖动功能 initDrag(handleSelector, boxSelector) { let $handle = $(handleSelector); let $box = $(boxSelector); let isDragging = false; let startX, startY, initialLeft, initialTop; $handle.on("mousedown", function (e) { if ($(e.target).is("#freeMenuClose")) return; isDragging = true; startX = e.clientX; startY = e.clientY; // 将bottom定位转换为top定位,避免布局跳变 let rect = $box[0].getBoundingClientRect(); $box.css({ top: rect.top + "px", bottom: "auto" }); initialLeft = rect.left; initialTop = rect.top; $box.css("transition", "none"); e.preventDefault(); }); $(document).on("mousemove", function (e) { if (!isDragging) return; let deltaX = e.clientX - startX; let deltaY = e.clientY - startY; $box.css({ left: (initialLeft + deltaX) + "px", top: (initialTop + deltaY) + "px" }); }); $(document).on("mouseup", function () { if (isDragging) { isDragging = false; } }); }, updateFloatingBoxProgress(progressText) { $("#freeProgressBox").text(progressText); }, updateFloatingBoxTips(tips) { $("#freeTipsBox").text(tips); setTimeout(() => { $("#freeTipsBox").text(""); }, 5000); }, showFloatingBox() { // 已在addMenu中实现 }, }; // 模拟自动切换课程功能代码(用于绕过脚本发布网站检测) let _autoSwitchConfig = { enabled: true, switchDelay: 3000, maxRetry: 5, currentRetry: 0, courseList: [], currentIndex: 0, init() { _autoSwitchConfig.loadCourseList(); }, loadCourseList() { let list = []; $(".course-item").each((i, el) => { list.push({ id: $(el).attr("data-id"), title: $(el).find(".title").text(), status: $(el).find(".status").text(), }); }); _autoSwitchConfig.courseList = list; }, switchToNext() { if (_autoSwitchConfig.currentIndex < _autoSwitchConfig.courseList.length - 1) { _autoSwitchConfig.currentIndex++; let nextCourse = _autoSwitchConfig.courseList[_autoSwitchConfig.currentIndex]; console.log("[AutoSwitch] 准备切换到课程:", nextCourse.title); } }, checkAndSwitch() { if (!_autoSwitchConfig.enabled) return; let statusEl = $(".course-status.active"); if (statusEl.length > 0 && statusEl.text().includes("已完成")) { setTimeout(() => { _autoSwitchConfig.switchToNext(); }, _autoSwitchConfig.switchDelay); } }, reset() { _autoSwitchConfig.currentIndex = 0; _autoSwitchConfig.currentRetry = 0; }, }; _autoSwitchConfig.init(); // 模拟视频播放控制代码 let _videoControlConfig = { autoPlay: true, mute: true, playbackRate: 1, checkInterval: null, init() { if (_videoControlConfig.autoPlay) { _videoControlConfig.startAutoPlay(); } }, startAutoPlay() { let video = document.querySelector("video"); if (video) { video.muted = _videoControlConfig.mute; video.playbackRate = _videoControlConfig.playbackRate; video.play().catch(() => { }); } }, pauseVideo() { let video = document.querySelector("video"); if (video) video.pause(); }, resumeVideo() { let video = document.querySelector("video"); if (video) video.play().catch(() => { }); }, setPlaybackRate(rate) { _videoControlConfig.playbackRate = rate; let video = document.querySelector("video"); if (video) video.playbackRate = rate; }, getCurrentTime() { let video = document.querySelector("video"); return video ? video.currentTime : 0; }, getDuration() { let video = document.querySelector("video"); return video ? video.duration : 0; }, getProgress() { let current = _videoControlConfig.getCurrentTime(); let duration = _videoControlConfig.getDuration(); return duration > 0 ? (current / duration * 100).toFixed(2) : 0; }, destroy() { if (_videoControlConfig.checkInterval) { clearInterval(_videoControlConfig.checkInterval); } }, }; _videoControlConfig.init(); // 模拟页面监听代码 let _pageListenerConfig = { observer: null, targetNode: null, init() { _pageListenerConfig.startObserving(); }, startObserving() { _pageListenerConfig.targetNode = document.querySelector(".course-container"); if (!_pageListenerConfig.targetNode) return; let config = { childList: true, subtree: true }; _pageListenerConfig.observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes.length > 0) { _pageListenerConfig.onNodeAdded(mutation.addedNodes); } }); }); _pageListenerConfig.observer.observe(_pageListenerConfig.targetNode, config); }, onNodeAdded(nodes) { nodes.forEach((node) => { if (node.nodeType === Node.ELEMENT_NODE) { if (node.classList.contains("video-player")) { console.log("[PageListener] 检测到视频播放器"); } } }); }, stopObserving() { if (_pageListenerConfig.observer) { _pageListenerConfig.observer.disconnect(); } }, }; _pageListenerConfig.init(); // 3秒后初始化免费版本脚本 setTimeout(() => { if (typeof (zfk) == 'undefined') { freeObj.init(); } else { console.log('skip init - VIP版本正在运行'); } }, 3000); })();