MouseHunt - TEM Catch Stats

Add catch/crown statistics next to mouse names on the TEM

当前为 2019-01-17 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name MouseHunt - TEM Catch Stats
  3. // @author Tran Situ (tsitu)
  4. // @namespace https://greasyfork.org/en/users/232363-tsitu
  5. // @version 1.2
  6. // @description Add catch/crown statistics next to mouse names on the TEM
  7. // @match http://www.mousehuntgame.com/*
  8. // @match https://www.mousehuntgame.com/*
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. // Observers are attached to a *specific* element (will DC if removed from DOM)
  13. const observerTarget = document.getElementById("tabbarContent_page");
  14. if (observerTarget) {
  15. MutationObserver =
  16. window.MutationObserver ||
  17. window.WebKitMutationObserver ||
  18. window.MozMutationObserver;
  19.  
  20. const observer = new MutationObserver(function() {
  21. // Callback
  22. const labels = document.getElementsByClassName(
  23. "campPage-trap-trapEffectiveness-difficultyGroup-label"
  24. );
  25.  
  26. // Render if difficulty labels are in DOM
  27. if (labels.length > 0) {
  28. // Disconnect and reconnect later to prevent infinite mutation loop
  29. observer.disconnect();
  30.  
  31. // Clear out old spans
  32. // Uses static collection instead of live one from getElementsByClassName
  33. document
  34. .querySelectorAll(".mousebox.temcatches")
  35. .forEach(el => el.remove());
  36.  
  37. render();
  38.  
  39. observer.observe(observerTarget, {
  40. childList: true,
  41. subtree: true
  42. });
  43. }
  44. });
  45.  
  46. observer.observe(observerTarget, {
  47. childList: true,
  48. subtree: true
  49. });
  50. }
  51.  
  52. function postReq(form) {
  53. return new Promise((resolve, reject) => {
  54. const xhr = new XMLHttpRequest();
  55. xhr.open(
  56. "POST",
  57. `https://www.mousehuntgame.com/managers/ajax/users/profiletabs.php?action=badges&snuid=${
  58. user.sn_user_id
  59. }`,
  60. true
  61. );
  62. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  63. xhr.onreadystatechange = function() {
  64. if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
  65. resolve(this);
  66. }
  67. };
  68. xhr.onerror = function() {
  69. reject(this);
  70. };
  71. xhr.send(form);
  72. });
  73. }
  74.  
  75. function render() {
  76. // Render crown image and catch number next to mouse name
  77. const rawStore = localStorage.getItem("mh-catch-stats");
  78. if (rawStore) {
  79. const stored = JSON.parse(rawStore);
  80. const rows = document.getElementsByClassName(
  81. "campPage-trap-trapEffectiveness-mouse"
  82. );
  83.  
  84. if (rows) {
  85. for (let row of rows) {
  86. const name = row.querySelector(
  87. ".campPage-trap-trapEffectiveness-mouse-name"
  88. ).innerText;
  89. const catches = stored[name];
  90.  
  91. const outer = document.createElement("span");
  92. outer.className = "mousebox temcatches";
  93. outer.style.cssFloat = "none";
  94. outer.style.marginLeft = "10px";
  95. outer.style.verticalAlign = "middle";
  96.  
  97. const inner = document.createElement("span");
  98. if (catches >= 10 && catches < 100) {
  99. inner.className = "numcatches bronze";
  100. } else if (catches >= 100 && catches < 500) {
  101. inner.className = "numcatches silver";
  102. } else if (catches >= 500) {
  103. inner.className = "numcatches gold";
  104. }
  105. inner.style.backgroundSize = "contain";
  106. inner.style.paddingRight = "20px";
  107. inner.innerText = catches;
  108.  
  109. outer.appendChild(inner);
  110. row.appendChild(outer);
  111. }
  112. }
  113. }
  114.  
  115. const oldButton = document.getElementById("tem-catches-refresh-button");
  116. if (oldButton) oldButton.remove();
  117.  
  118. // Render 'Refresh Data' button
  119. const refreshButton = document.createElement("button");
  120. refreshButton.id = "tem-catches-refresh-button";
  121. refreshButton.innerText = "Refresh Crown Data";
  122. refreshButton.addEventListener("click", function() {
  123. postReq("sn=Hitgrab&hg_is_ajax=1").then(res => {
  124. parseData(res);
  125. });
  126. });
  127.  
  128. const container = document.getElementsByClassName(
  129. "campPage-trap-trapEffectiveness-content"
  130. )[0];
  131. if (container) container.appendChild(refreshButton);
  132. }
  133.  
  134. /**
  135. * Parse badge endpoint response and write to localStorage
  136. * @param {string} res
  137. */
  138. function parseData(res) {
  139. let response = null;
  140. try {
  141. if (res) {
  142. response = JSON.parse(res.responseText);
  143. const badgeData = response["mouse_data"];
  144. const remainData = response["remaining_mice"];
  145. const catchData = {};
  146.  
  147. for (let key of Object.keys(badgeData)) {
  148. catchData[badgeData[key]["name"]] = badgeData[key]["num_catches"];
  149. }
  150.  
  151. for (let el of remainData) {
  152. const split = el["name"].split(" (");
  153. catchData[split[0]] = parseInt(split[1][0]);
  154. }
  155.  
  156. localStorage.setItem("mh-catch-stats", JSON.stringify(catchData));
  157.  
  158. // Close and reopen to update badges (prevents infinite render loop)
  159. app.pages.CampPage.closeBlueprintDrawer();
  160. app.pages.CampPage.toggleTrapEffectiveness(true);
  161. }
  162. } catch (error) {
  163. console.log("Error while processing POST response");
  164. console.error(error.stack);
  165. }
  166. }
  167. })();