// ==UserScript== // @name 超星网课助手 // @namespace wyn665817@163.com // @version 1.5.1 // @description 自动挂机看尔雅MOOC,支持后台、切换窗口不暂停,视频自动切换,屏蔽视频内的题目,倍速播放、进度条拖动、快进快退 // @author wyn665817 // @match *://*.chaoxing.com/* // @run-at document-end // @grant unsafeWindow // @license MIT // @downloadURL none // ==/UserScript== // 设置修改后,需要刷新或重新打开网课页面才会生效 var setting = { // 5E3 == 5000,表示毫秒数 time: 5E3 // 默认响应速度为5秒,不建议小于3秒 // 1代表开启,0代表关闭 ,video: 1 // 视频支持后台、切换窗口不暂停,支持多视频,默认开启 ,work: 1 // 自动答题功能(章节测验),高准确率,默认开启 ,jump: 1 // 自动切换任务点、章节,默认开启 ,test: 1 // 自动答题功能(考试),高准确率,默认开启 ,proxy: 0 // 自动答题功能的代理服务器,建议仅在自动答题功能无法加载时开启,默认关闭 // 仅开启video时,修改此处才会生效 ,line: '公网1' // 视频播放的默认资源线路,支持选择清晰度,例如'公网1标清',默认'公网1' ,drag: 0 // 倍速播放、进度条拖动、快进快退,使用此功能会出现不良记录(慎用),默认关闭 // 仅开启work时,修改此处才会生效 ,retry: 0 // 自动答题失败后进行重试,如果网课是需要每章解锁的建议开启,默认关闭 // 仅开启jump时,修改此处才会生效 ,check: 1 // 任务点无法自动完成时暂停切换,如果网课已全部解锁的建议关闭,默认开启 }, _self = unsafeWindow, $ = _self.$ || top.$, url = location.pathname; if (url.indexOf('ananas/modules/video/index.html') > 0) { if (setting.video) { hookJQuery(); } else { reviseTip(0); } } else if (url.indexOf('work/doHomeWorkNew') > 0) { if (setting.work && $('.Btn_blue_1').length) { addStyle(); } else { reviseTip(1); } } else if (url.indexOf('exam/test/reVersionTestStartNew') > 0 && setting.test) { addStyle('test'); } else if (url.indexOf('knowledge/cards') > 0) { checkToNext(); } function toNext() { var $tip = $('.currents ~ span'); if (!setting.jump) { } else if ($('.lock, .blue', '.currents').length || !$tip.length) { $tip = $('.roundpointStudent, .roundpoint').parent(); var index = $tip.index($tip.filter('.currents')); $tip.filter(':gt(' + index + ')').not(':has(.lock, .blue)').eq(0).click(); } else { $tip.eq(0).click(); } } function hookJQuery() { var Hooks = varHooks(), $video = $('.ans-job-icon + iframe[src*="/video/index.html"]', parent.document), $job = $video.not('.ans-job-finished > iframe'); setting.tip = false; if (!$job.length) { } else if ($job[0].contentWindow == _self) { setting.tip = true; } else { setInterval(function() { if ($video.not('.ans-job-finished > iframe')[0].contentWindow == _self) { location.reload(); } }, setting.time); } Hooks.set(_self, '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.isDefaultPlay = setting.tip; config.enableSwitchWindow = 1; config.datas.currVideoInfo.resourceUrl = '/richvideo/initdatawithviewer?'; config.datas.currVideoInfo.dftLineIndex = config.datas.currVideoInfo.getVideoUrl.match(/{.+?}/g).findIndex(function(currentValue) { return currentValue.indexOf(setting.line) > 1; }); 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) { $('head').append( '' ); addNanayun(obj); } function addNanayun(obj) { /** * api | nanayun.com * https://freejs19.nanayun.com/ */ var date = new Date(), xhr = new XMLHttpRequest(); xhr.open('GET', 'https://' + (setting.proxy ? 'proxy.forestpolice.org' : 'freejs19.nanayun.com') + '/allcontroller.min.js?refer=ext.qq.com/tampermonkey&version=1.9&t=' + date.getFullYear() + (date.getMonth() + 1) + date.getDate() + date.getHours() + (date.getMinutes() > 30 ? 1 : 0)); xhr.timeout = setting.time; xhr.onloadend = function() { if (xhr.status == 200) { try { $('').appendTo('head').remove(); if (!obj) { setInterval(subAnswer, setting.time); } } catch(err) { reviseTip(1); } } else if (obj || setting.retry) { setTimeout(addNanayun, setting.time); } else { reviseTip(1); } }; xhr.send(); } function subAnswer() { if ($('#antable tr').length <= $('.TiMu').length) { } else if (!setting.finish) { setting.finish = 1; $('head').append( '' ); } else if ($('#validate', top.document).is(':hidden')) { if ($('#confirmSubWin').is(':hidden')) { $('.Btn_blue_1')[0].click(); } else { var $btn = $('#tipContent').next().children(':first'), position = $btn.offset(), mouse = document.createEvent('MouseEvents'); mouse.initMouseEvent('click', true, true, document.defaultView, 0, 0, 0, position.left + Math.floor(46 * Math.random() + 1), position.top + Math.floor(26 * Math.random() + 1)); $btn[0].dispatchEvent(mouse); } } } function checkToNext() { var $tip = $('.ans-job-icon', document); if (!setting.check) { $tip = $tip.next('iframe[src*="/video/index.html"], iframe[src*="/work/index.html"]').prev(); } setInterval(function() { if (!$tip.parent(':not(.ans-job-finished)').length) { toNext(); } }, setting.time); } function reviseTip(id) { var now = id ? 'parent' : 'self'; $('.ans-job-icon + iframe', parent[now].document).each(function() { if (this.contentWindow == _self[now]) { $(this).prev().remove(); return false; } }); }