// ==UserScript== // @name 超星网课助手 // @namespace wyn665817@163.com // @version 1.7.1 // @description 自动挂机看尔雅MOOC,支持后台、切换窗口不暂停,视频自动切换,屏蔽视频内的题目,倍速播放、进度条拖动、快进快退 // @author wyn665817 // @match *://*.chaoxing.com/* // @connect forestpolice.org // @run-at document-end // @grant unsafeWindow // @grant GM_xmlhttpRequest // @supportURL https://greasyfork.org/zh-CN/scripts/369625/feedback // @license MIT // @downloadURL none // ==/UserScript== // 设置修改后,需要刷新或重新打开网课页面才会生效 var setting = { // 5E3 == 5000,表示毫秒数 time: 5E3 // 默认响应速度为5秒,不建议小于3秒 // 1代表开启,0代表关闭 ,video: 1 // 视频支持后台、切换窗口不暂停,支持多视频,默认开启 ,work: 1 // 自动答题功能(章节测验),高准确率,默认开启 ,jump: 1 // 自动切换任务点、章节,默认开启 // 仅开启video时,修改此处才会生效 ,line: '公网1' // 视频播放的默认资源线路,此功能适用于系统默认线路无资源,默认'公网1' ,http: '' // 视频播放的默认清晰度,可以设置'标清'等,无参数则使用系统默认清晰度,默认'' ,muted: 0 // 视频静音播放,此功能在视频开始播放时调整音量至静音,默认关闭 ,drag: 0 // 倍速播放、进度条拖动、快进快退,使用此功能会出现不良记录(慎用),默认关闭 ,player: '' // 指定播放器的类型,支持'html5'和'flash'两种参数,其他参数代表系统默认播放器,默认'' // 仅开启work时,修改此处才会生效 ,auto: 1 // 答题完成后自动提交,默认开启 // 仅开启jump时,修改此处才会生效 ,check: 1 // 任务点无法自动完成时暂停切换,如果网课已全部解锁的建议关闭,默认开启 }, _self = unsafeWindow, $ = _self.$ || top.$, url = location.pathname; if (url.startsWith('/ananas/modules/video/index.html')) { if (setting.video) { jobSort(); checkPlayer(); } else { getIframe(0).remove(); } } else if (url.startsWith('/work/doHomeWorkNew')) { if (setting.work && $('.Btn_blue_1').length) { jobSort(); setting.tip && beforeFind(); } else { getIframe(0).remove(); } } else if (url.startsWith('/knowledge/cards')) { checkToNext(); } function getIframe(tip, win, job) { do { win = win ? win.parent : _self; job = $(win.frameElement).prev('.ans-job-icon'); } while (!job.length && win.parent.frameElement); return tip ? win : job; } function jobSort() { var win = getIframe(1), $job = $('.ans-job-icon', win.parent.document).next('iframe[src*="/video/index.html"], iframe[src*="/work/index.html"]').not('.ans-job-finished > iframe'); setting.tip = false; if (!$job.length) { } else if ($job[0] == win.frameElement) { setting.tip = true; } else { setInterval(function() { if ($job.not('.ans-job-finished > iframe')[0] == win.frameElement) { location.reload(); } }, setting.time); } } 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.slice(index + 1).not(':has(.lock, .blue)').eq(0).click(); } else { $tip.eq(0).click(); } } function checkPlayer() { var data = $.parseJSON($(frameElement).attr('data')), danmaku = data && data.danmaku ? data.danmaku : 0; if (setting.player == 'flash') { _self.showHTML5Player = _self.showMoocPlayer; danmaku = 1; } else if (setting.player == 'html5') { _self.showMoocPlayer = _self.showHTML5Player; danmaku = 0; } if (!danmaku && _self.supportH5Video()) { hookVideo(); } else if (_self.flashChecker().hasFlash) { hookJQuery(); } } function hookVideo() { var Hooks = _self.videojs; _self.videojs = function () { var config = arguments[1], line = config.playlines.findIndex(function(currentValue) { return currentValue.label == setting.line; }), http = config.sources.find(function(currentValue) { return currentValue.label == setting.http; }); 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?'; setting.tip && (config.autoplay = true); setting.muted && (config.muted = true); if (setting.drag) { config.plugins.seekBarControl.enableFastForward = 1; config.playbackRates = [1, 1.25, 1.5, 2]; } var player = Hooks.apply(this, arguments); player.on('loadstart', function() { setting.tip && this.play().catch(function() {}); }); _self.videojs = Hooks; return player; }; } function hookJQuery() { var Hooks = varHooks(); 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 = decodeURIComponent(config.datas.currVideoInfo.getVideoUrl).match(/{.+?}/g).findIndex(function(currentValue) { return currentValue.includes(setting.line + setting.http); }); setting.drag && (config.datas.currVideoInfo.getVideoUrl = config.datas.currVideoInfo.getVideoUrl.replace(/&drag=false&/, '&drag=true&')); var $player = setting.muted ? Hooks.Reply.apply(arguments) : $(); $player.on('onStart', function() { for (var i = 0; i < 16; i++) { $player.addVolNum(false); } }); 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 beforeFind() { setting.div = $( '
题目 | ' + '答案 | ' + '