正保会计网校(原中华会计网校)继续教育刷课

已破解API,无需答题,支持多开

  1. // ==UserScript==
  2. // @name 正保会计网校(原中华会计网校)继续教育刷课
  3. // @description 已破解API,无需答题,支持多开
  4. // @version 0.3
  5. // @author ChenZihan
  6. // @match https://jxjy.chinaacc.com/courseware/*
  7. // @exclude https://jxjy.chinaacc.com/courseware/index
  8. // @grant none
  9. // @license Apache License, Version 2.0
  10. // @namespace https://greasyfork.org/users/737513
  11. // ==/UserScript==
  12. (function () {
  13. 'use strict';
  14.  
  15. async function getServerTime(url) {
  16. var result;
  17. await $.ajax({
  18. url: url, type: 'post', success: (res) => {
  19. result = res
  20. }
  21. })
  22. return result;
  23. }
  24. async function postMD5(innerTime, serverOffsetTime) {
  25.  
  26. const videoModel = require('h5/videoModel');
  27. const videoCtrl = require('h5/videoCtrl');
  28. const stats = require('h5/h5StatApi');
  29. const vEvents = require('h5/h5EventApi');
  30. const md5 = require('h5/md5');
  31.  
  32. // Properties
  33. var videoID = videoModel.getVideoInfo().videoRefID;
  34. var userID = videoModel.getPlayStatus().userID;
  35. var studyID = videoModel.getVideoInfo().studyID;
  36. var courseID = videoModel.getVideoInfo().courseID;
  37. var playTime = stats.getCurrentTime();
  38. var postTimeKey = videoModel.getPlayerOpts().postTimeKey;
  39.  
  40. // Urls
  41. var basePath = videoModel.getInterfaces().BASE_PATH;
  42. var postDataUrl = videoModel.getInterfaces().POST_TIMING_DATA_URL;
  43. var getSysTimeUrl = videoModel.getInterfaces().getServerTimeUrl;
  44. var sysTimeUrl = basePath + getSysTimeUrl;
  45.  
  46. // Get server time
  47. var serverTime;
  48. await getServerTime(sysTimeUrl).then(res => {
  49. serverTime = res - serverOffsetTime
  50. });
  51. var hs = parseInt(serverTime)
  52.  
  53. // console.log("videoID", videoID)
  54. // console.log("playTime", playTime)
  55. // console.log(videoID, userID, studyID, courseID, playTime, postTimeKey)
  56. // console.log("postTimeKey: ", postTimeKey)
  57. // console.log("hs: ", hs)
  58.  
  59. // Concat
  60. var keyStr = videoID.toString() + playTime.toString() + innerTime.toString() + postTimeKey + hs;
  61. // Get hex MD5
  62. var keyMd5Str = hex_md5(keyStr);
  63. // console.log("Final:", keyStr, keyMd5Str)
  64.  
  65. $.ajax({
  66. url: basePath + postDataUrl,
  67. dataType: 'json', async: true, type: 'post',
  68. data: {
  69. videoID: videoID,
  70. studyID: studyID,
  71. userID: userID,
  72. courseID: courseID,
  73. key: keyMd5Str,
  74. hs: hs,
  75. playTime: playTime,
  76. innerTime: innerTime,
  77. isEnded: 0
  78. },
  79. success: (result) => { console.log("Success: ", result); },
  80. error: (result) => { console.log("Failed: ", result); }
  81. })
  82. }
  83.  
  84.  
  85. function secMin(totalSeconds) {
  86. const minutes = Math.floor(totalSeconds / 60);
  87. const seconds = totalSeconds % 60;
  88. function padTo2Digits(num) {
  89. return num.toString().padStart(2, '0');
  90. }
  91. const result = `${padTo2Digits(minutes)}:${padTo2Digits(seconds)}`;
  92. return result;
  93. }
  94.  
  95. function getVideoTime(videoTime) {
  96. var total = Number(videoTime.split(':')[0]) * 60 + Number(videoTime.split(':')[1])
  97. return total
  98. }
  99.  
  100. var times = 0;
  101. var videoTotalSeconds = null;
  102. function studySchedule(innerTime, serverOffsetTime, leftTime) {
  103.  
  104. if (leftTime != null && leftTime != '') { videoTotalSeconds = getVideoTime(leftTime); }
  105. else {
  106. console.log(`❗️等待获取总时长`);
  107. if (document.getElementsByClassName("vplay vmPlay").length != 0) {
  108. document.getElementsByClassName("vplay vmPlay")[0].click()
  109. }
  110. var iterval = setInterval(() => {
  111. var videoTime = document.getElementsByClassName("timeNum")[0].innerHTML.split('/')[1]
  112. videoTotalSeconds = getVideoTime(videoTime)
  113. leftTime = videoTime
  114. if (videoTotalSeconds != 0) {
  115. clearInterval(iterval);
  116. startSchedule();
  117. if (document.getElementsByClassName("vplay vmPause").length != 0) {
  118. document.getElementsByClassName("vplay vmPause")[0].click()
  119. }
  120. }
  121. }, 100);
  122. }
  123.  
  124. function startSchedule() {
  125. console.log(`✅已配置Schedule ${leftTime}后切换至下一个视频`);
  126. var schedule = setInterval(() => {
  127. console.log("-----------------------------");
  128. times++;
  129. var totalSeconds = times * innerTime;
  130. postMD5(innerTime, serverOffsetTime);
  131. console.log(`🔴第${times}次添加学习时长👀 ${totalSeconds}/${videoTotalSeconds}`);
  132. console.log(`总添加时长: ${secMin(totalSeconds)}`);
  133. console.log("-----------------------------");
  134.  
  135. if (document.getElementsByClassName("vplay vmPause").length != 0) {
  136. document.getElementsByClassName("vplay vmPause")[0].click()
  137. }
  138.  
  139. if (totalSeconds > videoTotalSeconds && videoTotalSeconds != 0) {
  140. // console.log("❗️已停止添加学习时长");
  141. // clearInterval(schedule);
  142. // location.reload();
  143. console.log("❗️时长添加完毕,3秒后切换至下一个视频");
  144. setTimeout(() => {
  145. document.getElementsByClassName("vmFront")[0].click()
  146. }, 3000);
  147. }
  148. }, innerTime * 1000 - 5000);
  149. }
  150. }
  151.  
  152. console.log(`💿等待页面加载完成`);
  153. setTimeout(() => {
  154. studySchedule(20, 1000, "")
  155. }, 3000);
  156.  
  157. })();
  158.