优学院网课助手

看视频,答题目,挂机

  1. // ==UserScript==
  2. // @name 优学院网课助手
  3. // @namespace Brush-JIM
  4. // @version 1.2.2
  5. // @description 看视频,答题目,挂机
  6. // @author Brush-JIM
  7. // @match https://ua.ulearning.cn/learnCourse/learnCourse.html?*
  8. // @match https://www.ulearning.cn/umooc/user/study.do?*
  9. // @grant unsafeWindow
  10. // @run-at document-start
  11. // @icon https://www.ulearning.cn/ulearning/favicon.ico
  12. // ==/UserScript==
  13.  
  14. "use strict";
  15. const self_ = unsafeWindow;
  16. const Setting = {
  17. Video: "0",
  18. Volume: "0",
  19. Speed: "1",
  20. Answer: "0",
  21. ForcePut: "0",
  22. WaitPut: "0",
  23. NextPage: "0",
  24. WaitNextPage: "0",
  25. AutoExit: "0",
  26. PageChange: 0,
  27. NextPageChange: 0,
  28. LogRecordChange: 0,
  29. VideoID: 0,
  30. QuestionID: 0,
  31. WebSocketID: 0,
  32. BeforeNext: 5000,
  33. NextPageTime: 1000,
  34. VideoTime: 300,
  35. QuestionTime: 300,
  36. DealBouncedTime: 500,
  37. AnswerCount: 0,
  38. NextPageCount: 0,
  39. PageElement: undefined,
  40. Url: "wss://cncache.ml/ulearning",
  41. WS: undefined,
  42. };
  43. let Bug = {};
  44. let Log = {};
  45. const WebSocketSend = [];
  46. const SupportType = [
  47. "1", "2", "3", "4", "5", "11", "12", "17", "23", "24"
  48. ];
  49. var QuestionArray = [];
  50. var oldVideos = [];
  51. const QuestionTitle = [];
  52. (function () {
  53. var c;
  54. var crcTable = [];
  55. for (var n = 0; n < 256; n++) {
  56. c = n;
  57. for (var k = 0; k < 8; k++) {
  58. c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
  59. }
  60. crcTable[n] = c;
  61. }
  62. window.crcTable = crcTable;
  63. })();
  64. HookXHR(self_);
  65. WS();
  66. setInterval(function () {
  67. let ws = Setting.WS;
  68. if (ws) {
  69. Setting.WebSocketID = setTimeout(function (ws) {
  70. ws.close();
  71. Setting.WS = undefined;
  72. WS();
  73. }, 10000, ws);
  74. ws.send(JSON.stringify({
  75. type: 5,
  76. }));
  77. }
  78. else {
  79. WS();
  80. }
  81. }, 30000);
  82. setInterval(Upload, 3000);
  83. setInterval(LogRecord, 500);
  84. setInterval(QuestionCollect, 2000);
  85. function QuestionCollect() {
  86. document.querySelectorAll("[id^='question']").forEach(function (item) {
  87. let qid_match = item.id.match(/question(\d+)/);
  88. if (!qid_match) {
  89. return;
  90. }
  91. let qid = qid_match[1];
  92. let title = item.querySelector(".question-title-text");
  93. if (title == null) {
  94. return;
  95. }
  96. let titleHTML = title.outerHTML;
  97. title = (title.cloneNode(true));
  98. title.querySelectorAll(".question-sort, .question-sort-dot, .question-type-tag, .input-wrapper, .choose-fill-blank-words, .custom-select").forEach(function (child) {
  99. child.parentNode?.removeChild(child);
  100. });
  101. let titleText = title.innerText;
  102. if (QuestionTitle.indexOf(titleHTML) == -1 || QuestionTitle.indexOf(titleText) == -1) {
  103. QuestionTitle.push(titleHTML);
  104. QuestionTitle.push(titleText);
  105. WebSocketSend.push({
  106. type: 9,
  107. qid: qid,
  108. titleHTML: titleHTML,
  109. titleText: titleText,
  110. });
  111. }
  112. });
  113. }
  114. function HookXHR(self_) {
  115. self_.XMLHttpRequest.prototype.open_ = self_.XMLHttpRequest.prototype.open;
  116. self_.XMLHttpRequest.prototype.open = function () {
  117. let url = arguments[1] || "";
  118. let xhr = this;
  119. const UrlMatch = [
  120. url.match(/https:\/\/api.ulearning.cn\/questionAnswer\/(\d+)\?parentId=(\d+)/),
  121. url.match(/https:\/\/api.ulearning.cn\/wholepage\/stu\/(\d+)/) || url.match(/https:\/\/api.ulearning.cn\/wholepage\/chapter\/stu\/(\d+)/),
  122. url.match(/\/umooc\/learner\/exam.do\?operation=getPaperForStudent&paperID=(\d+)&examId=(\d+)&userId=(\d+)/),
  123. url.match(/\/umooc\/learner\/exam.do\?operation=getCorrectAnswer&paperID=(\d+)&examID=(\d+)/),
  124. ];
  125. UrlMatch.forEach(function (value, index) {
  126. if (index == 0 && value) {
  127. let QuestionID = value[1];
  128. let ParentID = value[2];
  129. xhr.addEventListener("load", function () {
  130. let answer = JSON.parse(xhr.responseText);
  131. WebSocketSend.push({
  132. type: 2,
  133. qid: QuestionID,
  134. pid: ParentID,
  135. result: answer,
  136. });
  137. }, false);
  138. }
  139. else if (index == 1 && value) {
  140. let wholePage = value[1];
  141. xhr.addEventListener("load", function () {
  142. let data = JSON.parse(xhr.responseText);
  143. WebSocketSend.push({
  144. type: 4,
  145. wholdPageID: wholePage,
  146. wholdPage: data,
  147. });
  148. }, false);
  149. }
  150. else if (index == 2 && value) {
  151. let paperID = value[1];
  152. xhr.addEventListener("load", function () {
  153. let data = JSON.parse(xhr.responseText);
  154. WebSocketSend.push({
  155. type: 6,
  156. paperID: paperID,
  157. paper: data,
  158. });
  159. }, false);
  160. }
  161. else if (index == 3 && value) {
  162. let paperID = value[1];
  163. xhr.addEventListener("load", function () {
  164. let data = JSON.parse(xhr.responseText);
  165. WebSocketSend.push({
  166. type: 7,
  167. paperID: paperID,
  168. paperAnswer: data,
  169. });
  170. });
  171. }
  172. }, xhr);
  173. return this.open_.apply(this, arguments);
  174. };
  175. }
  176. function Upload() {
  177. let ws = Setting.WS;
  178. let wsSend = WebSocketSend.pop();
  179. if (ws && wsSend) {
  180. ws.send(JSON.stringify(wsSend));
  181. setTimeout(function (ws, wsSend) {
  182. if (ws != Setting.WS) {
  183. WebSocketSend.push(wsSend);
  184. }
  185. }, 45000, ws, wsSend);
  186. }
  187. else if (wsSend) {
  188. WebSocketSend.push(wsSend);
  189. }
  190. }
  191. function WS() {
  192. let uid = self_.currentUserId || 0;
  193. if (!uid && self_["exam"] && self_["exam"]["userID"]) {
  194. uid = self_["exam"]["userID"];
  195. }
  196. if (uid) {
  197. let ws = new WebSocket(Setting.Url);
  198. ws.addEventListener("open", function () {
  199. this.send(JSON.stringify({
  200. type: 1,
  201. uid: Crc32(uid.toString()).toString(),
  202. }));
  203. Setting.WS = this;
  204. }, false);
  205. ws.addEventListener("message", function (event) {
  206. let data = JSON.parse(event.data);
  207. switch (data.type) {
  208. case 5:
  209. clearTimeout(Setting.WebSocketID);
  210. }
  211. }, false);
  212. }
  213. }
  214. function Crc32(str) {
  215. var crcTable = window.crcTable;
  216. var crc = 0 ^ (-1);
  217. for (var i = 0; i < str.length; i++) {
  218. crc = (crc >>> 8) ^ crcTable[(crc ^ str.charCodeAt(i)) & 0xFF];
  219. }
  220. return (crc ^ (-1)) >>> 0;
  221. }
  222. function Panel() {
  223. let css = document.createElement("style");
  224. css.innerText = "#div1Panel{z-index:99999;position:absolute;right:10px;top:10px;background-color:#CAE8CA;border:2px solid #4CAF50;padding:5px;width:300px;font-size:14px;}.h3Panel{text-align:center;margin-top:0px!important;margin-bottom:0px;}.s1lPanel{display:inline-block;width:70%;font-weight:bold!important;}.srPanel{display:inline-block;}.s2lPanel{display:inline-block;width:70%;}.numberBox{width:50px!important;height:19px;}";
  225. document.body.appendChild(css);
  226. let panel = document.createElement("div");
  227. panel.setAttribute("id", "div1Panel");
  228. panel.innerHTML = `<h3 class="h3Panel">优学院脚本</h3><div><span class="s1lPanel">自动播放视频</span><span class="srPanel"><input id="Video"type="checkbox"></span></div><div><span class="s2lPanel">音量(0~100)</span><span class="srPanel"><input id="Volume"class="numberBox"type="number"value="0"step="1"min="0"max="100"></span></div><div><span class="s2lPanel">速度(0.5~15)</span><span class="srPanel"><input id="Speed"class="numberBox"type="number"value="1"step="0.5"min="0.5"max="15"></span></div><div><span class="s1lPanel">自动答题</span><span class="srPanel"><input id="Answer"type="checkbox"></span></div><div><span class="s2lPanel">强制提交</span><span class="srPanel"><input id="ForcePut"type="checkbox"></span></div><div><span class="s2lPanel">延时提交(秒)</span><span class="srPanel"><input id="WaitPut"class="numberBox"type="number"value="0"step="1"min="0"></span></div><div><span class="s1lPanel">自动换页</span><span class="srPanel"><input id="NextPage"type="checkbox"></span></div><div><span class="s2lPanel">换页等待时间(秒)</span><span class="srPanel"><input id="WaitNextPage"class="numberBox"type="number"value="0"step="1"min="0"></span></div><div><span class="s1lPanel">完成后自动关闭网页</span><span class="srPanel"><input id="AutoExit"type="checkbox"></span></div><div><span class="s1lPanel">脚本运行异常?</span><span class="srPanel"><button id="putBug">提交BUG</button></span></div><div id="uploadBug"style="display: none;"><div style="color: blue;">请切换到有问题的页面,然后下面输入出现的问题,最后点击“上传BUG”按钮<br /><span style="color: red;">上传内容有:输入的问题,当前网页内容,脚本运行日志。</span></div><textarea id="bugDetail"placeholder="在此输入出现的问题"style="width: 100%;"></textarea><div><button id="buttonUploadBug">上传BUG</button></div></div><div><span class="s1lPanel"></span><span class="srPanel"><button id="checkDetail">查看状态</button></span></div><div id="runDetail"style="display: none;"><div><span style="display: inline-block; width: 50%;">自动播放:<span style="color: red"id="videoState">已关闭</span></span><span class="srPanel">自动答题:<span style="color: red;"id="answerState">已关闭</span></span></div><div><span style="display: inline-block; width: 50%;">自动翻页:<span style="color: red;"id="nextState">已关闭</span></span><span class="srPanel">当前页面视频数量:<span style="color: red;"id="videoCount">0</span></span></div></div>`;
  229. document.body.appendChild(panel);
  230. document.querySelector("#div1Panel") && Bind() && (function () {
  231. Setting.PageChange = new Date().getTime();
  232. ListenPageChange();
  233. Setting.VideoID = setInterval(Video, Setting.VideoTime);
  234. Setting.QuestionID = setInterval(Question, Setting.QuestionTime);
  235. setTimeout(NextPage, Setting.NextPageTime);
  236. DealBounced();
  237. })();
  238. }
  239. function DealBounced() {
  240. let csp = document.querySelector("button[data-bind='click: closeStatPage']");
  241. if (csp) {
  242. if (Setting.AutoExit == "1") {
  243. let btc = document.querySelector("[data-bind='text: i18nMessageText().backToCourse']");
  244. if (btc) {
  245. btc.click();
  246. }
  247. else if ("koLearnCourseViewModel" in self_ && "goBack" in self_["koLearnCourseViewModel"]) {
  248. self_["koLearnCourseViewModel"]["goBack"]();
  249. }
  250. }
  251. }
  252. else {
  253. let am = document.querySelector("#alertModal");
  254. if (am && am.getAttribute("style")?.indexOf("display: block") !== -1) {
  255. let gnp = document.querySelector("button[data-bind='click: goNextPage']");
  256. if (gnp) {
  257. gnp.click();
  258. }
  259. let cl = document.querySelector("button[data-bind='text: $root.i18nMsgText().confirmLeave']");
  260. if (cl) {
  261. cl.click();
  262. }
  263. let gI = document.querySelector("button[data-bind='text: $root.i18nMsgText().gotIt']");
  264. if (gI) {
  265. gI.click();
  266. }
  267. let cs = document.querySelector("button[data-bind='text: $root.i18nMsgText().continueStudy']");
  268. if (cs) {
  269. cs.click();
  270. }
  271. }
  272. }
  273. let jf = document.querySelector(".jconfirm-buttons");
  274. if (jf) {
  275. let jfb = jf.querySelector(":nth-child(1)");
  276. if (jfb) {
  277. jfb.click();
  278. }
  279. }
  280. setTimeout(DealBounced, Setting.DealBouncedTime);
  281. }
  282. function ReSet() {
  283. Setting.AnswerCount = 0;
  284. Setting.NextPageCount = 0;
  285. }
  286. function NextPage() {
  287. if (Setting.NextPageChange != Setting.PageChange) {
  288. Setting.NextPageChange = Setting.PageChange;
  289. ReSet();
  290. setTimeout(NextPage, Setting.BeforeNext);
  291. return;
  292. }
  293. (function () {
  294. if (Setting.NextPage == "0") {
  295. ReSet();
  296. return;
  297. }
  298. if (!GetVideo().every(function (item) { return item.Done; }) && Setting.Video == "1") {
  299. ReSet();
  300. return;
  301. }
  302. if (!QuestionArray.every(function (item) { return item.Status >= 3; })) {
  303. ReSet();
  304. return;
  305. }
  306. if (QuestionArray.length != 0 && (QuestionArray.every(function (item) { return item.Status == 3; }) || Setting.ForcePut == "1")) {
  307. if (Setting.AnswerCount < parseFloat(Setting.WaitPut) * 1000) {
  308. Setting.AnswerCount += Setting.NextPageTime;
  309. return;
  310. }
  311. else {
  312. let sQ = document.querySelector("button[data-bind='text: $root.i18nMessageText().submit, click: submitQuiz']");
  313. if (sQ) {
  314. sQ.click();
  315. }
  316. }
  317. }
  318. if (Setting.NextPageCount < parseFloat(Setting.WaitNextPage) * 1000) {
  319. Setting.NextPageCount += Setting.NextPageTime;
  320. return;
  321. }
  322. let np = document.querySelector("span[class='text: i18nMessageText().nextPage']");
  323. if (np) {
  324. np.click();
  325. }
  326. else if ("koLearnCourseViewModel" in self_ && "goNextPage" in self_["koLearnCourseViewModel"]) {
  327. self_["koLearnCourseViewModel"]["goNextPage"]();
  328. }
  329. ReSet();
  330. })();
  331. setTimeout(NextPage, Setting.NextPageTime);
  332. }
  333. function FillAnswer(QuestionArray, QuestionAnswer) {
  334. switch (QuestionArray.QuestionType) {
  335. case "1":
  336. case "2":
  337. (function () {
  338. let options = QuestionArray.Ele.querySelectorAll(".choice-item");
  339. QuestionAnswer.correctAnswerList.forEach(function (item) {
  340. let index = item.charCodeAt(0) - 65;
  341. index >= 0 && index < options.length && options[index] && (function () {
  342. options[index].click();
  343. return true;
  344. })() || (QuestionArray.Status = 5);
  345. });
  346. })();
  347. break;
  348. case "3":
  349. (function () {
  350. let blanks = QuestionArray.Ele.querySelectorAll("input");
  351. blanks.length == QuestionAnswer.correctAnswerList.length && (function () {
  352. QuestionAnswer.correctAnswerList.forEach(function (item, index) {
  353. let key = item.split("//");
  354. blanks[index].value = key[0];
  355. });
  356. return true;
  357. })() || (QuestionArray.Status = 5);
  358. })();
  359. break;
  360. case "4":
  361. let right = QuestionArray.Ele.querySelector(".right-btn");
  362. let wrong = QuestionArray.Ele.querySelector(".wrong-btn");
  363. right && wrong && (function () {
  364. QuestionAnswer.correctAnswerList[0] == "true" && (function () {
  365. right.click();
  366. return true;
  367. })() || QuestionAnswer.correctAnswerList[0] == "false" && (function () {
  368. wrong.click();
  369. return true;
  370. })() || (QuestionArray.Status = 5);
  371. return true;
  372. })() || (QuestionArray.Status = 5);
  373. break;
  374. case "5":
  375. let shortAnswer = QuestionArray.Ele.querySelector("textarea");
  376. shortAnswer && (function () {
  377. shortAnswer.value = QuestionAnswer.correctAnswerList[0] || "言之有理即可";
  378. let event = document.createEvent("Events");
  379. event.initEvent("change", true, true);
  380. shortAnswer.dispatchEvent(event);
  381. return true;
  382. })() || (QuestionArray.Status = 5);
  383. break;
  384. case "17":
  385. case "23":
  386. case "11":
  387. let selects = QuestionArray.Ele.querySelectorAll("select");
  388. selects.length == QuestionAnswer.subQuestionAnswerDTOList.length && (function () {
  389. selects.forEach(function (item, index) {
  390. item.click();
  391. let key = QuestionAnswer.subQuestionAnswerDTOList[index].correctAnswerList[0].charCodeAt(0) - 65;
  392. let options = QuestionArray.Ele.querySelectorAll(".option");
  393. key >= 0 && key < options.length && (function () {
  394. options[key].click();
  395. return true;
  396. })() || (QuestionArray.Status = 5);
  397. });
  398. return true;
  399. })() || (QuestionArray.Status = 5);
  400. break;
  401. case "12":
  402. (function () {
  403. let choices = QuestionArray.Ele.querySelectorAll(".choice-item");
  404. let areas = QuestionArray.Ele.querySelectorAll(".show-answer-area .answer-item .answer-blank");
  405. choices.length == areas.length && QuestionAnswer.correctAnswerList.length == areas.length && (function () {
  406. QuestionAnswer.correctAnswerList.forEach(function (item, index) {
  407. areas[index].innerText = item;
  408. choices[index].parentNode?.appendChild(choices[index]);
  409. });
  410. })() || (QuestionArray.Status = -5);
  411. return true;
  412. })();
  413. break;
  414. }
  415. QuestionArray.Status != 5 && (QuestionArray.Status = 3);
  416. }
  417. function Question() {
  418. if (Setting.Answer == "0") {
  419. return;
  420. }
  421. if (QuestionArray.length) {
  422. QuestionArray.every(function (item) {
  423. if (!document.documentElement.contains(item.Ele)) {
  424. QuestionArray = [];
  425. return false;
  426. }
  427. });
  428. QuestionArray.every(function (item) {
  429. if (item.Status == 0) {
  430. item.Status = 1;
  431. try {
  432. let xhr = new XMLHttpRequest();
  433. xhr.addEventListener("load", function () {
  434. item.Status = 2;
  435. try {
  436. FillAnswer(item, JSON.parse(this.responseText));
  437. }
  438. catch (e) {
  439. item.Status = 4;
  440. }
  441. }, false);
  442. xhr.addEventListener("error", function () {
  443. item.Status = 4;
  444. }, false);
  445. xhr.open("GET", "https://api.ulearning.cn/questionAnswer/" + item.QuestionID + "?parentId=" + item.ParentID);
  446. xhr.send();
  447. }
  448. catch (e) {
  449. item.Status = 4;
  450. }
  451. }
  452. return true;
  453. });
  454. }
  455. else if (document.querySelector(".page-item [class*='active']")) {
  456. let qUTS = document.querySelector("[data-bind='i18n: $root.i18nMsgText().points, places: { n: questionUserTotalScore() }']");
  457. if (qUTS && qUTS.innerText == "100分") {
  458. return;
  459. }
  460. let rD = document.querySelector("button[class='btn-hollow btn-redo']");
  461. rD && rD.click();
  462. let pEle = document.querySelector(".page-item [class*='active']")?.parentElement;
  463. if (!pEle || !pEle.id.match(/page(\d+)/)) {
  464. return;
  465. }
  466. let PID = pEle.id.match(/page(\d+)/)[1];
  467. document.querySelectorAll("div[id^='question']").forEach(function (ele) {
  468. if (ele.querySelector("div[id^='question']")) {
  469. return;
  470. }
  471. let QT = ele.querySelector("span[class*='question-title-html question-type-']");
  472. if (!QT || !QT.className.match(/question-type-(\d+)/)) {
  473. return;
  474. }
  475. ;
  476. let QTID = QT.className.match(/question-type-(\d+)/)[1];
  477. if (SupportType.indexOf(QTID) == -1) {
  478. return;
  479. }
  480. if (!ele.id.match(/question(\d+)/)) {
  481. return;
  482. }
  483. let QID = ele.id.match(/question(\d+)/)[1];
  484. QuestionArray.push({
  485. Ele: ele,
  486. QuestionType: QTID,
  487. QuestionID: QID,
  488. ParentID: PID,
  489. Status: 0
  490. });
  491. });
  492. }
  493. }
  494. function Video() {
  495. let VideoArray = (Setting.Video === "0" && []) || GetVideo();
  496. let finish = true;
  497. VideoArray.forEach(function (ele) {
  498. finish && (function () {
  499. !ele.Done && (function () {
  500. finish = false;
  501. ele.VideoEle.paused && ele.VideoEle.play().catch(function () {
  502. ele.VideoEle.currentTime > 3 && (function () {
  503. ele.VideoEle.currentTime -= 3;
  504. })();
  505. });
  506. ele.VideoEle.volume.toString() != Setting.Volume && (function () {
  507. switch (Setting.Volume) {
  508. case "0":
  509. ele.VideoEle.muted = true;
  510. break;
  511. default:
  512. ele.VideoEle.volume = parseFloat(Setting.Volume) * 0.01 || 0;
  513. }
  514. ;
  515. })();
  516. ele.VideoEle.playbackRate.toString() != Setting.Speed && (function () {
  517. ele.VideoEle.playbackRate = parseFloat(Setting.Speed);
  518. })();
  519. })();
  520. })();
  521. });
  522. }
  523. function GetVideo() {
  524. let VideoArray = [];
  525. document.querySelectorAll(".video-container").forEach(function (ele) {
  526. let video = ele.querySelector("video");
  527. let info = (ele.querySelector("span[data-bind='text: $root.i18nMessageText().unviewed']") ||
  528. ele.querySelector("span[data-bind='text: $root.i18nMessageText().viewed']") ||
  529. ele.querySelector("span[data-bind='text: $root.i18nMessageText().finished']"));
  530. video && info && (function (video, info) {
  531. switch (info.getAttribute("data-bind")) {
  532. case "text: $root.i18nMessageText().unviewed":
  533. case "text: $root.i18nMessageText().viewed":
  534. VideoArray.push({
  535. VideoEle: video,
  536. Done: false,
  537. });
  538. break;
  539. case "text: $root.i18nMessageText().finished":
  540. video.paused && VideoArray.push({
  541. VideoEle: video,
  542. Done: true,
  543. }) || VideoArray.push({
  544. VideoEle: video,
  545. Done: false,
  546. });
  547. }
  548. })(video, info);
  549. });
  550. return VideoArray;
  551. }
  552. function ListenPageChange() {
  553. let targetNode = document.querySelector(".catalog-list");
  554. if (targetNode !== null) {
  555. let config = { childList: false, attributes: true, subtree: true };
  556. let observer = new MutationObserver(function (mutationList, observer) {
  557. mutationList.forEach((mutation) => {
  558. switch (mutation.type) {
  559. case 'attributes':
  560. if (mutation.attributeName === "class") {
  561. if (mutation.target.className.indexOf("active") != -1) {
  562. if (Setting.PageElement !== mutation.target) {
  563. Setting.PageElement = mutation.target;
  564. Setting.PageChange = new Date().getTime();
  565. }
  566. }
  567. }
  568. }
  569. });
  570. });
  571. observer.observe(targetNode, config);
  572. }
  573. else {
  574. setTimeout(ListenPageChange, 100);
  575. }
  576. }
  577. function Bind() {
  578. document.querySelector("#div1Panel").querySelectorAll("input").forEach(function (ele) {
  579. ele.id && (function (self) {
  580. switch (self.type) {
  581. case "checkbox":
  582. switch (GetSet(self.id, "0")) {
  583. case "1":
  584. self.checked = true;
  585. break;
  586. case "0":
  587. self.checked = false;
  588. break;
  589. }
  590. Setting[self.id] = GetSet(self.id, "0");
  591. break;
  592. case "number":
  593. self.value = GetSet(self.id, self.value);
  594. Setting[self.id] = GetSet(self.id, self.value);
  595. break;
  596. }
  597. })(ele);
  598. ele.addEventListener("change", function () {
  599. this.id && (function (self) {
  600. switch (self.type) {
  601. case "checkbox":
  602. switch (self.checked) {
  603. case true:
  604. SaveSet(self.id, "1");
  605. break;
  606. case false:
  607. SaveSet(self.id, "0");
  608. }
  609. break;
  610. case "number":
  611. SaveSet(self.id, self.value);
  612. break;
  613. }
  614. })(this);
  615. }, false);
  616. });
  617. document.querySelector("#div1Panel").querySelectorAll("button").forEach(function (ele) {
  618. ele.id && (function () {
  619. ele.addEventListener('click', function () {
  620. switch (ele.id) {
  621. case "putBug":
  622. ele.disabled = true;
  623. document.querySelector("#uploadBug").setAttribute("style", "display: block;");
  624. break;
  625. case "buttonUploadBug":
  626. let textarea = document.querySelector("#bugDetail");
  627. if (textarea.value) {
  628. ele.disabled = true;
  629. WebSocketSend.push({
  630. type: 3,
  631. detail: textarea.value,
  632. html: document.documentElement.outerHTML,
  633. errors: Bug,
  634. logs: Log,
  635. });
  636. Bug = {};
  637. Log = {};
  638. ele.innerText = "上传成功";
  639. setTimeout(function () {
  640. document.querySelector("#uploadBug").setAttribute("style", "display: none;");
  641. textarea.value = "";
  642. ele.innerText = "上传Bug";
  643. ele.disabled = false;
  644. document.querySelector("#putBug").disabled = false;
  645. }, 3000);
  646. }
  647. else {
  648. ele.innerText = "请填写问题!";
  649. setTimeout(function () {
  650. ele.innerText = "上传Bug";
  651. }, 3000);
  652. }
  653. break;
  654. case "checkDetail":
  655. let rd = document.querySelector("#runDetail");
  656. rd && (function () {
  657. if (rd.getAttribute("style") == "display: none;") {
  658. rd.setAttribute("style", "display: block;");
  659. }
  660. else {
  661. rd.setAttribute("style", "display: none;");
  662. }
  663. })();
  664. break;
  665. }
  666. }, false);
  667. })();
  668. });
  669. return true;
  670. }
  671. function GetSet(key, def) {
  672. def = def || "";
  673. Log[new Date().getTime().toString()] = "Get: " + key + "=" + localStorage.getItem(key) || def;
  674. Detail(key, localStorage.getItem(key) || def);
  675. return localStorage.getItem(key) || def;
  676. }
  677. function SaveSet(key, value) {
  678. Setting[key] = value;
  679. localStorage.setItem(key, value);
  680. Log[new Date().getTime().toString()] = "Set: " + key + "=" + value;
  681. Detail(key, value);
  682. }
  683. function Detail(k, v) {
  684. let spanState = null;
  685. switch (k) {
  686. case "Video":
  687. spanState = document.querySelector("#videoState");
  688. break;
  689. case "Answer":
  690. spanState = document.querySelector("#answerState");
  691. break;
  692. case "NextPage":
  693. spanState = document.querySelector("#nextState");
  694. break;
  695. }
  696. spanState && (function () {
  697. switch (v) {
  698. case "0":
  699. spanState.innerText = "已关闭";
  700. spanState.setAttribute("style", "color: red;");
  701. break;
  702. case "1":
  703. spanState.innerText = "已开启";
  704. spanState.setAttribute("style", "color: green;");
  705. break;
  706. }
  707. })();
  708. }
  709. function Exam() {
  710. Array.prototype.slice.call(document.querySelectorAll("script")).some(function (item) {
  711. let m = item.text.match(/"\/umooc\/learner\/exam.do\?operation=getCorrectAnswer&paperID=(\d+)&examID=(\d+)"\,/);
  712. if (m && self_["exam"] && self_["exam"]["userID"]) {
  713. let pid = m[1];
  714. let eid = m[2];
  715. WebSocketSend.push({
  716. type: 8,
  717. eid: eid,
  718. pid: pid,
  719. });
  720. let xhr1 = new XMLHttpRequest();
  721. xhr1.open("GET", "https://www.ulearning.cn/umooc/learner/exam.do?operation=getCorrectAnswer&paperID=" + pid + "&examID=" + eid);
  722. xhr1.addEventListener("load", function () {
  723. WebSocketSend.push({
  724. type: 7,
  725. paperID: pid,
  726. paperAnswer: JSON.parse(this.responseText),
  727. });
  728. }, false);
  729. xhr1.send();
  730. let xhr2 = new XMLHttpRequest();
  731. xhr2.open("GET", "https://www.ulearning.cn/umooc/learner/exam.do?operation=getPaperForStudent&paperID=" + pid + "&examId=" + eid + "&userId=" + self_["exam"]["userID"]);
  732. xhr2.addEventListener("load", function () {
  733. WebSocketSend.push({
  734. type: 6,
  735. paperID: pid,
  736. paper: JSON.parse(this.responseText),
  737. });
  738. }, false);
  739. xhr2.send();
  740. return true;
  741. }
  742. }) || setTimeout(Exam, 1000);
  743. }
  744. function LogRecord() {
  745. if (Setting.PageChange != Setting.LogRecordChange) {
  746. Setting.LogRecordChange = Setting.PageChange;
  747. Log[new Date().getTime().toString()] = "Page Change";
  748. }
  749. else {
  750. oldVideos = oldVideos || [];
  751. let videos = GetVideo();
  752. (oldVideos.length != videos.length || !videos.every(function (value, index) {
  753. if (value.VideoEle != oldVideos[index].VideoEle) {
  754. return false;
  755. }
  756. else {
  757. return true;
  758. }
  759. })) && (function () {
  760. Log[new Date().getTime().toString()] = "video: " + videos.length.toString();
  761. document.querySelector("#videoCount").innerText = videos.length.toString();
  762. oldVideos = videos;
  763. })();
  764. }
  765. }
  766. if (location.href.match(/https:\/\/ua.ulearning.cn\/learnCourse\/learnCourse.html/)) {
  767. window.addEventListener("error", function (error) {
  768. let e = error.error;
  769. if (e) {
  770. let msg = (e || "").toString();
  771. let stack = e.stack;
  772. Bug[(new Date().getTime()).toString()] = "message: " + msg + "\nstack:" + stack;
  773. }
  774. }, false);
  775. navigator.__defineGetter__('userAgent', function () {
  776. return 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36';
  777. });
  778. Panel();
  779. }
  780. else if (location.href.match(/https:\/\/www.ulearning.cn\/umooc\/user\/study.do/)) {
  781. document.addEventListener("DOMContentLoaded", Exam, false);
  782. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址