iChineseReader Cheat

Anti too fast and quiz answers for iChineseReader.com

  1. // ==UserScript==
  2. // @name iChineseReader Cheat
  3. // @namespace s_ambigious
  4. // @version 1
  5. // @license MIT
  6. // @description Anti too fast and quiz answers for iChineseReader.com
  7. // @author @ambigious
  8. // @match *://*.ichinesereader.com/*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=ichinesereader.com
  10. // @grant GM_registerMenuCommand
  11. // @grant unsafeWindow
  12. // @require https://cdn.jsdelivr.net/npm/@violentmonkey/shortcut@1
  13. // ==/UserScript==
  14.  
  15. function create(tag, attrs, attach, ...children) {
  16. const element = document.createElement(tag);
  17.  
  18. if (attrs.events) {
  19. for (let [event, callback] of Object.entries(attrs.events)) {
  20. element.addEventListener(event, callback);
  21. }
  22. }
  23.  
  24. if (attrs.styles) {
  25. for (let [style, value] of Object.entries(attrs.styles)) {
  26. element.style[style] = value;
  27. }
  28. }
  29.  
  30. for (let [attr, value] of Object.entries(
  31. (({ events, styles, ...o }) => o)(attrs),
  32. )) {
  33. element.setAttribute(attr, value);
  34. }
  35.  
  36. if (children) {
  37. for (let child of children) {
  38. if (child instanceof HTMLElement) element.appendChild(child);
  39. else element.appendChild(document.createTextNode(child.toString()));
  40. }
  41. }
  42.  
  43. if (attach) attach.appendChild(element);
  44. else return element;
  45. }
  46.  
  47. window.addEventListener(
  48. "load",
  49. () => {
  50. const { register } = VM.shortcut;
  51.  
  52. async function answers() {
  53. const quiz = await (await fetch(
  54. performance
  55. .getEntries()
  56. .filter(e => e instanceof PerformanceResourceTiming)
  57. .map(e => e.name)
  58. .filter(e =>
  59. e.includes("api.ichinesereader.com/superadmin/quiz"),
  60. )
  61. .at(-1),
  62. {
  63. headers: {
  64. authtoken: Object.fromEntries(
  65. document.cookie
  66. .split(";")
  67. .map(e => e.split("=").map(e => e.trim())),
  68. ).nanhaiIndividualSession.concat("="),
  69. },
  70. },
  71. )).json();
  72.  
  73. const data = await (await fetch(quiz.book.quizLinkUrl)).json();
  74.  
  75. create("div", {}, window.open().document.body,
  76. create("style", {}, null,
  77. await (
  78. await fetch(
  79. "https://cdn.jsdelivr.net/npm/water.css@2/out/water.css",
  80. )
  81. ).text(),
  82. ),
  83. create("h1", {}, null, `Quiz Answers for ${data.simp_name}`),
  84. create("table", {}, null,
  85. create("thead", {}, null,
  86. create("tr", {}, null,
  87. create("th", {}, null, "Question"),
  88. create("th", {}, null, "Answer"),
  89. ),
  90. ),
  91. create("tbody", {}, null,
  92. ...data.questions
  93. .map(e => e.answers.find(e => e.isCorrect))
  94. .map((e, i) =>
  95. create("tr", {}, null,
  96. create("td", {}, null, i + 1),
  97. create("td", {}, null, e.simp_answer),
  98. ),
  99. ),
  100. ),
  101. ),
  102. );
  103.  
  104. /*console.log(
  105. data.questions.map(e =>
  106. e.answers
  107. .filter(e => e.isCorrect)
  108. .map((e, i) =>
  109. create(
  110. "tr",
  111. {},
  112. null,
  113. create("td", {}, null, i + 1),
  114. create("td", {}, null, e.simp_answer),
  115. ),
  116. ),
  117. ),
  118. );*/
  119. }
  120.  
  121. function anti() {
  122. const bookFrame = document
  123. .querySelector("iframe").contentDocument
  124. .querySelector("iframe").contentWindow;
  125.  
  126. bookFrame.userRole = "TEACHER";
  127. }
  128.  
  129. GM_registerMenuCommand("Anti too fast", anti);
  130. register("ctrl-alt-s", anti);
  131.  
  132. GM_registerMenuCommand("Get answers (Opens in new tab)", answers);
  133. register("ctrl-alt-a", answers);
  134. },
  135. false,
  136. );