🐭️ MouseHunt - Location Catches

View your mouse catches in your current location

当前为 2024-03-26 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        🐭️ MouseHunt - Location Catches
// @description View your mouse catches in your current location
// @version     2.0.1
// @license     MIT
// @author      bradp
// @namespace   bradp
// @match       https://www.mousehuntgame.com/*
// @icon        https://i.mouse.rip/mh-improved/icon-64.png
// @run-at      document-end
// @grant       none
// @require     https://cdn.jsdelivr.net/npm/[email protected]
// ==/UserScript==

var mhui = (() => {
  var __defProp = Object.defineProperty;
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  var __getOwnPropNames = Object.getOwnPropertyNames;
  var __hasOwnProp = Object.prototype.hasOwnProperty;
  var __export = (target, all) => {
    for (var name in all)
      __defProp(target, name, { get: all[name], enumerable: true });
  };
  var __copyProps = (to, from, except, desc) => {
    if (from && typeof from === "object" || typeof from === "function") {
      for (let key of __getOwnPropNames(from))
        if (!__hasOwnProp.call(to, key) && key !== except)
          __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
    }
    return to;
  };
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  var __async = (__this, __arguments, generator) => {
    return new Promise((resolve, reject) => {
      var fulfilled = (value) => {
        try {
          step(generator.next(value));
        } catch (e) {
          reject(e);
        }
      };
      var rejected = (value) => {
        try {
          step(generator.throw(value));
        } catch (e) {
          reject(e);
        }
      };
      var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
      step((generator = generator.apply(__this, __arguments)).next());
    });
  };

  // src/modules/location-catch-stats/index.js
  var location_catch_stats_exports = {};
  __export(location_catch_stats_exports, {
    default: () => location_catch_stats_default
  });

  // src/utils/event-registry.js
  var onEvent = (event, callback, remove = false) => {
    if (!eventRegistry) {
      return;
    }
    eventRegistry.addEventListener(event, callback, null, remove);
  };

  // src/utils/styles.js
  var addModuleStyles = (styles, identifier = "mh-improved-styles", replace = false) => {
    const existingStyles = document.querySelector(`#${identifier}`);
    styles = Array.isArray(styles) ? styles.join("\n") : styles;
    if (existingStyles) {
      if (replace) {
        existingStyles.innerHTML = styles;
      } else {
        existingStyles.innerHTML += styles;
      }
      return existingStyles;
    }
    const style = document.createElement("style");
    style.id = identifier;
    style.innerHTML = styles;
    document.head.append(style);
    return style;
  };
  var addStyles = (styles, module = false, identifier = "mh-improved-styles") => {
    if (!module) {
      throw new Error("Module ID is required for adding module styles.", module);
    }
    const key = `${identifier}-${module}`;
    let stylesEl = addModuleStyles(styles, key, true);
    onEvent(`mh-improved-settings-changed-${module}`, (enabled) => {
      if (enabled) {
        stylesEl = addModuleStyles(styles, key, true);
      } else if (stylesEl) {
        stylesEl.remove();
      }
    });
  };

  // src/utils/draggable.js
  var makeElementDraggable = (dragTarget, dragHandle, defaultX = null, defaultY = null, storageKey = null, savePosition = true) => {
    const modal = document.querySelector(dragTarget);
    if (!modal) {
      return;
    }
    const handle = document.querySelector(dragHandle);
    if (!handle) {
      return;
    }
    const keepWithinLimits = (type, value) => {
      if ("top" === type) {
        return value < -20 ? -20 : value;
      }
      if (value < handle.offsetWidth * -1 + 20) {
        return handle.offsetWidth * -1 + 20;
      }
      if (value > document.body.clientWidth - 20) {
        return document.body.clientWidth - 20;
      }
      return value;
    };
    const onMouseDown = (e) => {
      e.preventDefault();
      setTimeout(() => {
        x1 = e.clientX;
        y1 = e.clientY;
        modal.classList.add("mh-is-dragging");
        document.onmousemove = onDrag;
        document.onmouseup = finishDrag;
      }, 50);
    };
    const finishDrag = () => {
      document.onmouseup = null;
      document.onmousemove = null;
      modal.classList.remove("mh-is-dragging");
      if (storageKey) {
        localStorage.setItem(storageKey, JSON.stringify({ x: modal.offsetLeft, y: modal.offsetTop }));
      }
    };
    const onDrag = (e) => {
      e.preventDefault();
      x2 = x1 - e.clientX;
      y2 = y1 - e.clientY;
      x1 = e.clientX;
      y1 = e.clientY;
      const newLeft = keepWithinLimits("left", modal.offsetLeft - x2);
      const newTop = keepWithinLimits("top", modal.offsetTop - y2);
      modal.style.left = `${newLeft}px`;
      modal.style.top = `${newTop}px`;
    };
    let startX = defaultX || 0;
    let startY = defaultY || 0;
    if (!storageKey) {
      storageKey = `mh-draggable-${dragTarget}-${dragHandle}`;
    }
    if (savePosition) {
      const storedPosition = localStorage.getItem(storageKey);
      if (storedPosition) {
        const position = JSON.parse(storedPosition);
        startX = keepWithinLimits("left", position.x);
        startY = keepWithinLimits("top", position.y);
      }
    }
    modal.style.left = `${startX}px`;
    modal.style.top = `${startY}px`;
    let x1 = 0, y1 = 0, x2 = 0, y2 = 0;
    handle.onmousedown = onMouseDown;
  };

  // src/utils/links.js
  var getCleanSubmenuLabel = (label) => {
    return label.toLowerCase().replaceAll(/[^\da-z]/g, "-");
  };
  var addSubmenuItem = (options) => {
    const settings = Object.assign({}, {
      id: null,
      menu: "kingdom",
      label: "",
      icon: "https://www.mousehuntgame.com/images/ui/hud/menu/special.png",
      href: "",
      class: "",
      callback: null,
      external: false
    }, options);
    const menuTarget = document.querySelector(`.mousehuntHud-menu .${settings.menu}`);
    if (!menuTarget) {
      return;
    }
    if (!menuTarget.classList.contains("hasChildren")) {
      menuTarget.classList.add("hasChildren");
    }
    let hasSubmenu = true;
    let submenu = menuTarget.querySelector("ul");
    if (!submenu) {
      hasSubmenu = false;
      submenu = document.createElement("ul");
    }
    const item = document.createElement("li");
    item.classList.add("custom-submenu-item");
    const label = settings.label.length > 0 ? settings.label : settings.id;
    const cleanLabel = getCleanSubmenuLabel(label);
    const exists = document.querySelector(`#custom-submenu-item-${cleanLabel}`);
    if (exists) {
      exists.remove();
    }
    item.id = settings.id ? `custom-submenu-item-${settings.id}` : `custom-submenu-item-${cleanLabel}`;
    if (settings.class) {
      const classes = settings.class.split(" ");
      item.classList.add(...classes);
    }
    const link = document.createElement("a");
    link.href = settings.href || "#";
    if (settings.callback) {
      link.addEventListener("click", (e) => {
        e.preventDefault();
        settings.callback();
      });
    }
    const icon = document.createElement("div");
    icon.classList.add("icon");
    icon.style = `background-image: url(${settings.icon});`;
    const name = document.createElement("div");
    name.classList.add("name");
    name.innerHTML = settings.label;
    link.append(icon);
    link.append(name);
    if (settings.external) {
      const externalLinkIcon = document.createElement("div");
      externalLinkIcon.classList.add("external_icon");
      link.append(externalLinkIcon);
      link.target = "_blank";
      link.rel = "noopener noreferrer";
    }
    item.append(link);
    submenu.append(item);
    if (!hasSubmenu) {
      menuTarget.append(submenu);
    }
  };

  // src/utils/messages.js
  hadAddedErrorStyles = false;

  // src/utils/utils.js
  var doRequest = (_0, ..._1) => __async(void 0, [_0, ..._1], function* (url, formData = {}) {
    var _a;
    if ("undefined" === typeof lastReadJournalEntryId || "undefined" === typeof user) {
      return;
    }
    if (!lastReadJournalEntryId || !user || !(user == null ? void 0 : user.unique_hash)) {
      return;
    }
    const form = new FormData();
    form.append("sn", "Hitgrab");
    form.append("hg_is_ajax", 1);
    form.append("last_read_journal_entry_id", lastReadJournalEntryId != null ? lastReadJournalEntryId : 0);
    form.append("uh", (_a = user == null ? void 0 : user.unique_hash) != null ? _a : "");
    for (const key in formData) {
      form.append(key, formData[key]);
    }
    const requestBody = new URLSearchParams(form).toString();
    const response = yield fetch(
      callbackurl ? callbackurl + url : "https://www.mousehuntgame.com/" + url,
      {
        method: "POST",
        body: requestBody,
        headers: {
          "Content-Type": "application/x-www-form-urlencoded"
        }
      }
    );
    const data = yield response.json();
    return data;
  });

  // src/modules/location-catch-stats/styles.css
  var styles_default = "#mh-catch-stats{position:absolute;top:25px;left:25px;z-index:50}@media screen and (prefers-reduced-motion: reduce){.mh-catch-stats-wrapper{transition:none}}.mh-catch-stats-wrapper{width:275px;background:#f6f3eb;border:1px solid #534022;box-shadow:1px 1px 1px #9d917f,1px 3px 5px #6a6969;transition:box-shadow .25s}.mh-is-dragging .mh-catch-stats-wrapper{box-shadow:1px 1px 1px #9d917f,0 7px 9px 2px #6a6969}.mh-catch-stats-header{display:flex;align-items:center;justify-content:space-between;padding:10px;color:#f6f3eb;cursor:grab;background-color:#926944;border-bottom:1px solid #ceb7a6}.mh-catch-stats-header h1{color:#f6f3eb}.mh-catch-stats-close{cursor:pointer}.mh-catch-stats-close:hover,.mh-catch-stats-close:focus{color:#926944;background-color:#eee;border-radius:50%;outline:1px solid #ccc}.mh-catch-stats-body{max-height:90vh;overflow:hidden auto}.mh-catch-stats-wrapper .mh-catch-stats:nth-child(odd){background-color:#e8e3d7}.mh-catch-stats{display:flex;align-items:center;justify-content:space-between;padding:10px;color:#000}.mh-catch-stats:hover,.mh-catch-stats-wrapper .mh-catch-stats:nth-child(odd):hover,.mh-catch-stats:focus,.mh-catch-stats-wrapper .mh-catch-stats:nth-child(odd):focus{color:#665f5f;text-decoration:none;background-color:#eee;outline:1px solid #ccc}.mh-catch-stats-image{position:relative;display:inline-block;width:40px;height:40px;vertical-align:middle;background-repeat:no-repeat;background-size:contain;border-radius:2px;box-shadow:1px 1px 1px #999}.mh-catch-stats-crown{position:absolute;right:-5px;bottom:-5px;width:20px;height:20px;background-color:#fff;background-repeat:no-repeat;background-position:50% 50%;background-size:80%;border:1px solid #333;border-radius:50%}.mh-catch-stats-name{display:inline-block;padding-left:10px;vertical-align:middle}.mh-catch-stats-catches{padding-right:5px}\n";

  // src/modules/location-catch-stats/index.js
  var getMouseStats = () => __async(void 0, null, function* () {
    var _a, _b;
    const data = yield doRequest("managers/ajax/mice/mouse_list.php", {
      action: "get_environment",
      category: user.environment_type,
      user_id: user.user_id,
      display_mode: "stats",
      view: "ViewMouseListEnvironments"
    });
    const mouseData = (_b = (_a = data == null ? void 0 : data.mouse_list_category) == null ? void 0 : _a.subgroups[0]) == null ? void 0 : _b.mice;
    mouseData.sort((a, b) => {
      return b.num_catches - a.num_catches;
    });
    return mouseData != null ? mouseData : [];
  });
  var buildMouseMarkup = (mouseData) => {
    const mouse = Object.assign({}, {
      name: "",
      type: "",
      image: "",
      crown: "none",
      num_catches: 0
    }, mouseData);
    const mouseEl = document.createElement("a");
    mouseEl.classList.add("mh-catch-stats");
    mouseEl.title = mouse.name;
    mouseEl.addEventListener("click", () => {
      var _a, _b;
      if ("undefined" !== ((_b = (_a = hg == null ? void 0 : hg.views) == null ? void 0 : _a.MouseView) == null ? void 0 : _b.show)) {
        hg.views.MouseView.show(mouse.type);
      }
    });
    const image = document.createElement("div");
    image.classList.add("mh-catch-stats-image");
    image.style.backgroundImage = `url('${mouse.image}')`;
    if (mouse.crown && "none" !== mouse.crown) {
      const crown = document.createElement("div");
      crown.classList.add("mh-catch-stats-crown");
      crown.style.backgroundImage = `url('https://www.mousehuntgame.com/images/ui/crowns/crown_${mouse.crown}.png')`;
      image.append(crown);
    }
    const name = document.createElement("div");
    name.classList.add("mh-catch-stats-name");
    name.innerText = mouse.name;
    const imageNameContainer = document.createElement("div");
    imageNameContainer.append(image);
    imageNameContainer.append(name);
    const catches = document.createElement("div");
    catches.classList.add("mh-catch-stats-catches");
    catches.innerText = mouse.num_catches;
    mouseEl.append(imageNameContainer);
    mouseEl.append(catches);
    return mouseEl;
  };
  var showModal = () => __async(void 0, null, function* () {
    const existing = document.querySelector("#mh-catch-stats");
    if (existing) {
      existing.remove();
    }
    const modalWrapper = document.createElement("div");
    modalWrapper.id = "mh-catch-stats";
    const modal = document.createElement("div");
    modal.classList.add("mh-catch-stats-wrapper");
    const header = document.createElement("div");
    header.classList.add("mh-catch-stats-header");
    const title = document.createElement("h1");
    title.innerText = "Location Catch Stats";
    header.append(title);
    const closeIcon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
    closeIcon.classList.add("mh-catch-stats-close");
    closeIcon.setAttribute("viewBox", "0 0 24 24");
    closeIcon.setAttribute("width", "18");
    closeIcon.setAttribute("height", "18");
    closeIcon.setAttribute("fill", "none");
    closeIcon.setAttribute("stroke", "currentColor");
    closeIcon.setAttribute("stroke-width", "1.5");
    const closePath = document.createElementNS("http://www.w3.org/2000/svg", "path");
    closePath.setAttribute("d", "M18 6L6 18M6 6l12 12");
    closeIcon.append(closePath);
    closeIcon.addEventListener("click", () => {
      modalWrapper.remove();
    });
    header.append(closeIcon);
    modal.append(header);
    const mouseBody = document.createElement("div");
    mouseBody.classList.add("mh-catch-stats-body");
    const mouseStats = yield getMouseStats();
    mouseStats.forEach((mouseData) => {
      mouseBody.append(buildMouseMarkup(mouseData, mouseBody));
    });
    modal.append(mouseBody);
    modalWrapper.append(modal);
    document.body.append(modalWrapper);
    makeElementDraggable("#mh-catch-stats", ".mh-catch-stats-header", 25, 25, "mh-catch-stats-position");
  });
  var init = () => __async(void 0, null, function* () {
    addStyles(styles_default, "location-catch-stats");
    addSubmenuItem({
      menu: "mice",
      label: "Location Catch Stats",
      icon: "https://www.mousehuntgame.com/images/ui/hud/menu/prize_shoppe.png?",
      callback: showModal
    });
  });
  var location_catch_stats_default = {
    id: "location-catch-stats",
    name: "Location Catch Stats",
    type: "feature",
    default: true,
    description: 'Adds a "Location Catch Stats" to the Mice menu to see your catch stats for the current location.',
    load: init
  };
  return __toCommonJS(location_catch_stats_exports);
})();
mhui.default.load();
migrateUserscript('Location Catches', '2.0.1', 'https://greasyfork.org/en/scripts/463018-mousehunt-location-catches');