易班自动答题 ᴘʀᴏᴡʟ
// ==UserScript==
// @name 易班自动答题 ᴘʀᴏᴡʟ
// @namespace https://bbs.tampermonkey.net.cn/
// @version 1.8
// @description 通过解密网页答题内存做到百分百正确率
// @author Prowl
// @match https://exam.yooc.me/group/*/exam/*/take
// @match https://www.yooc.me/group/*/exam/*/detail
// @run-at document-end
// @require https://cdn.staticfile.org/limonte-sweetalert2/11.0.1/sweetalert2.all.min.js
// @require https://cdn.bootcss.com/crypto-js/3.1.9-1/crypto-js.min.js
// @original-script https://scriptcat.org/script-show-page/958/
// ==/UserScript==
//是否自动下一题 1 开启 2 关闭 0 询问
var autoNext = 0
Swal = Swal || window.Swal
if (origin == 'https://www.yooc.me') {
location.href = "https://exam.yooc.me" + location.pathname.slice(0, -6) + 'take'
}
if (autoNext == 0) {
Swal.fire({
title: "答题模式",
text: "是否开启自动答题?",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "确定",
cancelButtonText: "取消"
}).then((result) => {
autoNext = result.isConfirmed ? 1 : 2;
checkForH3();
});
} else {
checkForH3();
}
function wait() {
start()
var buttons = document.querySelectorAll('.size-n.round');
buttons.forEach(function(button) {
button.addEventListener('click', function(e) {
setTimeout(function() {
start();
}, 300);
});
});
}
let flag = false;
function checkForH3() {
try {
let h3 = document.querySelector('h3 > div').innerHTML.replace(/[\r\n]/g, "");
if (h3) {
flag = true;
wait();
return;
}
} catch(e) {}
if (!flag) {
setTimeout(checkForH3, 1000);
}
}
const Base64 = function () {
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
this.encode = function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}
this.decode = function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}
var _utf8_encode = function (string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utfText += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
// private method for UTF-8 decoding
var _utf8_decode = function (utftext) {
var string = "";
var i = 0;
var c = 0;
var c1 = 0;
var c2 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c1 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
i += 2;
} else {
c1 = utftext.charCodeAt(i + 1);
c2 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
i += 3;
}
}
return string;
}
}
function getyibanid() {
let value = "; " + document.cookie;
let parts = value.split("; " + "yiban_id" + "=");
if (parts.length === 2) {
return parts.pop().split(";").shift();
}
}
const CryptoDecrypt = (word,cbckey) => {
const key = CryptoJS.enc.Utf8.parse(cbckey) ;
const iv = CryptoJS.enc.Utf8.parse('42e07d2f7199c35d');
const srcs = CryptoJS.enc.Base64.parse(word);
const decrypt = CryptoJS.AES.decrypt({ ciphertext: srcs }, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr;
};
function start() {
let key = ''
for (var i = 0; i < localStorage.length; i++) {
if (localStorage.key(i).indexOf("exam-paper-") != -1) {
key = localStorage.key(i)
}
}
let exam_paper = JSON.parse(localStorage.getItem(key)).value.paper
const decode = (str) => {
//let result = (decodeURI(new Base64().decode(str.split("").reverse().join(''))).split("yooc@admin")[0] || "")CryptoJS.enc.Utf8.parse(
let cbckey = CryptoJS.MD5('yooc@admin'+getyibanid()).toString().substring(8, 24)
result = CryptoDecrypt(str,cbckey)
console.log('数据库解密中:\nKEY:'+cbckey+'\nIV:42e07d2f7199c35d\n原始数据:'+str+'\n返回数据:'+result)
return (result)
}
const getanswer = (sectionName, title) => {
for (let i in exam_paper) {
if (sectionName == exam_paper[i].sectionName) {
let subjects = exam_paper[i].subjects
for (let i in subjects) {
if (title == subjects[i].title[0].replace(/[\r\n]/g, "")) {
let question = subjects[i]
let answer = decode(question.answer)
answer = JSON.parse('[' + String(answer) + ']')
answer = eval('[' + String(answer) + ']')
let all_answer = []
for (let i = 0; i < answer.length; i++) {
all_answer.push(question.option[answer[i]][0])
}
return (all_answer)
}
}
}
}
}
const getinputanswer = (sectionName, title) => {
for (let i in exam_paper) {
if (sectionName == exam_paper[i].sectionName) {
let subjects = exam_paper[i].subjects
for (let i in subjects) {
let l_title = subjects[i].title[0].split('{input}').join('').replace(/\s*/g, "").replace(/<.*?>/ig, "").replace(/[\r\n]/g, "")
if (title == l_title) {
let question = subjects[i]
let answer = decode(question.answer)
answer = JSON.parse('[' + String(answer) + ']')[0]
return (answer)
}
}
}
}
}
const select = (sectionName) => {
let title = document.querySelector('h3 > div').innerHTML.replace(/[\r\n]/g, "")
console.log('题目:'+title)
let r_answer = getanswer(sectionName, title)
console.log('答案:'+r_answer)
Array.from(document.querySelectorAll('body>div>div>div>main>main>div>div>div>div>div>ul>li')).forEach((answer) => {
try {
for (let i = 0; i < r_answer.length; i++) {
let t_answer = answer.getElementsByClassName('flex-auto')[0]
if (r_answer[i] == t_answer.innerHTML.slice(2)) {
if (answer.className.slice(-2) != '_c') {
answer.click()
var event = document.createEvent('HTMLEvents');
event.initEvent("click", false, false);
answer.dispatchEvent(event)
}
}
}
} catch (err) {
console.log(err.message)
autoNext = 0
Swal.fire({
title: "未能找到数据",
text: "是否刷新页面重新获取?",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "确定",
cancelButtonText: "取消"
}).then((isConfirm) => {
if (isConfirm.value) {
localStorage.clear()
location.reload()
} else {
return
}
});
}
});
}
const input = (sectionName) => {
let question = document.querySelector('h3 > div > div')
let title = question.textContent.replace(/\s*/g, "").replace(/[\r\n]/g, "")
console.log('题目:'+title)
let r_answer = getinputanswer(sectionName, title)
console.log('答案:'+r_answer)
try {
for (let i = 0; i < r_answer.length; i++) {
if (Array.isArray(r_answer[i])) {
question.getElementsByTagName('input')[i].value = r_answer[i][0]
} else {
question.getElementsByTagName('input')[i].value = r_answer[i]
}
var event = document.createEvent('HTMLEvents');
event.initEvent("input", false, false);
question.getElementsByTagName('input')[i].dispatchEvent(event)
}
} catch (err) {
console.log(err.message)
//Swal.fire('未能找到数据,正在重新获取')
//localStorage.clear()
//location.reload()
}
}
const u = undefined
let whetherinput = document.getElementsByClassName('exam-input')
let sectionName = document.querySelector('h2').innerHTML
if (sectionName == u) {
sectionName = ""
}
if (whetherinput[0] == u) {
select(sectionName)
} else {
input(sectionName)
}
//自动答题
let timeoutId;
function stopAutoNext() {
clearTimeout(timeoutId);
}
function startAutoNext() {
timeoutId = setTimeout(function () {
document.getElementsByClassName('size-n round')[1].click();
}, 1000);
}
if (autoNext == 1) {
startAutoNext();
} else {
stopAutoNext();
}
};