dnomd343
4 years ago
commit
cba5044c64
6 changed files with 1811 additions and 0 deletions
@ -0,0 +1,107 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>刷课教程 - 后台</title> |
|||
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> |
|||
<script> |
|||
var validity; |
|||
var url; |
|||
$(document).ready(function() { |
|||
$.get("/js/pw/status", function(data) { |
|||
console.log(data); |
|||
output(data); |
|||
showLimit(); |
|||
}); |
|||
$("#reset").click(function() { |
|||
renewKey(); |
|||
}); |
|||
$("#copy").click(function() { |
|||
copyToClip(url); |
|||
}); |
|||
}); |
|||
function checkStatus() { |
|||
$.get("/js/pw/status", function(data) { |
|||
console.log(data); |
|||
output(data); |
|||
showLimit(); |
|||
}); |
|||
} |
|||
function renewKey() { |
|||
$.get("/js/pw/new", function(data) { |
|||
console.log(data); |
|||
output(data); |
|||
}); |
|||
} |
|||
function output(data) { |
|||
validity = data.validity; |
|||
url = 'https://menma01.com/js?key=' + data.passwd; |
|||
$("#validity").text(timestampToTime(data.validity)); |
|||
$("#url").text(url); |
|||
} |
|||
function showLimit() { |
|||
now = parseInt(new Date().getTime() / 1000); |
|||
limit = validity - now; |
|||
if (limit < 0) { |
|||
$("#limit").text('(刷新中...)'); |
|||
$.get("/js/pw/status", function(data) { |
|||
console.log(data); |
|||
output(data); |
|||
}); |
|||
} else { |
|||
$("#limit").text('(剩余:' + limit + 's)'); |
|||
} |
|||
} |
|||
function copyToClip(content, message) { |
|||
var aux = document.createElement("input"); |
|||
aux.setAttribute("value", content); |
|||
document.body.appendChild(aux); |
|||
aux.select(); |
|||
document.execCommand("copy"); |
|||
document.body.removeChild(aux); |
|||
if (message == null) { |
|||
alert("复制成功"); |
|||
} |
|||
} |
|||
function timestampToTime(timestamp) { |
|||
var date = new Date(timestamp * 1000); |
|||
var Y = date.getFullYear() + '-'; |
|||
var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'; |
|||
var D = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()) + ' '; |
|||
var h = (date.getHours() < 10 ? '0' + (date.getHours()) : date.getHours()) + ':'; |
|||
var m = (date.getMinutes() < 10 ? '0' + (date.getMinutes()) : date.getMinutes()) + ':'; |
|||
var s = (date.getSeconds() < 10 ? '0' + (date.getSeconds()) : date.getSeconds()); |
|||
return Y + M + D + h + m + s; |
|||
} |
|||
var t1 = window.setInterval(showLimit, 1000); |
|||
var t2 = window.setInterval(checkStatus, 5000); |
|||
</script> |
|||
<style> |
|||
div { |
|||
text-align: center; |
|||
margin-top: 150px; |
|||
} |
|||
#validity { |
|||
display: inline-block; |
|||
} |
|||
#limit { |
|||
display: inline-block; |
|||
} |
|||
#copy { |
|||
margin-right: 10px; |
|||
} |
|||
#reset { |
|||
margin-left: 10px; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div> |
|||
<p id="validity"></p> |
|||
<p id="limit"></p> |
|||
<p id="url"></p> |
|||
<button id="copy">一键复制</button> |
|||
<button id="reset">重置链接</button> |
|||
</div> |
|||
</body> |
|||
</html> |
@ -0,0 +1,133 @@ |
|||
<?php |
|||
|
|||
$mysqlServer = 'localhost'; |
|||
$mysqlUser = 'chaoxing'; |
|||
$mysqlPasswd = 'chaoxing_passwd'; |
|||
$databaseName = 'chaoxing'; |
|||
|
|||
function getStatus() { |
|||
global $mysqlServer, $mysqlUser, $mysqlPasswd, $databaseName; |
|||
$conn = new mysqli($mysqlServer, $mysqlUser, $mysqlPasswd, $databaseName); |
|||
$raw = $conn->query('SELECT * FROM main')->fetch_assoc(); |
|||
$status['passwd'] = $raw['passwd']; |
|||
$status['validity'] = $raw['validity']; |
|||
return $status; |
|||
} |
|||
|
|||
function setStatus($passwd, $validity) { |
|||
global $mysqlServer, $mysqlUser, $mysqlPasswd, $databaseName; |
|||
$conn = new mysqli($mysqlServer, $mysqlUser, $mysqlPasswd, $databaseName); |
|||
$conn->query('DELETE FROM main'); |
|||
$raw = $conn->query('INSERT INTO main (passwd,validity) VALUES ("' . $passwd . '","' . $validity . '")'); |
|||
} |
|||
|
|||
function checkStatus() { |
|||
header('Content-Type: application/json; charset=utf-8'); |
|||
echo json_encode(getStatus()); |
|||
} |
|||
|
|||
function newPasswd($length){ |
|||
$passwd = ''; |
|||
for ($i = 0; $i < $length; $i++) { |
|||
$rand = mt_rand(0, 61); |
|||
if ($rand >= 0 && $rand <=9) { |
|||
$passwd .= chr($rand + 48); |
|||
} else if ($rand >= 10 && $rand <=35) { |
|||
$passwd .= chr($rand + 55); |
|||
} else if ($rand >=36 && $rand <= 61) { |
|||
$passwd .= chr($rand + 61); |
|||
} |
|||
} |
|||
return $passwd; |
|||
} |
|||
|
|||
function newStatus() { |
|||
$passwd = newPasswd(16); |
|||
$validity = (int)time() + 300; |
|||
setStatus($passwd, $validity); |
|||
} |
|||
|
|||
function isExpired() { |
|||
if ((int)getStatus()['validity'] < (int)time()) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
function isAuth() { |
|||
if ($_GET['key'] != getStatus()['passwd']) { |
|||
return false; |
|||
} else { |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
function checkKey() { |
|||
header('Content-Type: application/json; charset=utf-8'); |
|||
if (isAuth()) { |
|||
echo '{"status":"T"}'; |
|||
} else { |
|||
echo '{"status":"F"}'; |
|||
} |
|||
} |
|||
|
|||
function outputFile($fileName) { |
|||
$data = file_get_contents($fileName); |
|||
echo $data; |
|||
} |
|||
|
|||
function queryScript($type) { |
|||
if (isAuth()) { |
|||
if ($type == 1) { |
|||
header('Content-Type: application/x-javascript; charset=utf-8'); |
|||
outputFile('script_1.user.js'); |
|||
} else if ($type == 2) { |
|||
header('Content-Type: application/x-javascript; charset=utf-8'); |
|||
outputFile('script_2.user.js'); |
|||
} else { |
|||
header('Content-Type: application/x-javascript; charset=utf-8'); |
|||
outputFile('script_3.user.js'); |
|||
} |
|||
} else { |
|||
header('Content-Type: text/html; charset=utf-8'); |
|||
echo '密钥已失效'; |
|||
} |
|||
} |
|||
|
|||
function route() { |
|||
$urlRaw = $_SERVER['DOCUMENT_URI']; |
|||
if ($urlRaw == '/js/admin') { |
|||
header('Content-Type: text/html; charset=utf-8'); |
|||
outputFile('admin.html'); |
|||
} else if ($urlRaw == '/js/pw/new') { |
|||
newStatus(); |
|||
checkStatus(); |
|||
} else if ($urlRaw == '/js/pw/status') { |
|||
checkStatus(); |
|||
} else if ($urlRaw == '/js') { |
|||
header('Content-Type: text/html; charset=utf-8'); |
|||
outputFile('user.html'); |
|||
} else if ($urlRaw == '/js/check') { |
|||
checkKey(); |
|||
} else if ($urlRaw == '/js/query/script_1.user.js') { |
|||
queryScript('1'); |
|||
} else if ($urlRaw == '/js/query/script_2.user.js') { |
|||
queryScript('2'); |
|||
} else if ($urlRaw == '/js/query/script_3.user.js') { |
|||
queryScript('3'); |
|||
} else { |
|||
echo '未授权操作'; |
|||
} |
|||
} |
|||
|
|||
function main() { |
|||
if (isExpired()) { |
|||
newStatus(); |
|||
} |
|||
route(); |
|||
} |
|||
|
|||
main(); |
|||
|
|||
?> |
@ -0,0 +1,281 @@ |
|||
// ==UserScript==
|
|||
// @name 超星学习通网课助手(考试专版)
|
|||
// @namespace victotyhilling
|
|||
// @version 1.1.6
|
|||
// @description 自动搜索尔雅MOOC考试答案,支持自动答题、自动切换题目、隐藏答案搜索提示框等,解除各类功能限制,开放自定义参数
|
|||
// @author victotyhilling
|
|||
// @match *://*.chaoxing.com/exam/test/reVersionTestStartNew*
|
|||
// @match *://*.edu.cn/exam/test/reVersionTestStartNew*
|
|||
// @match *://*.nbdlib.cn/exam/test/reVersionTestStartNew*
|
|||
// @match *://*.hnsyu.net/exam/test/reVersionTestStartNew*
|
|||
// @connect cx.icodef.com
|
|||
// @run-at document-end
|
|||
// @grant unsafeWindow
|
|||
// @grant GM_xmlhttpRequest
|
|||
// @grant GM_setClipboard
|
|||
// @grant GM_setValue
|
|||
// @grant GM_getValue
|
|||
// @license MIT
|
|||
// @original-script https://404.dnomd343.top/
|
|||
// @original-author wyn665817
|
|||
// @original-license MIT
|
|||
// ==/UserScript==
|
|||
|
|||
// 设置修改后,需要刷新或重新打开网课页面才会生效
|
|||
var setting = { |
|||
// 8E3 == 8000,科学记数法,表示毫秒数
|
|||
time: 1E3 // 默认响应速度为8秒,不建议小于5秒
|
|||
|
|||
// 1代表开启,0代表关闭
|
|||
,none: 1 // 未找到答案或无匹配答案时执行默认操作,默认关闭
|
|||
,jump: 1 // 答题完成后自动切换,默认开启
|
|||
,copy: 0 // 自动复制答案到剪贴板,也可以通过手动点击按钮或答案进行复制,默认关闭
|
|||
|
|||
// 非自动化操作
|
|||
,hide: 0 // 不加载答案搜索提示框,键盘↑和↓可以临时移除和加载,默认关闭
|
|||
,scale: 0 // 富文本编辑器高度自动拉伸,用于文本类题目,答题框根据内容自动调整大小,默认关闭
|
|||
}, |
|||
_self = unsafeWindow, |
|||
$ = _self.jQuery, |
|||
UE = _self.UE; |
|||
|
|||
setting.notice = '公告栏'; |
|||
String.prototype.toCDB = function() { |
|||
return this.replace(/\s/g, '').replace(/[\uff01-\uff5e]/g, function(str) { |
|||
return String.fromCharCode(str.charCodeAt(0) - 65248); |
|||
}).replace(/[“”]/g, '"').replace(/[‘’]/g, "'").replace(/。/g, '.'); |
|||
}; |
|||
|
|||
// setting.time += Math.ceil(setting.time * Math.random()) - setting.time / 2;
|
|||
setting.TiMu = [ |
|||
filterImg('.Cy_TItle .clearfix').replace(/\s*(\d+\.\d+分)$/, ''), |
|||
$('[name^=type]:not([id])').val() || '-1', |
|||
$('.cur a').text().trim() || '无', |
|||
$('li .clearfix').map(function() { |
|||
return filterImg(this); |
|||
}) |
|||
]; |
|||
var maximize=$( |
|||
'<div style="border: 2px dashed rgb(0, 85, 68); position: fixed; top: 0; right: 0; z-index: 99999; background-color: rgba(70, 196, 38, 0.6); overflow-x: auto;display:none;">◻</div>' |
|||
).appendTo('body').click(function(){ |
|||
$(setting.div).css("display","block"); |
|||
GM_setValue("minimize","0"); |
|||
$(maximize).css("display","none"); |
|||
}); |
|||
|
|||
setting.div = $( |
|||
'<div style="border: 2px dashed rgb(0, 85, 68); width: 330px; position: fixed; top: 0; right: 0; z-index: 99999; background-color: rgba(70, 196, 38, 0.6); overflow-x: auto;">' + |
|||
'<span style="font-size: medium;"></span>' + |
|||
'<div style="font-size: medium;width:70%;display: inline-block;">正在搜索答案...</div>'+ |
|||
'<div style="width:30%;display: inline-block;padding-right: 10px;box-sizing: border-box;text-align: right;"><minimize style="width:20px;font-size:16px;line-height: 12px;font-weight: bold;cursor: context-menu;user-select:none;">一</minimize></div>' + |
|||
'<div id="cx-notice" style="border-top: 1px solid #000;border-bottom: 1px solid #000;margin: 4px 0px;overflow: hidden;">' + setting.notice + '</div>' + |
|||
'<button style="margin-right: 10px;">暂停答题</button>' + |
|||
'<button style="margin-right: 10px;' + (setting.jump ? '' : ' display: none;') + '">点击停止本次切换</button>' + |
|||
'<button style="margin-right: 10px;">重新查询</button>' + |
|||
'<button style="margin-right: 10px; display: none;">复制答案</button>' + |
|||
'<button>答题详情</button>' + |
|||
'<div style="max-height: 200px; overflow-y: auto;">' + |
|||
'<table border="1" style="font-size: 12px;">' + |
|||
'<thead>' + |
|||
'<tr>' + |
|||
'<th colspan="2">' + ($('#randomOptions').val() == 'false' ? '' : '<font color="red">本次考试的选项为乱序 脚本会选择正确的选项</font>') + '</th>' + |
|||
'</tr>' + |
|||
'<tr>' + |
|||
'<th style="width: 60%; min-width: 130px;">题目(点击可复制)</th>' + |
|||
'<th style="min-width: 130px;">答案(点击可复制)</th>' + |
|||
'</tr>' + |
|||
'</thead>' + |
|||
'<tfoot style="' + (setting.jump ? ' display: none;' : '') + '">' + |
|||
'<tr>' + |
|||
'<th colspan="2">已关闭 本次自动切换</th>' + |
|||
'</tr>' + |
|||
'</tfoot>' + |
|||
'<tbody>' + |
|||
'<tr>' + |
|||
'<td colspan="2" style="display: none;"></td>' + |
|||
'</tr>' + |
|||
'</tbody>' + |
|||
'</table>' + |
|||
'</div>' + |
|||
'</div>' |
|||
).appendTo('body').on('click', 'button, td', function() { |
|||
var num = setting.$btn.index(this); |
|||
if (num == -1) { |
|||
GM_setClipboard($(this).text()); |
|||
} else if (num === 0) { |
|||
if (setting.loop) { |
|||
clearInterval(setting.loop); |
|||
delete setting.loop; |
|||
num = ['已暂停搜索', '继续答题']; |
|||
} else { |
|||
setting.loop = setInterval(findTiMu, setting.time); |
|||
num = ['正在搜索答案...', '暂停答题']; |
|||
} |
|||
setting.$div.html(function() { |
|||
return $(this).data('html') || num[0]; |
|||
}).removeData('html'); |
|||
$(this).html(num[1]); |
|||
} else if (num == 1) { |
|||
setting.jump = 0; |
|||
setting.$div.html(function() { |
|||
return arguments[1].replace('即将切换下一题', '未开启自动切换'); |
|||
}); |
|||
setting.div.find('tfoot').add(this).toggle(); |
|||
} else if (num == 2) { |
|||
location.reload(); |
|||
} else if (num == 3) { |
|||
GM_setClipboard(setting.div.find('td:last').text()); |
|||
} else if (num == 4) { |
|||
($('.leftCard .saveYl')[0] || $()).click(); |
|||
} else if (num == 5) { |
|||
setting.tk_num++; |
|||
GM_setValue('tk_num_1',setting.tk_num); |
|||
setting.tk_num = GM_getValue('tk_num_1'); |
|||
console.log(setting.tk_num); |
|||
parent.location.reload(); |
|||
} |
|||
}).on('click','minimize', function() { |
|||
$(this).parent().parent().css("display","none"); |
|||
GM_setValue("minimize","1"); |
|||
$(maximize).css("display","block"); |
|||
}).detach(setting.hide ? '*' : 'html'); |
|||
|
|||
if(GM_getValue("minimize")=="1"){ |
|||
$(setting.div).css("display","none"); |
|||
$(maximize).css("display","block"); |
|||
} |
|||
|
|||
setting.$btn = setting.div.children('button'); |
|||
setting.$div = setting.div.children('div:eq(0)'); |
|||
|
|||
$(document).keydown(function(event) { |
|||
if (event.keyCode == 38) { |
|||
setting.div.detach(); |
|||
} else if (event.keyCode == 40) { |
|||
setting.div.appendTo('body'); |
|||
} |
|||
}); |
|||
|
|||
if (setting.scale) _self.UEDITOR_CONFIG.scaleEnabled = false; |
|||
$.each(UE.instants, function() { |
|||
var key = this.key; |
|||
this.ready(function() { |
|||
this.destroy(); |
|||
UE.getEditor(key); |
|||
}); |
|||
}); |
|||
setting.loop = setInterval(findTiMu, setting.time); |
|||
|
|||
|
|||
function fillAnswer(obj, tip) { |
|||
var $input = $(':radio, :checkbox', '.Cy_ulBottom'), |
|||
str = String(obj.answer).toCDB() || new Date().toString(), |
|||
data = str.split(/#|\x01|\|/), |
|||
opt = obj.opt || str, |
|||
btn = $('.saveYl:contains(下一题)').offset(); |
|||
// $input.filter(':radio:checked').prop('checked', false);
|
|||
obj.code > 0 && $input.each(function(index) { |
|||
if (this.value == 'true') { |
|||
data.join().match(/(^|,)(正确|是|对|√|T|ri)(,|$)/) && this.click(); |
|||
} else if (this.value == 'false') { |
|||
data.join().match(/(^|,)(错误|否|错|×|F|wr)(,|$)/) && this.click(); |
|||
} else { |
|||
index = setting.TiMu[3][index].toCDB() || new Date().toString(); |
|||
index = $.inArray(index, data) + 1 || (setting.TiMu[1] == '1' && str.indexOf(index) + 1); |
|||
Boolean(index) == this.checked || this.click(); |
|||
} |
|||
}).each(function() { |
|||
if (!/^A?B?C?D?E?F?G?$/.test(opt)) return false; |
|||
Boolean(opt.match(this.value)) == this.checked || this.click(); |
|||
}); |
|||
if (setting.TiMu[1].match(/^[013]$/)) { |
|||
tip = $input.is(':checked') || setting.none && (($input[Math.floor(Math.random() * $input.length)] || $()).click(), ' '); |
|||
} else if (setting.TiMu[1].match(/^(2|[4-9]|1[08])$/)) { |
|||
data = String(obj.answer).split(/#|\x01|\|/); |
|||
tip = $('.Cy_ulTk textarea').each(function(index) { |
|||
index = (obj.code > 0 && data[index]) || ''; |
|||
UE.getEditor(this.name).setContent(index.trim()); |
|||
}).length; |
|||
tip = (obj.code > 0 && data.length == tip) || setting.none && ' '; |
|||
setting.len = str.length * setting.time / 10; |
|||
} |
|||
if (tip == ' ') { |
|||
tip = '已执行默认操作'; |
|||
} else if (tip) { |
|||
tip = '自动答题已完成'; |
|||
} else if (tip === undefined) { |
|||
tip = '该题型不支持自动答题'; |
|||
} else { |
|||
tip = '未找到有效答案'; |
|||
} |
|||
if (btn) { |
|||
tip += setting.jump ? ',即将切换下一题' : ',未开启自动切换'; |
|||
setInterval(function() { |
|||
if (!setting.jump) return; |
|||
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); |
|||
}, setting.len || Math.ceil(setting.time * Math.random()) * 2); |
|||
} else { |
|||
setting.$btn.eq(1).hide(); |
|||
tip = '答题已完成,请自行查看答题详情'; |
|||
} |
|||
setting.$div.data('html', tip).siblings('button:eq(0)').hide().click(); |
|||
} |
|||
|
|||
function findTiMu() { |
|||
GM_xmlhttpRequest({ |
|||
method: 'POST', |
|||
url: 'http://cx.icodef.com/wyn-nb?v=2', |
|||
headers: { |
|||
'Content-type': 'application/x-www-form-urlencoded' |
|||
}, |
|||
data: 'question=' + encodeURIComponent(setting.TiMu[0]) + '&type=' + setting.TiMu[1] + '&id=' + $('#paperId').val(), |
|||
timeout: setting.time, |
|||
onload: function(xhr) { |
|||
if (!setting.loop) { |
|||
} else if (xhr.status == 200) { |
|||
var obj = $.parseJSON(xhr.responseText) || {}; |
|||
obj.answer = obj.data; |
|||
if (obj.code) { |
|||
var answer = String(obj.answer).replace(/&/g, '&').replace(/<(?!img)/g, '<'), |
|||
que = setting.TiMu[0].match('<img') ? setting.TiMu[0] : setting.TiMu[0].replace(/&/g, '&').replace(/</g, '<'); |
|||
obj.answer = /^http/.test(answer) ? '<img src="' + obj.answer + '">' : obj.answer; |
|||
setting.div.find('tbody').append( |
|||
'<tr>' + |
|||
'<td title="点击可复制">' + que + '</td>' + |
|||
'<td title="点击可复制">' + (/^http/.test(answer) ? obj.answer : '') + answer + '</td>' + |
|||
'</tr>' |
|||
); |
|||
setting.copy && GM_setClipboard(obj.answer); |
|||
setting.$btn.eq(3).show(); |
|||
fillAnswer(obj); |
|||
} else { |
|||
setting.$div.html(obj.answer || '服务器繁忙,正在重试...'); |
|||
} |
|||
setting.div.children('span').html(obj.msg || ''); |
|||
} else if (xhr.status == 403) { |
|||
var html = xhr.responseText.indexOf('{') ? '请求过于频繁,建议稍后再试' : $.parseJSON(xhr.responseText).data; |
|||
setting.$div.data('html', html).siblings('button:eq(0)').click(); |
|||
} else { |
|||
setting.$div.text('服务器异常,正在重试...'); |
|||
} |
|||
}, |
|||
ontimeout: function() { |
|||
setting.loop && setting.$div.text('服务器超时,正在重试...'); |
|||
} |
|||
}); |
|||
|
|||
} |
|||
|
|||
|
|||
function filterImg(dom) { |
|||
return $(dom).clone().find('img[src]').replaceWith(function() { |
|||
return $('<p></p>').text(''); |
|||
}).end().find('iframe[src]').replaceWith(function() { |
|||
return $('<p></p>').text(''); |
|||
}).end().text().trim(); |
|||
} |
@ -0,0 +1,715 @@ |
|||
// ==UserScript==
|
|||
// @name 超星学习通~🚀刷课脚本插件【倍速播放,支持图片,填空题】
|
|||
// @namespace https://baidu.com
|
|||
// @version 3.7.2
|
|||
// @description 超星 学习通 尔雅~插件, 自动刷课 一键操作
|
|||
// @author 呆呆DY
|
|||
// @match *://*.chaoxing.com/*
|
|||
// @match *://*.edu.cn/*
|
|||
// @match *.nbdlib.cn/*
|
|||
// @match *.hnsyu.net/*
|
|||
// @run-at document-end
|
|||
// @grant unsafeWindow
|
|||
// @grant GM_xmlhttpRequest
|
|||
// @grant GM_setValue
|
|||
// @grant GM_getValue
|
|||
// @grant GM_setClipboard
|
|||
// @license MIT
|
|||
// @connect cx.icodef.com
|
|||
// @connect 121.36.212.145
|
|||
// @original-script https://404.dnomd343.top/
|
|||
// @original-author wyn665817
|
|||
// @original-license MIT
|
|||
// ==/UserScript==
|
|||
|
|||
// 设置修改后,需要刷新或重新打开网课页面才会生效
|
|||
var setting = { |
|||
// 5E3 == 5000,科学记数法,表示毫秒数
|
|||
time: 1E3 // 默认响应速度为5秒,不建议小于5秒
|
|||
, review: 0 // 复习模式,完整挂机视频(音频)时长,支持挂机任务点已完成的视频和音频,默认关闭
|
|||
, queue: 1 // 队列模式,开启后任务点逐一完成,关闭则单页面所有任务点同时进行,默认开启
|
|||
|
|||
// 1代表开启,0代表关闭
|
|||
, video: 1 // 视频支持后台、切换窗口不暂停,支持多视频,默认开启
|
|||
, work: 1 // 自动答题功能(章节测验),作业需要手动开启查询,高准确率,默认开启
|
|||
, audio: 1 // 音频自动播放,与视频功能共享vol和rate参数,默认开启
|
|||
, book: 1 // 图书阅读任务点,非课程阅读任务点,默认开启
|
|||
, docs: 1 // 文档阅读任务点,PPT类任务点自动完成阅读任务,默认开启
|
|||
// 本区域参数,上方为任务点功能,下方为独立功能
|
|||
, jump: 1 // 自动切换任务点、章节、课程(需要配置course参数),默认开启
|
|||
, read: '65' // 挂机课程阅读时间,单位是分钟,'65'代表挂机65分钟,请手动打开阅读页面,默认'65'分钟
|
|||
, face: 1 // 解除面部识别(不支持二维码类面部采集),此功能仅为临时解除,默认开启
|
|||
, total: 1 // 显示课程进度的统计数据,在学习进度页面的上方展示,默认开启
|
|||
|
|||
// 仅开启video(audio)时,修改此处才会生效
|
|||
, line: '公网1' // 视频播放的默认资源线路,此功能适用于系统默认线路无资源,默认'公网1'
|
|||
, http: '标清' // 视频播放的默认清晰度,无效参数则使用系统默认清晰度,默认'标清'
|
|||
// 本区域参数,上方为video功能独享,下方为audio功能共享
|
|||
, vol: '0' // 默认音量的百分数,设定范围:[0,100],'0'为静音,默认'0'
|
|||
, rate: '0' // 视频播放默认倍率,参数范围0∪[0.0625,16],'0'为秒过,默认'1'倍
|
|||
|
|||
// 仅开启work时,修改此处才会生效
|
|||
// auto: 1 已放置面板,请在面板配置,默认为自动提交 // 答题完成后自动提交,默认开启
|
|||
, none: 1 // 无匹配答案时执行默认操作,关闭后若题目无匹配答案则会暂时保存已作答的题目,默认开启
|
|||
, scale: 1 // 富文本编辑器高度自动拉伸,用于文本类题目,答题框根据内容自动调整大小,默认关闭
|
|||
|
|||
// 仅开启jump时,修改此处才会生效
|
|||
, course: 1 // 当前课程完成后自动切换课程,仅支持按照根目录课程顺序切换,默认开启
|
|||
, lock: 1 // 跳过未开放(图标是锁)的章节,即闯关模式或定时发放的任务点,默认开启
|
|||
|
|||
// 自动登录功能配置区
|
|||
, school: '账号为手机号可以不修改此参数' //
|
|||
, username: '' //
|
|||
, password: '' //
|
|||
|
|||
}, |
|||
_self = unsafeWindow, |
|||
url = location.pathname, |
|||
top = _self; |
|||
|
|||
var tmpSubmit = 1;//本次
|
|||
Object.defineProperty(setting, "auto", { |
|||
get: function () { |
|||
if (tmpSubmit >= 2) { |
|||
return tmpSubmit === 3; |
|||
} |
|||
return GM_getValue("autosubmit"); |
|||
}, set: function (value) { |
|||
tmpSubmit = value + 2; |
|||
} |
|||
}); |
|||
|
|||
setting.notice = '公告栏'; |
|||
|
|||
if (url != '/studyApp/studying' && top != _self.top) document.domain = location.host.replace(/.+?\./, ''); |
|||
|
|||
try { |
|||
while (top != _self.top) { |
|||
top = top.parent.document ? top.parent : _self.top; |
|||
if (top.location.pathname == '/mycourse/studentstudy') break; |
|||
} |
|||
} catch (err) { |
|||
// console.log(err);
|
|||
top = _self; |
|||
} |
|||
|
|||
var $ = _self.jQuery || top.jQuery, |
|||
parent = _self == top ? self : _self.parent, |
|||
Ext = _self.Ext || parent.Ext || {}, |
|||
UE = _self.UE, |
|||
vjs = _self.videojs; |
|||
|
|||
String.prototype.toCDB = function () { |
|||
return this.replace(/\s/g, '').replace(/[\uff01-\uff5e]/g, function (str) { |
|||
return String.fromCharCode(str.charCodeAt(0) - 65248); |
|||
}).replace(/[“”]/g, '"').replace(/[‘’]/g, "'").replace(/。/g, '.'); |
|||
}; |
|||
|
|||
setting.normal = ''; // ':visible'
|
|||
// setting.time += Math.ceil(setting.time * Math.random()) - setting.time / 2;
|
|||
setting.job = [':not(*)']; |
|||
|
|||
setting.video && setting.job.push('iframe[src*="/video/index.html"]'); |
|||
setting.work && setting.job.push('iframe[src*="/work/index.html"]'); |
|||
setting.audio && setting.job.push('iframe[src*="/audio/index.html"]'); |
|||
setting.book && setting.job.push('iframe[src*="/innerbook/index.html"]'); |
|||
setting.docs && setting.job.push('iframe[src*="/ppt/index.html"]', 'iframe[src*="/pdf/index.html"]'); |
|||
|
|||
setting.tip = !setting.queue || top != _self && jobSort($ || Ext.query); |
|||
|
|||
if (url == '/mycourse/studentstudy') { |
|||
_self.checkMobileBrowerLearn = $.noop; |
|||
var classId = location.search.match(/cla[zs]{2}id=(\d+)/i)[1] || 0, |
|||
courseId = _self.courseId || location.search.match(/courseId=(\d+)/i)[1] || 0; |
|||
setting.lock || $('#coursetree').on('click', '[onclick*=void], [href*=void]', function () { |
|||
_self.getTeacherAjax(courseId, classId, $(this).parent().attr('id').slice(3)); |
|||
}); |
|||
} else if (url == '/ananas/modules/video/index.html' && setting.video) { |
|||
if (setting.review) _self.greenligth = Ext.emptyFn; |
|||
checkPlayer(_self.supportH5Video()); |
|||
} else if (url == '/work/doHomeWorkNew' || url == '/api/work' || url == '/work/addStudentWorkNewWeb'|| url == '/mooc2/work/dowork') { |
|||
console.log("进入答题界面!"); |
|||
if (!UE) { |
|||
var len = ($ || Ext.query || Array)('font:contains(未登录)', document).length; |
|||
setTimeout(len == 1 ? top.location.reload : parent.greenligth, setting.time); |
|||
} else if (setting.work) { |
|||
setTimeout(relieveLimit, 0); |
|||
beforeFind(); |
|||
} |
|||
} else if (url == '/ananas/modules/audio/index.html' && setting.audio) { |
|||
if (setting.review) _self.greenligth = Ext.emptyFn; |
|||
_self.videojs = hookAudio; |
|||
hookAudio.xhr = vjs.xhr; |
|||
} else if (url == '/ananas/modules/innerbook/index.html' && setting.book && setting.tip) { |
|||
setTimeout(function () { |
|||
_self.setting ? _self.top.onchangepage(_self.getFrameAttr('end')) : _self.greenligth(); |
|||
}, setting.time); |
|||
} else if (url.match(/^\/ananas\/modules\/(ppt|pdf)\/index\.html$/) && setting.docs && setting.tip) { |
|||
setTimeout(function () { |
|||
_self.setting ? _self.finishJob() : _self.greenligth(); |
|||
}, setting.time); |
|||
frameElement.setAttribute('download', 1); |
|||
} else if (url == '/knowledge/cards') { |
|||
$ && checkToNext(); |
|||
} else if (url.match(/^\/(course|zt)\/\d+\.html$/)) { |
|||
setTimeout(function () { |
|||
+setting.read && _self.sendLogs && $('.course_section:eq(0) .chapterText').click(); |
|||
}, setting.time); |
|||
} else if (url == '/ztnodedetailcontroller/visitnodedetail') { |
|||
setting.read *= 60 / $('.course_section').length; |
|||
setting.read && _self.sendLogs && autoRead(); |
|||
} else if (url == '/mycourse/studentcourse') { |
|||
var gv = location.search.match(/d=\d+&/g); |
|||
setting.total && $('<a>', { |
|||
href: '/moocAnalysis/chapterStatisticByUser?classI' + gv[1] + 'courseI' + gv[0] + 'userId=' + _self.getCookie('_uid') + '&ut=s', |
|||
target: '_blank', |
|||
title: '点击查看章节统计', |
|||
style: 'margin: 0 25px;', |
|||
html: '本课程共' + $('.icon').length + '节,剩余' + $('em:not(.openlock)').length + '节未完成' |
|||
}).appendTo('.zt_logo').parent().width('auto'); |
|||
} else if (url.match(/^\/visit\/(courses|interaction)$/)) { |
|||
setting.face && $('.zmodel').on('click', '[onclick^=openFaceTip]', DisplayURL); |
|||
} else if (location.host.match(/^passport2/)) { |
|||
setting.username && getSchoolId(); |
|||
} else if (location.hostname == 'i.mooc.chaoxing.com') { |
|||
_self.layui.use('layer', function () { |
|||
this.layer.open({ content: '拖动进度条、倍速播放、秒过会导致不良记录!题库在慢慢补充,搜不到的题目系统会在次日进行自动补充', title: '超星网课助手提示', btn: '我已知悉', offset: 't', closeBtn: 0 }); |
|||
}); |
|||
} else if (url == '/widget/pcvote/goStudentVotePage') { |
|||
$(':checked').click(); |
|||
$('.StudentTimu').each(function (index) { |
|||
var ans = _self.questionlist[index].answer; |
|||
$(':radio, :checkbox', this).each(function (num) { |
|||
ans[num].isanswer && this.click(); |
|||
}); |
|||
$(':text', this).val(function (num) { |
|||
return $(ans[num].content).text().trim(); |
|||
}); |
|||
}); |
|||
} else if (url == '/work/selectWorkQuestionYiPiYue') { |
|||
submitAnswer(getIframe().parent(), $.extend(true, [], parent._data)); |
|||
} |
|||
|
|||
function getIframe(tip, win, job) { |
|||
if (!$) return Ext.get(frameElement || []).parent().child('.ans-job-icon') || Ext.get([]); |
|||
do { |
|||
win = win ? win.parent : _self; |
|||
job = $(win.frameElement).prevAll('.ans-job-icon'); |
|||
} while (!job.length && win.parent.frameElement); |
|||
return tip ? win : job; |
|||
} |
|||
|
|||
function jobSort($) { |
|||
var fn = $.fn ? [getIframe(1), 'length'] : [self, 'dom'], |
|||
sel = setting.job.join(', :not(.ans-job-finished) > .ans-job-icon' + setting.normal + ' ~ '); |
|||
if ($(sel, fn[0].parent.document)[0] == fn[0].frameElement) return true; |
|||
if (!getIframe()[fn[1]] || getIframe().parent().is('.ans-job-finished')) return null; |
|||
setInterval(function () { |
|||
$(sel, fn[0].parent.document)[0] == fn[0].frameElement && fn[0].location.reload(); |
|||
}, setting.time); |
|||
} |
|||
|
|||
function checkPlayer(tip) { |
|||
_self.videojs = hookVideo; |
|||
hookVideo.xhr = vjs.xhr; |
|||
Ext.isSogou = Ext.isIos = Ext.isAndroid = false; |
|||
var data = Ext.decode(_self.config('data')) || {}; |
|||
delete data.danmaku; |
|||
data.doublespeed = 1; |
|||
frameElement.setAttribute('data', Ext.encode(data)); |
|||
if (tip) return; |
|||
_self.supportH5Video = function () { return true; }; |
|||
alert('此浏览器不支持html5播放器,请更换浏览器'); |
|||
} |
|||
|
|||
function hookVideo() { |
|||
_self.alert = console.log; |
|||
var config = arguments[1], |
|||
line = Ext.Array.filter(Ext.Array.map(config.playlines, function (value, index) { |
|||
return value.label == setting.line && index; |
|||
}), function (value) { |
|||
return Ext.isNumber(value); |
|||
})[0] || 0, |
|||
http = Ext.Array.filter(config.sources, function (value) { |
|||
return value.label == setting.http; |
|||
})[0]; |
|||
config.playlines.unshift(config.playlines[line]); |
|||
config.playlines.splice(line + 1, 1); |
|||
config.plugins.videoJsResolutionSwitcher.default = http ? http.res : 360; |
|||
config.plugins.studyControl.enableSwitchWindow = 1; |
|||
config.plugins.timelineObjects.url = '/richvideo/initdatawithviewer?'; |
|||
config.plugins.seekBarControl.enableFastForward = 1; |
|||
if (!setting.queue) delete config.plugins.studyControl; |
|||
// config.preload = setting.tip ? 'auto' : 'none';
|
|||
var player = vjs.apply(this, arguments), |
|||
a = '<a href="https://d0.ananas.chaoxing.com/download/' + _self.config('objectid') + '" target="_blank">', |
|||
img = '<img src="https://d0.ananas.chaoxing.com/download/e363b256c0e9bc5bd8266bf99dd6d6bb" style="margin: 6px 0 0 6px;">'; |
|||
player.volume(Math.round(setting.vol) / 100 || 0); |
|||
Ext.get(player.controlBar.addChild('Button').el_).setHTML(a + img + '</a>').dom.title = '下载视频'; |
|||
player.on('loadstart', function () { |
|||
setting.tip && this.play().catch(Ext.emptyFn); |
|||
this.playbackRate(setting.rate > 16 || setting.rate < 0.0625 ? 1 : setting.rate); |
|||
}); |
|||
player.one(['loadedmetadata', 'firstplay'], function () { |
|||
setting.two = setting.rate === '0' && setting.two < 1; |
|||
setting.two && config.plugins.seekBarControl.sendLog(this.children_[0], 'ended', Math.floor(this.cache_.duration)); |
|||
}); |
|||
player.on('ended', function () { |
|||
Ext.fly(frameElement).parent().addCls('ans-job-finished'); |
|||
}); |
|||
return player; |
|||
} |
|||
|
|||
function hookAudio() { |
|||
_self.alert = console.log; |
|||
var config = arguments[1]; |
|||
config.plugins.studyControl.enableSwitchWindow = 1; |
|||
config.plugins.seekBarControl.enableFastForward = 1; |
|||
if (!setting.queue) delete config.plugins.studyControl; |
|||
var player = vjs.apply(this, arguments), |
|||
a = '<a href="https://d0.ananas.chaoxing.com/download/' + _self.config('objectid') + '" target="_blank">', |
|||
img = '<img src="https://d0.ananas.chaoxing.com/download/e363b256c0e9bc5bd8266bf99dd6d6bb" style="margin: 6px 0 0 6px;">'; |
|||
player.volume(Math.round(setting.vol) / 100 || 0); |
|||
player.playbackRate(setting.rate > 16 || setting.rate < 0.0625 ? 1 : setting.rate); |
|||
Ext.get(player.controlBar.addChild('Button').el_).setHTML(a + img + '</a>').dom.title = '下载音频'; |
|||
player.on('loadeddata', function () { |
|||
setting.tip && this.play().catch(Ext.emptyFn); |
|||
}); |
|||
player.one('firstplay', function () { |
|||
setting.rate === '0' && config.plugins.seekBarControl.sendLog(this.children_[0], 'ended', Math.floor(this.cache_.duration)); |
|||
}); |
|||
player.on('ended', function () { |
|||
Ext.fly(frameElement).parent().addCls('ans-job-finished'); |
|||
}); |
|||
return player; |
|||
} |
|||
|
|||
function relieveLimit() { |
|||
if (setting.scale) _self.UEDITOR_CONFIG.scaleEnabled = false; |
|||
$.each(UE.instants, function () { |
|||
var key = this.key; |
|||
this.ready(function () { |
|||
this.destroy(); |
|||
UE.getEditor(key); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
function beforeFind() { |
|||
setting.regl = parent.greenligth || $.noop; |
|||
if ($.type(parent._data) == 'array') return setting.regl(); |
|||
var maximize = $( |
|||
'<div style="border: 2px dashed rgb(255 ,fdsdf130 ,71); position: fixed; top: 0; right: 0; z-index: 99999; background-color: rgba(135,206,250, 0.6); overflow-x: auto;display:none;">◻</div>' |
|||
).appendTo('body').click(function () { |
|||
$(setting.div).css("display", "block"); |
|||
GM_setValue("minimize", "0"); |
|||
$(maximize).css("display", "none"); |
|||
}); |
|||
|
|||
setting.div = $( |
|||
'<div style="border: 2px dashed rgb(255, 130, 71); width: 330px; position: fixed; top: 0; right: 0; z-index: 99999; background-color: rgba(135,206,250, 1); overflow-x: auto;">' + |
|||
'<span style="font-size: medium;"></span>' + |
|||
'<div style="font-size: medium;width:70%;display: inline-block;">正在搜索答案...</div>' + |
|||
'<div style="width:30%;display: inline-block;padding-right: 10px;box-sizing: border-box;text-align: right;"><minimize style="width:20px;font-size:16px;line-height: 12px;font-weight: bold;cursor: context-menu;user-select:none;">一</minimize></div>' + |
|||
'<div id="cx-notice" style="border-top: 1px solid #000;border-bottom: 1px solid #000;margin: 4px 0px;overflow: hidden;">' + setting.notice + '</div>' + |
|||
'<button style="margin-right: 10px;">暂停答题</button>' + |
|||
'<button style="margin-right: 10px;">' + (setting.auto ? '取消本次自动提交' : '开启本次自动提交') + '</button>' + |
|||
'<button style="margin-right: 10px;">重新查询</button>' + |
|||
'<button>折叠面板</button><br>' + |
|||
'<input id="autosubmit" type="checkbox"' + (setting.auto ? ' checked' : '') + '>自动提交</input>' + |
|||
'<div style="max-height: 300px; overflow-y: auto;">' + |
|||
'<table border="1" style="font-size: 12px;">' + |
|||
'<thead>' + |
|||
'<tr>' + |
|||
'<th style="width: 25px; min-width: 25px;">题号</th>' + |
|||
'<th style="width: 60%; min-width: 130px;">题目(点击可复制)</th>' + |
|||
'<th style="min-width: 130px;">答案(点击可复制)</th>' + |
|||
'</tr>' + |
|||
'</thead>' + |
|||
'<tfoot style="display: none;">' + |
|||
'<tr>' + |
|||
'<th colspan="3">答案提示框 已折叠</th>' + |
|||
'</tr>' + |
|||
'</tfoot>' + |
|||
'<tbody>' + |
|||
'<tr>' + |
|||
'<td colspan="3" style="display: none;"></td>' + |
|||
'</tr>' + |
|||
'</tbody>' + |
|||
'</table>' + |
|||
'</div>' + |
|||
'</div>' |
|||
).appendTo('body').on('click', 'button, td, input', function () { |
|||
var len = $(this).prevAll('button').length; |
|||
if (this.nodeName == 'TD') { |
|||
$(this).prev().length && GM_setClipboard($(this).text()); |
|||
} else if (!$(this).siblings().length) { |
|||
$(this).parent().text('正在搜索答案...'); |
|||
setting.num++; |
|||
} else if (len === 0) { |
|||
if (setting.loop) { |
|||
clearInterval(setting.loop); |
|||
delete setting.loop; |
|||
len = ['已暂停搜索', '继续答题']; |
|||
} else { |
|||
setting.loop = setInterval(findAnswer, setting.time); |
|||
len = ['正在搜索答案...', '暂停答题']; |
|||
} |
|||
setting.div.children('div:eq(0)').html(function () { |
|||
return $(this).data('html') || len[0]; |
|||
}).removeData('html'); |
|||
$(this).html(len[1]); |
|||
} else if (len == 1) { |
|||
setting.auto = !setting.auto; |
|||
$(this).html(setting.auto ? '取消本次自动提交' : '开启本次自动提交'); |
|||
} else if (len == 2) { |
|||
parent.location.reload(); |
|||
} else if (len == 3) { |
|||
setting.div.find('tbody, tfoot').toggle(); |
|||
} else if (this.id == "autosubmit") { |
|||
// 题目自动提交配置
|
|||
console.log(this.checked); |
|||
GM_setValue("autosubmit", this.checked); |
|||
} |
|||
}).on('click', 'minimize', function () { |
|||
$(this).parent().parent().css("display", "none"); |
|||
GM_setValue("minimize", "1"); |
|||
$(maximize).css("display", "block"); |
|||
}).find('table, td, th').css('border', '1px solid').end(); |
|||
|
|||
if (GM_getValue("minimize") == "1") { |
|||
$(setting.div).css("display", "none"); |
|||
$(maximize).css("display", "block"); |
|||
} |
|||
|
|||
setting.lose = setting.num = 0; |
|||
setting.data = parent._data = []; |
|||
setting.over = '<button style="margin-right: 10px;">跳过此题</button>'; |
|||
setting.curs = $('script:contains(courseName)', top.document).text().match(/courseName:\'(.+?)\'|$/)[1] || $('h1').text().trim() || '无'; |
|||
setting.loop = setInterval(findAnswer, setting.time); |
|||
var tip = ({ undefined: '任务点排队中', null: '等待切换中' })[setting.tip]; |
|||
tip && setting.div.children('div:eq(0)').data('html', tip).siblings('button:eq(0)').click(); |
|||
|
|||
GM_xmlhttpRequest({ |
|||
method: 'GET', |
|||
url: 'http://121.36.212.145/inspect.json', |
|||
timeout: setting.time, |
|||
onload: function (xhr) { |
|||
if (xhr.status == 200) { |
|||
console.log(xhr.responseText); |
|||
var obj = $.parseJSON(xhr.responseText)|| {}; |
|||
console.log(obj.injection); |
|||
setting.notice = obj.injection; |
|||
document.querySelector('#cx-notice').innerHTML = setting.notice; |
|||
} |
|||
}, |
|||
ontimeout: function () { |
|||
setting.loop && setting.div.children('div:eq(0)').html(setting.over + '服务器超时,正在重试...或者尝试云插件'); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function findAnswer() { |
|||
if (setting.num >= $('.TiMu').length) { |
|||
var arr = setting.lose ? ['共有 <font color="red">' + setting.lose + '</font> 道题目待完善(橘色标注)', saveThis] : ['答题已完成', submitThis]; |
|||
setting.div.children('div:eq(0)').data('html', arr[0]).siblings('button:eq(0)').hide().click(); |
|||
return setTimeout(arr[1], setting.time); |
|||
} |
|||
var $TiMu = $('.TiMu').eq(setting.num), |
|||
question = filterImg($TiMu.find('.Zy_TItle:eq(0) .clearfix')).replace(/^【.*?】\s*/, '').replace(/\s*(\d+\.\d+分)$/, '').replace(/[(]\s*[)]。$/, '').replace(/(\s*)。$/, '').replace(/[(]\s*[)]$/, '').replace(/(\s*)$/, '').replace(/。$/, ''), |
|||
type = $TiMu.find('input[name^=answertype]:eq(0)').val() || '-1'; |
|||
|
|||
console.log($TiMu); |
|||
|
|||
if(question == ""){ |
|||
question = filterImg($TiMu.find('.mark_name:eq(0) .colorDeep')); |
|||
} |
|||
console.log($TiMu.find('.mark_name:eq(0) .colorDeep')); |
|||
|
|||
GM_xmlhttpRequest({ |
|||
method: 'POST', |
|||
url: 'http://cx.icodef.com/wyn-nb?v=2', |
|||
headers: { |
|||
'Content-type': 'application/x-www-form-urlencoded', |
|||
'Authorization': setting.token, |
|||
}, |
|||
data: 'question=' + encodeURIComponent(question) + '&type=' + type + '&id=' + ($('#workLibraryId').val() || $('#oldWorkId').val()), |
|||
timeout: setting.time, |
|||
onload: function (xhr) { |
|||
if (!setting.loop) { |
|||
} else if (xhr.status == 200) { |
|||
var obj = $.parseJSON(xhr.responseText) || {}; |
|||
obj.answer = obj.data; |
|||
if (obj.code) { |
|||
setting.div.children('div:eq(0)').text('正在搜索答案...'); |
|||
var td = '<td style="border: 1px solid;', |
|||
answer = String(obj.answer).replace(/&/g, '&').replace(/<(?!img)/g, '<'); |
|||
obj.answer = /^http/.test(answer) ? '<img src="' + obj.answer + '">' : obj.answer; |
|||
$( |
|||
'<tr>' + |
|||
td + ' text-align: center;">' + $TiMu.find('.Zy_TItle:eq(0) i').text().trim() + '</td>' + |
|||
td + '" title="点击可复制">' + (question.match('<img') ? question : question.replace(/&/g, '&').replace(/</g, '<')) + '</td>' + |
|||
td + '" title="点击可复制">' + (/^http/.test(answer) ? obj.answer : '橘色为未搜索到答案,麻烦聪明的你手动答题方便呆呆收集') + '</td>' + |
|||
'</tr>' |
|||
).appendTo(setting.div.find('tbody')).css('background-color', fillAnswer($TiMu.find('ul:eq(0)').find('li'), obj, type) ? '' : 'rgba(255,165,79, 1)'); |
|||
setting.data[setting.num++] = { |
|||
code: obj.code > 0 ? 1 : 0, |
|||
question: question, |
|||
option: obj.answer, |
|||
type: Number(type) |
|||
}; |
|||
} else { |
|||
setting.div.children('div:eq(0)').html(obj.answer || setting.over + '服务器繁忙,正在重试...可尝试云插件'); |
|||
} |
|||
setting.div.children('span').html(obj.msg || ''); |
|||
} else if (xhr.status == 403) { |
|||
var html = xhr.responseText.indexOf('{') ? '请求过于频繁,请稍后再试' : $.parseJSON(xhr.responseText).data; |
|||
setting.div.children('div:eq(0)').data('html', html).siblings('button:eq(0)').click(); |
|||
} else { |
|||
setting.div.children('div:eq(0)').html('题库异常,可能跑路了...请等待恢复'); |
|||
} |
|||
}, |
|||
ontimeout: function () { |
|||
setting.loop && setting.div.children('div:eq(0)').html(setting.over + '服务器超时,正在重试...可尝试云插件'); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function fillAnswer($li, obj, type) { |
|||
var $input = $li.find(':radio, :checkbox'), |
|||
str = String(obj.answer).toCDB() || new Date().toString(), |
|||
data = str.split(/#|\x01|\|/), |
|||
opt = obj.opt || str, |
|||
state = setting.lose; |
|||
// $li.find(':radio:checked').prop('checked', false);
|
|||
obj.code > 0 && $input.each(function (index) { |
|||
if (this.value == 'true') { |
|||
data.join().match(/(^|,)(正确|是|对|√|T|ri)(,|$)/) && this.click(); |
|||
} else if (this.value == 'false') { |
|||
data.join().match(/(^|,)(错误|否|错|×|F|wr)(,|$)/) && this.click(); |
|||
} else { |
|||
var tip = filterImg($li.eq(index).find('.after')).toCDB() || new Date().toString(); |
|||
Boolean($.inArray(tip, data) + 1 || (type == '1' && str.indexOf(tip) + 1)) == this.checked || this.click(); |
|||
} |
|||
}).each(function () { |
|||
if (!/^A?B?C?D?E?F?G?$/.test(opt)) return false; |
|||
Boolean(opt.match(this.value)) == this.checked || this.click(); |
|||
}); |
|||
if (type.match(/^[013]$/)) { |
|||
$input.is(':checked') || (setting.none ? ($input[Math.floor(Math.random() * $input.length)] || $()).click() : setting.lose++); |
|||
} else if (type.match(/^(2|[4-9]|1[08])$/)) { |
|||
data = String(obj.answer).split(/#|\x01|\|/); |
|||
str = $li.end().find('textarea').each(function (index) { |
|||
index = (obj.code > 0 && data[index]) || ''; |
|||
if (obj.code > 0) { |
|||
UE.getEditor(this.name).setContent(index.trim()); |
|||
} |
|||
}).length; |
|||
(obj.code > 0 && data.length == str) || setting.none || setting.lose++; |
|||
} else { |
|||
setting.none || setting.lose++; |
|||
} |
|||
return state == setting.lose; |
|||
} |
|||
|
|||
function saveThis() { |
|||
if (!setting.auto) return setTimeout(saveThis, setting.time); |
|||
setting.div.children('button:lt(3)').hide().eq(1).click(); |
|||
_self.alert = console.log; |
|||
$('#tempsave').click(); |
|||
setting.regl(); |
|||
} |
|||
|
|||
function submitThis() { |
|||
if (!setting.auto) { |
|||
} else if (!$('.Btn_blue_1:visible').length) { |
|||
setting.div.children('button:lt(3)').hide().eq(1).click(); |
|||
return setting.regl(); |
|||
} else if ($('#confirmSubWin:visible').length) { |
|||
var btn = $('#tipContent + * > a').offset() || { top: 0, left: 0 }, |
|||
mouse = document.createEvent('MouseEvents'); |
|||
btn = [btn.left + Math.ceil(Math.random() * 46), btn.top + Math.ceil(Math.random() * 26)]; |
|||
mouse.initMouseEvent('click', true, true, document.defaultView, 0, 0, 0, btn[0], btn[1], false, false, false, false, 0, null); |
|||
_self.event = $.extend(true, {}, mouse); |
|||
delete _self.event.isTrusted; |
|||
_self.form1submit(); |
|||
} else { |
|||
$('.Btn_blue_1')[0].click(); |
|||
} |
|||
setTimeout(submitThis, Math.ceil(setting.time * Math.random()) * 2); |
|||
} |
|||
|
|||
function checkToNext() { |
|||
var $tip = $(setting.job.join(', '), document).prevAll('.ans-job-icon' + setting.normal); |
|||
setInterval(function () { |
|||
$tip.parent(':not(.ans-job-finished)').length || setting.jump && toNext(); |
|||
}, setting.time); |
|||
} |
|||
|
|||
function toNext() { |
|||
var $cur = $('#cur' + $('#chapterIdid').val()), |
|||
$tip = $('span.currents ~ span'), |
|||
sel = setting.review ? 'html' : '.blue'; |
|||
if (!$cur.has(sel).length && $tip.length) return $tip.eq(0).click(); |
|||
$tip = $('.roundpointStudent, .roundpoint').parent(); |
|||
$tip = $tip.slice($tip.index($cur) + 1).not(':has(' + sel + ')'); |
|||
$tip.not(setting.lock ? ':has(.lock)' : 'html').find('span').eq(0).click(); |
|||
$tip.length || setting.course && switchCourse(); |
|||
} |
|||
|
|||
function switchCourse() { |
|||
GM_xmlhttpRequest({ |
|||
method: 'GET', |
|||
url: '/visit/courses/study?isAjax=true&fileId=0&debug=', |
|||
headers: { |
|||
'Referer': location.origin + '/visit/courses', |
|||
'X-Requested-With': 'XMLHttpRequest' |
|||
}, |
|||
onload: function (xhr) { |
|||
var list = $('h3 a[target]', xhr.responseText).map(function () { |
|||
return $(this).attr('href'); |
|||
}), |
|||
index = list.map(function (index) { |
|||
return this.match(top.courseId) && index; |
|||
}).filter(function () { |
|||
return $.isNumeric(this); |
|||
})[0] + 1 || 0; |
|||
setting.course = list[index] ? goCourse(list[index]) : 0; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function goCourse(url) { |
|||
GM_xmlhttpRequest({ |
|||
method: 'GET', |
|||
url: url, |
|||
onload: function (xhr) { |
|||
$.globalEval('location.href = "' + $('.articlename a[href]', xhr.responseText).attr('href') + '";'); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function autoRead() { |
|||
$('html, body').animate({ |
|||
scrollTop: $(document).height() - $(window).height() |
|||
}, Math.round(setting.read) * 1E3, function () { |
|||
$('.nodeItem.r i').click(); |
|||
}).one('click', '#top', function (event) { |
|||
$(event.delegateTarget).stop(); |
|||
}); |
|||
} |
|||
|
|||
function DisplayURL() { |
|||
_self.WAY.box.hide(); |
|||
var $li = $(this).closest('li'); |
|||
$.get('/visit/goToCourseByFace', { |
|||
courseId: $li.find('input[name=courseId]').val(), |
|||
clazzId: $li.find('input[name=classId]').val() |
|||
}, function (data) { |
|||
$li.find('[onclick^=openFaceTip]').removeAttr('onclick').attr({ |
|||
target: '_blank', |
|||
href: $(data).filter('script:last').text().match(/n\("(.+?)"/)[1] |
|||
}); |
|||
alert('本课程已临时解除面部识别'); |
|||
}, 'html'); |
|||
} |
|||
|
|||
function getSchoolId() { |
|||
var school = /^1\d{10}$/.test(setting.username) ? '' : setting.school; |
|||
if (!isNaN(school)) return setTimeout(toLogin, setting.time, school); |
|||
if (school == '账号为手机号可以不修改此参数') return alert('请修改school参数'); |
|||
$.getJSON('/org/searchUnis?filter=' + encodeURI(school) + '&product=44', function (data) { |
|||
if (!data.result) return alert('学校查询错误'); |
|||
var msg = $.grep(data.froms, function (value) { |
|||
return value.name == school; |
|||
})[0]; |
|||
msg ? setTimeout(toLogin, setting.time, msg.schoolid) : alert('学校名称不完整'); |
|||
}); |
|||
} |
|||
|
|||
function toLogin(fid) { |
|||
GM_xmlhttpRequest({ |
|||
method: 'GET', |
|||
url: '/api/login?name=' + setting.username + '&pwd=' + setting.password + '&schoolid=' + fid + '&verify=0', |
|||
onload: function (xhr) { |
|||
var obj = $.parseJSON(xhr.responseText) || {}; |
|||
obj.result ? location.href = decodeURIComponent($('#ref, #refer_0x001').val()) : alert(obj.errorMsg || 'Error'); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function submitAnswer($job, data) { |
|||
$job.removeClass('ans-job-finished'); |
|||
data = data.length ? $(data) : $('.TiMu').map(function () { |
|||
var title = filterImg($('.Zy_TItle .clearfix', this)); |
|||
return { |
|||
question: title.replace(/^【.*?】\s*/, ''), |
|||
type: ({ 单选题: 0, 多选题: 1, 填空题: 2, 判断题: 3 })[title.match(/^【(.*?)】|$/)[1]] |
|||
}; |
|||
}); |
|||
data = $.grep(data.map(function (index) { |
|||
var $TiMu = $('.TiMu').eq(index); |
|||
if (!($.isPlainObject(this) && this.type < 4 && $TiMu.find('.fr').length)) { |
|||
return false; |
|||
} else if (this.type == 2) { |
|||
var $ans = $TiMu.find('.Py_tk, .Py_answer').eq(0); |
|||
if (!$TiMu.find('.cuo').length && this.code) { |
|||
return false; |
|||
} else if (!$ans.find('.cuo').length) { |
|||
this.option = $ans.find('.clearfix').map(function () { |
|||
return $(this).text().trim(); |
|||
}).get().join('#') || '无'; |
|||
} else if (this.code) { |
|||
this.code = -1; |
|||
} else { |
|||
return false; |
|||
} |
|||
} else if (this.type == 3) { |
|||
var ans = $TiMu.find('.font20:last').text(); |
|||
if ($TiMu.find('.cuo').length) { |
|||
this.option = ({ '√': '错误', '×': '正确' })[ans] || '无'; |
|||
} else if (!this.code) { |
|||
this.option = ({ '√': '正确', '×': '错误' })[ans] || '无'; |
|||
} else { |
|||
return false; |
|||
} |
|||
} else { |
|||
var text = $TiMu.find('.Py_answer > span:eq(0)').text(); |
|||
if ($TiMu.find('.dui').length && this.code && !/^A?B?C?D?E?F?G?$/.test(this.option)) { |
|||
return false; |
|||
} else if ($TiMu.find('.dui').length || text.match('正确答案')) { |
|||
text = text.match(/[A-G]/gi) || []; |
|||
this.option = $.map(text, function (value) { |
|||
return filterImg($TiMu.find('.fl:contains(' + value + ') + a')); |
|||
}).join('#') || '无'; |
|||
this.key = text.join(''); |
|||
} else if (this.code) { |
|||
this.code = -1; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
return this; |
|||
}), function (value) { |
|||
return value && value.option != '无'; |
|||
}); |
|||
setting.curs = $('script:contains(courseName)', top.document).text().match(/courseName:\'(.+?)\'|$/)[1] || $('h1').text().trim() || '无'; |
|||
data.length && GM_xmlhttpRequest({ |
|||
method: 'POST', |
|||
url: 'http://cx.icodef.com/upload/cx?workRelationId=' + $('#workId').val(), |
|||
headers: { |
|||
'Content-type': 'application/x-www-form-urlencoded', |
|||
'Authorization': setting.token, |
|||
}, |
|||
data: 'course=' + encodeURIComponent(setting.curs) + '&data=' + encodeURIComponent((Ext.encode || JSON.stringify)(data)) + '&id=' + $('#jobid').val().slice(5) |
|||
}); |
|||
$job.addClass('ans-job-finished'); |
|||
} |
|||
|
|||
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(); |
|||
} |
@ -0,0 +1,488 @@ |
|||
// ==UserScript==
|
|||
// @name 智慧树知到网课助手(支持图片题)(可作业)(可考试)
|
|||
// @namespace sunflowerring
|
|||
// @version 3.2.5
|
|||
// @description 自动挂机看知到MOOC,支持屏蔽弹窗题目、自动切换下一节,章测试和考试支持自动答题
|
|||
// @author sunflowerring
|
|||
// @match *://*.zhihuishu.com/*
|
|||
// @connect cx.icodef.com
|
|||
// @run-at document-end
|
|||
// @grant unsafeWindow
|
|||
// @grant GM_xmlhttpRequest
|
|||
// @grant GM_setClipboard
|
|||
// @grant GM_setValue
|
|||
// @grant GM_getValue
|
|||
// @license MIT
|
|||
// @original-script https://404.dnomd343.top/
|
|||
// @original-author wyn665817
|
|||
// @original-license MIT
|
|||
// ==/UserScript==
|
|||
|
|||
// 设置修改后,需要刷新或重新打开网课页面才会生效
|
|||
var setting = { |
|||
// 5E3 == 5000,科学记数法,表示毫秒数
|
|||
time: 1E3 // 默认响应速度为5秒,不建议小于3秒
|
|||
|
|||
// 1代表开启,0代表关闭
|
|||
,video: 1 // 视频支持课程、见面课,默认开启
|
|||
,work: 1 // 自动答题功能,支持章测试、考试,高准确率,默认开启
|
|||
,jump: 1 // 自动切换视频,支持课程、见面课,默认开启
|
|||
|
|||
// 仅开启video时,修改此处才会生效
|
|||
,line: '流畅' // 视频播放的默认线路,可选参数:['高清', '流畅', '校内'],默认'流畅'
|
|||
,vol: '0' // 默认音量的百分数,设定范围:[0,100],'0'为静音,默认'0'
|
|||
,speed: '1.5' // 进度统计速率,高倍率可以快速完成任务点,设定范围:(0,+∞),默认'1.5'倍
|
|||
// 上方参数支持在页面改动,下方参数仅支持代码处修改
|
|||
,que: 1 // 屏蔽视频时间点对应的节试题,取消屏蔽则自动切换为模拟点击关闭弹题,默认开启
|
|||
,danmu: 0 // 见面课弹幕,关闭后在网页中无法手动开启,默认关闭
|
|||
,habit: '0' // 限制视频挂机时长,单位是分钟,如需挂机习惯分,可以修改参数为'30',默认不限制
|
|||
|
|||
// 仅开启work时,修改此处才会生效
|
|||
,none: 1 // 无匹配答案时执行默认操作,默认关闭
|
|||
,hide: 0 // 不加载答案搜索提示框,键盘↑和↓可以临时移除和加载,默认关闭
|
|||
|
|||
}, |
|||
_self = unsafeWindow, |
|||
url = location.pathname, |
|||
$ = _self.jQuery, |
|||
xhr = _self.XMLHttpRequest; |
|||
|
|||
setting.notice = '公告栏'; |
|||
|
|||
String.prototype.toCDB = function() { |
|||
return this.replace(/\s/g, '').replace(/[\uff01-\uff5e]/g, function(str) { |
|||
return String.fromCharCode(str.charCodeAt(0) - 65248); |
|||
}).replace(/[“”]/g, '"').replace(/[‘’]/g, "'").replace(/。/g, '.'); |
|||
}; |
|||
|
|||
// setting.time += Math.ceil(setting.time * Math.random()) - setting.time / 2;
|
|||
setting.queue = setting.curs = []; |
|||
|
|||
if (!$) { |
|||
} else if (url.match('/videoList')) { |
|||
$.tmDialog.alert({content: '2.X版本已取消支持旧版界面', title: '智慧树网课助手提示'}); |
|||
} else if (url == '/videoStudy.html') { |
|||
setting.habit *= 6E4; |
|||
setting.video && hookVideo(_self.vjsComponent, 1); |
|||
setting.jump && setInterval(checkToNext, setting.time); |
|||
} else if (url == '/portals_h5/2clearning.html') { |
|||
setting.video && hookVideo(_self.vjsComponent, 2); |
|||
setting.jump && setInterval(checkToNext, setting.time); |
|||
} else if (url == '/live/vod_room.html') { |
|||
setting.video && hookVideo(_self.vjsComponent); |
|||
setting.jump && setInterval(checkToNext, setting.time, 1); |
|||
} else if (location.hostname.match('examh5')) { |
|||
setTimeout(relieveLimit, 100, document); |
|||
if (location.hash.match(/dohomework|doexamination/) && setting.work) beforeFind(); |
|||
$(window).on('hashchange', function() { |
|||
setting.work && location.reload(); |
|||
}); |
|||
} else if (url.match('/sourceLearning')) { |
|||
setting.video && hookVideo(_self.vjsComponent, 3); |
|||
setting.jump && setInterval(checkToNext, setting.time, $('.source-file-item')); |
|||
} else if (url == '/shareCourse/questionDetailPage') { |
|||
setTimeout(relieveLimit, 100, document); |
|||
$('textarea[oncut]').each(function() { |
|||
setTimeout(relieveLimit, 100, this); |
|||
}); |
|||
} else if (url.match('exerciseList') && setting.work) { |
|||
_self.XMLHttpRequest = hookHiexam; |
|||
setInterval(function() { |
|||
$(setting.queue.shift()).parent().click(); |
|||
}, 1E3); |
|||
setting.jump && setInterval(function() { |
|||
// var $li = setting.queue.length ? $() : $('.jobclassallnumber-div li');
|
|||
// $li.slice($li.index($('.greenbordercur')) + 1).not('.greenbgcur').eq(0).click();
|
|||
setting.queue.length || $('.Topicswitchingbtn:contains(下一题)').click(); |
|||
}, setting.time); |
|||
} |
|||
|
|||
|
|||
|
|||
function totalTime() { |
|||
var player = _self.PlayerStarter.playerArray[0].player; |
|||
setting.habit -= player.paused() ? 0 : setting.time; |
|||
if (setting.habit >= 0) return; |
|||
clearInterval(setting.tip); |
|||
player.pause(); |
|||
$.getScript('//cdn.jsdelivr.net/gh/sentsin/layer/dist/layer.js', function() { |
|||
_self.layer.open({content: '已达到挂机限制时间', title: '智慧树网课助手提示', end: function() { |
|||
setting.habit = 0; |
|||
}}); |
|||
}); |
|||
} |
|||
|
|||
function checkToNext(tip) { |
|||
if (setting.habit < 0) return; |
|||
var $tip = $('.video, .lessonItem'); |
|||
if ($('.current_play .time_icofinish').length) { |
|||
$tip.slice($tip.index($('.current_play')) + 1).not(':has(.time_icofinish)').eq(0).click(); |
|||
} else if ($('.lessonItemActive .finish').length) { |
|||
// _self.PlayerStarter.playerArray[0].callback.playerNext();
|
|||
$tip.slice($tip.index($('.lessonItemActive')) + 1).not(':has(.finish)').eq(0).click(); |
|||
} else if (tip == 1) { |
|||
$('.current_player:contains("100%") + li').click(); |
|||
// $('.finish_tishi').hasClass('disNo') || console.log('签到已完成');
|
|||
} else if ($('.settleOn .finish').length) { |
|||
tip.slice(tip.index($('.settleOn')) + 1).not(':has(.finish)').eq(0).find('.file-name').click(); |
|||
} |
|||
} |
|||
|
|||
function doTest() { |
|||
if (!$('.dialog-test').length) { |
|||
} else if (setting.queue.length) { |
|||
$(setting.queue.shift()).parent().click(); |
|||
} else if (!$('.answer').length) { |
|||
$('.topic-item').eq(0).click(); |
|||
} else if (!$('.right').length) { |
|||
var tip = $('.answer span').text().match(/[A-Z]/g) || []; |
|||
if (tip.length == 1) return $('.topic-option-item:contains(' + tip[0] + ')').click(); |
|||
$('.topic-option-item').each(function() { |
|||
$.inArray($(this).text().slice(0, 1), tip) < 0 == $(this).hasClass('active') && setting.queue.push(this); |
|||
}); |
|||
} else if ($('.btn-next:enabled').length) { |
|||
$('.btn-next:enabled').click(); |
|||
} else { |
|||
$('.dialog-test .btn').click(); |
|||
_self.PlayerStarter.playerArray[0].player.play(); |
|||
} |
|||
} |
|||
|
|||
function hookVideo(Hooks, tip) { |
|||
// _self.PlayerUtil.debugMode = true;
|
|||
_self.vjsComponent = function() { |
|||
var config = arguments[0], |
|||
options = config.options, |
|||
line = $.map(options.sourceSrc.lines, function(value) { |
|||
return value.lineName.replace('标准', '高清'); |
|||
}), |
|||
vol = setting.vol > 100 ? 100 : setting.vol, |
|||
rate = tip == 3 ? [1, 1.25, 1.5, 2, 2.5, 3] : [1, 1.25, 1.5]; |
|||
vol = Math.round(vol) / 100; |
|||
options.volume = vol > 0 ? vol : 0; |
|||
options.autostart = true; |
|||
setting.speed = setting.speed > 0 ? +setting.speed : 1; |
|||
options.rate = $.inArray(setting.speed, rate) < 0 ? options.rate : setting.speed; |
|||
tip && config.callback.playbackRate(setting.speed); |
|||
options.chooseLine = $.inArray(setting.line, line) + 1 || options.chooseLine + 1; |
|||
options.src = options.sourceSrc.lines[--options.chooseLine].lineUrl || options.src; |
|||
if (!setting.danmu) { |
|||
config.defOptions.control.danmuBtn = false; |
|||
delete options.control.danmuBtn; |
|||
} |
|||
Hooks.apply(this, arguments); |
|||
config.player.on('loadstart', function() { |
|||
this.loop(true); |
|||
this.play(); |
|||
$('.speedBox span').text('X ' + setting.speed); |
|||
}); |
|||
}; |
|||
$(document).on('click', '.definiLines b', function() { |
|||
setting.line = ({xiaonei: '校内', line1gq: '高清', line1bq: '流畅'})[this.classList[0]]; |
|||
}).on('mouseup click', function() { |
|||
setting.vol = _self.PlayerStarter.playerArray[0].player.cache_.volume * 100; |
|||
}).on('click', '.speedList div', function() { |
|||
setting.speed = $(this).attr('rate'); |
|||
}); |
|||
if (tip != 1) return; |
|||
setting.tip = setting.habit && setInterval(totalTime, setting.time); |
|||
setInterval(doTest, 1E3); |
|||
_self.XMLHttpRequest = setting.que ? function() { |
|||
var ajax = new xhr(), |
|||
open = ajax.open; |
|||
ajax.open = function(method, url) { |
|||
if (url.match('/loadVideoPointerInfo')) method = 'OPTIONS'; |
|||
return open.apply(this, arguments); |
|||
}; |
|||
return ajax; |
|||
} : xhr; |
|||
} |
|||
function relieveLimit(doc) { |
|||
if (!doc.oncut && !doc.onselectstart) return setTimeout(relieveLimit, 100, doc); |
|||
doc.oncontextmenu = doc.onpaste = doc.oncopy = doc.oncut = doc.onselectstart = null; |
|||
} |
|||
|
|||
function beforeFind() { |
|||
_self.XMLHttpRequest = function() { |
|||
var ajax = new xhr(); |
|||
ajax.onload = function(e) { |
|||
if (this.status != 200 || !this.responseURL.match(/doHomework|doExam/)) return; |
|||
var obj = JSON.parse(this.responseText); |
|||
collectData(obj.rt.examBase); |
|||
}; |
|||
return ajax; |
|||
}; |
|||
setting.div = $( |
|||
'<div style="border: 2px dashed rgb(0, 85, 68); width: 330px; position: fixed; top: 0; left: 0; z-index: 99999; background-color: rgba(70, 196, 38, 0.6); overflow-x: auto;">' + |
|||
'<span style="font-size: medium;"></span>' + |
|||
'<div style="font-size: medium;">正在搜索答案...</div>' + |
|||
'<div id="cx-notice" style="border-top: 1px solid #000;border-bottom: 1px solid #000;margin: 4px 0px;overflow: hidden;">' + setting.notice + '</div>' + |
|||
'<button style="margin-right: 10px;">暂停答题</button>' + |
|||
'<button style="margin-right: 10px;">重新查询</button>' + |
|||
'<button style="margin-right: 10px;">折叠面板</button>' + |
|||
'<button style="display: none;">未作答题目</button>' + |
|||
'<form style="margin: 2px 0;">' + |
|||
'<label style="font-weight: bold; color: red;">自定义答题范围:</label>' + |
|||
'<input name="num" type="number" min="1" placeholder="开始" style="width: 60px;" disabled>' + |
|||
'<span> ~ </span>' + |
|||
'<input name="max" type="number" min="1" placeholder="结束" style="width: 60px;" disabled>' + |
|||
'</form>' + |
|||
'<div style="max-height: 300px; overflow-y: auto;">' + |
|||
'<table border="1" style="font-size: 12px;">' + |
|||
'<thead>' + |
|||
'<tr>' + |
|||
'<th style="width: 30px; min-width: 30px; font-weight: bold; text-align: center;">题号</th>' + |
|||
'<th style="width: 60%; min-width: 130px; font-weight: bold; text-align: center;">题目(点击可复制)</th>' + |
|||
'<th style="min-width: 130px; font-weight: bold; text-align: center;">答案(点击可复制)</th>' + |
|||
'</tr>' + |
|||
'</thead>' + |
|||
'<tfoot style="display: none;">' + |
|||
'<tr>' + |
|||
'<th colspan="3" style="font-weight: bold; text-align: center;">答案提示框 已折叠</th>' + |
|||
'</tr>' + |
|||
'</tfoot>' + |
|||
'<tbody>' + |
|||
'<tr>' + |
|||
'<td colspan="3" style="display: none;"></td>' + |
|||
'</tr>' + |
|||
'</tbody>' + |
|||
'</table>' + |
|||
'</div>' + |
|||
'</div>' |
|||
).appendTo('body').on('click', 'button, td', function() { |
|||
var len = $(this).prevAll('button').length; |
|||
if (this.nodeName == 'TD') { |
|||
$(this).prev().length && GM_setClipboard($(this).text()); |
|||
} else if (len === 0) { |
|||
if (setting.loop) { |
|||
clearInterval(setting.loop); |
|||
delete setting.loop; |
|||
len = [false, '已暂停搜索', '继续答题']; |
|||
} else { |
|||
setting.loop = setInterval(findAnswer, setting.time); |
|||
len = [true, '正在搜索答案...', '暂停答题']; |
|||
} |
|||
setting.div.find('input').attr('disabled', len[0]); |
|||
setting.div.children('div:eq(0)').html(function() { |
|||
return $(this).data('html') || len[1]; |
|||
}).removeData('html'); |
|||
$(this).html(len[2]); |
|||
} else if (len == 1) { |
|||
location.reload(); |
|||
} else if (len == 2) { |
|||
setting.div.find('tbody, tfoot').toggle(); |
|||
} else if (len == 3) { |
|||
var $li = $('.el-scrollbar__wrap li'), |
|||
$tip = $li.filter('.white, .yellow').eq(0); |
|||
$tip.click().length ? setting.div.children('div:last').scrollTop(function() { |
|||
var $tr = $('tbody tr', this).has('td:nth-child(1):contains(' + $tip.text() + ')'); |
|||
if (!$tr.length) return arguments[1]; |
|||
return $tr.offset().top - $tr.parents('table').offset().top; // $tr[0].offsetTop
|
|||
}) : $(this).hide(); |
|||
} else if (len == 4) { |
|||
setting.tk_num++; |
|||
GM_setValue('tk_num_1',setting.tk_num); |
|||
setting.tk_num = GM_getValue('tk_num_1'); |
|||
console.log(setting.tk_num); |
|||
parent.location.reload(); |
|||
} |
|||
}).on('change', 'input', function() { |
|||
setting[this.name] = this.value.match(/^\d+$/) ? parseInt(this.value) - 1 : -1; |
|||
if (!this.value) setting[this.name] = this.name == 'num' ? 0 : undefined; |
|||
}).detach(setting.hide ? '*' : 'html'); |
|||
setting.type = { |
|||
单选题: 1, |
|||
多选题: 2, |
|||
填空题: 3, |
|||
问答题: 4, |
|||
'分析题/解答题/计算题/证明题': 5, |
|||
'阅读理解(选择)/完型填空': 9, |
|||
判断题: 14 |
|||
}; |
|||
setting.lose = setting.num = setting.small = 0; |
|||
$(document).keydown(function(event) { |
|||
if (event.keyCode == 38) { |
|||
setting.div.detach(); |
|||
} else if (event.keyCode == 40) { |
|||
setting.div.appendTo('body'); |
|||
} |
|||
}); |
|||
setting.loop = setInterval(findAnswer, setting.time, true); |
|||
setInterval(function() { |
|||
$(setting.queue.shift()).parent().click(); |
|||
}, 1E3); |
|||
} |
|||
|
|||
function findAnswer(tip) { |
|||
if (setting.queue.length) { |
|||
return; |
|||
} else if (tip && !$('.answerCard').length) { |
|||
return setting.div.children('div:eq(0)').data('html', '非自动答题页面').siblings('button:eq(0)').click(); |
|||
} else if (setting.max < 0 || setting.num < 0) { |
|||
return setting.div.children('div:eq(0)').data('html', '范围参数应为 <font color="red">正整数</font>').siblings('button:eq(0)').click(); |
|||
} else if (setting.num >= $('.subject_stem').length || setting.num > setting.max) { |
|||
// setting.div.children('button:eq(3)').toggle(!!setting.lose);
|
|||
tip = setting.lose ? '共有 <font color="red">' + setting.lose + '</font> 道题目待完善(已深色标注)' : '答题已完成'; |
|||
return setting.div.children('div:eq(0)').data('html', tip).siblings('button:eq(0), form').hide().click(); |
|||
} else if (!setting.curs.length) { |
|||
setting.curs = $('.infoList span').map(function() { |
|||
return $(this).text().trim(); |
|||
}); |
|||
if (!setting.curs.length) return; |
|||
} |
|||
var $TiMu = $('.subject_stem').eq(setting.num).parent(), |
|||
$dom = $TiMu.find('.smallStem_describe').eq(setting.small).children('div').slice(1, -1), |
|||
question = filterStyle($dom) || filterStyle($TiMu.find('.subject_describe')), |
|||
type = $TiMu.find('.subject_type').text().match(/【(.+)】|$/)[1]; |
|||
type = type ? setting.type[type] || 0 : -1; |
|||
|
|||
GM_xmlhttpRequest({ |
|||
method: 'POST', |
|||
url: 'http://cx.icodef.com/wyn-nb?v=2', |
|||
headers: { |
|||
'Content-type': 'application/x-www-form-urlencoded' |
|||
}, |
|||
data: 'question=' + encodeURIComponent(question), |
|||
timeout: setting.time, |
|||
onload: function(xhr) { |
|||
if (!setting.loop) { |
|||
} else if (xhr.status == 200) { |
|||
var obj = $.parseJSON(xhr.responseText.replace(/^操作数据失败!/,'')) || {}; |
|||
obj.answer = obj.data; |
|||
if (obj.code) { |
|||
setting.div.children('div:eq(0)').text('正在搜索答案...'); |
|||
var answer = obj.answer.replace(/&/g, '&').replace(/<([^i])/g, '<$1'); |
|||
obj.answer = /^http/.test(answer) ? '<img src="' + obj.answer + '">' : obj.answer; |
|||
$( |
|||
'<tr>' + |
|||
'<td style="text-align: center;">' + $TiMu.find('.subject_num').text().trim().replace('.', '') + '</td>' + |
|||
'<td title="点击可复制">' + (question.match('<img') ? question : question.replace(/&/g, '&').replace(/</g, '<')) + '</td>' + |
|||
'<td title="点击可复制">' + (/^http/.test(answer) ? obj.answer : '') + answer + '</td>' + |
|||
'</tr>' |
|||
).appendTo(setting.div.find('tbody')).css('background-color', function() { |
|||
$dom = $dom.length ? $dom.closest('.examPaper_subject') : $TiMu; |
|||
if (fillAnswer($dom, obj, type)) return ''; |
|||
setting.div.children('button:eq(3)').show(); |
|||
return 'rgba(0, 150, 136, 0.6)'; |
|||
}); |
|||
setting.small = ++setting.small < $TiMu.find('.smallStem_describe').length ? setting.small : (setting.num++, 0); |
|||
} else { |
|||
setting.div.children('div:eq(0)').html(obj.answer || '服务器繁忙,正在重试...'); |
|||
} |
|||
setting.div.children('span').html(obj.msg || ''); |
|||
} else if (xhr.status == 403) { |
|||
var html = xhr.responseText.indexOf('{') ? '请求过于频繁,建议稍后再试' : $.parseJSON(xhr.responseText).answer; |
|||
setting.div.children('div:eq(0)').data('html', html).siblings('button:eq(0)').click(); |
|||
} else { |
|||
setting.div.children('div:eq(0)').text('服务器异常,正在重试...'); |
|||
} |
|||
}, |
|||
ontimeout: function() { |
|||
setting.loop && setting.div.children('div:eq(0)').text('服务器超时,正在重试...'); |
|||
} |
|||
}); |
|||
|
|||
} |
|||
|
|||
|
|||
function collectData(obj, data) { |
|||
setting.data = data = {}; |
|||
data.id = obj.id; |
|||
data.name = obj.name; |
|||
data.course = obj.courseName; |
|||
data.chapter = obj.toChapter || obj.explain; |
|||
data.timu = []; |
|||
$.each(obj.workExamParts, function() { |
|||
$.each(this.questionDtos, function() { |
|||
if (this.questionOptions) return pushData(this, data.timu); |
|||
$.each(this.questionChildrens, function() { |
|||
pushData(this, data.timu); |
|||
}); |
|||
}); |
|||
}); |
|||
GM_xmlhttpRequest({ |
|||
method: 'POST', |
|||
url: 'http://cx.icodef.com/report/zhs', |
|||
headers: { |
|||
'Content-type': 'application/x-www-form-urlencoded' |
|||
}, |
|||
data: 'data=' + encodeURIComponent(JSON.stringify(data)) |
|||
}); |
|||
} |
|||
|
|||
function fillAnswer($TiMu, obj, type) { |
|||
var $div = $TiMu.find('.nodeLab'), |
|||
str = String(obj.answer).toCDB() || new Date().toString(), |
|||
answer = str.split(/#|\x01|\|/), |
|||
state = setting.lose; |
|||
// $div.find(':radio:checked').prop('checked', false);
|
|||
obj.code > 0 && $div.each(function() { |
|||
var $input = $('input', this)[0], |
|||
tip = filterStyle('.node_detail', this).toCDB() || new Date().toString(); |
|||
if (tip.match(/^(正确|是|对|√|T|ri)$/)) { |
|||
answer.join().match(/(^|,)(正确|是|对|√|T|ri)(,|$)/) && setting.queue.push($input); |
|||
} else if (tip.match(/^(错误|否|错|×|F|wr)$/)) { |
|||
answer.join().match(/(^|,)(错误|否|错|×|F|wr)(,|$)/) && setting.queue.push($input); |
|||
} else if (type == 2) { |
|||
Boolean($.inArray(tip, answer) + 1 || str.indexOf(tip) + 1) == $input.checked || setting.queue.push($input); |
|||
} else { |
|||
$.inArray(tip, answer) + 1 && setting.queue.push($input); |
|||
} |
|||
}); |
|||
if (setting.queue.length) { |
|||
} else if (/^(1|2|14)$/.test(type)) { |
|||
var $input = $div.find('input'); |
|||
$input.is(':checked') || (setting.none ? setting.queue.push($input[Math.floor(Math.random() * $input.length)]) : setting.lose++); |
|||
} else if (/^[3-5]$/.test(type)) { |
|||
answer = String(obj.answer).split(/#|\x01|\|/); |
|||
str = $TiMu.find('textarea').each(function(index) { |
|||
index = (obj.code > 0 && answer[index]) || ''; |
|||
this.value = index.trim(); |
|||
// if (this.value == this._value) return true;
|
|||
this.dispatchEvent(new Event('input')); |
|||
this.dispatchEvent(new Event('blur')); |
|||
}).length; |
|||
(obj.code > 0 && answer.length == str) || setting.none || setting.lose++; |
|||
} else { |
|||
setting.none || setting.lose++; |
|||
} |
|||
return state == setting.lose; |
|||
} |
|||
|
|||
function pushData(obj, arr) { |
|||
arr.push({ |
|||
id: obj.id, |
|||
question: filterStyle('<p>' + obj.name + '</p>'), |
|||
option: $.map(obj.questionOptions, function(val) { |
|||
return filterStyle('<p>' + val.content + '</p>'); |
|||
}), |
|||
key: $.map(obj.questionOptions, function(val) { |
|||
return val.id; |
|||
}).join(), |
|||
type: obj.questionType.id |
|||
}); |
|||
} |
|||
|
|||
function hookHiexam() { |
|||
var ajax = new xhr(); |
|||
ajax.onload = function() { |
|||
if (this.status != 200 || !this.responseURL.match('getDoQuestSingle')) return; |
|||
var obj = JSON.parse(this.responseText).rt; |
|||
$.each(obj.questionOptionList || [], function(index) { |
|||
var $input = $('.TitleOptions-div input')[index]; |
|||
if (obj.questionTypeId == 1) { |
|||
this.isCorrect && setting.queue.push($input); |
|||
} else if (obj.questionTypeId == 2) { |
|||
this.isCorrect == $input.checked || setting.queue.push($input); |
|||
} |
|||
}); |
|||
}; |
|||
return ajax; |
|||
} |
|||
|
|||
function filterStyle(dom, that) { |
|||
var $dom = $(dom, that).clone().find('style').remove().end(); |
|||
return $dom.find('img[src]').replaceWith(function() { |
|||
return $('<p></p>').text('<img src="' + $(this).attr('src') + '">'); |
|||
}).end().text().trim(); |
|||
} |
@ -0,0 +1,87 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>刷课教程</title> |
|||
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> |
|||
<script> |
|||
var key; |
|||
$(document).ready(function() { |
|||
initCheck(); |
|||
$("#setup").click(function() { |
|||
key = getQuery("key"); |
|||
tryLoad(); |
|||
}); |
|||
}); |
|||
function initCheck() { |
|||
$("div").hide(); |
|||
key = getQuery("key"); |
|||
$.get("/js/check?key=" + key, function(data) { |
|||
console.log(data); |
|||
if (data.status == "F") { |
|||
if (key == null) { |
|||
alert('无效凭证'); |
|||
} else if (key.length != 16) { |
|||
alert('无效凭证'); |
|||
} else { |
|||
alert('凭证已过期'); |
|||
} |
|||
to404(); |
|||
} else { |
|||
$("div").show(); |
|||
} |
|||
}); |
|||
} |
|||
function to404() { |
|||
window.open('https://404.dnomd343.top/','_self'); |
|||
} |
|||
function tryLoad() { |
|||
$.get("/js/check?key=" + key, function(data) { |
|||
console.log(data); |
|||
if (data.status == "F") { |
|||
if (key == null) { |
|||
alert('无效凭证'); |
|||
} else if (key.length != 16) { |
|||
alert('无效凭证'); |
|||
} else { |
|||
alert('凭证已过期'); |
|||
} |
|||
} else { |
|||
loadScript(); |
|||
} |
|||
}); |
|||
} |
|||
function loadScript() { |
|||
window.open('https://menma01.com/js/query/script_1.user.js?key=' + key, '_self'); |
|||
window.open('https://menma01.com/js/query/script_2.user.js?key=' + key, '_self'); |
|||
window.open('https://menma01.com/js/query/script_3.user.js?key=' + key, '_self'); |
|||
} |
|||
function installTampermonkey() { |
|||
window.open('https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd?hl=zh-CN'); |
|||
} |
|||
function getQuery(name) { |
|||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); |
|||
var result = window.location.search.substr(1).match(reg); |
|||
if (result != null) { |
|||
return unescape(result[2]); |
|||
} else { |
|||
return null; |
|||
} |
|||
} |
|||
</script> |
|||
<style> |
|||
div { |
|||
text-align: center; |
|||
margin-top: 150px; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div> |
|||
<button onclick="installTampermonkey()">先点我安装插件</button> |
|||
<br> |
|||
<br> |
|||
<button id="setup">再点我安装脚本</button> |
|||
</div> |
|||
</body> |
|||
</html> |
Loading…
Reference in new issue