// ==UserScript== // @name 智慧职教资源库|学习中心 --网课助手 (青版) // @version 0.2 // @description 小巧强大的智慧职教自动学习辅助脚本,中文化自定义各项参数 // @author tuChanged // @run- document-end // @grant unsafeWindow // @grant GM_xmlhttpRequest // @match *www.icve.com.cn/study/directory* // @license MIT // @namespace https://greasyfork.org/users/449085 // @supportURL https://tuchg.github.io // @contributionURL https://greasyfork.org/users/449085 // @downloadURL https://update.greasyfork.icu/scripts/404677/%E6%99%BA%E6%85%A7%E8%81%8C%E6%95%99%E8%B5%84%E6%BA%90%E5%BA%93%7C%E5%AD%A6%E4%B9%A0%E4%B8%AD%E5%BF%83%20--%E7%BD%91%E8%AF%BE%E5%8A%A9%E6%89%8B%20%28%E9%9D%92%E7%89%88%29.user.js // @updateURL https://update.greasyfork.icu/scripts/404677/%E6%99%BA%E6%85%A7%E8%81%8C%E6%95%99%E8%B5%84%E6%BA%90%E5%BA%93%7C%E5%AD%A6%E4%B9%A0%E4%B8%AD%E5%BF%83%20--%E7%BD%91%E8%AF%BE%E5%8A%A9%E6%89%8B%20%28%E9%9D%92%E7%89%88%29.meta.js // ==/UserScript== (async function () { 'use strict'; const setting = { /*影响刷课速度关键选项,延时非最优解,过慢请自行谨慎调整*/ 最高延迟响应时间: 5000,//毫秒 最低延迟响应时间: 3000,//毫秒 //自行根据课件情况修改 固定PPT页数: 20,//页 //0-流畅 1-清晰 2-原画 视频清晰度: 0, //2倍速,允许开倍速则有效,请放心使用 视频播放倍速: 2, //是否保持静音 是否保持静音: true, //请求超时时间 请求超时时间: 2000, /* * 📣如果您有软件定制(管理系统,APP,小程序等),毕设困扰,又或者课程设计困扰等欢迎联系, * 价格从优,源码调试成功再付款💰, * 实力保证,包远程,包讲解 QQ:2622321887 */ }, _self = unsafeWindow, url = location.pathname, top = _self /** 等待获取jquery @油猴超星网课助手 wyn665817*/ try { while (top != _self.top) top = top.parent.document ? top.parent : _self.top; } catch (err) { console.log(err); top = _self; } var $ = _self.jQuery || top.jQuery; /** */ //产生区间随机数 const rnd = (min, max) => Math.floor(Math.random() * (max - min + 1) + min); //课程ID const courseID = getQueryValue("courseId") //章节ID const chapterID = getQueryValue("chapterId") //小节ID let cellID = getQueryValue("#") //小节类型 const type = getQueryValue("type") let db = undefined await initDB() if (!chapterID) { //非小节,解析目录 dirParser() } else { console.log(`当前课件为${type}`); switch (type) { case "video": delayExec(() => mediaHandler()) break; case "text": case "doc": delayExec(() => docHandler()) break default: delayExec(() => currentCompleted()) break; } } /** * 当前课程结束调用 * @param {*} params */ function currentCompleted() { db.transaction(['course'], 'readwrite').objectStore('course') .delete(cellID).onsuccess = function (params) { console.log(`课程${cellID}已完成`); delayExec(() => nextLesson()) } } function nextLesson() { db.transaction(['course'], 'readwrite').objectStore('course') .openCursor() .onsuccess = (event) => { console.log(event, `课程已准备`); const result = event.target.result; if (result) { let { ChapterId, CellType, Id } = result.value || {}; gotoURL(`dir_course.html?courseId=${courseID}&chapterId=${ChapterId}&type=${CellType}#${Id}`) } else { console.log("数据库读取失败,请规范操作,从课程目录进入\n清除浏览器IndexDB数据库后再次尝试"); } } } /** * 跳转 * @param {*} url */ function gotoURL(url) { console.log(url); top.location = url } //值监听 unsafeWindow.addEventListener("hashchange", () => cellID = getQueryValue("#")); /** * 获取url查询字段 * @param {查询字段} query */ function getQueryValue(query) { let url = window.location.search; //获取url中"?"符后的字串 //返回hash if (query == "#") return location.hash.slice(1); //返回Query let theRequest = new Object(); if (url.indexOf("?") != -1) { let str = url.substr(1); let strs = str.split("&"); for (let i = 0; i < strs.length; i++) theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]); } return theRequest[query]; } //解析目录 function dirParser() { request("GET", `https://www.icve.com.cn/study/Directory/directoryList?courseId=${courseID}`, { headers: { 'X-Requested-With': 'XMLHttpRequest' }, onSuccess: (xhr) => { const json = JSON.parse(xhr.responseText).directory; // console.log(dbRequest); //将课程目录解析 parseLessons(json) // parseLessons(JSON.parse(temp1.responseText).directory || {}) } } ) } //解析并处理储存课程列表 function parseLessons(json) { //status 0(未看) status 1已看 //将读取到课程的放到localStorge,并记录状态 进行 未进行 未完成 完成 // 0->->cells->0->status // chapter //将未完成的课程信息提取 if (db != undefined) { const tx = db.transaction(['course'], 'readwrite'); tx.oncomplete = (e) => { console.log('课程批量插入成功', e) nextLesson() }; tx.onerror = (e) => console.log('批量插入失败', e); const store = tx .objectStore('course'); json.forEach(e => { e.chapters.forEach(i => { i.cells.forEach(x => { if (x.Status == 0) store.put(x) }) }) }) } else console.log("数据库启动失败,程序终止"); } /** * 初始化indexDB * @param {} version */ function initDB(version = 1) { return new Promise((resolve, reject) => { const dbRequest = indexedDB.open('ICVE', version) dbRequest.addEventListener('upgradeneeded', e => { const objectStore = e.target.result .createObjectStore('course', { keyPath: 'Id', autoIncrement: false }); // //多字段查询 // objectStore.createIndex('SectionIdIndex', 'SectionId', { unique: false }); // objectStore.createIndex('ChapterIdIndex', 'ChapterId', { unique: false }); }); dbRequest.onsuccess = function (e) { db = e.target.result; console.log("数据库连接成功!"); resolve() } }) } /** * 对XHR的二次全局封装,方便后期扩展 * @param {*} method * @param {*} url * @param {*} headers * @param {*} data * @param {*} onSuccess */ function request(method, url, { headers, data, onSuccess }) { GM_xmlhttpRequest({ method: method, url: url, headers: headers, data: data, timeout: setting.请求超时, onload: function (xhr) { switch (xhr.status) { case 200: // var obj = $.parseJSON(xhr.responseText) || {}; onSuccess(xhr) break; default: console.log("服务器异常 " + xhr); break; } }, ontimeout: function () { console.log("响应超时"); } }); } /** * 使用异步实现 * * 随机延迟执行方法 * @param {需委托执行的函数} func */ function delayExec(func) { return new Promise((resolve, reject) => { setTimeout(async () => { try { await func() } catch (error) { console.log(func, error); } resolve(); }, rnd(setting.最低延迟响应时间, setting.最高延迟响应时间)); }) } /** * 视频/音频类处理 */ function mediaHandler() { let player = jwplayer($(".jwplayer").attr("id")) //视频暂停状态 if (player.getState() == "PAUSED") { console.log("媒体已暂停,恢复播放"); player.play() } //播放回调 if (player.getState() == "COMPLETE") { console.log("媒体已播放完毕\n"); delayExec(currentCompleted()); return; } //配置 player.setMute(setting.是否保持静音)//静音 player.setCurrentQuality(setting.视频清晰度) try { player.setPlaybackRate(setting.视频播放倍速) } catch (error) { console.log('倍速开启失败'); } //播放回调 player.onPlaylistComplete(function () { console.log("媒体播放完成\n"); delayExec(currentCompleted()); }) } /** * 文档处理 * @param {*} current */ async function docHandler() { //根据按钮状态判断是否还有下一页 while ($(".MPreview-pageNext").hasClass('current')) { console.log("文档翻页了"); //ppt翻页 异步方式 await delayExec(() => { $(".MPreview-pageNext").click() }) } delayExec(currentCompleted()); } })();