Greasy Fork

Greasy Fork is available in English.

MouseHunt Hyperspeed Travel

Because regular travel isn't nearly fast enough

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         MouseHunt Hyperspeed Travel
// @description  Because regular travel isn't nearly fast enough
// @author       LethalVision
// @version      1.1
// @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    http://greasyfork.icu/en/users/683695-lethalvision
// ==/UserScript==

(function () {
    const PREF_TAG = 'fast-travel-cache'
    const TRAVEL_TAG = 'fast-travel-list'
    const LINK_TAG = 'fast-travel-link'

    var currentLoc = {};
    currentLoc.envName = user.environment_name;
    currentLoc.envType = user.environment_type;

    var recall = {};
    var locationList = {};

    // == local storage ==
    function loadPref() {
        var prefJson = window.localStorage.getItem(PREF_TAG);
        if (prefJson){
            try{
                //console.log('Loaded preference: ' + prefJson);
                var loadedPref = JSON.parse(prefJson);
                locationList = loadedPref.locationList || {};
                recall = loadedPref.recall || {};
            } catch (err) {
                console.log('Preference parse error: ' + err);
            }
        }
    }

    function savePref() {
        const preferences = {};
        preferences.locationList = locationList;
        preferences.recall = recall;
        var jsonString = JSON.stringify(preferences);
        window.localStorage.setItem(PREF_TAG, jsonString);
        //console.log('Saved preference: ' + jsonString);
    }

    function initAjaxHooks() {
        const pageUrl = 'managers/ajax/pages/page.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) {
                    updateTravelLinks();
                } else if (this.responseURL.indexOf(travelUrl) != -1) {
                    updateRecall();
                }
            });
            originalOpen.apply(this, arguments);
        };
        // in case the window is refreshed in travel.php
        if (window.location.href.includes("travel.php")) {
            updateTravelLinks();
        }
    }

    function updateTravelTab() {
        const travelTab = document.querySelector('.travel');
        if (!travelTab) {
            return;
        }
        // remove stale listbody before start
        document.querySelectorAll(`.${TRAVEL_TAG}`).forEach(item => item.remove());
        // create new listbody
        const listBody = document.createElement("ul");
        listBody.classList.add(TRAVEL_TAG);
        travelTab.appendChild(listBody);
        // add recall
        if (!recall.envName || !recall.envType) { // set recall to current loc if empty
            recall.envName = currentLoc.envName;
            recall.envType = currentLoc.envType;
            savePref();
        }
        const recallItem = document.createElement("li");
        recallItem.innerHTML = getListHtml(`<b>Recall</b> - ${recall.envName}`);
        recallItem.onclick = function(){
            app.pages.TravelPage.travel(recall.envType);
        };
        listBody.appendChild(recallItem);
        // add clear prefs
        const clearItem = document.createElement("li");
        clearItem.innerHTML = getListHtml('<div style="color: red;"><b>Clear Saved Locations</b></div>');
        clearItem.onclick = function(){
            locationList = {};
            saveAndRefresh();
        };
        listBody.appendChild(clearItem);
        // add the rest
        for (var key in locationList) {
            const listItem = document.createElement("li");
            listItem.innerHTML = getListHtml(locationList[key]);
            const envType = key;
            listItem.onclick = function(){
                app.pages.TravelPage.travel(envType);
            };
            listBody.appendChild(listItem);
        }
    }

    function getListHtml(textElemStr) {
        return `<a href="#" style="overflow: hidden; white-space: nowrap; text-overflow: ellipsis;"><div class="icon"></div>${textElemStr}</a>`;
    }

    function updateTravelLinks() {
        // remove stale links before start
        document.querySelectorAll(`.${LINK_TAG}`).forEach(item => item.remove());
        // update links
        const detailList = document.querySelectorAll('.travelPage-map-environment-detail');
        detailList.forEach(item => {
            const descElem = item.querySelector('.travelPage-map-environment-detail-shops');
            if (!descElem) return;
            const envType = item.getAttribute('data-environment-type');
            if (!envType) return;
            const travelLink = document.createElement("p");
            travelLink.classList.add(LINK_TAG);
            var linkElem = document.createElement("a");
            if (locationList[envType]) {
                // location already registered
                linkElem.innerText = 'Remove from Fast Travel';
                linkElem.style.color = 'red';
                linkElem.onclick = function() {removeLocation(envType);};
            } else {
                const envTitle = item.querySelector('.travelPage-map-environment-detail-title');
                if (!envTitle) return;
                // extract location name from title
                const envName = envTitle.innerText.replace(/\([^\)]+\)/g, '').trim();
                linkElem.innerText = 'Add to Fast Travel';
                linkElem.onclick = function() {addLocation(envType, envName);};
            }
            travelLink.appendChild(linkElem);
            descElem.appendChild(travelLink);
        });
    }

    function removeLocation(envType) {
        //console.log('removeLocation');
        delete locationList[envType];
        saveAndRefresh();
    }

    function addLocation(envType, envName) {
        //console.log('addLocation: ' + envName);
        locationList[envType] = envName;
        saveAndRefresh();
    }

    function updateRecall() {
        // save previous location
        recall.envName = currentLoc.envName;
        recall.envType = currentLoc.envType;
        // refresh current location
        currentLoc.envName = user.environment_name;
        currentLoc.envType = user.environment_type;
        saveAndRefresh();
    }

    function saveAndRefresh() {
        savePref();
        updateTravelTab();
        updateTravelLinks();
    }

    // init
    loadPref();
    initAjaxHooks();
    updateTravelTab();
})();