// ==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 ? `