Greasy Fork is available in English.

超星网课助手

自动挂机看尔雅MOOC,支持后台、切换窗口不暂停,视频自动切换,屏蔽视频内的题目,倍速播放、进度条拖动、快进快退

您查看的为 2018-06-19 提交的版本。查看 最新版本

// ==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
// ==/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);
};