智慧树脚本和使用方法

下载火狐浏览器,打开浏览器然后Ctrl+Shift+A,搜索Tampermonkey插件,然后添加。点开插件Tampermonkey,添加新脚本,然后复制以下代码点击保存,网页打开智慧树登录点击要学的课程就可以自动学习了。

// ==UserScript==
// @name         智慧树网课助手
// @namespace    [email protected]
// @version      2.0.0
// @description  自动挂机看知到MOOC,支持屏蔽弹窗题目、自动切换下一节,章测试和考试支持自动答题,视频自动倍速播放、线路选择、默认静音等,解除各类功能限制,开放自定义参数
// @author       wyn665817
// @match        *://*.zhihuishu.com/*
// @connect      forestpolice.org
// @run-at       document-end
// @grant        unsafeWindow
// @grant        GM_xmlhttpRequest
// @grant        GM_setClipboard
// @supportURL   https://greasyfork.org/zh-CN/scripts/380506/feedback
// @license      MIT
// ==/UserScript==

// 设置修改后,需要刷新或重新打开网课页面才会生效
var setting = {
    // 5E3 == 5000,科学记数法,表示毫秒数
    time: 5E3 // 默认响应速度为5秒,不建议小于3秒
    ,token: '' // 捐助用户可以使用上传选项功能,更精准的匹配答案,此处填写捐助后获取的识别码

    // 1代表开启,0代表关闭
    ,video: 1 // 视频支持课程、见面课,默认开启
    ,work: 1 // 自动答题功能,支持章测试、考试,高准确率,默认开启
    ,jump: 1 // 自动切换视频,支持课程、见面课,默认开启

    // 仅开启video时,修改此处才会生效
    ,line: '流畅' // 视频播放的默认线路,可选参数:['高清', '流畅', '校内'],默认'流畅'
    ,vol: '0' // 默认音量的百分数,设定范围:[0,100],'0'为静音,默认'0'
    ,rate: '1.5' // 默认播放速率,可选参数:['1.0', '1.25', '1.5'],默认'1.5'
    // 上方参数支持在页面改动,下方参数仅支持代码处修改
    ,que: 1 // 屏蔽视频时间点对应的节试题,取消屏蔽则自动切换为模拟点击关闭弹题,默认开启
    ,danmu: 0 // 见面课弹幕,关闭后在网页中无法手动开启,默认关闭
    ,habit: '0' // 限制视频挂机时长,单位是分钟,如需挂机习惯分,可以修改参数为'30',默认不限制

    // 仅开启work时,修改此处才会生效
    ,none: 0 // 无匹配答案时执行默认操作,默认关闭
    ,hide: 0 // 不加载答案搜索提示框,键盘↑和↓可以临时移除和加载,默认关闭
},
_self = unsafeWindow,
url = location.pathname,
$ = _self.jQuery;

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 (url == '/login/gologin' && top == self) {
    history.back();
} else 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')) {
    var $tip = $('.source-file-item');
    setting.jump && setInterval(function() {
        if (!$('.settleOn .finish').length) return;
        $tip.slice($tip.index($('.settleOn')) + 1).not(':has(.finish)').eq(0).find('.file-name').click();
    }, setting.time);
}

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;
        vol = Math.round(vol) / 100;
        options.volume = vol > 0 ? vol : 0;
        options.autostart = true;
        options.rate = $.inArray(setting.rate, ['1.0', '1.25', '1.5']) < 0 ? options.rate : +setting.rate;
        tip && config.callback.playbackRate(options.rate);
        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();
        });
    };
    $(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.rate = Number($(this).attr('rate'));
    });
    if (tip != 1) return;
    setting.habit && setTimeout(totalTime, setting.time);
    setInterval(doTest, 1E3);
    _self.XMLHttpRequest = setting.que ? function() {
        var ajax = new XMLHttpRequest(),
        open = ajax.open;
        ajax.open = function(method, url) {
            if (url.match('/loadVideoPointerInfo')) method = 'OPTIONS';
            return open.apply(this, arguments);
        };
        return ajax;
    } : XMLHttpRequest;
}

function totalTime() {
    var player = _self.PlayerStarter.playerArray[0].player;
    setting.habit -= player.paused() ? 0 : setting.time;
    if (setting.habit > 0) return setTimeout(totalTime, setting.time);
    player.pause();
    $.getScript('//cdn.jsdelivr.net/gh/sentsin/layer/dist/layer.js', function() {
        _self.layer.open({content: '已达到挂机限制时间', title: '智慧树网课助手提示'});
    });
}

function checkToNext(tip) {
    if ($('.time_icofinish, .finish', '.current_play, .lessonItemActive').length) {
        _self.PlayerStarter.playerArray[0].callback.playerNext();
    } else if (tip) {
        $('.current_player:contains("100%") + li').click();
        // $('.finish_tishi').hasClass('disNo') || console.log('签到已完成');
    }
}

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) {
        $('.dialog-test .btn').click();
        _self.PlayerStarter.playerArray[0].player.play();
    } else {
        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);
        });
    }
}

function relieveLimit(doc) {
    if (!doc.oncut) return setTimeout(relieveLimit, 100, doc);
    doc.oncontextmenu = doc.onpaste = doc.oncopy = doc.oncut = doc.onselectstart = null;
}

function beforeFind() {
    setting.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(); } }).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', '范围参数应为 正整数').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 ? '共有 ' + setting.lose + ' 道题目待完善(已深色标注)' : '答题已完成'; 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], option = setting.token && $TiMu.find('.node_detail').map(function() { return filterStyle(this); }).filter(function() { return this.length; }).get().join('#'); type = type ? setting.type[type] || 0 : -1; option = /^[12]$/.test(type) ? option : ''; GM_xmlhttpRequest({ method: 'POST', url: 'http://mooc.forestpolice.org/zhs/' + (setting.token || 0) + '/' + encodeURIComponent(question), headers: { 'Content-type': 'application/x-www-form-urlencoded' }, data: 'course=' + encodeURIComponent(setting.curs[0]) + '&chapter=' + encodeURIComponent(setting.curs[1]) + '&type=' + type + '&option=' + encodeURIComponent(option), timeout: setting.time, onload: function(xhr) { if (!setting.loop) { } else if (xhr.status == 200) { var obj = $.parseJSON(xhr.responseText) || {}; if (obj.code) { setting.div.children('div:eq(0)').text('正在搜索答案...'); var data = obj.data.replace(/&/g, '&').replace(/<([^i])/g, '<$1'); $( '' + '' + $TiMu.find('.subject_num').text().trim().replace('.', '') + '' + '' + (question.match(') ? question : question.replace(/&/g, '&').replace(/</g, '<')) + '' + '' + (/^http/.test(data) ? '+ obj.data + '">' : '') + data + '' + '' ).appendTo(setting.div.find('tbody')).css('background-color', function() { $TiMu = $dom.length ? $dom.closest('.examPaper_subject') : $TiMu; if (fillAnswer($TiMu, obj, type)) return ''; setting.div.children('button:eq(3)').show(); return 'rgba(0, 150, 136, 0.6)'; }); setting.small = ++setting.small < $dom.length ? setting.small : (setting.num++, 0); } else { setting.div.children('div:eq(0)').html(obj.data || '服务器繁忙,正在重试...'); } setting.div.children('span').html(obj.msg || ''); } else if (xhr.status == 403) { setting.div.children('div:eq(0)').data('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 fillAnswer($TiMu, obj, type) { var $div = $TiMu.find('.nodeLab'), str = String(obj.data).toCDB(), data = 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)$/)) { data.join().match(/(^|,)(正确||||T|ri)(,|$)/) && setting.queue.push($input); } else if (tip.match(/^(错误|||×|F|wr)$/)) { data.join().match(/(^|,)(错误|||×|F|wr)(,|$)/) && setting.queue.push($input); } else if (type == 2) { Boolean($.inArray(tip, data) + 1 || str.match(tip)) == $input.checked || setting.queue.push($input); } else { $.inArray(tip, data) + 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)) { var $text = $TiMu.find('textarea'); (obj.code > 0 && data.length == $text.length) || setting.none || setting.lose++; state == setting.lose && $text.each(function(index) { this.value = (obj.code > 0 && data[index]) || '不会'; // if (this.value == this._value) return true; this.dispatchEvent(new Event('input')); this.dispatchEvent(new Event('blur')); }); } else { setting.none || setting.lose++; } return state == setting.lose; } function filterStyle(dom, that) { return ($(dom, that).clone().find('style').remove().end().map(function() { return $('img', this).length ? $(this).html() : $(this).text(); })[0] || '').trim(); }

你可能感兴趣的:(智慧树脚本和使用方法)