超星学习通助手Plus
// ==UserScript==
// @name 超星学习通助手Plus
// @namespace unrival
// @version 3.7
// @description ▶▶▶全新升级3.7版本,修复搜题限制问题◀◀◀
// @author unrival
// @run-at document-end
// @storageName unrivalxxt
// @match *://*.chaoxing.com/*
// @match *://*.edu.cn/*
// @match *://*.nbdlib.cn/*
// @match *://*.hnsyu.net/*
// @match *://*.ac.cn/*
// @icon http://pan-yz.chaoxing.com/favicon.ico
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addValueChangeListener
// @grant GM_info
// @connect mooc1-1.chaoxing.com
// @connect mooc1.chaoxing.com
// @connect mooc1-2.chaoxing.com
// @connect passport2-api.chaoxing.com
// @connect 14.29.190.187
// @connect cx.icodef.com
// @license GPL-3.0-or-later
// @original-script https://scriptcat.org/script-show-page/878/
// @original-author unrival
// @original-license GPL-3.0-or-later
//如果脚本提示添加安全网址,请将脚本提示内容填写到下方区域,一行一个,如果不会,请加群询问
//安全网址请填写在上方空白区域
// ==/UserScript==
(() => {
var token = GM_getValue('IGLXHuBPjDjcuCNm'),
jumpType = 1, // 0:智能模式,1:遍历模式,2:不跳转,如果智能模式出现无限跳转/不跳转情况,请切换为遍历模式
disableMonitor = 0, // 0:无操作,1:解除多端学习监控,开启此功能后可以多端学习,不会被强制下线。
accuracy = 0, //章节测试正确率百分比,在答题正确率在规定之上并且允许自动提交时才会提交答案
randomDo = 1, //将0改为1,找不到答案的单选、多选、判断就会自动选【B、ABCD、错】,只在规定正确率不为100%时才生效
backGround = 0, //是否对接超星挂机小助手,需要先安装对应脚本
//-----------------------------------------------------------------------------------------------------
autoLogin = 0, //掉线是否自动登录,1为自动登录,需要配置登录信息(仅支持手机号+密码登陆)
phoneNumber = '', //自动登录的手机号,填写在单引号之间。
password = ''; //自动登录的密码,填写在单引号之间。
//-----------------------------------------------------------------------------------------------------
var host = 'http://14.29.190.187:54223/',
rate = GM_getValue('unrivalrate', '1'),
ctUrl = 'https://cx.icodef.com/wyn-nb?v=4',
getQueryVariable = (variable) => {
let q = _l.search.substring(1),
v = q.split("&"),
r = false;
for (let i = 0, l = v.length; i < l; i++) {
let p = v[i].split("=");
p[0] == variable && (r = p[1]);
}
return r;
},
getCookie = name => `; ${document.cookie}`.split(`; ${name}=`).pop().split(';').shift(),
isCat = GM_info.scriptHandler == 'ScriptCat',
_w = unsafeWindow,
_d = _w.document,
_l = _w.location,
_p = _l.protocol,
_h = _l.host,
//isEdge = _w.navigator.userAgent.includes("Edg/"),
isFf = _w.navigator.userAgent.includes("Firefox"),
isMobile = _w.navigator.userAgent.includes("Android"),
stop = false,
handleImgs = (s) => {
imgEs = s.match(/(<img([^>]*)>)/);
if (imgEs) {
for (let j = 0, k = imgEs.length; j < k; j++) {
let urls = imgEs[j].match(
/http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+/),
url;
if (urls) {
url = urls[0].replace(/http[s]?:\/\//, '');
s = s.replaceAll(imgEs[j], url);
}
}
}
return s;
},
trim = (s) => {
return handleImgs(s).replaceAll('javascript:void(0);', '').replaceAll(" ", '').replaceAll(",", ',').replaceAll(
"。", '.').replaceAll(":", ':').replaceAll(";",
';').replaceAll("?", '?').replaceAll("(", '(').replaceAll(")", ')').replaceAll("“", '"')
.replaceAll("”", '"').replaceAll("!", '!').replaceAll("-", ' ').replace(/(<([^>]+)>)/ig, '')
.replace(/^\s+/ig, '').replace(/\s+$/ig, '');
},
cVersion = 999,
classId = getQueryVariable('clazzid') || getQueryVariable('clazzId') || getQueryVariable('classid') ||
getQueryVariable('classId'),
courseId = getQueryVariable('courseid') || getQueryVariable('courseId'),
UID = getCookie('_uid') || getCookie('UID'),
FID = getCookie('fid'),
jq = _w.top.$ || _w.top.jQuery;
_w.confirm = (msg) => {
return true;
}
setInterval(function () {
_w.confirm = (msg) => {
return true;
}
}, 2000);
if (parseFloat(rate) == parseInt(rate)) {
rate = parseInt(rate);
} else {
rate = parseFloat(rate);
}
try {
_w.top.unrivalReviewMode = GM_getValue('unrivalreview', '0') || '0';
_w.top.unrivalDoWork = GM_getValue('unrivaldowork', '1') || '1';
_w.top.unrivalAutoSubmit = GM_getValue('unrivalautosubmit', '1') || '1';
_w.top.unrivalAutoSave = GM_getValue('unrivalautosave', '0') || '0';
} catch (e) { }
if (_l.href.indexOf("knowledge/cards") > 0) {
let allowBackground = false,
spans = _d.getElementsByTagName('span');
for (let i = 0, l = spans.length; i < l; i++) {
if (spans[i].innerHTML.indexOf('章节未开放') != -1) {
if (_l.href.indexOf("ut=s") != -1) {
_l.href = _l.href.replace("ut=s", "ut=t").replace(/&cpi=[0-9]{1,10}/, '');
} else if (_l.href.indexOf("ut=t") != -1) {
spans[i].innerHTML = '此课程为闯关模式,请回到上一章节完成学习任务!'
return;
}
break;
}
}
_w.top.unrivalPageRd = String(Math.random());
if (!isFf) {
try {
cVersion = parseInt(navigator.userAgent.match(/Chrome\/[0-9]{2,3}./)[0].replace('Chrome/', '')
.replace('.', ''));
} catch (e) { }
}
var busyThread = 0,
getStr = (str, start, end) => {
let res = str.substring(str.indexOf(start), str.indexOf(end)).replace(start, '');
return res;
},
scripts = _d.getElementsByTagName('script'),
param = null;
for (let i = 0, l = scripts.length; i < l; i++) {
if (scripts[i].innerHTML.indexOf('mArg = "";') != -1 && scripts[i].innerHTML.indexOf(
'==UserScript==') == -1) {
param = getStr(scripts[i].innerHTML, 'try{\n mArg = ', ';\n}catch(e){');
}
}
if (param == null) {
return;
}
try {
vrefer = _d.getElementsByClassName('ans-attach-online ans-insertvideo-online')[0].src;
} catch (e) {
vrefer = _p + '//' + _h + '/ananas/modules/video/index.html?v=2022-1118-1729';
}
GM_setValue('vrefer', vrefer);
GM_setValue('host', _h);
var tikutoken=GM_getValue("tikutoken")
if(tikutoken==null){
tikutoken=""
}
var base222 = `https://tc.yjie.fun/uploads/97843ea42d76b3425ff0bff8a1fcbc6.jpg`
_d.getElementsByTagName("html")[0].innerHTML = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学习通助手</title>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
<link href="https://z.chaoxing.com/yanshi/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background: #fff;
color: #333;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
.container {
max-width: 800px;
margin: 30px auto;
padding: 0 15px;
padding-bottom: 50px; /* 增加底部内边距 */
}
.header {
margin-bottom: 30px;
text-align: center;
}
.header h2 {
font-weight: 600;
color: #2c3e50;
margin-bottom: 10px;
}
.header p {
color: #7f8c8d;
font-size: 14px;
line-height: 1.6;
}
.panel {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0,0,0,0.1);
margin-bottom: 25px;
}
.panel-heading {
padding: 15px 20px;
border-bottom: 1px solid #eee;
font-weight: 600;
color: #2c3e50;
}
.panel-body {
padding: 20px;
}
.btn {
border-radius: 6px;
padding: 8px 16px;
font-size: 14px;
font-weight: 500;
margin: 5px;
transition: all 0.2s;
}
.btn-default {
color: #2c3e50;
background: #f8f9fa;
border: 1px solid #dee2e6;
}
.btn-default:hover {
background: #e9ecef;
}
.btn-success {
color: #fff;
background: #3498db;
border: none;
}
.btn-success:hover {
background: #2980b9;
}
input[type="number"] {
border: 1px solid #dee2e6;
border-radius: 6px;
padding: 8px 12px;
width: 80px;
}
#result {
max-height: 400px;
overflow-y: auto;
font-size: 14px;
line-height: 1.6;
margin-bottom: 10px; /* 增加底部外边距 */
}
.notice {
padding: 15px;
background: #f8f9fa;
border-radius: 6px;
margin: 15px 0;
font-size: 14px;
color: #666;
}
/* 新增样式 */
.panel:last-child {
margin-bottom: 50px; /* 最后一个panel增加更大的底部外边距 */
}
#log {
padding-bottom: 20px; /* 日志内容区增加底部内边距 */
}
/* 确保iframe不会溢出 */
#workPanel {
margin-bottom: 50px;
}
#frame_content {
width: 100%;
height: 600px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h2>学习通助手 v3.6</h2>
<p>二次开发版本 - 优化搜题接口,新增AI助手支持</p>
</div>
<div class="panel">
<div class="panel-heading">高级配置</div>
<div class="panel-body">
<div class="config-item">
<label>跳转模式:</label>
<select id="jumpType" class="form-control">
<option value="0">智能模式</option>
<option value="1" selected>遍历模式</option>
<option value="2">不跳转</option>
</select>
<small class="text-muted">智能模式如果出现无限跳转/不跳转情况,请切换为遍历模式</small>
</div>
<div class="config-item">
<label>多端监控:</label>
<select id="disableMonitor" class="form-control">
<option value="0" selected>保持默认</option>
<option value="1">解除监控</option>
</select>
<small class="text-muted">解除后可以多端学习,不会被强制下线(谨慎使用)</small>
</div>
<div class="config-item">
<label>答题正确率:</label>
<input type="number" id="accuracy" class="form-control" value="0" min="0" max="100">
<small class="text-muted">设置章节测试提交的最低正确率要求(0-100)</small>
</div>
<div class="config-item">
<label>随机答题:</label>
<select id="randomDo" class="form-control">
<option value="0">关闭</option>
<option value="1" selected>开启</option>
</select>
<small class="text-muted">找不到答案时自动选择(单选B/多选ABCD/判断错)</small>
</div>
<div class="config-item">
<label>自动登录:</label>
<select id="autoLogin" class="form-control">
<option value="0" selected>关闭</option>
<option value="1">开启</option>
</select>
<div id="loginConfig" style="display:none">
<input type="text" id="phoneNumber" class="form-control" placeholder="手机号">
<input type="password" id="password" class="form-control" placeholder="密码">
</div>
</div>
<button id="saveConfig" class="btn btn-primary">保存配置</button>
</div>
</div>
<div class="panel">
<div class="panel-heading">功能说明</div>
<div class="panel-body">
<div class="feature-list">
<h4>基础功能</h4>
<ul>
<li><strong>视频加速:</strong>可自定义视频播放速度,支持最小化播放</li>
<li><strong>自动答题:</strong>自动完成章节测试,支持题库搜索和AI辅助</li>
<li><strong>复习模式:</strong>可选择是否跳过已完成的视频任务</li>
<li><strong>后台挂机:</strong>支持最小化窗口继续运行</li>
</ul>
<h4>高级功能</h4>
<ul>
<li><strong>跳转模式:</strong>
<ul>
<li>智能模式:自动判断下一个任务点</li>
<li>遍历模式:按顺序遍历所有任务点(推荐)</li>
<li>不跳转:完成当前任务后停止</li>
</ul>
</li>
<li><strong>多端监控:</strong>解除后可同时在多个设备登录学习</li>
<li><strong>答题设置:</strong>
<ul>
<li>正确率要求:设置自动提交的最低正确率</li>
<li>随机答题:找不到答案时自动选择预设选项</li>
</ul>
</li>
<li><strong>自动登录:</strong>掉线后自动使用配置的账号密码重新登录</li>
</ul>
<h4>特别说明</h4>
<ul>
<li>本脚本为优化版本,修复了原版搜题接口不稳定的问题</li>
<li>新增AI助手支持,搜题失败时可使用 <a href="https://ai1.yjie.fun/" target="_blank">AI助手</a> 获取答案</li>
<li>建议使用遍历模式,避免出现跳转异常</li>
<li>解除多端监控可能存在风险,请谨慎使用</li>
</ul>
</div>
</div>
</div>
<div class="panel">
<div class="panel-heading">任务配置</div>
<div class="panel-body">
<div>
<div style="margin-bottom: 20px;">
<span style="font-size: 14px;">视频倍速:</span>
<input type="number" id="unrivalRate" style="width: 80px;">
<a id='updateRateButton' class="btn btn-default">保存</a>
<a id='reviewModeButton' class="btn btn-default">复习模式</a>
<a id='fuckMeModeButton' class="btn btn-default" href="https://scriptcat.org/script-show-page/379" target="view_window">后台挂机</a>
<a id='backGround' class="btn btn-default">激活挂机</a>
</div>
<div>
<span style="font-size: 14px;">章节测试:</span>
<a id='autoDoWorkButton' class="btn btn-default">自动答题</a>
<a id='autoSubmitButton' class="btn btn-default">自动提交</a>
<a id='autoSaveButton' class="btn btn-default">自动保存</a>
</div>
</div>
</div>
</div>
<div class="panel">
<div class="panel-heading">任务列表</div>
<div class="panel-body" id='joblist'></div>
</div>
<div class="panel">
<div class="panel-heading">运行日志</div>
<div class="panel-body">
<div id="result">
<div id="log"></div>
</div>
</div>
</div>
<div class="panel" id='workPanel' style="display: none;">
<div class="panel-heading">章节测试</div>
<div class="panel-body" id='workWindow'>
<iframe id="frame_content" name="frame_content" src="" frameborder="0" scrolling="auto" style="width: 100%; height: 600px;"></iframe>
</div>
</div>
<!-- 赞助支持面板 -->
<div class="panel">
<div class="panel-heading">赞助支持</div>
<div class="panel-body" style="text-align: center;">
<p>如果这个脚本帮助到了你,欢迎赞助支持~</p>
<div style="display: flex; justify-content: center; gap: 20px; margin-top: 20px;">
<div>
<p>支付宝</p>
<img src="https://fs-im-kefu.7moor-fs1.com/ly/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1735283194150/6d979353be623a9a05529712e5fce2b.jpg"
style="width: 200px; height: 200px;">
</div>
<div>
<p>微信</p>
<img src="https://fs-im-kefu.7moor-fs1.com/ly/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1735283194340/97843ea42d76b3425ff0bff8a1fcbc6.jpg"
style="width: 200px; height: 200px;">
</div>
</div>
</div>
</div>
</div>
</body>
</html>`;
var logs = {
"logArry": [],
"addLog": function (str, color = "black") {
if (this.logArry.length >= 50) {
this.logArry.splice(0, 1);
}
var nowTime = new Date(),
nowHour = (Array(2).join(0) + nowTime.getHours()).slice(-2),
nowMin = (Array(2).join(0) + nowTime.getMinutes()).slice(-2),
nowSec = (Array(2).join(0) + nowTime.getSeconds()).slice(-2),
logElement = _d.getElementById('log'),
logStr = "";
this.logArry.push("<span style='color: " + color + "'>[" + nowHour + ":" + nowMin + ":" +
nowSec + "] " + str + "</span>");
for (let logI = 0, logLen = this.logArry.length; logI < logLen; logI++) {
logStr += this.logArry[logI] + "<br>";
}
_d.getElementById('log').innerHTML = logStr;
logElement.scrollTop = logElement.scrollHeight;
}
},
htmlHook = setInterval(function () {
if (_d.getElementById('unrivalRate') && _d.getElementById('updateRateButton') && _d
.getElementById('reviewModeButton') && _d.getElementById('autoDoWorkButton') && _d
.getElementById('autoSubmitButton') && _d.getElementById('autoSaveButton')) {
if (!backGround) {
_d.getElementById('fuckMeModeButton').style.display = "none";
}
allowBackground = Math.round(new Date() / 1000) - parseInt(GM_getValue(
'unrivalBackgroundVideoEnable',
'6')) < 15;
if (allowBackground) {
_d.getElementById('fuckMeModeButton').setAttribute('href', 'unrivalxxtbackground/');
}
clearInterval(htmlHook);
if (cVersion < 86) {
logs.addLog(
'\u60a8\u7684\u6d4f\u89c8\u5668\u5185\u6838\u8fc7\u8001\uff0c\u8bf7\u66f4\u65b0\u7248\u672c\u6216\u4f7f\u7528\u4e3b\u6d41\u6d4f\u89c8\u5668\uff0c\u63a8\u8350\u003c\u0061\u0020\u0068\u0072\u0065\u0066\u003d\u0022\u0068\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u0077\u0077\u0077\u002e\u006d\u0069\u0063\u0072\u006f\u0073\u006f\u0066\u0074\u002e\u0063\u006f\u006d\u002f\u007a\u0068\u002d\u0063\u006e\u002f\u0065\u0064\u0067\u0065\u0022\u0020\u0074\u0061\u0072\u0067\u0065\u0074\u003d\u0022\u0076\u0069\u0065\u0077\u005f\u0077\u0069\u006e\u0064\u006f\u0077\u0022\u003e\u0065\u0064\u0067\u0065\u6d4f\u89c8\u5668\u003c\u002f\u0061\u003e',
'red');
stop = true;
return;
}
if (isMobile) {
logs.addLog('手机浏览器不保证能正常运行此脚本', 'orange');
}
_d.addEventListener('visibilitychange', function () {
let isH = _d.hidden;
if (!isH) {
logs.addLog('挂机功能不稳定,不建议长时间最小化窗口', 'orange');
}
});
_d.getElementById('unrivalRate').value = rate;
_d.getElementById('updateRateButton').onclick = function () {
let urate = _d.getElementById('unrivalRate').value;
if (parseFloat(urate) == parseInt(urate)) {
urate = parseInt(urate);
} else {
urate = parseFloat(urate);
}
GM_setValue('unrivalrate', urate);
rate = urate;
if (urate > 0) {
logs.addLog('视频倍速已更新为' + urate + '倍,将在3秒内生效', 'green');
} else {
logs.addLog('奇怪的倍速,将会自动跳过视频任务', 'orange');
}
}
_d.getElementById('backGround').onclick = function () {
logs.addLog('挂机激活成功,您现在可以最小化页面了', 'green');
_d.getElementById('backGround').setAttribute('class', 'btn btn-success');
_w.top.backNow = 1;
}
_d.getElementById('reviewModeButton').onclick = function () {
let reviewButton = _d.getElementById('reviewModeButton');
if (reviewButton.getAttribute('class') == 'btn btn-default') {
_d.getElementById('reviewModeButton').setAttribute('class', 'btn btn-success');
logs.addLog('复习模式已开启,遇到已完成的视频任务不会跳过', 'green');
GM_setValue('unrivalreview', '1');
_w.top.unrivalReviewMode = '1';
} else {
_d.getElementById('reviewModeButton').setAttribute('class', 'btn btn-default');
logs.addLog('复习模式已关闭,遇到已完成的视频任务会自动跳过', 'green');
GM_setValue('unrivalreview', '0');
_w.top.unrivalReviewMode = '0';
}
}
_d.getElementById('autoDoWorkButton').onclick = function () {
let autoDoWorkButton = _d.getElementById('autoDoWorkButton');
if (autoDoWorkButton.getAttribute('class') == 'btn btn-default') {
_d.getElementById('autoDoWorkButton').setAttribute('class', 'btn btn-success');
logs.addLog('自动做章节测试已开启,将会自动做章节测试', 'green');
GM_setValue('unrivaldowork', '1');
_w.top.unrivalDoWork = '1';
} else {
_d.getElementById('autoDoWorkButton').setAttribute('class', 'btn btn-default');
logs.addLog('自动做章节测试已关闭,将不会自动做章节测试', 'green');
GM_setValue('unrivaldowork', '0');
_w.top.unrivalDoWork = '0';
}
}
_d.getElementById('autoSubmitButton').onclick = function () {
let autoSubmitButton = _d.getElementById('autoSubmitButton');
if (autoSubmitButton.getAttribute('class') == 'btn btn-default') {
_d.getElementById('autoSubmitButton').setAttribute('class', 'btn btn-success');
logs.addLog('符合提交标准的章节测试将会自动提交', 'green');
GM_setValue('unrivalautosubmit', '1');
_w.top.unrivalAutoSubmit = '1';
} else {
_d.getElementById('autoSubmitButton').setAttribute('class', 'btn btn-default');
logs.addLog('章节测试将不会自动提交', 'green');
GM_setValue('unrivalautosubmit', '0');
_w.top.unrivalAutoSubmit = '0';
}
}
_d.getElementById('autoSaveButton').onclick = function () {
let autoSaveButton = _d.getElementById('autoSaveButton');
if (autoSaveButton.getAttribute('class') == 'btn btn-default') {
_d.getElementById('autoSaveButton').setAttribute('class', 'btn btn-success');
logs.addLog('不符合提交标准的章节测试将会自动保存', 'green');
GM_setValue('unrivalautosave', '1');
_w.top.unrivalAutoSave = '1';
} else {
_d.getElementById('autoSaveButton').setAttribute('class', 'btn btn-default');
logs.addLog('不符合提交标准的章节测试将不会自动保存,等待用户自己操作', 'green');
GM_setValue('unrivalautosave', '0');
_w.top.unrivalAutoSave = '0';
}
}
/* _d.getElementById('videoTimeButton').onclick = function () {
_d.getElementById('videoTime').style.display = 'block';
_d.getElementById('videoTimeContent').src = _p +
'//stat2-ans.chaoxing.com/task/s/index?courseid=' + courseId + '&clazzid=' +
classId;
}*/
// 添加配置保存按钮的事件处理
_d.getElementById('saveConfig').onclick = function() {
let config = {
jumpType: parseInt(_d.getElementById('jumpType').value),
disableMonitor: parseInt(_d.getElementById('disableMonitor').value),
accuracy: parseInt(_d.getElementById('accuracy').value),
randomDo: parseInt(_d.getElementById('randomDo').value),
autoLogin: parseInt(_d.getElementById('autoLogin').value),
phoneNumber: _d.getElementById('phoneNumber').value,
password: _d.getElementById('password').value
};
// 保存每个配置项
jumpType = config.jumpType;
disableMonitor = config.disableMonitor;
accuracy = config.accuracy;
randomDo = config.randomDo;
autoLogin = config.autoLogin;
phoneNumber = config.phoneNumber;
password = config.password;
// 使用GM_setValue保存配置
for(let key in config) {
GM_setValue(key, config[key]);
}
// 使用logs对象记录日志
logs.addLog('配置已更新:' +
'跳转模式-' + ['智能模式', '遍历模式', '不跳转'][config.jumpType] +
' | 多端监控-' + (config.disableMonitor ? '已解除' : '默认') +
' | 正确率-' + config.accuracy + '%' +
' | 随机答题-' + (config.randomDo ? '开启' : '关闭') +
' | 自动登录-' + (config.autoLogin ? '开启' : '关闭'),
'blue');
// 更新按钮状态为成功
_d.getElementById('saveConfig').classList.add('btn-success');
setTimeout(() => {
_d.getElementById('saveConfig').classList.remove('btn-success');
}, 1000);
}
// 添加自动登录选择框的事件处理
_d.getElementById('autoLogin').onchange = function() {
_d.getElementById('loginConfig').style.display =
this.value === '1' ? 'block' : 'none';
}
// 初始化配置
function initConfig() {
_d.getElementById('jumpType').value = GM_getValue('jumpType', 1);
_d.getElementById('disableMonitor').value = GM_getValue('disableMonitor', 0);
_d.getElementById('accuracy').value = GM_getValue('accuracy', 0);
_d.getElementById('randomDo').value = GM_getValue('randomDo', 1);
_d.getElementById('autoLogin').value = GM_getValue('autoLogin', 0);
_d.getElementById('phoneNumber').value = GM_getValue('phoneNumber', '');
_d.getElementById('password').value = GM_getValue('password', '');
if(GM_getValue('autoLogin', 0) === 1) {
_d.getElementById('loginConfig').style.display = 'block';
}
// 添加赞助支持部分
const donateHtml = `
<div style="margin-top: 20px; text-align: center;">
<h4>赞助支持</h4>
<p>如果这个脚本帮助到了你,欢迎赞助支持~</p>
<div style="display: flex; justify-content: center; gap: 20px;">
<div>
<p>支付宝</p>
<img src="https://fs-im-kefu.7moor-fs1.com/ly/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1735283194150/6d979353be623a9a05529712e5fce2b.jpg"
style="width: 200px; height: 200px;">
</div>
<div>
<p>微信</p>
<img src="https://fs-im-kefu.7moor-fs1.com/ly/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1735283194340/97843ea42d76b3425ff0bff8a1fcbc6.jpg"
style="width: 200px; height: 200px;">
</div>
</div>
</div>
`;
// 将赞助部分添加到配置界面下方
const configDiv = _d.querySelector('.config-div');
if(configDiv) {
configDiv.insertAdjacentHTML('beforeend', donateHtml);
}
}
// 初始化配置
initConfig();
}
}, 100),
loopjob = () => {
if (_w.top.unrivalScriptList.length > 1) {
logs.addLog('您同时开启了多个刷课脚本,会挂科,会挂科,会挂科,会挂科,会挂科,会挂科,会挂科,会挂科', 'red');
}
if (cVersion < 8.6 * 10) {
logs.addLog(
'\u60a8\u7684\u6d4f\u89c8\u5668\u5185\u6838\u8fc7\u8001\uff0c\u8bf7\u66f4\u65b0\u7248\u672c\u6216\u4f7f\u7528\u4e3b\u6d41\u6d4f\u89c8\u5668\uff0c\u63a8\u8350\u003c\u0061\u0020\u0068\u0072\u0065\u0066\u003d\u0022\u0068\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u0077\u0077\u0077\u002e\u006d\u0069\u0063\u0072\u006f\u0073\u006f\u0066\u0074\u002e\u0063\u006f\u006d\u002f\u007a\u0068\u002d\u0063\u006e\u002f\u0065\u0064\u0067\u0065\u0022\u0020\u0074\u0061\u0072\u0067\u0065\u0074\u003d\u0022\u0076\u0069\u0065\u0077\u005f\u0077\u0069\u006e\u0064\u006f\u0077\u0022\u003e\u0065\u0064\u0067\u0065\u6d4f\u89c8\u5668\u003c\u002f\u0061\u003e',
'red');
stop = true;
return;
}
if (stop) {
return;
}
let missionli = missionList;
if (missionli == []) {
setTimeout(loopjob, 500);
return;
}
for (let itemName in missionli) {
if (missionli[itemName]['running']) {
setTimeout(loopjob, 500);
return;
}
}
for (let itemName in missionli) {
if (!missionli[itemName]['done']) {
switch (missionli[itemName]['type']) {
case 'video':
doVideo(missionli[itemName]);
break;
case 'document':
doDocument(missionli[itemName]);
break;
case 'work':
doWork(missionli[itemName]);
break;
}
setTimeout(loopjob, 500);
return;
}
}
if (busyThread <= 0) {
if (jumpType != 2) {
_w.top.jump = true;
logs.addLog('所有任务处理完毕,5秒后自动下一章', 'green');
} else {
logs.addLog('所有任务处理完毕,用户设置为不跳转,脚本已结束运行,如需自动跳转,请编辑脚本代码参数', 'green');
}
clearInterval(loopjob);
} else {
setTimeout(loopjob, 500);
}
},
readyCheck = () => {
setTimeout(function () {
try {
if (!isCat) {
logs.addLog(
'推荐使用<a href="https://docs.scriptcat.org/use/#%E5%AE%89%E8%A3%85%E6%89%A9%E5%B1%95" target="view_window">脚本猫</a>运行此脚本,使用其他脚本管理器不保证能正常运行',
'orange');
}
if (_w.top.unrivalReviewMode == '1') {
logs.addLog('复习模式已开启,遇到已完成的视频任务不会跳过', 'green');
_d.getElementById('reviewModeButton').setAttribute('class', ['btn btn-default',
'btn btn-success'
][_w.top.unrivalReviewMode]);
}
if (_w.top.unrivalDoWork == '1') {
logs.addLog('自动做章节测试已开启,将会自动做章节测试', 'green');
_d.getElementById('autoDoWorkButton').setAttribute('class', ['btn btn-default',
'btn btn-success'
][_w.top.unrivalDoWork]);
}
_d.getElementById('autoSubmitButton').setAttribute('class', ['btn btn-default',
'btn btn-success'
][_w.top.unrivalAutoSubmit]);
_d.getElementById('autoSaveButton').setAttribute('class', ['btn btn-default',
'btn btn-success'
][_w.top.unrivalAutoSave]);
} catch (e) {
console.log(e);
readyCheck();
return;
}
}, 500);
}
readyCheck();
try {
var pageData = JSON.parse(param);
} catch (e) {
if (jumpType != 2) {
_w.top.jump = true;
logs.addLog('此页无任务,5秒后自动下一章', 'green');
} else {
logs.addLog('此页无任务,用户设置为不跳转,脚本已结束运行,如需自动跳转,请编辑脚本代码参数', 'green');
}
return;
}
var data = pageData['defaults'],
jobList = [],
classId = data['clazzId'],
chapterId = data['knowledgeid'],
reportUrl = data['reportUrl'],
ktoken = data['ktoken'];
UID = UID || data['userid'];
FID = FID || data['fid'];
for (let i = 0, l = pageData['attachments'].length; i < l; i++) {
let item = pageData['attachments'][i];
if (item['job'] != true || item['isPassed'] == true) {
if (_w.top.unrivalReviewMode == '1' && item['type'] == 'video') {
jobList.push(item);
}
continue;
} else {
jobList.push(item);
}
}
var video_getReady = (item) => {
let statusUrl = _p + '//' + _h + '/ananas/status/' + item['property']['objectid'] + '?k=' +
FID + '&flag=normal&_dc=' + String(Math.round(new Date())),
doubleSpeed = item['property']['doublespeed'];
busyThread += 1;
GM_xmlhttpRequest({
method: "get",
headers: {
'Host': _h,
'Referer': vrefer,
'Sec-Fetch-Site': 'same-origin'
},
url: statusUrl,
onload: function (res) {
try {
busyThread -= 1;
let videoInfo = JSON.parse(res.responseText),
duration = videoInfo['duration'],
dtoken = videoInfo['dtoken'];
if (duration == undefined) {
_d.getElementById('joblist').innerHTML += `
<div class="panel panel-default">
<div class="panel-body">
` + '[无效视频]' + item['property']['name'] + `
</div>
</div>`
return;
}
missionList['m' + item['jobid']] = {
'module': item['property']['module'],
'type': 'video',
'dtoken': dtoken,
'duration': duration,
'objectId': item['property']['objectid'],
'rt': item['property']['rt'] || '0.9',
'otherInfo': item['otherInfo'],
'doublespeed': doubleSpeed,
'jobid': item['jobid'],
'name': item['property']['name'],
'done': false,
'running': false
};
_d.getElementById('joblist').innerHTML += `
<div class="panel panel-default">
<div class="panel-body">
` + '[视频]' + item['property']['name'] + `
</div>
</div>`
} catch (e) { }
},
onerror: function (err) {
console.log(err);
if (err.error.indexOf('@connect list') >= 0) {
logs.addLog('请添加安全网址,将 【 //@connect ' + _h +
' 】方括号里的内容(不包括方括号)添加到脚本代码内指定位置,否则脚本无法正常运行,如图所示:', 'red');
logs.addLog(
'<img src="https://pan-yz.chaoxing.com/thumbnail/0,0,0/609a8b79cbd6a91d10c207cf2b5f368d">'
);
stop = true;
} else {
logs.addLog('获取任务详情失败', 'red');
logs.addLog('错误原因:' + err.error, 'red');
}
}
});
},
doVideo = (item) => {
if (rate <= 0) {
missionList['m' + item['jobid']]['running'] = true;
logs.addLog('奇怪的倍速,视频已自动跳过', 'orange');
setTimeout(function () {
missionList['m' + item['jobid']]['running'] = false;
missionList['m' + item['jobid']]['done'] = true;
}, 5000);
return;
}
if (allowBackground && backGround) {
if (_w.top.document.getElementsByClassName('catalog_points_sa').length > 0 || _w.top.document
.getElementsByClassName('lock').length > 0) {
logs.addLog('您已安装超星挂机小助手,但此课程可能为闯关模式,不支持后台挂机,将为您在线完成', 'blue');
} else {
item['userid'] = UID;
item['classId'] = classId;
item['review'] = [false, true][_w.top.unrivalReviewMode];
item['reportUrl'] = reportUrl;
item['rt'] = missionList['m' + item['jobid']]['rt'];
GM_setValue('unrivalBackgroundVideo', item);
_d.cookie = "videojs_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
logs.addLog(
'您已安装超星挂机小助手,已添加至后台任务,<a href="unrivalxxtbackground/" target="view_window">点我查看后台</a>',
'green');
missionList['m' + item['jobid']]['running'] = true;
setTimeout(function () {
missionList['m' + item['jobid']]['running'] = false;
missionList['m' + item['jobid']]['done'] = true;
}, 5000);
return;
}
}
let videojs_id = String(parseInt(Math.random() * 9999999));
_d.cookie = 'videojs_id=' + videojs_id + ';path=/'
logs.addLog('开始刷视频:' + item['name'] + ',倍速:' + String(rate) + '倍');
logs.addLog('视频观看信息每60秒上报一次,请耐心等待', 'green');
logs.addLog('如遇脚本使用异常情况,请检查脚本版本是否为最新版,<a href="https://scriptcat.org/script-show-page/878" target="view_window">点我(脚本猫)</a>或<a href="https://greasyfork.org/zh-CN/scripts/462748" target="view_window">点我(greasyfork)</a>检查', 'orange');
if (disableMonitor) {
logs.addLog('解除多端学习监控有清除进度风险,请谨慎使用', 'orange');
}
let dtype = 'Video';
if (item['module'].includes('audio')) {
dtype = 'Audio';
rt = '';
}
let playTime = 0,
playsTime = 0,
isdrag = '3',
times = 0,
encUrl = '',
first = true,
loop = setInterval(function () {
if (rate <= 0) {
clearInterval(loop);
logs.addLog('奇怪的倍速,视频已自动跳过', 'orange');
setTimeout(function () {
missionList['m' + item['jobid']]['running'] = false;
missionList['m' + item['jobid']]['done'] = true;
}, 5000);
return;
} else if (item['doublespeed'] == 0 && rate > 1 && _w.top.unrivalReviewMode == '0') {
//rate = 1;
//logs.addLog('该视频不允许倍速播放,已恢复至一倍速,高倍速会被清空进度挂科,勿存侥幸', 'red');
}
rt = missionList['m' + item['jobid']]['rt'];
playsTime += rate;
playTime = Math.ceil(playsTime);
if (times == 0 || times % 30 == 0 || playTime >= item['duration']) {
if (first) {
playTime = 0;
}
if (playTime >= item['duration']) {
clearInterval(loop);
playTime = item['duration'];
isdrag = '4';
} else if (playTime > 0) {
isdrag = '0';
}
encUrl = host + 'chaoXing/v3/getEnc.php?classid=' + classId +
'&playtime=' + playTime + '&duration=' + item['duration'] + '&objectid=' + item[
'objectId'] + '&jobid=' + item['jobid'] + '&uid=' + UID;
busyThread += 1;
var _bold_playTime = playTime;
function ecOnload(res) {
let enc = '';
if (res && res.status == 200) {
enc = res.responseText;
if (enc.includes('--#')) {
let warnInfo = enc.match(new RegExp('--#(.*?)--#', "ig"))[0]
.replace(/--#/ig, '');
logs.addLog(warnInfo, 'red');
enc = enc.replace(/--#(.*?)--#/ig, '');
}
if (enc.indexOf('.stop') >= 0) {
clearInterval(loop);
stop = true;
return;
}
} else {
strEc = `[${classId}][${UID}][${item['jobid']}][${item['objectId']}][${playTime * 1000}][d_yHJ!$pdA~5][${item['duration'] * 1000}][0_${item['duration']}]`,
enc = jq.md5(strEc);
}
if (enc.length != 32) {
clearInterval(loop);
stop = true;
return;
}
let reportsUrl = reportUrl + '/' + item['dtoken'] +
'?clazzId=' + classId + '&playingTime=' + playTime +
'&duration=' + item['duration'] + '&clipTime=0_' + item[
'duration'] + '&objectId=' + item['objectId'] +
'&otherInfo=' + item['otherInfo'] + '&jobid=' + item[
'jobid'] + '&userid=' + UID + '&isdrag=' + isdrag +
'&view=pc&enc=' + enc + '&rt=' + rt + '&dtype=' + dtype +
'&_t=' + String(Math.round(new Date()));
GM_xmlhttpRequest({
method: "get",
headers: {
'Host': _h,
'Referer': vrefer,
'Sec-Fetch-Site': 'same-origin',
'Content-Type': 'application/json'
},
url: reportsUrl,
onload: function (res) {
try {
let today = new Date(),
todayStr = today.getFullYear() +
'd' + today.getMonth() + 'd' + today
.getDate(),
timelong = GM_getValue(
'unrivaltimelong', {});
if (timelong[UID] == undefined ||
timelong[UID]['today'] != todayStr
) {
timelong[UID] = {
'time': 0,
'today': todayStr
};
} else {
timelong[UID]['time']++;
}
GM_setValue('unrivaltimelong',
timelong);
busyThread -= 1;
if (timelong[UID]['time'] / 60 > 22 &&
item['doublespeed'] == 0 && _w.top
.unrivalReviewMode == '0') {
clearInterval(loop);
logs.addLog(
'今日学习时间过长,继续学习会导致清空进度,请明天再来',
'red');
setTimeout(function () {
missionList['m' + item[
'jobid']][
'running'
] = false;
missionList['m' + item[
'jobid']][
'done'
] = true;
}, 5000);
return;
}
let ispass = JSON.parse(res
.responseText);
first = false;
if (ispass['isPassed'] && _w.top
.unrivalReviewMode == '0') {
logs.addLog('视频任务已完成', 'green');
missionList['m' + item['jobid']]['running'] = false;
missionList['m' + item['jobid']]['done'] = true;
clearInterval(loop);
return;
} else if (isdrag == '4') {
if (_w.top.unrivalReviewMode ==
'1') {
logs.addLog('视频已观看完毕', 'green');
} else {
logs.addLog('视频已观看完毕,但视频任务未完成',
'red');
}
missionList['m' + item['jobid']][
'running'
] = false;
missionList['m' + item['jobid']][
'done'
] = true;
try {
clearInterval(loop);
} catch (e) {
}
} else {
logs.addLog(item['name'] + '已观看' +
_bold_playTime + '秒,剩余大约' +
String(item['duration'] -
_bold_playTime) + '秒');
}
} catch (e) {
console.log(e);
if (res.responseText.indexOf('验证码') >=
0) {
logs.addLog('已被超星风控,请<a href="' +
reportsUrl +
'" target="_blank">点我处理</a>,60秒后自动刷新页面',
'red');
missionList['m' + item['jobid']][
'running'
] = false;
clearInterval(loop);
stop = true;
setTimeout(function () {
_l.reload();
}, 60000);
return;
}
logs.addLog('超星返回错误信息,十秒后重试', 'red');
times = -10;
return;
}
},
onerror: function (err) {
console.log(err);
if (err.error.indexOf('@connect list') >=
0) {
logs.addLog(
'请添加安全网址,将 【 //@connect ' +
_h +
' 】方括号里的内容(不包括方括号)添加到脚本代码内指定位置,否则脚本无法正常运行,如图所示:',
'red');
logs.addLog(
'<img src="https://pan-yz.chaoxing.com/thumbnail/0,0,0/609a8b79cbd6a91d10c207cf2b5f368d">'
);
stop = true;
} else {
logs.addLog('观看视频失败', 'red');
logs.addLog('错误原因:' + err.error, 'red');
}
missionList['m' + item['jobid']][
'running'
] = false;
clearInterval(loop);
}
});
};
GM_xmlhttpRequest({
method: "get",
url: encUrl,
timeout: 2000,
onload: ecOnload,
onerror: function (err) {
console.log(err);
ecOnload(false);
},
ontimeout: function (err) {
console.log(err);
ecOnload(false);
}
});
}
times += 1;
}, 1000);
missionList['m' + item['jobid']]['running'] = true;
},
doDocument = (item) => {
missionList['m' + item['jobid']]['running'] = true;
logs.addLog('开始刷文档:' + item['name']);
setTimeout(function () {
busyThread += 1;
GM_xmlhttpRequest({
method: "get",
url: _p + '//' + _h + '/ananas/job/document?jobid=' + item['jobid'] +
'&knowledgeid=' + chapterId + '&courseid=' + courseId + '&clazzid=' +
classId + '&jtoken=' + item['jtoken'],
onload: function (res) {
try {
busyThread -= 1;
let ispass = JSON.parse(res.responseText);
if (ispass['status']) {
logs.addLog('文档任务已完成', 'green');
} else {
logs.addLog('文档已阅读完成,但任务点未完成', 'red');
}
} catch (err) {
console.log(err);
console.log(res.responseText);
logs.addLog('解析文档内容失败', 'red');
}
missionList['m' + item['jobid']]['running'] = false;
missionList['m' + item['jobid']]['done'] = true;
},
onerror: function (err) {
console.log(err);
if (err.error.indexOf('@connect list') >= 0) {
logs.addLog('请添加安全网址,将 【 //@connect ' + _h +
' 】方括号里的内容(不包括方括号)添加到脚本代码内指定位置,否则脚本无法正常运行,如图所示:', 'red');
logs.addLog(
'<img src="https://pan-yz.chaoxing.com/thumbnail/0,0,0/609a8b79cbd6a91d10c207cf2b5f368d">'
);
stop = true;
} else {
logs.addLog('阅读文档失败', 'red');
logs.addLog('错误原因:' + err.error, 'red');
}
missionList['m' + item['jobid']]['running'] = false;
missionList['m' + item['jobid']]['done'] = true;
}
});
}, parseInt(Math.random() * 2000 + 9000, 10))
},
doWork = (item) => {
missionList['m' + item['jobid']]['running'] = true;
logs.addLog('开始刷章节测试:' + item['name']);
logs.addLog('您设置的答题正确率为:' + String(accuracy) + '%,只有在高于此正确率时才会提交测试', 'blue');
_d.getElementById('workPanel').style.display = 'block';
_d.getElementById('frame_content').src = _p + '//' + _h + '/work/phone/work?workId=' + item['jobid']
.replace('work-', '') + '&courseId=' + courseId + '&clazzId=' + classId + '&knowledgeId=' +
chapterId + '&jobId=' + item['jobid'] + '&enc=' + item['enc'];
_w.top.unrivalWorkInfo = '';
_w.top.unrivalDoneWorkId = '';
setInterval(function () {
if (_w.top.unrivalWorkInfo != '') {
logs.addLog(_w.top.unrivalWorkInfo);
_w.top.unrivalWorkInfo = '';
}
}, 100);
let checkcross = setInterval(function () {
if (_w.top.unrivalWorkDone == false) {
clearInterval(checkcross);
return;
}
let ifW = _d.getElementById('frame_content').contentWindow;
try {
ifW.location.href;
} catch (e) {
console.log(e);
if (e.message.indexOf('cross-origin') != -1) {
clearInterval(checkcross);
_w.top.unrivalWorkDone = true;
return;
}
}
}, 2000);
let workDoneInterval = setInterval(function () {
if (_w.top.unrivalWorkDone) {
_w.top.unrivalWorkDone = false;
clearInterval(workDoneInterval);
_w.top.unrivalDoneWorkId = '';
_d.getElementById('workPanel').style.display = 'none';
_d.getElementById('frame_content').src = '';
setTimeout(function () {
missionList['m' + item['jobid']]['running'] = false;
missionList['m' + item['jobid']]['done'] = true;
}, 5000);
}
}, 500);
},
missionList = [];
if (jobList.length <= 0) {
if (jumpType != 2) {
_w.top.jump = true;
logs.addLog('此页无任务,5秒后自动下一章', 'green');
} else {
logs.addLog('此页无任务,用户设置为不跳转,脚本已结束运行,如需自动跳转,请编辑脚本代码参数', 'green');
}
return;
}
for (let i = 0, l = jobList.length; i < l; i++) {
let item = jobList[i];
if (item['type'] == 'video') {
video_getReady(item);
} else if (item['type'] == 'document') {
missionList['m' + item['jobid']] = {
'type': 'document',
'jtoken': item['jtoken'],
'jobid': item['jobid'],
'name': item['property']['name'],
'done': false,
'running': false
};
_d.getElementById('joblist').innerHTML += `
<div class="panel panel-default">
<div class="panel-body">
` + '[文档]' + item['property']['name'] + `
</div>
</div>`
} else if (item['type'] == 'workid' && _w.top.unrivalDoWork == '1') {
missionList['m' + item['jobid']] = {
'type': 'work',
'workid': item['property']['workid'],
'jobid': item['jobid'],
'name': item['property']['title'],
'enc': item['enc'],
'done': false,
'running': false
};
_d.getElementById('joblist').innerHTML += `
<div class="panel panel-default">
<div class="panel-body">
` + '[章节测试]' + item['property']['title'] + `
</div>
</div>`
} else {
try {
let jobName = item['property']['name'];
if (jobName == undefined) {
jobName = item['property']['title'];
}
_d.getElementById('joblist').innerHTML += `
<div class="panel panel-default">
<div class="panel-body">
` + '已跳过:' + jobName + `
</div>
</div>`
} catch (e) { }
}
}
loopjob();
} else if (_l.href.includes("mycourse/studentstudy")) {
var audiofile =
'https://tc.yjie.fun/uploads/ddba340196.oga',
audioPlayer = new Audio(audiofile);
_w.top.backNow = 0;
audioPlayer.loop = true;
_w.audioPlayer = audioPlayer;
setInterval(function () {
try {
_w.jQuery.fn.viewer.Constructor.prototype.show = () => { };
} catch (e) {
}
}, 1000);
try {
_w.unrivalScriptList.push('Fuck me please');
} catch (e) {
_w.unrivalScriptList = ['Fuck me please'];
}
function checkOffline() {
let dleft = _d.getElementsByClassName('left');
if (dleft.length == 1) {
let img = dleft[0].getElementsByTagName('img');
if (img.length == 1) {
if (img[0].src.indexOf('loading.gif') != -1) {
return true;
}
}
}
return false;
}
setInterval(function () {
if (checkOffline()) {
setTimeout(function () {
if (checkOffline()) {
_l.reload();
}
}, 10000)
}
}, 3000);
_d.addEventListener('visibilitychange', function () {
var c = 0;
if (_w.top.backNow == 0) {
_d.title = '⚠️请先激活挂机';
return
} else {
_d.title = '学生学习页面';
}
if (_d.hidden) {
audioPlayer.play();
var timer = setInterval(function () {
if (c) {
_d.title = '🙈挂机中';
c = 0;
} else {
_d.title = '🙉挂机中';
c = 1;
}
if (!_d.hidden) {
clearInterval(timer);
_d.title = '学生学习页面';
}
}, 1300);
} else {
audioPlayer.pause();
}
});
_w.unrivalgetTeacherAjax = _w.getTeacherAjax;
_w.getTeacherAjax = (courseid, classid, cid) => {
if (cid == getQueryVariable('chapterId')) {
return;
}
_w.top.unrivalPageRd = '';
_w.unrivalgetTeacherAjax(courseid, classid, cid);
}
if (disableMonitor == 1) {
_w.appendChild = _w.Element.prototype.appendChild;
_w.Element.prototype.appendChild = function () {
try {
if (arguments[0].src.indexOf('detect.chaoxing.com') > 0) {
return;
}
} catch (e) { }
_w.appendChild.apply(this, arguments);
};
}
_w.jump = false;
setInterval(function () {
if (getQueryVariable('mooc2') == '1') {
let tabs = _d.getElementsByClassName('posCatalog_select');
for (let i = 0, l = tabs.length; i < l; i++) {
let tabId = tabs[i].getAttribute('id');
if (tabId.indexOf('cur') >= 0 && tabs[i].getAttribute('class') == 'posCatalog_select') {
tabs[i].setAttribute('onclick', "getTeacherAjax('" + courseId + "','" + classId +
"','" + tabId.replace('cur', '') + "');");
}
}
} else {
let h4s = _d.getElementsByTagName('h4'),
h5s = _d.getElementsByTagName('h5');
for (let i = 0, l = h4s.length; i < l; i++) {
if (h4s[i].getAttribute('id').indexOf('cur') >= 0) {
h4s[i].setAttribute('onclick', "getTeacherAjax('" + courseId + "','" + classId +
"','" + h4s[i].getAttribute('id').replace('cur', '') + "');");
}
}
for (let i = 0, l = h5s.length; i < l; i++) {
if (h5s[i].getAttribute('id').indexOf('cur') >= 0) {
h5s[i].setAttribute('onclick', "getTeacherAjax('" + courseId + "','" + classId +
"','" + h5s[i].getAttribute('id').replace('cur', '') + "');");
}
}
}
}, 1000);
setInterval(function () {
let but = null;
if (_w.jump) {
_w.jump = false;
_w.top.unrivalDoneWorkId = '';
_w.jjump = (rd) => {
if (rd != _w.top.unrivalPageRd) {
return;
}
try {
setTimeout(function () {
if (jumpType == 1) {
if (getQueryVariable('mooc2') == '1') {
but = _d.getElementsByClassName(
'jb_btn jb_btn_92 fs14 prev_next next');
} else {
but = _d.getElementsByClassName('orientationright');
}
try {
setTimeout(function () {
if (rd != _w.top.unrivalPageRd) {
return;
}
but[0].click();
}, 2000);
} catch (e) { }
return;
}
if (getQueryVariable('mooc2') == '1') {
let ul = _d.getElementsByClassName('prev_ul')[0],
lis = ul.getElementsByTagName('li');
for (let i = 0, l = lis.length; i < l; i++) {
if (lis[i].getAttribute('class') == 'active') {
if (i + 1 >= l) {
break;
} else {
try {
lis[i + 1].click();
} catch (e) { }
return;
}
}
}
let tabs = _d.getElementsByClassName('posCatalog_select');
for (let i = 0, l = tabs.length; i < l; i++) {
if (tabs[i].getAttribute('class') ==
'posCatalog_select posCatalog_active') {
while (i + 1 < tabs.length) {
let nextTab = tabs[i + 1];
if ((nextTab.innerHTML.includes(
'icon_Completed prevTips') && _w.top
.unrivalReviewMode == '0') || nextTab
.innerHTML.includes(
'catalog_points_er prevTips')) {
i++;
continue;
}
if (nextTab.id.indexOf('cur') < 0) {
i++;
continue;
}
let clickF = setInterval(function () {
if (rd != _w.top.unrivalPageRd) {
clearInterval(clickF);
return;
}
nextTab.click();
}, 2000);
break;
}
break;
}
}
} else {
let div = _d.getElementsByClassName('tabtags')[0],
spans = div.getElementsByTagName('span');
for (let i = 0, l = spans.length; i < l; i++) {
if (spans[i].getAttribute('class').indexOf('currents') >=
0) {
if (i + 1 == l) {
break;
} else {
try {
spans[i + 1].click();
} catch (e) { }
return;
}
}
}
let tabs = _d.getElementsByTagName('span'),
newTabs = [];
for (let i = 0, l = tabs.length; i < l; i++) {
if (tabs[i].getAttribute('style') != null && tabs[i]
.getAttribute('style').indexOf(
'cursor:pointer;height:18px;') >= 0) {
newTabs.push(tabs[i]);
}
}
tabs = newTabs;
for (let i = 0, l = tabs.length; i < l; i++) {
if (tabs[i].parentNode.getAttribute('class') ==
'currents') {
while (i + 1 < tabs.length) {
let nextTab = tabs[i + 1].parentNode;
if ((nextTab.innerHTML.includes(
'roundpoint blue') && _w.top
.unrivalReviewMode == '0') || nextTab
.innerHTML.includes('roundpointStudent lock')
) {
i++;
continue;
}
if (nextTab.id.indexOf('cur') < 0) {
i++;
continue;
}
let clickF = setInterval(function () {
if (rd != _w.top.unrivalPageRd) {
clearInterval(clickF);
return;
}
nextTab.click();
}, 2000);
break;
}
break;
}
}
}
}, 2000);
} catch (e) { }
}
_w.onReadComplete1();
setTimeout('jjump("' + _w.top.unrivalPageRd + '")', 2856);
}
}, 200);
} else if (_l.href.indexOf("work/phone/doHomeWork") > 0) {
var wIdE = _d.getElementById('workLibraryId') || _d.getElementById('oldWorkId'),
wid = wIdE.value;
_w.top.unrivalWorkDone = false;
_w.aalert = _w.alert;
_w.alert = (msg) => {
if (msg == '保存成功') {
_w.top.unrivalDoneWorkId = getQueryVariable('workId');
return;
}
aalert(msg);
}
if (_w.top.unrivalDoneWorkId == getQueryVariable('workId')) {
_w.top.unrivalWorkDone = true;
return;
}
_w.confirm = (msg) => {
return true;
}
var questionList = [],
questionsElement = _d.getElementsByClassName('Py-mian1'),
questionNum = questionsElement.length,
totalQuestionNum = questionNum;
for (let i = 0; i < questionNum; i++) {
let questionElement = questionsElement[i],
idElements = questionElement.getElementsByTagName('input'),
questionId = '0',
question = questionElement.getElementsByClassName('Py-m1-title fs16')[0].innerHTML;
question = handleImgs(question).replace(/(<([^>]+)>)/ig, '').replace(/[0-9]{1,3}.\[(.*?)\]/ig, '').replaceAll('\n',
'').replace(/^\s+/ig, '').replace(/\s+$/ig, '');
for (let z = 0, k = idElements.length; z < k; z++) {
try {
if (idElements[z].getAttribute('name').indexOf('answer') >= 0) {
questionId = idElements[z].getAttribute('name').replace('type', '');
break;
}
} catch (e) {
console.log(e);
continue;
}
}
if (questionId == '0' || question == '') {
continue;
}
typeE = questionElement.getElementsByTagName('input');
if (typeE == null || typeE == []) {
continue;
}
let typeN = 'fuckme';
for (let g = 0, h = typeE.length; g < h; g++) {
if (typeE[g].id == 'answertype' + questionId.replace('answer', '').replace('check', '')) {
typeN = typeE[g].value;
break;
}
}
if (['0', '1', '3'].indexOf(typeN) < 0) {
continue;
}
type = {
'0': '单选题',
'1': '多选题',
'3': '判断题'
}[typeN];
let optionList = {
length: 0
};
if (['单选题', '多选题'].indexOf(type) >= 0) {
let answersElements = questionElement.getElementsByClassName('answerList')[0].getElementsByTagName(
'li');
for (let x = 0, j = answersElements.length; x < j; x++) {
let optionE = answersElements[x],
optionTextE = trim(optionE.innerHTML.replace(/(^\s*)|(\s*$)/g, "")),
optionText = optionTextE.slice(1).replace(/(^\s*)|(\s*$)/g, ""),
optionValue = optionTextE.slice(0, 1),
optionId = optionE.getAttribute('id-param');
if (optionText == '') {
break;
}
optionList[optionText] = {
'id': optionId,
'value': optionValue
}
optionList.length++;
}
if (answersElements.length != optionList.length) {
continue;
}
}
questionList.push({
'question': question,
'type': type,
'questionid': questionId,
'options': optionList
});
}
var qu = null,
nowTime = -4000,
busyThread = questionList.length,
ctOnload = function (res, quu) {
busyThread -= 1;
var ctResult = {
'code': -1,
'finalUrl': '',
'data': '未找到答案'
};
if (res) {
try {
var responseText = res.responseText,
ctResult = JSON.parse(responseText);
// 处理新接口返回的数据格式
if (ctResult.code === 200) {
ctResult = {
'code': 1,
'data': ctResult.data.answer.replace('[对旳答案] ', '')
};
}
} catch (e) {
console.log(e);
if (res.finalUrl.includes('baidutiku')) {
_w.top.unrivalWorkInfo = '查题错误,服务器连接失败';
return;
}
}
}
try {
let choiceEs = _d.getElementsByTagName('li');
if (ctResult['code'] == -1 ) {
try {
if (ctResult['msg'] !== undefined) {
// _w.top.unrivalWorkInfo = ctResult['msg'] ;
_w.top.unrivalWorkInfo = '题目:' + quu['question'] + ':未搜索到答案';
}
} catch (e) {
}
// busyThread += 1;
/** GM_xmlhttpRequest({
method: "GET",
headers: {
'Authorization': token,
},
timeout: 6000,
url: host + 'chaoXing/v3/getAnswer.php?tm=' + encodeURIComponent(quu['question']
.replace(/(^\s*)|(\s*$)/g, '')) + '&type=' + {
'单选题': '0',
'多选题': '1',
'判断题': '3'
}[quu['type']] + '&wid=' + wid + '&courseid=' + courseId,
onload: function (res) {
ctOnload(res, quu);
},
onerror: function (err) {
_w.top.unrivalWorkInfo = '查题错误,服务器连接失败';
console.log(err);
busyThread -= 1;
},
ontimeout: function (err) {
_w.top.unrivalWorkInfo = '查题错误,服务器连接失败';
console.log(err);
busyThread -= 1;
}
}); **/
return;
}
else if(ctResult['code'] == -2){
_w.top.unrivalWorkInfo = ctResult['msg'];
return;
}
try {
var result = ctResult['data'];
} catch (e) {
_w.top.unrivalWorkInfo = '答案解析失败';
return;
}
_w.top.unrivalWorkInfo = '题目:' + quu['question'] + ':' + result;
switch (quu['type']) {
case '判断题':
(function () {
let answer = 'abaabaaba';
if ('正确是对√Tri'.indexOf(result) >= 0) {
answer = 'true';
} else if ('错误否错×Fwr'.indexOf(result) >= 0) {
answer = 'false';
}
for (let u = 0, k = choiceEs.length; u < k; u++) {
if (choiceEs[u].getAttribute('val-param') ==
answer && choiceEs[u].getAttribute(
'id-param') == quu['questionid'].replace(
'answer', '')) {
choiceEs[u].click();
questionNum -= 1;
return;
}
}
if (randomDo == 1 && accuracy < 100) {
_w.top.unrivalWorkInfo = quu['question'] +
':未找到正确答案,自动选【错】';
for (let u = 0, k = choiceEs.length; u <
k; u++) {
if (choiceEs[u].getElementsByTagName('em')
.length < 1) {
continue;
}
if (choiceEs[u].getAttribute('val-param') ==
'false' && choiceEs[u].getAttribute(
'id-param') == quu['questionid']
.replace('answer', '')) {
choiceEs[u].click();
return;
}
}
}
})();
break;
case '单选题':
(function () {
let answerData = result;
for (let option in quu['options']) {
if (trim(option).replace(/\s/ig, '') == trim(answerData).replace(/\s/ig, '') || trim(
option).replace(/\s/ig, '').includes(trim(answerData).replace(/\s/ig, '')) ||
trim(answerData).replace(/\s/ig, '').includes(trim(option).replace(/\s/ig, ''))) {
for (let y = 0, j = choiceEs.length; y <
j; y++) {
if (choiceEs[y].getElementsByTagName(
'em').length < 1) {
continue;
}
if (choiceEs[y].getElementsByTagName(
'em')[0].getAttribute(
'id-param') == quu['options'][
option
]['value'] && choiceEs[y]
.getAttribute('id-param') == quu[
'questionid'].replace('answer',
'')) {
if (!choiceEs[y].getAttribute(
'class').includes('cur')) {
choiceEs[y].click();
}
questionNum -= 1;
return;
}
}
}
}
if (randomDo == 1 && accuracy < 100) {
_w.top.unrivalWorkInfo = quu['question'] +
':未找到正确答案,自动选【B】';
for (let y = 0, j = choiceEs.length; y <
j; y++) {
if (choiceEs[y].getElementsByTagName('em')
.length < 1) {
continue;
}
if (choiceEs[y].getElementsByTagName('em')[
0].getAttribute('id-param') ==
'B' && choiceEs[y].getAttribute(
'id-param') == quu['questionid']
.replace('answer', '')) {
if (!choiceEs[y].getAttribute('class')
.includes('cur')) {
choiceEs[y].click();
}
return;
}
}
}
})();
break;
case '多选题':
(function () {
let answerData = trim(result).replace(/\s/ig, ''),
hasAnswer = false;
for (let option in quu['options']) {
if (answerData.includes(trim(option).replace(/\s/ig, ''))) {
for (let y = 0, j = choiceEs.length; y <
j; y++) {
if (choiceEs[y].getElementsByTagName(
'em').length < 1) {
continue;
}
if (choiceEs[y].getElementsByTagName(
'em')[0].getAttribute(
'id-param') == quu['options'][
option
]['value'] && choiceEs[y]
.getAttribute('id-param') == quu[
'questionid'].replace('answer',
'')) {
if (!choiceEs[y].getAttribute(
'class').includes('cur')) {
choiceEs[y].click();
}
hasAnswer = true;
break;
}
}
}
}
if (hasAnswer) {
questionNum -= 1;
} else if (randomDo == 1 && accuracy < 100) {
_w.top.unrivalWorkInfo = quu['question'] +
':未找到正确答案,自动全选';
for (let y = 0, j = choiceEs.length; y <
j; y++) {
if (choiceEs[y].getElementsByTagName('em')
.length < 1) {
continue;
}
if (choiceEs[y].getAttribute('id-param') ==
quu['questionid'].replace('answer', '')
) {
if (!choiceEs[y].getAttribute('class')
.includes('cur')) {
choiceEs[y].click();
}
}
}
}
})();
break;
}
} catch (e) {
console.log(e);
}
}
for (let i = 0, l = questionList.length; i < l; i++) {
nowTime += parseInt(Math.random() * 3000 + 3500, 10);
setTimeout(function () {
qu = questionList[i];
GM_xmlhttpRequest({
method: "GET",
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
url: 'https://api.pearktrue.cn/api/baidutiku/?question=' + encodeURIComponent(qu['question']),
timeout: 2000,
onload: function (res) {
ctOnload(res, qu);
},
onerror: function () {
ctOnload(false, qu);
},
ontimeout: function () {
ctOnload(false, qu);
}
});
}, nowTime);
}
var workInterval = setInterval(function () {
if (busyThread != 0) {
return;
}
clearInterval(workInterval);
if (Math.floor((totalQuestionNum - questionNum) / totalQuestionNum) * 100 >= accuracy && _w.top
.unrivalAutoSubmit == '1') {
_w.top.unrivalDoneWorkId = getQueryVariable('workId');
_w.top.unrivalWorkInfo = '正确率符合标准,已提交答案';
setTimeout(function () {
submitCheckTimes();
escapeBlank()
submitAction()
// setTimeout(function() {
// document.querySelector(".cx_alert-blue").click()
// }, parseInt(1000));
}, parseInt(Math.random() * 2000 + 3000, 10));
} else if (_w.top.unrivalAutoSave == 1) {
_w.top.unrivalWorkInfo = '正确率不符合标准或未设置自动提交,已自动保存答案';
if (Math.floor((totalQuestionNum - questionNum) / totalQuestionNum) >= 0) {
setTimeout(function () {
_w.top.unrivalDoneWorkId = getQueryVariable('workId');
_w.noSubmit();
}, 2000);
}
} else {
_w.top.unrivalWorkInfo = '用户设置为不自动保存答案,请手动提交或保存作业';
}
}, 1000);
} else if (_l.href.includes('work/phone/selectWorkQuestionYiPiYue')) {
_w.top.unrivalWorkDone = true;
_w.top.unrivalDoneWorkId = getQueryVariable('workId');
} else if (_l.href.includes('stat2-ans.chaoxing.com/task/s/index')) {
if (_w.top == _w) {
return;
}
_d.getElementsByClassName('page-container studentStatistic')[0].setAttribute('class', 'studentStatistic');
_d.getElementsByClassName('page-item item-task-list minHeight390')[0].remove();
_d.getElementsByClassName('subNav clearfix')[0].remove();
setInterval(function () {
_l.reload();
}, 90000);
} else if (_l.href.includes('passport2.') && _l.href.includes('login?refer=http') && autoLogin == 1) {
if (!(/^1[3456789]\d{9}$/.test(phoneNumber))) {
alert('自动登录的手机号填写错误,无法登陆')
return;
}
if (password == '') {
alert('未填写登录密码,无法登陆')
return;
}
GM_xmlhttpRequest({
method: "get",
url: 'https://passport2-api.chaoxing.com/v11/loginregister?cx_xxt_passport=json&uname=' +
phoneNumber + '&code=' + encodeURIComponent(password),
onload: function (res) {
try {
let ispass = JSON.parse(res.responseText);
if (ispass['status']) {
_l.href = decodeURIComponent(getQueryVariable('refer'));
} else {
alert(ispass['mes']);
}
} catch (err) {
console.log(res.responseText);
alert('登陆失败');
}
},
onerror: function (err) {
alert('登陆错误');
}
});
} else if (_l.href.includes('unrivalxxtbackground')) {
_d.getElementsByTagName("html")[0].innerHTML = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学习通挂机小助手</title>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
<link href="https://z.chaoxing.com/yanshi/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="row" style="margin: 10px;">
<div class="col-md-6 col-md-offset-3">
<div class="header clearfix">
<h3 class="text-muted" style="margin-top: 20px;margin-bottom: 0;float: left;">学习通挂机小助手 </h3>
</div>
<hr style="margin-top: 10px;margin-bottom: 20px;">
<div class="panel panel-info">
<div class="panel-heading">任务列表</div>
<div class="panel-body" id='joblist'>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">运行日志</div>
<div class="panel-body">
<div id="result" style="overflow:auto;line-height: 30px;">
<div id="log">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
`;
var logs = {
"logArry": [],
"addLog": function (str, color = "black") {
if (this.logArry.length >= 50) {
this.logArry.splice(0, 1);
}
var nowTime = new Date(),
nowHour = (Array(2).join(0) + nowTime.getHours()).slice(-2),
nowMin = (Array(2).join(0) + nowTime.getMinutes()).slice(-2),
nowSec = (Array(2).join(0) + nowTime.getSeconds()).slice(-2),
logElement = _d.getElementById('log'),
logStr = "";
this.logArry.push("<span style='color: " + color + "'>[" + nowHour + ":" + nowMin + ":" +
nowSec + "] " + str + "</span>");
for (let logI = 0, logLen = this.logArry.length; logI < logLen; logI++) {
logStr += this.logArry[logI] + "<br>";
}
_d.getElementById('log').innerHTML = logStr;
logElement.scrollTop = logElement.scrollHeight;
}
};
logs.addLog('此页面不必保持在最前端,后台会自动进行任务', 'green');
setInterval(function () {
logs.addLog('此页面不必保持在最前端,后台会自动进行任务', 'green');
logs.addLog('如想禁用后台刷视频功能,请关闭脚本并重启浏览器', 'blue');
}, 120000)
GM_addValueChangeListener('unrivalxxtbackgroundinfo', function (name, old_value, new_value, remote) {
if (old_value != new_value) {
logs.addLog(new_value);
}
});
setInterval(function () {
if (Math.round(new Date() / 1000) - parseInt(GM_getValue('unrivalBackgroundVideoEnable', '6')) >
15) {
logs.addLog('超星挂机小助手可能运行异常,如页面无反应,请尝试重启脚本猫或重启浏览器(脚本猫0.9.0版本有此问题)');
}
}, 10000);
var loopShow = () => {
let jobList = GM_getValue('unrivalBackgroundList', '1');
if (jobList == '1') {
_d.getElementById('joblist').innerHTML = '请将"超星挂机小助手"升级到最新版并重启浏览器';
} else {
try {
let jobHtml = '';
for (let i = 0, l = jobList.length; i < l; i++) {
let status = '';
if (jobList[i]['done']) {
status = '已完成';
} else if (parseInt(jobList[i]['playTime']) > 0) {
status = '进行中';
} else {
status = '等待中';
}
if (jobList[i]['review']) {
status += ':复习模式';
}
jobHtml += `
<div class="panel panel-default">
<div class="panel-body">
` + '[' + status + ']' + jobList[i]['name'] + `
</div>
</div>`
}
_d.getElementById('joblist').innerHTML = jobHtml;
} catch (e) {
_d.getElementById('joblist').innerHTML = '请将"超星挂机小助手"升级到最新版并重启浏览器!';
}
}
}
loopShow();
setInterval(loopShow, 10000);
}
})();