// ==UserScript== // @name 超星网课助手 // @namespace wyn665817@163.com // @description 自动挂机看尔雅MOOC,支持后台、切换窗口不暂停,视频自动切换,屏蔽视频内的题目,倍速播放、进度条拖动、快进快退 // @author wyn665817 // @version 1.0.0 // @grant none // @run-at document-end // @match *://*.chaoxing.com/* // @license MIT // @downloadURL none // ==/UserScript== //设置修改后,需要刷新或重新打开网课页面才会生效 var setting = { // 5E3 == 5000,表示毫秒数 time: 5E3, // 默认响应速度为5秒,不建议小于3秒 // 1代表开启,0代表关闭 video: 1, // 视频支持后台、切换窗口不暂停,支持多视频,默认开启 work: 1, // 自动答题功能(章节测验),高准确率,默认开启 switch: 1, // 自动切换任务点、章节,默认开启 test: 1, // 自动答题功能(考试),高准确率,默认开启 // 仅开启video时,修改此处才会生效 drag: 0, // 倍速播放、进度条拖动、快进快退,使用此功能会出现不良记录(慎用),默认关闭 // 仅开启work时,修改此处才会生效 retry: 0 // 自动答题失败后进行重试,如果网课是需要每章解锁的建议开启,默认关闭 }; (function() { var url = location.pathname; if (url.indexOf('ananas/modules/video/index.html') > 0) { if (setting.video) { hookJQuery(); } else { setTimeout(toNext, setting.time); } } else if (url.indexOf('work/doHomeWorkNew') > 0) { if (setting.work && document.getElementsByClassName('Btn_blue_1').length) { addStyle(); } else { setTimeout(toNext, setting.time); } } else if (url.indexOf('exam/test/reVersionTestStartNew') > 0 && setting.test) { addStyle('test'); } else if (url.indexOf('knowledge/cards') > 0) { checkToNext(); } })(); function toNext() { if (!setting.switch) { return; } var card = top.document.querySelectorAll('#mainid .tabtags span'), index = findCurIdx(card) + 1; if (index < card.length) { card[index].click(); } else { var chapter = top.document.querySelectorAll('#coursetree .roundpointStudent'), ochapter = new Array(), i = 0, len = chapter.length; for (; i < len; i++) { ochapter[i] = chapter[i].parentNode; } index = findCurIdx(ochapter) + 1; if (index < ochapter.length) { ochapter[index].click(); } } }; /** * xymopen * xuyiming.open@outlook.com */ function findCurIdx(nodeList) { return Array.from(nodeList).findIndex(function(chapter) { return chapter.classList.contains('currents'); }); }; function hookJQuery() { var Hooks = varHooks(); // CXPlayer extends jQuery for its own APIs // so hook jQuery to modify these APIs. Hooks.set(window, 'jQuery', function(target, propertyName, ignored, jQuery) { Hooks.set(jQuery.fn, 'cxplayer', function(target, propertyName, oldValue, newValue) { return Hooks.apply(newValue, function(target, thisArg, args) { var config = args[0]; config.datas.isAutoChgLine = true; config.datas.isAutoPlayNext = true; config.datas.isDefaultPlay = true; config.enableSwitchWindow = 1; config.datas.currVideoInfo.resourceUrl = '/richvideo/initdatawithviewer?'; if (setting.drag) { config.datas.currVideoInfo.getVideoUrl = config.datas.currVideoInfo.getVideoUrl.replace(/&drag=false&/, '&drag=true&'); } return Hooks.Reply.apply(arguments); }); }); return Hooks.Reply.set(arguments); }); }; function varHooks() { /** * Hooks.js v1.1.3 | xymopen * xuyiming.open@outlook.com * https://github.com/xymopen/JS_Utilities/blob/master/Hooks.js */ var Hooks = { apply: function apply(target, onApply) { if ('function' === typeof target && 'function' === typeof onApply) { return function() { return onApply.call(this, target, this, arguments); }; } else { throw new TypeError(); } }, property: function property(target, propertyName, onGet, onSet) { var descriptor, oldValue; if (Object.prototype.hasOwnProperty.call(target, propertyName)) { descriptor = Object.getOwnPropertyDescriptor(target, propertyName); if (Object.prototype.hasOwnProperty.call(descriptor, 'value')) { oldValue = descriptor.value; delete descriptor.value; delete descriptor.writable; } else if (Object.prototype.hasOwnProperty.call(descriptor, 'get')) { oldValue = descriptor.get.call(target); } else { oldValue = undefined; } } else { descriptor = { 'configurable': true, 'enumerable': true }; oldValue = undefined; } descriptor.get = function get() { return onGet.call(this, target, propertyName, oldValue); }; descriptor.set = function set(newValue) { oldValue = onSet.call(this, target, propertyName, oldValue, newValue); return oldValue; }; Object.defineProperty(target, propertyName, descriptor); }, set: function set(target, propertyName, onSet) { return Hooks.property(target, propertyName, function(target, propertyName, oldValue) { return Hooks.Reply.set(arguments); }, onSet); } }; Hooks.Reply = { apply: function apply(param) { return param[0].apply(param[1], param[2]); }, set: function(param) { return param[param.length - 1]; } }; return Hooks; }; function addStyle(obj) { var style = document.createElement('style'); style.innerHTML = '#toNext1 + button, a[target=_blank] {display: none !important;}' + 'body > div:not(.clearfix) {min-height: 0px !important;}' + 'body > div:not(.clearfix):before {content:"正在查找答案...";}'; document.head.appendChild(style); addNanayun(obj); }; function addNanayun(obj) { /** * api | nanayun.com * https://freejs19.nanayun.com/ */ var href = 'https://freejs19.nanayun.com/allcontroller.min.js?refer=ext.qq.com/tampermonkey&version=1.9&t=', date = new Date(); href += date.getFullYear(); href += date.getMonth() + 1; href += date.getDate(); href += date.getHours(); href += date.getMinutes() > 30 ? 1 : 0; window.$.ajax({ url: href, dataType: 'script', timeout: 1E3, complete: function(xhr) { if (obj) { if (!xhr.status) { setTimeout(addNanayun, setting.time); } } else if (xhr.status) { setInterval(subAnswer, setting.time); } else if (setting.retry) { setTimeout(addNanayun, setting.time); } else { toNext(); } } }); }; function subAnswer() { var $ = window.$, $TiMu = $('.TiMu'); if ($TiMu.children('a').length >= $TiMu.length) { if (top.$('#validate').is(':hidden')) { if ($('.AlertCon02').is(':hidden')) { $('.Btn_blue_1')[0].click(); } else { var $btn = $('#tipContent').next().children().eq(0), position = $btn.offset(), mouse = document.createEvent('MouseEvents'); mouse.initMouseEvent('click', true, true, document.defaultView, 0, 0, 0, position.left + Math.floor(50 * Math.random() + 1), position.top + Math.floor(28 * Math.random() + 1)); $btn[0].dispatchEvent(mouse); } } return; } }; function checkToNext() { var iframe = document.getElementsByTagName('iframe'), len = iframe.length; if (!len) { return setTimeout(toNext, setting.time); } var oiframe = '', src = '', i = 0, job = new Array(), olen = 0; for (; i < len; i++) { oiframe = iframe[i].previousElementSibling; if (oiframe && oiframe.classList.contains('ans-job-icon')) { src = iframe[i].getAttribute('src'); if (src.indexOf('/video/index.html') > 0 || src.indexOf('/work/index.html') > 0) { job[olen++] = iframe[i].parentNode; } } } if (!olen) { return setTimeout(toNext, setting.time); } setInterval(function() { for (var i = 0; i < olen; i++) { if (!job[i].classList.contains('ans-job-finished')) { break; } } if (i == olen) { toNext(); } }, setting.time); };