MegamiDeviceBP - EnglishTranslationScript

Text blocks for param01-10 with universal bg; swap bpp.png to English version without breaking formatting; swap bchart_bg.png to English version without breaking formatting

目前為 2025-08-22 提交的版本,檢視 最新版本

// ==UserScript==
// @name         MegamiDeviceBP - EnglishTranslationScript
// @namespace    http://tampermonkey.net/
// @version      4.0
// @description  Text blocks for param01-10 with universal bg; swap bpp.png to English version without breaking formatting; swap bchart_bg.png to English version without breaking formatting
// @match        https://user.kotobukiya.co.jp/megamideviceBP/*
// @grant        none
// @run-at       document-idle
// @author       Animal22
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // ---------------- Chart logic ----------------
    const CHART_NEEDLE = 'chart_bg.png';
    const CHART_REPLACEMENT = 'https://i.postimg.cc/13Z3vq2K/chart.png';
    const replacementChartImg = new Image();
    replacementChartImg.src = CHART_REPLACEMENT;

    // Hook img.src
    const imgDesc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, 'src');
    Object.defineProperty(HTMLImageElement.prototype, 'src', {
        configurable: true,
        enumerable: imgDesc.enumerable,
        get: imgDesc.get,
        set(url) {
            if (typeof url === 'string' && url.includes(CHART_NEEDLE)) url = CHART_REPLACEMENT;
            return imgDesc.set.call(this, url);
        }
    });

    // Hook setAttribute('src', ...)
    const _setAttr = Element.prototype.setAttribute;
    Element.prototype.setAttribute = function(name, value) {
        if (name === 'src' && typeof value === 'string' && value.includes(CHART_NEEDLE)) {
            value = CHART_REPLACEMENT;
        }
        return _setAttr.call(this, name, value);
    };

    // Hook drawImage for canvas
    const originalDrawImage = CanvasRenderingContext2D.prototype.drawImage;
    CanvasRenderingContext2D.prototype.drawImage = function(...args) {
        try {
            let img = args[0];
            if (img && img.src && img.src.includes(CHART_NEEDLE)) {
                args[0] = replacementChartImg;
            }
        } catch (e) {}
        return originalDrawImage.apply(this, args);
    };

    // ---------------- Translate logic ----------------
    const replacements = {
        "param01.png": "Short-Range Attack",
        "param02.png": "Mid-Range Attack",
        "param03.png": "Long-Range Attack",
        "param04.png": "Armor/Defense",
        "param05.png": "Weight",
        "param06.png": "Endurance",
        "param07.png": "Stealth",
        "param08.png": "Search",
        "param09.png": "Aerial Mobility",
        "param10.png": "Ground  Mobility"
    };

    const textColor = "#e58801";
    const backgroundColor = "#535353";
    const blockWidth = "434px";
    const padding = "4px 8px";
    const borderRadius = "0";
    const backgroundImageURL = "https://i.postimg.cc/Mp4VmjL5/param.png";
    const bppReplacementURL = "https://i.postimg.cc/4dJcfCF7/Header.png";

    function filenameFromURL(u) {
        if (!u) return "";
        const clean = u.split("#")[0].split("?")[0];
        return clean.split("/").pop() || "";
    }

    function replaceTranslateImages(root = document) {
        root.querySelectorAll("img").forEach(img => {
            if (img.dataset.replaced === "true") return;

            const candidates = [img.getAttribute("src"), img.getAttribute("data-src"), img.src].filter(Boolean);

            for (const s of candidates) {
                const file = filenameFromURL(s);

                // param01–param10 → text block
                if (replacements[file]) {
                    const span = document.createElement("span");
                    span.textContent = replacements[file];
                    span.style.color = textColor;
                    span.style.backgroundColor = backgroundColor;
                    span.style.padding = padding;
                    span.style.borderRadius = borderRadius;
                    span.style.backgroundImage = `url('${backgroundImageURL}')`;
                    span.style.backgroundSize = "cover";
                    span.style.backgroundRepeat = "no-repeat";
                    span.style.fontWeight = "bold";
                    span.style.display = "inline-block";
                    span.style.width = blockWidth;
                    span.style.boxSizing = "border-box";

                    img.replaceWith(span);
                    img.dataset.replaced = "true";
                    return;
                }

                // bpp.png → swap src
                if (file === "bpp.png") {
                    const rect = img.getBoundingClientRect();
                    if (!img.getAttribute("width") && rect.width) img.setAttribute("width", Math.round(rect.width));
                    if (!img.getAttribute("height") && rect.height) img.setAttribute("height", Math.round(rect.height));
                    img.src = bppReplacementURL;
                    if (img.srcset !== undefined) img.srcset = "";
                    img.dataset.replaced = "true";
                    return;
                }
            }
        });
    }

    // ---------------- MutationObserver ----------------
    const observer = new MutationObserver(mutations => {
        for (const mutation of mutations) {
            mutation.addedNodes.forEach(node => {
                if (node.nodeType !== 1) return; // Only elements
                replaceTranslateImages(node);
            });
        }
    });

    // Start observing as soon as document.body exists
    function startObserver() {
        if (!document.body) {
            requestAnimationFrame(startObserver);
            return;
        }
        replaceTranslateImages(); // Initial run for existing images
        observer.observe(document.body, { childList: true, subtree: true });
    }

    startObserver();

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址