66// @author techxuexi ,荷包蛋。
77// @match https://www.xuexi.cn
88// @match https://www.xuexi.cn/*
9+ // @match https://pc.xuexi.cn/points/login.html*
910// @match https://pc.xuexi.cn/points/exam-practice.html
1011// @match https://pc.xuexi.cn/points/exam-weekly-detail.html?id=*
1112// @match https://pc.xuexi.cn/points/exam-weekly-list.html
@@ -55,7 +56,16 @@ var news = [];
5556var videoNum = 6 ;
5657var videos = [ ] ;
5758//配置
58- var settings = [ ] ;
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+ }
5969var pause = false ; //是否暂停答题
6070//每周答题当前页码
6171var examWeeklyPageNo = 1 ;
@@ -75,15 +85,35 @@ const ratelimitms = 3000;
7585//默认情况下, chrome 只允许 window.close 关闭 window.open 打开的窗口,所以我们就要用window.open命令,在原地网页打开自身窗口再关上,就可以成功关闭了
7686function closeWin ( ) {
7787 try {
78- window . opener = window ;
79- var win = window . open ( "" , "_self" ) ;
80- win . close ( ) ;
81- top . close ( ) ;
88+ window . opener = window ;
89+ var win = window . open ( "" , "_self" ) ;
90+ win . close ( ) ;
91+ top . close ( ) ;
8292 } catch ( e ) {
83- }
93+ }
8494
8595}
8696
97+ /**
98+ * 随机等待最小到最大之间几秒, 需要await
99+ * @param {number } minSecond 最短时长
100+ * @param {number } MaxSecond 最长时长
101+ * @returns Promise
102+ */
103+ function waitRandomBetween ( minSecond = 2 , MaxSecond = 5 ) {
104+ if ( MaxSecond <= minSecond ) {
105+ MaxSecond = minSecond + 3
106+ }
107+
108+ let waitTime = Math . floor ( Math . random ( ) * ( MaxSecond * 1000 - minSecond * 1000 ) + minSecond * 1000 )
109+ return new Promise ( ( resolve , reject ) => {
110+ setTimeout ( ( ) => {
111+ console . log ( `随机等待${ waitTime / 1000 } 秒` )
112+ resolve ( )
113+ } , waitTime )
114+ } )
115+ }
116+
87117$ ( document ) . ready ( function ( ) {
88118 let url = window . location . href ;
89119 if ( url == "https://www.xuexi.cn" || url == "https://www.xuexi.cn/" || url == "https://www.xuexi.cn/index.html" ) {
@@ -96,7 +126,13 @@ $(document).ready(function () {
96126 createStartButton ( ) ;
97127 }
98128 } , 800 ) ;
99- } else if ( typeof GM_getValue ( "readingUrl" ) != 'object' && url == GM_getValue ( "readingUrl" ) ) {
129+ } else if ( url . indexOf ( "login.html" ) !== - 1 ) {
130+ console . log ( "检测到登录页" )
131+ setTimeout ( ( ) => {
132+ window . scrollTo ( 0 , 1000 ) ;
133+ } , 500 ) ;
134+ }
135+ else if ( typeof GM_getValue ( "readingUrl" ) != 'object' && url == GM_getValue ( "readingUrl" ) ) {
100136 try {
101137 let settingTemp = JSON . parse ( GM_getValue ( 'studySetting' ) ) ;
102138 if ( ! settingTemp [ 7 ] ) {
@@ -170,48 +206,48 @@ function getVideoTag() {
170206 let video = null ;
171207 let pauseButton = null ;
172208 var u = navigator . userAgent ;
173- if ( u . indexOf ( 'Mac' ) > - 1 ) { //Mac
174- if ( iframe != null && iframe . innerHTML ) {
175- //如果有iframe,说明外面的video标签是假的
176- video = iframe . contentWindow . document . getElementsByTagName ( "video" ) [ 0 ] ;
177- pauseButton = iframe . contentWindow . document . getElementsByClassName ( "prism-play-btn" ) [ 0 ] ;
178- } else {
179- //否则这个video标签是真的
180- video = document . getElementsByTagName ( "video" ) [ 0 ] ;
181- pauseButton = document . getElementsByClassName ( "prism-play-btn" ) [ 0 ] ;
182- }
183- return {
184- "video" : video ,
185- "pauseButton" : pauseButton
186- }
187- }
188- else {
189- if ( iframe ) {
190- //如果有iframe,说明外面的video标签是假的
191- video = iframe . contentWindow . document . getElementsByTagName ( "video" ) [ 0 ] ;
192- pauseButton = iframe . contentWindow . document . getElementsByClassName ( "prism-play-btn" ) [ 0 ] ;
193- } else {
194- //否则这个video标签是真的
195- video = document . getElementsByTagName ( "video" ) [ 0 ] ;
196- pauseButton = document . getElementsByClassName ( "prism-play-btn" ) [ 0 ] ;
197- }
198- return {
199- "video" : video ,
200- "pauseButton" : pauseButton
209+ if ( u . indexOf ( 'Mac' ) > - 1 ) { //Mac
210+ if ( iframe != null && iframe . innerHTML ) {
211+ //如果有iframe,说明外面的video标签是假的
212+ video = iframe . contentWindow . document . getElementsByTagName ( "video" ) [ 0 ] ;
213+ pauseButton = iframe . contentWindow . document . getElementsByClassName ( "prism-play-btn" ) [ 0 ] ;
214+ } else {
215+ //否则这个video标签是真的
216+ video = document . getElementsByTagName ( "video" ) [ 0 ] ;
217+ pauseButton = document . getElementsByClassName ( "prism-play-btn" ) [ 0 ] ;
218+ }
219+ return {
220+ "video" : video ,
221+ "pauseButton" : pauseButton
222+ }
201223 }
224+ else {
225+ if ( iframe ) {
226+ //如果有iframe,说明外面的video标签是假的
227+ video = iframe . contentWindow . document . getElementsByTagName ( "video" ) [ 0 ] ;
228+ pauseButton = iframe . contentWindow . document . getElementsByClassName ( "prism-play-btn" ) [ 0 ] ;
229+ } else {
230+ //否则这个video标签是真的
231+ video = document . getElementsByTagName ( "video" ) [ 0 ] ;
232+ pauseButton = document . getElementsByClassName ( "prism-play-btn" ) [ 0 ] ;
233+ }
234+ return {
235+ "video" : video ,
236+ "pauseButton" : pauseButton
237+ }
202238 }
203239}
204240
205241//读新闻或者看视频
206242//type:0为新闻,1为视频
207243async function reading ( type ) {
208244 //看文章或者视频
209- var time = 1 ;
210- if ( type == 0 ) {
211- time = parseInt ( Math . random ( ) * ( 100 - 80 + 1 ) + 80 , 10 ) ; //80-100秒后关闭页面,看文章
212- } else {
213- time = parseInt ( Math . random ( ) * ( 250 - 230 + 1 ) + 230 , 10 ) ; //230-250秒后关闭页面,看视频
214- }
245+ var time = 1 ;
246+ if ( type == 0 ) {
247+ time = parseInt ( Math . random ( ) * ( 100 - 80 + 1 ) + 80 , 10 ) ; //80-100秒后关闭页面,看文章
248+ } else {
249+ time = parseInt ( Math . random ( ) * ( 250 - 230 + 1 ) + 230 , 10 ) ; //230-250秒后关闭页面,看视频
250+ }
215251 let firstTime = time - 2 ;
216252 let secendTime = 12 ;
217253 let scrollLength = document . body . scrollHeight / 2 ;
@@ -285,7 +321,7 @@ async function readNews() {
285321 console . log ( "正在看第" + ( i + 1 ) + "个新闻" ) ;
286322 let newPage = GM_openInTab ( news [ i ] . url , { active : true , insert : true , setParent : true } ) ;
287323 await waitingClose ( newPage ) ;
288- await waitingTime ( 1500 ) ;
324+ await waitRandomBetween ( 1 , 3 ) ;
289325 }
290326}
291327//获取新闻列表
@@ -377,7 +413,7 @@ async function watchVideo() {
377413 console . log ( "正在观看第" + ( i + 1 ) + "个视频" ) ;
378414 let newPage = GM_openInTab ( videos [ i ] . url , { active : true , insert : true , setParent : true } )
379415 await waitingClose ( newPage ) ;
380- await waitingTime ( 1500 ) ;
416+ await waitRandomBetween ( 1 , 3 ) ;
381417 }
382418}
383419//做每日答题
@@ -395,10 +431,11 @@ function doExamPractice() {
395431}
396432
397433//fix code = 429
398- async function waitingDependStartTime ( startTime ) {
434+ async function waitingDependStartTime ( startTime ) {
399435 let remainms = Date . now ( ) - startTime ;
400436 if ( remainms < ratelimitms ) {
401- await waitingTime ( ratelimitms - remainms + 1000 )
437+ let second = ( ratelimitms - remainms ) / 1000
438+ await waitRandomBetween ( second + 1 , second + 3 )
402439 }
403440}
404441//初始化专项答题总页数属性
@@ -661,7 +698,7 @@ async function doingExam() {
661698 let shouldSaveAnswer = false ;
662699 while ( true ) {
663700 //先等等再开始做题
664- await waitingTime ( 2500 ) ;
701+ await waitRandomBetween ( 2 , 5 ) ;
665702 await doingPause ( ) ;
666703 nextButton = await getNextButton ( ) ;
667704 if ( nextButton . textContent == "再练一次" || nextButton . textContent == "再来一组" || nextButton . textContent == "查看解析" ) {
@@ -674,7 +711,7 @@ async function doingExam() {
674711 }
675712 //所有提示
676713 var allTips = document . querySelectorAll ( "font[color=red]" ) ;
677- await waitingTime ( 1500 ) ;
714+ await waitRandomBetween ( 2 , 3 ) ;
678715 //选项按钮
679716 var allbuttons = document . querySelectorAll ( ".q-answer" ) ;
680717 //获取所有填空
@@ -926,17 +963,6 @@ function cancelVerify() {
926963 console . log ( "去除验证失败" ) ;
927964 }
928965}
929- //等待时间工具函数
930- function waitingTime ( time ) {
931- if ( ! Number . isInteger ( time ) ) {
932- time = 1000 ;
933- }
934- return new Promise ( resolve => {
935- setTimeout ( function ( ) {
936- resolve ( 'done' ) ;
937- } , time ) ;
938- } ) ;
939- }
940966//查询今日完成情况
941967function getToday ( ) {
942968 return new Promise ( function ( resolve ) {
@@ -960,14 +986,15 @@ function getToday() {
960986function initSetting ( ) {
961987 try {
962988 let settingTemp = JSON . parse ( GM_getValue ( 'studySetting' ) ) ;
963- if ( settingTemp != null ) {
989+ if ( settingTemp != null && Object . prototype . toString . call ( settingTemp ) === '[object Object]' ) {
990+ // 增加判断是否为旧数组类型缓存
964991 settings = settingTemp ;
965992 } else {
966- settings = [ true , true , true , true , true , true , true , false ] ;
993+ settings = JSON . parse ( JSON . stringify ( settingsDefault ) ) ;
967994 }
968995 } catch ( e ) {
969996 //没有则直接初始化
970- settings = [ true , true , true , true , true , true , true , false ] ;
997+ settings = JSON . parse ( JSON . stringify ( settingsDefault ) ) ;
971998 }
972999}
9731000//创建“手动答题”按钮
@@ -1007,7 +1034,10 @@ function clickManualButton() {
10071034function createStartButton ( ) {
10081035 let base = document . createElement ( "div" ) ;
10091036 var baseInfo = "" ;
1010- baseInfo += "<form id=\"settingData\" class=\"egg_menu\" action=\"\" target=\"_blank\" onsubmit=\"return false\"><div class=\"egg_setting_box\"><div class=\"egg_setting_item\"><label>新闻<\/label><input class=\"egg_setting_switch\" type=\"checkbox\" name=\"0\" " + ( settings [ 0 ] ? 'checked' : '' ) + "\/> <\/div> <div class=\"egg_setting_item\"> <label>视频<\/label> <input class=\"egg_setting_switch\" type=\"checkbox\" name=\"1\" " + ( settings [ 1 ] ? 'checked' : '' ) + "\/> <\/div> <div class=\"egg_setting_item\"> <label>每日答题<\/label> <input class=\"egg_setting_switch\" type=\"checkbox\" name=\"6\" " + ( settings [ 6 ] ? 'checked' : '' ) + "\/> <\/div> <div class=\"egg_setting_item\"> <label>每周答题<\/label> <input class=\"egg_setting_switch\" type=\"checkbox\" name=\"2\" " + ( settings [ 2 ] ? 'checked' : '' ) + "\/> <\/div> <div class=\"egg_setting_item\"> <label>专项练习<\/label> <input class=\"egg_setting_switch\" type=\"checkbox\" name=\"5\" " + ( settings [ 5 ] ? 'checked' : '' ) + "\/><\/div><hr \/><div title='Tip:开始学习后,隐藏相关页面和提示(不隐藏答题中的关闭自动答题按钮)' class=\"egg_setting_item\"> <label>运行隐藏<\/label> <input class=\"egg_setting_switch\" type=\"checkbox\" name=\"7\"" + ( settings [ 7 ] ? 'checked' : '' ) + "/></div><a style=\"text-decoration: none;\" title=\"视频不自动播放?点此查看解决办法\" target=\"blank\" href=\"https://docs.qq.com/doc/DZllGcGlJUG1qT3Vx\"><div style=\"color:#5F5F5F;font-size:14px;\" class=\"egg_setting_item\"><label style=\"cursor: pointer;\">视频不自动播放?<\/label><\/div><\/a><\/div><\/form>" ;
1037+ baseInfo += "<form id=\"settingData\" class=\"egg_menu\" action=\"\" target=\"_blank\" onsubmit=\"return false\"><div class=\"egg_setting_box\"><div class=\"egg_setting_item\"><label>新闻<\/label><input class=\"egg_setting_switch\" type=\"checkbox\" name=\"News\" " + ( settings . News ? 'checked' : '' ) + "\/> <\/div> <div class=\"egg_setting_item\"> <label>视频<\/label> <input class=\"egg_setting_switch\" type=\"checkbox\" name=\"Video\" " + ( settings . Video ? 'checked' : '' ) + "\/> <\/div> <div class=\"egg_setting_item\"> <label>每日答题<\/label> <input class=\"egg_setting_switch\" type=\"checkbox\" name=\"ExamPractice\" " + ( settings . ExamPractice ? 'checked' : '' ) + "\/> <\/div> <div class=\"egg_setting_item\"> <label>每周答题<\/label> <input class=\"egg_setting_switch\" type=\"checkbox\" name=\"ExamWeekly\" " + ( settings . ExamWeekly ? 'checked' : '' ) + "\/> <\/div> <div class=\"egg_setting_item\"> <label>专项练习<\/label> <input class=\"egg_setting_switch\" type=\"checkbox\" name=\"ExamPaper\" " + ( settings . ExamPaper ? 'checked' : '' ) + "\/><\/div><hr \/><div title='Tip:开始学习后,隐藏相关页面和提示(不隐藏答题中的关闭自动答题按钮)' class=\"egg_setting_item\"> <label>运行隐藏<\/label> <input class=\"egg_setting_switch\" type=\"checkbox\" name=\"ShowMenu\"" + ( settings . ShowMenu ? 'checked' : '' ) + "/></div>" +
1038+ "<div title='Tip:进入学习首页5秒后自动开始学习' class=\"egg_setting_item\"> <label>自动开始<\/label> <input class=\"egg_setting_switch\" type=\"checkbox\" name=\"AutoStart\"" + ( settings . AutoStart ? 'checked' : '' ) + "/></div>"
1039+ +
1040+ "<a style=\"text-decoration: none;\" title=\"视频不自动播放?点此查看解决办法\" target=\"blank\" href=\"https://docs.qq.com/doc/DZllGcGlJUG1qT3Vx\"><div style=\"color:#5F5F5F;font-size:14px;\" class=\"egg_setting_item\"><label style=\"cursor: pointer;\">视频不自动播放?<\/label><\/div><\/a><\/div><\/form>" ;
10111041 base . innerHTML = baseInfo ;
10121042 let body = document . getElementsByTagName ( "body" ) [ 0 ] ;
10131043 body . append ( base )
@@ -1027,17 +1057,26 @@ function createStartButton() {
10271057 }
10281058 //插入节点
10291059 body . append ( startButton )
1060+
1061+ if ( settings . AutoStart ) {
1062+ setTimeout ( ( ) => {
1063+ if ( startButton . innerText === "开始学习" ) {
1064+ start ( )
1065+ }
1066+ } , 5000 )
1067+ }
10301068}
10311069//保存配置
10321070function saveSetting ( ) {
10331071 let form = document . getElementById ( "settingData" ) ;
10341072 let formData = new FormData ( form ) ;
1035- settings [ 0 ] = ( formData . get ( '0' ) != null ) ;
1036- settings [ 1 ] = ( formData . get ( '1' ) != null ) ;
1037- settings [ 6 ] = ( formData . get ( '6' ) != null ) ;
1038- settings [ 2 ] = ( formData . get ( '2' ) != null ) ;
1039- settings [ 5 ] = ( formData . get ( '5' ) != null ) ;
1040- settings [ 7 ] = ( formData . get ( '7' ) != null ) ; //运行时是否要隐藏
1073+ settings . News = ( formData . get ( 'News' ) != null ) ;
1074+ settings . Video = ( formData . get ( 'Video' ) != null ) ;
1075+ settings . ExamPractice = ( formData . get ( 'ExamPractice' ) != null ) ;
1076+ settings . ExamWeekly = ( formData . get ( 'ExamWeekly' ) != null ) ;
1077+ settings . ExamPaper = ( formData . get ( 'ExamPaper' ) != null ) ;
1078+ settings . ShowMenu = ( formData . get ( 'ShowMenu' ) != null ) ; //运行时是否要隐藏
1079+ settings . AutoStart = ( formData . get ( 'AutoStart' ) != null ) ; //是否自动启动
10411080 GM_setValue ( 'studySetting' , JSON . stringify ( settings ) ) ;
10421081}
10431082//是否显示目录
@@ -1059,7 +1098,7 @@ async function start() {
10591098 startButton . innerText = "正在学习" ;
10601099 startButton . style . cursor = "default" ;
10611100 startButton . setAttribute ( "disabled" , true ) ;
1062- if ( settings [ 7 ] ) {
1101+ if ( settings . ShowMenu ) {
10631102 showMenu ( false ) ;
10641103 }
10651104 let taskProgress = null ;
@@ -1073,7 +1112,7 @@ async function start() {
10731112 console . log ( "开始学习" )
10741113
10751114 //检查新闻
1076- if ( settings [ 0 ] && taskProgress [ 0 ] . currentScore != taskProgress [ 0 ] . dayMaxScore ) {
1115+ if ( settings . News && taskProgress [ 0 ] . currentScore != taskProgress [ 0 ] . dayMaxScore ) {
10771116 tasks [ 0 ] = false ; //只要还有要做的,就当做没完成
10781117 newsNum = taskProgress [ 0 ] . dayMaxScore - taskProgress [ 0 ] . currentScore ; //还需要看多少个新闻
10791118 console . log ( "1.看新闻" ) ;
@@ -1085,7 +1124,7 @@ async function start() {
10851124 //检查视频
10861125 let temp = parseInt ( taskProgress [ 1 ] . dayMaxScore - taskProgress [ 1 ] . currentScore ) ;
10871126 let temp2 = parseInt ( taskProgress [ 3 ] . dayMaxScore - taskProgress [ 3 ] . currentScore ) ;
1088- if ( settings [ 1 ] && ( temp != 0 || temp2 != 0 ) ) {
1127+ if ( settings . Video && ( temp != 0 || temp2 != 0 ) ) {
10891128 tasks [ 1 ] = false ; //只要还有要做的,就当做没完成
10901129 videoNum = temp > temp2 ? temp : temp2 ; //还需要看多少个视频
10911130 console . log ( "2.看视频" ) ;
@@ -1095,7 +1134,7 @@ async function start() {
10951134 }
10961135
10971136 //检查每日答题
1098- if ( settings [ 6 ] && taskProgress [ 6 ] . currentScore != taskProgress [ 6 ] . dayMaxScore ) {
1137+ if ( settings . ExamPractice && taskProgress [ 6 ] . currentScore != taskProgress [ 6 ] . dayMaxScore ) {
10991138 tasks [ 2 ] = false ; //只要还有要做的,就当做没完成
11001139 console . log ( "3.做每日答题" ) ;
11011140 await doExamPractice ( ) ;
@@ -1104,7 +1143,7 @@ async function start() {
11041143 }
11051144
11061145 //检查每周答题
1107- if ( settings [ 2 ] && taskProgress [ 2 ] . currentScore == 0 ) {
1146+ if ( settings . ExamWeekly && taskProgress [ 2 ] . currentScore == 0 ) {
11081147 tasks [ 3 ] = false ; //只要还有要做的,就当做没完成
11091148 console . log ( "4.做每周答题" ) ;
11101149 let result = await doExamWeekly ( ) ;
@@ -1117,7 +1156,7 @@ async function start() {
11171156 }
11181157
11191158 //检查专项练习
1120- if ( settings [ 5 ] && taskProgress [ 5 ] . currentScore == 0 ) {
1159+ if ( settings . ExamPaper && taskProgress [ 5 ] . currentScore == 0 ) {
11211160 tasks [ 4 ] = false ; //只要还有要做的,就当做没完成
11221161 console . log ( "5.做专项练习" ) ;
11231162 let result = await doExamPaper ( ) ;
@@ -1142,12 +1181,19 @@ async function start() {
11421181 console . log ( "已完成" )
11431182 startButton . innerText = "已完成" ;
11441183 startButton . style . color = "#c7c7c7" ;
1145- if ( settings [ 7 ] ) {
1184+ if ( settings . ShowMenu ) {
11461185 showMenu ( )
11471186 }
11481187 } else {
1149- //提醒登录
1150- alert ( "请先登录" ) ;
1188+ //提醒登录
1189+ // alert("请先登录");
1190+
1191+ //修改为跳转到登陆页
1192+ let loggedButton = document . querySelectorAll ( "a[class='icon login-icon']" ) [ 0 ] ;
1193+ loggedButton . click ( )
1194+ setTimeout ( ( ) => {
1195+ closeWin ( )
1196+ } , 2000 ) ;
11511197 }
11521198 return false ;
11531199}
0 commit comments