您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
View your mouse catches in your current location
当前为
// ==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');