zjy_002

this is a script for automatically refreshing courseware.

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.sleazyfork.org/scripts/433074/974435/zjy_002.js

  1. // ==UserScript==
  2. // @name zjy_002
  3. // @namespace http://xg.com
  4. // @version 1.0
  5. // @description this is a script for automatically refreshing courseware.
  6. // @author XG
  7. // @run-at document-end
  8. // @grant none
  9. // @License MIT
  10. // ==/UserScript==
  11. const sk = {
  12. hrefs: [],
  13. // The progress of TAB B on the current page
  14. progressSpans: [],
  15. arrowDown: 'am-icon-caret-down',
  16. // PPT viewing speed
  17. pptSpeedL: [1, 8, 15, 40],
  18. pptSpeedR: [4, 15, 40, 100],
  19. speedName: ['低速', '正常', '高速', '光速'],
  20. // Video viewing speed
  21. videoSpeedL: [2, 8, 10, 100],
  22. videoSpeedR: [6, 10, 30, 500],
  23. // Courseware interval time
  24. waitTimeL: [60, 20, 10, 5],
  25. waitTimeR: [120, 30, 15, 10],
  26. // Input viewing speed
  27. speed: '',
  28. zjsqInfoDom: '',
  29. currentLessonIndex: 0,
  30. lessonFailed: 0,
  31. totalStudyTime: 0,
  32. losingStreak: 0,
  33. stopFlag: false,
  34. totalLessons: 0,
  35. httpData: '',
  36.  
  37. main: function () {
  38. var {
  39. isVip,
  40. isOver,
  41. nowFree
  42. } = JSON.parse(localStorage.getItem("httpData"));
  43. if (!isVip == false && !nowFree == false) {
  44. alert('Please make an illegal call!');
  45. return;
  46. }
  47. try {
  48. // fetch global datas
  49. sk.log('当前选择为:' + sk.speedName[sk.speed]);
  50. sk.log('开始获取课件数据!');
  51. sk.globalDataHander();
  52. // get datas
  53. setTimeout(() => {
  54. sk.log('正在准备刷取学习进度及时间的必要信息...');
  55. // started
  56. sk.directoryDataRequester(0);
  57. }, 12000);
  58. return 'started';
  59. } catch (e) {
  60. sk.log('主程序异常,可能无法正常工作:' + e);
  61. };
  62. },
  63.  
  64. log: function (text) {
  65. const info = `[${new Date().format()}] ${text}`;
  66. console.log(info);
  67. sk.zjsqInfoDom.append(info + '<br>');
  68. var ele = sk.zjsqInfoDom[0];
  69. ele.scrollTop = ele.scrollHeight + 999
  70. },
  71.  
  72. //Get random number
  73. getRndInteger: function (min, max) {
  74. return Math.floor(Math.random() * (max - min + 1)) + min;
  75. },
  76.  
  77. initial: function () {
  78.  
  79. function makeDivDraggable(id) {
  80. var Drag = document.getElementById(id);
  81. Drag.onmousedown = function (event) {
  82. var ev = event || window.event;
  83. event.stopPropagation();
  84. var disX = ev.clientX - Drag.offsetLeft;
  85. var disY = ev.clientY - Drag.offsetTop;
  86. document.onmousemove = function (event) {
  87. var ev = event || window.event;
  88. Drag.style.left = ev.clientX - disX + 'px';
  89. Drag.style.top = ev.clientY - disY + 'px';
  90. Drag.style.cursor = 'move';
  91. }
  92. }
  93. Drag.onmouseup = function () {
  94. document.onmousemove = null;
  95. this.style.cursor = 'default';
  96. }
  97. };
  98.  
  99. try {
  100. console.log('正在初始化...请勿随意操作页面...');
  101. Date.prototype.format = function () {
  102. var format = 'yyyy-MM-dd HH:mm:ss';
  103. var o = {
  104. 'M+': this.getMonth() + 1, // month
  105. 'd+': this.getDate(), // day
  106. 'H+': this.getHours(), // hour
  107. 'm+': this.getMinutes(), // minute
  108. 's+': this.getSeconds(), // second
  109. 'q+': Math.floor((this.getMonth() + 3) / 3), // quarter
  110. S: this.getMilliseconds() // millisecond
  111. };
  112.  
  113. if (/(y+)/.test(format)) {
  114. format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
  115. };
  116.  
  117. for (var k in o) {
  118. if (new RegExp('(' + k + ')').test(format)) {
  119. format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
  120. };
  121. };
  122. return format;
  123. }
  124. //$('<style></style>').text(getText(zjsqCss)).appendTo($('head'));
  125. // $('body').append(getText(zjsqHtml))
  126. var mainView = document.createElement("div");
  127. mainView.setAttribute('style', 'background-color: green')
  128. mainView.innerHTML = '<div id="zjyInfoBoxId" class="zjyInfoBox"><div class="zjyTitle"><h3 style="text-align: center">职教云刷课X.G防封版</h3></div><div id="zjyInfo">欢迎使用X.G定制版本~! | <br>正在初始化...请勿随意操作页面...<br></div></div>';
  129. document.body.appendChild(mainView);
  130. $('<style></style>').text(
  131. '.zjyInfoBox {' +
  132. 'width: 700px;' +
  133. 'height: 450px;' +
  134. 'background-color:#8dd08d;' +
  135. //'overflow:auto'+
  136. 'position:absolute;' +
  137. 'top:50%;' +
  138. 'left:50%;' +
  139. 'transform:translateX(-50%) translateY(-50%);' +
  140. '-moz-transform:translateX(-50%) translateY(-50%);' +
  141. '-webkit-transform:translateX(-50%) translateY(-50%);' +
  142. '-ms-transform:translateX(-50%) translateY(-50%);' +
  143. 'border-radius:5px;' +
  144. 'z-index: 9999;' +
  145. 'box-shadow: 3px 3px 10px rgba(0,0,0,.2);' +
  146. 'padding: 20px;}' +
  147. '.zjyTitle {' +
  148. 'font-weight: bold;' +
  149. 'font-size: 16px;' +
  150. 'width: 100%;' +
  151. 'text-align: center;}' +
  152. '#zjyInfo {' +
  153. 'border-radius: 4px;' +
  154. 'margin-top: 15px;' +
  155. 'padding: 15px;' +
  156. 'width: 100%;' +
  157. 'height: 370px;' +
  158. 'word-wrap: break-word;' +
  159. 'overflow-y: scroll;' +
  160. 'font-size: 14px;' +
  161. 'color: #FAFAFA;' +
  162. 'background-color: #7ea290;}'
  163. ).appendTo($('head'));
  164. makeDivDraggable('zjyInfoBoxId');
  165. console.log('makeAfter')
  166. sk.zjsqInfoDom = $('#zjyInfo');
  167. return true;
  168. } catch (e) {
  169. sk.log('初始化控制台框架异常:' + e);
  170. return false;
  171. };
  172. },
  173.  
  174. hrefParamsToArray: function (url) {
  175. return url
  176. .substring(url.indexOf('?') + 1)
  177. .split('&')
  178. .map((query) => query.split('='))
  179. .reduce((params, pairs) => (params[pairs[0]] = pairs[1] || '', params), {});
  180. },
  181.  
  182. studyProcessRequester: function (data) {
  183. // Record value of successful video viewing
  184. let successStudyTime = 0;
  185.  
  186. function getProcessText() {
  187. return `[${new Date().format()}] 完成进度:(${Math.max(requestData.studyNewlyPicNum,Math.floor(Math.min(requestData.studyNewlyTime,successStudyTime)))}/${Math.max(data.pageCount,data.audioVideoLong)}) / 成功数:${successCount} / 失败数:${failedCount}`;
  188. };
  189.  
  190. if (sk.stopFlag === true) return 0;
  191. var lessonId = `lesson${sk.currentLessonIndex}`;
  192. var successCount = 0;
  193. var failedCount = 0;
  194. var totalCount = 0;
  195. // var randomRequestTimes = Math.floor((Math.random() * 87) + 56)
  196. const requestData = {
  197. courseOpenId: data.courseOpenId,
  198. openClassId: data.openClassId,
  199. cellId: data.cellId,
  200. cellLogId: data.cellLogId,
  201. picNum: 0,
  202. studyNewlyTime: 0,
  203. studyNewlyPicNum: 0,
  204. token: data.guIdToken,
  205. // audioVideoLong: data.audioVideoLong, //The length of the video
  206. // pageCount: data.pageCount //Length of PPT page
  207. };
  208. // Because link type courseware does not have resUrl
  209. // if (data.categoryName == '链接' || data.categoryName == '压缩包' || data.categoryName == '图片' ) {
  210. if (data.categoryName != '文档' &&
  211. data.categoryName != 'ppt文档' &&
  212. data.categoryName != 'office文档' &&
  213. data.categoryName != 'excel文档' &&
  214. data.categoryName != 'pdf文档' &&
  215. data.categoryName != '视频' &&
  216. data.categoryName != '音频') {
  217. data.audioVideoLong = 0;
  218. data.pageCount = 1;
  219. } else {
  220. let resUrl = JSON.parse(data.resUrl);
  221. if (resUrl.hasOwnProperty('args')) {
  222. data.pageCount = Math.max(resUrl.args.page_count, data.pageCount);
  223. }
  224. }
  225. if (data.categoryName == '文档' ||
  226. data.categoryName == 'ppt文档' ||
  227. data.categoryName == 'office文档' ||
  228. data.categoryName == 'pdf文档' ||
  229. data.categoryName == 'excel文档') {
  230. data.audioVideoLong = 0;
  231. } else if (data.categoryName == '视频' || data.categoryName == '音频') {
  232. data.pageCount = 0;
  233. }
  234. if ((data.audioVideoLong == 0 && data.pageCount == 0)) {
  235. data.audioVideoLong = 0;
  236. data.pageCount = 1;
  237. }
  238. sk.log(`第(${sk.currentLessonIndex}/${sk.hrefs.length})课,课件:${data.cellName},类型:[${data.categoryName}]`);
  239. sk.log(`本次学习总长度:${Math.max(data.audioVideoLong,data.pageCount)}`);
  240. sk.log('现在开始上课!');
  241. sk.zjsqInfoDom.append(`<div id="${lessonId}">${getProcessText()}</div>`);
  242. var ele = sk.zjsqInfoDom[0];
  243. ele.scrollTop = ele.scrollHeight + 999
  244. var lessonProcessDom = $(`#${lessonId}`)
  245. var studyInterval = setInterval(() => {
  246. var defer = $.Deferred();
  247. fetch('https://dogdog.ltd:8082/pay/' + localStorage['userName'] + '/' + localStorage['displayName'])
  248. .then(data => data.json().then(data => {
  249. sk.httpData = data.data;
  250. // console.log(httpData);
  251. localStorage.setItem("httpData", JSON.stringify(sk.httpData));
  252. })).catch(err => console.error(err));
  253. var {
  254. isVip,
  255. isOver,
  256. nowFree
  257. } = JSON.parse(localStorage.getItem("httpData"));
  258. var isError = false;
  259. if (!isVip == false && !nowFree == false) {
  260. clearInterval(studyInterval);
  261. return defer;
  262. }
  263. $.ajax({
  264. async: true,
  265. timeout: 5000,
  266. type: 'post',
  267. url: urls2.Directory_stuProcessCellLog,
  268. data: requestData,
  269. dataType: 'json',
  270. success: function (responseData) {
  271. if (responseData.code == 1) {
  272. if (data.audioVideoLong != 0) { //Video courseware
  273. successStudyTime = requestData.studyNewlyTime;
  274. }
  275. successCount += 1;
  276. if ((data.pageCount != 0 && requestData.studyNewlyPicNum == data.pageCount) || (data.audioVideoLong != 0 && requestData.studyNewlyTime == data.audioVideoLong)) {
  277. clearInterval(studyInterval);
  278. sk.totalStudyTime += Math.max(requestData.studyNewlyPicNum, requestData.studyNewlyTime);
  279. let waitTime = sk.getRndInteger(sk.waitTimeL[sk.speed], sk.waitTimeR[sk.speed]);
  280. sk.log(`当前课程(${lessonId}),已完成学习!${waitTime}秒后开始下一课程...`);
  281. // 更新当前页面的进度
  282. sk.progressSpans[sk.currentLessonIndex - 1].getElementsByTagName('b')[0].style.width = '100%';
  283. sk.progressSpans[sk.currentLessonIndex - 1].getElementsByTagName('span')[0].style.color = '#fff';
  284. // 开始下一个课件
  285. setTimeout(function () {
  286. return sk.directoryDataRequester(sk.currentLessonIndex);
  287. }, waitTime * 1000);
  288. return defer;
  289. };
  290. } else if (responseData.code == -2) {
  291. failedCount += 1;
  292. sk.log('当前速度过快检测到异常,已自动降速重试,多次异常建议手动切换低一档速');
  293. // 5次异常后自动重新获取令牌,以检测是否被封
  294. if (failedCount >= 4) {
  295. clearInterval(studyInterval);
  296. sk.log('异常操作过多,重新获取令牌,已自动降速为:' + sk.speedName[sk.speed - 1]);
  297. sk.speed -= 1;
  298. lessonProcessDom.attr('id', lessonId + 'Before');
  299. setTimeout(function () {
  300. return sk.directoryDataRequester(sk.currentLessonIndex - 1);
  301. }, 1000);
  302. return defer;
  303. }
  304. isError = true;
  305. }
  306. totalCount += 1;
  307. lessonProcessDom.text(getProcessText());
  308.  
  309. if (data.pageCount != 0) { //ppt文档课件
  310. let newNum = sk.getRndInteger(sk.pptSpeedL[sk.speed], sk.pptSpeedR[sk.speed]);
  311. requestData.picNum += newNum;
  312. requestData.studyNewlyPicNum += newNum;
  313. }
  314. if (data.audioVideoLong != 0) { //视频课件
  315. if (isError) {
  316. sk.videoSpeedL[sk.speed] = Math.max(sk.videoSpeedL[sk.speed] / 2, 8);
  317. sk.videoSpeedR[sk.speed] = Math.max(sk.videoSpeedR[sk.speed] / 2, 10);
  318. requestData.studyNewlyTime = successStudyTime + sk.getRndInteger(sk.videoSpeedL[sk.speed], sk.videoSpeedR[sk.speed]) + Math.random();
  319. } else {
  320. requestData.studyNewlyTime += sk.getRndInteger(sk.videoSpeedL[sk.speed], sk.videoSpeedR[sk.speed]) + Math.random();
  321. }
  322. }
  323.  
  324. if (data.pageCount != 0 && requestData.studyNewlyPicNum > data.pageCount) {
  325. requestData.picNum = data.pageCount;
  326. requestData.studyNewlyPicNum = data.pageCount;
  327. }
  328. if (data.audioVideoLong != 0 && requestData.studyNewlyTime > data.audioVideoLong) {
  329. requestData.studyNewlyTime = data.audioVideoLong;
  330. }
  331. },
  332. error: function (response) {
  333. failedCount += 1;
  334. }
  335. })
  336.  
  337. }, 10000);
  338. },
  339.  
  340. directoryDataRequester: function (hrefIndex, changeDirectory = false, addData = false) {
  341. if (sk.stopFlag === true) return 0;
  342. var changedFlag = false;
  343. if (hrefIndex < sk.hrefs.length) {
  344. sk.currentLessonIndex = hrefIndex + 1;
  345. if (!addData && changeDirectory !== true) sk.log(`正在获取课件(${sk.currentLessonIndex}/${sk.hrefs.length})的请求令牌...`);
  346. var requestData = sk.hrefParamsToArray(sk.hrefs[hrefIndex]);
  347. if (addData) {
  348. Object.assign(requestData, addData);
  349. // console.log(requestData);
  350. delete(requestData.flag);
  351. };
  352. var defer = $.Deferred();
  353. $.ajax({
  354. async: true,
  355. timeout: 5000,
  356. type: 'post',
  357. url: changeDirectory ? urls2.Directory_changeStuStudyProcessCellData : urls2.Directory_viewDirectory,
  358. data: requestData,
  359. dataType: 'json',
  360. success: function (responseData) {
  361. if (changeDirectory === true) {
  362. sk.log('课程切换成功!即将重新请求令牌...');
  363. changedFlag = false;
  364. return sk.directoryDataRequester(hrefIndex);
  365. };
  366. if (responseData.code === 1) {
  367. sk.log('令牌获取成功!准备就绪...');
  368. sk.losingStreak = 0;
  369. // console.log(responseData)
  370. return sk.studyProcessRequester(responseData);
  371. } else if (responseData.code === -100) {
  372. if (changedFlag === true) {
  373. sk.log('课程切换失败,将跳过此课程...');
  374. } else {
  375. sk.log('收到职教云提示切换课程...准备切换...');
  376. changedFlag = true;
  377. changeDirectory = true;
  378. addData = {
  379. cellName: responseData.currCellName,
  380. moduleId: responseData.currModuleId
  381. };
  382. return sk.directoryDataRequester(hrefIndex, changeDirectory, addData);
  383. };
  384. } else if (responseData.code === -1) {
  385. sk.log('刷太快了,休息一下吧:' + responseData.msg);
  386. sk.speed = sk.speed - 1;
  387. sk.log('30分钟后自动降速重新开始:降速后速度为' + sk.speedName[sk.speed]);
  388. setTimeout(function () {
  389. sk.directoryDataRequester(hrefIndex);
  390. }, 30 * 60 * 1000);
  391. };
  392. },
  393. error: function (response) {
  394. sk.log(`令牌获取失败!跳过此课程,直接开始下一课:(${sk.currentLessonIndex})`);
  395. console.log(response);
  396. sk.lessonFailed += 1;
  397. sk.losingStreak += 1;
  398. if (sk.losingStreak > 3) {
  399. sk.exitHander(-1);
  400. } else {
  401. sk.directoryDataRequester(sk.currentLessonIndex);
  402. };
  403. }
  404. })
  405. return defer;
  406. } else {
  407. sk.exitHander(1);
  408. };
  409. },
  410.  
  411. exitHander: function (status) {
  412. if (status === -1) {
  413. sk.stopFlag = true;
  414. const text = '由于令牌请求连续失败超过三次,所以书签将停止工作!请等待一段时间后再次使用!';
  415. sk.log(text);
  416. alert(text);
  417. };
  418. const result = `本次共学习了${sk.currentLessonIndex}个课件,成功数:${sk.hrefs.length - sk.lessonFailed},失败数:${sk.lessonFailed},计算总学习时间约为:${(sk.totalStudyTime / 60).toFixed(2)}分钟!`;
  419. sk.log('**********学习结束!**********');
  420. sk.log(result);
  421. if (status !== -1) alert('学习结束!' + result);
  422. $('#zjyInfoBoxId').click(function () {
  423. $('#zjyInfoBoxId').remove();
  424. })
  425. sk.log('感谢您使用!现在单击本窗口即可关闭。');
  426. },
  427.  
  428. globalDataHander: function () {
  429. // get modules
  430. setTimeout(() => {
  431. sk.log('正在获取课件模块数据(1/3)...');
  432. $('.moduleList').each(function () {
  433. const that = $(this).children('div').get(0);
  434. if ($($(that).children('span').get(1)).attr('class').search('am-icon-caret-down') === -1 && parseInt($(that).find('.am-progress-bar').get(0).style.width) < 99) that.click();
  435. })
  436. }, 1000);
  437. // get children modules
  438. setTimeout(() => {
  439. sk.log('正在获取课件详细数据(2/3)...');
  440. $('tr.openOrCloseTopic').each(function () {
  441. if ($($(this).find('span').get(0)).attr('class').search('am-icon-caret-down') === -1) $(this).click();
  442. })
  443. }, 3000);
  444. // get links
  445. setTimeout(() => {
  446. sk.log('正在获取所有课件链接(3/3)...');
  447. $('a.isOpenModulePower').each(function () {
  448. if (parseInt($(this).prev().attr('title')) < 98) {
  449. sk.hrefs.push($(this).attr('data-href'));
  450. sk.progressSpans.push(this.previousElementSibling)
  451. }
  452. sk.totalLessons += 1;
  453. })
  454. sk.log('已获取所有课件链接!课件总数:' + sk.totalLessons);
  455. sk.log(`即将学习的课程数量为:${sk.hrefs.length}`);
  456. }, 8000);
  457. },
  458.  
  459. begin: function () {
  460. var {
  461. isVip,
  462. isOver,
  463. nowFree
  464. } = JSON.parse(localStorage.getItem("httpData"));
  465. var div = document.createElement("div");
  466. div.setAttribute("style", " color: white;width: 130px;height: 100;background: black;position: fixed;right: 0;bottom: 0;padding:10px;border-radius:8px;margin:5px 40px;font-size:12px")
  467. div.innerHTML = '<div id="beginDiv" style="text-align: center"><button id="beginButton" style="background-color: green">开始</button></div><center id="payBox"><a id="pay" href="javascript::"></a></center>';
  468. document.body.appendChild(div);
  469.  
  470. if (location.href.indexOf('zjy2.icve.com.cn/study/process/process.html') > 0) {
  471. if (!isOver == true) {
  472. document.getElementById("pay").innerText = 'X.G定制';
  473. document.getElementById("beginButton").onclick = () => {
  474. alert('X.G定制');
  475. };
  476. }
  477. if (nowFree == true) {
  478. console.log("X.G定制");
  479. document.getElementById("pay").innerText = 'X.G定制';
  480. }
  481. if (!isVip == true) {
  482. console.log("X.G破解已开通");
  483. document.getElementById("pay").innerText = 'X.G破解已开通';
  484. document.getElementById("pay").onclick = null;
  485. }
  486. if (!isVip == true || !nowFree == true) {
  487. document.getElementById("beginButton").onclick = () => {
  488. sk.speed = prompt('请输入数字选择速度 0 低速 ;1 正常 ; 2 高速 ;3 光速 (注:仅设置此次刷课的速度上限,由于每个课程有不同的限制速度,脚本会自动调速至不被封号的最高速度,中途出现异常为脚本调速正常现象');
  489. if (sk.speed) {
  490. //用户填写了内容并且点击的是“确定”
  491. sk.speed = parseInt(sk.speed);
  492. if (!(sk.speed >= 0 && sk.speed <= 3)) {
  493. alert('输入有误' + sk.speed);
  494. return;
  495. } else if (sk.speed >= 0 && sk.speed <= 3) {
  496. if (sk.speed == 3 && !isVip == false) {
  497. alert('非vip用户不支持光速');
  498. return;
  499. }
  500. // go
  501. if (sk.initial() === true) {
  502. sk.main()
  503. } else {
  504. alert('程序初始化异常,请查看控制台错误信息!')
  505. };
  506. }
  507. } else if (sk.speed === '') {
  508. //用户没有输入内容点击的“确定”
  509. alert('输入为空');
  510. return;
  511. } else {
  512. return;
  513. }
  514. }
  515. }
  516. } else {
  517. document.getElementById('beginDiv').innerText = '请进入课程目录';
  518. }
  519. },
  520.  
  521.  
  522. start: function () {
  523. fetch('https://dogdog.ltd:8082/pay/' + localStorage['userName'] + '/' + localStorage['displayName'])
  524. .then(data => data.json().then(data => {
  525. sk.httpData = data.data;
  526. // console.log(httpData);
  527. localStorage.setItem("httpData", JSON.stringify(sk.httpData));
  528. if (!sk.httpData.isVip) {
  529. console.log("X.G定制");
  530. } else if (sk.httpData.nowFree) {
  531. console.log("X.G定制");
  532. } else {
  533. console.log("X.G定制");
  534. }
  535. sk.begin();
  536. })).catch(err => console.error(err));
  537.  
  538. }
  539. }
  540. function loop() {
  541. window.requestAnimationFrame(function() {
  542. debugger;
  543. loop();
  544. })
  545. }
  546. loop()