├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── default.yml └── workflows │ └── release.yml ├── README.md ├── techxuexi-js └── version_info.json ├── 不学习何以强国.js └── 强国学习.js /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/default.yml: -------------------------------------------------------------------------------- 1 | name: 报告问题 2 | description: 提 issue 报告问题,请点击右边绿色按钮 3 | labels: ["bug"] 4 | title: "请修改这里的名称" 5 | assignees: 6 | - octocat 7 | body: 8 | - type: checkboxes 9 | id: lists 10 | attributes: 11 | label: 清单 12 | description: 你必须按要求尝试并勾选完成。 13 | options: 14 | - label: 我已经仔细阅读过 README 说明 https://github.com/TechXueXi/techxuexi-js 15 | required: true 16 | - label: 我已经查看/搜索过所有已有 issue,无论是open还是close的 https://github.com/TechXueXi/techxuexi-js/issues?q=is%3Aissue 17 | required: true 18 | - label: 我已经通过搜索引擎搜索,尝试不同的关键词 www.google.com www.baidu.com 19 | required: true 20 | - label: 我已经到提供的在线聊天室询问过 聊天室说明:https://github.com/TechXueXi/TechXueXi/issues/14 21 | required: true 22 | - type: input 23 | id: js-name 24 | attributes: 25 | label: 脚本名称 26 | description: 如 不学习何以强国.js 27 | placeholder: 不学习何以强国.js 28 | validations: 29 | required: true 30 | - type: input 31 | id: source-version 32 | attributes: 33 | label: 软件/源码版本 34 | description: js文件的“// @version 20211223”是版本号 35 | placeholder: "20211223" 36 | validations: 37 | required: true 38 | - type: input 39 | id: sys-version 40 | attributes: 41 | label: 系统版本,包含位数 42 | description: 如 windows7 x64 , centos7.8 x64 43 | placeholder: windows7 x64 44 | validations: 45 | required: true 46 | - type: input 47 | id: browser-version 48 | attributes: 49 | label: 浏览器版本 50 | description: 如 chrome v73.0.0 51 | placeholder: chrome v73.0.0 52 | validations: 53 | required: true 54 | - type: input 55 | id: e-version 56 | attributes: 57 | label: 油猴等插件和它的版本 58 | description: 油猴在管理面板的左上角图标处可以看到,如 v4.11,填写格式: 油猴 v4.11 59 | placeholder: 油猴 v4.11 60 | validations: 61 | required: true 62 | - type: textarea 63 | id: description 64 | attributes: 65 | label: 详细描述 66 | description: 报错请复制粘贴,可以粘贴图片,但不要只使用图片,方便同志们搜索。 67 | placeholder: 68 | value: 69 | validations: 70 | required: true 71 | - type: markdown 72 | attributes: 73 | value: | 74 | **必须填写完成才能按提交按钮** 75 | 76 | 许多IT人员本终日埋头写代码,对我们这类软件确实有需求, 77 | 与其各人重复修改编写浪费生产力不如团队合作维护,因此我们希望长期维护此生态。 78 | 有意愿加入本组织者,请 https://techxuexi.js.org/ 79 | 80 | 我们不接受任何捐赠。远离非法牟利。 81 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | # 用于发布release 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | version_tag: 8 | description: '' 9 | required: true 10 | default: 'v' 11 | prerelease: 12 | description: '' 13 | required: true 14 | default: 'false' 15 | techxuexi_text: 16 | description: '' 17 | required: true 18 | default: '更新日志请查看 https://github.com/TechXueXi/techxuexi-js/blob/main/techxuexi-js/version_info.json 交流群: https://github.com/TechXueXi/TechXueXi/issues/14 ,使用方法:https://github.com/TechXueXi/techxuexi-js' 19 | 20 | 21 | jobs: 22 | Release: 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - name: Checkout code 27 | uses: actions/checkout@v2 28 | - name: Get tag 29 | id: tag 30 | run: | 31 | echo ::set-output name=tag::${GITHUB_REF#refs/tags/} 32 | - name: Create Release 33 | id: create_release 34 | uses: actions/create-release@v1 35 | env: 36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 37 | with: 38 | tag_name: ${{ github.event.inputs.version_tag }} 39 | release_name: ${{ github.event.inputs.version_tag }} 40 | draft: false 41 | prerelease: ${{ github.event.inputs.prerelease }} 42 | body: ${{ github.event.inputs.techxuexi_text }} 43 | - name: Delete Workflow Runs 44 | uses: Mattraks/delete-workflow-runs@main 45 | with: 46 | token: ${{ github.token }} 47 | repository: ${{ github.repository }} 48 | retain_days: 1 49 | keep_minimum_runs: 0 50 | - name: send telegram message on push 51 | uses: appleboy/telegram-action@master 52 | with: 53 | to: ${{ secrets.TELEGRAM_TO }} 54 | token: ${{ secrets.TELEGRAM_TOKEN }} 55 | disable_web_page_preview: true 56 | disable_notification: false 57 | format: markdown 58 | message: | 59 | #techxuexijs #发布 通知 60 | 仓库: ${{ github.repository }} 61 | `${{ github.event.inputs.version_tag }}` 的版本已经发布。 62 | [点击查看这个Github release的详细信息](https://github.com/${{ github.repository }}/releases/tag/${{ github.event.inputs.version_tag }}) 63 | 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # techxuexi-js 2 | 3 | **[交流群地址及说明(点击查看)](https://github.com/TechXueXi/TechXueXi/issues/14)** 4 | 5 | **我们随时删库跑路,请加交流群防失联。** 6 | 7 | 有建议说上传到 greasyfork,方便更新。其实,我们在这里发布,是因为有同志发现 greasyfork **有审查**,上传就被举报,被封,**都没有地方可以下载**,所以在这里开库收集的。**该同志表示: 习惯在 greasyfork 找强国佛系xx的人,太年轻了,还不知道社会的险恶** 8 | 9 | 收集油猴等插件的科技强国 js 代码。 10 | 11 | 这里没有各种恶心的审查,欢迎大家提交贡献,比如新增脚本,修改代码等。 12 | 13 | 提交贡献方法: https://github.com/TechXueXi/TechXueXi/blob/dev/CONTRIBUTING.md 14 | 15 | ## 使用方法 16 | 17 | 请优先使用 不学习何以强国 ,它可以全自动,以后维护工作以它为主, 强国学习 需要手动进入答题。 18 | 19 | 装个浏览器插件 tampermonkey (可以从这里下载 https://github.com/TechXueXi/Tampermonkey ,网上也很多教程),点击插件里添加按钮,去掉编辑框里原来的代码,把 不学习何以强国 js 脚本复制粘贴进编辑框保存。开启这个脚本,然后进入网页强国 www.xuexi.cn 登录,刷新登录网页,左上角有启动按钮。 20 | 21 | ### 如何设置自动升级? 22 | 23 | 看图: 24 | 25 |  26 | 27 |  28 | 29 | 30 | ## 不想每天开电脑学习,可以配置 techxuexi python 在服务器。 https://github.com/TechXueXi/TechXueXi 31 | -------------------------------------------------------------------------------- /techxuexi-js/version_info.json: -------------------------------------------------------------------------------- 1 | { 2 | "techxuexi_js_version": "v20230318", 3 | "notice": "...", 4 | "techxuexi_js_update_log": [{ 5 | "version": "v20230318", 6 | "info": "更新学习进度api" 7 | },{ 8 | "version": "v20220922", 9 | "info": "添加自动开始学习,未登陆则会跳转到登录页" 10 | },{ 11 | "version": "v20220329", 12 | "info": "修复视频播放一直正在初始化的问题" 13 | },{ 14 | "version": "v20220214", 15 | "info": "修复因为视频学习的时长不够导致的问题" 16 | },{ 17 | "version": "v20220206", 18 | "info": "修复无法关闭视频" 19 | },{ 20 | "version": "v20220205", 21 | "info": "修复 视频学习不会自动关闭" 22 | },{ 23 | "version": "v20220201", 24 | "info": "更新cdn链接" 25 | },{ 26 | "version": "v20220125", 27 | "info": "适配 Kiwi Browser安卓浏览器" 28 | },{ 29 | "version": "v20220121", 30 | "info": "替换被墙的链接" 31 | },{ 32 | "version": "v20211015", 33 | "info": "初始化仓库,优化强国学习js" 34 | },{ 35 | "version": "v20211129", 36 | "info": "处理不自动播放视频和自动答题Bug" 37 | },{ 38 | "version": "v20211216", 39 | "info": "修复?" 40 | },{ 41 | "version": "v20211221", 42 | "info": "增加倒序答题配置" 43 | },{ 44 | "version": "v20211223", 45 | "info": "修复上一个合并引入的code:429错误" 46 | }] 47 | } 48 | -------------------------------------------------------------------------------- /不学习何以强国.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name 不学习何以强国-beta 3 | // @namespace http://tampermonkey.net/ 4 | // @version 20230318 5 | // @description 问题反馈位置: https://github.com/TechXueXi/techxuexi-js/issues 。读文章,看视频,做习题。 6 | // @author techxuexi ,荷包蛋。 7 | // @match https://www.xuexi.cn 8 | // @match https://www.xuexi.cn/* 9 | // @match https://pc.xuexi.cn/points/login.html* 10 | // @match https://pc.xuexi.cn/points/exam-practice.html 11 | // @match https://pc.xuexi.cn/points/exam-weekly-detail.html?id=* 12 | // @match https://pc.xuexi.cn/points/exam-weekly-list.html 13 | // @match https://pc.xuexi.cn/points/exam-paper-detail.html?id=* 14 | // @match https://pc.xuexi.cn/points/exam-paper-list.html 15 | // @require https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.5.1.min.js 16 | // @require https://cdn.jsdelivr.net/npm/blueimp-md5@2.9.0 17 | // @grant GM_addStyle 18 | // @grant GM_setValue 19 | // @grant GM_getValue 20 | // @grant GM_deleteValue 21 | // @grant GM_openInTab 22 | // ==/UserScript== 23 | var study_css = ".egg_study_btn{outline:0;border:0;position:fixed;top:5px;left:5px;padding:12px 20px;border-radius:10px;cursor:pointer;background-color:#fff;color:#d90609;font-size:18px;font-weight:bold;text-align:center;box-shadow:0 0 9px #666777}.egg_manual_btn{transition:0.5s;outline:none;border:none;padding:12px 20px;border-radius:10px;cursor:pointer;background-color:#e3484b;color:rgb(255,255,255);font-size:18px;font-weight:bold;text-align:center;}.egg_auto_btn{transition:0.5s;outline:none;border:none;padding:12px 20px;border-radius:10px;cursor:pointer;background-color:#666777;color:rgb(255,255,255);font-size:18px;font-weight:bold;text-align:center;}.egg_setting_box{position:fixed;top:70px;left:5px;padding:12px 20px;border-radius:10px;background-color:#fff;box-shadow:0 0 9px #666777}.egg_setting_item{margin-top:5px;height:30px;width:140px;font-size:16px;display:flex;justify-items:center;justify-content:space-between}input[type='checkbox'].egg_setting_switch{cursor:pointer;margin:0;outline:0;appearance:none;-webkit-appearance:none;-moz-appearance:none;position:relative;width:40px;height:22px;background:#ccc;border-radius:50px;transition:border-color .3s,background-color .3s}input[type='checkbox'].egg_setting_switch::after{content:'';display:inline-block;width:1rem;height:1rem;border-radius:50%;background:#fff;box-shadow:0,0,2px,#999;transition:.4s;top:3px;position:absolute;left:3px}input[type='checkbox'].egg_setting_switch:checked{background:#fd5052}input[type='checkbox'].egg_setting_switch:checked::after{content:'';position:absolute;left:55%;top:3px}"; 24 | GM_addStyle(study_css); 25 | //https://www.xuexi.cn/lgdata/3uoe1tg20en0.json 26 | //查询今日完成情况 27 | const SearchSocreUrl = "https://pc-proxy-api.xuexi.cn/delegate/score/days/listScoreProgress?sence=score&deviceType=2"; 28 | //重要新闻列表(主) 29 | const NewsUrl1 = "https://www.xuexi.cn/lgdata/1jscb6pu1n2.json"; 30 | //学习时评新闻列表 31 | const NewsUrl2 = "https://www.xuexi.cn/lgdata/1ap1igfgdn2.json"; 32 | //新闻视频列表 33 | const VideosUrl1 = "https://www.xuexi.cn/lgdata/3o3ufqgl8rsn.json"; 34 | //新闻视频列表 35 | const VideosUrl2 = "https://www.xuexi.cn/lgdata/1742g60067k.json"; 36 | //每日答题页面 37 | const ExamPracticeUrl = "https://pc.xuexi.cn/points/exam-practice.html"; 38 | //每周答题列表API 39 | const ExamWeeklyListUrl = "https://pc-proxy-api.xuexi.cn/api/exam/service/practice/pc/weekly/more?pageNo={pageNo}&pageSize=50"; 40 | //专项答题列表API 41 | const ExamPaperListUrl = "https://pc-proxy-api.xuexi.cn/api/exam/service/paper/pc/list?pageSize=50&pageNo={pageNo}"; 42 | //题目API(只有每周答题和专项练习) 43 | //const ExamQueryUrl = "https://pc-proxy-api.xuexi.cn/api/exam/service/detail/queryV3?type={type}&id={id}&forced=true";//type=1专项练习,type=2每周答题 44 | //每周答题页面 45 | const ExamWeeklyUrl = "https://pc.xuexi.cn/points/exam-weekly-detail.html?id={id}"; 46 | //专项测试页面 47 | const ExamPaperUrl = "https://pc.xuexi.cn/points/exam-paper-detail.html?id={id}"; 48 | //文本服务器保存API 49 | const AnswerSaveUrl = "https://a6.qikekeji.com/txt/data/save/"; 50 | //文本服务器获取API 51 | const AnswerDetailUrl = "https://a6.qikekeji.com/txt/data/detail/"; 52 | //获取当前日期 53 | var currDate = new Date().toISOString().split('T')[0]; 54 | var newsNum = 6; 55 | var news = []; 56 | var videoNum = 6; 57 | var videos = []; 58 | //配置 59 | var settings = {}; 60 | var settingsDefault = { 61 | News: true, //0 62 | Video: true,//1 63 | ExamPractice: true, //6 每日答题 64 | ExamWeekly: true,//2 每周答题 65 | ExamPaper: true,//5 专项练习 66 | ShowMenu: false, //7 隐藏菜单 67 | AutoStart: false, //是否加载脚本后自动播放 68 | } 69 | var pause = false;//是否暂停答题 70 | //每周答题当前页码 71 | var examWeeklyPageNo = 1; 72 | //每周答题总页码 73 | var examWeeklyTotalPageCount = null; 74 | //每周答题开启逆序答题: false: 顺序答题; true: 逆序答题 75 | var examWeeklyReverse = false; 76 | //专项答题当前页码 77 | var examPaperPageNo = 1; 78 | //专项答题总页码 79 | var examPaperTotalPageCount = null; 80 | //专项答题开启逆序答题: false: 顺序答题; true: 逆序答题 81 | var examPaperReverse = false; 82 | //每周答题,专项答题 请求rate 限制 每 3000ms 一次 83 | const ratelimitms = 3000; 84 | 85 | //默认情况下, chrome 只允许 window.close 关闭 window.open 打开的窗口,所以我们就要用window.open命令,在原地网页打开自身窗口再关上,就可以成功关闭了 86 | function closeWin() { 87 | try { 88 | window.opener = window; 89 | var win = window.open("", "_self"); 90 | win.close(); 91 | top.close(); 92 | } catch (e) { 93 | } 94 | 95 | } 96 | 97 | async function sleep( timeMS ) { 98 | return new Promise( res => setTimeout( res, time ) ); 99 | } 100 | 101 | /** 模拟鼠标移动 改方法来自https://blog.csdn.net/Wuzihui___/article/details/79952068 102 | * @param id 103 | * @param clientX 相对窗口横坐标 104 | * @param clientY 相对窗口纵坐标 105 | * @param distance 滑动距离 106 | */ 107 | function dragandDrop(btn_hk, clientX, clientY, distance) { 108 | var elem = btn_hk, 109 | k = 0, 110 | interval; 111 | iME(elem,"mousedown",0, 0, clientX, clientY); 112 | let waitTime = Math.floor(Math.random() * (0.005 * 1000 - 0.09 * 1000) + 0.09 * 1000) 113 | interval = setInterval(function() { 114 | k++; 115 | iter(k); 116 | if (k === distance) { 117 | clearInterval(interval); 118 | iME(elem, "mouseup", clientX + k, clientY, 220 + k, 400); 119 | } 120 | }, waitTime); 121 | function iter(y) { 122 | iME(elem, "mousemove", clientX + y, clientY, clientX + y, clientY); 123 | } 124 | function iME(obj, event, screenXArg, screenYArg, clientXArg, clientYArg) { 125 | var mousemove = document.createEvent("MouseEvent"); 126 | mousemove.initMouseEvent(event, true, true, unsafeWindow, 0, screenXArg, screenYArg, clientXArg, clientYArg, 0, 0, 0, 0, 0, null); 127 | obj.dispatchEvent(mousemove); 128 | } 129 | } 130 | 131 | /** 132 | * 随机等待最小到最大之间几秒, 需要await 133 | * @param {number} minSecond 最短时长 134 | * @param {number} MaxSecond 最长时长 135 | * @returns Promise 136 | */ 137 | function waitRandomBetween(minSecond = 2, MaxSecond = 5) { 138 | if (MaxSecond <= minSecond) { 139 | MaxSecond = minSecond + 3 140 | } 141 | 142 | let waitTime = Math.floor(Math.random() * (MaxSecond * 1000 - minSecond * 1000) + minSecond * 1000) 143 | return new Promise((resolve, reject) => { 144 | setTimeout(() => { 145 | console.log(`随机等待${waitTime / 1000}秒`) 146 | resolve() 147 | }, waitTime) 148 | }) 149 | } 150 | 151 | $(document).ready(function () { 152 | let url = window.location.href; 153 | if (url == "https://www.xuexi.cn" || url == "https://www.xuexi.cn/" || url == "https://www.xuexi.cn/index.html") { 154 | let ready = setInterval(function () { 155 | if (document.getElementsByClassName("text-wrap")[0]) { 156 | clearInterval(ready);//停止定时器 157 | //初始化设置 158 | initSetting(); 159 | //创建"开始学习"按钮 160 | createStartButton(); 161 | } 162 | }, 800); 163 | } else if (url.indexOf("login.html") !== -1) { 164 | console.log("检测到登录页") 165 | setTimeout(() => { 166 | window.scrollTo(0, 1000); 167 | }, 500); 168 | } 169 | else if (typeof GM_getValue("readingUrl") != 'object' && url == GM_getValue("readingUrl")) { 170 | try { 171 | let settingTemp = JSON.parse(GM_getValue('studySetting')); 172 | if (!settingTemp[7]) { 173 | createTip();//创建学习提示 174 | } 175 | reading(0); 176 | } catch (e) { 177 | createTip();//创建学习提示 178 | reading(0); 179 | } 180 | } else if (typeof GM_getValue("watchingUrl") != 'object' && url == GM_getValue("watchingUrl")) { 181 | try { 182 | let settingTemp = JSON.parse(GM_getValue('studySetting')); 183 | if (!settingTemp[7]) { 184 | createTip();//创建学习提示 185 | } 186 | } catch (e) { 187 | createTip();//创建学习提示 188 | } 189 | let randNum = 0; 190 | var checkVideoPlayingInterval = setInterval(function () { 191 | let temp = getVideoTag(); 192 | if (temp.video) { 193 | if (!temp.video.muted) { 194 | temp.video.muted = true; 195 | } 196 | if (temp.video.paused) { 197 | temp.video.paused = false; 198 | console.log("正在尝试播放视频") 199 | if (randNum == 0) {//尝试使用js的方式播放 200 | try { 201 | temp.video.play();//尝试使用js的方式播放 202 | } catch (e) { } 203 | randNum++; 204 | } else { 205 | try { 206 | temp.pauseButton.click();//尝试点击播放按钮播放 207 | } catch (e) { } 208 | randNum--; 209 | } 210 | } else { 211 | console.log("成功播放") 212 | clearInterval(checkVideoPlayingInterval); 213 | reading(1); 214 | } 215 | } else { 216 | console.log("等待加载") 217 | } 218 | }, 800); 219 | } else if (url.indexOf("exam") != -1 && url.indexOf("list") == -1) { 220 | //答题页面 221 | let ready = setInterval(function () { 222 | if (document.getElementsByClassName("title")[0]) { 223 | clearInterval(ready);//停止定时器 224 | //创建“手动答题”按钮 225 | createManualButton(); 226 | //去除答题验证 227 | //cancelVerify(); 228 | //开始答题 229 | doingExam(); 230 | } 231 | }, 500); 232 | } else { 233 | } 234 | }); 235 | 236 | 237 | //获取video标签 238 | function getVideoTag() { 239 | let iframe = document.getElementsByTagName("iframe")[0]; 240 | let video = null; 241 | let pauseButton = null; 242 | var u = navigator.userAgent; 243 | 244 | // 视频播放按钮更新 245 | video = document.getElementsByTagName("video")[0]; 246 | pauseButton = document.getElementsByClassName("prism-big-play-btn")[0]; 247 | 248 | return { 249 | "video": video, 250 | "pauseButton": pauseButton 251 | } 252 | 253 | // if (u.indexOf('Mac') > -1) {//Mac 254 | // if (iframe != null && iframe.innerHTML) { 255 | // //如果有iframe,说明外面的video标签是假的 256 | // video = iframe.contentWindow.document.getElementsByTagName("video")[0]; 257 | // pauseButton = iframe.contentWindow.document.getElementsByClassName("prism-play-btn")[0]; 258 | // } else { 259 | // //否则这个video标签是真的 260 | // video = document.getElementsByTagName("video")[0]; 261 | // pauseButton = document.getElementsByClassName("prism-play-btn")[0]; 262 | // } 263 | // return { 264 | // "video": video, 265 | // "pauseButton": pauseButton 266 | // } 267 | // } 268 | // else { 269 | // if (iframe) { 270 | // //如果有iframe,说明外面的video标签是假的 271 | // video = iframe.contentWindow.document.getElementsByTagName("video")[0]; 272 | // pauseButton = iframe.contentWindow.document.getElementsByClassName("prism-play-btn")[0]; 273 | // } else { 274 | // //否则这个video标签是真的 275 | // video = document.getElementsByTagName("video")[0]; 276 | // pauseButton = document.getElementsByClassName("prism-play-btn")[0]; 277 | // } 278 | // return { 279 | // "video": video, 280 | // "pauseButton": pauseButton 281 | // } 282 | // } 283 | } 284 | 285 | //读新闻或者看视频 286 | //type:0为新闻,1为视频 287 | async function reading(type) { 288 | //看文章或者视频 289 | var time = 1; 290 | if (type == 0) { 291 | time = parseInt(Math.random() * (100 - 80 + 1) + 80, 10);//80-100秒后关闭页面,看文章 292 | } else { 293 | time = parseInt(Math.random() * (250 - 230 + 1) + 230, 10);//230-250秒后关闭页面,看视频 294 | } 295 | let firstTime = time - 2; 296 | let secendTime = 12; 297 | let scrollLength = document.body.scrollHeight / 2; 298 | var readingInterval = setInterval(function () { 299 | time--; 300 | $("#studyTip").text(time + " 秒后关闭页面"); 301 | if (time <= firstTime) { 302 | try { 303 | $("html,body").animate({ scrollTop: 394 }, 1000); 304 | } catch (e) { 305 | window.scrollTo(0, 394); 306 | } 307 | firstTime = -1; 308 | } 309 | if (time <= secendTime) { 310 | try { 311 | $("html,body").animate({ scrollTop: scrollLength / 3 }, 1000); 312 | } catch (e) { 313 | window.scrollTo(0, scrollLength / 3); 314 | } 315 | secendTime = -1; 316 | } 317 | if (time <= 0) { 318 | if (type == 0) { 319 | GM_setValue('readingUrl', null); 320 | } else { 321 | GM_setValue('watchingUrl', null); 322 | } 323 | clearInterval(readingInterval); 324 | closeWin(); 325 | } 326 | }, 1000); 327 | //关闭文章或视频页面 328 | } 329 | //创建学习提示 330 | function createTip() { 331 | let tipInfo = document.createElement("div"); 332 | //添加样式 333 | tipInfo.setAttribute("id", "studyTip"); 334 | tipInfo.innerText = "正在初始化...."; 335 | tipInfo.style.position = "fixed"; 336 | tipInfo.style.bottom = "15px"; 337 | tipInfo.style.left = "5px"; 338 | tipInfo.style.padding = "12px 14px"; 339 | tipInfo.style.border = "none"; 340 | tipInfo.style.borderRadius = "10px"; 341 | tipInfo.style.backgroundColor = "#222222"; 342 | tipInfo.style.color = "#ffffff"; 343 | tipInfo.style.fontSize = "14px"; 344 | tipInfo.style.fontWeight = "bold"; 345 | //插入节点 346 | let body = document.getElementsByTagName("body")[0]; 347 | body.append(tipInfo) 348 | } 349 | //等待窗口关闭 350 | function waitingClose(newPage) { 351 | return new Promise(resolve => { 352 | let doing = setInterval(function () { 353 | if (newPage.closed) { 354 | clearInterval(doing);//停止定时器 355 | resolve('done'); 356 | } 357 | }, 1000); 358 | }); 359 | } 360 | //阅读文章 361 | async function readNews() { 362 | await getNews(); 363 | for (let i = 0; i < news.length; i++) { 364 | GM_setValue('readingUrl', news[i].url); 365 | console.log("正在看第" + (i + 1) + "个新闻"); 366 | let newPage = GM_openInTab(news[i].url, { active: true, insert: true, setParent: true }); 367 | await waitingClose(newPage); 368 | await waitRandomBetween(1, 3); 369 | } 370 | } 371 | //获取新闻列表 372 | function getNews() { 373 | return new Promise(resolve => { 374 | news = new Array(); 375 | let n = 6; 376 | if (newsNum < 6) {//如果需要学习的新闻数量不到6,也就是已经学过了,但是积分不够,补的 377 | n = newsNum; 378 | } 379 | console.log("还需要看" + n + "个新闻") 380 | //新闻数量是否足够 381 | let enough = true; 382 | //获取重要新闻 383 | $.ajax({ 384 | type: "GET", 385 | url: NewsUrl1, 386 | dataType: "json", 387 | success: function (data) { 388 | let j = 0; 389 | if (n == 6) {//如果今天还没学过,则优先找今天的新闻 390 | for (let i = 0; i < n; i++) { 391 | //如果有当天日期的,则加入 392 | if (data[j].auditTime.indexOf(currDate) != -1) { 393 | news.push(data[j]); 394 | j++; 395 | } else {//否则跳出循环 396 | break; 397 | } 398 | } 399 | } 400 | for (j; j < n; j++) { 401 | let temp = parseInt(Math.random() * (data.length + 1), 10); 402 | news.push(data[temp]); 403 | } 404 | resolve('done'); 405 | }, 406 | error: function () { 407 | news = null; 408 | resolve('done'); 409 | } 410 | }); 411 | }); 412 | } 413 | //获取视频列表 414 | function getVideos() { 415 | return new Promise(resolve => { 416 | videos = new Array(); 417 | let n = 6; 418 | if (videoNum < 6) {//如果需要学习的视频数量不到6,也就是已经学过了,但是积分不够,补的 419 | n = videoNum; 420 | } 421 | console.log("还需要看" + n + "个视频") 422 | $.ajax({ 423 | type: "GET", 424 | url: VideosUrl1, 425 | dataType: "json", 426 | success: function (data) { 427 | let j = 0; 428 | if (n == 6) { 429 | for (let i = 0; i < n; i++) { 430 | //如果有当天日期的,则加入 431 | if (data[j].auditTime.indexOf(currDate) != -1) { 432 | videos.push(data[j]); 433 | j++; 434 | } else {//否则跳出循环 435 | break; 436 | } 437 | } 438 | } 439 | for (j; j < n; j++) { 440 | let temp = parseInt(Math.random() * (data.length + 1), 10); 441 | videos.push(data[temp]); 442 | } 443 | resolve('done'); 444 | }, 445 | error: function () { 446 | videos = []; 447 | resolve('done'); 448 | } 449 | }); 450 | }); 451 | } 452 | //看学习视频 453 | async function watchVideo() { 454 | await getVideos(); 455 | for (let i = 0; i < videos.length; i++) { 456 | GM_setValue('watchingUrl', videos[i].url); 457 | console.log("正在观看第" + (i + 1) + "个视频"); 458 | let newPage = GM_openInTab(videos[i].url, { active: true, insert: true, setParent: true }) 459 | await waitingClose(newPage); 460 | await waitRandomBetween(1, 3); 461 | } 462 | } 463 | //做每日答题 464 | function doExamPractice() { 465 | return new Promise(resolve => { 466 | console.log("正在完成每日答题") 467 | let newPage = GM_openInTab(ExamPracticeUrl, { active: true, insert: true, setParent: true }); 468 | let doing = setInterval(function () { 469 | if (newPage.closed) { 470 | clearInterval(doing);//停止定时器 471 | resolve('done'); 472 | } 473 | }, 1000); 474 | }); 475 | } 476 | 477 | //fix code = 429 478 | async function waitingDependStartTime(startTime) { 479 | let remainms = Date.now() - startTime; 480 | if (remainms < ratelimitms) { 481 | let second = (ratelimitms - remainms) / 1000 482 | await waitRandomBetween(second + 1, second + 3) 483 | } 484 | } 485 | //初始化专项答题总页数属性 486 | async function InitExamPaperAttr() { 487 | let startTime = Date.now(); 488 | var data = await getExamPaperByPageNo(1); // 默认从第一页获取全部页属性 489 | if (data) { 490 | // 初始化总页码 491 | examPaperTotalPageCount = data.totalPageCount; 492 | // 若专项答题逆序, 则从最后一页开始 493 | if (examPaperReverse) { 494 | examPaperPageNo = examPaperTotalPageCount; 495 | } 496 | } 497 | await waitingDependStartTime(startTime); 498 | } 499 | 500 | //获取指定页数的专项答题列表 501 | function getExamPaperByPageNo(examPaperPageNoParam) { 502 | return new Promise(function (resolve) { 503 | $.ajax({ 504 | type: "GET", 505 | url: ExamPaperListUrl.replace("{pageNo}", examPaperPageNoParam), 506 | xhrFields: { 507 | withCredentials: true //如果没有这个请求失败 508 | }, 509 | dataType: "json", 510 | success: function (data) { 511 | data = decodeURIComponent(escape(window.atob(data.data_str.replace(/-/g, "+").replace(/_/g, "/")))); 512 | //JSON格式化 513 | data = JSON.parse(data); 514 | resolve(data); 515 | }, 516 | error: function () { 517 | resolve(new Array()); 518 | } 519 | }); 520 | }) 521 | } 522 | 523 | //查询专项答题列表看看还有没有没做过的,有则返回id 524 | async function findExamPaper() { 525 | var continueFind = true; 526 | var examPaperId = null; 527 | console.log("初始化专项答题属性"); 528 | await InitExamPaperAttr(); 529 | console.log("正在寻找未完成的专项答题"); 530 | while (continueFind) { 531 | let startTime = Date.now(); 532 | 533 | await getExamPaperByPageNo(examPaperPageNo).then(async (data) => { 534 | if (data) { 535 | let examPapers = data.list;//获取专项答题的列表 536 | if (examPaperReverse) { 537 | // 若开启逆序答题, 则反转专项答题列表 538 | console.log("专项答题,开启逆序模式,从最早的题目开始答题"); 539 | examPapers.reverse(); 540 | } 541 | for (let j = 0; j < examPapers.length; j++) { 542 | //遍历查询有没有没做过的 543 | if (examPapers[j].status != 2) {//status: 1为"开始答题" , 2为"重新答题" 544 | //如果不是"重新答题",则可以做 545 | examPaperId = examPapers[j].id; 546 | continueFind = false; 547 | break; 548 | } 549 | } 550 | if (!continueFind) { 551 | } else { 552 | //增加页码 (若开启逆序翻页, 则减少页码) 553 | examPaperPageNo += examPaperReverse ? -1 : 1; 554 | if (examPaperTotalPageCount == null 555 | || examPaperPageNo > examPaperTotalPageCount 556 | || examPaperPageNo < 1) { 557 | //已经找完所有页码,还是没找到,不再继续查找 558 | continueFind = false; 559 | } 560 | } 561 | } else { 562 | continueFind = false; 563 | } 564 | //fix code = 429 565 | await waitingDependStartTime(startTime); 566 | }) 567 | } 568 | return examPaperId; 569 | } 570 | 571 | //做专项答题 572 | function doExamPaper() { 573 | return new Promise(function (resolve) { 574 | //查找有没有没做过的专项答题,有则返回ID 575 | findExamPaper().then(examPaperId => { 576 | if (examPaperId != null) { 577 | console.log("正在做专项答题") 578 | let newPage = GM_openInTab(ExamPaperUrl.replace("{id}", examPaperId), { active: true, insert: true, setParent: true }); 579 | let doing = setInterval(function () { 580 | if (newPage.closed) { 581 | clearInterval(doing);//停止定时器 582 | resolve('done'); 583 | } 584 | }, 1000); 585 | } else { 586 | console.log("没有找到未完成的专项答题,跳过") 587 | resolve('noTest'); 588 | } 589 | }); 590 | }) 591 | } 592 | 593 | //初始化每周答题总页数属性 594 | async function InitExamWeeklyAttr() { 595 | let startTime = Date.now(); 596 | var data = await getExamWeeklyByPageNo(1); // 默认从第一页获取全部页属性 597 | if (data) { 598 | // 初始化总页码 599 | examWeeklyTotalPageCount = data.totalPageCount; 600 | // 若每周答题逆序, 则从最后一页开始 601 | if (examWeeklyReverse) { 602 | examWeeklyPageNo = examWeeklyTotalPageCount; 603 | } 604 | } 605 | await waitingDependStartTime(startTime); 606 | } 607 | 608 | //获取指定页数的每周答题列表 609 | function getExamWeeklyByPageNo(examWeeklyPageNoParam) { 610 | return new Promise(function (resolve) { 611 | $.ajax({ 612 | type: "GET", 613 | url: ExamWeeklyListUrl.replace("{pageNo}", examWeeklyPageNoParam), 614 | xhrFields: { 615 | withCredentials: true //如果没有这个请求失败 616 | }, 617 | dataType: "json", 618 | success: function (data) { 619 | data = decodeURIComponent(escape(window.atob(data.data_str.replace(/-/g, "+").replace(/_/g, "/")))); 620 | //JSON格式化 621 | data = JSON.parse(data); 622 | resolve(data); 623 | }, 624 | error: function () { 625 | resolve(new Array()); 626 | } 627 | }); 628 | }) 629 | } 630 | 631 | //查询每周答题列表看看还有没有没做过的,有则返回id 632 | async function findExamWeekly() { 633 | var continueFind = true; 634 | var examWeeklyId = null; 635 | console.log("初始化每周答题"); 636 | await InitExamWeeklyAttr(); 637 | console.log("正在寻找未完成的每周答题"); 638 | while (continueFind) { 639 | let startTime = Date.now(); 640 | await getExamWeeklyByPageNo(examWeeklyPageNo).then(async (data) => { 641 | if (data) { 642 | if (examWeeklyReverse) { 643 | // 若开启逆序答题, 则反转列表 644 | console.log("每周答题,开启逆序模式,从最早的题目开始答题"); 645 | data.list.reverse(); 646 | } 647 | for (let i = 0; i < data.list.length; i++) { 648 | let examWeeks = data.list[i].practices;//获取每周的测试列表 649 | if (examWeeklyReverse) { 650 | // 若开启逆序, 则反转每周的测试列表 651 | examWeeks.reverse(); 652 | } 653 | for (let j = 0; j < examWeeks.length; j++) { 654 | //遍历查询有没有没做过的 655 | if (examWeeks[j].status != 2) {//status: 1为"开始答题" , 2为"重新答题" 656 | //如果不是"重新答题",则可以做 657 | examWeeklyId = examWeeks[j].id; 658 | continueFind = false; 659 | break; 660 | } 661 | } 662 | if (!continueFind) { 663 | //如果已经找到了,则退出循环 664 | break; 665 | } 666 | } 667 | if (!continueFind) { 668 | } else { 669 | //增加页码 670 | examWeeklyPageNo += examWeeklyReverse ? -1 : 1; 671 | if (examWeeklyTotalPageCount == null 672 | || examWeeklyPageNo > examWeeklyTotalPageCount 673 | || examWeeklyPageNo < 1) { 674 | //已经找完所有页码,还是没找到,不再继续查找 675 | continueFind = false; 676 | } 677 | } 678 | } else { 679 | continueFind = false; 680 | } 681 | 682 | //fix code = 429 683 | await waitingDependStartTime(startTime); 684 | }) 685 | } 686 | return examWeeklyId; 687 | } 688 | //做每周答题 689 | function doExamWeekly() { 690 | return new Promise(function (resolve) { 691 | //查找有没有没做过的每周测试,有则返回ID 692 | //examWeeklyId = 147;//测试题目 693 | findExamWeekly().then(examWeeklyId => { 694 | if (examWeeklyId != null) { 695 | console.log("正在做每周答题") 696 | let newPage = GM_openInTab(ExamWeeklyUrl.replace("{id}", examWeeklyId), { active: true, insert: true, setParent: true }); 697 | let doing = setInterval(function () { 698 | if (newPage.closed) { 699 | clearInterval(doing);//停止定时器 700 | resolve('done'); 701 | } 702 | }, 1000); 703 | } else { 704 | console.log("没有找到未完成的每周答题,跳过") 705 | resolve('noTest'); 706 | } 707 | }); 708 | }) 709 | } 710 | //获取答题按钮 711 | function getNextButton() { 712 | return new Promise(function (resolve) { 713 | let nextInterVal = setInterval(() => { 714 | let nextAll = document.querySelectorAll(".ant-btn"); 715 | let next = nextAll[0]; 716 | if (nextAll.length == 2) { 717 | next = nextAll[1]; 718 | } 719 | if (next.textContent) { 720 | clearInterval(nextInterVal);//停止定时器 721 | resolve(next); 722 | } 723 | }, 800); 724 | }) 725 | } 726 | //暂停锁 727 | function doingPause() { 728 | return new Promise(function (resolve) { 729 | let doing = setInterval(function () { 730 | if (!pause) { 731 | clearInterval(doing);//停止定时器 732 | resolve('done'); 733 | } 734 | console.log("等待") 735 | }, 500); 736 | }) 737 | } 738 | //答题过程(整合) 739 | async function doingExam() { 740 | let nextButton = null; 741 | let qNum = 0;//题号,第一题从0开始算 742 | let shouldSaveAnswer = false; 743 | while (true) { 744 | //先等等再开始做题 745 | await waitRandomBetween(2, 5); 746 | await doingPause(); 747 | nextButton = await getNextButton(); 748 | if (document.getElementsByClassName('nc_iconfont btn_slide')[0] != null) { 749 | dragandDrop(document.getElementsByClassName('nc_iconfont btn_slide')[0], 0, 0, 300); 750 | } 751 | if (nextButton.textContent == "再练一次" || nextButton.textContent == "再来一组" || nextButton.textContent == "查看解析") { 752 | break; 753 | } 754 | try { 755 | document.querySelector(".tips").click(); 756 | } catch (e) { 757 | console.log(e); 758 | } 759 | //所有提示 760 | var allTips = document.querySelectorAll("font[color=red]"); 761 | await waitRandomBetween(2, 3); 762 | //选项按钮 763 | var allbuttons = document.querySelectorAll(".q-answer"); 764 | //获取所有填空 765 | var blanks = document.querySelectorAll("input[type=text][class=blank]"); 766 | try { 767 | //获取问题类型 768 | var questionType = document.querySelector(".q-header").textContent; 769 | questionType = questionType.substr(0, 3) 770 | } catch (e) { 771 | } 772 | var results = []; 773 | switch (questionType) { 774 | case "填空题": { 775 | //第几个填空 776 | var inputBubblesEvent = new Event('input', { bubbles: true }); 777 | if (blanks.length > 1) {//如果有多个填空 778 | if (allTips.length == 0) {//如果没有提示,先获取看看有没有答案 779 | try {//尝试点击视频播放按钮,播不播都没关系 780 | document.getElementsByClassName("outter")[0].click(); 781 | } catch (e) { } 782 | //生成秘钥 783 | let key = getKey(); 784 | //尝试获取答案 785 | let answerData = await getAnswer(key); 786 | if (answerData.status == 0 || answerData == "error") {//没有答案 787 | for (let i = 0; i < blanks.length; i++) {//没答案,随便填点东西 788 | blanks[i].setAttribute("value", i); 789 | //必须要阻止事件,不然无效 790 | blanks[i].dispatchEvent(inputBubblesEvent); 791 | } 792 | shouldSaveAnswer = true;//答完保存答案 793 | } else {//获取到了答案 794 | //格式化 795 | answerData = JSON.parse(answerData.data.txt_content); 796 | answerData = answerData[0].content; 797 | //因为有多个空,所以有多个答案,先切割 798 | answerData = answerData.split(";"); 799 | for (let i = 0; i < answerData.length; i++) {//将答案填入 800 | blanks[i].setAttribute("value", answerData[i]); 801 | blanks[i].dispatchEvent(inputBubblesEvent); 802 | } 803 | } 804 | } else if (allTips.length == blanks.length) { 805 | //如果填空数量和提示数量一致 806 | for (let i = 0; i < allTips.length; i++) { 807 | //将答案填写到对应的空中 808 | let answer = allTips[i].textContent; 809 | if (answer && answer.length > 0) { 810 | blanks[i].setAttribute("value", answer); 811 | blanks[i].dispatchEvent(inputBubblesEvent); 812 | } else { 813 | //发生了错误,只好随便填一下 814 | blanks[i].setAttribute("value", i); 815 | blanks[i].dispatchEvent(inputBubblesEvent); 816 | } 817 | } 818 | } else if (allTips.length > blanks.length) { 819 | //若提示数量比填空的数量多 820 | //直接将所有答案整合填进去 821 | let answer = ""; 822 | for (let i = 0; i < allTips.length; allTips++) { 823 | answer += allTips[i].textContent(); 824 | } 825 | for (let j = 0; j < blanks.length; j++) { 826 | blanks[j].setAttribute("value", answer); 827 | blanks[j].dispatchEvent(inputBubblesEvent); 828 | } 829 | } else { 830 | //一般不会跑到这,如果到这了输出一下,表示惊讶 831 | console.log("居然跑到了这里") 832 | } 833 | } else if (blanks.length == 1) {//只有一个空,直接把所有tips合并。 834 | let answer = ""; 835 | if (allTips.length != 0) {//如果有提示 836 | for (let i = 0; i < allTips.length; i++) { 837 | answer += allTips[i].textContent; 838 | } 839 | } else { 840 | try {//尝试点击视频播放按钮,不过播不播都没关系 841 | document.querySelector('video').play(); 842 | } catch (e) { } 843 | let key = getKey(); 844 | let answerData = await getAnswer(key); 845 | if (answerData.status == 0 || answerData == "error") { 846 | //没有获取到答案 847 | answer = "不知道"; 848 | //没有其他人做过这道视频题,所以需要答完保存答案,这样其他人遇到就能做对 849 | shouldSaveAnswer = true; 850 | } else { 851 | //有答案 852 | answerData = JSON.parse(answerData.data.txt_content); 853 | answer = answerData[0].content; 854 | } 855 | } 856 | blanks[0].setAttribute("value", answer); 857 | blanks[0].dispatchEvent(inputBubblesEvent); 858 | break; 859 | } 860 | else { 861 | //怕有没空白的情况。 862 | } 863 | break; 864 | } 865 | case "多选题": { 866 | results = []; 867 | let hasButton = false; 868 | for (let i = 0; i < allTips.length; i++) { 869 | let tip = allTips[i]; 870 | let answer = tip.textContent; 871 | if (answer && answer.length > 0) { 872 | for (let j = 0; j < allbuttons.length; j++) { 873 | //获取按钮 874 | let selectButton = allbuttons[j]; 875 | //获取按钮的上的答案 876 | let buttonAnswer = selectButton.textContent; 877 | if (buttonAnswer == answer || buttonAnswer.indexOf(answer) != -1 || answer.indexOf(buttonAnswer) != -1) { 878 | hasButton = true; 879 | if (!$(selectButton).hasClass("chosen")) { 880 | selectButton.click(); 881 | } 882 | break; 883 | } 884 | } 885 | } 886 | } 887 | if (!hasButton) { 888 | allbuttons[0].click(); 889 | } 890 | break; 891 | } 892 | case "单选题": { 893 | let results = []; 894 | let answer = ""; 895 | for (let i = 0; i < allTips.length; i++) { 896 | answer += allTips[i].textContent; 897 | } 898 | if (answer && answer.length > 0) { 899 | let hasButton = false; 900 | for (let i = 0; i < allbuttons.length; i++) { 901 | let radioButton = allbuttons[i]; 902 | let buttonAnswer = radioButton.textContent; 903 | //对比答案 904 | if (buttonAnswer == answer || buttonAnswer.indexOf(answer) != -1 || answer.indexOf(buttonAnswer) != -1) { 905 | hasButton = true; 906 | radioButton.click(); 907 | break; 908 | } 909 | } 910 | if (!hasButton) { 911 | //没找到按钮,随便选一个 912 | allbuttons[0].click(); 913 | } 914 | } else { 915 | //没答案,随便选一个 916 | try { 917 | allbuttons[0].click(); 918 | } catch(e) { 919 | console.log(e); 920 | } 921 | } 922 | break; 923 | } 924 | default: 925 | break; 926 | } 927 | qNum++; 928 | nextButton = await getNextButton(); 929 | if (nextButton.textContent != "再练一次" && nextButton.textContent != "再来一组" && nextButton.textContent != "查看解析") { 930 | nextButton.click(); 931 | if (shouldSaveAnswer) {//如果应该保存答案 932 | let key = getKey();//获取key 933 | let answerTemp = document.getElementsByClassName("answer")[0].innerText; 934 | let reg = new RegExp(' ', "g") 935 | let answer = ""; 936 | try {//从字符串中拿出答案 937 | answer = answerTemp.split(":")[1]; 938 | answer = answer.replace(reg, ";"); 939 | } catch (e) { 940 | answer = answerTemp; 941 | } 942 | await saveAnswer(key, answer); 943 | shouldSaveAnswer = false; 944 | } 945 | } else { 946 | //已经做完,跳出循环 947 | break; 948 | } 949 | } 950 | closeWin(); 951 | } 952 | //获取关键字 953 | function getKey() { 954 | //获取题目的文本内容 955 | let key = document.getElementsByClassName("q-body")[0].innerText; 956 | //外部引用md5加密 957 | key = md5(key); 958 | console.log(key) 959 | return key; 960 | } 961 | //保存答案 962 | function saveAnswer(key, value) { 963 | return new Promise(function (resolve) { 964 | value = [{ "title": key, "content": value }]; 965 | value = JSON.stringify(value); 966 | $.ajax({ 967 | type: "POST", 968 | url: AnswerSaveUrl, 969 | data: { 970 | txt_name: key, 971 | txt_content: value, 972 | password: "", 973 | v_id: "" 974 | }, 975 | dataType: "json", 976 | success: function (data) { 977 | resolve(data); 978 | }, 979 | error: function () { 980 | resolve("error"); 981 | } 982 | }); 983 | }) 984 | } 985 | //获取答案 986 | function getAnswer(key) { 987 | return new Promise(function (resolve) { 988 | $.ajax({ 989 | type: "POST", 990 | url: AnswerDetailUrl, 991 | data: { 992 | txt_name: key, 993 | password: "" 994 | }, 995 | dataType: "json", 996 | success: function (data) { 997 | resolve(data); 998 | }, 999 | error: function () { 1000 | resolve("error"); 1001 | } 1002 | }); 1003 | }) 1004 | } 1005 | //去除答题验证 1006 | function cancelVerify() { 1007 | try { 1008 | let verifyBox = document.getElementById("nc_mask"); 1009 | verifyBox.id = "egg_nc_mask"; 1010 | verifyBox.innerHTML = ""; 1011 | verifyBox.remove(); 1012 | } catch (e) { 1013 | console.log("去除验证失败"); 1014 | } 1015 | } 1016 | //查询今日完成情况 1017 | function getToday() { 1018 | return new Promise(function (resolve) { 1019 | $.ajax({ 1020 | type: "GET", 1021 | url: SearchSocreUrl, 1022 | xhrFields: { 1023 | withCredentials: true //如果没有这个请求失败 1024 | }, 1025 | dataType: "json", 1026 | success: function (temp) { 1027 | resolve(temp.data.taskProgress); 1028 | }, 1029 | error: function () { 1030 | resolve(new Array()); 1031 | } 1032 | }); 1033 | }) 1034 | } 1035 | //初始化配置 1036 | function initSetting() { 1037 | try { 1038 | let settingTemp = JSON.parse(GM_getValue('studySetting')); 1039 | if (settingTemp != null && Object.prototype.toString.call(settingTemp) === '[object Object]') { 1040 | // 增加判断是否为旧数组类型缓存 1041 | settings = settingTemp; 1042 | } else { 1043 | settings = JSON.parse(JSON.stringify(settingsDefault)); 1044 | } 1045 | } catch (e) { 1046 | //没有则直接初始化 1047 | settings = JSON.parse(JSON.stringify(settingsDefault)); 1048 | } 1049 | } 1050 | //创建“手动答题”按钮 1051 | function createManualButton() { 1052 | let title = document.getElementsByClassName("title")[0]; 1053 | let manualButton = document.createElement("button"); 1054 | manualButton.setAttribute("id", "manualButton"); 1055 | manualButton.innerText = "关闭自动答题"; 1056 | manualButton.className = "egg_auto_btn"; 1057 | //添加事件监听 1058 | try {// Chrome、FireFox、Opera、Safari、IE9.0及其以上版本 1059 | manualButton.addEventListener("click", clickManualButton, false); 1060 | } catch (e) { 1061 | try {// IE8.0及其以下版本 1062 | manualButton.attachEvent('onclick', clickManualButton); 1063 | } catch (e) {// 早期浏览器 1064 | console.log("不学习何以强国error: 手动答题按钮绑定事件失败") 1065 | } 1066 | } 1067 | //插入节点 1068 | title.parentNode.insertBefore(manualButton, title.nextSibling); 1069 | } 1070 | //点击手动学习按钮 1071 | function clickManualButton() { 1072 | let manualButton = document.getElementById("manualButton"); 1073 | if (manualButton.innerText == "关闭自动答题") { 1074 | manualButton.innerText = "开启自动答题"; 1075 | manualButton.className = "egg_manual_btn"; 1076 | pause = true; 1077 | } else { 1078 | manualButton.innerText = "关闭自动答题"; 1079 | manualButton.className = "egg_auto_btn"; 1080 | pause = false; 1081 | } 1082 | } 1083 | //创建“开始学习”按钮和配置 1084 | function createStartButton() { 1085 | let base = document.createElement("div"); 1086 | var baseInfo = ""; 1087 | baseInfo += "