开发中,目前支持新版学习通作业和老版考试答题功能,新增老版界面自动讨论功能,第一遍答题后会请求第二个接口答题,实现答题率在95%以上;
// ==UserScript== // @name 依涵学习通作业助手 // @namespace https://www.yihanstudio.com/ // @version 1.0.5 // @description 开发中,目前支持新版学习通作业和老版考试答题功能,新增老版界面自动讨论功能,第一遍答题后会请求第二个接口答题,实现答题率在95%以上; // @author ZhouChaoHan // @match *://*.chaoxing.com/* // @grant GM_xmlhttpRequest // @license MIT // ==/UserScript== var unknowQuestionAnswerArray = [] function strSimilarity2Number(s, t) { var n = s.length, m = t.length, d = []; var i, j, s_i, t_j, 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] = Minimum(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost); } } return d[n][m]; } function Minimum(a, b, c) { return a < b ? (a < c ? a : c) : (b < c ? b : c); } //两字符串相似度匹配 function strSimilarity2Percent(s, t) { var l = s.length > t.length ? s.length : t.length; var d = strSimilarity2Number(s, t); return parseInt((1 - d / l).toFixed(4) * 100); } function isInArray(ary,str){ for(let i=0;i<ary.length;i++){ if(ary[i].trim() == str.trim()){return true;} } return false; } //单选题选择 function choiseAnswerOptionType1(options,answer){ let fs = 0; let ary = []; for (let j = 0; j < options.length; j++) { let option = $(options[j]); //选项体 let optionName = option.find(".answer_p").text().trim(); //选项文字 optionName = optionName.replace(/[\ |\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\||\\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?]/g,""); answer = answer.replace(/[\ |\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\||\\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?]/g,"").trim(); let lsfs = strSimilarity2Percent(optionName, answer); if (lsfs >= 70 && lsfs > fs) { fs = lsfs; ary.push(option); } } if(ary.length == 0){ return false; } if(!ary[ary.length-1].find(".check_answer").attr("data")){ ary[ary.length-1].click(); return true; }else{ return true; } return false; } //多选题选择 function choiseAnswerOptionType2(options,answers){ let choiseNum = 0; let lsAnswers = answers.replace(/\s/g,"").split("#"); if(lsAnswers.length <= 1){ lsAnswers = answers.replace(/\s/g,"").split(/[^\u4e00-\u9fa5^\w]/g); } for(let i=0;i<options.length;i++){ let option = $(options[i]); //选项体 let optionName = option.find(".answer_p").text().trim(); //选项文字 optionName = optionName.replace(/[\ |\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\||\\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?]/g,""); for(let j=0;j<lsAnswers.length;j++){ let answer = lsAnswers[j];//答案 answer = answer.replace(/[\ |\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\||\\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?]/g,"").trim(); if(optionName == answer){ if(!option.find(".check_answer_dx").attr("data")){ option.click(); } choiseNum++; } } } if(choiseNum > 0){ return true; } return false; } //填空题填空 function writeTextAnswerType3(textareas,answers){ let writeNum = 0; let lsAnswers = answers.replace(/\s/g,"").split("#"); if(lsAnswers.length <= 1){ lsAnswers = answers.replace(/\s/g,"").split(/[^\u4e00-\u9fa5^\w]/g); } if(textareas.length == lsAnswers.length){ for(let i=0;i<textareas.length;i++){ UE.getEditor(textareas[i].name).setContent(lsAnswers[i]); } return true; } return false; } //判断题选择 function choiseAnswerOptionType4(options,answer){ let zq = ["正确","是","true","True","T","对","√","ri"]; let cw = ["错误","否","false","False","F","错","×","wr"]; let lsAnswer = null; if(isInArray(zq,answer.trim())){lsAnswer = true;} if(isInArray(cw,answer.trim())){lsAnswer = false;} for (let j = 0; j < options.length; j++) { let lsOption = null; let option = $(options[j]); //选项体 let optionName = option.find(".answer_p").text().trim(); //选项文字 if(isInArray(zq,optionName)){lsOption = true;} if(isInArray(cw,optionName)){lsOption = false;} if(lsAnswer != null && lsOption != null && lsOption == lsAnswer){ if(!option.find(".check_answer").attr("data")){ option.click(); } return true; }else{ continue; } } return false; } function getAnswer(questionName,isFirst){ return new Promise(res => { let qType = $(".Cy_TItle").next().val() || '-1'; let courseId = location.search.match(/courseId=(\d+)/i)[1]; let classId= location.search.match(/classId=(\d+)/i)[1]; let knowledgeId=0 try { knowledgeId= location.search.match(/knowledgeid=(\d+)/i)[1]; } catch (err) { } GM_xmlhttpRequest({ method: 'POST', url: isFirst ? "http://onlinecoursekiller.online/OnlineCourseKiller/killer" : "http://s.jiaoyu139.com:886/get?ua=cx&v=1&keyword="+questionName+"&courseid="+courseId+"&type="+qType+"&classid="+classId+"&knowledgeid="+knowledgeId, headers: { 'Content-type': 'application/x-www-form-urlencoded' }, data: isFirst ? "q=" + questionName : "", timeout: 5000, onload: function(xhr) { if (xhr.status == 200) { if(isFirst == true){ let answer = JSON.parse(xhr.response); if (answer.success === "true") { $('<tr>' + '<td style="border: 1px solid;">0</td>' + '<td style="border: 1px solid;">' + questionName + '</td>' + '<td style="border: 1px solid;">' + answer.answer + '</td>' + '</tr>').appendTo(".question-table-tbody").css('background-color',''); }else{ $('<tr>' + '<td style="border: 1px solid;">0</td>' + '<td style="border: 1px solid;">' + questionName + '</td>' + '<td style="border: 1px solid;">' + answer.answer + '</td>' + '</tr>').appendTo(".question-table-tbody").css('background-color', 'rgba(200 ,0 ,0, 0.6)'); } }else{ let answer = JSON.parse(xhr.response); if (answer.code == 1) { $('<tr>' + '<td style="border: 1px solid;">1</td>' + '<td style="border: 1px solid;">' + questionName + '</td>' + '<td style="border: 1px solid;">' + answer.data.answer + '</td>' + '</tr>').appendTo(".question-table-tbody").css('background-color',''); }else{ $('<tr>' + '<td style="border: 1px solid;">1</td>' + '<td style="border: 1px solid;">' + questionName + '</td>' + '<td style="border: 1px solid;">' + answer.data.answer + '</td>' + '</tr>').appendTo(".question-table-tbody").css('background-color', 'rgba(200 ,0 ,0, 0.6)'); } } var divscll = document.getElementById('question-scdiv'); divscll.scrollTop = divscll.scrollHeight; }else{ getAnswer(questionName,isFirst); } setTimeout(() => { res(); }, 200); }, ontimeout: function() { } }); }); } function findAnswer(isFirst,questionName, type, question) { return new Promise(res => { let qType = question.find('input[name^=answertype]:eq(0)').val() || '-1'; let courseId = location.search.match(/courseId=(\d+)/i)[1]; let classId= location.search.match(/classId=(\d+)/i)[1]; let knowledgeId=0 try { knowledgeId= location.search.match(/knowledgeid=(\d+)/i)[1]; } catch (err) { } GM_xmlhttpRequest({ method: 'POST', url: isFirst ? "http://onlinecoursekiller.online/OnlineCourseKiller/killer" : "http://s.jiaoyu139.com:886/get?ua=cx&v=1&keyword="+questionName+"&courseid="+courseId+"&type="+qType+"&workid="+($('#workId').val() || $('#oldWorkId').val())+"&classid="+classId+"&knowledgeid="+knowledgeId, headers: { 'Content-type': 'application/x-www-form-urlencoded' }, data: isFirst ? "q=" + questionName : "", timeout: 5000, onload: function(xhr) { if (xhr.status == 200) { if(isFirst == true){ let answer = JSON.parse(xhr.response); if (answer.success === "true") { let tf = false; //1.2.4获取选项组 if (type == 1 || type == 2 || type == 4) { let answerOptions = question.find(".stem_answer .clearfix"); if(type == 1){ tf = choiseAnswerOptionType1(answerOptions,answer.answer); }else if(type == 2){ tf = choiseAnswerOptionType2(answerOptions,answer.answer); }else if(type == 4){ tf = choiseAnswerOptionType4(answerOptions,answer.answer); } } else if (type == 3) { //填空题 let textareas = question.find("textarea"); tf = writeTextAnswerType3(textareas,answer.answer); } if(tf == false){ $('<tr>' + '<td style="border: 1px solid;">' + questionName + '</td>' + '<td style="border: 1px solid;">' + answer.answer + '</td>' + '</tr>').appendTo(".question-table-tbody").css('background-color', 'rgba(200 ,0 ,0, 0.6)'); question.attr("noGetAnswer","no"); question.css('background-color', 'rgba(200 ,0 ,0, 0.6)'); unknowQuestionAnswerArray.push(question); }else{ $('<tr>' + '<td style="border: 1px solid;">' + questionName + '</td>' + '<td style="border: 1px solid;">' + answer.answer + '</td>' + '</tr>').appendTo(".question-table-tbody").css('background-color',''); question.css('background-color', 'rgba(0 ,200 ,0, 0.6)'); } }else{ $('<tr>' + '<td style="border: 1px solid;">' + questionName + '</td>' + '<td style="border: 1px solid;">' + answer.answer + '</td>' + '</tr>').appendTo(".question-table-tbody").css('background-color', 'rgba(200 ,0 ,0, 0.6)'); //未获取到答案 question.attr("noGetAnswer","no"); question.css('background-color', 'rgba(200 ,0 ,0, 0.6)'); unknowQuestionAnswerArray.push(question); } }else{ let answer = JSON.parse(xhr.response); if (answer.code == 1) { let tf = false; if (type == 1 || type == 2 || type == 4) { let answerOptions = question.find(".stem_answer .clearfix"); if(type == 1){ tf = choiseAnswerOptionType1(answerOptions,answer.data.answer); }else if(type == 2){ tf = choiseAnswerOptionType2(answerOptions,answer.data.answer); }else if(type == 4){ tf = choiseAnswerOptionType4(answerOptions,answer.data.answer); } } else if (type == 3) { //填空题 let textareas = question.find("textarea"); tf = writeTextAnswerType3(textareas,answer.data.answer); } if(tf == true && question.attr("noGetAnswer") == "no"){ question.css('background-color', 'rgba(0 ,200 ,0, 0.6)'); } } } var divscll = document.getElementById('question-scdiv'); divscll.scrollTop = divscll.scrollHeight; }else{ findAnswer(isFirst,questionName, type, question); } setTimeout(() => { res(); }, 200); }, ontimeout: function() { } }); }); } function getQueryVariable(variable) { var query = window.location.search.substring(1); var vars = query.split("&"); for (var i=0;i<vars.length;i++) { var pair = vars[i].split("="); if(pair[0] == variable){return pair[1];} } return(false); } (async function() { 'use strict'; var taolunList = []; var index = 0; $(document).on("click", "#hideButton", function() { $(".question-showdiv").show(); $(".question-div").hide(); }); $(document).on("click", "#showButton", function() { $(".question-div").show(); $(".question-showdiv").hide(); }); $(".clearfix").click(function(){ if($(this).parent().parent().attr("noGetAnswer") == "no"){ $(this).parent().parent().css('background-color', 'rgba(0 ,0 ,0, 0)'); } }); $(document).on("click",".thisCT",function(){ let div = $(".content1118 .oneRight"); let go = false; taolunList = []; for(let i=0;i<div.length;i++){ if(div.eq(i).parent().attr("id") == $(this).parent().attr("id")){ go = true; } if(go){ taolunList.push(div.eq(i).find(".bt a")); } } let val = window.open(taolunList[index].attr("href")+"&isFirstJoin=1", "讨论", "height=500, width=1500,top=200"); }); var url = location.pathname; console.log(url); if (url === "/mooc2/work/dowork") { console.log("进入作业") let div = $( '<div class="question-showdiv" style="display: none;position: fixed;top: ' + $(".subNav") .height() + 'px;right: 10px;height: 100px;width: 300px;">' + '<div style="font-size: medium;">已隐藏</div>' + '<button id="showButton">取消隐藏</button>' + '</div>' + '<div class="question-div" style="position: fixed;top: ' + $(".subNav").height() + 'px;right: 10px;height: 500px;width: 300px;z-index: 99999;background-color: rgba(190, 231, 233 ,0.9);border: 2px dashed rgb(190 ,231 ,233);">' + '<div style="font-size: medium;height:20px;" id="question">正在搜索答案...</div>' + '<button id="hideButton" style="height:20px;">隐藏显示</button>' + '<div style="max-height: 460px; overflow-y: auto;" id="question-scdiv">'+ '<table border="1" style="font-size: 12px;overflow-y: auto;">' + '<thead>' + '<tr>' + '<th style="width: 60%; min-width: 130px;">题目(点击可复制)</th>' + '<th style="min-width: 130px;">答案(点击可复制)</th>' + '</tr>' + '</thead>' + '<tbody class="question-table-tbody">' + '</tbody>' + '</table>' + '</div>'+ '</div>' ); $("body").append(div); //获取题目组 var questions = $(".questionLi"); if (questions.length === parseInt($(".infoHead span:eq(0)").text().split(':')[1])) { console.log("共" + questions.length + "题"); for (let i = 0; i < questions.length; i++) { let question = $(questions[i]); //题目体 let type = 0; if (question.attr("typename").trim() === "单选题") { type = 1 } else if (question.attr("typename").trim() === "多选题") { type = 2 } else if (question.attr("typename").trim() === "填空题") { type = 3 } else if (question.attr("typename").trim() === "判断题") { type = 4 } //获取题目 let questionName = question.find(".mark_name").text(); //题目文字 questionName = questionName.substring(questionName.indexOf(")") + 1).trim(); //查找答案 await findAnswer(true, questionName, type, question); } if(unknowQuestionAnswerArray.length > 0){ //二次查找答案 for(let i=0;i<unknowQuestionAnswerArray.length;i++){ let question = $(unknowQuestionAnswerArray[i]); //题目体 let type = 0; if (question.attr("typename").trim() === "单选题") { type = 1 } else if (question.attr("typename").trim() === "多选题") { type = 2 } else if (question.attr("typename").trim() === "填空题") { type = 3 } else if (question.attr("typename").trim() === "判断题") { type = 4 } //获取题目 let questionName = question.find(".mark_name").text(); //题目文字 questionName = questionName.substring(questionName.indexOf(")") + 1).trim(); await findAnswer(false, questionName, type, question); } } } }else if(url === "/exam/test/reVersionTestStartNew"){ console.log("进入考试"); let div = $( '<div class="question-showdiv" style="display: none;position: fixed;top: 10px;right: 10px;height: 100px;width: 300px;">' + '<div style="font-size: medium;">已隐藏</div>' + '<button id="showButton">取消隐藏</button>' + '</div>' + '<div class="question-div" style="position: fixed;top: 10px;right: 10px;height: 500px;width: 300px;z-index: 99999;background-color: rgba(190, 231, 233 ,0.9);border: 2px dashed rgb(190 ,231 ,233);">' + '<div style="font-size: medium;height:20px;" id="question">正在搜索答案...</div>' + '<button id="hideButton" style="height:20px;">隐藏显示</button>' + '<div style="max-height: 460px; overflow-y: auto;" id="question-scdiv">'+ '<table border="1" style="font-size: 12px;overflow-y: auto;">' + '<thead>' + '<tr>' + '<th>接口</th>' + '<th style="width: 60%; min-width: 130px;">题目(点击可复制)</th>' + '<th style="min-width: 130px;">答案(点击可复制)</th>' + '</tr>' + '</thead>' + '<tbody class="question-table-tbody">' + '</tbody>' + '</table>' + '</div>'+ '</div>' ); $("body").append(div); let thisQuestionName = $(".Cy_TItle div:eq(0)").text().trim().replace(/\(.*?\)/g,'').replace(/\(.*?\)/g,'').replace(/([^)]+)/g,''); getAnswer(thisQuestionName,true); getAnswer(thisQuestionName,false); }else if (url === "/bbscircle/grouptopic"){ let ct = $(".content1118"); for(let i=0;i<ct.length;i++){ ct.eq(i).append("<button class='thisCT'>从此处开始</button>"); } //重写message事件以接受打开表单页面2返回的值 window.onmessage = function (e) { var data = e.data; if (data != undefined && data != null) { console.log(data); if(data == "close"){ index += 1; if(index == taolunList.length){ alert("讨论回答完毕!"); return; } if(!taolunList[index].attr("href")){ alert("讨论回答完毕!"); return; } let val = window.open(taolunList[index].attr("href")+"&isFirstJoin=1", "讨论", "height=500, width=1500,top=200"); } } }; }else if(url == "/bbscircle/gettopicdetail"){ $("body").append(` <script> function submitTaoLun(topicId,clazzid,cpi,ut,showChooseClazzId){ var content = $("#" + topicId).val(); var img=$("#images_img_"+topicId).find("img"); var str=""; for(var i=0;i<img.size();i++){ var imgsrc=img[i]; if(i==img.size()){ str=str+imgsrc.src.replace("100_100","origin"); }else{ str=str+imgsrc.src.replace("100_100","origin")+","; } } if((content==""||content=="回复话题:"||content.trim()=='')&&str==""){ alert("请输入回复内容!"); return false; } if(typeof(cpi) == "undefined" || cpi == ""){ cpi = 0; } if(typeof(ut) == "undefined" ){ ut = "t"; } var allAttachment = getAllNoticeAttachment(); jQuery.ajax({ type: "post", url : "https://mooc1-2.chaoxing.com/bbscircle/addreply", dataType:'html', data: { clazzid : clazzid, topicId : topicId, content : content, files : str, cpi : cpi, ut : ut, attachmentFile:allAttachment, openc : getOpenc(), showChooseClazzId: showChooseClazzId }, success: function(data){ } }); } </script> `); if(getQueryVariable("isFirstJoin") == 1){ let replyfirstname = $($("[name=replyfirstname]")[Math.floor(Math.random()*$("[name=replyfirstname]").length)]); $(".oneDiv .tl1").click(); $(".oneDiv textarea").val(replyfirstname.text()); $("body").append(`<button id="subTL" onclick="submitTaoLun${$(".oneDiv textarea").parent().find("input[type=submit]").attr("onclick").match(/\((.+?)\)/g)[0]}"></button>`); $("#subTL").click(); if (window.opener) { setTimeout(function(){window.opener.postMessage("close", '*');},1500); } } } })();