Greasy Fork is available in English.
自动签到,自动统计未完成作业、未完成任务等、提前解锁章节,查看章节统计。我是热#学习的好孩子,(配合超星网课助手可自动观看课程、自动完成作业等)
// ==UserScript==// @name 超星网课挂科模式// @namespace https://userscript.snomiao.com// @version 0.2// @description 自动签到,自动统计未完成作业、未完成任务等、提前解锁章节,查看章节统计。我是热#学习的好孩子,(配合超星网课助手可自动观看课程、自动完成作业等)// @author [email protected]// @match *://*.chaoxing.com/*// @match *://mobilelearn.chaoxing.com/*// @match *://mooc1-1.chaoxing.com/*// @match *://i.mooc.chaoxing.com/*// @grant GM_setValue// @grant GM_getValue// @grant GM_addValueChangeListener// ==/UserScript==// 课程列表// http://mooc1-1.chaoxing.com/visit/interaction////// 开发中/////////////////////////////////// 防多开// var genId = '' + Math.random()///////////////////////////////// 异步组件var 睡 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));var 异步防抖函数 = (异步函数, 间隔时间 = 1000) => {var 上次执行时间 = null;return async (...参列) => {if (上次执行时间 != null && 上次执行时间 + 间隔时间 >= +new Date())return null;上次执行时间 = +new Date();return await 异步函数(参列);};};// 对象操作var 深合并 = (t, s) =>(t instanceof Object &&([...Object.keys(s)].forEach((k) => (t[k] = 深合并(t[k], s[k]))), t)) ||(undefined === s && t) ||s;var 键值对列转对象 = (键值对列) =>键值对列.reduce((a, b) => ((a[b[0]] = b[1]), a), {});var 全部提取 = (str, reg) => {if (!reg.global) return null;var coll = [];while (((e) => e && coll.push(e))(reg.exec(str)));return coll;};var 提取为表 = (html, 正则表达式, 键值对函数) => ({...键值对列转对象(全部提取(html, 正则表达式).map(键值对函数)),});///////////////////////////////// FETCHvar GETHTML = async (url) => await (await fetch(url)).text();// 存储var 加载状态 = () => {try {var r = JSON.parse(GM_getValue("超星网课挂科模式"));} catch (e) {}console.log("加载状态", r);return r || {};};var 保存状态 = (json = {}) => {GM_setValue("超星网课挂科模式", JSON.stringify(json));};var 更新状态 = (函数) => 保存状态(函数(加载状态()));var 合并状态 = (函数) => {var 状态 = 加载状态();保存状态(深合并(状态, 函数(状态)));};///////////////////////////////// 更新状态// 课程列表var 取课程表地址 = () => `http://mooc1-1.chaoxing.com/visit/interaction`;var 更新课程表 = (html) =>合并状态((状态) => ({课程表: 提取为表(html,/<a .*?courseId=(\d+).*?clazzid=(\d+).*?title="(.*?)"[\s\S]*?<p title="(.*?)">/g,([_, courseId, clazzid, title, 教师]) => [clazzid,{ courseId, classId: clazzid, title, 教师 },]),}));// 作业列表var 取作业表地址 = ({classId,courseId,isdisplaytable,mooc,ut,enc,cpi,openc,}) =>`https://mooc1-1.chaoxing.com/work/getAllWork?classId=${classId}&courseId=${courseId}&isdisplaytable=${isdisplaytable}&mooc=${mooc}&ut=${ut}&enc=${enc}&cpi=${cpi}&openc=${openc}`;var 更新作业表 = (html) =>合并状态((状态) => ({课程表: 提取为表(html, /id="cid" value="(\d+)"/g, ([_, classId]) => [classId,{ t检查作业表: +new Date() },]),作业表: 提取为表(html,/<a.*?href="(.*?courseId=(\d+).*?classId=(\d+).*?workId=(\d+)(?:.*?workAnswerId=(\d+))?.*?)".*?title="(.*?)"[\s\S]*?开始时间.*>(.*?)<[\s\S]*?截止时间.*?>(.*?)<[\s\S]*?作业状态[\s\S]*?<strong>\s*(.*?)\s*?</g,([_,url,courseId,classId,workId,workAnswerId,title,开始时间,截止时间,作业状态,]) => [workId,{url,courseId,classId,workId,workAnswerId,title,开始时间,截止时间,作业状态,},]),}));// 签到列表var 取签到表地址 = ({ courseId, classId }) =>`https://mobilelearn.chaoxing.com/widget/pcpick/stu/index?courseId=${courseId}&jclassId=${classId}`;var 更新签到表 = (html) => {var 课程表 = 提取为表(html,/id="puid" value="(.*?)"[\s\S]*?id="courseId" value="(.*?)"[\s\S]*?id="classId" value="(.*?)"[\s\S]*?id="fid" value="(.*?)"[\s\S]*?id="activeId" value="(.*?)"[\s\S]*?id="appType" value="(.*?)"/g,([_, puid, courseId, classId, fid, activeId, appType]) => [classId,{puid,courseId,classId,fid,activeId,appType,t更新签到表: +new Date(),},]);var { puid, courseId, classId, fid, activeId, appType } =Object.values(课程表)[0];合并状态((状态) => ({课程表,签到表: 提取为表(html,/activeDetail\((\d+),2,null\)[\s\S]*?<dd class="green">(.*?)<[\s\S]*?<a.*?>(.*?)</g,([_, activeId, type, title]) => [activeId,{activeId,type,title,puid,courseId,classId,fid,activeId,appType,},]),}));};// 更新签到状态// 普通签到var 取普通签到地址 = ({ activeId, classId, fid = "", courseId }) =>`https://mobilelearn.chaoxing.com/widget/sign/pcStuSignController/preSign?activeId=${activeId}&classId=${classId}&fid=${fid}&courseId=${courseId}`;// 手势签到var 取手势签到地址 = ({ courseId, classId, activeId }) =>`https://mobilelearn.chaoxing.com/widget/sign/pcStuSignController/signIn?&courseId=${courseId}&classId=${classId}&activeId=${activeId}`;var 更新签到状态 = (html) =>合并状态((状态) => ({签到表: 提取为表(html,/id="activeId".*?"(.*?)"[\s\S]*?id="activeStatus".*?"(.*?)"[\s\S]*?id="courseId".*?"(.*?)"[\s\S]*?id="classId".*?"(.*?)"[\s\S]*?id="puid".*?"(.*?)"[\s\S]*?id="createUid".*?"(.*?)"[\s\S]*?id="fid".*?"(.*?)"[\s\S]*?<span.*?>(.*?)<\/span><em id="st">(.*?)</g,([_,activeId,activeStatus,courseId,classId,puid,createUid,fid,statusText,succTimeRaw,]) => [activeId,{activeId,activeStatus,courseId,classId,puid,createUid,fid,statusText,succTimeRaw,t签到成功: +new Date(),},]),}));// 二维码、位置、拍照签到// https://mobilelearn.chaoxing.com/pptSign/stuSignajaxvar 更新签到状态2 = (html, href) =>合并状态((状态) => ({签到表: 提取为表(html + "~" + href,/(.*?)~.*?activeId=(\d+)/g,([_, status, activeId]) => [activeId,{ activeId, status, t签到成功: +new Date() },]),}));// 更新课程状态var 取课程首页地址 = () =>`https://mooc1-1.chaoxing.com/mycourse/studentcourse?courseId=${courseId}&clazzid=${clazzid}&vc=${vc}&cpi=${cpi}&enc=${enc}`;var 更新课程首页 = (html) =>合并状态((状态) => ({课程表: 提取为表(html,/id="cid" value="(\d+)"[\s\S]*?(?:(待完成任务点))?/g,([_, activeId, 待完成任务点]) => [activeId,{ 待完成状态: !!待完成任务点, t完成状态: +new Date() },]),}));var 更新当前页面状态 = () => {if (location.pathname == "/visit/interaction")更新课程表(document.body.innerHTML, location.href);if (location.pathname == "/mycourse/studentcourse")更新课程首页(document.body.innerHTML, location.href);//if (location.pathname == "/work/getAllWork")更新作业表(document.body.innerHTML, location.href);//if (location.pathname == "/widget/pcpick/stu/index")更新签到表(document.body.innerHTML, location.href);if (location.pathname == "/widget/sign/pcStuSignController/preSign")更新签到状态(document.body.innerHTML, location.href);if (location.pathname == "/widget/sign/pcStuSignController/signIn")更新签到状态(document.body.innerHTML, location.href);if (location.pathname == "/pptSign/stuSignajax")更新签到状态2(document.body.innerHTML, location.href);};var 自动签到 = async () => {var 状态 = 加载状态();// 4分半钟检查一次签到var 未知签到课程列 = [...Object.values(状态.课程表 || {})].filter((课程) => (课程.t检查签到表 || 课程.t更新签到表 || 0) + 270e3 <= +new Date());合并状态(() => ({课程表: 键值对列转对象(未知签到课程列.map(({ classId }) => [classId,{ t检查签到表: +new Date() },])),}));var 课程;while ((课程 = 未知签到课程列.shift())) {const 地址 = 取签到表地址(课程);console.debug("正在检查签到列表", 课程, 地址);更新签到表(await GETHTML(地址));await 睡(3e3);}// 5 秒尝试一次签到var 未完成签到列 = [...Object.values(状态.签到表 || {})].filter((签到) => (签到.t尝试签到 || 0) + 5e3 <= +new Date()).filter((签到) => !(签到.succTime || 签到.succTimeRaw || 签到.t签到成功));合并状态(() => ({签到表: 键值对列转对象(未完成签到列.map(({ activeId }) => [activeId, { t尝试签到: +new Date() }])),}));var 签到;while ((签到 = 未完成签到列.shift())) {let 地址;if (签到.title.match("手势")) {地址 = 取手势签到地址(签到);} else {地址 = 取普通签到地址(签到);}console.debug("正在签到", 签到, 地址);// window.open(地址 + "#自动关闭")更新签到状态(await GETHTML(地址));await 睡(3e3);}};///////////////////////////////////////////////////////////////var main = async () => {更新当前页面状态();var 状态 = 加载状态();var 未完成作业 = [...Object.values(状态.作业表)].filter((e) => e.作业状态 != "已完成");if (location.hostname == "mobilelearn.chaoxing.com" &&decodeURI(location.hash) == "#巡逻自动签到") {console.log("[超星网课挂科模式] 启动巡逻自动签到");var 间隔自动签到 = 异步防抖函数(自动签到, 270e3); // 最快四分半钟检查一次签到setInterval(async () => {document.body.innerHTML = new Date(+new Date()) + "#自动签到运行中...";if (null !== (await 间隔自动签到())) {console.log(new Date(), "4分半钟后重新运行");}}, 1e3);}if (decodeURI(location.hash) == "#自动签到") {var iframe = document.createElement("iframe");iframe.src = "https://mobilelearn.chaoxing.com/";document.body.appendChild(a);}if (decodeURI(location.hash) == "#自动巡逻") {console.log("3分钟后重新运行");setTimeout(main, 180e3);}if (decodeURI(location.hash) == "#自动关闭") {window.close();}};window.addEventListener("load", main);