您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Keep track of what state you left an area in, because travelling just to check is jank
// ==UserScript== // @name MouseHunt Location HUD Preview // @description Keep track of what state you left an area in, because travelling just to check is jank // @author LethalVision // @version 0.5.2 // @require https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.4.4/lz-string.min.js // @match https://www.mousehuntgame.com/* // @match https://apps.facebook.com/mousehunt/* // @icon https://www.google.com/s2/favicons?domain=mousehuntgame.com // @grant none // @license MIT // @namespace https://gf.qytechs.cn/en/users/683695-lethalvision // ==/UserScript== (function () { const STORAGE_TAG = 'mh-lochud-cache'; const MAIN_ID = 'hudPreview-main'; const PREVIEW_ID = 'hudPreview'; const LG_COMPLEX = ['desert_oasis', 'sand_dunes', 'lost_city']; const TWISTED = '_twisted'; const LABYKOR = ['labyrinth', 'ancient_city']; var areaHuds = { display:true }; // == local storage == function loadCache() { var cacheJson = window.localStorage.getItem(STORAGE_TAG); if (cacheJson){ try{ if (!cacheJson.startsWith('{')) { // compressed data cacheJson = LZString.decompressFromUTF16(cacheJson); } areaHuds = JSON.parse(cacheJson); } catch (err) { console.log('Cache parse error: ' + err); } } } function saveCache() { var jsonString = LZString.compressToUTF16(JSON.stringify(areaHuds)); window.localStorage.setItem(STORAGE_TAG, jsonString); //console.log('Saved cache: ' + jsonString); } // == init hooks == function initHooks() { // hook showEnv const _parentShowEnv = app.pages.TravelPage.showEnvironment; app.pages.TravelPage.showEnvironment = function (envType, instant) { updatePreview(envType); _parentShowEnv(envType, instant); } // hook toggleQuickMap const _parentToggleQuick = app.pages.TravelPage.toggleQuickMap; app.pages.TravelPage.toggleQuickMap = function () { _parentToggleQuick(); updateVisibility(); } // hook page.php const pageUrl = 'managers/ajax/pages/page.php'; const travelPageUrl = 'travel.php'; const travelUrl = 'managers/ajax/users/changeenvironment.php'; const originalOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function() { this.addEventListener('load', function() { if (this.responseURL.indexOf(pageUrl) != -1) { // page is called basically when you do anything in MH storeHud(); } else if (this.responseURL.indexOf(travelUrl) != -1) { // travelling to new location storeHud(); updatePreview(user.environment_type); } }); originalOpen.apply(this, arguments); }; // in case the window is refreshed in travel.php if (window.location.href.includes('travel.php')) { updatePreview(user.environment_type); } } // UI, my one love in life function updatePreview(envType) { var mainDiv = document.getElementById(MAIN_ID); if (!mainDiv) { // create the main div if it doesn't exist var mapContainer = document.querySelector('.travelPage-mapContainer.full'); if (!mapContainer) return; // idk just return mainDiv = getMainDiv(); mapContainer.parentNode.insertBefore(mainDiv, mapContainer); } const previewElem = mainDiv.querySelector(`#${PREVIEW_ID}`); // load cached HUD or handle based on exceptions const cachedHud = areaHuds[envType]; if (LG_COMPLEX.includes(envType)) { previewElem.innerHTML = renderLgComplex(envType); } else if (user.environment_type == envType) { previewElem.innerHTML = getTextDiv('You are currently hunting here.'); } else if (cachedHud) { previewElem.innerHTML = cachedHud; // the frox HUD specifically sets margin-bottom to display correctly, don't override it previewElem.querySelector(' div').style.marginBottom = (envType == 'fort_rox') ? '' :'0px'; } else if (cachedHud != undefined) { previewElem.innerHTML = getTextDiv('This location does not have a HUD.'); } else { previewElem.innerHTML = getTextDiv('There is no saved data for this location, travel here at least once to save the HUD.'); } } // it's called LG complex, not LG simple, amirite function renderLgComplex(envType) { if (user.environment_type == envType) { // current location, display the inverse version if (document.querySelector('#hudLocationContent .corrupted')) { // at twisted return areaHuds[envType] || getTextDiv('There is no saved data for the normal version of this location.'); } else { // at normal return areaHuds[envType + TWISTED] || getTextDiv('There is no saved data for the twisted version of this location.'); } } else { // not at location, display both (if available) const normal = areaHuds[envType] || ''; const twisted = areaHuds[envType + TWISTED] || ''; const noData = getTextDiv('There is no saved data for this location, travel here at least once to save the HUD.'); return (normal + twisted) ? normal + twisted : noData; } } // hide the whole thing when Quick Travel is selected function updateVisibility() { const mapTab = document.querySelector('.mousehuntHud-page-tabContent.map'); if (!mapTab) return; // idk just return const mainDiv = document.getElementById(MAIN_ID); if (!mapTab) return; // idk just return again // hide mainDiv if it's quick travel, and vice versa mainDiv.style.display = mapTab.classList.contains('quick') ? 'none' : ''; } function getMainDiv() { const mainDiv = document.createElement('div'); mainDiv.style.color = '#FFF' mainDiv.style.background = 'url(https://www.mousehuntgame.com/images/ui/backgrounds/hud_bg_blue_repeating.png?asset_cache_version=2) repeat-y bottom center'; mainDiv.style.borderRadius = '12px'; mainDiv.style.paddingTop = '10px'; mainDiv.style.paddingBottom = '10px'; mainDiv.style.marginBottom = '10px'; mainDiv.style.boxShadow = '-1px -1px 1px #ccc inset'; mainDiv.id = MAIN_ID; // title div const titleDiv = document.createElement('div'); titleDiv.style.height = '20px'; titleDiv.style.paddingLeft = '10px'; titleDiv.style.paddingRight = '10px'; titleDiv.style.display = 'flex'; titleDiv.style.justifyContent = 'space-between'; titleDiv.style.alignItems = 'center'; const titleText = document.createElement('div'); titleText.innerHTML = '<b>Location HUD Preview</b>' titleDiv.appendChild(titleText); const toggleBtn = document.createElement('button'); toggleBtn.innerHTML = areaHuds.display ? '-' : '+'; toggleBtn.style.padding = '0'; toggleBtn.style.height = '18px'; toggleBtn.style.width = '18px'; toggleBtn.style.borderRadius = '5px'; toggleBtn.style.background = '#ccc'; toggleBtn.style.border = '1px solid #999'; toggleBtn.addEventListener('click', (e) => toggleDisplay(e.target)); titleDiv.appendChild(toggleBtn); mainDiv.appendChild(titleDiv); // preview elem const previewElem = document.createElement('div'); previewElem.style.paddingTop = '10px'; previewElem.id = PREVIEW_ID; previewElem.style.display = areaHuds.display ? '' : 'none'; mainDiv.appendChild(previewElem); return mainDiv; } function getTextDiv(text) { return `<div style="padding-left:10px;">${text}</div>`; } // button onclicks function toggleDisplay(element) { const previewElem = document.getElementById(PREVIEW_ID); if (!previewElem) return; areaHuds.display = !areaHuds.display; previewElem.style.display = areaHuds.display ? '' : 'none'; element.innerHTML = areaHuds.display ? '-' : '+'; //saveCache(); } // process and store the current location HUD function storeHud() { var hudElem = document.getElementById('hudLocationContent'); if (!hudElem) { console.log('failed to get HUD element'); return; } const envType = user.environment_type; var hudName = envType; var cloneHud = hudElem.cloneNode(true); // disable all warning elements (wrong powertype etc) var activeList = cloneHud.querySelectorAll('.active'); activeList.forEach((elem) => { if (elem.className.toLowerCase().indexOf('warning') != -1) { elem.classList.remove('active'); } }); // location-based processing if (LG_COMPLEX.includes(envType)) { cloneHud.querySelectorAll('.baitWarning').forEach((elem) => elem.remove()); if (cloneHud.querySelector('.corrupted')) { // is twisted version hudName = envType + TWISTED; } } else if (LABYKOR.includes(envType)) { // remove zokor hud if in laby, and vice versa - both areas can't coexist const pairEnv = LABYKOR[(LABYKOR.indexOf(envType) + 1) % 2]; // fancy mirror math that returns the counterpart delete areaHuds[pairEnv]; } fixHud(envType, cloneHud); // strip mouse events and href from the cached HUD to disable clicks const cloneInnerHtml = cloneHud.innerHTML .replace(/on[a-z]+?=".+?"/g, '') .replace(/ href="#"/g, ''); areaHuds[hudName] = cloneInnerHtml; saveCache(); } // fix HUD elements that don't display properly as preview function fixHud(envType, hudElem) { var colorSelector = []; switch(envType) { case 'zugzwang_tower': // I could fix floating elements, but I will delete them instead // do not try me hudElem.querySelectorAll('.zugzwangsTowerHUD-retreatButton').forEach((elem) => elem.remove()); break; case 'sunken_city': colorSelector.push('.item.quantity'); break; case 'rift_gnawnia': colorSelector.push('.riftGnawniaHud-label'); break; case 'rift_valour': colorSelector.push('.valourRiftHUD-fuelContainer-armButton'); colorSelector.push('.valourRiftHUD-powerUp-title'); break; case 'rift_bristle_woods': colorSelector.push('.riftBristleWoodsHUD-chamberSpecificTextContainer'); break; } colorSelector.forEach((selector) => { hudElem.querySelectorAll(selector).forEach((elem) => {elem.style.color = 'white'}); }); } // init loadCache(); initHooks(); storeHud(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址