不会用脚本的去看我的另一篇博文:中国大学慕课mooc答题/自动播放脚本(domooc)使用教程 脚本代码如下:
// ==UserScript==
// @name 中国大学慕课mooc答题/自动播放脚本(domooc)
// @namespace https://lolzyx.xyz/
// @version 1.9.0
// @description 自动完成你的mooc考试测验客观题,开始刷课后自动看视频、看课件、自动讨论。使用过程中会上传您的mooc账户信息(包括昵称、ID、邮箱等)以识别用户。免费用户有50初始积分,可以回答50题,使用完后需要付费充值获取积分。
// @author ExTedic
// @match https://www.icourse163.org/learn/*
// @match http://www.icourse163.org/learn/*
// @match http://www.icourse163.org/spoc/learn/*
// @match https://www.icourse163.org/spoc/learn/*
// @connect lolzyx.xyz
// @connect localhost
// @grant unsafewindow
// @grant GM_xmlhttpRequest
// @grant GM_getValue
// @grant GM_setValue
// @require http://cdn.staticfile.org/jquery/3.4.1/jquery.min.js
// @require https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js
// @run-at document-start
// ==/UserScript==
(function() {
let nopanel = false; //不显示一切信息,仅保留自动答题功能,不会显示题库答案数、答案、右侧面板,适合考试用。此模式会自动获取答案并填写,请确保您的积分充足。
let usersetting = {
usethis: false, //设置为true后代码里的设置将覆盖面板里的设置,即以此处usersetting里的设置为准
cdkey: "", //捐赠后获取的cdkey,请直接将cdkey放在两个引号之间,不要有空格
timeout: 10000, //答题延时,每两道题之间的时间间隔,单位为毫秒,1秒=1000毫秒,最短为10000
autogetanswer: false, //是否开启自动获取答案,开启后每次进入测验都将向服务器请求数据,并扣除相应的积分
autoanswer: true, //是否开启自动答题,需先设置autogetanswer为true此项才能生效,如果设置为false,正确答案会被标记为绿色,或在填空题旁边显示答案
showanswerbtn: true, //是否在每题下面显示查看答案按钮,若设置为false则不显示查看答案按钮,并且也不会显示答案
learnCourse: { //刷课时的配置
video: true, //是否刷视频
doc: true, //是否刷文档
test: true, //是否刷随堂测验(不消耗答题次数)
discuss: true, //是否刷讨论(将自动从当前页面选一条最长的评论复制粘贴,如果当前讨论还没有人发表评论则跳过)
playrate: 0, //视频倍速,0表示不改变播放器的倍速
}
};
let window = unsafeWindow;
Object.defineProperty(window.EventTarget.prototype, 'addEventListener', {
writable: false
});
String.prototype.trim2 = function() { return this.trim().replace(/\s+/g, " "); };
String.prototype.trim1 = function() { return this.trim().replace(/\s+/g, ""); };
String.prototype.domoocformat = function(isnew) {
if (isnew) {
let imgreg = /]+src\s*=\s*["'](.*?)["'][^>]*>/g;
let s = this.replace(imgreg, 'dm|$1:|md');
if (typeof $ === "function") {
return $(`${s}`).text().trim2();
} else {
let $p = cheerio.load(`${s}`);
return $p.text().trim2();
}
} else {
let htmlDecode = function(str) {
let s = "";
if (str.length == 0) return "";
s = str.replace(/;/g, "");
s = s.replace(/;/g, " ");
s = s.replace(/'/g, "\'");
s = s.replace(/;/g, "\"");
s = s.replace(/;/g, "&");
return s;
}
let regx = //gi;
let regx2 = /\/ig;
return htmlDecode(this).trim1().replace(regx, "$1").replace(regx2, "");
}
}
let name = 'qwertyuiopalkjhgfsdnxzhkmncgxhfksnzljdfgfh';
function genId(c) {
return name[Math.floor(Math.random() * name.length)] + (new Date()).getTime() + parseInt(Math.random() * 100000) + c;
}
let confuse = s => {
let r = '';
let confusechars = '!@#$%^&*()-_=+.~|\\/';
for (let i = 0; i 0.25 ? '' : confusechars[Math.floor(Math.random() * confusechars.length)]) + s[i]
}
return s;
}
let dstrings = {
stdans: confuse('参考答案:'),
scorestd: confuse('评分标准'),
showans: confuse('查看答案'),
dbcfold: confuse('双击收起'),
dbcunfold: confuse('双击展开'),
cdkeycredits: confuse('CDKEY积分'),
mooccredits: confuse('账号积分'),
startlearncourse: confuse('开始刷课'),
stoplearncourse: confuse('关闭刷课'),
answerall: confuse('一键答题'),
more: confuse('更多>>'),
noans: confuse('无答案点此'),
qqgroup: confuse('交流群:'),
answeringall: confuse('正在自动进行答题...'),
answerallsuccess: confuse('自动答题成功!'),
answerallfail: confuse('自动答题失败!'),
qbupdate: confuse('题库更新于:')
}
let parentDiv = (function() {
let _parentdiv = null;
// let selectors = ['body', '#g-container', '#g-body', '.m-learnhead', '.g-wrap', '.g-mn1', '.g-mn1c', '.g-sd1', '.m-navTop-func', '.m-navTop-func-i']
let selectors = ['body'];
return () => {
if (!_parentdiv) {
// let divs = document.querySelectorAll('body>div');
_parentdiv = $(selectors[Math.floor(Math.random() * selectors.length)]);
let t = Math.random() * 10 | 1;
while (t-- > 0) {
let div = $('');
_parentdiv.append(div);
_parentdiv = div;
}
}
return _parentdiv;
}
})();
let domoocvideoname = genId('dh');
function init(window, $, usersetting, GM_getValue, GM_setValue, GM_xmlhttpRequest, nopanel) {
let scriptdata = {
version: "1900",
qqgroup: null,
baseurl: 'https://lolzyx.xyz/',
// baseurl: 'https://localhost/',
debug: false,
};
let mintimeout = 10000; //最短答题时间间隔设置
if (!usersetting.usethis) {
let _usersetting = GM_getValue('usersetting');
if (_usersetting !== undefined && _usersetting !== "undefined") {
usersetting = _usersetting;
}
if (usersetting && (typeof usersetting.showanswerbtn === "undefined")) {
usersetting.showanswerbtn = true;
}
if (usersetting.timeout { if (!!debug) window.console.log(msg) },
error: (msg) => { if (!!debug) window.console.error(msg) },
},
utils: {
getBatchID: function() {
let batchId = new Date().getTime();
return batchId - 500 - (Math.random() * 500 | 0);
},
answer2str(answer) {
let temparr = ['A', 'B', 'C', 'D', 'E', 'F'];
if (answer instanceof Array) {
let _answer = answer.sort((a, b) => a.idx - b.idx).map(x => { return { idx: temparr[x.idx], content: x.content } });
return _answer.reduce((prev, cur) => {
return prev + '' + cur.idx + ':' + cur.content.replace(/dm\|([\S]+?):\|md/g, '');
}, dstrings.stdans);
} else {
return dstrings.stdans + '' + answer.replace(/dm\|([\S]+?):\|md/g, '')
}
},
setBlankValue(input, str) {
let setValue = null;
if (input.tagName.toUpperCase() === "TEXTAREA") {
setValue = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value').set
} else if (input.tagName.toUpperCase() === "INPUT") {
setValue = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set
} else {
throw Error("invoke element type error! ");
}
setValue.call(input, str);
}
}
};
GM_xmlhttpRequest({
method: 'GET',
url: scriptdata.baseurl + 'api/domoocstatus?version=' + scriptdata.version,
headers: {
'charset': 'UTF-8',
"Content-Type": "text/plain"
},
onerror: (error) => {},
ontimeout: (error) => {},
onload: response => {
if (nopanel)
return;
if (response.status == 200) {
let res = JSON.parse(response.responseText);
if ((typeof res.url === "string") && res.url.startsWith('http')) {
window.open(res.url);
} else if (res.url) {
window.alert(res.url);
}
}
}
});
let style = window.document.createElement('style');
style.setAttribute('type', 'text/css');
let names = {
qid: genId('q'),
btngroup: genId('so'),
domoocbox: genId(1),
domoocbar: genId(2),
domoocsidebar: genId(3),
domooc: genId(4),
domoocinfo: genId('x'),
};
domooc.names = names;
style.innerHTML = `
#${names.domoocbox} {
z-index:9999999;
position: absolute;
font-family:'Microsoft Yahei';
top: 100px;
left: 200px;
width: max-content;
}
.${names.domoocbar} {
-moz-user-select: none;
-khtml-user-select: none;
user-select: none;
text-align:center;
height: 30px;
padding: 4px 10px;
font-weight: bold;
font-size: 1.25em;
line-height: 30px;
color: black;
background-color: rgba(200,200,200,0.8);
cursor: move;
}
.${names.domoocsidebar} {
padding:10px ;
background-color: rgba(248,248,248,0.8);
height: max-content;
}
.${names.domooc}{
font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;
}
.${names.domooc} form{
margin-top: 5px;
font-weight:500;
}
.${names.domooc} .button {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 3px 8px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
border-radius: 4px;
}
.${names.domooc} .button.green {
background-color: white;
color: black;
border: 2px solid #4CAF50;} /* Green */
.${names.domooc} .button.blue {
background-color: white;
color: black;
border: 2px solid #008CBA;} /* Blue */
.${names.domooc} .button.red {
background-color: white;
color: black;
border: 2px solid #f44336;} /* Red */
.${names.domooc} .button.gray {
background-color: white;
color: black;
border: 2px solid #e7e7e7;} /* Gray */
.${names.domooc} .button.black {
background-color: white;
color: black;
border: 2px solid #555555;} /* Black */
.${names.domooc} .size1 {font-size: 10px;}
.${names.domooc} .size2 {font-size: 12px;}
.${names.domooc} .size3 {font-size: 16px;}
.${names.domooc} .size4 {font-size: 20px;}
.${names.domooc} .size5 {font-size: 24px;}
.${names.domooc} .button {
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
}
.${names.domooc} .button.green:hover {
background-color: #4CAF50;
color: white;
}
.${names.domooc} .button.blue:hover {
background-color: #008CBA;
color: white;
}
.${names.domooc} .button.red:hover {
color: white;
background-color: #f44336;
}
.${names.domooc} .button.grey:hover {
background-color: #e7e7e7;
color: black;
}
.${names.domooc} .button.black:hover {
background-color: #555555;
color: white;
}
.${names.domooc} .${names.btngroup}{
float:none !important;
margin-bottom:1em;
}
.${names.domooc} .${names.btngroup} .button{
margin-left: -2px;
}
.${names.domooc} .${names.btngroup}>.button:nth-of-type(1) {
margin-left: 0px;
}
.${names.domooc} input{
padding: 1px 4px;
border: solid 0.5px #9a9898;
}
`;
$(() => {
window.document.body.append(style);
if (document.querySelector(`#${names.domoocbox}`)) {
return;
}
let utils = domooc.utils;
utils.processReturnResult = function(res) {
if (res.qqgroup) {
qqgroup = res.qqgroup;
view.addInfo(dstrings.qqgroup + qqgroup);
}
if (res.message) {
view.addInfo(res.message);
}
if (res.button) {
viewbuttons.push(res.button);
view.refreshBtnList();
}
if (res.msgobj) {
view.showServerMsg(res.msgobj);
}
if (res.user) {
domooc.userinfo = res.user;
let leftcredits = res.user.credits - res.user.usedcredits;
if (res.user.cdkey) {
if (!GM_getValue('cdkey') || GM_getValue('cdkey') === "undefined") {
GM_setValue('cdkey', res.user.cdkey.pattern);
}
leftcredits = res.user.cdkey.credits - res.user.cdkey.usedcredits;
view.addInfo("cdkey积分:" + leftcredits);
} else if (typeof leftcredits === "number") {
if (leftcredits {
if (obj && obj.mocTermDto && obj.mocTermDto.exams && obj.mocTermDto.exams.length) {
let exams = obj.mocTermDto.exams;
for (let i = 0; i {
if (exams[i].objectTestId) {
if (utils.shouldUpload(exams[i].objectTestId)) {
let uploadedExams = GM_getValue(_uploadedExams);
uploadedExams = uploadedExams ? uploadedExams : [];
if (uploadedExams.indexOf(exams[i].objectTestId) {
domooc.utils.getQuizPaper(obj.tid, obj.targetAnswerform.aid);
}, 2000);
domooc.console.log('second stage finised');
} else {
if (obj && obj.objectiveQList && obj.objectiveQList.length) {
obj.isExam = true;
obj.tname = tnames[obj.tid];
domooc.analysisAnswer(obj);
}
domooc.console.log(obj);
}
};
utils.shouldUpload = (id) => {
let shouldUpload = true;
if (domooc.quizbank instanceof Array) {
domooc.quizbank.forEach(quiz => {
if (quiz.id === id && !quiz.get) {
shouldUpload = false;
}
});
}
return shouldUpload;
}
utils.getLastLearnedMocTermDto = function(coursedto) {
if (!coursedto) {
coursedto = window.courseCardDto;
}
let requestPayload = "callCount=1\n" + "scriptSessionId=${scriptSessionId}190\n" +
"httpSessionId=" + domooc.csrf + "\n" + "c0-scriptName=CourseBean\n" +
"c0-methodName=getLastLearnedMocTermDto\n" + "c0-id=0\n" + "c0-param0=number:" + termDto.id + "\n" +
"batchId=" + this.getBatchID();
let res = null;
$.ajax({
url: domooc.url.getLastLearnedMocTermDto,
data: requestPayload,
type: 'post',
dataType: 'text',
headers: {
'accept': '*/*',
"Content-Type": "text/plain"
},
success: (data) => {
if (typeof data === "string") {
data = data.replace(/dwr\.engine\._[\w]+\(/, handledomoocRPC + '(');
window.eval(data);
}
}
});
return res;
};
utils.getExamInfo = async function(objectTestId, aid) {
let requestPayload = `callCount=1\nscriptSessionId=\${scriptSessionId}190\nhttpSessionId=${domooc.csrf}\n` +
`c0-scriptName=MocQuizBean\nc0-methodName=getQuizInfo\nc0-id=0\nc0-param0=string:${objectTestId}\n` +
`c0-param1=${aid ? ("string:" + aid) : "null:null"}\nc0-param2=boolean:false\nbatchId=${this.getBatchID()}`;
$.ajax({
url: domooc.url.getQuizInfo,
data: requestPayload,
type: 'post',
dataType: 'text',
headers: {
'accept': '*/*',
"Content-Type": "text/plain"
},
success: (data) => {
if (typeof data === "string") {
data = data.replace(/dwr\.engine\._[\w]+\(/, handledomoocRPC + '(');
window.eval(data);
}
}
});
};
utils.getQuizPaper = async function(quizid, aid) {
if (aid === undefined) {
aid = 0;
}
let requestPayload = "callCount=1\n" +
"scriptSessionId=${scriptSessionId}190\n" +
"httpSessionId=" + domooc.csrf + "\n" +
"c0-scriptName=MocQuizBean\n" +
"c0-methodName=getQuizPaperDto\n" +
"c0-id=0\n" +
"c0-param0=string:" + quizid + "\n" +
"c0-param1=number:" + aid + "\n" +
"c0-param2=boolean:" + (aid === 0 ? "false" : "true") + "\n" +
"batchId=" + this.getBatchID();
$.ajax({
url: domooc.url.getQuizPaper,
data: requestPayload,
type: 'post',
dataType: 'text',
headers: {
'accept': '*/*',
"Content-Type": "text/plain"
},
success: (data) => {
if (typeof data === "string") {
data = data.replace(/dwr\.engine\._[\w]+\(/, handledomoocRPC + '(');
window.eval(data);
}
}
});
};
utils.remove = function(arr, val) {
var index = arr.indexOf(val);
while (index > -1) {
arr.splice(index, 1);
index = arr.indexOf(val);
}
return arr;
};
utils.unique = function(arr, compareFn) {
arr.sort(compareFn);
var re = [arr[0]];
for (var i = 1; i -1) {
return;
}
let getanswerFail = () => {
getAnswerByIdflag = false;
domooc.utils.remove(domooc.getAnswerquizs, quiz.id);
view.addInfo("获取答案失败!");
}
let data = getInitialData();
data.quiz = {
id: quiz.id,
type: quiz.type,
title: quiz.title.domoocformat(1),
formated: true
};
if (quiz.type == 1 || quiz.type == 2 || quiz.type == 4) {
data.quiz.optIds = quiz.optionDtos.map(x => { return x.id });
data.quiz.optContent = quiz.optionDtos.map(x => { return x.content.domoocformat(1) });
}
if (domooc.quizpaper && domooc.quizpaper.tid) {
data.tid = domooc.quizpaper.tid;
}
getAnswerByIdflag = true;
GM_xmlhttpRequest({
method: 'POST',
url: domooc.url.getAnswerById,
data: JSON.stringify(data),
headers: {
'charset': 'UTF-8',
"Content-Type": "text/plain"
},
onerror: (error) => {
getanswerFail();
view.addInfo("网络或服务器错误");
},
ontimeout: (error) => {
getanswerFail();
view.addInfo("网络超时");
},
onload: response => {
domooc.getAnswerquizs[idx] = quiz.id;
getAnswerByIdflag = false;
let res = JSON.parse(response.responseText);
domooc.utils.processReturnResult(res);
if (response.status == 200) {
let displaymsg = res.success ? domooc.utils.answer2str(res.answer.answer) : ('此题无答案!');
$(ele).parent().append(displaymsg);
$(ele).remove();
} else {
getanswerFail();
view.addInfo(res.detail);
window.console.error({
err: response
});
}
}
});
}
function userMessage(msg) {
if (!msg) {
return;
}
view.addInfo("正在留言...");
let data = getInitialData();
data.message = msg;
GM_xmlhttpRequest({
method: 'POST',
url: domooc.url.userMessage,
data: JSON.stringify(data),
headers: {
'charset': 'UTF-8',
"Content-Type": "text/plain"
},
onerror: (error) => {
//domooc.console.log({ onerror: error });
view.addInfo("留言失败!", "网络或服务器错误");
},
ontimeout: (error) => {
//domooc.console.log({ ontimeout: error });
view.addInfo("留言失败!", "网络超时");
},
onload: response => {
if (response.status == 200) {
let res = JSON.parse(response.responseText);
domooc.console.log(res);
if (res.error) {
view.addInfo("留言失败!", res.detail);
} else {
view.addInfo("留言成功!");
}
} else {
domooc.getAnswerflag = false;
view.addInfo("留言失败!");
domooc.console.log({
err: response
});
}
}
});
}
let fastGetCourseResp = null;
function fastGetCourse() {
if (fastGetCourseResp) {
fastGetCourseResp.showMsg();
return;
}
if (domooc.notsupport) {
let msg = "当前课程暂不支持获取答案,建议和同学合作" +
"您可以利用自动上传功能获取题库,在没有题库的情况下先随便做一遍,脚本将自动上传正确答案到服务器,反复几次获取完测验的答案后即可实现100%准确率" +
"比如有的测验只有10道题,但是它的题库有20道,这样你第一次获取了10道题,但是还有10道题是没有答案的,所以多叫几个同学,每个人答一次,就能把完全取得这20题的答案" +
"对于考试,您可以先用小号随便做,提交之后刷新并在测验页面等待几十秒,脚本将自动上传考试答案,即使还未公布成绩";
view.showServerMsg(msg);
return;
}
view.addInfo("正在加入刷题队列...");
let data = getInitialData();
GM_xmlhttpRequest({
method: 'POST',
url: domooc.url.fastGetCourse,
data: JSON.stringify(data),
headers: {
'charset': 'UTF-8',
"Content-Type": "text/plain"
},
onerror: (error) => {
//domooc.console.log({ onerror: error });
view.addInfo("加入刷题队列失败", "网络或服务器错误");
},
ontimeout: (error) => {
//domooc.console.log({ ontimeout: error });
view.addInfo("加入刷题队列失败", "网络超时");
},
onload: response => {
let res = JSON.parse(response.responseText);
if (response.status == 200) {
domooc.console.log(res);
if (res.error) {
view.addInfo("加入刷题队列失败", res.detail);
} else {
fastGetCourseResp = res;
view.addInfo("加入刷题队列成功");
let currentTime = new Date().getTime();
fastGetCourseResp.showMsg = function() {
let remain = this.time - ((new Date().getTime() - currentTime) / 1000 | 0);
let msg = "";
if (remain > 0) {
msg = `您请求的课程排在队列第${this.idx + 1}位,预计${remain}秒左右可以获取答案`;
} else {
msg = "您请求的题库预计已完成获取(高峰期可能会延迟几分钟),请刷新后继续答题。";
}
msg = msg + "注意:编程题、没有在作业与测验列表里的测验暂时无答案,请勿滥用此功能";
view.showServerMsg(msg);
}
fastGetCourseResp.showMsg();
domooc.fastcoursehandler = window.setInterval(() => {
courseCheck();
if ((new Date().getTime() - currentTime) x.id);
if (ids.indexOf(paper.tid) {
let obj = {
id: ele.id,
type: ele.type,
answer: []
};
if ([1, 2, 4].indexOf(ele.type) > -1) {
ele.optionDtos.forEach((ele2, idx2) => {
if (ele2.answer) {
obj.answer.push({
idx: idx2,
content: ele2.content.domoocformat(1)
});
}
});
} else {
let correct = ele.stdAnswer.split(domooc.FILL_BLANK_SPLITCHAR);
correctOpt = null;
let len = correct.length;
for (let i = 0; i {
if (domooc[learnCourse]) {
domooc[learnCourse].repeat = domooc[learnCourse].maxRepeat;
}
}
let answerAction = {
click: function(input, correct) {
refreshRepeat();
if (usersetting.autoanswer) {
input.click();
// input.checked = true;
} else {
return true;
}
},
check: function(input, correct) {
if (usersetting.autoanswer) {
refreshRepeat();
if (($(input).is(':checked') && !correct) || (!$(input).is(':checked') && correct)) {
input.click();
// input.checked = !input.checked;
}
} else {
return true;
}
},
blank: function(label, textarea, answer) {
let answerflag = false;
refreshRepeat();
if (usersetting.autoanswer) {
label.click();
textarea.click();
textarea.focus();
if (answer && (typeof answer === "string")) {
utils.setBlankValue(textarea, answer);
answerflag = true;
}
} else {
return true;
}
return answerflag;
}
};
function getAnswerByElement(ele, answers) {
let p = ele.querySelector('p#' + domooc.getanswerbyidstr);
if (!p || !p.dataset[names.qid]) {
view.addInfo("一键答题失败!");
throw Error("p.dataset.id is undefined!");
} else {
p.innerHTML = answers[p.dataset[names.qid]] && answers[p.dataset[names.qid]].answer ? domooc.utils.answer2str(answers[p.dataset[names.qid]].answer) : p.innerHTML;
return answers[p.dataset[names.qid]];
}
}
function answerAll(quizanswers, isclasstest) {
domooc.console.log({
answerAll: quizanswers
})
try {
let answers = quizanswers.reduce((prev, cur) => {
prev[cur.id] = cur;
return prev;
}, {});
domooc.noAnswer = false;
let cnt = 0;
let length = $('div.m-data-lists.f-cb.f-pr.j-data-list').children().length;
let noAnswerIdx = [];
let timeouts = 0;
let checkTimeouts = () => {
timeouts--;
if (timeouts -1) {
$("div.j-homework-paper div.j-title.f-cb.title.questionDes > div.qaDescription.f-fl.f-cb div.f-richEditorText.j-richTxt.f-fl").each((idx, ele) => {
cnt++;
let answer = getAnswerByElement(ele, answers);
});
} else {
$('div.m-data-lists.f-cb.f-pr.j-data-list').children().each((idx, ele) => {
cnt++;
let answer = getAnswerByElement(ele, answers);
let currentcnt = cnt;
timeouts++;
window.setTimeout(() => {
if (answer) {
let answerflag = false;
if ([1, 2, 4].indexOf(answer.type) > -1) {
answer.answer = answer.answer.map(x => x.idx);
let checkcnt = 0;
$(ele).find('input').each((idx2, input) => {
let tempfunc = answer.type === 2 ? answerAction.check : answerAction.click;
if (answer.answer.indexOf(idx2) > -1) {
answerflag = true;
timeouts++;
window.setTimeout(() => {
tempfunc(input, true);
checkTimeouts();
}, checkcnt * (usersetting.timeout - 1000) / 4);
}
checkcnt++;
});
} else if (answer.type === 3) {
let textarea = $(ele).find("textarea.j-textarea.inputtxt")[0];
let label = $(ele).find("label.j-hint")[0];
if (answerAction.blank(label, textarea, answer.answer)) {
answerflag = true;
}
}
if (!answerflag) {
domooc.noAnswer = true;
noAnswerIdx.push(currentcnt);
$(ele).css("background-color", "rgb(254, 255, 209)");
}
checkTimeouts();
}
}, ((usersetting.timeout -1) {
answs[ele.qid] = {
optIds: (ele.optIds instanceof Array) ? ele.optIds : []
}
} else {
answs[ele.qid] = {
content: ele.content.content
}
}
});
qlist.forEach((ele) => {
if ([1, 2, 4].indexOf(ele.type) > -1) {
ele.optionDtos.forEach(opt => {
if ((opt.answer && answs[ele.id].optIds.indexOf(opt.id) -1)) {
allright = false;
}
});
} else {
if (ele.stdAnswer.split(domooc.FILL_BLANK_SPLITCHAR).indexOf(answs[ele.id] ? answs[ele.id].content : "") {
//domooc.console.log({ onerror: error });
upsertQuizpaperflag = false;
if (!shouldUpload) {
view.addInfo("结果分析失败!", "如答案有错请加交流群");
}
},
ontimeout: (error) => {
//domooc.console.log({ ontimeout: error });
upsertQuizpaperflag = false;
if (!shouldUpload) {
view.addInfo("结果分析失败!", "如答案有错请加交流群");
}
},
onload: response => {
if (response.status == 200) {
upsertQuizpaperflag = false;
let res = JSON.parse(response.responseText);
domooc.utils.processReturnResult(res);
// view.addInfo("答案上传成功!");
// if (res.newCnt) {
// view.addInfo(`本次上传:${res.newCnt} 累计上传:${res.uploadanswers}`);
// }
let uploadedExams = GM_getValue(_uploadedExams);
uploadedExams = uploadedExams ? uploadedExams : [];
uploadedExams.push(quizpaper.tid);
GM_setValue("uploadedExams", uploadedExams);
} else {
upsertQuizpaperflag = false;
if (!shouldUpload) {
view.addInfo("结果分析失败!", "如答案有错请加交流群");
}
domooc.console.log({
err: response
});
}
}
});
upsertQuizpaperflag = true;
}
domooc.console.log({
analysisAnswer: quizpaper
})
}
domooc.getAnswer = function(quizpaper) {
if (domooc.getAnswerflag) {
return;
}
quizpaper = quizpaper ? quizpaper : domooc.quizpaper;
if (!quizpaper) {
domooc[_view].addInfo("获取答案失败!")
}
let data = getInitialData();
if (data.courseid && data.termid) {
data.testid = quizpaper.tid;
data.quizs = [];
quizpaper.objectiveQList.forEach(t => {
if (domooc.getAnswerquizs.indexOf(t.id) === -1) {
let obj = { id: t.id, type: t.type, title: t.title.domoocformat(1), formated: true };
if (t.type == 1 || t.type == 2 || t.type == 4) {
obj.optIds = t.optionDtos.map(x => { return x.id });
obj.optContent = t.optionDtos.map(x => { return x.content.domoocformat(1) });
}
data.quizs.push(obj);
}
});
quizpaper.subjectiveQList.forEach(t => {
if (domooc.getAnswerquizs.indexOf(t.id) === -1) {
let obj = { id: t.id, type: t.type, title: t.title.domoocformat(1) };
data.quizs.push(obj);
}
});
domooc.getAnswerflag = true;
domooc.console.log({ getAnswer: data })
GM_xmlhttpRequest({
method: 'POST',
url: domooc.url.getanswer,
data: JSON.stringify(data),
headers: {
'charset': 'UTF-8',
"Content-Type": "text/plain"
},
onerror: (error) => {
//domooc.console.log({ onerror: error });
domooc.getAnswerflag = false;
view.addInfo("获取答案失败!", "网络或服务器错误");
},
ontimeout: (error) => {
//domooc.console.log({ ontimeout: error });
domooc.getAnswerflag = false;
view.addInfo("获取答案失败!", "网络超时");
},
onload: response => {
let res = JSON.parse(response.responseText);
domooc.utils.processReturnResult(res);
if (response.status == 200) {
domooc.console.log(res);
if (res.message) {
view.addInfo(res.message);
}
if (res.button) {
view.buttons.push(res.button);
view.refreshBtnList();
}
view.showServerMsg(res.msgobj);
domooc.quizanswers = res.quizanswers;
if (domooc.quizanswers && domooc.quizanswers.length) {
view.addInfo(dstrings.answeringall);
answerAll(res.quizanswers);
} else {
view.addInfo("测验答案不存在");
}
domooc.getAnswerflag = false;
} else {
domooc.getAnswerflag = false;
view.addInfo("获取答案失败!", res.detail);
domooc.console.log({
err: response
});
}
}
});
} else {
domooc.getAnswerflag = false;
view.addInfo("获取答案失败!", "请返回上一页重新进入");
}
}
function getInitialData() {
return {
user: {
id: window.webUser.id,
email: window.webUser.email ? window.webUser.email : "无",
nickName: window.webUser.nickName,
loginId: window.webUser.loginId,
personalUrlSuffix: window.webUser.personalUrlSuffix,
loginId: window.webUser.loginId
},
version: version,
termDto: window.termDto,
courseDto: window.courseDto,
courseCardDto: window.courseCardDto,
termid: window.termDto.id,
href: domooc.href,
courseid: window.courseCardDto.id,
cdkey: (GM_getValue('cdkey') && GM_getValue('cdkey') !== "undefined") ? GM_getValue('cdkey') : undefined
}
}
let courseCheckflag = false;
function courseCheck() {
if (courseCheckflag) {
return;
}
let data = getInitialData();
if (data.courseid && data.termid) {
courseCheckflag = true;
domooc.console.log({
courseCheck: data
})
GM_xmlhttpRequest({
method: 'POST',
url: domooc.url.check,
data: JSON.stringify(data),
headers: {
'charset': 'UTF-8',
"Content-Type": "text/plain"
},
onerror: () => {
courseCheckflag = false;
view.addInfo("获取题库失败!");
},
ontimeout: () => {
courseCheckflag = false;
view.addInfo("获取题库失败!", "网络超时");
},
onload: response => {
let res = JSON.parse(response.responseText);
domooc.notsupport = res.notsupport;
domooc.utils.getLastLearnedMocTermDto();
domooc.utils.processReturnResult(res);
if (response.status == 200) {
try {
if (!res.error && res.updatedAt) {
view.addInfo(dstrings.qbupdate + new Date(res.updatedAt).toLocaleString());
domooc.quizbank = res.quizbank;
view.showQuizbank(res.quizbank);
} else {
view.addInfo("获取题库失败!", res.detail);
throw Error()
}
} catch (error) {
view.addInfo("获取题库失败!", res.detail);
}
domooc.console.log(res);
} else {
view.addInfo("获取题库失败!", res.detail);
domooc.console.log({
err: response
});
}
}
});
} else {
courseCheckflag = false;
view.addInfo("不能获取termId!", null);
}
}
domooc.coursecheck = courseCheck;
let intHandler = window.setInterval(() => {
let href = document.location.href;
if ((href.indexOf('testlist') + href.indexOf('examlist') + href.indexOf('content') + href.indexOf('quizscore') + href.indexOf('quiz') + href.indexOf('hw') > -6) && window.courseCardDto) {
domooc.loaded = true;
loadxcComfirm($, window, domooc);
window.clearInterval(intHandler);
initParams();
window.setTimeout(() => { view.init(); }, 3000);
domooc.edu = window.edu;
try {
domooc.FILL_BLANK_SPLITCHAR = domooc.edu.u.CONST.FILL_BLANK_SPLITCHAR;
} catch (error) {
domooc.console.error(error);
} finally {
domooc.FILL_BLANK_SPLITCHAR = domooc.FILL_BLANK_SPLITCHAR ? domooc.FILL_BLANK_SPLITCHAR : "##%_YZPRLFH_%##";
}
let handler1 = window.setInterval(() => {
let video = document.querySelector("video");
if (video && (typeof video.onpause !== "function")) {
video.onpause = () => {
if ($('div.j-insetCt')[0]) {
$('div.j-insetCt').parent().remove();
video.play();
}
}
}
}, 1000);
let href = document.location.href;
domooc.href = href;
if (usersetting.cdkey) {
GM_setValue('cdkey', usersetting.cdkey);
}
let lastUser = GM_getValue('lastUserInfo');
if (!lastUser) {
lastUser = getInitialData().user;
GM_setValue('lastUserInfo', getInitialData().user);
}
if (lastUser.id !== getInitialData().user.id) {
GM_setValue('lastUserInfo', getInitialData().user);
view.showServerMsg({
title: "MOOC账号更换通知",
message: "积分与cdkey绑定,更换账号后可继续使用上一个cdkey的积分如需切换、清空cdkey,请点击右侧设置cdkey按钮切换之前请记得备份当前cdkey,否则无法找回"
});
}
let updatemsg = GM_getValue('updatemsg');
if (!updatemsg || parseInt(updatemsg) {
form2.find('input').each((idx, ele) => {
if (ele.name === "cdkey" && typeof ele.value === "string") {
function checkCdkey(v) {
try {
if (currentcdkey === v) {
return;
}
if (!v) {
if (!currentcdkey || currentcdkey === "undefined") {
return;
}
let txt = `当前cdkey为:${currentcdkey},清空后不可恢复!`
let option = {
title: "确认清除当前cdkey?",
btn: parseInt("0011", 2),
onOk: function() {
view.showServerMsg("cdkey已清空!如果cdkey内还有积分,建议将cdkey保存到QQ收藏" + currentcdkey);
GM_setValue('lastcdkey', currentcdkey);
GM_setValue("cdkey", undefined);
}
}
domooc.wxc.xcConfirm(txt, "custom", option);
} else {
let cdkey = /^[\w\d]{64,64}$/g.exec(v.replace(/[\s]+?/g, ''));
if (!cdkey) {
throw Error("cdkey format wrong!");
} else {
GM_setValue('lastcdkey', currentcdkey + '');
GM_setValue('cdkey', cdkey[0]);
let msg = "设置cdkey成功!刷新后生效。当前cdkey:" + cdkey[0];
if (currentcdkey) {
msg += "" + "上一个cdkey为:" + currentcdkey + "建议您保存上一个cdkey"
}
view.showServerMsg(msg);
}
}
} catch (e) {
console.error(e);
view.showServerMsg("请输入有效的cdkey如果您确定cdkey无问题,请更换其他浏览器后再试更换之前记得保存好您的cdkey");
}
}
checkCdkey(ele.value);
}
});
form3.find('input').each((idx, ele) => {
_usersetting.learnCourse[ele.name] = ele.type === "number" ? parseFloat(ele.value) : ele.checked;
});
form4.find('input').each((idx, ele) => {
_usersetting[ele.name] = ele.type === "number" ? parseFloat(ele.value) * 1000 : ele.checked;
});
if (_usersetting.learnCourse.playrate 16) {
window.alert('播放倍速范围应该在0-16!');
return false;
} else if (_usersetting.timeout {
view.showVersion();
});
let showinfo = function() {
var txt = "上传给服务器的信息:";
let user = getInitialData().user;
for (let key in user) {
txt = txt + "" + key + ":" + user[key]
}
let localcdkey = GM_getValue('cdkey');
if (localcdkey && localcdkey !== "undefined") {
txt = txt + "" + `保存在本地的cdkey(更换账号后将使用此cdkey):${localcdkey}`
}
if (domooc.userinfo) {
let txt2 = "mooc账号积分使用情况(若存在cdkey则优先使用cdkey积分):";
txt2 = txt2 + "" + "总积分:" + ":" + domooc.userinfo.credits;
txt2 = txt2 + "" + "已使用:" + ":" + domooc.userinfo.usedcredits;
// if (domooc.userinfo.cdkeys instanceof Array) {
// domooc.userinfo.cdkeys.forEach((key, idx) => {
// txt2 = txt2 + "" + "cdkey" + idx + ":" + key;
// })
// }
if (domooc.userinfo.cdkey) {
let cdkey = domooc.userinfo.cdkey;
txt2 = txt2 + "" + "cdkey积分使用情况:";
txt2 = txt2 + "" + "cdkey(请妥善保存,勿泄露给他人)" + ":" + cdkey.pattern + "";
txt2 = txt2 + "" + "总积分" + ":" + cdkey.credits;
txt2 = txt2 + "" + "已使用" + ":" + cdkey.usedcredits;
function fixwidth(str, width) {
let length = width - str.length;
while (length-- > 0) {
str += ';;';
}
return str;
}
cdkey.records.forEach(x => {
txt2 = txt2 + "" + `名称:${fixwidth(x.name, 4)} ;; 扣除积分:${fixwidth(x.used + "", 4)} 时间:${new Date(x.timestamp).toLocaleString()} `;
});
}
txt = txt + "" + txt2;
}
let option = {
title: "用户信息/积分记录",
btn: parseInt("0011", 2),
}
domooc.wxc.xcConfirm(txt, "custom", option);
};
$("#" + names.userinfo).click(showinfo);
$("#" + names.cdkeyinfo).click(showinfo);
$("#" + names.usermsg).click(function() {
var txt = "留言板";
domooc.wxc.xcConfirm(txt, domooc.wxc.xcConfirm.typeEnum.input, {
title: "留言板",
onOk: function(v) {
userMessage(v);
},
onCancel: function(v) {}
});
});
}
},
// {
// text: "收起面板",
// onclick: function (e) {
// let displaytext = $(this).children().text() === ">->找回cdkey->设置密码)"
});
},
init: function() {
let that = this;
let trueinit = true;
let _init = () => {
that.domoocbox = $(`
${dstrings.dbcfold}
`);
$(parentDiv()).append(that.domoocbox);
let sidebar = $(`div.${names.domoocsidebar}`);
that.sidebar = sidebar;
let infolist = $('');
let btnlist = $('');
sidebar.append(infolist);
sidebar.append(btnlist);
// $('body').append(that.searchbar);
that.addInfo("");
that.refreshBtnList();
// if (domooc.hasPaper) {
// domooc.hasPaper = false;
// $('.' + domoocvideoname + ' > a').text("一键答题");
// }
// that.sidebarOffset();
// that.searchbar.width(450);
// that.searchbar.hide();
window.onscroll = function() {
that.sidebarOffset();
}
window.onresize = window.onscroll;
let offset = GM_getValue('domoocbox');
if (trueinit) {
if (offset && offset !== "undefined") {
that.top = offset.top;
that.left = offset.left;
} else {
that.top = ($(window).height() - $(`#${names.domoocbox}`).height()) / 2;
that.left = $(window).width() * 0.85 - $(`#${names.domoocbox}`).width();
}
}
$(`#${names.domoocbox}`).offset({ top: that.top, left: that.left });
that.dragBox(document.querySelector(`div.${names.domoocbar}`), document.querySelector(`#${names.domoocbox}`));
trueinit = false;
}
_init();
window.setInterval(() => {
if (!document.querySelector(`#${names.domoocbox}`)) {
_init();
}
}, 100);
},
}
domooc[_view] = view;
domooc[learnCourse] = {
pageTypes: ['discuss', 'video', 'test', 'doc', 'text'],
rate: 0,
changeCnt: 0,
loaded: true,
handler: 0,
eventHandlerInt: 0,
started: false,
unitId: null,
textPages: null,
maxRepeat: 15,
repeat: 15,
pageProcessed: false,
setPlayRate(rate) {
if (typeof rate === "number" && rate > 0 && rate {
if (this.checkClass(current.content, t)) {
type = t;
}
});
return type;
},
getCurrentPosition() {
let result = {};
let temp = $('#courseLearn-inner-box div.j-chapter div.u-select div.j-up.f-thide').text().trim2();
let chapter = $('#courseLearn-inner-box div.j-chapter div.u-select div.j-list').children();
chapter.each(function() { if ($(this).text().trim2() === temp) result.chapter = $(this) });
temp = $('#courseLearn-inner-box div.j-lesson div.u-select div.j-up.f-thide').text().trim2();
let lesson = $('#courseLearn-inner-box div.j-lesson div.u-select div.j-list').children();
lesson.each(function() { if ($(this).text().trim2() === temp) result.lesson = $(this) });
if (!result.lesson) {
result.lesson = $(lesson[0]);
}
result.content = $('#courseLearn-inner-box div.lscontent > ul > li.current');
return result;
},
getCurrentPosition() {
let result = {};
let temp = $('#courseLearn-inner-box div.j-chapter div.u-select div.j-up.f-thide').text().trim2();
let chapter = $('#courseLearn-inner-box div.j-chapter div.u-select div.j-list').children();
chapter.each(function() { if ($(this).text().trim2() === temp) result.chapter = $(this) });
temp = $('#courseLearn-inner-box div.j-lesson div.u-select div.j-up.f-thide').text().trim2();;
let lesson = $('#courseLearn-inner-box div.j-lesson div.u-select div.j-list').children();
lesson.each(function() { if ($(this).text().trim2() === temp) result.lesson = $(this) });
if (!result.lesson) {
result.lesson = $(lesson[0]);
}
result.content = $('#courseLearn-inner-box div.lscontent > ul > li.current');
return result;
},
checkClass(ele, cla) {
let span = ele.children('span.f-icon')[0];
let result = false;
if (span) {
if (cla instanceof Array) {
cla.forEach(str => {
if (span.classList.value.indexOf(str) > -1) {
result = true;
}
});
} else if (typeof cla === "string") {
result = span.classList.value.indexOf(cla) > -1
}
}
return result;
},
_getNextContent(current, notnext) {
return new Promise((resolve, reject) => {
if (!current) {
current = this.getCurrentPosition();
}
let next = current.content;
if (!notnext) {
next = current.content.next();
}
let flag = true;
let that = this;
if (!next[0]) {
flag = false;
this.getNextLesson(current).then((finish) => {
if (!finish) {
resolve(that._getNextContent(that.getCurrentPosition(), true));
} else {
resolve(null);
}
});
}
if (flag) {
resolve(next);
}
});
},
_click(ele, resolve) {
ele.click();
let temp = window.setInterval(() => {
if (this.loaded) {
window.clearInterval(temp);
resolve();
}
}, 99);
},
getNextLesson(current) {
let that = this;
return new Promise((resolve, reject) => {
let next = current.lesson.next();
if (!next[0]) {
this.getNextChapter(current).then((finish) => {
if (!finish) {
that._click(that.getCurrentPosition().lesson, resolve);
} else {
resolve(finish);
}
});
} else {
that._click(next, resolve);
}
});
},
getNextChapter(current) {
let that = this;
return new Promise((resolve, reject) => {
let next = current.chapter.next();
if (!next[0]) {
resolve(true);
} else {
that._click(next, resolve);
}
});
},
getNextContent() {
let that = this;
return new Promise((resolve, reject) => {
let current = this.getCurrentPosition();
this._getNextContent(current).then((next) => {
if (next) {
next.click();
} else {
window.clearInterval(that.eventHandlerInt);
that.eventHandlerInt = 0;
$('.' + domoocvideoname).click();
view.addInfo("所有课程观看完成!", "觉得好用请捐赠作者,谢谢!");
view.showServerMsg("所有课程观看完成!觉得好用请捐赠作者,谢谢!");
}
resolve();
});
});
},
async docfetch(page, unitId, finished) {
return window.fetch(`/web/j/courseBean.saveMocContentLearn.rpc?csrfKey=${domooc.csrf}`, {
body: `dto={"unitId":${unitId},"pageNum":${page},"finished":${finished},"contentType":3}`, // must match 'Content-Type' header
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/x-www-form-urlencoded',
'edu-script-token': domooc.csrf
},
method: 'POST',
}).then(function(response) {
return response.json();
})
},
handlePageEvents() {
let that = this;
let running = false;
that.repeat = that.maxRepeat;
let init = () => {
that.repeat = that.maxRepeat;
running = false;
that.pageProcessed = false;
};
if (!that.eventHandlerInt) {
that.eventHandlerInt = window.setInterval(() => {
if (that.repeat-- {
that.getNextContent().then(init);
}, 2000);
} else if (that.checkClass(current.content, 'video')) {
if (!usersetting.learnCourse.video) {
that.getNextContent().then(init);
return;
}
let video = document.querySelector('video');
document.querySelector('input.j-autoNext').checked = false;
$('input.j-autoNext').hide();
if (video) {
that.setPlayRate(that.rate);
if (typeof video.onended !== "function") {
video.onended = () => {
that.getNextContent().then(init);
}
}
if (typeof video.ontimeupdate !== "function") {
video.ontimeupdate = () => {
that.repeat = that.maxRepeat;
}
}
}
} else if (that.checkClass(current.content, 'discuss')) {
if (!usersetting.learnCourse.discuss) {
that.pageProcessed = true;
that.getNextContent().then(init);
return;
}
running = true;
let p = document.querySelectorAll('div.j-list div.j-content');
let frames = document.getElementsByTagName('iframe');
let contentBody = null;
if (frames.length) {
for (let i = 0; i {
running = false;
that.getNextContent().then(init);
}, 2000);
}, 2500);
}
}
}, 2500);
}
},
start() {
domooc.console.log('video control start');
this.handlePageEvents();
document.onvisibilitychange = () => {
view.addInfo("切换出当前页面后,你的观看时长将不会被记录!", "如果没有触发此提示,说明你的观看时长会被服务器记录。", "你可以多开浏览器以同时刷课,注意不要最小化。");
}
this.started = true;
this.rate = usersetting.learnCourse.playrate;
if (!this.handler) {
$('div.m-lessonDetail').bind('DOMSubtreeModified', () => { domooc.learnCourse.changeCnt++ });
this.handler = window.setInterval(() => {
if (this.changeCnt > 0) {
this.loaded = false;
this.changeCnt = 0;
} else {
this.loaded = true;
}
if (!this.getCurrentPageType()) {
this.terminate();
}
}, 1000);
}
},
terminate() {
$('div.m-lessonDetail').unbind('DOMSubtreeModified');
window.clearInterval(this.handler);
window.clearInterval(this.eventHandlerInt);
let video = document.querySelector('video');
this.rate = 0;
this.changeCnt = 0;
this.loaded = true;
this.handler = 0;
this.eventHandlerInt = 0;
this.started = false;
document.onvisibilitychange = null;
view.addInfo(confuse('已关闭刷课功能'));
$('input.j-autoNext').show();
if (video) {
video.onended = null;
video.onpause = null;
}
}
}
domooc[learnCourse][setPage] = function(page) {
this.textPages = page;
};
domooc[learnCourse][setUnitId] = function(unitId) {
this.unitId = unitId;
};
window.setPlayRate = domooc.learnCourse.setPlayRate;
})
domooc.execAfterLoaded = function(fname, param) {
return new Promise((resolve, reject) => {
let handler = window.setInterval(() => {
if (domooc.loaded) {
window.clearInterval(handler);
if (typeof fname === "string") {
if (fname === answerClassTest) {
let redo = document.querySelector('.submit.j-replay');
if (redo && redo.style.display !== "none") {
redo.click();
}
domooc[bindGetAnswer](param);
domooc[fname](param.paper);
} else {
domooc[fname](param);
}
resolve();
} else if (fname instanceof Array) {
let func = domooc;
let that = null;
fname.forEach(f => {
that = func;
func = func[f];
});
func.call(that, param);
resolve();
}
}
}, 300);
});
};
domooc.bindGetAnswer = function(obj) {
let quizs = [];
if (!(domooc.getAnswerquizs instanceof Array)) {
domooc.getAnswerquizs = [];
}
if (obj) {
if (obj.paper) {
obj = obj.paper;
}
if (obj.objectiveQList && obj.objectiveQList.length) {
quizs = obj.objectiveQList;
} else if (obj.subjectiveQList && obj.subjectiveQList.length) {
quizs = obj.subjectiveQList;
}
domooc.getAnswerquizs = quizs.map(x => 0);
}
$('div.j-title.title div.f-richEditorText.j-richTxt').each((idx, ele) => {
let btn = $(` |