// ==UserScript==
// @name 超星学习.智慧树.执教云.雨课堂.自动答题脚本
// @version 1.1.8
// @namespace https://www.zbhui.cn/?r=/l&sort=0d
// @description 本脚本支持超星学习.智慧树.执教云.雨课堂等平台的测验考试,内置题库,自动答题功能。
// @author 万能
// @match *://*.chaoxing.com/*
// @match *://*.edu.cn/*
// @match *://*.hnsyu.net/*
// @match *://*.zhihuishu.com/*
// @match *://*.bsnc.cn/*
// @match *://*.xuetangx.com/*
// @match *://*.yuketang.cn/*
// @match *://*.icve.com.cn/*
// @match *://item.taobao.com/*
// @match *://*detail.tmall.com/*
// @match *://*detail.tmall.hk/*
// @match *://*.jkcsjd.com/*
// @match *://*.taobao.com/*
// @match *://*.tmall.com/*
// @match *://*.tmall.hk/*
// @match *://*.liangxinyao.com/*
// @match *://*.taobao.com/*
// @match *://*.tmall.com/*
// @match *://*.tmall.hk/*
// @match *://*.jd.com/*
// @match *://*.jd.hk/*
// @match *://*.yiyaojd.com/*
// @match *://*.liangxinyao.com/*
// @compatible chrome firefox edge
// @contributionURL https://lyck6.cn/pay
// @license MIT
// @grant GM_info
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @grant GM_getResourceText
// @grant GM_addStyle
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @run-at document-end
// @connect yuketang.cn
// @connect appwk.baidu.com
// @connect lyck6.cn
// @resource Table https://www.forestpolice.org/ttf/2.0/table.json
// @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.jsdelivr.net/npm/jquery@2.2.3/dist/jquery.min.js
// @require https://cdn.jsdelivr.net/npm/jquery.md5@1.0.2/index.min.js
// @require https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js
// @require https://cdn.jsdelivr.net/gh/zyufstudio/jQuery@3a09ff54b33fc2ae489b5083174698b3fa83f4a7/jPopBox/dist/jPopBox.min.js
// @require https://cdn.bootcss.com/jquery.qrcode/1.0/jquery.qrcode.min.js
// @require https://update.greasyfork.org/scripts/451606/1345888/%E7%BA%A2%E5%8C%85%E5%BA%93.js
// ==/UserScript==
//全局配置参数
var GLOBAL = {
time: 3E3, //查题间隔时间,不建议小于5s,如果为了安全起见最好10s以上,即10E3
delay: 2E3, //延迟加载,页面初始化完毕之后的等待2s之后再去搜题,
fillAnswerDelay: 1E3 //填充答案的延迟,不建议小于0.5秒,默认一秒
};
(function (exports) {
'use strict';
if(coupon.isRun()){
coupon.show();
}else{
function sleep(time) {
return new Promise((resolve) => {
setTimeout(resolve, time);
})
}
function iframeMsg(type, message) {
exports.top.document.getElementById('iframeNode').contentWindow.vueDefinedProp(type, message);
}
function filterImg(dom) {
return $(dom).clone().find("img[src]").replaceWith(function () {
return $("<p></p>").text('<img src="' + $(this).attr("src") + '">');
}).end().find("iframe[src]").replaceWith(function () {
return $("<p></p>").text('<iframe src="' + $(this).attr("src") + '"></irame>');
}).end().text().trim();
}
// 需要创建太多嵌套标签了,没个函数不行
function createContainer(name, childElem) {
name = name.toLowerCase();
let elem = exports.top.document.createElement(name);
elem.style.display = 'block';
// id 改成驼峰式
elem.id = name.replace('hcsearche', 'hcSearche').replace(/\-[a-z]/g, function (w) {
return w.replace('-', '').toUpperCase();
});
if (childElem) {
if (Array.isArray(childElem) === false)
childElem = [childElem];
for (let i = 0; i < childElem.length; i++)
elem.appendChild(childElem[i]);
}
return elem;
}
function dragModel(drag) {
const TOP = exports.top;
//获取drag元素
// let drag = document.getElementById("drag")
//当鼠标按下时
drag.onmousedown = function (e) {
drag.style.cursor = 'move';
//做到浏览器兼容
e = e || window.event;
let diffX = e.clientX - drag.offsetLeft;
let diffY = e.clientY - drag.offsetTop;
//当拉着box移动时
exports.top.onmousemove = function (e) {
// 浏览器兼容
e = e || top.event;
let left = e.clientX - diffX;
let top = e.clientY - diffY;
if (left < 0) {
left = 0;
} else if (left > TOP.innerWidth * 0.95 - drag.offsetWidth) {
left = TOP.innerWidth * 0.95 - drag.offsetWidth;
}
if (top < 0) {
top = 0;
} else if (top > TOP.innerHeight - drag.offsetHeight) {
top = TOP.innerHeight - drag.offsetHeight;
}
console.log(drag.style.left);
console.log(drag.style.top);
drag.style.left = left + 'px';
drag.style.top = top + 'px';
};
// 当鼠标抬起时
exports.top.onmouseup = function (e) {
drag.style.cursor = 'default';
this.onmousemove = null;
this.onmouseup = null;
};
};
}
function defaultWorkTypeResolver($options) {
function count(selector) {
let c = 0;
// $options.each(fun)
for (const option of $options || []) {
if ($(option).find(selector) !== null) {
c++;
}
}
return c;
}
return count('[type="radio"]') === 2
? 3
: count('[type="radio"]') > 2
? 0
: count('[type="checkbox"]') > 2
? 1
: count('textarea') >= 1
? 4
: undefined;
}
function formatAnswer(res) {
let msg = res.msg, num = res.data.num;
let success = res.code === 200;
if (res.code === 104) {
msg = '积分不足请关闭收费答题答题功能\n或者请点击【获取积分】进行充值';
}
return {
success,
msg,
num,
list: res.data.list
}
}
/**
* 相似度对比
* @param s 文本1
* @param t 文本2
* @param f 小数位精确度,默认2位
* @returns {string|number|*} 百分数前的数值,最大100. 比如 :90.32
*/
// similar("我不知道啊,不行","我不知道啊,不行",1)
// xsd("我不知道啊不行", "我也不知道啊不行")
function similar(s, t, f) {
if (!s || !t) {
return 0
}
if (s === t) {
return 100;
}
var l = s.length > t.length ? s.length : t.length;
var n = s.length;
var m = t.length;
var d = [];
f = f || 2;
var min = function (a, b, c) {
return a < b ? (a < c ? a : c) : (b < c ? b : c)
};
var i, j, si, tj, 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++) {
si = s.charAt(i - 1);
for (j = 1; j <= m; j++) {
tj = t.charAt(j - 1);
if (si === tj) {
cost = 0;
} else {
cost = 1;
}
d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
}
}
let res = (1 - d[n][m] / l) * 100;
return res.toFixed(f)
}
function answerSimilar(src, list) {
return $.map(list, function (val) {
return similar(formatString(val), formatString(src), 2)
})
}
/** 判断答案是否为A-Z的文本, 并且字符序号依次递增, 并且 每个字符是否都只出现了一次 */
function isPlainAnswer(answer) {
if (answer.length > 8 || !/[A-Z]/.test(answer)) {
return false;
}
let counter = {};
let min = 0;
for (let i = 0; i < answer.length; i++) {
if (answer.charCodeAt(i) < min) {
return false;
}
min = answer.charCodeAt(i);
counter[min] = (counter[min] || 0) + 1;
}
return true;
}
/**
*
* @param list 获取的答案列表
* @param data 发送请求的data
* @param $options 选项的dom
* @param handler 执行的函数
*/
async function defaultQuestionResolve(list, data, handler) {
console.log(data);
//最后的选项 集合
let targetOptionsList = [];
for (const answers of list) {
console.log('当前答案', JSON.stringify(answers));
if (data.type === 4 || data.type === 2) {
let ans = answers.length > data.$options.length ? answers.slice(0, data.$options.length) : answers;
ans.forEach((val, index) => {
handler(data.type, val, data.$options.eq(index));
});
return {ok: true, ans: answers.join('===='), question: data.question};
} else if (data.type === 3) {
if (answers.join().match(/(^|,)(正确|是|对|√|T|ri|false)(,|$)/)) {
if (data.options[0].match(/(^|,)(正确|是|对|√|T|ri|true)(,|$)/)) {
handler(data.type, '', data.$options.eq(0));
} else if (data.options[0].match(/(^|,)(错误|否|错|×|F|不是|wr|false)(,|$)/)) {
handler(data.type, '', data.$options.eq(1));
}
return {ok: true, ans: '正确', question: data.question};
} else if (answers.join().match(/(^|,)(错误|否|错|×|F|不是|wr|false)(,|$)/)) {
if (data.options[0].match(/(^|,)(正确|是|对|√|T|ri|true)(,|$)/)) {
handler(data.type, '', data.$options.eq(1));
} else if (data.options[0].match(/(^|,)(错误|否|错|×|F|不是|wr|false)(,|$)/)) {
handler(data.type, '', data.$options.eq(0));
}
handler(data.type, '', data.$options.eq(1));
return {ok: true, ans: '错误', question: data.question};
}
} else if (data.type === 0 || data.type === 1) {
let targetOptions = new Set();
//选项内容
for (const ans of answers) {
if (ans.length === 1 && isPlainAnswer(ans)) {
const index = ans.charCodeAt(0) - 65;
targetOptions.add(data.$options.eq(index));
}
}
//文字内容
answers.forEach((val, index) => {
val = formatString(val);
//精确匹配
let optIndex = $.inArray(val, data.options);
if (optIndex >= 0) {
targetOptions.add(data.$options.eq(optIndex));
} else {
if ((targetOptions.size > 1 && data.type === 1)) {
console.log('多选题已经有合适的选项,不进行模糊匹配');
} else {
//模糊匹配
const ratings = answerSimilar(val, data.options);
/** 找出最相似的选项 */
let max = 0;
ratings.forEach((rating, i) => {
if (rating > max) {
max = rating;
optIndex = i;
}
});
if (optIndex !== -1 && max > 60) {
/** 经自定义的处理器进行处理 */
targetOptions.add(data.$options.eq(optIndex));
}
}
}
});
//已经判断完毕
targetOptionsList.push(targetOptions);
}
}
console.log(targetOptionsList);
let set = new Set();//最后的set集合
let index = 0;//取用的第几个答案
if (data.type === 0) {
for (let targetOptionsListElement of targetOptionsList) {
if (targetOptionsListElement && targetOptionsListElement.size === 1) {
set = targetOptionsListElement;
index = targetOptionsList.indexOf(targetOptionsListElement);
break;
}
}
} else if (data.type === 1) {
for (let targetOptionsListElement of targetOptionsList) {
if (targetOptionsListElement && targetOptionsListElement.size > set.size) {
set = targetOptionsListElement;
index = targetOptionsList.indexOf(targetOptionsListElement);
}
}
}
console.log(set);
if (set.size > 0) {
let items = Array.from(set);
//set 遍历无法设置延迟,转为list后循环
for (let i in items) {
setTimeout(() => {
handler(data.type, '', items[i]);
}, i * GLOBAL.fillAnswerDelay);
}
await sleep(GLOBAL.fillAnswerDelay * set.size);
return {ok: true, ans: list[index].join('===='), question: data.question};
} else {
return {ok: false, question: data.question, ans: list.join('====')};
}
}
//HTML反转义
function HTMLDecode(text) {
var temp = document.createElement("div");
temp.innerHTML = text;
var output = temp.innerText || temp.textContent;
temp = null;
return output;
}
function formatString(src) {
return (src.includes('img') ? src : HTMLDecode(src)).replace(/\s+/, ' ').replace(/[\uff01-\uff5e]/g, function (str) {
return String.fromCharCode(str.charCodeAt(0) - 65248);
}).replace(/^[A-Z]\./, '').replace(/\(\d+\s分\)$/, '')
.replace(/[“”]/g, '"')
.replace(/[‘’]/g, "'")
.replace(/。/g, '.')
.replace(/\+/g, '').replace(/;$/, '').toLowerCase().trim();
}
const TYPE = {
单项选择题: 0,
单选题: 0,
多选题: 1,
填空题: 2,
判断题: 3,
简答题: 4,
名词解释: 5,
论述题: 6,
计算题: 7,
其它: 8,
分录题: 9,
资料题: 10,
连线题: 11,
排序题: 13,
完形填空: 14,
阅读理解: 15,
口语题: 18,
听力题: 19,
};
/**
* 图片url 转 base64
* @param url
* @returns {Promise<unknown>}
*/
const url2Base64 = (url) => new Promise((resolve, reject) => {
GM_xmlhttpRequest({
url: url,
responseType: 'blob',
onload: function (r) {
// "s".replaceAll()
const fileReader = new FileReader();
fileReader.readAsDataURL(r.response);
fileReader.onload = (e) => {
resolve(e.target.result);
};
}
});
});
/**
* 图片透明背景转白色
* @param base64
* @returns {Promise<unknown>}
*/
const imgHandle = (base64) => new Promise((resolve, reject) => {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
const image = new Image();
image.setAttribute("crossOrigin", 'Anonymous');
image.src = base64;
image.onload = function () {
canvas.width = image.width;
canvas.height = image.height;
context.fillStyle = "#fff"; /// set white fill style
context.fillRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0, 0);
canvas.toBlob((blob) => {
resolve(blob);
});
};
});
const imgOcr = (blob) => new Promise((resolve, reject) => {
var fd = new FormData();
fd.append("image", blob, "1.png");
GM_xmlhttpRequest({
url: "https://appwk.baidu.com/naapi/api/totxt",
method: "POST",
responseType: 'json',
data: fd,
onload: function (r) {
const res = r.response.words_result.map(item => {
return item.words
}).join('');
resolve(res);
}
});
});
const yuketangOcr = async url => {
//将图片下载转 base64
const base64 = await url2Base64(url);
//图片转白色背景
const img_blob = await imgHandle(base64);
//识别图片
const res = await imgOcr(img_blob);
return res
};
function showPanel() {
let html =
`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- import CSS -->
<link rel="stylesheet" href="//lib.baomitu.com/element-ui/2.15.9/theme-chalk/index.min.css">
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
*{
padding: 0px;
margin: 0px;
}
.el-form-item{
display: flex;
justify-content: center
}
</style>
</head>
<body>
<div id="app">
<div id="drag_auto_answer" style="position: absolute;">
<el-main
class="onlinekf"
style="min-width: 328px;margin-top: 0px;margin-left: 0px;border: 0px solid #666;width: 100%;background-color: #ffffff; padding: 15px 0px 0px; z-index: 99999;">
<el-row>
<el-form>
<el-form-item label="请输入手机号" style="margin-top: -20px">
<el-input v-model="opt.token" placeholder="请输入内容" style="max-width: 130px" size="mini"></el-input>
<el-button @click="btnClick(opt.token,'opt.confim')" size="mini" type="warning">确定</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row style="margin-top: -20px;margin-bottom: 5px;display: flex">
<el-alert
style="display: block"
:title="tip"
:closable="false"
type="success">
<el-button v-if="need_jump" @click="btnClick(opt.jump,'opt.jump')" size="mini" type="info">跳过本题</el-button>
<el-button v-if="!hidden" @click="btnClick(opt.auto_jump,'opt.auto_jump')" size="mini" type="warning">{{opt.auto_jump ? '停止自动切换': '开启自动切换'}}</el-button>
</el-alert>
</el-row>
<el-row style="display: flex;flex-flow: wrap;width: 100%;align-items: flex-start;">
<el-button v-if="!hidden" @click="btnClick(opt.stop,'opt.stop')" size="mini" type="success" style="margin-left: 5px">{{!opt.stop ? '暂停答题': '继续答题'}}</el-button>
<el-button size="mini" type="info" style="margin-left: 5px">重新查询</el-button>
<el-button @click="btnClick(opt.start_pay,'opt.start_pay')" size="mini" type="primary" style="margin-left: 5px">{{opt.start_pay ?'关闭收费题库' : '开启收费题库'}}</el-button>
<el-button size="mini" type="danger" style="margin-left: 5px"><a style="text-decoration:none;color: aliceblue" target="_blank" href="https://lyck6.cn/pay" >获取积分</a></el-button>
</el-row>
<el-table size="mini" :data="tableData" style="width: 100%;margin-top: 5px" :row-class-name="tableRowClassName">
<el-table-column prop="index" label="题号" width="45"></el-table-column>
<el-table-column prop="question" label="问题" width="130"></el-table-column>
<el-table-column prop="answer" label="答案" width="130"></el-table-column>
</el-table>
</el-main>
</div>
</div>
</body>
<!-- import Vue before Element -->
<script src="//lib.baomitu.com/vue/2.6.0/vue.min.js"></script>
<!-- import JavaScript -->
<script src="//lib.baomitu.com/element-ui/2.15.9/index.js"></script>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
<script>
new Vue({
el: '#app',
data: function () {
return {
hidden: false,
need_jump: false,
tip: '正在搜索',
opt:{
token: '` + GM_getValue('token') + `',
auto_jump: ` + GM_getValue('auto_jump') + `,
stop: false,
start_pay: `+GM_getValue('start_pay')+`
},
input: '',
visible: false,
tableData: []
}
},
mounted() {
},
created(){
/**
* 油猴脚本 给 iframe 通信的方法
* @param type 消息类型
* @param receiveParams 消息参数
*/
window['vueDefinedProp'] = (type,receiveParams) => {
//**
if (type === 'push'){
let length = this.tableData.length
this.tableData.push({index: length + 1,question: receiveParams.question,answer: receiveParams.answer,ok:receiveParams.ok})
}else if (type === 'clear'){
this.tableData = []
}else if (type === 'tip'){
if (receiveParams.type && receiveParams.type === 'jump'){
window.parent.postMessage({"type": 'jump'}, '*');
}else if (receiveParams.type && receiveParams.type === 'error'){
this.need_jump = true
}else if (receiveParams.type && receiveParams.type === 'hidden'){
this.hidden = true
}else if (receiveParams.type && receiveParams.type === 'stop'){
this.opt.stop = true
}
this.tip = receiveParams.tip
}
}
},
methods: {
tableRowClassName({row, rowIndex}) {
return row.ok ? 'success-row': 'warning-row'
},
btnClick(e,type){
if (type === 'opt.stop'){//暂停搜索
this.opt.stop = !this.opt.stop
this.tip = this.opt.stop? '已暂停搜索': '继续搜索'
window.parent.postMessage({type: 'stop',val:this.opt.stop}, '*');
}else if (type === 'opt.start_pay'){
this.opt.start_pay = ! this.opt.start_pay
window.parent.postMessage({type: 'start_pay',flag:this.opt.start_pay}, '*');
}else if (type === 'opt.auto_jump'){//开启自动切换
this.opt.auto_jump = ! this.opt.auto_jump
window.parent.postMessage({type: 'auto_jump',flag:this.opt.auto_jump}, '*');
}else if (type === 'opt.jump'){//跳过本题
window.parent.postMessage({type: 'jump'}, '*');
this.need_jump = false
}else if (type === 'opt.confim'){
window.parent.postMessage({type: 'confim',token:e}, '*');
}
}
}
})
</script>
</html>
`;
addModal2(html);
}
function addModal2(html, newPos, footerChildNode = false) {
// // // header link
let headersNode = createContainer('headers-node');
let adNode = exports.top.document.createElement('img');
adNode.setAttribute('src', 'http://lyck6.cn/img/6.png');
adNode.setAttribute("draggable", "false");
adNode.setAttribute("width", "98%");
adNode.setAttribute("height", "121px");
adNode.setAttribute("style", "display: block;margin-bottom: -2%;padding-left: 1%;");
// linkNode.setAttribu/te('data-seindex', 0);
// linkNode.setAttribute('data-seclass', 'baidu');
// linkNode.innerHTML =
// linkNode.setAttribute('data-securrent', 'true');
// linkNode.style.color = '#586069';
//
// linkNode.addEventListener('click', function () {
// window.open('https://www.itihey.com')
// });
//
headersNode.appendChild(adNode);
// iframe
let iframeNode = exports.top.document.createElement('iframe');
iframeNode.id = 'iframeNode';
iframeNode.setAttribute('width', '100%');
iframeNode.setAttribute("height", "350px");
iframeNode.setAttribute('frameborder', '0');
iframeNode.srcdoc = html;
// let headerNode = createContainer('hcsearche-modal-header', [linksNode]);
// let bodyNode = createContainer('hcsearche-modal-body', iframeNode);
//
// let footerNode = createContainer('hcsearche-modal-footer', footerChildNode);
//
let contentNode = createContainer('content-modal', [headersNode, iframeNode]);
let modal = renderModal(contentNode);
// return model
dragModel(modal);
}
// 搜索窗口可以根据设置决定是相对文档还是相对窗口定位
function renderModal(childElem, newPos) {
//不是自动关闭就是绝对定位 或者依据用户设置
return render('modal', 'model-id', childElem);
}
function render(tagName, elemId, childElem, isFixed, newPos) {
// console.log('开始渲染 model', isFixed)
let doc = exports.top.document;
let elem = doc.getElementById(elemId);
if (elem) {
elem.innerHTML = '';
} else {
elem = doc.createElement(tagName);
elem.id = elemId;
doc.body.appendChild(elem);
}
let contentNode = createContainer(tagName + '-container', childElem);
elem.appendChild(contentNode);
// class ID same
elem.classList.add(elemId);
// let X = false;
// let Y = false;
// if (!newPos) {
// X = elem.style.left.replace('px', '');
// console.log(X, "X")
// Y = elem.style.top.replace('px', '');
// }
// if (!X) {
// let pos = getXY(elem.offsetWidth, elem.offsetHeight);
// X = pos.X;
// Y = pos.Y;
// // 相对文档定位时需要将文档滚动距离加上
// if (!isFixed) {
// Y += window.pageYOffset;
// }
// }
elem.style.zIndex = '9999999';
// elem.style.width = '430px'
// elem.style.height = '660px'
elem.style.position = 'fixed';
elem.style.left = '30px';
elem.style.top = '30px';
setTimeout(function () {
elem.classList.add(elemId + '-show');
}, 10);
return elem;
}
async function searchAnswer(data) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: "POST",
url: "https://lyck6.cn/api/autoAnswer/" + (GM_getValue('start_pay') ? GM_getValue('token') : 0),
headers: {
"Content-Type": "application/json;charset=utf-8",
"Version": GM_info.script.version
},
data: JSON.stringify(data),
timeout: 10 * 1000,
onload: function (r) {
console.log(r.responseText);
resolve(JSON.parse(r.responseText));
},
onerror: function (e) {
reject(e);
}
});
})
}
/**
* 自动答题核心代码
*/
/**
*
* @param select 选择的元素{
* root: '.questionLi',
* elements: {
* question: 'h3 div',
* options: '.answerBg .answer_p, .textDIV, .eidtDiv',
* type: 'input[name^=type]:eq(0)'
* }
* }
* @param searchHander 规范化 题目 选项 类型
* @param fillHander 填充答案的函数
* @param onFinish 答题完成之后的回调函数 need_jump是否需要跳转
* @constructor
*/
var WorkerJS = function (select, searchHander, fillHander, onFinish = function (need_jump) {
}, fillFinish = function () {
}) {
GLOBAL.index = 0;
/**
* 根据传入的 元素进行初始化
*/
this.init = async function ($TiMu, select) {
let question = formatString(filterImg($TiMu.find(select.elements.question)));
let data = {
question: question.length === 0 ? $TiMu.find(select.elements.question) : question,
$options: $TiMu.find(select.elements.$options),
options: jQuery.map($TiMu.find(select.elements.options), function (val) {
return formatString(filterImg(val))
})
};
data.type = select.elements.type ? ($TiMu.find(select.elements.type).text() || $TiMu.find(select.elements.type).val()) : $TiMu;
return await searchHander(data)
};
this.fillAnswer = async function () {
let arr = jQuery(select.root);
console.log(arr.length);
GLOBAL.setInterval = async () => {
console.log('当前index', GLOBAL.index);
if (GLOBAL.index >= arr.length) {
clearInterval(GLOBAL.loop);
delete GLOBAL.loop;
let auto_jump = GM_getValue('auto_jump') === undefined || GM_getValue('auto_jump');
//答题事件监听,如果完成还要继续重新运行则返回 true
const next = onFinish(auto_jump);
if (next) {
GLOBAL.index = 0;
setTimeout(() => {
this.fillAnswer();
}, GLOBAL.time);
}
if (auto_jump) {
iframeMsg('tip', {type: 'jump', tip: '自动答题已完成,即将切换下一题'});
//如果在5秒内 没有切换就是答题完成了
next || setTimeout(() => {
iframeMsg('tip', {type: 'hidden', tip: '自动答题已完成,请检查提交'});
}, GLOBAL.time);
} else {
iframeMsg('tip', {tip: '自动答题已完成' + (arr.length === 1 ? ',请手动切换' : '请检查提交')});
}
return true
}
try {
let data = await this.init(jQuery(arr[GLOBAL.index++]), select);// arr[GLOBAL.index]
if (!data) return
iframeMsg('tip', {tip: '准备答第' + (GLOBAL.index) + '题'});
//格式化返回答案 成为二维数组
const formatAns = data.answer ? {
success: true,
num: '免费',
list: [data.answer]
} : formatAnswer(await searchAnswer({question: data.question}));
if (formatAns.success) {
//解析答案
iframeMsg('tip', {tip: '准备填充答案,' + (formatAns.num.includes('免费题库') ? '免费题库不扣积分' : '剩余积分:' + formatAns.num)});
let r = await defaultQuestionResolve(formatAns.list, data, fillHander);
iframeMsg('push', {index: GLOBAL.index, question: r.question, answer: r.ans, ok: r.ok});
} else {
iframeMsg('tip', {tip: formatAns.msg});
}
} catch (e) {
iframeMsg('tip', {type: 'error', tip: '发生异常' + e});
} finally {
fillFinish();
}
};
GLOBAL.loop = setInterval(GLOBAL.setInterval, GLOBAL.time);
console.log('GLOBAL.loop', GLOBAL.loop);
};
};
/**
* 借鉴 网页限制解除(改)
* 原作者 qxin i
* 开源地址 https://greasyfork.org/zh-CN/scripts/28497-%E7%BD%91%E9%A1%B5%E9%99%90%E5%88%B6%E8%A7%A3%E9%99%A4-%E6%94%B9/code
*/
// 初始化 init func 这里才是核心
function init() {
rule = rwl_userData.rules.rule_def;
hook_eventNames = rule.hook_eventNames.split("|");
// TODO Allowed to return value
unhook_eventNames = rule.unhook_eventNames.split("|");
eventNames = hook_eventNames.concat(unhook_eventNames);
if (rule.dom0) {
setInterval(clearLoop, 10 * 1000);
setTimeout(clearLoop, 1500);
window.addEventListener('load', clearLoop, true);
clearLoop();
}
// hook addEventListener //导致搜索跳转失效的原因
if (rule.hook_addEventListener) {
EventTarget.prototype.addEventListener = addEventListener;
document.addEventListener = addEventListener;
if (hasFrame) {
for (let i = 0; i < hasFrame.length; i++) {
hasFrame[i].contentWindow.document.addEventListener = addEventListener;
}
}
}
// hook preventDefault
if (rule.hook_preventDefault) {
Event.prototype.preventDefault = function () {
if (hook_eventNames.indexOf(this.type) < 0) {
Event_preventDefault.apply(this, arguments);
}
};
if (hasFrame) {
for (let i = 0; i < hasFrame.length; i++) {
hasFrame[i].contentWindow.Event.prototype.preventDefault = function () {
if (hook_eventNames.indexOf(this.type) < 0) {
Event_preventDefault.apply(this, arguments);
}
};
}
}
}
// Hook set returnValue
if (rule.hook_set_returnValue) {
Event.prototype.__defineSetter__('returnValue', function () {
if (this.returnValue !== true && hook_eventNames.indexOf(this.type) >= 0) {
this.returnValue = true;
}
});
}
}
// Hook addEventListener proc
function addEventListener(type, func, useCapture) {
var _addEventListener = this === document ? document_addEventListener : EventTarget_addEventListener;
if (hook_eventNames.indexOf(type) >= 0) {
_addEventListener.apply(this, [type, returnTrue, useCapture]);
} else if (unhook_eventNames.indexOf(type) >= 0) {
var funcsName = storageName + type + (useCapture ? 't' : 'f');
if (this[funcsName] === undefined) {
this[funcsName] = [];
_addEventListener.apply(this, [type, useCapture ? unhook_t : unhook_f, useCapture]);
}
this[funcsName].push(func);
} else {
_addEventListener.apply(this, arguments);
}
}
// 清理循环
function clearLoop() {
rule = clear(); // 对于动态生成的节点,随时检测
var elements = getElements();
for (var i in elements) {
for (var j in eventNames) {
var name = 'on' + eventNames[j];
if (Object.prototype.toString.call(elements[i]) == "[object String]") {
continue;
}
if (elements[i][name] !== null && elements[i][name] !== onxxx) {
if (unhook_eventNames.indexOf(eventNames[j]) >= 0) {
elements[i][storageName + name] = elements[i][name];
elements[i][name] = onxxx;
} else {
elements[i][name] = null;
}
}
}
}
document.onmousedown = function () {
return true;
};
}
// 返回true的函数
function returnTrue(e) {
return true;
}
function unhook_t(e) {
return unhook(e, this, storageName + e.type + 't');
}
function unhook_f(e) {
return unhook(e, this, storageName + e.type + 'f');
}
function unhook(e, self, funcsName) {
var list = self[funcsName];
for (var i in list) {
list[i](e);
}
e.returnValue = true;
return true;
}
function onxxx(e) {
var name = storageName + 'on' + e.type;
this[name](e);
e.returnValue = true;
return true;
}
// 获取所有元素 包括document
function getElements() {
var elements = Array.prototype.slice.call(document.getElementsByTagName('*'));
elements.push(document);
// 循环所有 frame 窗口
var frames = document.querySelectorAll("frame");
if (frames) {
hasFrame = frames;
var frames_element;
for (let i = 0; i < frames.length; i++) {
frames_element = Array.prototype.slice.call(frames[i].contentWindow.document.querySelectorAll("*"));
elements.push(frames[i].contentWindow.document);
elements = elements.concat(frames_element);
}
}
return elements;
}
var settingData = {
"status": 1,
"version": 0.1,
"message": "",
"positionTop": "0",
"positionLeft": "0",
"positionRight": "auto",
"addBtn": false,
"connectToTheServer": false,
"waitUpload": [],
"currentURL": "null",
"shortcut": 3,
// 域名规则列表
"rules": {},
"data": []
};
var rwl_userData = null;
var rule = null;
var hasFrame = false;
// 储存名称
var storageName = "storageName";
// 要处理的 event 列表
var hook_eventNames, unhook_eventNames, eventNames;
// 储存被 Hook 的函数
var EventTarget_addEventListener = EventTarget.prototype.addEventListener;
var document_addEventListener = document.addEventListener;
var Event_preventDefault = Event.prototype.preventDefault;
// 查看本地是否存在旧数据
rwl_userData = GM_getValue("rwl_userData");
if (!rwl_userData) {
rwl_userData = settingData;
}
// 自动更新数据
for (let value in settingData) {
if (!rwl_userData.hasOwnProperty(value)) {
rwl_userData[value] = settingData[value];
GM_setValue("rwl_userData", rwl_userData);
}
}
/**
* 原作者 wyn665817@163.com
* 开源地址 https://scriptcat.org/script-show-page/432/code
* 特别感谢 wyn大佬 提供的 字典匹配表
*/
function removeF() {
var md5 = $.md5;
// 判断是否存在加密字体
var $tip = $('style:contains(font-cxsecret)');
if (!$tip.length) return;
// 解析font-cxsecret字体
var font = $tip.text().match(/base64,([\w\W]+?)'/)[1];
font = Typr.parse(base64ToUint8Array(font))[0];
// 匹配解密字体
var table = JSON.parse(GM_getResourceText('Table'));
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'); // 移除字体加密
function 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;
}
}
function start() {
setInterval(function () {
try {removeF();} catch (e) {}
try {init();} catch (e) {}
}, 500);
}
function chaoxingOldExam() {
showPanel();
setTimeout(() => {
new WorkerJS({
root: '.TiMu',
elements: {
question: '.Cy_TItle .clearfix',
options: '.Cy_ulTop .clearfix',//文字的选项列表
$options: ':radio, :checkbox, .Cy_ulTk textarea',//绑定的事件的 dom列表
type: '[name^=type]:not([id])'
}
}, (obj) => {
obj.type = parseInt(obj.type);
if (obj.type === 3) {
obj.options = ['正确', '错误'];
}
return obj
}, (type, answer, $option) => {
if (type === 0 || type === 3 || type === 1) {
$option.get(0).click();
} else if (type === 4 || type === 2) {
UE.getEditor($option.attr('name')).setContent(answer);
}
}, (auto_jump) => {
auto_jump && setInterval(function() {
const btn = $('.saveYl:contains(下一题)').offset();
var mouse = document.createEvent('MouseEvents'),
arr = [btn.left + Math.ceil(Math.random() * 80), btn.top + Math.ceil(Math.random() * 26)];
mouse.initMouseEvent('click', true, true, document.defaultView, 0, 0, 0, arr[0], arr[1], false, false, false, false, 0, null);
_self.event = $.extend(true, {}, mouse);
delete _self.event.isTrusted;
_self.getTheNextQuestion(1);
}, Math.ceil(GLOBAL.time * Math.random()) * 2);
}).fillAnswer();
}, GLOBAL.delay);
}
/**
* 超星章节测验,新版旧版通用
*/
function chaoxingQuiz() {
removeF();
showPanel();
setTimeout(() => {
new WorkerJS({
root: '.clearfix .TiMu',
elements: {
question: '.Zy_TItle .clearfix',
options: 'ul:eq(0) li .after',//文字的选项列表
$options: 'ul:eq(0) li :radio,:checkbox,textarea',//绑定的事件的 dom列表
type: 'input[name^=answertype]'
}
}, (obj) => {
obj.question = obj.question.replace(/\s+/g,'');
obj.type = parseInt(obj.type);
if (obj.type === 3) {
obj.options = ['正确', '错误'];
}
return obj
}, (type, answer, $option) => {
if (type === 0 || type === 3 || type === 1) {
$option.get(0).click();
} else if (type === 4 || type === 2) {
UE.getEditor($option.attr('name')).setContent(answer);
}
}).fillAnswer();
}, GLOBAL.delay);
}
function chaoxingNewWork() {
showPanel();
setTimeout(() => {
let cxWork = new WorkerJS({
root: '.questionLi',
elements: {
question: 'h3',
options: '.stem_answer .answerBg .answer_p, .textDIV, .eidtDiv',
$options: '.stem_answer .answerBg, .textDIV, .eidtDiv',
type: 'input[type^=hidden]:eq(0)'
}
}, (obj) => {
obj.type = parseInt(obj.type);
//多选题清楚样式,清楚已经保存的结果
obj.type === 1 && $.each(obj.$options, (index, val) => {
$(val).find('.check_answer,.check_answer_dx').length === 1 && $(val).click();
});
return obj
}, (type, answer, $option) => {
if (type === 0 || type === 1 || type === 3) {
if ($option.find('.check_answer,.check_answer_dx').length === 0) {
$option.click();
}
} else if (type === 4 || type === 2) {
UE.getEditor($option.find('textarea').attr('name')).setContent(answer);
}
}, (auto_jump) => {
/**
* 答题成功之后要跳转了
*/
auto_jump && setTimeout(() => {
$('.nextDiv .jb_btn:contains("下一题")').click();
}, GLOBAL.time / 5);
});
cxWork.fillAnswer();
}, GLOBAL.delay);
}
function chaoxingNewExam(i) {
showPanel();
setTimeout(() => {
let cxWork = new WorkerJS({
root: '.questionLi',
elements: {
question: 'h3 div',
options: '.answerBg .answer_p, .textDIV, .eidtDiv',
$options: '.answerBg, .textDIV, .eidtDiv',
type: 'input[name^=type]:eq(' + i + ')'
}
}, (obj) => {
obj.type = parseInt(obj.type);
//多选题清楚样式,清楚已经保存的结果
obj.type === 1 && $.each(obj.$options, (index, val) => {
$(val).find('.check_answer,.check_answer_dx').length === 1 && $(val).click();
});
return obj
}, (type, answer, $option) => {
if (type === 0 || type === 1 || type === 3) {
if ($option.find('.check_answer,.check_answer_dx').length === 0) {
$option.click();
}
} else if (type === 4 || type === 2) {
UE.getEditor($option.find('textarea').attr('name')).setContent(answer);
}
}, (auto_jump) => {
/**
* 答题成功之后要跳转了
*/
auto_jump && setTimeout(() => {
$('.nextDiv .jb_btn:contains("下一题")').click();
}, GLOBAL.time / 5);
});
cxWork.fillAnswer();
}, GLOBAL.delay);
}
function ZjyExam() {
showPanel();
setTimeout(() => {
GM_xmlhttpRequest({
method: "GET",
url: 'https://lyck6.cn/api/init/zjy?id='+unsafeWindow.examRecordId,
timeout: 10 * 1000,
onload: function (r) {
console.log('初始化',r.responseText);
}
});
new WorkerJS({
root: '.q_content',
elements: {
question: '.divQuestionTitle',
options: '.questionOptions .q_option',
$options: '.questionOptions .q_option'
}
}, (obj) => {
obj.question = obj.question.replace(/^\d+、/, '').replace(/(\d+\s+分)$/, '');
obj.type = defaultWorkTypeResolver(obj.$options);
obj.options = $.map(obj.options, (val) => {
return formatString(val.replace(/[A-G][.|\\.\s+]/, '')).trim()
});
return obj
}, (type, answer, $option) => {
$option = $option.find('div');
if (type === 0 || type === 3) {
$option.click();
} else if (type === 1) {
if ($option.attr('class') !== 'checkbox_on') {
$option.click();
}
}
}, () => {
/**
* 答题完成的监听
*/
if ($('.paging_next').attr('style').includes('block')) {
//如果有下一页
$('.paging_next').click();
return true
}
}).fillAnswer();
}, GLOBAL.delay);
}
function mooc_icve_com_cn() {
showPanel();
setTimeout(() => {
new WorkerJS({
root: '.e-q-r',
elements: {
question: '.e-q-q .ErichText',
options: '.e-a-g li .ErichText',
$options: 'li',
type: '.quiz-type'
}
}, (obj) => {
obj.type = TYPE[obj.type.replaceAll(/\s+/g,'')];
return obj
}, (type, answer, $option) => {
if (type === 0 || type === 3) {
$option.click();
} else if (type === 1) {
if (!$option.attr('class').includes('checked')) {
$option.click();
}
}
}, () => {
/**
* 答题完成的监听
*/
// if ($('.paging_next').attr('style').includes('block')) {
// //如果有下一页
// $('.paging_next').click()
// return true
// }
}).fillAnswer();
}, GLOBAL.delay);
}
function zjyold() {
showPanel();
setTimeout(() => {
new WorkerJS({
root: '.e-q-r',
elements: {
question: '.e-q-q .ErichText',
options: '.e-a-g li,li .ErichText',
$options: '.e-a-g li',
type: '.quiz-type'
}
}, (obj) => {
obj.type = TYPE[obj.type.replaceAll(/\s+/g,'')];
obj.options = obj.options.map(i=>{
return i.replace(/^[ab]\)\s+/,'').replace(/^[a-z]\s+/,'').trim()
});
return obj
}, (type, answer, $option) => {
if (type === 0 || type === 3) {
$option.click();
} else if (type === 1) {
if (!$option.attr('class').includes('checked')) {
$option.click();
}
}
}).fillAnswer();
}, GLOBAL.delay);
}
function zhsExam() {
console.log("我走到这;zhsExam");
showPanel();
setTimeout(() => {
// sleep(3000)
new WorkerJS({
root: '.examPaper_subject',
elements: {
question: '.subject_describe div',
options: '.subject_node .nodeLab .node_detail',//文字的选项列表
$options: '.subject_node .nodeLab',//绑定的事件的 dom列表
type: '.subject_type span:eq(0)'
}
}, (obj) => {
obj.question = obj.question.get(0).__vue__._data.shadowDom.textContent;
obj.type = TYPE[obj.type.match('【(.*)】')[1]];
//多选题清楚样式,清楚已经保存的结果
obj.type === 1 && $.each(obj.$options, (index, val) => {
$(val).find('.node_detail').hasClass('onChecked') && $(val).click();
});
if ($(".yidun_popup").hasClass('yidun_popup--light')){
console.log('我到这了',GLOBAL.loop);
iframeMsg('tip', {type: 'stop', tip: '答题暂停,请自行通过验证'});
clearInterval(GLOBAL.loop);
delete GLOBAL.loop;
return undefined
}
return obj
}, (type, answer, $option) => {
// fill answer
if (type === 0 || type === 3 || type === 1) {
$option.click();
// $('.el-button:contains(下一题)').click()
}
// if (type === 0 || type === 1 || type === 3) {
// if ($option.find('.check_answer,.check_answer_dx').length === 0) {
// $option.click()
// }
// } else if (type === 4 || type === 2) {
// UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
// }
}, () => {
setTimeout(() => {
$('.el-button:contains(保存)').click();
}, GLOBAL.time / 3);
}, () => {
setTimeout(() => {
$('.el-button:contains(下一题)').click();
}, GLOBAL.time / 3);
}).fillAnswer();
}, GLOBAL.delay*1.5);
}
function zhsIntegral() {
showPanel();
setTimeout(() => {
// sleep(3000)
let zhsIn = new WorkerJS({
root: '.questionBox',
elements: {
question: '.questionContent',
options: '.optionUl label .el-radio__label',//文字的选项列表
$options: '.optionUl label',//绑定的事件的 dom列表
type: '.questionTit'
}
}, (obj) => {
obj.type = TYPE[obj.type.match('【(.*)】')[1]];
//多选题清楚样式,清楚已经保存的结果
obj.type === 1 && $.each(obj.$options, (index, val) => {
$(val).find('.el-radio__input').hasClass('is-checked') && $(val).click();
});
obj.options = obj.options.map(item=>{
return formatString(item.replaceAll(/^[a-zA-Z]\./g,''))
});
if ($(".yidun_popup").hasClass('yidun_popup--light')){
console.log('我到这了',GLOBAL.loop);
iframeMsg('tip', {type: 'stop', tip: '答题暂停,请自行通过验证'});
clearInterval(GLOBAL.loop);
delete GLOBAL.loop;
return undefined
}
return obj
}, (type, answer, $option) => {
// fill answer
if (type === 0 || type === 3 || type === 1) {
$option.click();
// $('.el-button:contains(下一题)').click()
}
// if (type === 0 || type === 1 || type === 3) {
// if ($option.find('.check_answer,.check_answer_dx').length === 0) {
// $option.click()
// }
// } else if (type === 4 || type === 2) {
// UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
// }
}, () => {
if ($('.Nextbtndiv .Topicswitchingbtn-gray:contains(下一题)').hasClass('Topicswitchingbtn-gray')) return false
setTimeout(() => {
$('.Nextbtndiv .Topicswitchingbtn:contains(下一题)').click();
}, GLOBAL.time / 5);
return true
});
zhsIn.fillAnswer();
}, GLOBAL.delay);
}
function ybkExam() {
console.log("我走到这;ybkExam");
showPanel();
setTimeout(() => {
// sleep(3000)
new WorkerJS({
root: '.topic-item',
elements: {
question: '.t-con .t-subject',
options: '.t-option .el-radio__label .option-content',//文字的选项列表
$options: '.t-option .el-radio__input .nodeLab',//绑定的事件的 dom列表
type: '.t-info .t-type'
}
}, (obj) => {
obj.type = TYPE[obj.type];
return obj
}, (type, answer, $option) => {
// fill answer
if (type === 0 || type === 3 || type === 1) {
$option.click();
// $('.el-button:contains(下一题)').click()
}
// if (type === 0 || type === 1 || type === 3) {
// if ($option.find('.check_answer,.check_answer_dx').length === 0) {
// $option.click()
// }
// } else if (type === 4 || type === 2) {
// UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
// }
}).fillAnswer();
}, GLOBAL.delay*1.5);
}
function hookJSON() {
const parse = JSON.parse;
JSON.parse = function (s) {
const o = parse(s);
if (location.pathname === '/study/works/works.html') {
if (o.paper){
GLOBAL.json = parseIcve(o.paper.PaperQuestions);
}
} else if (location.pathname === '/study/exam/exam.html') {
if (o.array) {
let arr = [];
for (let arrayElement of o.array) {
arr.push(...arrayElement.Questions);
}
GLOBAL.json = parseIcve(arr);
}
}else if (location.pathname.includes('/v2/web/cloud/student/exercise/')){
if (o.data && o.data.problems){
GLOBAL.json = parseYkt(o.data.problems);
// console.log(JSON.stringify(collectYkt(o.data.problems)))
}
}else if (location.host === 'examination.xuetangx.com' && location.pathname.includes('/exam/') ){
if (o.data && o.data.problems){
GLOBAL.json = parseYktExam(o.data.problems);
// console.log(JSON.stringify(collectYkt(o.data.problems)))
}
}
return o
};
}
function parseYkt(problems){
return problems.map(item=>{
const type = TYPE[item.content.TypeText];
if (type === 2 || type === 4){
return {
question: filterImg($(item.content.Body)),
type
}
}
return {
question: formatString(item.content.Body),
options: item.content.Options.map(i=>{return formatString(type === 3 ? i.key :i.value)}),
type
}
})
}
function parseYktExam(problems){
return problems.map(item=>{
const type = TYPE[item.TypeText];
if (type === 2 || type === 4){
return {
question: formatString(item.Body),
type
}
}
return {
question: formatString(item.Body),
options: item.Options.map(i=>{return formatString(type === 3 ? i.key :i.value)}),
type
}
})
}
function parseIcve(questions) {
return questions.map(item => {
const options = item.Selects.map(opt => {
return formatString(opt)
});
const type = TYPE[item.ACHType.QuestionTypeName];
const answer = item.Answers.map(key => {
if (type === 0 || type === 1) {
return options[key.charCodeAt() - 65]
} else if (type === 3) {
return key === '1' ? '正确' : '错误'
}
});
const answerKey = (type === 0 || type === 1) ? item.Answers : answer;
return {
id: item.Id,
question: item.ContentText,
answerKey,
options,
answer,
type
}
})
}
/**
* http://www.icve.com.cn/study/works/works.html
*/
function icve_works() {
hookJSON();
function get_element(id) {
for (let jsonElement of GLOBAL.json) {
if (jsonElement.id === id) {
return jsonElement
}
}
}
showPanel();
setTimeout(() => {
console.log(GLOBAL.json);
new WorkerJS({
root: '.questions',
elements: {
question: '.tigan',
options: 'label ',//文字的选项列表
$options: '.dy_input',//绑定的事件的 dom列表
type: 'input[name^=paperItemId]'
}
}, (obj) => {
const ele = get_element(obj.type);
obj.question = ele.question;
obj.answer = ele.answerKey ? ele.answerKey : ele.answer;
obj.type = ele.type;
return obj
}, (type, answer, $option) => {
if (type === 0 || type === 3 || type === 1) {
$option.get(0).click();
} else if (type === 4 || type === 2) {
UE.getEditor($option.attr('name')).setContent(answer);
}
}).fillAnswer();
}, GLOBAL.delay);
}
async function collectYkt() {
const class_room_id = location.pathname.split('/').pop();
const instance = axios.create({
timeout: 10 * 1000,
headers: {
'xtbz': 'ykt',
'classroom-id': class_room_id
}
});
const res1 = await instance.get('https://www.yuketang.cn/v2/api/web/logs/learn/' + class_room_id + '?actype=-1&page=0&offset=20&sort=-1');
const courseware_id = res1.data.data.activities[0].courseware_id;
const res2 = await instance.get(`https://www.yuketang.cn/c27/online_courseware/xty/kls/pub_news/${courseware_id}/`);
const content_info = res2.data.data.content_info;
for (const content of content_info) {
for (let leaf of content.leaf_list) {
if (leaf.leaf_type === 6) {
const res3 = await instance.get(`https://www.yuketang.cn/mooc-api/v1/lms/learn/leaf_info/${class_room_id}/${leaf.id}/`);
const res4 = await instance.get('https://www.yuketang.cn/mooc-api/v1/lms/exercise/get_exercise_list/' + res3.data.data.content_info.leaf_type_id + '/');
// console.log(res4.data)
console.log(JSON.stringify(collectYktWork(res4.data.data.problems)));
}
}
}
function collectYktWork(collect) {
return collect.map(item => {
const type = TYPE[item.content.TypeText];
const options = item.content.Options.map(i => {
return (type === 3 ? i.key : i.value)
});
try {
if (item.user.is_show_answer && item.user.answer) {
console.log(item.user);
return {
question: (item.content.Body),
options,
answer: (typeof item.user.answer === 'string' ? item.user.answer.split('') : item.user.answer).map(as => {
if (as.match(/[A-G]/)) {
return options[as.charCodeAt() - 65]
} else {
return as
}
}),
type
}
}
} catch (e) {
console.log(e);
}
}).filter(item1 => item1 !== undefined)
}
}
function yktOldExam() {
showPanel();
setTimeout(() => {
new WorkerJS({
root: '.problem_item',
elements: {
question: '.notBullet:eq(0)',
options: '.notBullet:gt(0)',//文字的选项列表
$options: '.problembullet',//绑定的事件的 dom列表
}
}, async (obj) => {
const $item = obj.type;
var tmp = $item.find('.ptype').clone();
tmp.children().remove();
obj.type = TYPE[tmp.text().replaceAll(/\s+/g, '')];
obj.question = await yuketangOcr(obj.question.attr('data-background'));
if (obj.$options.length === 2) {
obj.options = ['正确', '错误'];
} else {
const opt = [];
for (const tmpElement of $item.find('.notBullet:gt(0)')) {
opt.push(await yuketangOcr(jQuery(tmpElement).attr('data-background')));
}
obj.options = opt;
}
return obj
}, (type, answer, $option) => {
console.log($option);
// fill answer
if (type === 0 || type === 3 || type === 1) {
if (!$option.hasClass('is-checked')) {
$option.click();
}
// $('.el-button:contains(下一题)').click()
}
// if (type === 0 || type === 1 || type === 3) {
// if ($option.find('.check_answer,.check_answer_dx').length === 0) {
// $option.click()
// }
// } else if (type === 4 || type === 2) {
// UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
// }
}).fillAnswer();
}, GLOBAL.delay * 1.5);
}
function yktExam() {
hookJSON();
showPanel();
setTimeout(() => {
console.log(GLOBAL.json);
// sleep(3000)
// $('.')
new WorkerJS({
root: '.exam-main--body .subject-item',
elements: {
question: '.item-body .problem-body ,p',
options: '.item-body ul li',//文字的选项列表
$options: '.item-body ul label, .blank-item-dynamic',//绑定的事件的 dom列表
type: '.item-type'
}
}, async (obj) => {
console.log(obj);
const ele = GLOBAL.json[GLOBAL.index-1];
// obj.$options = document.querySelector('.subject-item')
obj.type = ele.type;
obj.options = ele.options;
obj.question = ele.question;
if (obj.type === 1){
for (let val of obj.$options) {
jQuery(val).hasClass('is-checked') && jQuery(val).click();
await sleep(500);
}
}
return obj
}, (type, answer, $option) => {
console.log($option);
// fill answer
if (type === 0 || type === 3 || type === 1) {
if (!$option.hasClass('is-checked')) {
$option.click();
}
// $('.el-button:contains(下一题)').click()
} else if (type === 4 || type === 2) {
UE.getEditor($option).setContent(answer);
}
// if (type === 0 || type === 1 || type === 3) {
// if ($option.find('.check_answer,.check_answer_dx').length === 0) {
// $option.click()
// }
// } else if (type === 4 || type === 2) {
// UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
// }
}).fillAnswer();
}, GLOBAL.delay * 1.5);
}
function yktText() {
hookJSON();
showPanel();
setTimeout(() => {
console.log(GLOBAL.json);
// sleep(3000)
// $('.')
new WorkerJS({
root: '.container-problem .subject-item',
elements: {
// question: '.item-body .problem-body ,p',
// options: '.item-body ul li',//文字的选项列表
$options: '.item-body ul label',//绑定的事件的 dom列表
type: '.item-type'
}
}, async (obj) => {
console.log(obj);
//测验题号
const index = obj.type.trim().match(/^(\d+)/)[1];
obj.index = index - 1;
const ele = GLOBAL.json[obj.index];
obj.type = ele.type;
obj.options = ele.options;
obj.question = ele.question;
if (obj.type === 1) {
for (let val of obj.$options) {
jQuery(val).hasClass('is-checked') && jQuery(val).click();
await sleep(500);
}
}
console.log(obj);
return obj
}, (type, answer, $option) => {
console.log($option);
// fill answer
if (type === 0 || type === 3 || type === 1) {
if (!$option.hasClass('is-checked')) {
$option.click();
}
// $('.el-button:contains(下一题)').click()
}
// if (type === 0 || type === 1 || type === 3) {
// if ($option.find('.check_answer,.check_answer_dx').length === 0) {
// $option.click()
// }
// } else if (type === 4 || type === 2) {
// UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
// }
}, (need_jump) => {
if ($('.el-button--text:contains(下一题)').hasClass('is-disabled')) return false
// if (ne)
need_jump && setTimeout(() => {
$('.el-button--text:contains(下一题)').click();
}, GLOBAL.time / 3);
return need_jump
}).fillAnswer();
}, GLOBAL.delay * 1.5);
}
function zgdzText() {
console.log("我走到这;zgdzText");
showPanel();
setTimeout(() => {
// sleep(3000)
new WorkerJS({
root: '.stViewItem',
elements: {
question: '.stViewHead div',
options: '.stViewCont .stViewOption a',//文字的选项列表
$options: '.stViewCont .stViewOption a,input',//绑定的事件的 dom列表
}
}, (obj) => {
obj.type = TYPE[obj.type.parents().find('.E_E_L_I_C_R_C_T_SubType').eq(0).text().replace(/\(共\d+分\)/,'')];
obj.options = obj.options.map(i=>{
return i.replace(/\([A-Za-z]\)/,'').trim()
});
return obj
}, (type, answer, $option) => {
// fill answer
if (type === 0 || type === 3 || type === 1) {
$option.click();
// $('.el-button:contains(下一题)').click()
}else if (type === 4 || type === 2) {
$option.val(answer);
}
// if (type === 0 || type === 1 || type === 3) {
// if ($option.find('.check_answer,.check_answer_dx').length === 0) {
// $option.click()
// }
// } else if (type === 4 || type === 2) {
// UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
// }
}).fillAnswer();
}, GLOBAL.delay*1.5);
}
function xetText() {
showPanel();
setTimeout(() => {
// sleep(3000)
new WorkerJS({
root: '.question-container',
elements: {
question: '.question-title #_flag4unlimit p',
options: 'label .image-text-box p',//文字的选项列表
$options: 'label',//绑定的事件的 dom列表
type:'.quetion-type'
}
}, (obj) => {
obj.type = TYPE[obj.type.replace("(","").replace(")","")];
if (obj.type === 3) {
obj.options = ['正确', '错误'];
}
obj.options = obj.options.map(i=>{
return i.replace(/\([A-Za-z]\)/,'').trim()
});
return obj
}, (type, answer, $option) => {
// fill answer
if (type === 0 || type === 3 || type === 1) {
$option.click();
// $('.el-button:contains(下一题)').click()
}
// if (type === 0 || type === 1 || type === 3) {
// if ($option.find('.check_answer,.check_answer_dx').length === 0) {
// $option.click()
// }
// } else if (type === 4 || type === 2) {
// UE.getEditor($option.find('textarea').attr('name')).setContent(answer)
// }
}).fillAnswer();
}, GLOBAL.delay*1.5);
}
var _self = unsafeWindow;
exports.top = _self;
// _self.$ = jQuery
try {
while (exports.top !== _self.top) {
exports.top = exports.top.parent.document ? exports.top.parent : _self.top;
if (exports.top.location.pathname === '/mycourse/studentstudy') break;
}
} catch (err) {
exports.top = _self;
}
// console.log('顶部窗口链接',top.location.href)
var parent = _self === exports.top ? self : _self.parent,
Ext = _self.Ext || parent.Ext || {},
UE = _self.UE;
/**
* 顶层窗口监听 iframeNode 的参数
*/
exports.top.addEventListener("message", (event => {
console.log('监听器的', GLOBAL);
if (event.data.type === 'jump') ; else if (event.data.type === 'stop') {
if (event.data.val) {
let intv = setInterval(() => {
if (GLOBAL.loop) {
clearInterval(GLOBAL.loop);
delete GLOBAL.loop;
clearInterval(intv);
}
}, 20);
} else {
GLOBAL.loop = setInterval(GLOBAL.setInterval, GLOBAL.time);
}
} else if (event.data.type === 'start_pay') {
GM_setValue('start_pay', event.data.flag);
iframeMsg('tip', {tip: '已' + (event.data.flag ? '开启' : '关闭') + '请求收费题库,已实时生效'});
} else if (event.data.type === 'auto_jump') {
GM_setValue('auto_jump', event.data.flag);
iframeMsg('tip', {tip: '已' + (event.data.flag ? '开启' : '关闭') + '自动切换,页面刷新后生效'});
} else if (event.data.type === 'confim') {
GM_setValue('token', event.data.token);
} else if (event.data.type === 'jump') {
GLOBAL.index++;
iframeMsg('tip', {tip: '准备答第' + (GLOBAL.index + 1) + '题'});
}
// GM_getValue
}), false);
/**
* 类似于老板键,上箭头隐藏,下箭头显示
*/
$(document).keydown(function (event) {
if (event.keyCode === 38) {
$('#model-id').hide();
} else if (event.keyCode === 40) {
$('#model-id').show();
}
});
// yuketangOcr('https://qn-s0.yuketang.cn/Fmx0luZ4H0Kntw9_9Uctwj4I-iRi').then(res=>console.log(res))
setTimeout(() => {
start();
}, GLOBAL.time);
if (location.pathname === '/exam/examflow_index.action') {
ZjyExam();
} else if (location.pathname === '/study/homework/do.html') {
zjyold();
}else if ((location.pathname === '/exam/test/reVersionTestStartNew' || location.pathname === '/exam-ans/exam/test/reVersionTestStartNew') && location.href.includes('newMooc=true')) {
chaoxingNewExam(1);
} else if ((location.pathname === '/exam/test/reVersionTestStartNew' || location.pathname === '/exam-ans/exam/test/reVersionTestStartNew') && !location.href.includes('newMooc=true')) {
chaoxingOldExam();
} else if (location.pathname === '/work/doHomeWorkNew') {
chaoxingQuiz();
} else if (location.pathname === '/mooc2/exam/preview' || location.pathname === '/exam-ans/mooc2/exam/preview') {
chaoxingNewExam(0);
} else if (location.pathname === '/mooc2/work/dowork') {
chaoxingNewWork();
} else if (location.pathname === '/study/workExam/testWork/preview.html' || location.pathname === '/study/workExam/homeWork/preview.html' || location.pathname === '/study/workExam/onlineExam/preview.html') {
mooc_icve_com_cn();
} else if (location.pathname === '/stuExamWeb.html' && location.href.includes('/webExamList/dohomework/')) {
zhsExam();
} else if (location.pathname === '/stuExamWeb.html' && location.href.includes('/webExamList/doexamination/')) {
zhsExam();
} else if (location.href.includes('/atHomeworkExam/stu/homeworkQ/exerciseList')) {
zhsIntegral();
} else if (location.pathname === '/web/index.php') {
ybkExam();
} else if (location.pathname === '/study/works/works.html' || location.pathname === '/study/exam/exam.html') {
icve_works();
} else if (location.pathname.includes('/v2/web/cloud/student/exercise/')) {
yktText();
} else if (location.host === 'examination.xuetangx.com' && location.pathname.includes('/exam/')) {
yktExam();
} else if (location.pathname.includes('/v/quiz/quiz_result')) {
const intv = setInterval(() => {
if ($('#cover').attr('style').includes('display: none;')) {
clearInterval(intv);
yktOldExam();
}
}, 2000);
} else if (location.pathname.includes('/v2/web/studentLog')) {
collectYkt();
} else if (location.pathname.includes('/Exam/OnlineExamV2/')) {
zgdzText();
} else if (location.pathname.includes('/evaluation_wechat/examination/detail/')) {
xetText();
}
exports.Ext = Ext;
exports.UE = UE;
exports._self = _self;
exports.parent = parent;
Object.defineProperty(exports, '__esModule', { value: true });
return exports;
}
})({});