Greasy Fork

MouseHunt - TEM Catch Stats

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

目前为 2019-03-21 提交的版本。查看 最新版本

// ==UserScript==
// @name         MouseHunt - TEM Catch Stats
// @author       Tran Situ (tsitu)
// @namespace    https://greasyfork.org/en/users/232363-tsitu
// @version      1.3
// @description  Adds catch/crown statistics next to mouse names on the TEM
// @match        http://www.mousehuntgame.com/*
// @match        https://www.mousehuntgame.com/*
// ==/UserScript==

(function() {
  // Observers are attached to a *specific* element (will DC if removed from DOM)
  const observerTarget = document.getElementById("tabbarContent_page");
  if (observerTarget) {
    MutationObserver =
      window.MutationObserver ||
      window.WebKitMutationObserver ||
      window.MozMutationObserver;

    const observer = new MutationObserver(function() {
      // Callback
      const labels = document.getElementsByClassName(
        "campPage-trap-trapEffectiveness-difficultyGroup-label"
      );

      // Render if difficulty labels are in DOM
      if (labels.length > 0) {
        // Disconnect and reconnect later to prevent infinite mutation loop
        observer.disconnect();

        // Clear out old spans
        // Uses static collection instead of live one from getElementsByClassName
        document
          .querySelectorAll(".mousebox.temcatches")
          .forEach(el => el.remove());

        render();

        observer.observe(observerTarget, {
          childList: true,
          subtree: true
        });
      }
    });

    observer.observe(observerTarget, {
      childList: true,
      subtree: true
    });
  }

  function postReq(form) {
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      xhr.open(
        "POST",
        `https://www.mousehuntgame.com/managers/ajax/users/profiletabs.php?action=badges&snuid=${
          user.sn_user_id
        }`,
        true
      );
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      xhr.onreadystatechange = function() {
        if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
          resolve(this);
        }
      };
      xhr.onerror = function() {
        reject(this);
      };
      xhr.send(form);
    });
  }

  function render() {
    // Render crown image and catch number next to mouse name
    const rawStore = localStorage.getItem("mh-catch-stats");
    if (rawStore) {
      const stored = JSON.parse(rawStore);
      const rows = document.getElementsByClassName(
        "campPage-trap-trapEffectiveness-mouse"
      );

      if (rows) {
        for (let row of rows) {
          const name = row.querySelector(
            ".campPage-trap-trapEffectiveness-mouse-name"
          ).innerText;
          const catches = stored[name];

          const outer = document.createElement("span");
          outer.className = "mousebox temcatches";
          outer.style.cssFloat = "none";
          outer.style.marginLeft = "10px";
          outer.style.verticalAlign = "middle";

          const inner = document.createElement("span");
          if (catches >= 10 && catches < 100) {
            inner.className = "numcatches bronze";
          } else if (catches >= 100 && catches < 500) {
            inner.className = "numcatches silver";
          } else if (catches >= 500) {
            inner.className = "numcatches gold";
          }
          inner.style.backgroundSize = "contain";
          inner.style.paddingRight = "20px";
          inner.innerText = catches || 0;

          outer.appendChild(inner);
          row.appendChild(outer);
        }
      }
    }

    const oldButton = document.getElementById("tem-catches-refresh-button");
    if (oldButton) oldButton.remove();

    // Render 'Refresh Data' button
    const refreshButton = document.createElement("button");
    refreshButton.id = "tem-catches-refresh-button";
    refreshButton.innerText = "Refresh Crown Data";
    refreshButton.addEventListener("click", function() {
      postReq("sn=Hitgrab&hg_is_ajax=1").then(res => {
        parseData(res);
      });
    });

    const container = document.getElementsByClassName(
      "campPage-trap-trapEffectiveness-content"
    )[0];
    if (container) container.appendChild(refreshButton);
  }

  /**
   * Parse badge endpoint response and write to localStorage
   * @param {string} res
   */
  function parseData(res) {
    let response = null;
    try {
      if (res) {
        response = JSON.parse(res.responseText);
        const badgeData = response["mouse_data"];
        const remainData = response["remaining_mice"];
        const catchData = {};

        for (let key of Object.keys(badgeData)) {
          catchData[badgeData[key]["name"]] = badgeData[key]["num_catches"];
        }

        for (let el of remainData) {
          const split = el["name"].split(" (");
          catchData[split[0]] = parseInt(split[1][0]);
        }

        localStorage.setItem("mh-catch-stats", JSON.stringify(catchData));

        // Close and reopen to update badges (prevents infinite render loop)
        app.pages.CampPage.closeBlueprintDrawer();
        app.pages.CampPage.toggleTrapEffectiveness(true);
      }
    } catch (error) {
      console.log("Error while processing POST response");
      console.error(error.stack);
    }
  }
})();