优学院自动静音播放、自动做练习题、自动翻页、修改播放速率

自动静音播放每页视频、自动作答、修改播放速率!

  1. // ==UserScript==
  2. // @name 优学院自动静音播放、自动做练习题、自动翻页、修改播放速率
  3. // @namespace [url=mailto:moriartylimitter@outlook.com]moriartylimitter@outlook.com[/url]
  4. // @version 1.6.1
  5. // @description 自动静音播放每页视频、自动作答、修改播放速率!
  6. // @author EliotZhang、Brush-JIM
  7. // @match *://*.ulearning.cn/learnCourse/*
  8. // @require https://code.jquery.com/jquery-3.4.1.min.js
  9. // @require https://code.jquery.com/ui/1.12.1/jquery-ui.js
  10. // @run-at document-start
  11. // @grant unsafeWindow
  12. // ==/UserScript==
  13.  
  14. (function () {
  15. 'use strict';
  16. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  17. * 优学院自动静音播放、自动做练习题、自动翻页、修改播放速率脚本v1.6.1由EliotZhang @ 2020/06/04 最后更新
  18. * 特别感谢Brush-JIM (Mail:Brush-JIM@protonmail.com) 提供的脚本改进支持!
  19. * 使用修改播放速率功能请谨慎!!!产生的不良后果恕某概不承担!!!
  20. * 请保持网课播放页面在浏览器中活动,避免长时间后台挂机(平台有挂机检测功能),以减少不必要的损失
  21. * 自动作答功能由于精力有限目前只支持单/多项选择、判断题、部分填空问答题,如果出现问题请尝试禁用这个功能!
  22. * 如果脚本无效请优先尝试刷新页面,若是无效请查看脚本最后的解决方案,如果还是不行请反馈给本人,本人将会尽快修复
  23. * 如果是因为网络问题,本人也无能为力
  24. * 如果在使用中还有什么问题请通过邮箱联系EliotZhang:moriartylimitter@outlook.com
  25. * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  26. */
  27.  
  28. var N = 1.50;
  29. var EnableAutoPlay = true;
  30. var EnableAutoMute = true;
  31. var EnableAutoChangeRate = true;
  32. var EnableAutoFillAnswer = true;
  33. var EnableAutoShowAnswer = true;
  34. var EnableAutoAnswerChoices = true;
  35. var EnableAutoAnswerJudges = true;
  36. var EnableAutoAnswerFills = true;
  37.  
  38. // 新增函数 By Brush-JIM
  39. function Video(func = {}, slept = false) {
  40. if (!EnableAutoPlay)
  41. return;
  42. if (autoAnswering) {
  43. setTimeout(function () {
  44. Video({}, true);
  45. }, '1000');
  46. return;
  47. }
  48. if (!slept) {
  49. setTimeout(function () {
  50. Video({}, true);
  51. }, '3000');
  52. return;
  53. }
  54. var A_tmp = $('video');
  55. var A = [];
  56. for (let d = 0; d < A_tmp.length; d++) {
  57. if (A_tmp[d].src != "") {
  58. A.push(A_tmp[d]);
  59. }
  60. }
  61. if (A.length === 0) {
  62. GotoNextPage();
  63. return;
  64. }
  65. var B = [];
  66. var tmp = $('div[class="video-bottom"]');
  67. for (let b = 0; b < tmp.length; b++) {
  68. let span = tmp[b].getElementsByTagName("span")[0];
  69. if (span) {
  70. let data_bind = span.getAttribute('data-bind');
  71. if (data_bind == 'text: $root.i18nMessageText().finished' || data_bind == 'text: $root.i18nMessageText().viewed' || data_bind == 'text: $root.i18nMessageText().unviewed') {
  72. B.push(data_bind);
  73. }
  74. }
  75. }
  76.  
  77. function video_ctrl(func) {
  78. for (let c = 0; c < A.length; c++) {
  79. if (B[c] == 'text: $root.i18nMessageText().viewed' || B[c] == 'text: $root.i18nMessageText().unviewed' || B[c] === false) {
  80. if (c - 1 >= 0) {
  81. if (A[c - 1].currentTime != 0) {
  82. if (A[c - 1].paused === true) {
  83. A[c - 1].play()
  84. }
  85. if (EnableAutoMute && A[c - 1].muted === false) {
  86. A[c - 1].muted = true;
  87. }
  88. if (EnableAutoChangeRate && A[c - 1].playbackRate != N) {
  89. A[c - 1].playbackRate = N
  90. }
  91. break;
  92. }
  93. }
  94. if (A[c].paused === true) {
  95. A[c].play();
  96. }
  97. if (EnableAutoMute && A[c].muted === false) {
  98. A[c].muted = true;
  99. }
  100. if (EnableAutoChangeRate && A[c].playbackRate != N) {
  101. A[c].playbackRate = N;
  102. }
  103. break;
  104. }
  105. }
  106. if (B[B.length - 1] == 'text: $root.i18nMessageText().finished' || B[B.length - 1] === true) {
  107. if (A[A.length - 1].currentTime != 0) {
  108. if (A[A.length - 1].paused === true) {
  109. A[A.length - 1].play()
  110. }
  111. if (EnableAutoMute && A[A.length - 1].muted === false) {
  112. A[A.length - 1].muted = true
  113. }
  114. if (EnableAutoChangeRate && A[A.length - 1].playbackRate != N) {
  115. A[A.length - 1].playbackRate = N
  116. }
  117. setTimeout(func, "2000", func);
  118. } else {
  119. GotoNextPage();
  120. }
  121. } else {
  122. setTimeout(func, "2000", func);
  123. }
  124. }
  125. if (A.length == B.length) {
  126. video_ctrl(Video);
  127. } else {
  128. B = [];
  129. for (let d = 0; d < A.length; d++) {
  130. B[d] = false;
  131. A[d].addEventListener("ended", function () {
  132. B[d] = true;
  133. }, true);
  134. }
  135. video_ctrl(video_ctrl);
  136. }
  137. }
  138.  
  139. function GotoNextPage() {
  140. if (autoAnswering || !EnableAutoPlay || checkingModal)
  141. return;
  142. var nextPageBtn = $('.mobile-next-page-btn');
  143. if (nextPageBtn.length === 0)
  144. return;
  145. nextPageBtn.each((k, n) => {
  146. n.click();
  147. });
  148. setTimeout(Video, "1000");
  149. }
  150.  
  151. function CheckModal(slept = false) {
  152. if (autoAnswering)
  153. return;
  154. if (!slept) {
  155. setTimeout(function () {
  156. CheckModal(true);
  157. }, '2000');
  158. return;
  159. }
  160. if (EnableAutoPlay) {
  161. CheckModal();
  162. }
  163. checkingModal = true;
  164. var qw = $('.question-wrapper');
  165. if (qw.length > 0 && EnableAutoFillAnswer) {
  166. ShowAndFillAnswer();
  167. checkingModal = false;
  168. return;
  169. }
  170. var statModal = $('#statModal');
  171. if (statModal.length > 0) {
  172. var ch = statModal[0];
  173. ch.getElementsByTagName('button');
  174. if (ch.length >= 2)
  175. ch[1].click();
  176. }
  177. var err = $('.mobile-video-error');
  178. if (err && err.css('display') != 'none')
  179. $('.try-again').click();
  180. var alertModal = document.getElementById("alertModal");
  181. if (alertModal === undefined) {
  182. checkingModal = false;
  183. return;
  184. }
  185. if (alertModal.className.match(/\sin/)) {
  186. var op = $('.modal-operation').children();
  187. if (op.length >= 2)
  188. op[EnableAutoFillAnswer ? 0 : 1].click();
  189. else {
  190. var continueBtn = $('.btn-submit');
  191. if (continueBtn.length > 0) {
  192. continueBtn.each((k, v) => {
  193. if ($(v).text() != '提交')
  194. $(v).click();
  195. });
  196. }
  197. }
  198. if (EnableAutoFillAnswer)
  199. ShowAndFillAnswer();
  200. }
  201. checkingModal = false;
  202. }
  203.  
  204. function RemoveDuplicatedItem(arr) {
  205. for (var i = 0; i < arr.length - 1; i++) {
  206. for (var j = i + 1; j < arr.length; j++) {
  207. if (arr[i] == arr[j]) {
  208. arr.splice(j, 1);
  209. j--;
  210. }
  211. }
  212. }
  213. return arr;
  214. }
  215.  
  216. function Escape2Html(str) {
  217. var arrEntities = {
  218. 'lt': '<',
  219. 'gt': '>',
  220. 'nbsp': ' ',
  221. 'amp': '&',
  222. 'quot': '"'
  223. };
  224. return str.replace(/&(lt|gt|nbsp|amp|quot);/ig, function (all, t) {
  225. return arrEntities[t];
  226. });
  227. }
  228.  
  229. function DelHtmlTag(str) {
  230. return str.replace(/(<[^>]+>|\\n|\\r)/g, " ");
  231. }
  232.  
  233. function FillAnswers() {
  234. if (!autoAnswering || !EnableAutoAnswerFills)
  235. return;
  236. var ansarr = [];
  237. var idList = [];
  238. var re = [];
  239. var txtAreas = $('textarea, .blank-input');
  240. $(txtAreas).each((k, v) => {
  241. var reg = /question\d+/;
  242. var fa = $(v).parent();
  243. while (!reg.test($(fa).attr('id'))) {
  244. fa = $(fa).parent();
  245. }
  246. var id = $(fa).attr('id').replace('question', '');
  247. idList.push(id);
  248. });
  249. idList = RemoveDuplicatedItem(idList);
  250. $(idList).each((k, id) => {
  251. $.ajax({
  252. url: 'https://api.ulearning.cn/questionAnswer/' + id,
  253. type: "GET",
  254. contentType: "application/json",
  255. dataType: 'json',
  256. async: false,
  257. data: {
  258. parentId: pageid,
  259. },
  260. success: function (result, status, xhr) {
  261. re.push(result.correctAnswerList);
  262. }
  263. });
  264. });
  265.  
  266. $(re).each((k1, v1) => {
  267. if (v1.length == 1) {
  268. ansarr.push(DelHtmlTag(Escape2Html(v1[0])));
  269. } else {
  270. $(v1).each(function (k2, v2) {
  271. ansarr.push(DelHtmlTag(Escape2Html(v2)));
  272. });
  273. }
  274. });
  275. $(txtAreas).each((k, v) => {
  276. $(v).val(ansarr.shift());
  277. });
  278. }
  279.  
  280. function ShowAndFillAnswer() {
  281. if (autoAnswering | !EnableAutoFillAnswer)
  282. return;
  283. autoAnswering = true;
  284. var sqList = [];
  285. var qw = $('.question-wrapper');
  286. var pages = $('.page-item');
  287. var an = [];
  288. qw.each(function (k, v) {
  289. var id = $(v).attr('id');
  290. sqList.push(id.replace('question', ''));
  291. });
  292. var flag = false;
  293. pages.each(function (k, v) {
  294. if (flag) return;
  295. var sp = $(v).find('.page-name');
  296. if (sp.length > 0 && sp[0].className.search('active') >= 0) {
  297. var pd = $(v).attr('id');
  298. pd = pd.slice(pd.search(/\d/g));
  299. pageid = pd;
  300. flag = true;
  301. }
  302. });
  303. if (!flag) {
  304. autoAnswering = false;
  305. GotoNextPage();
  306. return;
  307. }
  308. if (sqList.length <= 0) {
  309. autoAnswering = false;
  310. return;
  311. }
  312. $(sqList).each(function (k, id) {
  313. var flag = false;
  314. while (!flag)
  315. $.ajax({
  316. url: 'https://api.ulearning.cn/questionAnswer/' + id,
  317. type: "GET",
  318. contentType: "application/json",
  319. dataType: 'json',
  320. async: false,
  321. data: {
  322. parentId: pageid,
  323. },
  324. success: function (result, status, xhr) {
  325. an.push(result.correctAnswerList);
  326. flag = true;
  327. }
  328. });
  329. });
  330. //
  331. if (EnableAutoShowAnswer) {
  332. var t = qw.find('.question-title-html');
  333. t.each(function (k, v) {
  334. var ans = an.shift();
  335. $(v).after('<span style="color:red;">答案:' + ans + '</span>');
  336. an.push(ans);
  337. });
  338. }
  339. //
  340. var checkBox = qw.find('.checkbox');
  341. var choiceBox = qw.find('.choice-btn');
  342. var checkList = [];
  343. var choiceList = [];
  344. let lasOffsetP = '';
  345. checkBox.each((k, cb) => {
  346. if (lasOffsetP == $(cb).offsetParent().attr('id')) {
  347. checkList[checkList.length - 1].push(cb);
  348. } else {
  349. var l = [];
  350. l.push(cb);
  351. checkList.push(l);
  352. lasOffsetP = $(cb).offsetParent().attr('id');
  353. }
  354. });
  355. lasOffsetP = '';
  356. choiceBox.each((k, cb) => {
  357. if (lasOffsetP == $(cb).offsetParent().attr('id')) {
  358. choiceList[choiceList.length - 1].push(cb);
  359. } else {
  360. var l = [];
  361. l.push(cb);
  362. choiceList.push(l);
  363. lasOffsetP = $(cb).offsetParent().attr('id');
  364. }
  365. });
  366. an.forEach(a => {
  367. if (a == null || a == undefined || a.length <= 0) {
  368. return;
  369. }
  370. if (a[0].match(/[A-Z]/) && a[0].length == 1 && EnableAutoAnswerChoices) {
  371. var cb = checkList.shift();
  372. a.forEach(aa => {
  373. var cccb = $(cb[aa.charCodeAt() - 65]);
  374. if (cccb[0] === undefined || (cccb[0] != undefined && cccb[0].className.search('selected') < 0))
  375. cccb.click();
  376. });
  377. } else if (a[0].match(/(([tT][rR][uU][eE])|([fF][aA][lL][sS][eE]))/) && EnableAutoAnswerJudges) {
  378. var ccb = choiceList.shift();
  379. a.forEach(aa => {
  380. if (aa.match(/([tT][rR][uU][eE])/))
  381. ccb[0].click();
  382. else
  383. ccb[1].click();
  384. });
  385. }
  386. return;
  387.  
  388. });
  389. if (EnableAutoAnswerFills) {
  390. FillAnswers();
  391. $.globalEval("$('textarea, .blank-input').trigger('change')");
  392. }
  393. if (EnableAutoPlay) {
  394. $('textarea, .blank-input').trigger('change');
  395. $('.btn-submit').click();
  396. var A_tmp = $('video');
  397. var A = [];
  398. for (let d = 0; d < A_tmp.length; d++) {
  399. if (A_tmp[d].src != "") {
  400. A.push(A_tmp[d]);
  401. }
  402. }
  403. if (A.length === 0) {
  404. autoAnswering = false;
  405. GotoNextPage();
  406. return;
  407. }
  408. }
  409. autoAnswering = false;
  410. }
  411.  
  412. function LoadStyle(url) {
  413. var link = document.createElement('link');
  414. link.type = 'text/css';
  415. link.rel = 'stylesheet';
  416. link.href = url;
  417. var head = document.getElementsByTagName('head')[0];
  418. head.appendChild(link);
  419. }
  420.  
  421. function DrawOptionPanel() {
  422. LoadStyle('https://eliotzhang.club/CSS/ulearning.css');
  423. var root = document.getElementsByTagName('body')[0];
  424. var panel = document.createElement('div');
  425. root.appendChild(panel);
  426. panel.setAttribute('class', 'OptionPanel');
  427. panel.innerHTML = "<div class='OptionPanel'><div class='DragBall'>UL</div><div class='MainPanel'><h2 class='OptionMainTitle'>优学院辅助脚本</br>by EliotZhang、BrushJIM</h2><button id='MainBtn'>隐藏设置</button><h4>视频播放</h4><ul class='OptionUL'><li>自动翻页、播放视频?<input class='OptionInput'id='AutoPlay'type='checkbox'checked='checked'></li><li>自动静音?<input class='OptionInput'id='AutoMute'type='checkbox'checked='checked'></li><li>自动调整速率(依赖自动播放视频功能)?<input class='OptionInput'id='AutoPlayRate'type='checkbox'checked='checked'></li><li>自动的速率速度<input class='OptionInput'id='AutoPlayRateChange'type='number'value='1.50'step='0.25'min='0.25'max='15.00'></li></ul><h4>自动作答</h4><ul class='OptionUL'><li>自动作答(总开关)?<input class='OptionInput'id='AutoAnswer'type='checkbox'checked='checked'></li><li>自动显示答案?<input class='OptionInput'id='AutoShowAnswer'type='checkbox'checked='checked'></li><li>自动作答选择题?<input class='OptionInput'id='AutoAnswerChoices'type='checkbox'checked='checked'></li><li>自动作答判断题?<input class='OptionInput'id='AutoAnswerJudges'type='checkbox'checked='checked'></li><li>自动作答填空、简答题?<input class='OptionInput'id='AutoAnswerFills'type='checkbox'checked='checked'></li></ul><button id='SaveOpBtn'>保存设置并刷新脚本</button><p style='color:hotpink;'>若<strong>关闭自动翻页功能</strong>导致<strong>自动作答系列功能失效</strong>请点击<strong>保存设置并刷新脚本按钮!</strong></p><p style='color:hotpink;'>若关闭自动翻页功能答完题后请<strong>手动提交!!</strong></p></div></div>";
  428. }
  429.  
  430. function Init() {
  431. mainBtn = document.getElementById('MainBtn');
  432. dragBall = $('.DragBall');
  433. saveOpBtn = document.getElementById('SaveOpBtn');
  434. OptionPanel = $('.OptionPanel');
  435. MainPanel = $('.MainPanel');
  436. autoPlayOp = document.getElementById('AutoPlay');
  437. autoMuteOp = document.getElementById('AutoMute');
  438. autoPlayRateOp = document.getElementById('AutoPlayRate');
  439. autoPlayRateChangeOp = document.getElementById('AutoPlayRateChange');
  440. autoAnswerOp = document.getElementById('AutoAnswer');
  441. autoShowAnswerOp = document.getElementById('AutoShowAnswer');
  442. autoAnswerChoicesOp = document.getElementById('AutoAnswerChoices');
  443. autoAnswerJudgesOp = document.getElementById('AutoAnswerJudges');
  444. autoAnswerFillsOp = document.getElementById('AutoAnswerFills');
  445. dragBall.draggable({
  446. containment: ".page-scroller ps ps--theme_default",
  447. start: function (event, ui) {
  448. $(this).addClass('noclick');
  449. }
  450. });
  451. dragBall.hide();
  452. mainBtn.addEventListener('click', function () {
  453. MainPanel.hide();
  454. dragBall.show();
  455. }, true);
  456. dragBall.click(function (e) {
  457. if ($(this).hasClass('noclick')) {
  458. $(this).removeClass('noclick');
  459. } else if (e.target == e.currentTarget) {
  460. MainPanel.show();
  461. $(this).hide();
  462. }
  463. });
  464. autoPlayRateChangeOp.addEventListener('change', function () {
  465. let val = autoPlayRateChangeOp.value;
  466. if (val > 15.0)
  467. autoPlayRateChangeOp.value = 15;
  468. else if (val < 0.25)
  469. autoPlayRateChangeOp.value = 0.25;
  470. }, true);
  471. autoPlayOp.addEventListener('change', function () {
  472. if (autoPlayOp.checked === false)
  473. autoMuteOp.checked = autoPlayRateOp.checked = false;
  474. else
  475. autoMuteOp.checked = autoPlayRateOp.checked = true;
  476. });
  477. autoAnswerOp.addEventListener('change', function () {
  478. if (autoAnswerOp.checked === false)
  479. autoAnswerChoicesOp.checked = autoAnswerJudgesOp.checked = autoAnswerFillsOp.checked = autoShowAnswerOp.checked = false;
  480. else
  481. autoAnswerChoicesOp.checked = autoAnswerJudgesOp.checked = autoAnswerFillsOp.checked = autoShowAnswerOp.checked = true;
  482. });
  483. saveOpBtn.addEventListener('click', function () {
  484. EnableAutoMute = autoMuteOp.checked;
  485. EnableAutoChangeRate = autoPlayRateOp.checked;
  486. EnableAutoPlay = autoPlayOp.checked;
  487. EnableAutoShowAnswer = autoShowAnswerOp.checked;
  488. EnableAutoAnswerChoices = autoAnswerChoicesOp.checked;
  489. EnableAutoAnswerJudges = autoAnswerJudgesOp.checked;
  490. EnableAutoAnswerFills = autoAnswerFillsOp.checked;
  491. if (!EnableAutoShowAnswer && !EnableAutoAnswerChoices && !EnableAutoAnswerJudges && !EnableAutoAnswerFills)
  492. autoAnswerOp.checked = false;
  493. EnableAutoFillAnswer = autoAnswerOp.checked;
  494. N = autoPlayRateChangeOp.value;
  495. // Save
  496. window.localStorage.EZUL = 'EliotZhang、BrushJIM';
  497. window.localStorage.EAM = EnableAutoMute ? 't' : 'f';
  498. window.localStorage.EACR = EnableAutoChangeRate ? 't' : 'f';
  499. window.localStorage.EAP = EnableAutoPlay ? 't' : 'f';
  500. window.localStorage.EASA = EnableAutoShowAnswer ? 't' : 'f';
  501. window.localStorage.EAAC = EnableAutoAnswerChoices ? 't' : 'f';
  502. window.localStorage.EAAJ = EnableAutoAnswerJudges ? 't' : 'f';
  503. window.localStorage.EAAF = EnableAutoAnswerFills ? 't' : 'f';
  504. window.localStorage.EAFA = EnableAutoFillAnswer ? 't' : 'f';
  505. window.localStorage.APRC = autoPlayRateChangeOp.value.toString();
  506. Video({}, true);
  507. CheckModal(true);
  508. }, true);
  509. // Load
  510. if (window.localStorage.getItem('EZUL') === 'EliotZhang、BrushJIM') {
  511. autoMuteOp.checked = EnableAutoMute = window.localStorage.EAM == 't';
  512. autoPlayRateOp.checked = EnableAutoChangeRate = window.localStorage.EACR == 't';
  513. autoPlayOp.checked = EnableAutoPlay = window.localStorage.EAP == 't';
  514. autoShowAnswerOp.checked = EnableAutoShowAnswer = window.localStorage.EASA == 't';
  515. autoAnswerChoicesOp.checked = EnableAutoAnswerChoices = window.localStorage.EAAC == 't';
  516. autoAnswerJudgesOp.checked = EnableAutoAnswerJudges = window.localStorage.EAAJ == 't';
  517. autoAnswerFillsOp.checked = EnableAutoAnswerFills = window.localStorage.EAAF == 't';
  518. autoAnswerOp.checked = EnableAutoFillAnswer = window.localStorage.EAFA == 't';
  519. autoPlayRateChangeOp.value = N = parseFloat(window.localStorage.APRC);
  520. }
  521. }
  522.  
  523. function Main() {
  524. DrawOptionPanel();
  525. Init();
  526. Video();
  527. CheckModal();
  528. }
  529.  
  530. var autoAnswering = false;
  531. var checkingModal = false;
  532. var mainBtn;
  533. var dragBall;
  534. var saveOpBtn;
  535. var OptionPanel;
  536. var MainPanel;
  537. var autoPlayOp;
  538. var autoMuteOp;
  539. var autoPlayRateOp;
  540. var autoPlayRateChangeOp;
  541. var autoAnswerOp;
  542. var autoShowAnswerOp;
  543. var autoAnswerChoicesOp;
  544. var autoAnswerJudgesOp;
  545. var autoAnswerFillsOp;
  546. var pageid = '';
  547.  
  548. setInterval(function () { unsafeWindow.document.dispatchEvent(new Event('mousemove')) }, 1000);
  549.  
  550. setTimeout(Main, '3000');
  551.  
  552. })();