Před instalací, Greasy Fork chce abyste věděli, že tento skript obsahuje "antifunkce", což jsou věci, které spíše přispívají autorovi skriptu, než vám.
Tento skript přidává reklamy na vámi navštěvované stránky.
超星全自动刷课,支持章节、作业、考试等多项任务点。
// ==UserScript== // @name 🦁超星学习通AIIT全自动小助手🐑🐑 // @namespace http://tampermonkey.net/ // @version 1.1.1 // @description 超星全自动刷课,支持章节、作业、考试等多项任务点。 // @author 阿宽 // @run-at document-end // @match *://*.chaoxing.com/* // @match *://*.edu.cn/* // @match *://*.nbdlib.cn/* // @match *://*.hnsyu.net/* // @connect 121.62.16.77 // @connect cx.icodef.com // @connect sso.chaoxing.com // @connect mooc1-api.chaoxing.com // @connect mooc1-1.chaoxing.com // @connect mooc1-2.chaoxing.com // @connect mooc1.chaoxing.com // @connect fystat-ans.chaoxing.com // @grant unsafeWindow // @grant GM_info // @grant GM_getResourceText // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @antifeature ads // @require https://greasyfork.org/scripts/455606-layx-js/code/layxjs.js?version=1122546 // @require https://lib.baomitu.com/jquery/3.6.0/jquery.min.js // @require https://cdn.jsdelivr.net/gh/photopea/Typr.js@15aa12ffa6cf39e8788562ea4af65b42317375fb/src/Typr.min.js // @require https://cdn.jsdelivr.net/gh/photopea/Typr.js@f4fcdeb8014edc75ab7296bd85ac9cde8cb30489/src/Typr.U.min.js // @require https://cdn.bootcdn.net/ajax/libs/blueimp-md5/2.18.0/js/md5.min.js // @resource layxcss https://greasyfork.org/scripts/455605-layx/code/layx.user.css // @resource ttf https://www.forestpolice.org/ttf/2.0/table.json // ==/UserScript== // 默认配置 var defaultConfig = { // 默认请求头 ua: 'Dalvik/2.1.0 (Linux; U; Android 12; M2102K1AC Build/SKQ1.211006.001) (schild:1b39227c6f3c3b7d95c59ad476567cdb) (device:M2102K1AC) Language/zh_CN com.chaoxing.mobile/ChaoXingStudy_3_6.1.0_android_phone_906_100 (@Kalimdor)_cc0454aaa3b7439daf7cebe7e43f62ba', // 公共间隔 interval: 3000, // 答案模糊匹配率。0-1之间,越大越严格 matchRate: 0.8, // 答案正确率,满足此正确率则提交,否则自动提交失效 autoSubmitRate: 0.9, // 是否开启自动提交 autoSubmit: true, // 是否开启自动答题 autoAnswer: true, // api接口 api:'http://121.62.16.77:996/', // 是否开启自动播放视频 autoPlayVideo: true, // 是否开启调试模式(正常用户不用理会这个参数) debugger: true, script_info : GM_info.script, },_self = unsafeWindow,top = _self; function log(msg) { if (defaultConfig.debugger) { console.log(msg); } } (function () { 'use strict'; // 工具类 var utils = { // 通知消息 notify: function (level, msg) { let data={ level: level, msg: msg } return JSON.stringify(data); }, // 章节递归排序 sortData: function (data) { let arr = []; data.forEach(item=>{ if(item.parentnodeid == 0){ arr.push(item); }else{ data.forEach(item2=>{ if(item2.id == item.parentnodeid){ if(item2.children){ item2.children.push(item); }else{ item2.children = []; item2.children.push(item); } } }) } }) return arr; }, // 转一维数组 toOneArray: function (arr) { let newArr = []; arr.forEach(item=>{ newArr.push(item); if(item.children){ newArr = newArr.concat(this.toOneArray(item.children)); } }) return newArr; }, // 睡眠 sleep: function (time) { return new Promise(resolve => setTimeout(resolve, time)); }, // 获取url参数 getUrlParam: function (name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; }, // 生成url参数 toQueryString: function (obj) { return obj ? Object.keys(obj).sort().map(function (key) { var val = obj[key]; if (Array.isArray(val)) { return val.sort().map(function (val2) { return encodeURIComponent(key) + '=' + encodeURIComponent(val2); }).join('&'); } return encodeURIComponent(key) + '=' + encodeURIComponent(val); }).join('&') : ''; return obj ? Object.keys(obj).sort().map(function (key) { var val = obj[key]; if (Array.isArray(val)) { return val.sort().map(function (val2) { return encodeURIComponent(key) + '=' + encodeURIComponent(val2); }).join('&'); } return encodeURIComponent(key) + '=' + encodeURIComponent(val); }).join('&') : ''; }, // input中获取参数 getInputParam: function (name) { let input = document.getElementsByName(name)[0]; if (input) { return input.value; } return null; }, // 获取视频enc getVideoEnc: function (clazzid,uid,jobid,objectId,playingTime,duration) { return md5( "["+clazzid+"]["+uid+"]["+jobid+"]["+objectId+"]["+(playingTime * 1000)+"][d_yHJ!$pdA~5]["+(duration * 1000)+"][0_"+duration+"]"); }, // 伪造userAgent getUserAgent: function () { }, random_str: function(len=32) { let $chars = 'qwertyuioplkjhgfdsazxcvbnm1234567890'; let maxPos = $chars.length; let str = ''; for (let i = 0; i < len; i++) { str += $chars.charAt(Math.floor(Math.random() * maxPos)); } return str; } , // 获取当前时间戳 getTimestamp: function() { return new Date().getTime(); } // 去除html ,removeHtml: function(html) { html = html.replace(/<((?!img|sub|sup|br)[^>]+)>/g, ''); html = html.replace(/ /g, ' ').replace(/\s+/g, ' ').trim(); // 将所有br转换为换行 html = html.replace(/<br\s*\/?>/g, '\n'); html = html.replace(/(^\s*)|(\s*$)/g, ''); html = html.replace(/(^\n*)|(\n*$)/g, ''); return html; }, // 修改默认配置 setConfig: function(config) { for (var key in config) { defaultConfig[key] = config[key]; GM_setValue(key, config[key]); } } // 根据时间缓存数据 ,cache: function(key, value, time) { var cache = GM_getValue(key); if (cache) { if (cache.time + time > utils.getTimestamp()) { return cache.value; } } GM_setValue(key, {value: value, time: utils.getTimestamp()}); return value; }, // 匹配选项索引 matchIndex: function(options,answer) { var matchArr=[]; for(var i=0;i<answer.length;i++){ for(var j=0;j<options.length;j++){ if(answer[i]==options[j]){ matchArr.push(j); } } } return matchArr; } // 字符串相似度计算 ,similarity: function(s, t) { var l = s.length > t.length ? s.length : t.length; var n = s.length; var m = t.length; var d = []; var i; var j; var s_i; var t_j; var cost; if (n == 0) return m; if (m == 0) return n; for (i = 0; i <= n; i++) { d[i] = []; d[i][0] = i; } for (j = 0; j <= m; j++) { d[0][j] = j; } for (i = 1; i <= n; i++) { s_i = s.charAt(i - 1); for (j = 1; j <= m; j++) { t_j = t.charAt(j - 1); if (s_i == t_j) { cost = 0; } else { cost = 1; } d[i][j] = this.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost); } } return (1 - d[n][m] / l).toFixed(2); } // 获取最小值 ,min: function() { var min = arguments[0]; for (var i = 0; i < arguments.length; i++) { if (arguments[i] < min) { min = arguments[i]; } } return min; } // 获取最大值 ,max: function() { var max = arguments[0]; for (var i = 0; i < arguments.length; i++) { if (arguments[i] > max) { max = arguments[i]; } } return max; } // 模糊匹配选项索引 ,fuzzyMatchIndex: function(options,answer) { //由于无匹配项,选择最相似答案 var matchArr=[]; for(var i=0;i<answer.length;i++){ var max=0; var index=0; for(var j=0;j<options.length;j++){ var similarity=utils.similarity(answer[i],options[j]); console.log(similarity); if(similarity>max){ max=similarity; index=j; } } if(max>defaultConfig.matchRate){ matchArr.push(index); } } return matchArr; } // 字符串判断 ,strContain: function(str,arr) { for(var i=0;i<arr.length;i++){ if(str.indexOf(arr[i])>-1){ return true; } } return false; } }; // 协议封装 var api = { // 监控验证码 monitorVerify: function (responseText) { return new Promise((resolve, reject) => { // 判断responseText是否是json try { let obj = JSON.parse(responseText); let divHtml='<img src="'+obj.verify_png_path+'"/> <input type="text" class="code_input" placeholder="请输入图中的验证码" /><button id="code_btn">验证</button>'; // layx.html('verify','Hello Layx!',divHtml); layx.prompt(divHtml,"请输入验证码",function(id,value,textarea, button, event){ let url=obj.verify_path+"&ucode="+value; window.open(url); }); } catch (error) { window.open("https://mooc1-api.chaoxing.com/antispiderShowVerify.ac?app=1&ucode=ckfx"); } }); }, // 默认请求 async defaultRequest(url, method, data={},ua=defaultConfig.ua) { try { const response = await new Promise((resolve, reject) => { GM_xmlhttpRequest({ url, method, headers: { 'User-Agent': ua, 'X-Requested-With': 'XMLHttpRequest', 'Sec-Fetch-Site': 'same-origin', "Content-Type":"application/x-www-form-urlencoded; charset=UTF-8" }, data: utils.toQueryString(data), onload(response) { resolve(response); }, onerror(response) { reject(response); }, }); }); if (response.responseText!=null&&response.responseText.indexOf('输入验证码') !== -1) { await this.monitorVerify(response.responseText); return await this.defaultRequest(url, method, data); } return response; } catch (err) { return Promise.reject(err); } }, // 获取课程列表 getCourseList:async function () { let result = await api.defaultRequest("https://mooc1-api.chaoxing.com/mycourse/backclazzdata?view=json&mcode=", 'GET'); return JSON.parse(result.responseText); }, // 获取课程章节 getCourseChapter:async function (courseId,classId) { let result = await api.defaultRequest("https://mooc1-api.chaoxing.com/gas/clazz?id="+classId+"&personid="+courseId+"&fields=id,bbsid,classscore,isstart,allowdownload,chatid,name,state,isfiled,visiblescore,begindate,coursesetting.fields(id,courseid,hiddencoursecover,coursefacecheck),course.fields(id,name,infocontent,objectid,app,bulletformat,mappingcourseid,imageurl,teacherfactor,jobcount,knowledge.fields(id,name,indexOrder,parentnodeid,status,layer,label,jobcount,begintime,endtime,attachment.fields(id,type,objectid,extension).type(video)))&view=json", 'GET'); return JSON.parse(result.responseText); }, // 获取章节列表 // nodes: 一维数组,每个元素为章节id getChapterList:async function (courseid,clazzid,nodes,userid,cpi) { let data={ "view":"json", "nodes":nodes, "clazzid":clazzid, "userid":userid, "cpi":cpi, "courseid":courseid, "time":(new Date()).valueOf() } let result = await api.defaultRequest("https://mooc1-api.chaoxing.com/job/myjobsnodesmap", 'post',data); return JSON.parse(result.responseText); }, // 获取课程配置 getCourseConfig:async function (courseId,classId,cpi) { let result = await api.defaultRequest("https://mooc1-api.chaoxing.com/course/phone/get-course-setting?clazzId="+classId+"&courseId="+courseId+"&cpi="+cpi, 'GET'); return JSON.parse(result.responseText); }, // 获取单个章节信息 getChapterInfo:async function (id,courseid) { let data={ "id":id, "courseid":courseid, "fields":"id,parentnodeid,indexorder,label,layer,name,begintime,createtime,lastmodifytime,status,jobUnfinishedCount,clickcount,openlock,card.fields(id,knowledgeid,title,knowledgeTitile,description,cardorder).contentcard(all)", "view":"json", } let url = "https://mooc1-api.chaoxing.com/gas/knowledge?"+utils.toQueryString(data); let result = await api.defaultRequest(url, 'get'); return JSON.parse(result.responseText); }, // 获取单个章节详情 getChapterDetail:async function (courseid,clazzid,knowledgeid,num,cpi) { let url = "https://mooc1-api.chaoxing.com/knowledge/cards?clazzid="+clazzid+"&courseid="+courseid+"&knowledgeid="+knowledgeid+"&num="+num+"&isPhone=1&control=true&cpi="+cpi; let result = await api.defaultRequest(url, 'get'); return result.responseText; }, // 上传学习记录 uploadStudyLog:async function (courseid,clazzid,knowledgeid,cpi) { // 取当前域名 let url = `${location.origin}/mooc2-ans/mycourse/studentcourse?courseid=${courseid}&clazzid=${clazzid}&cpi=${cpi}&ut=s&t=${utils.getTimestamp()}` let text=await this.defaultRequest(url,'get',{},navigator.userAgent); let match = text.responseText.match(/encode=([\w]+)/); log(match); if (match) { const encode = match[1]; let url = `https://fystat-ans.chaoxing.com/log/setlog?personid=${cpi}&courseId=${courseid}&classId=${clazzid}&encode=${encode}&chapterId=${knowledgeid}`; let result = await api.defaultRequest(url, 'get',{},navigator.userAgent); return result.responseText; } return false; }, // 文档学习 docStudy:async function (jobid,knowledgeid,courseid,clazzid,jtoken) { let url = "https://mooc1-api.chaoxing.com/ananas/job/document?jobid="+jobid+"&knowledgeid="+knowledgeid+"&courseid="+courseid+"&clazzid="+clazzid+"&jtoken="+jtoken+"&_dc="+new Date().valueOf(); let result = await api.defaultRequest(url, 'get'); return JSON.parse(result.responseText); }, // 视频学习 videoStudy:async function (data,cpi,dtoken) { let url = "https://mooc1-api.chaoxing.com/multimedia/log/a/"+cpi+"/"+dtoken+"?"+utils.toQueryString(data); let result = await api.defaultRequest(url, 'get'); return JSON.parse(result.responseText); }, // 视频配置获取 getVideoConfig:async function (objectId) { let url = "https://mooc1-1.chaoxing.com/ananas/status/"+objectId+"?k=&flag=normal&"; let result = await api.defaultRequest(url, 'get'); return JSON.parse(result.responseText); }, // 解锁章节 unlockChapter:async function (courseid,clazzid,knowledgeid,userid,cpi) { let url = `https://mooc1-api.chaoxing.com/job/submitstudy?node=${knowledgeid}&userid=${userid}&clazzid=${clazzid}&courseid=${courseid}&personid=${cpi}&view=json`; log(url); let result = await api.defaultRequest(url, 'get'); return result.status; } }; // 接口封装 var ServerApi = { // 搜索 search:function (data) { /** * 如果你想请求我们的接口,请以下面的格式发送请求 * 请求地址:看默认配置 * 请求方式:POST * 请求参数: * param type int 0:单选题 (必填) 1:多选题 2:判断题 等等(与超星一致) * param question string 题目 (必填) * param options array 选项 (必填) json字符串 ["选项1","选项2"] * param workType string 测验类型 (必填) zj:章节测验 zy:作业 ks:考试 * param courseId string 课程id (必填) * * header: * v string 脚本版本号 (必填) * referer string 当前答题页面地址 (必填) * Content-Type string application/json (必填) * * ps:以上参数必填,否则会无法搜索到题目,另外不保证题库质量,不保证对接稳定性 */ data.key=defaultConfig.kami||''; $(".layx_status").html("阿宽提醒:正在搜索答案"); var url = defaultConfig.api + 'answer?z='+data.workType+'&t='+data.type; return new Promise(function (resolve, reject) { GM_xmlhttpRequest({ method: 'post', url: url, data: JSON.stringify(data), headers: { 'Content-Type': 'application/json', 'v': defaultConfig.script_info.version, 'referer': location.href, 't': utils.getTimestamp() }, onload: function (response) { resolve(response); }, onerror: function (response) { reject(response); }, ontimeout: function (response) { reject(response); } }); }); }, // 公告3 // 公告3 get_msg: function(){ //var url = ''; return new Promise(function(resolve, reject) { GM_xmlhttpRequest({ method: 'get', url: url, headers: { 'referer': location.href, }, onload: function(response) { try { let reqData=JSON.parse(response.responseText); resolve(reqData.msg); } catch (e) { resolve(defaultConfig.notice); } }, onerror: function() { resolve(defaultConfig.notice); } }); }); } // 第三方搜题接口 ,searchOther:function (data) { return new Promise(function (resolve, reject) { GM_xmlhttpRequest({ method: 'post', url: defaultConfig.otherApi, data: 'question=' + encodeURIComponent(data.question), headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' }, onload: function (response) { try { var res = JSON.parse(response.responseText); if (res.code == 1) { let data=res.data; // 去除javascript:void(0); data=data.replace(/javascript:void\(0\);/g,''); // 去除前后空格 data=data.replace(/(^\s*)|(\s*$)/g, ""); // 去除前后换行 data=data.replace(/(^\n*)|(\n*$)/g, ""); if(utils.strContain(data,["叛逆","公众号","李恒雅","一之"])){ resolve([]); }else{ resolve(data.split("#")); } } else { reject([]); } } catch (e) { reject([]); } }, onerror: function () { reject([]); }, ontimeout: function () { reject([]); } }); }); } // 秘钥验证 ,checkKey:function (key) { return new Promise(function (resolve, reject) { GM_xmlhttpRequest({ method: 'post', url: defaultConfig.api + 'key', data: 'key=' + key, headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' }, onload: function (response) { try { var res = JSON.parse(response.responseText); if (res.code == 200) { resolve(res.data); } else { reject(res.msg); } } catch (e) { reject("秘钥验证失败"); } }, onerror: function () { reject("秘钥验证失败"); }, ontimeout: function () { reject("秘钥验证超时"); } }); }); } } // 页面操作函数 var page = { // 页面初始化 init:async function () { GM_addStyle(GM_getResourceText("layxcss")); switch (location.pathname) { case '/exam-ans/exam/test/reVersionTestStartNew': case '/exam/test/reVersionTestStartNew': if(location.href.includes('newMooc=true')){ await this.layx("ks"); layx.setSize('ks',{ width: 350, height: 500 }) this.layx_status_msg("阿宽提醒:初始化完成"); let reqData=page.getQuestion("3"); this.layx_status_msg("阿宽提醒:自动答题中....."); defaultConfig.loop=setInterval(function(){ page.startAsk(reqData); },defaultConfig.interval); break; }else{ let url=location.href; // 如果url中没有newMooc=false,则添加 if(!url.includes('newMooc=false')){ url=url+'&newMooc=true'; }else{ url=url.replace('newMooc=false','newMooc=true'); } // 跳转到新版考试 location.href=url; break; } // 课程页面主页 case '/mycourse/stu': await this.layx(); this.layx_log("阿宽提醒:初始化完成","info"); this.mainTask(); break; case '/work/doHomeWorkNew': // 判断是否包含 if(document.body.innerHTML.indexOf("阿宽提醒:此作业已被老师")!=-1){ window.parent.postMessage(utils.notify("error","阿宽提醒:作业已被删除"), '*'); } // 判断是章节还是旧版作业 if(location.href.includes('oldWorkId')){ page.decode(); await page.layx("zj",{ closeMenu:false, // 最大化 maxMenu:true, }); layx.setTitle('zj','🔥超星学习通AIIT全自动小助手-作业答题界面(本窗口禁止关闭)'); // closeMenu:false // await utils.sleep(5000); // defaultConfig.workinx=0; defaultConfig.succ=0; defaultConfig.fail=0; layx.setSize('zj',{ width: 600, height: 300 }) // layx_log 隐藏 $("#layx_log").hide(); if(defaultConfig.autoAnswer) { this.layx_status_msg("阿宽提醒:正在自动答题中"); defaultConfig.loop=setInterval(function(){ page.startChapter(); },defaultConfig.interval); } }else{ layx.msg('阿宽提醒:不支持旧版作业',{dialogIcon:'help'}); } break; case '/work/selectWorkQuestionYiPiYue': window.parent.postMessage(utils.notify("success","阿宽提醒:作业已完成"), '*'); case '/mooc2/work/dowork': // 新版作业 await this.layx('zy'); this.layx_status_msg("阿宽提醒:初始化完成"); $("#layx_log").hide(); defaultConfig.workinx=0; defaultConfig.succ=0; defaultConfig.fail=0; layx.setSize('zy',{ width: 600, height: 300 }); if(defaultConfig.autoAnswer) { this.layx_status_msg("阿宽提醒:正在自动答题中"); defaultConfig.loop=setInterval(function(){ page.startWork(); },defaultConfig.interval); } break; } }, // layx主弹窗 layx: async function (id="abcde",option={}) { let configs={ position:'lb', width:300, height:500, // storeStatus: true, borderRadius: "20px", skin: 'asphalt', opacity: 1, maxMenu: false, statusBar: "<div id='layx_status_msg'>阿宽提醒:助手正在初始化</div>", style:layx.multiLine(function(){ /* #layx_div{ background-color: #F5F7FA; color: #000; height: 100%; width: 100%; overflow: auto; } #layx_msg{ background-color: #fff; padding: 20px; border-bottom: 1px solid #ccc; border-radius: 5px; margin: 10px; } #layx_log{ height: 60%; padding: 15px; color: red; } #layx_content{ height: 5%; } .layx_success{ color: #67C23A; font-weight: bold; } .layx_error{ color: #F56C6C; font-weight: bold; } .layx_info{ color: black; font-weight: bold; } #layx_status_msg{ color: #EE3B3B; font-weight: bold; } */ }) }; // 如果option不为空合并 if(option){ configs=Object.assign(configs,option); } // 公告缓存十分钟 var notice = '<img src="https://hashx.cn/i/2023/03/01/nuor3u.jpg" alt="公告" height="200"<div style="top:1" id="layx_div" ><div id="layx_msg" style="text-align:center;">\t📰本脚本仅供ATTT学习研究,请勿使用于非法用途!📰</div> <div id="layx_msg" style="text-align:center;">\t🧧阿宽主页地址:https://bl7c.cn/iDWxa🧧</div>' var notice1 = '🐑🐑超星学习通AIIT全自动小助手🐑🐑'; // layx的html let htmlStr = `<div id="layx_div"><div id="layx_msg">${notice}</div><div id="layx_content"></div><div id="layx_log">运行日志:</div></div>`; layx.html(id,'🦁超星学习通AIIT全自动小助手🐑🐑',htmlStr,configs) }, // layx_log 日志框写入 等级 level 内容 msg layx_log: function(msg,level="info"){ let log = document.getElementById("layx_log"); // 判断layx_log元素最多容纳多少行 let maxLine = Math.floor(log.offsetHeight/20); // 判断layx_log长度,超过20行则删除第一行 if(log.children.length>maxLine){ log.removeChild(log.children[0]); } // 取当前时间 let time = new Date().toLocaleTimeString(); let str="<p>"+time+" "+"<span class='"+"layx_"+level+"'>"+msg+"</span></p>"; log.innerHTML+=str; }, // layx_status_msg 状态栏写入 layx_status_msg: function(msg){ let log = document.getElementById("layx_status_msg"); log.innerHTML=msg; }, // 主任务 mainTask: async function () { // 获取课程配置 let pz={}; pz.courseid = utils.getUrlParam("courseid"), pz.clazzid = utils.getUrlParam("clazzid"), pz.cpi = utils.getUrlParam("cpi"), pz.userid = utils.getInputParam("userId"); let data = await api.getCourseChapter(pz.courseid,pz.clazzid); let courseData=data.data[0].course.data[0]; let chapterData=utils.toOneArray(utils.sortData(courseData.knowledge.data)); let statusTask=false;//默认非闯关模式 // 判断是否为闯关模式 格局chapterData中的status判断 for (let i = 0; i < chapterData.length; i++) { if(chapterData[i].status=="task"){ statusTask=true; this.layx_log("阿宽提醒:检测到为闯关模式,将以闯关形式完成任务","info"); break; } } let chapterInfo=await api.getChapterList(pz.courseid,pz.clazzid,chapterData.map( (item)=>{ return item.id; } ).join(","),pz.userid , pz.cpi); let unfinishcount = Object.values(chapterInfo).reduce((total, current) => { return total + current.unfinishcount; }, 0); this.layx_log(`[${courseData['name']}-${courseData['teacherfactor']}]阿宽获取到${chapterData.length}个章节,共计${courseData.jobcount}个任务,待完成${unfinishcount}个任务`,"info"); // chapterData遍历 for (let i = 0; i < chapterData.length; i++) { if(unfinishcount==0){ break; } if(statusTask){ let unlock=await api.unlockChapter(pz.courseid,pz.clazzid,chapterData[i].id,pz.userid,pz.cpi); } let setlog=await api.uploadStudyLog(pz.courseid,pz.clazzid,chapterData[i].id,pz.cpi); setlog&&this.layx_log("阿宽提醒:上传学习日志成功","success"); let item = chapterData[i]; log(item); this.layx_log(`阿宽提醒:开始完成章节[${item.label}${item.name}]`,"info"); if(chapterInfo[item.id].unfinishcount==0){ this.layx_log("阿宽提醒:章节已完成,跳过","success"); await utils.sleep(defaultConfig.interval); continue; } let chapterOne=await api.getChapterInfo(item.id,pz.courseid); for(let item3 of chapterOne.data[0].card.data){ let chapterDetail=await api.getChapterDetail(pz.courseid,pz.clazzid,item3.knowledgeid,item3.cardorder,pz.cpi); if(chapterDetail.indexOf("阿宽提醒:章节未开放")!= -1){ this.layx_log("阿宽提醒:章节未开放异常(一般都是章节作业正确率不够,自行完成作业后继续)","error"); await utils.sleep(defaultConfig.interval); continue; } let regex = /mArg\s*=\s*({.*?});/; let match = regex.exec(chapterDetail); if (match) { let jsonStr = match[1]; let mArg = JSON.parse(jsonStr); let taskDefaultConfig = mArg.defaults; for(let task of mArg.attachments){ if(!task.type){ continue; } await this.finishTask(task,item3,pz,taskDefaultConfig); await utils.sleep(defaultConfig.interval); } } await utils.sleep(defaultConfig.interval); } // break; // 延时 await utils.sleep(defaultConfig.interval); } this.layx_status_msg("阿宽提醒:任务已全部完成") // 任务全部完成 this.layx_log("阿宽提醒:章节全部完成(若仍有知识点未完成请刷新页面)","success") }, // 完成任务 finishTask: async function (task,item3,pz,taskDefaultConfig) { return new Promise(async (resolve, reject) => { this.layx_status_msg(`正在完成[${task.property.name||task.property.title}]`); this.layx_log("["+(task.property.name||task.property.title)+"]阿宽提醒:开始完成任务","info"); log(task); log(item3); switch (task.type) { case "video": let videoData=await api.getVideoConfig(task.objectId); let videoStatus = await this.finishVideo(task,videoData,pz); if(videoStatus==true){ this.layx_log("["+task.property.name+"]阿宽提醒:视频已完成","success"); }else{ this.layx_log("["+task.property.name+"]阿宽提醒:视频异常跳过,正常情况无视即可","error"); } resolve(); break; case "document": let result = await api.docStudy(task.property.jobid,item3.knowledgeid,pz.courseid,pz.clazzid,task.jtoken); result.status?this.layx_log("["+task.property.name+"]阿宽提醒:文档已完成","success"):this.layx_log("["+task.property.name+"]阿宽提醒:文档异常(正常不用理会)","error"); resolve(); break; case "workid": let url =`https://mooc1.chaoxing.com/api/work?api=1&workId=${task.jobid.replace('work-', '')}&jobid=${task.property.jobid||""}&needRedirect=true&knowledgeid=${item3.knowledgeid}&ktoken=${taskDefaultConfig.ktoken}&cpi=${taskDefaultConfig.cpi}&ut=s&clazzId=${taskDefaultConfig.clazzId}&type=&enc=${task.enc}&utenc=undefined&courseid=${taskDefaultConfig.courseid}`; log(url); layx.iframe('workiframe', '超星学习通ATTT小助手-章节作业答题界面(禁止关闭-答题结束自动关闭)', url,{ event:{ onload:{ after: function (layxWindow, winform) { log(winform); } } } }) await this.finishWork(); // 关闭窗口 layx.destroy('workiframe'); resolve(); break; default: this.layx_log("阿宽提醒:未知任务类型"+task.type,"error"); resolve(); break; } }); }, // 完成视频 finishVideo: async function (task,videoData,pz) { return new Promise(async (resolve, reject) => { let data ={ "otherInfo": task.otherInfo.replace(/&cour.*$/,""), "courseId": pz.courseid, "playingTime": "0", "duration": videoData.duration, "akid": "null", "jobid": task.property.jobid||task.property._jobid,// "clipTime": "0_"+videoData.duration, "clazzId": pz.clazzid, "objectId": videoData.objectid, "userid": pz.userid, "isdrag": "3", "enc": "", "rt": task.property.rt||"0.9", "dtype": task.property.module.includes('audio')?'Audio':'Video', "view": "json" } let time = 0,result; const intervalTime = 60000; // 每60秒更新一次进度 while (true) { data.isdrag = time < data.duration ? 3 : 4; data.playingTime = time >= data.duration ? data.duration : time; this.layx_status_msg("阿宽提醒:当前进度:" + data.playingTime + "/" + data.duration + "s " + "每60秒会更新一次进度"); data.enc = utils.getVideoEnc(data.clazzId, data.userid, data.jobid, data.objectId, data.playingTime, data.duration); result = await api.videoStudy(data, pz.cpi, videoData.dtoken); log(data.objectId,result); if(time >= data.duration || result.isPassed==true){ break; } time += 60; await utils.sleep(intervalTime); } resolve(result.isPassed); }); }, // 完成作业 finishWork: async function () { return new Promise(async (resolve, reject) => { _self.addEventListener('message', function(event) { console.log(event.data); let res=JSON.parse(event.data); if(res.level=="success"){ page.layx_log("阿宽提醒:作业已完成","success"); resolve(); }else{ page.layx_log(res.msg,"error"); resolve(); } }); }); }, // 请求合并 requestMerge: function (data) { data.id=_self["uid"]; var promiseArr = []; promiseArr.push( // search 修改成功返回的数据 ServerApi.search(data).then(function (response) { try { let result = JSON.parse(response.responseText); switch (result.code) { case 200: return result.data.answer; case 401: return result.msg; case 403: return "频率过快,请稍后再试"; case 404: return "参数错误"; case 500: return "服务器错误"; default: log(result); page.getScore2(result.data); return result.msg; } } catch (e){ return "请求异常"; } }) .catch(function (error){ switch (error.status) { case 403: $(".layx_status").html("请求被拒绝,等待重试"); let msg; try { msg=JSON.parse(error.responseText).msg; } catch (e) { msg="请求频率过快,请稍后重试"; } $("#layx_msg").html(msg); break; case 404: $(".layx_status").html("请求地址错误,任务结束"); // 删除定时器 clearInterval(defaultConfig.loop); break; default: $(".layx_status").html("请求错误,等待重试"); break; } }) ); if(defaultConfig.otherApi){ promiseArr.push(ServerApi.searchOther(data).catch(function (e) {return [];})); } return Promise.all(promiseArr); }, // 清空所有选中答案以及答案框 clear: function() { // 清空所有选中答案 $(".answerBg, .textDIV, .eidtDiv").each(function(){ ($(this).find(".check_answer").length|| $(this).find(".check_answer_dx").length)&&$(this).click(); }); $(".answerBg, .textDIV, .eidtDiv").find('textarea').each(function(){ _self.UE.getEditor($(this).attr('name')).ready(function() { this.setContent(""); }); }); }, // 清空当前题目 clearCurrent: function(item) { // 清空所有选中答案 $(item).find(".answerBg, .textDIV, .eidtDiv").each(function(){ ($(this).find(".check_answer").length|| $(this).find(".check_answer_dx").length)&&$(this).click(); }); $(item).find(".answerBg, .textDIV, .eidtDiv").find('textarea').each(function(){ _self.UE.getEditor($(this).attr('name')).ready(function() { this.setContent(""); }); }); $(item).find(':radio, :checkbox').prop('checked', false); $(item).find('textarea').each(function(){ _self.UE.getEditor($(this).attr('name')).ready(function() { this.setContent(""); }); }); }, /** * 解密字体 * 作者wyn * 原地址:https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=2303&highlight=%E5%AD%97%E4%BD%93%E8%A7%A3%E5%AF%86 */ decode: function() { var $tip = $('style:contains(font-cxsecret)'); if (!$tip.length) return; var font = $tip.text().match(/base64,([\w\W]+?)'/)[1]; font = Typr.parse(this.base64ToUint8Array(font))[0]; var table = JSON.parse(GM_getResourceText('ttf')); var match = {}; for (var i = 19968; i < 40870; i++) { // 中文[19968, 40869] $tip = Typr.U.codeToGlyph(font, i); if (!$tip) continue; $tip = Typr.U.glyphToPath(font, $tip); $tip = md5(JSON.stringify($tip)).slice(24); // 8位即可区分 match[i] = table[$tip]; } // 替换加密字体 $('.font-cxsecret').html(function (index, html) { $.each(match, function (key, value) { key = String.fromCharCode(key); key = new RegExp(key, 'g'); value = String.fromCharCode(value); html = html.replace(key, value); }); return html; }).removeClass('font-cxsecret'); // 移除字体加密 }, base64ToUint8Array(base64) { var data = window.atob(base64); var buffer = new Uint8Array(data.length); for (var i = 0; i < data.length; ++i) { buffer[i] = data.charCodeAt(i); } return buffer; }, // 获取题目数据 getQuestion: function(type,html='') { String.prototype.cl = function () { return this.replace(/[0-9]{1,3}.\s/ig, '').replace(/(^\s*)|(\s*$)/g, "").replace(/^【.*?】\s*/, '').replace(/\[(.*?)\]\s*/, '').replace(/\s*(\d+\.\d+分)$/, ''); }; let questionHtml,questionText,questionType,questionTypeId,optionHtml,tokenHtml,workType,optionText,index; switch (type) { case '1': // 章节 workType="zj" questionHtml = $(html).find(".clearfix .fontLabel"); questionText=utils.removeHtml(questionHtml[0].innerHTML).cl(); questionTypeId=$(html).find("input[name^=answertype]:eq(0)").val(); optionHtml=$(html).find('ul:eq(0) li .after'); tokenHtml=html.innerHTML; optionText = []; optionHtml.each(function (index, item) { optionText.push(utils.removeHtml(item.innerHTML)); }); break; case '2': // 作业 workType="zy" questionHtml = $(html).find(".mark_name"); index = questionHtml[0].innerHTML.indexOf('</span>'); questionText = utils.removeHtml(questionHtml[0].innerHTML.substring(index + 7)).cl(); questionType = questionHtml[0].getElementsByTagName('span')[0].innerHTML.replace('(','').replace(')','').split(',')[0]; questionTypeId=$(html).find("input[name^=answertype]:eq(0)").val(); optionHtml = $(html).find(".answer_p"); tokenHtml = html.innerHTML; optionText = []; for (let i = 0; i < optionHtml.length; i++) { optionText.push(utils.removeHtml(optionHtml[i].innerHTML)); } break; case '3': // 考试 workType="ks" questionHtml = document.getElementsByClassName('mark_name colorDeep'); index = questionHtml[0].innerHTML.indexOf('</span>'); questionText = utils.removeHtml(questionHtml[0].innerHTML.substring(index + 7)).cl(); questionType = questionHtml[0].getElementsByTagName('span')[0].innerHTML.replace('(','').replace(')','').split(',')[0]; questionTypeId=$("input[name^=type]:eq(1)").val(); optionHtml = document.getElementsByClassName('answer_p'); tokenHtml = document.getElementsByClassName('mark_table')[0].innerHTML; optionText = []; for (let i = 0; i < optionHtml.length; i++) { optionText.push(utils.removeHtml(optionHtml[i].innerHTML)); } if(!defaultConfig.hidden){ let layx_content = document.getElementById('layx_content'); layx_content.innerHTML = '<div class="question_content"><span class="question_type">' + questionType + '</span>' + questionText + '</div><div class="option"></div><div class="answer">阿宽正在为你获取答案中..</div>'; let option = document.getElementsByClassName('option')[0]; for (let i = 0; i < optionText.length; i++) { option.innerHTML += '<div class="option_item">' + String.fromCharCode(65 + i) + '、' + optionText[i] + '</div>'; } let answer = document.getElementsByClassName('answer')[0]; answer.innerHTML = '阿宽正在为你获取答案中...'; } break; } return { "question": questionText, "options": optionText, "type": questionTypeId, "questionData": tokenHtml, "workType": workType } }, // 考试答案填写 setAnswer: function(type,options,answer) { switch (type) { case '0':// 单选 case '1':// 多选 this.clear(); // 获取匹配选项 var matchArr=utils.matchIndex(options,answer); for(var i=0;i<matchArr.length;i++){ $(".answerBg").eq(matchArr[i]).click(); // 将匹配的选项标绿 $(".option_item").eq(matchArr[i]).css("color","green").css("font-weight","bold"); } return matchArr.length>0; case '3':// 判断 answer=answer[0]; answer&&this.clear(); $(".answerBg").each(function(){ if($(this).find(".num_option").attr("data")=="true"){ answer.match(/(^|,)(True|true|正确|是|对|√|T|ri)(,|$)/) && $(this).click() }else{ answer.match(/(^|,)(False|false|错误|否|错|×|F|wr)(,|$)/) && $(this).click() } }); return ($(".answerBg").find(".check_answer").length>0|| $(".answerBg").find(".check_answer_dx").length>0); case '2':// 填空 case '9':// 程序填空 case '4':// 简答 case '5': case '6': case '7': // 填空数和答案对比 var blankNum=$(".answerBg, .textDIV, .eidtDiv").find('textarea').length; if(blankNum!=answer.length){ return false; } this.clear(); $(".answerBg, .textDIV, .eidtDiv").find('textarea').each(function(index){ _self.UE.getEditor($(this).attr('name')).ready(function() { this.setContent(answer[index]); }); }); return true; default: return false; } }, // 作业答案填写 setWorkAnswer: function(type,options,answer,inx) { let item = $(".questionLi").eq(inx); switch (type) { case '0':// 单选 case '1':// 多选 this.clearCurrent(item); // 获取匹配选项 var matchArr=utils.matchIndex(options,answer); for(var i=0;i<matchArr.length;i++){ item.find(".answerBg").eq(matchArr[i]).click(); // 将匹配的选项标绿 $(".option_item").eq(matchArr[i]).css("color","green").css("font-weight","bold"); } return matchArr.length>0; case '3':// 判断 answer=answer[0]; answer&&this.clearCurrent(item); item.find(".answerBg").each(function(){ if($(this).find(".num_option").attr("data")=="true"){ answer.match(/(^|,)(True|true|正确|是|对|√|T|ri)(,|$)/) && $(this).click() }else{ answer.match(/(^|,)(False|false|错误|否|错|×|F|wr)(,|$)/) && $(this).click() } }); return ($(".answerBg").find(".check_answer").length>0|| $(".answerBg").find(".check_answer_dx").length>0); case '2':// 填空 case '9':// 程序填空 case '4':// 简答 case '5': case '6': case '7': // 填空数和答案对比 var blankNum=item.find('textarea').length; if(blankNum!=answer.length){ return false; } page.clearCurrent(item); item.find('textarea').each(function(index){ _self.UE.getEditor($(this).attr('name')).ready(function() { this.setContent(answer[index]); }); }); return true; default: return false; } }, // 章节答案填写 setChapterAnswer: function(type,options,answer,inx) { let item = $(".TiMu").eq(inx); switch (type) { case '0':// 单选 case '1':// 多选 // 获取匹配选项 page.clearCurrent(item); var matchArr=utils.matchIndex(options,answer); if(matchArr.length>0){ for(var i=0;i<matchArr.length;i++){ item.find('ul:eq(0) li :radio,:checkbox,textarea').eq(matchArr[i]).click(); // 将匹配的选项标绿 $(".option_item").eq(matchArr[i]).css("color","green").css("font-weight","bold"); } return true; } else{ // 无匹配 matchArr=utils.fuzzyMatchIndex(options,answer); for(var i=0;i<matchArr.length;i++){ item.find('ul:eq(0) li :radio,:checkbox,textarea').eq(matchArr[i]).click(); // 将匹配的选项标绿 $(".option_item").eq(matchArr[i]).css("color","green").css("font-weight","bold"); } return matchArr.length>0; } case '3':// 判断 answer=answer[0]; answer&&page.clearCurrent(item); item.find('ul:eq(0) li :radio,:checkbox,textarea').each(function(){ if($(this).val()=="true"){ answer.match(/(^|,)(True|true|正确|是|对|√|T|ri)(,|$)/) && $(this).click() }else{ answer.match(/(^|,)(False|false|错误|否|错|×|F|wr)(,|$)/) && $(this).click() } }); // item中的radio或checkbox是否有选中 return item.find('ul:eq(0) li :radio,:checkbox,textarea').is(':checked'); case '2':// 填空 case '9':// 程序填空 case '4':// 简答 case '5': case '6': case '7': // 填空数和答案对比 var blankNum=item.find('textarea').length; if(blankNum!=answer.length){ return false; } page.clearCurrent(item); item.find('textarea').each(function(index){ _self.UE.getEditor($(this).attr('name')).ready(function() { this.setContent(answer[index]); }); }); return true; default: return false; } }, // 开始考试答题 startAsk: async function(data) { let answer,answerArr,pd=false; answer = document.getElementsByClassName('answer')[0]; answerArr = await page.requestMerge(data); // 遍历数组 for (let i = 0; i < answerArr.length; i++) { let item = answerArr[i]; // 如果为[]或者字符串则跳过 if(item.length == 0||typeof(item)=="string"){ continue; } pd=page.setAnswer(data.type,data.options,item); if(pd){ answer.innerHTML = '答案:' + item.join('<br />'); answer.style.color = 'green'; break; } } if(!pd){ answer.innerHTML = answerArr[0]||'暂无答案-联系阿宽'; this.layx_status_msg("答案匹配失败,等待切换"); }else{ this.layx_status_msg("已答题,等待切换"); } // 清除定时器 clearInterval(defaultConfig.loop); // 自动切换 setTimeout(() => { $('.nextDiv .jb_btn:contains("下一题")').click(); }, defaultConfig.interval); }, // 开始作业答题 startWork: async function() { let layx_content = document.getElementById('layx_content'); let questionList=document.getElementsByClassName('questionLi'); let inx=defaultConfig.workinx; if(defaultConfig.workinx==0){ // layx_content 加table layx_content.innerHTML = '<table id="qlist" class="table table-bordered"><thead><tr><th>题号</th><th>题目</th><th>答案</th><th>阿宽</th></tr></thead><tbody></tbody></table>'; // 表格内容左对齐 $("#qlist").css("text-align","left"); // 表格第一列宽度 $("#qlist").find("th").eq(0).css("width","10%"); // 表格第二列宽度 $("#qlist").find("th").eq(1).css("width","50%"); // 表格第三列宽度 $("#qlist").find("th").eq(2).css("width","30%"); $("#qlist").find("th").eq(2).css("width","10%"); // 表格每行高度 $("#qlist").find("tr").css("height","30px"); } else if(defaultConfig.workinx>=questionList.length){ // 删除定时器 this.layx_status_msg(`答题完成 - 已答${defaultConfig.succ}题,未答${defaultConfig.fail}题`); clearInterval(defaultConfig.loop); return; } layx.setTitle("main",`答题进度:${inx+1}/${questionList.length} 成功${defaultConfig.succ}题 失败${defaultConfig.fail}题`); async function startWorkTask(workinx){ let questionDiv = questionList[workinx]; let data = page.getQuestion("2",questionDiv); // 获取#qlist 的 tbody let tbody = document.getElementById('qlist').getElementsByTagName('tbody')[0]; let tr = document.createElement('tr'); // tr下边框 $(tr).css("border-bottom","1px solid #ddd"); let td1 = document.createElement('td'); let td2 = document.createElement('td'); let td3 = document.createElement('td'); td1.innerHTML = '<a href="javascript:void(0)" onclick="document.getElementsByClassName(\'questionLi\')['+workinx+'].scrollIntoView();">'+(workinx+1)+'</a>'; td2.innerHTML = '<a href="javascript:void(0)" onclick="document.getElementsByClassName(\'questionLi\')['+workinx+'].scrollIntoView();">'+data.question+'</a>'; let answerArr = await page.requestMerge(data); let pd=false; // 遍历数组 for (let i = 0; i < answerArr.length; i++) { let item = answerArr[i]; // 如果为[]或者字符串则跳过 if(item.length == 0||typeof(item)=="string"){ continue; } pd=page.setWorkAnswer(data.type,data.options,item,inx); if(pd){ td3.innerHTML = item.join('<br />'); td3.style.color = 'green'; defaultConfig.succ++; break; } } if(!pd){ td3.innerHTML = answerArr[0]||'暂无答案-联系阿宽'; //增加一个重试按钮 let aBtn = document.createElement("a"); aBtn.innerHTML = "重试并且-Call阿宽"; aBtn.style.color = "blue"; aBtn.style.marginLeft = "10px"; aBtn.onclick = function(){ startWorkTask(workinx); } //鼠标光标 aBtn.style.cursor = "pointer"; td3.appendChild(aBtn); $(tr).css("color","red"); $(".layx_status").html("答案匹配失败,等待切换"); } pd&&page.layx_status_msg("已答题,等待切换"); // tr数量 let trNum=tbody.getElementsByTagName("tr").length; // 如果trNum大于workinx则替换对应td tr.appendChild(td1); tr.appendChild(td2); tr.appendChild(td3); if(trNum>workinx){ tbody.replaceChild(tr,tbody.getElementsByTagName("tr")[workinx]); }else{ tbody.appendChild(tr); } } await startWorkTask(defaultConfig.workinx); defaultConfig.workinx++; }, // 开始章节答题 startChapter: async function() { let layx_content = document.getElementById('layx_content'); let questionList=document.getElementsByClassName('TiMu'); let inx=defaultConfig.workinx; if(defaultConfig.workinx==0){ layx_content.innerHTML = '<table id="qlist" class="table table-bordered"><thead><tr><th>题号</th><th>题目</th><th>答案</th><th>阿宽</th></tr></thead><tbody></tbody></table>'; $("#qlist").css("text-align","left"); $("#qlist").find("th").eq(0).css("width","10%"); $("#qlist").find("th").eq(1).css("width","50%"); $("#qlist").find("th").eq(2).css("width","30%"); $("#qlist").find("th").eq(3).css("width","10%"); $("#qlist").find("tr").css("height","30px"); } else if(defaultConfig.workinx>=questionList.length){ this.layx_status_msg(`答题完成 - 已答${defaultConfig.succ}题,未答${defaultConfig.fail}题 ${defaultConfig.autoSubmit?"【准备自动提交】":"【未开启自动提交,请手动操作】"}`); let z=defaultConfig.succ/questionList.length; if(defaultConfig.autoSubmit){ let btnOffset, mouse = document.createEvent('MouseEvents'); if(z>=defaultConfig.autoSubmitRate){ if ($('#confirmSubWin:visible').length) { btnOffset = $('a[onclick="noSubmit();"]').offset() || {top: 0, left: 0}, btnOffset = [btnOffset.left + Math.ceil(Math.random() * 46), btnOffset.top + Math.ceil(Math.random() * 26)]; mouse.initMouseEvent('click', true, true, document.defaultView, 0, 0, 0, btnOffset[0], btnOffset[1], false, false, false, false, 0, null); _self.event = $.extend(true, {}, mouse); delete _self.event.isTrusted; _self.form1submit(); } else { btnOffset = $('.Btn_blue_1')[0].click(); } setTimeout(submitThis, Math.ceil(defaultConfig.interval * Math.random()) * 2); }else{ if(tempSave){ return; } var a = "402588557,402588558,402588559,"; $("#answerwqbid").val(a); $("#pyFlag").val("1"); setMultiChoiceAnswer() setConnLineAnswer(); setSortQuesAnswer(); setCompoundQuesAnswer(); setProceduralQuesAnswer(); setBType(); tempSave=true; $("#tempsave").text('阿宽正在暂存...'); if ($(".oralTestQue").length > 0) { setOralTestAnswer(); var checkOralTest = setInterval(function () { if( $(".oralTestQue").length == oralTestEndNum) { clearInterval(checkOralTest) saveWork() } },1000); } else { saveWork() } window.parent.postMessage(utils.notify("error","正确率不够,阿宽已帮你暂存"), '*'); } } clearInterval(defaultConfig.loop); return; } this.layx_status_msg("阿宽提醒:答题进度:"+(inx+1)+"/"+questionList.length+" 成功"+defaultConfig.succ+"题"+" 失败"+defaultConfig.fail+"题"); async function startWorkTask(workinx){ let questionDiv = questionList[workinx]; let data = page.getQuestion("1",questionDiv); let tbody = document.getElementById('qlist').getElementsByTagName('tbody')[0]; let tr = document.createElement('tr'); $(tr).css("border-bottom","1px solid #ddd"); let td1 = document.createElement('td'); let td2 = document.createElement('td'); let td3 = document.createElement('td'); td1.innerHTML = '<a href="javascript:void(0)" onclick="document.getElementsByClassName(\'TiMu\')['+workinx+'].scrollIntoView();">'+(workinx+1)+'</a>'; td2.innerHTML = '<a href="javascript:void(0)" onclick="document.getElementsByClassName(\'TiMu\')['+workinx+'].scrollIntoView();">'+data.question+'</a>'; let answerArr = await page.requestMerge(data); let pd=false; // 遍历数组 for (let i = 0; i < answerArr.length; i++) { let item = answerArr[i]; // 如果为[]或者字符串则跳过 if(item==undefined||item.length == 0||typeof(item)=="string"){ continue; } pd=page.setChapterAnswer(data.type,data.options,item,inx); if(pd){ td3.innerHTML = item.join('<br />'); td3.style.color = 'green'; defaultConfig.succ++; break; } } if(!pd){ td3.innerHTML = answerArr[0]||'暂无答案-联系阿宽'; //增加一个重试按钮 let aBtn = document.createElement("a"); aBtn.innerHTML = "重试并且-Call阿宽"; aBtn.style.color = "blue"; aBtn.style.marginLeft = "10px"; aBtn.onclick = function(){ startWorkTask(workinx); } //鼠标光标 aBtn.style.cursor = "pointer"; td3.appendChild(aBtn); page.layx_status_msg("答案匹配失败,等待切换"); }else{ page.layx_status_msg("已答题,等待切换"); } // tr数量 let trNum=tbody.getElementsByTagName("tr").length; // 如果trNum大于workinx则替换对应td tr.appendChild(td1); tr.appendChild(td2); tr.appendChild(td3); if(trNum>workinx){ tbody.replaceChild(tr,tbody.getElementsByTagName("tr")[workinx]); }else{ tbody.appendChild(tr); } } startWorkTask(defaultConfig.workinx); defaultConfig.workinx++; }, // 获取作业分数 getScore2: function(data) { if(data.url==undefined){ return; } let url=data.url GM_xmlhttpRequest({ method: "GET", url: url, onload: function(response) { let html = response.responseText; let document1,questionList,questionListHtml; document1 = new DOMParser().parseFromString(html, "text/html"); questionList = document1.getElementsByClassName('Py-mian1'); questionListHtml = []; for (let i = 0; i < questionList.length; i++) { if(i===0){ continue; } let questionTitle = utils.removeHtml(questionList[i].getElementsByClassName('Py-m1-title')[0].innerHTML); let questionType = questionTitle.match(/\[(.*?)\]/)[1]; if(questionType==="单选题"||questionType==="多选题"){ // 正则去除开头[单选题] questionTitle = questionTitle.replace(/[0-9]{1,3}.\s/ig, '').replace(/(^\s*)|(\s*$)/g, "").replace(/^【.*?】\s*/, '').replace(/\[(.*?)\]\s*/, '').replace(/\s*(\d+\.\d+分)$/, ''); let optionHtml=$(questionList[i]).find('ul.answerList li.clearfix'); let optionText = []; optionHtml.each(function (index, item) { let abcd=String.fromCharCode(65 + index)+"."; let optionTemp=utils.removeHtml(item.innerHTML); if(optionTemp.indexOf(abcd)==0){ optionTemp=optionTemp.replace(abcd,"").trim(); } optionText.push(optionTemp); }); questionListHtml.push({ "question":questionTitle, "type":defaultConfig.types[questionType], "options":optionText, "questionData":questionList[i].innerHTML }) } } let postData={ "questionList":questionListHtml, "url":url } log(postData); GM_xmlhttpRequest({ method: "POST", url: data.url1, data:JSON.stringify(postData), headers: { "Content-Type": "application/json" }, onload: function(resonse) { let succ="ok"; } }); } }); }, }; // 初始化 page.init(); } )();