- // ==UserScript==
- // @name 🐭️ MouseHunt - Better Mice
- // @description Adds an attraction rate table from MHCT, links to the MouseHunt wiki and MHCT, as well as various other features to the mouse view page.
- // @version 2.1.0
- // @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/script-migration@1.1.1
- // ==/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/better-mice/index.js
- var better_mice_exports = {};
- __export(better_mice_exports, {
- default: () => better_mice_default
- });
-
- // src/utils/event-registry.js
- var eventsAdded = {};
- var onEvent = (event, callback, remove = false) => {
- if (!eventRegistry) {
- return;
- }
- const id = `${event}-${remove.toString()}-${callback.toString()}`;
- if (eventsAdded[id]) {
- return;
- }
- eventsAdded[id] = true;
- eventRegistry.addEventListener(event, callback, null, remove);
- };
-
- // src/utils/styles.js
- var addStylesDirect = (styles, identifier = "mh-utils-custom-styles", once = false) => {
- identifier = `mh-utils-${identifier}`;
- const existingStyles = document.querySelector(`#${identifier}`);
- if (existingStyles) {
- if (once) {
- return existingStyles;
- }
- existingStyles.innerHTML += styles;
- return existingStyles;
- }
- const style = document.createElement("style");
- style.id = identifier;
- style.innerHTML = styles;
- document.head.append(style);
- return style;
- };
- 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/settings.js
- var getSettingDirect = (key = null, defaultValue = null, identifier = "mousehunt-improved-settings") => {
- const settings = JSON.parse(localStorage.getItem(identifier)) || {};
- if (!key) {
- return settings;
- }
- if (!key.includes(".")) {
- if (settings[key] === void 0) {
- return defaultValue;
- }
- return settings[key];
- }
- const groupAndKey = getGroupAndKey(key);
- if (!groupAndKey.group) {
- if (settings[groupAndKey.key] === void 0) {
- return defaultValue;
- }
- return settings[groupAndKey.key];
- }
- const groupSettings = settings[groupAndKey.group] || {};
- if (groupSettings[groupAndKey.key] === void 0) {
- return defaultValue;
- }
- return groupSettings[groupAndKey.key];
- };
- var saveSettingDirect = (key, value, identifier = "mousehunt-improved-settings") => {
- const settings = getSettingDirect(null, {}, identifier);
- const groupAndKey = getGroupAndKey(key);
- if (groupAndKey.group) {
- if (!settings[groupAndKey.group]) {
- settings[groupAndKey.group] = {};
- }
- settings[groupAndKey.group][groupAndKey.key] = value;
- } else {
- settings[key] = value;
- }
- localStorage.setItem(identifier, JSON.stringify(settings));
- };
- var getGroupAndKey = (key) => {
- const split = key.split(".");
- if (split.length === 1) {
- return {
- group: null,
- key: split[0]
- };
- }
- if (split[0] === "location-huds-enabled") {
- return {
- group: "location-huds-enabled",
- key: split[1]
- };
- }
- return {
- group: `${split[0]}-settings`,
- key: split[1]
- };
- };
- var getSetting = (key, defaultValue = false) => {
- return getSettingDirect(key, defaultValue, "mousehunt-improved-settings");
- };
- var saveSetting = (key, value) => {
- saveSettingDirect(key, value, "mousehunt-improved-settings");
- return value;
- };
-
- // src/utils/styles/favorite-button.css
- var favorite_button_default = ".custom-favorite-button{top:0;right:0;display:inline-block;width:35px;height:35px;vertical-align:middle;background:url(https://www.mousehuntgame.com/images/ui/camp/trap/star_empty.png?asset_cache_version=2) 50% 50% no-repeat;background-size:90%;border-radius:50%}.custom-favorite-button-small{width:20px;height:20px}.custom-favorite-button:hover{background-color:#fff;background-image:url(https://www.mousehuntgame.com/images/ui/camp/trap/star_favorite.png?asset_cache_version=2);outline:2px solid #ccc}.custom-favorite-button.active{background-image:url(https://www.mousehuntgame.com/images/ui/camp/trap/star_favorite.png?asset_cache_version=2)}.custom-favorite-button.busy{background-image:url(https://www.mousehuntgame.com/images/ui/loaders/small_spinner.gif?asset_cache_version=2)}\n";
-
- // src/utils/elements.js
- var makeElement = (tag, classes = "", text = "", appendTo = null) => {
- const element = document.createElement(tag);
- if (Array.isArray(classes)) {
- classes = classes.join(" ");
- }
- if (classes && classes.length) {
- element.className = classes;
- }
- element.innerHTML = text;
- if (appendTo) {
- appendTo.append(element);
- return appendTo;
- }
- return element;
- };
- var makeLink = (text, href, encodeAsSpace = false) => {
- if (encodeAsSpace) {
- href = href.replaceAll("_", "%20");
- }
- return `<a href="${href}" target="_mouse" class="mousehuntActionButton tiny"><span>${text}</span></a>`;
- };
- var makeFavoriteButton = (options) => __async(void 0, null, function* () {
- addStylesDirect(favorite_button_default, "mh-improved-styles-favorite-button", true);
- const {
- id = null,
- target = null,
- size = "small",
- state = false,
- isSetting = true,
- defaultState = false,
- onChange = null,
- onActivate = null,
- onDeactivate = null
- } = options;
- const existing = document.querySelector(`#${id}`);
- if (existing) {
- existing.remove();
- }
- const star = document.createElement("a");
- star.classList.add("custom-favorite-button");
- if (size === "small") {
- star.classList.add("custom-favorite-button-small");
- }
- star.id = id;
- star.setAttribute("data-item-id", id);
- star.setAttribute("href", "#");
- star.style.display = "inline-block";
- let currentSetting = false;
- currentSetting = isSetting ? getSetting(id, defaultState) : state;
- if (currentSetting) {
- star.classList.add("active");
- } else {
- star.classList.add("inactive");
- }
- star.addEventListener("click", (e) => __async(void 0, null, function* () {
- star.classList.add("busy");
- e.preventDefault();
- e.stopPropagation();
- const currentStar = e.target;
- const currentState = !currentStar.classList.contains("active");
- if (onChange !== null) {
- yield onChange(currentState);
- } else if (isSetting) {
- saveSetting(id, currentState);
- }
- currentStar.classList.remove("inactive");
- currentStar.classList.remove("active");
- if (currentState) {
- currentStar.classList.add("active");
- if (onActivate !== null) {
- yield onActivate(currentState);
- }
- } else {
- currentStar.classList.add("inactive");
- if (onDeactivate !== null) {
- yield onDeactivate(currentState);
- }
- }
- setTimeout(() => {
- currentStar.classList.remove("busy");
- }, 300);
- }));
- if (target) {
- target.append(star);
- }
- return star;
- });
- var makeTooltip = (options) => {
- if (!options.appendTo) {
- return false;
- }
- const { appendTo, className = "", text = "" } = options;
- const tooltip = makeElement("div", ["PreferencesPage__blackTooltip", "mh-improved-tooltip", className]);
- makeElement("span", "PreferencesPage__blackTooltipText", text, tooltip);
- appendTo.append(tooltip);
- return tooltip;
- };
-
- // src/utils/db.js
- var database = (databaseName) => __async(void 0, null, function* () {
- return new Promise((resolve, reject) => {
- const request = indexedDB.open(`mh-improved-${databaseName}`, 6);
- request.onerror = (event) => {
- reject(event.target.error);
- };
- request.onsuccess = (event) => {
- resolve(event.target.result);
- };
- request.onupgradeneeded = (event) => {
- const db = event.target.result;
- if (!db.objectStoreNames.contains(databaseName)) {
- db.createObjectStore(databaseName, { keyPath: "id" });
- }
- };
- });
- });
- var dbGet = (databaseName, id) => __async(void 0, null, function* () {
- const db = yield database(databaseName);
- const transaction = db.transaction(databaseName, "readonly");
- transaction.onerror = (event) => {
- throw new Error(event.target.error);
- };
- const objectStore = transaction.objectStore(databaseName);
- const request = objectStore.get(id);
- return new Promise((resolve, reject) => {
- request.onsuccess = () => {
- resolve(request.result);
- };
- request.onerror = () => {
- reject(request.error);
- };
- transaction.oncomplete = () => {
- db.close();
- };
- });
- });
- var dbSet = (databaseName, data) => __async(void 0, null, function* () {
- const db = yield database(databaseName);
- const transaction = db.transaction(databaseName, "readwrite");
- const objectStore = transaction.objectStore(databaseName);
- data = {
- data,
- id: data.id || Date.now()
- };
- const request = objectStore.put(data);
- return new Promise((resolve, reject) => {
- request.onsuccess = () => {
- resolve(request.result);
- };
- request.onerror = () => {
- reject(request.error);
- };
- transaction.oncomplete = () => {
- db.close();
- };
- });
- });
- var dbDelete = (databaseName, id) => __async(void 0, null, function* () {
- const db = yield database(databaseName);
- const transaction = db.transaction(databaseName, "readwrite");
- const objectStore = transaction.objectStore(databaseName);
- const request = objectStore.delete(id);
- return new Promise((resolve, reject) => {
- request.onsuccess = () => {
- resolve(request.result);
- };
- request.onerror = () => {
- reject(request.error);
- };
- transaction.oncomplete = () => {
- db.close();
- };
- });
- });
- var dbDeleteAll = (databaseName) => __async(void 0, null, function* () {
- const db = yield database(databaseName);
- const transaction = db.transaction(databaseName, "readwrite");
- const objectStore = transaction.objectStore(databaseName);
- const request = objectStore.clear();
- return new Promise((resolve, reject) => {
- request.onsuccess = () => {
- resolve(request.result);
- };
- request.onerror = () => {
- reject(request.error);
- };
- transaction.oncomplete = () => {
- db.close();
- };
- });
- });
-
- // src/utils/global.js
- var getGlobal = (key) => {
- if (window && window.mhui) {
- return window.mhui[key] || false;
- }
- if ("undefined" !== typeof app && app && app.mhui) {
- return app.mhui[key] || false;
- }
- return false;
- };
-
- // src/utils/debug.js
- var debuglog = (module, message, ...args) => {
- if (getSetting("debug.all", false) || getSetting(`debug.${module}`, false) || getGlobal("mh-improved-updating")) {
- console.log(
- `%cMH Improved %c${module}%c ${message}`,
- "color: #90588c; font-weight: 900",
- "color: #90588c; font-weight: 400",
- "color: inherit; font-weight: inherit",
- ...args
- );
- }
- };
-
- // src/utils/data.js
- var validDataFiles = /* @__PURE__ */ new Set([
- "effs",
- "environments-events",
- "environments",
- "item-thumbnails",
- "items-tradable",
- "m400-locations",
- "marketplace-hidden-items",
- "mice-groups",
- "mice-regions",
- "mice-thumbnails",
- "minlucks",
- "relic-hunter-hints",
- "scoreboards",
- "ultimate-checkmark",
- "upscaled-images",
- "wisdom"
- ]);
- var isValidDataFile = (file) => {
- return validDataFiles.has(file);
- };
- var getCacheExpiration = (key = null) => __async(void 0, null, function* () {
- return yield cacheGet(`expiration-${key}`, false);
- });
- var setCacheExpiration = (key) => __async(void 0, null, function* () {
- debuglog("utils-data", `Setting cache expiration for ${key}`);
- cacheSet(`expiration-${key}`, Date.now() + (Math.floor(Math.random() * 7) + 7) * 24 * 60 * 60 * 1e3);
- });
- var isCacheExpired = (key) => __async(void 0, null, function* () {
- const expiration = yield getCacheExpiration(key);
- if (!expiration) {
- return true;
- }
- return expiration.date < Date.now();
- });
- var fetchData = (key, retries = 0) => __async(void 0, null, function* () {
- try {
- const data = yield fetch(`https://api.mouse.rip/${key}`, {
- method: "GET",
- headers: getHeaders()
- });
- return yield data.json();
- } catch (error) {
- console.error(`Error fetching data for ${key}:`, error);
- if (retries >= 3) {
- return false;
- }
- yield new Promise((resolve) => setTimeout(resolve, 500 * retries));
- return fetchData(key, retries + 1);
- }
- });
- var getData = (key) => __async(void 0, null, function* () {
- if (!isValidDataFile(key)) {
- debuglog("utils-data", `Cannot get data for ${key}, invalid key`);
- return false;
- }
- const isExpired = yield isCacheExpired(key);
- if (!isExpired) {
- const cachedData = yield dataCacheGet(key, false);
- if (cachedData) {
- return cachedData;
- }
- }
- debuglog("utils-data", `Fetching data for ${key}\u2026`);
- const data = yield fetchData(key);
- debuglog("utils-data", `Fetched data for ${key}`, data);
- if (data) {
- dataCacheSet(key, data);
- setCacheExpiration(key);
- }
- return data;
- });
- var clearCaches = () => __async(void 0, null, function* () {
- validDataFiles.forEach((file) => {
- dbDelete("data", file);
- });
- dbDeleteAll("ar-cache");
- for (const key of Object.keys(localStorage)) {
- if (key.startsWith("mh-improved-cache")) {
- localStorage.removeItem(key);
- }
- }
- for (const key of Object.keys(sessionStorage)) {
- if (key.startsWith("mh-improved")) {
- sessionStorage.removeItem(key);
- }
- }
- yield dbDelete("cache", "expirations");
- });
- var getHeaders = () => {
- return {
- "Content-Type": "application/json",
- "X-MH-Improved": "true",
- "X-MH-Improved-Version": mhImprovedVersion || "unknown",
- "X-MH-Improved-Platform": mhImprovedPlatform || "unknown"
- };
- };
- var sessionSet = (key, value, retry = false) => {
- if (getSetting("debug.no-cache")) {
- return;
- }
- key = `mh-improved-${key}`;
- const stringified = JSON.stringify(value);
- try {
- sessionStorage.setItem(key, stringified);
- } catch (error) {
- if ("QuotaExceededError" === error.name && !retry) {
- clearCaches();
- sessionSet(key, value, true);
- }
- }
- };
- var sessionGet = (key, defaultValue = false) => {
- if (getSetting("debug.no-cache")) {
- return defaultValue;
- }
- key = `mh-improved-${key}`;
- const value = sessionStorage.getItem(key);
- if (!value) {
- return defaultValue;
- }
- return JSON.parse(value);
- };
- var cacheSet = (key, value) => {
- dbSet("cache", { id: key, value });
- };
- var dataCacheSet = (key, value) => {
- dbSet("data", { id: key, value });
- };
- var cacheGetHelper = (key, defaultValue = false, db = "cache") => __async(void 0, null, function* () {
- var _a;
- const cached = yield dbGet(db, key);
- if (!((_a = cached == null ? void 0 : cached.data) == null ? void 0 : _a.value)) {
- return defaultValue;
- }
- return cached.data.value;
- });
- var cacheGet = (key, defaultValue = false) => __async(void 0, null, function* () {
- return yield cacheGetHelper(key, defaultValue, "cache");
- });
- var dataCacheGet = (key, defaultValue = false) => __async(void 0, null, function* () {
- return yield cacheGetHelper(key, defaultValue, "data");
- });
-
- // src/utils/page.js
- var getCurrentPage = () => {
- var _a, _b, _c, _d;
- if (!((_b = (_a = hg == null ? void 0 : hg.utils) == null ? void 0 : _a.PageUtil) == null ? void 0 : _b.getCurrentPage)) {
- return null;
- }
- const page = hg.utils.PageUtil.getCurrentPage();
- if (!page) {
- const query = ((_d = (_c = hg == null ? void 0 : hg.utils) == null ? void 0 : _c.PageUtil) == null ? void 0 : _d.getQueryParams()) || {};
- if ((query == null ? void 0 : query.switch_to) && "mobile" === query.switch_to) {
- return "camp";
- }
- return null;
- }
- return page.toLowerCase();
- };
- var setPage = (page, ...args) => {
- var _a, _b;
- if ("wiki" === page.toLowerCase()) {
- doEvent("mh-improved-open-wiki");
- return;
- }
- page = page.charAt(0).toUpperCase() + page.slice(1);
- if ((_b = (_a = hg == null ? void 0 : hg.utils) == null ? void 0 : _a.PageUtil) == null ? void 0 : _b.setPage) {
- hg.utils.PageUtil.setPage(page, ...args);
- }
- };
- var getCurrentTab = () => {
- var _a, _b;
- if (!((_b = (_a = hg == null ? void 0 : hg.utils) == null ? void 0 : _a.PageUtil) == null ? void 0 : _b.getCurrentPageTab)) {
- return getCurrentPage();
- }
- const tab = hg.utils.PageUtil.getCurrentPageTab() || "";
- if (tab.length <= 0) {
- return getCurrentPage();
- }
- return tab.toLowerCase();
- };
- var getCurrentSubtab = () => {
- const subtab = hg.utils.PageUtil.getCurrentPageSubTab();
- if (!subtab || subtab.length <= 0) {
- return getCurrentTab();
- }
- return subtab.toLowerCase();
- };
- var isCurrentPage = (targetPage = null, targetTab = null, targetSubtab = null, forceCurrentPage = null, forceCurrentTab = null, forceCurrentSubtab = null) => {
- if (!targetPage) {
- return false;
- }
- const currentPage = forceCurrentPage || getCurrentPage();
- if (!targetTab) {
- return currentPage === targetPage;
- }
- const currentTab = forceCurrentTab || getCurrentTab();
- if (!targetSubtab) {
- return currentPage === targetPage && currentTab === targetTab;
- }
- const currentSubtab = forceCurrentSubtab || getCurrentSubtab();
- if (currentSubtab === currentTab) {
- return currentPage === targetPage && currentTab === targetTab;
- }
- return currentPage === targetPage && currentTab === targetTab && currentSubtab === targetSubtab;
- };
-
- // src/utils/location.js
- var getRelicHunterLocation = () => {
- const cacheExpiry = 5 * 60 * 1e3;
- const cacheKey = "mh-improved-relic-hunter-location";
- let cached = sessionGet(cacheKey);
- if (cached) {
- cached = JSON.parse(cached);
- }
- if (cached && cached.expiry > Date.now()) {
- return cached.data;
- }
- return fetch("https://rh-api.mouse.rip/", { headers: getHeaders() }).then((response) => response.json()).then((data) => {
- const expiry = Date.now() + cacheExpiry;
- sessionSet(cacheKey, JSON.stringify({ expiry, data }));
- return data;
- }).catch((error) => {
- console.error(error);
- });
- };
-
- // src/utils/events.js
- var runCallbacks = (settings, parentNode, callbacks2) => {
- Object.keys(settings).forEach((key) => {
- if (parentNode && parentNode.classList && parentNode.classList.contains(settings[key].selector)) {
- settings[key].isVisible = true;
- if (callbacks2[key] && callbacks2[key].show) {
- callbacks2[key].show();
- }
- } else if (settings[key].isVisible) {
- settings[key].isVisible = false;
- if (callbacks2[key] && callbacks2[key].hide) {
- callbacks2[key].hide();
- }
- }
- });
- return settings;
- };
- var overlayMutationObserver = null;
- var overlayCallbacks = [];
- var onOverlayChange = (callbacks2) => {
- let overlayData = {
- map: {
- isVisible: false,
- selector: "treasureMapPopup"
- },
- item: {
- isVisible: false,
- selector: "itemViewPopup"
- },
- mouse: {
- isVisible: false,
- selector: "mouseViewPopup"
- },
- image: {
- isVisible: false,
- selector: "largerImage"
- },
- convertible: {
- isVisible: false,
- selector: "convertibleOpenViewPopup"
- },
- adventureBook: {
- isVisible: false,
- selector: "adventureBookPopup"
- },
- marketplace: {
- isVisible: false,
- selector: "marketplaceViewPopup"
- },
- gifts: {
- isVisible: false,
- selector: "giftSelectorViewPopup"
- },
- support: {
- isVisible: false,
- selector: "supportPageContactUsForm"
- },
- premiumShop: {
- isVisible: false,
- selector: "MHCheckout"
- }
- };
- overlayCallbacks.push(callbacks2);
- if (overlayMutationObserver) {
- return;
- }
- overlayMutationObserver = true;
- const observer = new MutationObserver(() => {
- overlayCallbacks.forEach((callback) => {
- if (callback.change) {
- callback.change();
- }
- const overlayType = document.querySelector("#overlayPopup");
- if (overlayType && overlayType.classList.length <= 0) {
- return;
- }
- const overlayBg = document.querySelector("#overlayBg");
- if (overlayBg && overlayBg.classList.length > 0) {
- if (callback.show) {
- callback.show();
- }
- } else if (callback.hide) {
- callback.hide();
- }
- overlayData = runCallbacks(overlayData, overlayType, callback);
- });
- });
- const observeTarget = document.querySelector("#overlayPopup");
- if (observeTarget) {
- observer.observe(observeTarget, {
- attributes: true,
- attributeFilter: ["class"]
- });
- }
- };
- var callbacks = [];
- var hasAddedNavigationListener = false;
- var onNavigation = (callback, options = {}) => {
- const defaults = {
- page: false,
- tab: false,
- subtab: false,
- onLoad: true,
- anyTab: false,
- anySubtab: false
- };
- const { page, tab, subtab, onLoad, anyTab, anySubtab } = Object.assign(defaults, options);
- const bypassMatch = !page;
- if (onLoad && (bypassMatch || isCurrentPage(
- page,
- anyTab ? getCurrentTab() : tab,
- anySubtab ? getCurrentSubtab() : subtab
- ))) {
- callback();
- }
- callbacks.push({ callback, page, tab, subtab, bypassMatch });
- if (!hasAddedNavigationListener) {
- addNavigationListeners();
- hasAddedNavigationListener = true;
- }
- };
- var addNavigationListeners = () => {
- eventRegistry.addEventListener("set_page", (e) => {
- var _a;
- const tabs = ((_a = e == null ? void 0 : e.data) == null ? void 0 : _a.tabs) || {};
- const currentTab = Object.keys(tabs).find((key) => tabs[key].is_active_tab);
- const forceCurrentTab = currentTab == null ? void 0 : currentTab.type;
- callbacks.forEach(({ callback, page, tab, subtab, bypassMatch }) => {
- if (bypassMatch) {
- callback();
- return;
- }
- if (!subtab) {
- if (isCurrentPage(page, tab, false, getCurrentPage(), forceCurrentTab)) {
- callback();
- }
- return;
- }
- if ((currentTab == null ? void 0 : currentTab.subtabs) && (currentTab == null ? void 0 : currentTab.subtabs.length) > 0) {
- const forceSubtab = currentTab.subtabs.find((searchTab) => searchTab.is_active_subtab).subtab_type;
- if (isCurrentPage(page, tab, subtab, getCurrentPage(), forceCurrentTab, forceSubtab)) {
- callback();
- }
- }
- });
- });
- eventRegistry.addEventListener("set_tab", (e) => {
- callbacks.forEach(({ callback, page, tab, subtab, bypassMatch }) => {
- if (bypassMatch) {
- callback();
- return;
- }
- if (isCurrentPage(page, tab, subtab, getCurrentPage(), e.page_arguments.tab, e.page_arguments.sub_tab)) {
- callback();
- }
- });
- });
- };
-
- // 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/maps.js
- var mapper = (key = false) => {
- if (key) {
- const mapperData = getGlobal("mapper");
- if (!mapperData || !mapperData[key]) {
- return false;
- }
- return mapperData[key];
- }
- return getGlobal("mapper");
- };
- var mapData = () => {
- const m = mapper();
- if (!m) {
- return {};
- }
- return m.mapData;
- };
- var getCachedValue = (key) => __async(void 0, null, function* () {
- var _a;
- const value = yield dbGet("ar-cache", key);
- if (!((_a = value == null ? void 0 : value.data) == null ? void 0 : _a.value)) {
- return null;
- }
- return value.data.value;
- });
- var setCachedValue = (key, value) => __async(void 0, null, function* () {
- yield dbSet("ar-cache", { id: key, value });
- });
- var getArForMouse = (id, type = "mouse") => __async(void 0, null, function* () {
- let mhctJson = [];
- const cacheKey = `${type}-${id}`;
- const cachedAr = yield getCachedValue(cacheKey);
- if (cachedAr) {
- return cachedAr;
- }
- const isItem = "item" === type;
- const mhctPath = isItem ? "mhct-item" : "mhct";
- let mhctData = [];
- const data = mapData() || {};
- const mapType = (data == null ? void 0 : data.map_type) || "";
- let url = `https://api.mouse.rip/${mhctPath}/${id}`;
- if (mapType.toLowerCase().includes("halloween")) {
- url = `https://api.mouse.rip/${mhctPath}/${id}-hlw_22`;
- }
- try {
- mhctData = yield fetch(url, { headers: getHeaders() });
- } catch (error) {
- console.error("Error fetching MHCT data:", error);
- yield new Promise((resolve) => setTimeout(resolve, 500));
- try {
- mhctData = yield fetch(url, { headers: getHeaders() });
- } catch (errorRetry) {
- console.error("Error fetching MHCT data:", errorRetry);
- return [];
- }
- }
- if (!mhctData.ok) {
- return [];
- }
- mhctJson = yield mhctData.json();
- if (!mhctJson || mhctJson.length === 0) {
- return [];
- }
- if (isItem) {
- for (const rate of mhctJson) {
- rate.rate = Number.parseInt(rate.drop_pct * 100);
- delete rate.drop_ct;
- }
- }
- if (mhctJson.error) {
- return [];
- }
- mhctJson = mhctJson.filter((rate) => {
- if (rate.rate === 0) {
- return false;
- }
- if (rate.rate === 9999) {
- rate.rate = 1e4;
- }
- return true;
- });
- yield setCachedValue(cacheKey, mhctJson);
- return mhctJson;
- });
-
- // src/utils/messages.js
- hadAddedErrorStyles = false;
-
- // src/utils/utils.js
- var isLoggedIn = () => {
- return user && user.user_id && "login" !== getCurrentPage();
- };
- var requests = {};
- var doRequest = (_0, ..._1) => __async(void 0, [_0, ..._1], function* (url, formData = {}, skipChecks = false) {
- var _a;
- if (!isLoggedIn()) {
- return;
- }
- if ("undefined" === typeof lastReadJournalEntryId || "undefined" === typeof user) {
- return;
- }
- if (!lastReadJournalEntryId || !user || !(user == null ? void 0 : user.unique_hash)) {
- return;
- }
- const requestKey = Object.keys(formData).length ? `${url}-${JSON.stringify(formData)}` : url;
- const timeRequested = Date.now();
- debuglog("utils-data", `Making request: ${requestKey} at ${timeRequested}`);
- if (requests[requestKey] && !skipChecks) {
- debuglog("utils-data", `Request already in progress: ${requestKey}`);
- if (requests[requestKey].in_progress) {
- return new Promise((resolve) => {
- const timeout = setTimeout(() => __async(void 0, null, function* () {
- debuglog("utils-data", `Request timed out: ${requestKey}, starting new request`);
- clearInterval(interval);
- const newRequest = yield doRequest(url, formData, true);
- resolve(newRequest);
- }), 2500);
- const interval = setInterval(() => {
- debuglog("utils-data", `Checking if request is complete: ${requestKey}`);
- if (!requests[requestKey].in_progress) {
- debuglog("utils-data", `Returning saved response: ${requestKey}`);
- clearInterval(interval);
- clearTimeout(timeout);
- resolve(requests[requestKey].response);
- }
- }, 100);
- });
- } else if (requests[requestKey].time_requested > timeRequested - 350) {
- debuglog("utils-data", `Request already completed: ${requestKey}`);
- return requests[requestKey].response;
- }
- }
- debuglog("utils-data", `Starting request: ${requestKey}`);
- requests[requestKey] = {
- in_progress: true,
- time_requested: timeRequested
- };
- 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();
- let response;
- let attempts = 0;
- while (!response && attempts < 3) {
- try {
- response = yield fetch(
- callbackurl ? callbackurl + url : "https://www.mousehuntgame.com/" + url,
- {
- method: "POST",
- body: requestBody,
- headers: {
- "Content-Type": "application/x-www-form-urlencoded"
- }
- }
- );
- } catch (error) {
- attempts++;
- console.error(`Attempt ${attempts} failed. Retrying...`, error);
- }
- }
- if (attempts >= 3) {
- console.error("Failed to fetch after maximum attempts");
- }
- let data;
- try {
- data = yield response.json();
- } catch (error) {
- console.error(`Error parsing response for ${url}:`, error, url, formData, response);
- return false;
- }
- requests[requestKey] = {
- time_requested: timeRequested,
- response: data
- };
- return data;
- });
-
- // src/modules/better-mice/mouse-page.js
- var makeKingsCrownsTab = () => {
- const tabContainer = document.querySelector(".mousehuntHud-page-tabHeader-container");
- if (!tabContainer) {
- return;
- }
- const existingTab = document.querySelector(".mousehuntHud-page-tabHeader.kings-crowns-tab");
- if (existingTab) {
- return;
- }
- const kingsCrownsTab = makeElement("a", ["mousehuntHud-page-tabHeader", "groups", "kings-crowns-tab"]);
- makeElement("span", "", "King's Crowns", kingsCrownsTab);
- kingsCrownsTab.setAttribute("data-tab", "kings_crowns");
- kingsCrownsTab.setAttribute("data-legacy-mode", "");
- kingsCrownsTab.setAttribute("onclick", "hg.utils.PageUtil.onclickPageTabHandler(this); return false;");
- tabContainer.append(kingsCrownsTab);
- return kingsCrownsTab;
- };
- var makeKingsCrownsTabContentContent = () => {
- const tabContentContainer = document.querySelector(".mousehuntHud-page-tabContentContainer");
- if (!tabContentContainer) {
- return;
- }
- const tabContent = makeElement("div", ["mousehuntHud-page-tabContent", "kings_crowns"]);
- tabContent.setAttribute("data-tab", "kings_crowns");
- tabContent.setAttribute("data-template-file", "AdversariesPage");
- makeElement("div", "mousehuntHud-page-tabContent-loading", "", tabContent);
- const subTabContent = makeElement("div", ["mousehuntHud-page-subTabContent", "all", "active"]);
- subTabContent.setAttribute("data-tab", "all");
- subTabContent.setAttribute("data-template-file", "AdversariesPage");
- subTabContent.setAttribute("data-template", "subtab");
- subTabContent.setAttribute("data-initialized", "");
- subTabContent.setAttribute("data-user-id", "");
- makeElement("div", "mouseCrownsView", "", subTabContent);
- tabContent.append(subTabContent);
- tabContentContainer.append(tabContent);
- };
- var makeMouseCrownSection = (type, mice, header = false, subheader = false) => {
- const wrapper = makeElement("div", ["kings-crown-section", "mouseCrownsView-group", type]);
- if (header) {
- const headerDiv = makeElement("div", "mouseCrownsView-group-header");
- makeElement("div", ["mouseCrownsView-crown", type], "", headerDiv);
- const name = makeElement("div", "mouseCrownsView-group-header-name");
- makeElement("b", false, header, headerDiv);
- if (subheader) {
- makeElement("div", "mouseCrownsView-group-header-subtitle", subheader, name);
- }
- headerDiv.append(name);
- wrapper.append(headerDiv);
- }
- const list = makeElement("div", "mouseCrownsView-group-mice");
- mice.forEach((mouse) => {
- if (!mouse.id) {
- return;
- }
- const mouseWrapper = makeElement("div", "mouseCrownsView-group-mouse");
- mouseWrapper.setAttribute("data-mouse-id", mouse.id);
- mouseWrapper.setAttribute("data-mouse-type", mouse.type);
- mouseWrapper.setAttribute("data-mouse-large", mouse.large);
- mouseWrapper.setAttribute("onclick", "hg.views.MouseCrownsView.showMouseImage(this); return false;");
- if (mouse.landscape) {
- mouseWrapper.classList.add("landscape");
- }
- const innerWrapper = makeElement("div", "mouseCrownsView-group-mouse-padding");
- const image = makeElement("div", ["mouseCrownsView-group-mouse-image", mouse.type]);
- image.setAttribute("data-image", mouse.image);
- image.setAttribute("data-loader", "mouse");
- image.setAttribute("style", `background-image: url("${mouse.image}");`);
- innerWrapper.append(image);
- makeElement("div", "mouseCrownsView-group-mouse-catches", mouse.num_catches, innerWrapper);
- const label = makeElement("div", "mouseCrownsView-group-mouse-label");
- const nameWrapper = makeElement("span", false, "");
- makeElement("div", "mouseCrownsView-group-mouse-name", mouse.name, nameWrapper);
- label.append(nameWrapper);
- innerWrapper.append(label);
- const favoriteButton = makeElement("div", "mouseCrownsView-group-mouse-favouriteButton");
- if (mouse.is_favourite) {
- favoriteButton.classList.add("active");
- }
- favoriteButton.setAttribute("data-mouse-id", mouse.id);
- favoriteButton.setAttribute("onclick", "hg.views.MouseCrownsView.toggleFavouriteHandler(event); return false;");
- innerWrapper.append(favoriteButton);
- mouseWrapper.append(innerWrapper);
- list.append(mouseWrapper);
- });
- wrapper.append(list);
- return wrapper;
- };
- var makeKingsCrownsTabContent = () => __async(void 0, null, function* () {
- var _a, _b, _c, _d;
- makeKingsCrownsTabContentContent();
- let crowns = [];
- const cachedCrowns = sessionGet("kings-crowns");
- const cachedCrownsTime = sessionGet("kings-crowns-time");
- if (cachedCrowns && cachedCrownsTime && Date.now() - cachedCrownsTime < 3e5) {
- crowns = JSON.parse(cachedCrowns);
- } else {
- const crownsReq = yield doRequest("managers/ajax/pages/page.php", {
- page_class: "HunterProfile",
- "page_arguments[tab]": "kings_crowns",
- "page_arguments[sub_tab]": false
- });
- crowns = ((_d = (_c = (_b = (_a = crownsReq == null ? void 0 : crownsReq.page) == null ? void 0 : _a.tabs) == null ? void 0 : _b.kings_crowns) == null ? void 0 : _c.subtabs[0]) == null ? void 0 : _d.mouse_crowns) || [];
- if (crowns.length <= 0) {
- return;
- }
- sessionSet("kings-crowns", crowns);
- sessionSet("kings-crownsTime", Date.now());
- }
- const tabInnerContent = document.querySelector(".mousehuntHud-page-tabContent.kings_crowns");
- if (!tabInnerContent) {
- return;
- }
- if (crowns.favourite_mice_count > 0) {
- const favorites = makeMouseCrownSection("favorites", crowns.favourite_mice);
- const existingFavorites = tabInnerContent.querySelector(".mouseCrownsView-group.favorites");
- if (existingFavorites) {
- existingFavorites.replaceWith(favorites);
- } else {
- tabInnerContent.append(favorites);
- }
- }
- crowns.badge_groups.forEach((group) => {
- var _a2, _b2;
- if (group.mice.length === 0) {
- return;
- }
- group.name = ((_a2 = group == null ? void 0 : group.name) == null ? void 0 : _a2.length) > 0 ? group.name : "No";
- group.catches = ((_b2 = group == null ? void 0 : group.catches) == null ? void 0 : _b2.length) > 0 ? group.catches : "0";
- const section = makeMouseCrownSection(group.type, group.mice, `${group.name} Crown (${group.count})`, `Earned at ${group.catches} catches`);
- const existingSection = tabInnerContent.querySelector(`.mouseCrownsView-group.${group.type}`);
- if (existingSection) {
- existingSection.replaceWith(section);
- } else {
- tabInnerContent.append(section);
- }
- });
- });
- var addKingsCrownsToMicePage = () => __async(void 0, null, function* () {
- makeKingsCrownsTab();
- makeKingsCrownsTabContent();
- });
- var parseImperialWeight = (weightText) => {
- const lbsSplit = weightText.innerText.split("lb.");
- const lbs = lbsSplit.length > 1 ? lbsSplit[0] : 0;
- const ozSplit = weightText.innerText.split("oz.");
- const oz = ozSplit.length > 1 ? ozSplit[0] : 0;
- return Number.parseInt(lbs) * 16 + Number.parseInt(oz);
- };
- var getSetRowValue = (row, type) => {
- let value = 0;
- value = row.getAttribute(`data-sort-value-${type}`);
- if (value) {
- return Number.parseInt(value);
- }
- const valueText = row.querySelector(`${getSelectorPrefix()} .mouseListView-categoryContent-subgroup-mouse-stats.${type}`);
- if (type === "average_weight" || type === "heaviest_catch") {
- if (valueText.innerText.includes("lb") || valueText.innerText.includes("oz")) {
- value = parseImperialWeight(valueText);
- } else if (valueText.innerText.includes("kg")) {
- value = valueText.innerText.replace("kg.", "");
- } else {
- value = 0;
- }
- } else {
- value = valueText.innerText ? valueText.innerText.replaceAll(",", "") || 0 : 0;
- }
- row.setAttribute(`data-sort-value-${type}`, value);
- return Number.parseInt(value);
- };
- var sortStats = (type, reverse = false) => {
- reverse = !reverse;
- let rows = document.querySelectorAll(`${getSelectorPrefix()} .active .mouseListView-categoryContent-subgroup-mouse:not(:first-child)`);
- if (!rows.length) {
- return;
- }
- const headerRow = document.querySelector(`${getSelectorPrefix()} .active .mouseListView-categoryContent-subgroup-mouse:first-child`);
- if (!headerRow) {
- return;
- }
- rows.forEach((row) => {
- getSetRowValue(row, type);
- });
- rows = [...rows].sort((a, b) => {
- const aVal = getSetRowValue(a, type);
- const bVal = getSetRowValue(b, type);
- if (aVal === bVal || type === "name") {
- const aNameEl = a.querySelector(".mouseListView-categoryContent-subgroup-mouse-stats.name");
- if (!aNameEl) {
- return 0;
- }
- const bNameEl = b.querySelector(".mouseListView-categoryContent-subgroup-mouse-stats.name");
- if (!bNameEl) {
- return 0;
- }
- const aName = aNameEl.innerText;
- const bName = bNameEl.innerText;
- if (aName === bName) {
- return 0;
- }
- return aName > bName ? 1 : -1;
- }
- return aVal > bVal ? 1 : -1;
- });
- if (reverse) {
- rows = rows.reverse();
- }
- rows.forEach((row) => {
- row.parentNode.append(row);
- });
- };
- var addSortButton = (elements, type) => {
- elements.forEach((el) => {
- const sortButton = makeElement("div", ["sort-button", "unsorted"], "");
- el.addEventListener("click", () => {
- const otherSortButtons = el.parentNode.querySelectorAll(".sort-button");
- otherSortButtons.forEach((button) => {
- if (button !== sortButton) {
- button.classList.remove("reverse");
- button.classList.add("unsorted");
- }
- });
- if (sortButton.classList.contains("unsorted")) {
- sortButton.classList.remove("unsorted");
- sortStats(type);
- return;
- }
- if (sortButton.classList.contains("reverse")) {
- sortButton.classList.remove("reverse");
- sortStats(type);
- return;
- }
- sortButton.classList.add("reverse");
- sortStats(type, true);
- });
- el.append(sortButton);
- });
- };
- var getSelectorPrefix = () => {
- const currentTab = getCurrentTab();
- let currentSubtab = getCurrentSubtab();
- if (currentTab === currentSubtab) {
- currentSubtab = false;
- }
- return `.${currentTab} .mousehuntHud-page-subTabContent.active${currentSubtab ? `.${currentSubtab}` : ""}`;
- };
- var addSortingToCat = (cat, retries = 0) => {
- const cats = [
- "name",
- "catches",
- "misses",
- "average_weight",
- "heaviest_catch"
- ];
- const selector = `${getSelectorPrefix()} .mouseListView-categoryContent-category[data-category="${cat}"]`;
- const category = document.querySelector(selector);
- if (!category || category && category.classList.contains("loading")) {
- if (retries > 10) {
- return;
- }
- setTimeout(() => addSortingToCat(cat, retries + 1), 300);
- return;
- }
- if (category.getAttribute("data-added-sorting")) {
- return;
- }
- cats.forEach((mCat) => {
- const els = category.querySelectorAll(`${getSelectorPrefix()} .mouseListView-categoryContent-category.all.active .mouseListView-categoryContent-subgroup-mouse.header .mouseListView-categoryContent-subgroup-mouse-stats.${mCat}`);
- if (els.length) {
- addSortButton(els, mCat);
- }
- });
- category.setAttribute("data-added-sorting", true);
- const rows = category.querySelectorAll(`${getSelectorPrefix()} .mouseListView-categoryContent-subgroup-mouse:not(:first-child)`);
- if (!rows.length) {
- return;
- }
- rows.forEach((row) => {
- const catches = row.querySelector(`${getSelectorPrefix()} .mouseListView-categoryContent-subgroup-mouse-stats.catches`);
- if (!catches) {
- return;
- }
- const value = catches.innerText ? catches.innerText.replaceAll(",", "") || 0 : 0;
- if (value >= 2500) {
- row.classList.add("crown", "diamond");
- } else if (value >= 1e3) {
- row.classList.add("crown", "platinum");
- } else if (value >= 500) {
- row.classList.add("crown", "gold");
- } else if (value >= 100) {
- row.classList.add("crown", "silver");
- } else if (value >= 10) {
- row.classList.add("crown", "bronze");
- }
- });
- };
- var hasAddedSortingTabClickListeners = false;
- var addSortingTabClickListeners = () => {
- if (hasAddedSortingTabClickListeners) {
- return;
- }
- hasAddedSortingTabClickListeners = true;
- const _categoryClickHandler = hg.views.MouseListView.categoryClickHandler;
- hg.views.MouseListView.categoryClickHandler = (el) => {
- _categoryClickHandler(el);
- addSortingToCat(el.getAttribute("data-category"));
- };
- };
- var clickCurrentTab = () => {
- const activeTab = document.querySelector(".mousehuntHud-page-tabContent.active .mousehuntHud-page-subTabContent.active .mouseListView-categoryContainer.active a");
- if (!activeTab) {
- setTimeout(clickCurrentTab, 250);
- return;
- }
- addSortingToCat(activeTab.getAttribute("data-category"));
- hg.views.MouseListView.categoryClickHandler(activeTab);
- };
- var addSortingToStatsPage = () => {
- addSortingTabClickListeners();
- clickCurrentTab();
- };
- var mouse_page_default = () => __async(void 0, null, function* () {
- var _a, _b;
- if ("adversaries" === getCurrentPage() && getCurrentTab() === "kings_crowns") {
- addKingsCrownsToMicePage();
- const tab = document.querySelector(".mousehuntHud-page-tabHeader.kings-crowns-tab");
- if (tab && ((_b = (_a = hg == null ? void 0 : hg.utils) == null ? void 0 : _a.PageUtil) == null ? void 0 : _b.onclickPageTabHandler)) {
- hg.utils.PageUtil.onclickPageTabHandler(tab);
- }
- }
- onNavigation(addKingsCrownsToMicePage, {
- page: "adversaries"
- });
- onNavigation(addSortingToStatsPage, {
- page: "adversaries",
- tab: "your_stats",
- subtab: "group"
- });
- onNavigation(addSortingToStatsPage, {
- page: "adversaries",
- tab: "your_stats",
- subtab: "location"
- });
- onEvent("set_tab", () => {
- if ("your_stats" === getCurrentTab()) {
- addSortingToStatsPage();
- }
- });
- onNavigation(addSortingToStatsPage, {
- page: "hunterprofile",
- tab: "mice"
- });
- });
-
- // src/modules/better-mice/settings/index.js
- var settings_default = () => __async(void 0, null, function* () {
- return [
- {
- id: "better-mice.show-attraction-rates",
- title: "Show attraction rates",
- default: true
- },
- {
- id: "better-mice.show-mouse-hover",
- title: "Show mice details on hover (in journal)"
- },
- {
- id: "better-mice.show-sidebar",
- title: "Show available mice in sidebar",
- default: true
- }
- ];
- });
-
- // src/modules/better-mice/styles.css
- var styles_default = '.mouseView-titleContainer{height:26px}.mouseView-values{float:none;font-size:11px;line-height:unset}.mouseView-title{font-size:1.2em;line-height:24px}.mh-ui-mouse-links{display:inline-block;float:right;margin-right:15px}.mh-ui-mouse-links-map{display:flex;justify-content:center;padding-bottom:5px}.mh-ui-mouse-links a{margin-right:10px}.mh-ui-mouse-links-map a{margin:10px 10px 10px 0}.mouseview-title-group{font-size:11px}.mh-ui-mouse-links-map .mousehuntActionButton.tiny{margin:3px}.mouseView-movedContainer{display:flex;flex-flow:row wrap;gap:10px}.mouseview-has-mhct .mouseView-weaknessContainer{display:flex;flex-direction:column;align-items:center;width:90px}.mouseview-has-mhct .mouseView-categoryContent-subgroup-mouse-weaknesses{width:100%}.mouseview-has-mhct .mouseView-socialContainer{display:none}.mouseview-has-mhct .mouseView-statsContainer{display:flex;align-items:stretch;width:155px}.mouseview-has-mhct .mouseView-statsContainer-block-padding{display:flex;flex-direction:column;align-items:center;min-width:125px;padding:10px}.mouseview-has-mhct .mouseView-descriptionContainer{width:100%}.mouseView-categoryContent-subgroup-mouse-weaknesses-label{font-size:12px;font-weight:400;font-variant:none}.mouseview-has-mhct .mouseView-difficulty{display:none}.mouseview-has-mhct .mouse-ar-wrapper{display:grid;grid-template-columns:1fr 1fr 50px;gap:10px;place-items:center stretch;width:100%;padding:5px;margin:5px 0;font-size:12px}.mouseview-has-mhct .has-stages .mouse-ar-wrapper{grid-template-columns:3fr 2fr 2fr 50px}.mouseview-has-mhct .mouse-ar-wrapper div{padding:0 2px;font-size:12px}.mouseview-has-mhct .mice-ar-wrapper{margin-right:10px}.mouseview-has-mhct .mouse-ar-wrapper div.rate{font-size:13px}.mouseview-has-mhct .ar-header{display:flex;align-items:center;justify-content:space-between;height:26px;padding-bottom:2px;margin-top:10px;font-size:12px;font-weight:900;border-bottom:1px solid #ccc}.mouseview-has-mhct .ar-link{font-weight:400}.mouseview-has-mhct .rate{text-align:right}.mouseview-has-mhct .mouse-ar-wrapper:nth-child(odd){background-color:#e7e7e7}.mouseview-has-mhct .mouseView-description{font-weight:500;line-height:19px}.mh-ui-mouse-links-map-name{color:#3b5998;cursor:pointer}.treasureMapView-highlight-name{padding:5px 0 10px;font-weight:400;text-align:center}.mh-ui-mouse-links-map-name:hover{text-decoration:underline}.mh-ui-mouse-links-map .treasureMapView-highlight-group{text-align:center}.mouseView-image{box-shadow:none}.mouseView-image:hover{box-shadow:1px 1px 2px #e70}.mouseView a.custom-favorite-button,.mouseView a.custom-favorite-button-small{position:absolute;top:15px;left:15px;width:30px;height:30px;background-size:contain}#custom-submenu-item-king-s-crowns .icon{filter:sepia(1) brightness(.5)}.mouseView-statsContainer-block-padding abbr{text-decoration:none}.mouseView-statsContainer-block-padding{padding:5px}a.mouseListView-categoryContent-subgroup-mouse-thumb{position:relative}.crown .mouseListView-categoryContent-subgroup-mouse-thumb:after{position:absolute;top:-4px;left:-8px;z-index:2;width:20px;height:20px;content:"";background-color:#fdfdfa;background-size:contain;border:1px solid #929292;border-radius:50%}.crown.bronze .mouseListView-categoryContent-subgroup-mouse-thumb:after{background-image:url(https://www.mousehuntgame.com/images/ui/crowns/crown_bronze.png)}.crown.silver .mouseListView-categoryContent-subgroup-mouse-thumb:after{background-image:url(https://www.mousehuntgame.com/images/ui/crowns/crown_silver.png)}.crown.gold .mouseListView-categoryContent-subgroup-mouse-thumb:after{background-image:url(https://www.mousehuntgame.com/images/ui/crowns/crown_gold.png)}.crown.diamond .mouseListView-categoryContent-subgroup-mouse-thumb:after{background-image:url(https://www.mousehuntgame.com/images/ui/crowns/crown_diamond.png)}.crown.platinum .mouseListView-categoryContent-subgroup-mouse-thumb:after{background-image:url(https://www.mousehuntgame.com/images/ui/crowns/crown_platinum.png)}.mouseListView-categoryContent-subgroup-mouse-thumb,.mouseListView-categoryContent-subgroup-mouse .mouseListView-categoryContent-subgroup-mouse-margin{transition:.2s ease-in}.mouseListView-categoryContent-subgroup-mouse-thumb:hover{transform:scale(1.2)}a.mouseListView-categoryContent-subgroup-mouse:hover .mouseListView-categoryContent-subgroup-mouse-margin{background-size:contain}.mouseViewPopup .mouseView-image:hover{box-shadow:none;transform:scale(.95)}.mouseViewPopup .mouseView-image{margin-bottom:10px;transition:.2s ease-in}.mouseViewPopup .mouseView-descriptionContainer{display:grid;grid-template-columns:3fr 2fr;justify-items:stretch}.mouseViewPopup .mouseView-values{margin-left:0}.mouseViewPopup .mouseView-description{grid-column:span 2;padding-top:5px}.mouseViewPopup .mouseView-group.mouseview-title-group{text-align:right}img.minluck-power-type-img{width:20px}li.minluck-item{display:inline-flex;gap:3px;align-items:center;width:auto;padding:2px;margin:2px;font-size:12px;background-color:#f2f2f2;border:1px solid #ccc;border-radius:8px}ul.minluck-list{display:flex;flex-wrap:wrap;place-content:center flex-start;width:auto;margin-right:-5px}.minluck-title{display:flex;align-items:center;justify-content:space-between;padding-bottom:2px;margin-top:10px;margin-bottom:5px;font-size:12px;font-weight:900;border-bottom:1px solid #ccc}.mouseview-relicHunter{display:flex;align-items:center;justify-content:space-around;width:100%;padding:10px;font-size:15px;background-color:#edd1f3;border-radius:10px}\n';
-
- // src/modules/better-mice/index.js
- var getLinkMarkup = (name) => {
- return makeLink("MHCT AR", `https://www.mhct.win/attractions.php?mouse_name=${name}`) + makeLink("Wiki", `https://mhwiki.hitgrab.com/wiki/index.php/${name}`);
- };
- var addLinks = () => {
- const title = document.querySelector(".mouseView-title");
- if (!title) {
- return;
- }
- const currentLinks = document.querySelector(".mh-ui-mouse-links");
- if (currentLinks) {
- currentLinks.remove();
- }
- const div = document.createElement("div");
- div.classList.add("mh-ui-mouse-links");
- div.innerHTML = getLinkMarkup(title.innerText);
- title.parentNode.insertBefore(div, title);
- const values = document.querySelector(".mouseView-values");
- const desc = document.querySelector(".mouseView-descriptionContainer");
- if (values && desc) {
- desc.insertBefore(values, desc.firstChild);
- }
- };
- var isFavorite = (mouseId) => __async(void 0, null, function* () {
- var _a, _b, _c, _d, _e;
- const favorites = yield doRequest("managers/ajax/pages/page.php", {
- page_class: "HunterProfile",
- "page_arguments[tab]": "kings_crowns",
- "page_arguments[sub_tab]": false,
- "page_arguments[snuid]": window.user.sn_user_id
- });
- if (!((_e = (_d = (_c = (_b = (_a = favorites == null ? void 0 : favorites.page) == null ? void 0 : _a.tabs) == null ? void 0 : _b.kings_crowns) == null ? void 0 : _c.subtabs[0]) == null ? void 0 : _d.mouse_crowns) == null ? void 0 : _e.favourite_mice.length)) {
- return false;
- }
- return favorites.page.tabs.kings_crowns.subtabs[0].mouse_crowns.favourite_mice.some((mouse) => {
- return mouse.id && mouse.id === Number.parseInt(mouseId, 10);
- });
- });
- var addFavoriteButton = (mouseId, mouseView) => __async(void 0, null, function* () {
- const state = yield isFavorite(mouseId);
- const fave = yield makeFavoriteButton({
- target: mouseView,
- size: "large",
- isSetting: false,
- state,
- onChange: () => {
- doRequest("managers/ajax/mice/mouse_crowns.php", {
- action: "toggle_favourite",
- user_id: window.user.user_id,
- mouse_id: mouseId
- });
- }
- });
- mouseView.append(fave);
- });
- var addMinluck = (mouseId, mouseView) => __async(void 0, null, function* () {
- const appendTo = mouseView.querySelector(".mouseView-contentContainer");
- if (!appendTo) {
- return;
- }
- const minluckContainer = makeElement("div", "minluck-container");
- const titleText = makeElement("div", "minluck-title", "Minlucks");
- makeTooltip({
- appendTo: titleText,
- text: "If your current luck is above the minluck, you are guaranteed to catch the mouse if you attract it."
- });
- minluckContainer.append(titleText);
- const minluckList = makeElement("ul", "minluck-list");
- const minluck = minlucks.find((m) => m.id === Number.parseInt(mouseId, 10));
- const mouseMinlucks = (minluck == null ? void 0 : minluck.minlucks) || {};
- Object.keys(mouseMinlucks).forEach((powerType) => {
- if (!mouseMinlucks[powerType] || "\u221E" === mouseMinlucks[powerType]) {
- return;
- }
- const minluckItem = makeElement("li", "minluck-item");
- const powerTypeImg = makeElement("img", "minluck-power-type-img");
- powerTypeImg.src = `https://www.mousehuntgame.com/images/powertypes/${powerType.toLowerCase()}.png`;
- minluckItem.append(powerTypeImg);
- makeElement("div", "minluck-power-type-minluck", mouseMinlucks[powerType], minluckItem);
- minluckList.append(minluckItem);
- });
- minluckContainer.append(minluckList);
- appendTo.append(minluckContainer);
- });
- var addWisdom = (mouseId, mouseView) => __async(void 0, null, function* () {
- const values = mouseView.querySelector(".mouseView-values");
- if (!values) {
- return;
- }
- let wisdom = wisdoms.find((m) => m.id === Number.parseInt(mouseId, 10));
- wisdom = (wisdom == null ? void 0 : wisdom.wisdom) || 0;
- wisdom = wisdom.toString().replaceAll(/\B(?=(\d{3})+(?!\d))/g, ",");
- makeElement("span", "wisdom-container", ` / ${wisdom} Wisdom`, values);
- });
- var updateMouseView = () => __async(void 0, null, function* () {
- const mouseView = document.querySelector("#overlayPopup .mouseView");
- if (!mouseView) {
- return;
- }
- const mouseId = mouseView.getAttribute("data-mouse-id");
- if (!mouseId) {
- return;
- }
- const name = mouseView.querySelector(".mouseView-title");
- if (!name) {
- return;
- }
- const catchesEl = document.querySelectorAll(".mouseView-statsContainer-block-padding td abbr");
- if (catchesEl && catchesEl.length > 0) {
- catchesEl.forEach((el) => {
- const catchesNumber = el.getAttribute("title").replace(" Catches", "").replace(" catches", "").replace(" Misses", "").replace(" misses", "").trim();
- if (catchesNumber) {
- el.innerText = catchesNumber;
- }
- });
- }
- addLinks();
- addFavoriteButton(mouseId, mouseView);
- addMinluck(mouseId, mouseView);
- addWisdom(mouseId, mouseView);
- mouseView.classList.add("mouseview-has-mhct");
- const group = document.querySelector(".mouseView-group");
- if (group) {
- group.classList.add("mouseview-title-group");
- const descContainer = document.querySelector(".mouseView-descriptionContainer");
- if (descContainer) {
- if (descContainer.childNodes.length > 1) {
- descContainer.insertBefore(group, descContainer.childNodes[1]);
- } else {
- descContainer.append(group);
- }
- }
- }
- const groupTitle = mouseView.querySelector(".mouseView-group.mouseview-title-group");
- if (groupTitle) {
- let newHtml = groupTitle.innerHTML.replace("Group: ", "");
- const subGroups = newHtml.split("(");
- if (subGroups.length > 1) {
- newHtml = `<span class="mouseview-group">${subGroups[0]}</span><span class="mouseview-subgroup">(${subGroups[1]}</span>`;
- groupTitle.classList.add("mouseview-title-group-has-subgroup");
- } else {
- newHtml = `<span class="mouseview-group">${newHtml}</span>`;
- }
- groupTitle.innerHTML = newHtml;
- }
- const container = mouseView.querySelector(".mouseView-contentContainer");
- if (!container) {
- return;
- }
- const imageContainer = mouseView.querySelector(".mouseView-imageContainer");
- if (imageContainer) {
- const movedContainer = makeElement("div", "mouseView-movedContainer");
- const statsContainer = mouseView.querySelector(".mouseView-statsContainer");
- if (statsContainer) {
- movedContainer.append(statsContainer);
- }
- const weaknessContainer = mouseView.querySelector(".mouseView-weaknessContainer");
- if (weaknessContainer) {
- movedContainer.append(weaknessContainer);
- const weaknesses = weaknessContainer.querySelectorAll(".mouseView-categoryContent-subgroup-mouse-weaknesses-padding");
- weaknesses.forEach((w) => {
- const weakness = w.querySelector(".mouseView-weakness");
- if (!weakness) {
- w.classList.add("mouseview-weakness-empty");
- w.classList.add("hidden");
- }
- });
- }
- if (401 === Number.parseInt(mouseId, 10)) {
- const location = yield getRelicHunterLocation();
- if (location && location.name) {
- const relicHunterBox = makeElement("div", ["mouseview-relicHunter", "mouseview-relicHunter"]);
- makeElement("div", "hint", location.name, relicHunterBox);
- const button = makeElement("div", ["mousehuntActionButton", "small"]);
- makeElement("span", "", "Travel", button);
- button.addEventListener("click", () => {
- app.pages.TravelPage.travel(location.id);
- setPage("Camp");
- });
- relicHunterBox.append(button);
- movedContainer.append(relicHunterBox);
- }
- }
- imageContainer.append(movedContainer);
- }
- if (!getSetting("better-mice.show-attraction-rates", true)) {
- return;
- }
- const arWrapper = makeElement("div", "ar-wrapper");
- const title = makeElement("div", "ar-header");
- const titleText = makeElement("div", "ar-title", "Attraction Rates", title);
- makeTooltip({
- appendTo: titleText,
- text: 'The best location and bait, according to data gathered by <a href="https://mhct.win/" target="_blank" rel="noopener noreferrer">MHCT</a>.'
- });
- const link = makeElement("a", "ar-link", "View on MHCT \u2192");
- link.href = `https://www.mhct.win/attractions.php?mouse_name=${name.innerText}`;
- link.target = "_mhct";
- title.append(link);
- arWrapper.append(title);
- let mhctJson = yield getArForMouse(mouseId, "mouse");
- if (!mhctJson || mhctJson === void 0 || mhctJson.length === 0 || "error" in mhctJson) {
- return;
- }
- mhctJson = mhctJson.slice(0, 15);
- const miceArWrapper = makeElement("div", "mice-ar-wrapper");
- const hasStages = mhctJson.some((mouseAr) => mouseAr.stage);
- if (hasStages) {
- miceArWrapper.classList.add("has-stages");
- }
- mhctJson.forEach((mouseAr) => {
- const mouseArWrapper = makeElement("div", "mouse-ar-wrapper");
- makeElement("div", "location", mouseAr.location, mouseArWrapper);
- if (hasStages) {
- makeElement("div", "stage", mouseAr.stage, mouseArWrapper);
- }
- makeElement("div", "cheese", mouseAr.cheese, mouseArWrapper);
- makeElement("div", "rate", `${(mouseAr.rate / 100).toFixed(2)}%`, mouseArWrapper);
- miceArWrapper.append(mouseArWrapper);
- });
- if (mhctJson.length > 0) {
- arWrapper.append(miceArWrapper);
- container.append(arWrapper);
- }
- });
- var _original;
- var replaceShowMouseImage = () => {
- if (_original) {
- return;
- }
- _original = hg.views.MouseCrownsView.showMouseImage;
- hg.views.MouseCrownsView.showMouseImage = (element) => {
- const type = element.getAttribute("data-mouse-type");
- if (type) {
- hg.views.MouseView.show(type);
- return;
- }
- _original(element);
- };
- };
- var main = () => __async(void 0, null, function* () {
- onOverlayChange({ mouse: { show: updateMouseView } });
- minlucks = yield getData("minlucks");
- wisdoms = yield getData("wisdom");
- addSubmenuItem({
- menu: "mice",
- label: "Groups",
- icon: "https://www.mousehuntgame.com/images/ui/hud/menu/mice.png?asset_cache_version=2",
- href: "https://www.mousehuntgame.com/adversaries.php?tab=groups"
- });
- addSubmenuItem({
- menu: "mice",
- label: "Regions",
- icon: "https://www.mousehuntgame.com/images/ui/hud/menu/travel.png?asset_cache_version=2",
- href: "https://www.mousehuntgame.com/adversaries.php?tab=regions"
- });
- addSubmenuItem({
- menu: "mice",
- label: "Your Stats",
- icon: "https://www.mousehuntgame.com/images/ui/hud/menu/special.png?asset_cache_version=2",
- href: "https://www.mousehuntgame.com/adversaries.php?tab=your_stats"
- });
- addSubmenuItem({
- menu: "mice",
- label: "King's Crowns",
- icon: "https://www.mousehuntgame.com/images/ui/crowns/crown_silver.png?asset_cache_version=2",
- href: "https://www.mousehuntgame.com/adversaries.php?tab=kings_crowns"
- });
- });
- var wisdoms;
- var minlucks;
- var init = () => __async(void 0, null, function* () {
- addStyles(styles_default, "better-mice");
- main();
- mouse_page_default();
- if (getSetting("better-mice.show-mouse-hover", true)) {
- }
- if (getSetting("better-mice.show-mice-sidebar", true)) {
- }
- replaceShowMouseImage();
- });
- var better_mice_default = {
- id: "better-mice",
- name: "Better Mice",
- type: "better",
- default: true,
- description: "Adds attraction rate stats and links to MHWiki and MHCT to mouse dialogs. Adds sorting to the mouse stats pages, and adds the King's Crown tab to the mouse pages.",
- load: init,
- settings: settings_default
- };
- return __toCommonJS(better_mice_exports);
- })();
- mhImprovedVersion = "0.0.0-userscript;"
- mhImprovedPlatform = "userscript";
- mhui.default.load();
- migrateUserscript('Better Mice', 'https://greasyfork.org/en/scripts/449332-mousehunt-mouse-links');