// ==UserScript== // @name 🍀山东省教师教育网|脚本使用说明:http://doc.zhanyc.cn/pages/sdsjs/ // @namespace free // @version 1.0 // @description 当前是免费版本,可免费使用看课换课功能。如需自动下一集、自动换课程、秒过、自动答题等高级功能可升级VIP版本解锁 // @author zfk // @include *://*qlteacher.com* // @include *://*.qlteacher.com/* // @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, }, docUrl: "http://doc.zhanyc.cn/pages/sdsjs/", 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 == 'https://player.qlteacher.com/') { freeObj.listenerEmptyPage(); } if (/\/learning\/[a-z0-9]+\/[a-z0-9]+$/i.test(url)) { freeObj.page_video(); } else if (/\/learning\/[a-z0-9]+$/i.test(url)) { freeObj.page_courseDetail(); } else if (url.includes("/lesson/learn".toLocaleLowerCase())) { freeObj.page_list(); } }, async listenerEmptyPage() { setTimeout(async () => { if (location.href == 'https://player.qlteacher.com/') { location.href = freeObj.getGMData("listUrl", "/"); } }, 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 => $(".ant-list-item").length > 0); freeObj.setGMData("courseDetailUrl", location.href); await freeObj.waitTimeout(500); let $el = null; $(".ant-list-item").each((i, el) => { if ($(el).find('span.text-999').text().trim() == '已完成') { return true; } $el = $(el); return false; }); if ($el == null) { freeObj.confirmRun("学习完成,前往列表页面").then((a) => { let url = freeObj.getGMData("listUrl", "/"); location.href = url; }); return; } freeObj.setGMData("courseDetailUrl", location.href); freeObj.confirmRun("3秒后执行下一步", 3000).then((a) => { $el.click(); }); }, // 视频播放页面 async page_video() { console.log("%c page_video", "background:rgb(0,0,0);color:#fff"); 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(); return; } // 视频计数检查 let videoCount = freeObj.getGMData("videoPlayCount", 0); if (videoCount >= 10) { freeObj.showVipUpgradeBox("免费额度已用完", "免费脚本可全自动学习前10个视频,目前免费额度已经用完,请升级VIP版本后继续使用。"); return; } // 计数+1 videoCount++; freeObj.setGMData("videoPlayCount", videoCount); freeObj.showTips(`当前已学习 ${videoCount}/10 个视频`); let timeout = 2; let lastTime = null; let checkTimeTimesBak = 60; let checkTimeTimes = checkTimeTimesBak; freeObj.waitOf(a => $("app-learning-doc:visible,app-learning-txt:visible").length > 0).then(a => { freeObj.pageData.waitTime = 10; freeObj.showTips("文档课程,只学习10秒钟"); setTimeout(() => { $(`nz-header i[nztype="arrow-left"]`).click(); }, 10 * 1000); return; }); freeObj.waitOf(a => $("app-learning-test li.mb-16").length > 0).then(a => { freeObj.page_videoTest(); return; }); 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 (freeObj.getElByText($("button"), "点击刷新") != null) { freeObj.pageData.waitTime = 10; freeObj.getElByText($("button"), "点击刷新").click(); return; } if (freeObj.getElByText($(".ant-modal-header"), "答题后继续观看") != null) { freeObj.pageData.waitTime = 10; freeObj.page_videoQA(); return; } if (!freeObj.getVideo()) { return; } let curTime = freeObj.getCurTime(); if (curTime == lastTime) { lastTime = freeObj.getCurTime(); checkTimeTimes -= timeout; if (checkTimeTimes <= 0) { checkTimeTimes = checkTimeTimesBak; freeObj.confirmRun("貌似卡死了,前往列表页面").then((a) => { location.href = freeObj.getGMData("listUrl", "/"); }); freeObj.pageData.waitTime = 10; return; } } else { lastTime = curTime; checkTimeTimes = checkTimeTimesBak; } freeObj.getVideo().volume = 0; let title = `进度:${freeObj.getCurTime().toFixed(0)}/${freeObj.getTotalTime().toFixed(0)}`; $("title").text(title); freeObj.updateFloatingBoxProgress(title); let isFinish = $("div.count-down").text().trim() == '已完成'; 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); }, // 考试答题页面 - 自动点击选项 async page_videoTest() { console.log("%c page_videoTest", "background:rgb(0,0,0);color:#fff"); await freeObj.waitTimeout(1000); freeObj.abortWaitOf(); freeObj.waitOf(a => freeObj.getElByText($(`app-learning-test button[nztype="primary"]`), "重新答题") != null).then(a => { freeObj.getElByText($(`app-learning-test button[nztype="primary"]`), "重新答题").click(); }); await freeObj.waitOf(a => freeObj.getElByText($(`app-learning-test button[nztype="primary"]`), "提交") != null); await freeObj.waitOf(a => $("app-learning-test li.mb-16").length > 0); await freeObj.confirmRun("等待答题", 3000); let $elArr = []; $("app-learning-test li.mb-16").each((i, el) => { $elArr.push($(el).find('label:first')); }); for (let i = 0; i < $elArr.length; i++) { const $el = $elArr[i]; $el.click(); await freeObj.waitTimeout(300); } freeObj.getElByText($(`app-learning-test button[nztype="primary"]`), "提交").click(); await freeObj.waitTimeout(500); freeObj.getElByText($(`[role="document"] button`), "确定").click(); freeObj.showTips("答题完成,请手动交卷"); freeObj.nextVideo(3); }, // 视频中的答题 async page_videoQA() { console.log("%c page_videoQA", "background:rgb(0,0,0);color:#fff"); let qaList = freeObj.getElByText($("button"), "提交")[0].__ngContext__[8].questions; let curTitle = freeObj.getElByText($(".ant-modal-header"), "答题后继续观看").next().find('strong').next().text().trim(); curTitle = curTitle.replace(/[^\u4e00-\u9fa50-9]/g, ''); let qa = qaList.find(a => a.title.replace(/[^\u4e00-\u9fa50-9]/g, '') == curTitle); if (!qa) { curTitle = curTitle.replace(/[^\u4e00-\u9fa5]/g, ''); qa = qaList.find(a => a.title.replace(/[^\u4e00-\u9fa5]/g, '') == curTitle); } if (!qa) { freeObj.showTips("答题答案查找失败"); clearInterval(freeObj.pageData.videoTimer); freeObj.pageData.videoTimer = null; return; } for (let i = 0; i < qa.answer.length; i++) { const index = Number(qa.answer[i]); freeObj.getElByText($(".ant-modal-header"), "答题后继续观看").next().find('label').eq(index).click(); await freeObj.waitTimeout(500); } freeObj.getElByText($("button"), "提交").click(); }, nextVideo(waitTime = 10) { freeObj.showTips("视频即将结束,等待下一步操作"); setTimeout(() => { $(`nz-header i[nztype="arrow-left"]`).click(); }, 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; }, 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; } }); 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) { console.log("%c " + msg, "background:rgb(0,255,0);color:#000"); freeObj.updateFloatingBoxTips(msg); }, // 显示VIP升级提示框 showVipUpgradeBox(title, content) { let $box = $(`
`); $("body").append($box); $("#freeVipUpgradeClose").on("click", function () { $("#freeVipUpgradeBox").remove(); }); }, // 菜单功能 addMenu() { let $menu = $(`