Greasy Fork

MouseHunt HUD Backgroundifier

Change your HUD background (But why? What possessed you to seek this out?)

目前为 2021-10-19 提交的版本。查看 最新版本

// ==UserScript==
// @name         MouseHunt HUD Backgroundifier
// @author       LethalVision
// @version      0.2
// @description  Change your HUD background (But why? What possessed you to seek this out?)
// @include	http://mousehuntgame.com/*
// @include	https://mousehuntgame.com/*
// @include	http://www.mousehuntgame.com/*
// @include	https://www.mousehuntgame.com/*
// @grant        none
// @namespace    https://greasyfork.org/en/users/683695-lethalvision
// ==/UserScript==

const TAG = "HUD_BCKGRNDFR"
const BACK_URL = "https://media.discordapp.net/attachments/857605363314458634/898655517034053652/genshin21.png";

var preferences = {
    imgUrl: "",
    mode: "",
    statOpacity: 1,
    hudOpacity: 1,
    statShadow: false
};

function init() {
    var loadedPref = window.localStorage.getItem(TAG);
    if (loadedPref){
        try{
            loadedPref = JSON.parse(loadedPref);
            preferences.imgUrl = loadedPref.imgUrl;
            preferences.mode = loadedPref.mode;
            preferences.statOpacity = loadedPref.statOpacity;
            preferences.hudOpacity = loadedPref.hudOpacity;
            preferences.statShadow = loadedPref.statShadow;
            console.log("Backgroundifier preferences loaded");
        } catch (err) {
            console.log('Preference parse error: ' + err);
        }
    }
    addListener();
    addButton();
    setTimeout(function(){
        updateAll();
    }, 500);
}

// stuff preferences into the localStorage
function savePreferences() {
    var jsonString = JSON.stringify(preferences);
    window.localStorage.setItem(TAG, jsonString);
}

function addListener() {
    const originalOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function() {
        this.addEventListener("load", function() {
            if ( this.responseURL === "https://www.mousehuntgame.com/managers/ajax/pages/page.php" ||
               this.responseURL === "https://www.mousehuntgame.com/managers/ajax/pages/preferences.php") {
                addButton();
                updateAll();

            }
        });
        originalOpen.apply(this, arguments);
    };
}

// === SMOKE AND MIRRORS HERE ===
// add button to bring up the settings
function addButton() {
    if (document.getElementById("hudBtn")) {
        // if button already exists
        console.log("ding");
        return;
    }
    const div = document.createElement("div");
    div.className = "hudBtn-container";
    div.style.position = "absolute";
    div.style.bottom = "5px";
    div.style.right = "7px"

    const hudBtn = document.createElement("button");
    hudBtn.id = "hudBtn";
    hudBtn.textContent = "!";
    hudBtn.style.width = "20px"
    hudBtn.style.height = "20px"
    hudBtn.style.opacity = "0.5"
    hudBtn.onclick = function(){renderBox();}

    div.appendChild(hudBtn);
    const hudContainer = document.getElementsByClassName("headsUpDisplayView")[0];
    hudContainer.insertAdjacentElement("afterend",div);
}

// render the almighty Tsitu's Floating Box
function renderBox(){return new Promise((resolve, reject) => {
    // clear all open boxes
    document
     .querySelectorAll("#hud-options")
     .forEach(el=> el.remove())

    const div = document.createElement("div");
    div.id = "hud-options";
    div.style.backgroundColor = "#F5F5F5";
    div.style.position = "fixed";
    div.style.zIndex = "9999";

    div.style.left = "35vw";
    div.style.top = "55vh";

    div.style.border = "solid 3px #696969";
    div.style.borderRadius = "20px";
    div.style.padding = "10px";
    div.style.textAlign = "left";
    div.style.minWidth = "207px";

    const buttonDiv = document.createElement("div");
    buttonDiv.style.float= "right";
    buttonDiv.style.textAlign = "right";
    const closeButton = document.createElement("button", {
        id: "close-button"
    });
    closeButton.textContent = "x";
    closeButton.onclick = function () {
    document.body.removeChild(div);
    };
    closeButton.style.marginRight = "5px"

    const titleDiv = document.createElement("div")
    titleDiv.id = "hud-optionsheader";
    titleDiv.textContent = "HUD Backgroundifier";
    titleDiv.style.width = "75%";
    titleDiv.style.float= "left";
    titleDiv.style.textAlign = "left";
    titleDiv.style.fontSize = "12px"
    titleDiv.style.fontWeight = "bold";
    titleDiv.style.marginLeft = "5px";

    var urlTable = document.createElement('table');
    urlTable.className = "clear"
    urlTable.style.textAlign = "left";
    urlTable.style.borderSpacing = "1em 0";
    urlTable.style.paddingTop = "5px"

    var topRow = urlTable.insertRow();
    topRow.style.height = "24px";
    var topDesc = topRow.insertCell(0);
    topDesc.appendChild(document.createTextNode("Image URL:"));
    // set width once and the rest should follow
    topDesc.style.width = "20%"
    var urlInput = document.createElement('input');
    urlInput.id = "urlInput";
    urlInput.style.width = "95%";
    urlInput.value = preferences.imgUrl;
    urlInput.onchange = function(){
        checkAndLoadImage(urlInput.value);
    }
    topRow.insertCell(1).appendChild(urlInput);

    const opDiv = document.createElement("div")
    opDiv.textContent = "Transparency Settings";
    opDiv.style.fontWeight = "bold";
    opDiv.style.textAlign = "left";
    opDiv.style.marginTop = "5px";
    opDiv.style.marginLeft = "5px";

    var opTable = document.createElement('table');
    opTable.style.textAlign = "left";
    opTable.style.borderSpacing = "1em 0";
    opTable.style.paddingTop = "5px"

    var statOpRow = opTable.insertRow();
    statOpRow.style.height = "24px";
    var statDesc = statOpRow.insertCell(0);
    statDesc.appendChild(document.createTextNode("Hunter Stats:"));
    // set width once and the rest should follow
    statDesc.style.width = "20%"
    var statSlider = document.createElement('input');
    statSlider.id = "statSlider";
    statSlider.type = "range"
    statSlider.style.width = "95%";
    statSlider.style.verticalAlign = "middle";
    // this is where I should use some fancy function to handle the conversion for each slider instead of just copy/pasting it twice
    // but it's 3AM and I'm in physical pain
    statSlider.value = preferences.statOpacity*100;
    statSlider.onchange = function(){
        preferences.statOpacity = statSlider.value/100.0;
        updateOpacity()
    }
    statOpRow.insertCell(1).appendChild(statSlider);

    var hudOpRow = opTable.insertRow();
    hudOpRow.style.height = "24px";
    var hudDesc = hudOpRow.insertCell(0);
    hudDesc.appendChild(document.createTextNode("Location HUD:"));
    // set width once and the rest should follow
    hudDesc.style.width = "20%"
    var hudSlider = document.createElement('input');
    hudSlider.id = "hudSlider";
    hudSlider.type = "range"
    hudSlider.style.width = "95%";
    hudSlider.style.verticalAlign = "middle";
    hudSlider.value = preferences.hudOpacity*100;
    hudSlider.onchange = function(){
        preferences.hudOpacity = hudSlider.value/100.0;
        updateOpacity()
    }
    hudOpRow.insertCell(1).appendChild(hudSlider);

    const miscDiv = document.createElement("div")
    miscDiv.textContent = "Misc Settings";
    miscDiv.style.fontWeight = "bold";
    miscDiv.style.textAlign = "Left";
    miscDiv.style.marginTop = "5px";
    miscDiv.style.marginLeft = "5px";

    var shadowLabel = document.createElement("label");
    shadowLabel.textContent = "Toggle shadow for hunter stats";
    shadowLabel.style.textAlign = "left";
    shadowLabel.style.marginLeft = "10px";
    var shadowCheckbox = document.createElement('input');
    shadowCheckbox.id = "shadowCheckbox";
    shadowCheckbox.style.height = "24px";
    shadowCheckbox.style.verticalAlign = "middle";
    shadowCheckbox.type = "checkbox"
    shadowCheckbox.checked = preferences.statShadow;
    shadowCheckbox.onchange = function(){
        preferences.statShadow = shadowCheckbox.checked;
        updateShadow();
    }
    shadowLabel.appendChild(shadowCheckbox);

    buttonDiv.appendChild(closeButton);
    div.appendChild(titleDiv);
    div.appendChild(buttonDiv)
    div.appendChild(urlTable);
    div.appendChild(opDiv);
    div.appendChild(opTable);
    div.appendChild(miscDiv);
    div.appendChild(shadowLabel);
    document.body.appendChild(div);
    // why does this exist
    dragElement(div);
    resolve();
})}

// === Tsitu's drag magic functions ===
// no seriously this should be a library or something
function dragElement(elmnt) {
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  if (document.getElementById(elmnt.id + "header")) {
    // if present, the header is where you move the DIV from:
    document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
  } else {
    // otherwise, move the DIV from anywhere inside the DIV:
    elmnt.onmousedown = dragMouseDown;
  }

  function dragMouseDown(e) {
    e = e || window.event;
    e.preventDefault();
    // get the mouse cursor position at startup:
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    // call a function whenever the cursor moves:
    document.onmousemove = elementDrag;
  }

  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    // calculate the new cursor position:
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    // set the element's new position:
    elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
    elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
  }

  function closeDragElement() {
    // stop moving when mouse button is released:
    document.onmouseup = null;
    document.onmousemove = null;
  }
}

// === Main logic ===

async function checkAndLoadImage(url) {
    if (url){
        // check if url is a valid image
        let imgPromise = new Promise(function(resolve) {
            try{
                var img = new Image();
                img.onload = function(){
                    resolve(this.width != 0 && this.height != 0)
                };
                img.src = url;
            } catch (error) {
                console.error(error.stack);
                resolve(false);
            }
        });
        var validImage = await imgPromise;
        preferences.imgUrl = validImage ? url : "";
    } else {
        preferences.imgUrl = "";
    }
    savePreferences();
    updateHUD();
}

// Update the actual HUD
function updateHUD() {
    const drawerElem = document.getElementsByClassName("mousehuntHud-marbleDrawer")[0];
    // only update if a url is specified
    if (preferences.imgUrl){
        // YEAH HARDCODING
        drawerElem.style.background = `url(https://www.mousehuntgame.com/images/ui/hud/mousehuntHudPedestal.gif?asset_cache_version=2) -37px 0 no-repeat,
        url(https://www.mousehuntgame.com/images/ui/hud/mousehuntHudPedestal.gif?asset_cache_version=2) 723px 0 no-repeat,
        url(${preferences.imgUrl}) bottom center / 100%`;
    } else {
        // this should reset the background
        drawerElem.style.background = "";
    }
}

// update transparency
function updateOpacity() {
    savePreferences();
    const statsElem = document.getElementsByClassName("headsUpDisplayView-stats")[0];
    const hudElem = document.getElementsByClassName("hudLocationContent")[0];

    statsElem.style.opacity = preferences.statOpacity;
    hudElem.style.opacity = preferences.hudOpacity;
}

// update stat shading
function updateShadow() {
    savePreferences();
    const statsElem = document.getElementsByClassName("headsUpDisplayView-stats")[0];
    if (preferences.statShadow) {
        // set background to black with 0.3 opacity
        statsElem.style.backgroundColor = "rgba(0, 0, 0, 0.30)";
    } else {
        statsElem.style.backgroundColor = "transparent";
    }
}

function updateAll() {
    updateHUD();
    updateOpacity();
    updateShadow();
}
// start the script
init();