Greasy Fork

Greasy Fork is available in English.

[MWI] Ultimate Enhancement Notifier v2.6 (Styled)

Optimize floating enhancement panel and add toggle to F9, update styling

当前为 2025-04-05 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         [MWI] Ultimate Enhancement Notifier v2.6 (Styled)
// @namespace    http://tampermonkey.net/
// @version      2.6
// @description  Optimize floating enhancement panel and add toggle to F9, update styling
// @author       Truth_Light (modified by Nex, styled by Cosmic)
// @match        https://www.milkywayidle.com/*
// @match        https://test.milkywayidle.com/*
// @license      MIT
// @grant        GM_registerMenuCommand
// @icon         https://www.google.com/s2/favicons?sz=64&domain=milkywayidle.com
// ==/UserScript==

(function() {
    'use strict';

    // ======================
    // STYLE CONFIGURATION
    // ======================
    const STYLE = {
      colors: {
        primary: '#00ffe7', // Bright neon cyan
        background: 'rgba(5, 5, 15, 0.95)', // Deep black-blue
        border: '1px solid rgba(0, 255, 234, 0.4)', // Glowing border
        textPrimary: '#e0f7ff', // Soft neon white-blue
        textSecondary: '#9b9bff', // Neon purple tint
        accent: '#ff00d4', // Vibrant pink-magenta
        danger: '#ff0055', // Electric red
        success: '#00ff99', // Neon green
        headerBg: 'rgba(15, 5, 35, 0.7)', // Dark purple gradient tint
        epic: '#c63dff', // Deep neon purple
        legendary: '#ff6f1a', // Bright orange neon
        mythic: '#ff0033', // Intense mythic red
        blessed: 'linear-gradient(135deg, #ff00d4, #c63dff, #00ffe7)' // Trippy neon gradient
      },
      fonts: {
        primary: '14px "Orbitron", "Segoe UI", Roboto, sans-serif', // Futuristic font
        secondary: '12px "Orbitron", "Segoe UI", Roboto, sans-serif',
        header: 'bold 16px "Orbitron", "Segoe UI", Roboto, sans-serif',
        milestone: 'bold 18px "Orbitron", "Segoe UI", Roboto, sans-serif'
      },
      shadows: {
        panel: '0 0 20px rgba(0, 255, 234, 0.3)', // Neon glow panel
        notification: '0 0 15px rgba(255, 0, 212, 0.3)', // Pink neon soft glow
        milestone: '0 0 25px rgba(198, 61, 255, 0.4)', // Epic purple glow
        text: '0 0 6px rgba(0, 255, 234, 0.3)' // Soft text glow
      },
      borderRadius: {
        medium: '14px', // Rounded with a modern edge
        small: '8px'
      },
      transitions: {
        fast: 'all 0.15s ease-in-out',
        medium: 'all 0.3s ease-in-out',
        slow: 'all 0.5s ease-in-out'
      }
    };

    // Core Variables
    const userLanguage = localStorage.getItem('i18nextLng');
    let enhancementLevel;
    let currentEnhancingIndex = 1;
    let enhancementData = {
        [currentEnhancingIndex]: { "强化数据": {}, "其他数据": {} }
    };
    let item_name_to_hrid;
    let item_hrid_to_name;

    const isZH = userLanguage.startsWith("zh");

    // ======================
    // NOTIFICATION SYSTEM
    // ======================

    function createNotificationContainer(headerElement) {
        const container = document.createElement("div");
        container.id = "enhancementNotificationContainer";
        Object.assign(container.style, {
            position: "absolute",
            top: "calc(100% + 5px)",
            left: "50%",
            transform: "translateX(-50%)",
            zIndex: "9999",
            display: "flex",
            flexDirection: "column",
            gap: "5px",
            width: "220px",
            pointerEvents: "none"
        });

        if (getComputedStyle(headerElement).position === "static") {
            headerElement.style.position = "relative";
        }

        headerElement.appendChild(container);
        return container;
    }

    function showNotification(message, type, level, isBlessed = false) {
        const headerElement = document.querySelector('[class^="Header_myActions"]');
        if (!headerElement) return;

        let container = document.getElementById("enhancementNotificationContainer");
        if (!container) {
            container = createNotificationContainer(headerElement);
        }

        if (type === "success") {
            createStandardNotification(container, level, isBlessed);

            if (level >= 10) {
                setTimeout(() => {
                    createMilestoneNotification(container, level);
                }, 300);
            }
        } else {
            createFailureNotification(container);
        }
    }

    function createStandardNotification(container, level, isBlessed) {
        const notification = document.createElement("div");
        notification.className = "enhancement-notification standard";

        Object.assign(notification.style, {
            padding: "10px 15px",
            borderRadius: STYLE.borderRadius.small,
            color: "white",
            fontWeight: "bold",
            boxShadow: STYLE.shadows.notification,
            transform: "translateY(-20px)",
            opacity: "0",
            transition: STYLE.transitions.medium,
            textAlign: "center",
            marginBottom: "5px",
            position: "relative",
            overflow: "hidden",
            pointerEvents: "auto",
            textShadow: STYLE.shadows.text
        });

        if (isBlessed) {
            Object.assign(notification.style, {
                background: STYLE.colors.blessed,
                color: "#8B4513"
            });
            notification.textContent = isZH ? `祝福强化! +${level}` : `BLESSED! +${level}`;
            addHolyEffects(notification);
        } else {
            notification.style.background = getLevelGradient(level);
            notification.textContent = isZH ? `强化成功 +${level}` : `Success +${level}`;
        }

        animateNotification(notification, container, level, isBlessed);
    }

    function createMilestoneNotification(container, level) {
        const milestone = document.createElement("div");
        milestone.className = "enhancement-notification milestone";

        Object.assign(milestone.style, {
            padding: "12px 15px",
            borderRadius: STYLE.borderRadius.small,
            color: "white",
            fontWeight: "bolder",
            boxShadow: STYLE.shadows.milestone,
            transform: "translateY(-20px)",
            opacity: "0",
            transition: STYLE.transitions.medium,
            textAlign: "center",
            marginBottom: "5px",
            animation: "pulse 2s infinite",
            position: "relative",
            overflow: "hidden",
            pointerEvents: "auto",
            textShadow: STYLE.shadows.text,
            font: STYLE.fonts.milestone
        });

        if (level >= 20) {
            milestone.style.background = `
                linear-gradient(
                    135deg,
                    ${STYLE.colors.mythic},
                    #ff0044,
                    #ff2200,
                    #ff0055
                )
            `;
            milestone.style.backgroundSize = "400% 400%";
            milestone.style.animation = "mythicPulse 2.5s ease-in-out infinite";

            milestone.style.color = "#fff";
            milestone.style.fontWeight = "bold";
            milestone.style.textShadow = `
                0 0 4px #ff0044,
                0 0 8px #ff0044,
                0 0 12px #ff0044
            `;
            milestone.textContent = isZH ? "命中注定!" : "IT. IS. DESTINY.";
        }
        else if (level >= 15) {
            milestone.style.background = `linear-gradient(135deg, ${STYLE.colors.legendary}, #FF6600)`;
            milestone.style.textShadow = "0 0 8px rgba(255, 102, 0, 0.8)";
            milestone.textContent = isZH ? "奇迹发生!" : "IT'S A MIRACLE!";
        }
        else if (level >= 10) {
            milestone.style.background = `linear-gradient(135deg, ${STYLE.colors.epic}, #8000FF)`;
            milestone.style.textShadow = "0 0 8px rgba(153, 51, 255, 0.8)";
            milestone.textContent = isZH ? "运气不错!" : "NICE LUCK!";
        }

        animateNotification(milestone, container, level, false);
    }

    function createFailureNotification(container) {
        const notification = document.createElement("div");
        notification.className = "enhancement-notification failure";

        Object.assign(notification.style, {
            padding: "10px 15px",
            borderRadius: STYLE.borderRadius.small,
            color: "white",
            fontWeight: "bold",
            boxShadow: STYLE.shadows.notification,
            transform: "translateY(-20px)",
            opacity: "0",
            transition: STYLE.transitions.medium,
            textAlign: "center",
            marginBottom: "5px",
            position: "relative",
            overflow: "hidden",
            pointerEvents: "auto",
            textShadow: STYLE.shadows.text,
            backgroundColor: STYLE.colors.danger,
            borderTop: "3px solid #C62828"
        });
        notification.textContent = isZH ? "强化失败!" : "Failed!";

        animateNotification(notification, container, 0, false);
    }

    function animateNotification(notification, container, level, isBlessed) {
        container.appendChild(notification);

        setTimeout(() => {
            notification.style.transform = "translateY(0)";
            notification.style.opacity = "1";
        }, 10);

        setTimeout(() => {
            notification.style.transform = "translateY(20px)";
            notification.style.opacity = "0";
            setTimeout(() => notification.remove(), 300);
        }, getNotificationDuration(level, isBlessed));

        notification.addEventListener("click", () => {
            notification.style.transform = "translateY(20px)";
            notification.style.opacity = "0";
            setTimeout(() => notification.remove(), 300);
        });
    }

    function addHolyEffects(notification) {
        const rays = document.createElement("div");
        rays.className = "holy-rays";
        Object.assign(rays.style, {
            position: "absolute",
            top: "0",
            left: "0",
            width: "100%",
            height: "100%",
            background: "radial-gradient(circle, transparent 20%, rgba(255,215,0,0.3) 70%)",
            pointerEvents: "none",
            animation: "raysRotate 4s linear infinite"
        });
        notification.appendChild(rays);

        for (let i = 0; i < 4; i++) {
            const cross = document.createElement("div");
            cross.textContent = "✝";
            Object.assign(cross.style, {
                position: "absolute",
                fontSize: "16px",
                animation: `floatUp ${3 + Math.random() * 2}s linear infinite`,
                opacity: "0.7",
                left: `${10 + (i * 25)}%`,
                top: "100%"
            });
            notification.appendChild(cross);
        }
    }

    function getLevelGradient(level) {
        if (level >= 20) {
            return `linear-gradient(135deg, ${STYLE.colors.mythic}, #FF0000)`;
        }
        else if (level >= 15) {
            return `linear-gradient(135deg, ${STYLE.colors.legendary}, #FF6600)`;
        }
        else if (level >= 10) {
            return `linear-gradient(135deg, ${STYLE.colors.epic}, #8000FF)`;
        }
        else if (level >= 5) {
            return "linear-gradient(135deg, #3399FF, #0066FF)";
        }
        else if (level >= 1) {
            return "linear-gradient(135deg, #33CC33, #009900)";
        }
        else {
            return "linear-gradient(135deg, #CCCCCC, #999999)";
        }
    }

    function getNotificationDuration(level, isBlessed) {
        if (isBlessed) return 5000;
        if (level >= 20) return 5000;
        if (level >= 15) return 4000;
        if (level >= 10) return 3000;
        return 2500;
    }

    // ======================
    // ENHANCEMENT TRACKING
    // ======================

    function hookWS() {
        const dataProperty = Object.getOwnPropertyDescriptor(MessageEvent.prototype, "data");
        const oriGet = dataProperty.get;

        dataProperty.get = hookedGet;
        Object.defineProperty(MessageEvent.prototype, "data", dataProperty);

        function hookedGet() {
            const socket = this.currentTarget;
            if (!(socket instanceof WebSocket)) return oriGet.call(this);
            if (!socket.url.includes("api.milkywayidle.com/ws") && !socket.url.includes("api-test.milkywayidle.com/ws")) {
                return oriGet.call(this);
            }

            const message = oriGet.call(this);
            Object.defineProperty(this, "data", { value: message });
            return handleMessage(message);
        }
    }

    function handleMessage(message) {
        try {
            const obj = JSON.parse(message);
            if (!obj) return message;

            if (obj.type === "init_character_data") {
                handleInitData();
            } else if (obj.type === "action_completed" && obj.endCharacterAction?.actionHrid === "/actions/enhancing/enhance") {
                handleEnhancement(obj.endCharacterAction);
            }
        } catch (error) {
            console.error("Error processing message:", error);
        }
        return message;
    }

    function handleInitData() {
        const initClientData = localStorage.getItem('initClientData');
        if (!initClientData) return;

        try {
            const data = JSON.parse(initClientData);
            if (data.type !== 'init_client_data') return;

            item_hrid_to_name = data.itemDetailMap;
            for (const key in item_hrid_to_name) {
                if (item_hrid_to_name[key]?.name) {
                    item_hrid_to_name[key] = item_hrid_to_name[key].name;
                }
            }
            item_name_to_hrid = Object.fromEntries(
                Object.entries(item_hrid_to_name).map(([key, value]) => [value, key])
            );
        } catch (error) {
            console.error('数据解析失败:', error);
        }
    }

    function handleEnhancement(action) {
        const newLevel = parseInt(action.primaryItemHash.match(/::(\d+)$/)[1]);
        const targetLevel = action.enhancingMaxLevel;
        const currentCount = action.currentCount;
        const wasBlessed = enhancementLevel !== undefined && (newLevel - enhancementLevel) >= 2;

        if (enhancementLevel !== undefined) {
            if (currentCount < enhancementData[currentEnhancingIndex]["强化次数"]) {
                startNewEnhancementSession();
                return;
            }

            const currentItem = enhancementData[currentEnhancingIndex]["强化数据"];
            if (!currentItem[enhancementLevel]) {
                currentItem[enhancementLevel] = { "成功次数": 0, "失败次数": 0, "成功率": 0 };
            }

            if (newLevel > enhancementLevel) {
                handleSuccess(currentItem, newLevel, wasBlessed);
            } else {
                handleFailure(action, currentItem);
            }

            if (newLevel >= targetLevel) {
                showTargetAchievedCelebration(newLevel, targetLevel);
            }

            updateStats(currentItem);
            enhancementData[currentEnhancingIndex]["强化状态"] = getEnhancementState(currentItem);
        } else {
            initializeNewItem(action, newLevel);
        }

        enhancementLevel = newLevel;
        enhancementData[currentEnhancingIndex]["强化次数"] = currentCount;
        updateDisplay();
        updateFloatingUI();
    }

    function startNewEnhancementSession() {
        currentEnhancingIndex++;
        enhancementData[currentEnhancingIndex] = { "强化数据": {}, "其他数据": {} };
        enhancementLevel = undefined;
    }

    function handleSuccess(currentItem, newLevel, wasBlessed) {
        currentItem[enhancementLevel]["成功次数"]++;
        const message = isZH ? `强化成功 +${newLevel}` : `Success +${newLevel}`;
        showNotification(
            wasBlessed ? (isZH ? `祝福强化! +${newLevel}` : `BLESSED! +${newLevel}`) : message,
            "success",
            newLevel,
            wasBlessed
        );
    }

    function handleFailure(action, currentItem) {
        currentItem[enhancementLevel]["失败次数"]++;
        showNotification(isZH ? "强化失败!" : "Failed!", "failure", 0);
        if (action.enhancingProtectionMinLevel >= 2 && enhancementLevel >= action.enhancingProtectionMinLevel) {
            enhancementData[currentEnhancingIndex]["其他数据"]["保护消耗总数"]++;
        }
    }

    function updateStats(currentItem) {
        const success = currentItem[enhancementLevel]["成功次数"];
        const failure = currentItem[enhancementLevel]["失败次数"];
        currentItem[enhancementLevel]["成功率"] = success / (success + failure);
    }

    function getEnhancementState(currentItem) {
        const highestSuccessLevel = Math.max(...Object.keys(currentItem).filter(level => currentItem[level]["成功次数"] > 0));
        return (highestSuccessLevel + 1 >= enhancementData[currentEnhancingIndex]["其他数据"]["目标强化等级"]) ? "强化成功" : "强化失败";
    }

    function initializeNewItem(action, newLevel) {
        const itemName = item_hrid_to_name[action.primaryItemHash.match(/::([^:]+)::[^:]*$/)[1]];
        enhancementData[currentEnhancingIndex]["其他数据"] = {
            "物品名称": itemName,
            "目标强化等级": action.enhancingMaxLevel,
            "保护消耗总数": 0,
        };
    }

    function showTargetAchievedCelebration(achievedLevel, targetLevel) {
        const celebration = document.createElement("div");
        celebration.id = "enhancementCelebration";
        Object.assign(celebration.style, {
            position: "fixed",
            top: "0",
            left: "0",
            width: "100%",
            height: "100%",
            zIndex: "99999",
            pointerEvents: "none",
            display: "flex",
            flexDirection: "column",
            justifyContent: "center",
            alignItems: "center",
            background: "radial-gradient(circle, rgba(0,0,0,0.7), transparent 70%)"
        });

        const text = document.createElement("div");
        text.textContent = isZH ? `目标达成! +${achievedLevel}` : `TARGET ACHIEVED! +${achievedLevel}`;
        Object.assign(text.style, {
            fontSize: "3rem",
            fontWeight: "900",
            color: "#FFD700",
            textShadow: "0 0 20px #FF0000, 0 0 30px #FF8C00",
            animation: "celebrateText 2s ease-out both"
        });
        celebration.appendChild(text);

        for (let i = 0; i < 100; i++) {
            const confetti = document.createElement("div");
            Object.assign(confetti.style, {
                position: "absolute",
                width: "10px",
                height: "10px",
                backgroundColor: getRandomColor(),
                borderRadius: "50%",
                left: "50%",
                top: "50%",
                opacity: "0",
                animation: `confettiFly ${Math.random() * 2 + 1}s ease-out ${Math.random() * 0.5}s both`
            });
            celebration.appendChild(confetti);
        }

        for (let i = 0; i < 8; i++) {
            setTimeout(() => {
                createFireworkBurst(celebration);
            }, i * 300);
        }

        document.body.appendChild(celebration);

        setTimeout(() => {
            celebration.style.opacity = "0";
            celebration.style.transition = "opacity 1s ease-out";
            setTimeout(() => celebration.remove(), 1000);
        }, 4000);
    }

    function createFireworkBurst(container) {
        const burst = document.createElement("div");
        Object.assign(burst.style, {
            position: "absolute",
            left: `${Math.random() * 80 + 10}%`,
            top: `${Math.random() * 80 + 10}%`,
            width: "5px",
            height: "5px",
            borderRadius: "50%",
            background: getRandomColor(),
            boxShadow: `0 0 10px 5px ${getRandomColor()}`,
            animation: `fireworkExpand 0.8s ease-out both`
        });
        container.appendChild(burst);

        for (let i = 0; i < 30; i++) {
            setTimeout(() => {
                const particle = document.createElement("div");
                Object.assign(particle.style, {
                    position: "absolute",
                    left: burst.style.left,
                    top: burst.style.top,
                    width: "3px",
                    height: "3px",
                    backgroundColor: burst.style.background,
                    borderRadius: "50%",
                    animation: `fireworkTrail ${Math.random() * 0.5 + 0.5}s ease-out both`
                });
                container.appendChild(particle);
            }, i * 20);
        }
    }

    function getRandomColor() {
        const colors = ["#FF0000", "#FF8C00", "#FFD700", "#4CAF50", "#2196F3", "#9C27B0"];
        return colors[Math.floor(Math.random() * colors.length)];
    }

    // ======================
    // DISPLAY SYSTEM
    // ======================

    function updateDisplay() {
        const targetElement = document.querySelector(".SkillActionDetail_enhancingComponent__17bOx");
        if (!targetElement) return;

        let parentContainer = document.querySelector("#enhancementParentContainer");
        if (!parentContainer) {
            parentContainer = createDisplayContainer(targetElement);
        }

        updateDropdown(parentContainer);
    }

    function createDisplayContainer(targetElement) {
        const parentContainer = document.createElement("div");
        parentContainer.id = "enhancementParentContainer";
        Object.assign(parentContainer.style, {
            display: "block",
            borderLeft: `2px solid ${STYLE.colors.border}`,
            padding: "0 4px"
        });

        const title = document.createElement("div");
        title.textContent = isZH ? "强化数据" : "Enhancement Data";
        Object.assign(title.style, {
            fontWeight: "bold",
            marginBottom: "10px",
            textAlign: "center",
            color: STYLE.colors.textSecondary,
            font: STYLE.fonts.header
        });
        parentContainer.appendChild(title);

        const dropdownContainer = document.createElement("div");
        dropdownContainer.style.marginBottom = "10px";
        const dropdown = document.createElement("select");
        dropdown.id = "enhancementDropdown";
        Object.assign(dropdown.style, {
            width: "100%",
            padding: "4px",
            borderRadius: STYLE.borderRadius.small,
            background: STYLE.colors.background,
            color: STYLE.colors.textPrimary,
            border: STYLE.colors.border
        });
        dropdown.addEventListener("change", function() {
            renderStats(this.value);
            updateDropdownColor();
        });
        dropdownContainer.appendChild(dropdown);
        parentContainer.appendChild(dropdownContainer);

        const statsContainer = document.createElement("div");
        statsContainer.id = "enhancementStatsContainer";
        Object.assign(statsContainer.style, {
            display: "grid",
            gridTemplateColumns: "repeat(4, 1fr)",
            gap: "10px",
            textAlign: "center",
            marginTop: "10px",
            font: STYLE.fonts.secondary
        });
        parentContainer.appendChild(statsContainer);

        targetElement.appendChild(parentContainer);
        return parentContainer;
    }

    function updateDropdown(parentContainer) {
        const dropdown = parentContainer.querySelector("#enhancementDropdown");
        const previousSelectedValue = dropdown.value;
        dropdown.innerHTML = "";

        Object.keys(enhancementData).forEach(key => {
            const item = enhancementData[key];
            if (!item["其他数据"]) return;

            const option = document.createElement("option");
            const itemName = item["其他数据"]["物品名称"] || "Unknown";
            const targetLevel = item["其他数据"]["目标强化等级"] || 0;
            const currentLevel = Math.max(...Object.keys(item["强化数据"] || {}).map(Number).filter(n => !isNaN(n))) || 0;
            const enhancementState = item["强化状态"] || "";

            option.text = isZH
                ? `${itemName} (目标: ${targetLevel}, 总计: ${item["强化次数"] || 0}${item["其他数据"]["保护消耗总数"] > 0 ? `, 垫子: ${item["其他数据"]["保护消耗总数"]}` : ""})`
                : `${itemName} (Target: ${targetLevel}, Total: ${item["强化次数"] || 0}${item["其他数据"]["保护消耗总数"] > 0 ? `, Protectors: ${item["其他数据"]["保护消耗总数"]}` : ""})`;

            option.value = key;
            option.style.color = enhancementState === "强化成功" ? STYLE.colors.success
                : (currentLevel < targetLevel && Object.keys(enhancementData).indexOf(key) === Object.keys(enhancementData).length - 1) ? STYLE.colors.accent
                : STYLE.colors.danger;

            dropdown.appendChild(option);
        });

        if (Object.keys(enhancementData).length > 0) {
            dropdown.value = previousSelectedValue || Object.keys(enhancementData)[0];
            updateDropdownColor();
            renderStats(dropdown.value);
        }
    }

    function updateDropdownColor() {
        const dropdown = document.querySelector("#enhancementDropdown");
        if (!dropdown) return;
        const selectedOption = dropdown.options[dropdown.selectedIndex];
        dropdown.style.color = selectedOption ? selectedOption.style.color : STYLE.colors.textPrimary;
    }

    function renderStats(selectedKey) {
        const statsContainer = document.querySelector("#enhancementStatsContainer");
        if (!statsContainer) return;
        statsContainer.innerHTML = "";

        const item = enhancementData[selectedKey];
        if (!item || !item["强化数据"]) return;

        const headers = ["等级", "成功", "失败", "概率"];
        headers.forEach(headerText => {
            const headerDiv = document.createElement("div");
            headerDiv.style.fontWeight = "bold";
            headerDiv.textContent = isZH ? headerText :
                headerText === "等级" ? "Level" :
                headerText === "成功" ? "Success" :
                headerText === "失败" ? "Failure" :
                "Success Rate";
            statsContainer.appendChild(headerDiv);
        });

        const totalSuccess = Object.values(item["强化数据"]).reduce((acc, val) => acc + (val["成功次数"] || 0), 0);
        const totalFailure = Object.values(item["强化数据"]).reduce((acc, val) => acc + (val["失败次数"] || 0), 0);
        const totalCount = totalSuccess + totalFailure;
        const totalRate = totalCount > 0 ? (totalSuccess / totalCount * 100).toFixed(2) : "0.00";

        ["总计", totalSuccess, totalFailure, `${totalRate}%`].forEach((totalText, index) => {
            const totalDiv = document.createElement("div");
            totalDiv.textContent = isZH ? totalText : index === 0 ? "Total" : totalText;
            statsContainer.appendChild(totalDiv);
        });

        Object.keys(item["强化数据"])
            .map(Number)
            .sort((a, b) => b - a)
            .forEach(level => {
                const levelData = item["强化数据"][level];
                const levelDivs = [
                    level,
                    levelData["成功次数"] || 0,
                    levelData["失败次数"] || 0,
                    `${((levelData["成功率"] || 0) * 100).toFixed(2)}%`
                ];

                levelDivs.forEach(data => {
                    const dataDiv = document.createElement("div");
                    dataDiv.textContent = data;
                    statsContainer.appendChild(dataDiv);
                });
            });
    }

    // ======================
    // FLOATING UI SYSTEM (F9 TOGGLE)
    // ======================

    let floatingUI = null;
    let cleanupFunctions = [];

    function createFloatingUI() {
        if (floatingUI && document.body.contains(floatingUI)) {
            return floatingUI;
        }

        // Create main container
        floatingUI = document.createElement("div");
        floatingUI.id = "enhancementFloatingUI";
        Object.assign(floatingUI.style, {
            position: "fixed",
            top: "50px",
            left: "50px",
            zIndex: "9998",
            fontSize: "14px",
            padding: "0",
            borderRadius: STYLE.borderRadius.medium,
            boxShadow: '0 8px 32px rgba(0, 0, 0, 0.6)',
            overflow: "hidden",
            width: "320px",
            minHeight: "auto", // Changed from fixed height
            background: 'rgba(25, 0, 35, 0.92)',
            backdropFilter: 'blur(12px)',
            border: `1px solid ${STYLE.colors.primary}`,
            color: STYLE.colors.textPrimary,
            willChange: "transform",
            transform: "translateZ(0)",
            backfaceVisibility: "hidden",
            perspective: "1000px",
            display: "flex", // Added flex layout
            flexDirection: "column" // Stack children vertically
        });

        // Create header
        const header = document.createElement("div");
        header.id = "enhancementPanelHeader";
        Object.assign(header.style, {
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            cursor: "move",
            padding: "10px 15px",
            background: STYLE.colors.headerBg,
            borderBottom: `1px solid ${STYLE.colors.border}`,
            userSelect: "none",
            WebkitUserSelect: "none",
            flexShrink: "0"
        });

        const title = document.createElement("span");
        title.textContent = isZH ? "强化追踪器" : "Enhancement Tracker";
        title.style.fontWeight = "bold";
        header.appendChild(title);

        // Drag functionality
        let isDragging = false;
        let offsetX, offsetY;
        let animationFrameId;

        header.addEventListener("mousedown", (e) => {
            isDragging = true;
            offsetX = e.clientX - floatingUI.offsetLeft;
            offsetY = e.clientY - floatingUI.offsetTop;
            floatingUI.classList.add("dragging");
            e.preventDefault();
        });

        const mouseMoveHandler = (e) => {
            if (!isDragging) return;
            cancelAnimationFrame(animationFrameId);
            animationFrameId = requestAnimationFrame(() => {
                floatingUI.style.left = `${e.clientX - offsetX}px`;
                floatingUI.style.top = `${e.clientY - offsetY}px`;
            });
        };

        const mouseUpHandler = () => {
            if (!isDragging) return;
            isDragging = false;
            floatingUI.classList.remove("dragging");
            cancelAnimationFrame(animationFrameId);
        };

        document.addEventListener("mousemove", mouseMoveHandler, { passive: true });
        document.addEventListener("mouseup", mouseUpHandler, { passive: true });

        cleanupFunctions.push(() => {
            document.removeEventListener("mousemove", mouseMoveHandler);
            document.removeEventListener("mouseup", mouseUpHandler);
        });

        floatingUI.appendChild(header);

        // Create content area
        const content = document.createElement("div");
        content.id = "enhancementPanelContent";
        Object.assign(content.style, {
            padding: "8px",
            overflowY: "hidden",
            flexGrow: "1",
            minHeight: "0", // Important for flex filling
            contain: "strict",
            boxSizing: "border-box",
            display: "flex",
            flexDirection: "column"
        });

        // Add resize observer for dynamic content
        const resizeObserver = new ResizeObserver(() => {
            // Ensure UI grows with content but stays within max height
            const headerHeight = header.offsetHeight;
            const contentHeight = content.scrollHeight;
            floatingUI.style.height = `min(${headerHeight + contentHeight}px, 80vh)`;
        });
        resizeObserver.observe(content);

        cleanupFunctions.push(() => resizeObserver.disconnect());
        floatingUI.appendChild(content);


        document.body.appendChild(floatingUI);
        return floatingUI;
    }

    function refreshFloatingUIHeight() {
        const header = document.getElementById("enhancementPanelHeader");
        const content = document.getElementById("enhancementPanelContent");
        if (!header || !content || !floatingUI) return;

        const headerHeight = header.offsetHeight;
        const contentHeight = content.scrollHeight;

        floatingUI.style.height = `min(${headerHeight + contentHeight}px, 80vh)`;
    }

    function updateFloatingUI() {
        const floatingUI = document.getElementById("enhancementFloatingUI") || createFloatingUI();
        const content = document.getElementById("enhancementPanelContent");

        if (currentEnhancingIndex === -1 || !enhancementData[currentEnhancingIndex]) {
            content.innerHTML = isZH ? "没有活跃的强化数据" : "No active enhancement data";
            return;
        }

        const session = enhancementData[currentEnhancingIndex];
        const totalAttempts = session["强化次数"];
        const totalSuccess = Object.values(session["强化数据"]).reduce((sum, level) => sum + (level["成功次数"] || 0), 0);
        const totalFailure = Object.values(session["强化数据"]).reduce((sum, level) => sum + (level["失败次数"] || 0), 0);
        const totalRate = totalAttempts > 0 ? (totalSuccess / totalAttempts * 100).toFixed(2) : 0;

        /* Additional Table Styling */
        const compactTableStyle = `
            width: 100%;
            border-collapse: separate;
            border-spacing: 0;
            font-size: 13px;
            margin: 5px 0;
            background: rgba(30, 0, 40, 0.6);
            border-radius: ${STYLE.borderRadius.small};
            overflow: hidden;
        `;

        const compactCellStyle = `
            padding: 4px 8px;
            line-height: 1.3;
            border-bottom: 1px solid rgba(126, 87, 194, 0.2);
        `;

        const compactHeaderStyle = `
            ${compactCellStyle}
            font-weight: bold;
            text-align: center;
            background: ${STYLE.colors.headerBg};
            color: ${STYLE.colors.textPrimary};
            border-bottom: 2px solid ${STYLE.colors.primary};
        `;

        // Generate compact HTML content
        content.innerHTML = `
        <div style="margin-bottom: 5px; font-size: 13px;">
            <div style="display: flex; justify-content: space-between;">
                <span>${isZH ? "物品" : "Item"}:</span>
                <strong>${session["其他数据"]["物品名称"]}</strong>
            </div>
            <div style="display: flex; justify-content: space-between;">
                <span>${isZH ? "目标" : "Target"}:</span>
                <span>+${session["其他数据"]["目标强化等级"]}</span>
            </div>
        </div>

        <table style="${compactTableStyle}">
            <thead>
                <tr>
                    <th style="${compactHeaderStyle}">${isZH ? "等级" : "Lvl"}</th>
                    <th style="${compactHeaderStyle}">${isZH ? "成功" : "Success"}</th>
                    <th style="${compactHeaderStyle}">${isZH ? "失败" : "Fail"}</th>
                    <th style="${compactHeaderStyle}">%</th>
                </tr>
            </thead>
            <tbody>
                ${Object.keys(session["强化数据"])
                    .sort((a, b) => b - a)
                    .map(level => {
                        const levelData = session["强化数据"][level];
                        const rate = ((levelData["成功率"] || 0) * 100).toFixed(1);
                        const isCurrent = level == enhancementLevel;
                        return `
                        <tr ${isCurrent ? `
                            style="
                                background: linear-gradient(90deg, rgba(126, 87, 194, 0.25), rgba(0, 242, 255, 0.1));
                                box-shadow: 0 0 12px rgba(126, 87, 194, 0.5), inset 0 0 6px rgba(0, 242, 255, 0.3);
                                border-left: 3px solid ${STYLE.colors.accent};
                                font-weight: bold;
                            "` : ''}>
                            <td style="${compactCellStyle} text-align: center;">${level}</td>
                            <td style="${compactCellStyle} text-align: right;">${levelData["成功次数"] || 0}</td>
                            <td style="${compactCellStyle} text-align: right;">${levelData["失败次数"] || 0}</td>
                            <td style="${compactCellStyle} text-align: right;">${rate}%</td>
                        </tr>`;
                    }).join('')}
            </tbody>
        </table>

        <table style="${compactTableStyle} margin-top: 5px;">
            <tr>
                <td style="${compactCellStyle}">${isZH ? "总计尝试" : "Total"}:</td>
                <td style="${compactCellStyle} text-align: right;">${totalAttempts}</td>
                <td style="${compactCellStyle} text-align: right;">${totalRate}%</td>
            </tr>
            ${session["其他数据"]["保护消耗总数"] > 0 ? `
            <tr>
                <td style="${compactCellStyle}">${isZH ? "保护" : "Protect"}:</td>
                <td colspan="2" style="${compactCellStyle} text-align: right;">${session["其他数据"]["保护消耗总数"]}</td>
            </tr>` : ''}
        </table>`;

        // Force content to fill container
        content.style.minHeight = "0";
        content.style.height = "auto";
        refreshFloatingUIHeight();
    }


    function toggleFloatingUI() {
        if (!floatingUI || !document.body.contains(floatingUI)) {
            createFloatingUI();
            updateFloatingUI();
            floatingUI.style.display = "block";
            showUINotification(
                isZH ? "强化追踪器已启用" : "Enhancement Tracker Enabled"
            );
        } else {
            const willShow = floatingUI.style.display === "none";
            floatingUI.style.display = willShow ? "flex" : "none";
            showUINotification(
                isZH ? `强化追踪器${willShow ? "已显示" : "已隐藏"}` :
                      `Enhancement Tracker ${willShow ? "Shown" : "Hidden"}`
            );
        }
        localStorage.setItem("enhancementUIVisible", floatingUI.style.display !== "none");
    }

function cleanupFloatingUI() {
    if (floatingUI && document.body.contains(floatingUI)) {
        floatingUI.remove();
    }
    cleanupFunctions.forEach(fn => fn());
    cleanupFunctions = [];
    floatingUI = null;
}

// ======================
// UI NOTIFICATION SYSTEM
// ======================

function showUINotification(message, duration = 2000) {
    const notification = document.createElement("div");
    Object.assign(notification.style, {
        position: "fixed",
        bottom: "20px",
        left: "50%",
        transform: "translateX(-50%)",
        padding: '8px 12px',
        borderRadius: "4px",
        backdropFilter: 'blur(4px)',
        border: `1px solid ${STYLE.colors.primary}`,
        background: 'rgba(40, 0, 60, 0.9)',
        backgroundColor: "rgba(0, 0, 0, 0.8)",
        color: "white",
        zIndex: "10000",
        fontSize: "14px",
        animation: "fadeInOut 2s ease-in-out",
        pointerEvents: "none"
    });
    notification.textContent = message;
    document.body.appendChild(notification);

    setTimeout(() => {
        notification.style.opacity = "0";
        setTimeout(() => notification.remove(), 300);
    }, duration);
}

// ======================
// KEYBOARD SHORTCUT
// ======================

function setupKeyboardShortcut() {
    document.addEventListener("keydown", (e) => {
        if (e.key === "F9") {
            e.preventDefault();
            toggleFloatingUI();
        }
    });
}

    // ======================
    // TESTING SYSTEM
    // ======================

    function initializeTesting() {
        if (typeof GM_registerMenuCommand !== 'undefined') {
            GM_registerMenuCommand("🔧 Test Success Notifications", () => testNotifications("success"));
            GM_registerMenuCommand("🔧 Test Failure Notifications", () => testNotifications("failure"));
            GM_registerMenuCommand("✨ Test Blessed Success", () => testNotifications("blessed"));
            GM_registerMenuCommand("🌀 Test All Notifications", () => testNotifications("all"));
        }

        window.testEnhancement = {
            success: () => testNotifications("success"),
            allSuccess: () => testNotifications("allSuccess"),
            failure: () => testNotifications("failure"),
            blessed: () => testNotifications("blessed"),
            all: () => testNotifications("all"),
            custom: (level, type, targetLevel) => {
                const isBlessed = type === "blessed";
                const isSuccess = type !== "failure";
                showNotification(
                    isBlessed ? "BLESSED!" : isSuccess ? "Success" : "Failed!",
                    isSuccess ? "success" : "failure",
                    level,
                    isBlessed
                );

                if (level >= targetLevel){
                  showTargetAchievedCelebration(level, targetLevel);
                }
            }
        };
    }

    function testNotifications(type) {
        const tests = {
            success: [
                { level: 1, blessed: false },
                { level: 5, blessed: false },
                { level: 10, blessed: false },
                { level: 15, blessed: false },
                { level: 20, blessed: false }
            ],
            allSuccess: [
                { level: 1, blessed: false },
                { level: 2, blessed: false },
                { level: 3, blessed: false },
                { level: 4, blessed: false },
                { level: 5, blessed: false },
                { level: 6, blessed: false },
                { level: 7, blessed: false },
                { level: 8, blessed: false },
                { level: 9, blessed: false },
                { level: 10, blessed: false },
                { level: 11, blessed: false },
                { level: 12, blessed: false },
                { level: 13, blessed: false },
                { level: 14, blessed: false },
                { level: 15, blessed: false },
                { level: 16, blessed: false },
                { level: 17, blessed: false },
                { level: 18, blessed: false },
                { level: 19, blessed: false },
                { level: 20, blessed: false }
            ],
            blessed: [
                { level: 3, blessed: true },
                { level: 8, blessed: true },
                { level: 12, blessed: true },
                { level: 17, blessed: true },
                { level: 22, blessed: true }
            ],
            failure: [
                { level: 0, blessed: false }
            ],
            all: [
                { level: 1, blessed: false },
                { level: 0, blessed: false },
                { level: 3, blessed: true },
                { level: 0, blessed: false },
                { level: 10, blessed: false },
                { level: 12, blessed: true },
                { level: 15, blessed: false },
                { level: 0, blessed: false },
                { level: 20, blessed: false }
            ]
        };

        tests[type].forEach((test, i) => {
            setTimeout(() => {
                const message = test.blessed ?
                    (isZH ? `祝福强化! +${test.level}` : `BLESSED! +${test.level}`) :
                    (test.level > 0 ?
                        (isZH ? `强化成功 +${test.level}` : `Success +${test.level}`) :
                        (isZH ? "强化失败!" : "Failed!"));

                showNotification(
                    message,
                    test.level > 0 ? "success" : "failure",
                    test.level,
                    test.blessed
                );
            }, i * 800);
        });
    }

    // ======================
    // INITIALIZATION
    // ======================

    function addGlobalStyles() {
        const style = document.createElement("style");
        style.textContent = `
            @keyframes pulse {
                0% { transform: scale(1); }
                50% { transform: scale(1.05); }
                100% { transform: scale(1); }
            }
            @keyframes holyGlow {
                0% { box-shadow: 0 0 10px #FFD700; }
                50% { box-shadow: 0 0 25px #FFD700, 0 0 40px white; }
                100% { box-shadow: 0 0 10px #FFD700; }
            }
            @keyframes raysRotate {
                from { transform: rotate(0deg); }
                to { transform: rotate(360deg); }
            }
            @keyframes floatUp {
                0% { transform: translateY(0) rotate(0deg); opacity: 0; }
                10% { opacity: 0.7; }
                90% { opacity: 0.7; }
                100% { transform: translateY(-100px) rotate(20deg); opacity: 0; }
            }
            @keyframes celebrateText {
                0% { transform: scale(0.5); opacity: 0; }
                50% { transform: scale(1.2); opacity: 1; }
                100% { transform: scale(1); }
            }
            @keyframes confettiFly {
                0% { transform: translate(0,0) rotate(0deg); opacity: 1; }
                100% { transform: translate(${Math.random() > 0.5 ? '-' : ''}${Math.random() * 300 + 100}px, ${Math.random() * 300 + 100}px) rotate(360deg); opacity: 0; }
            }
            @keyframes fireworkExpand {
                0% { transform: scale(0); opacity: 1; }
                100% { transform: scale(20); opacity: 0; }
            }
            @keyframes fireworkTrail {
                0% { transform: translate(0,0); opacity: 1; }
                100% { transform: translate(${Math.random() > 0.5 ? '-' : ''}${Math.random() * 100 + 50}px, ${Math.random() * 100 + 50}px); opacity: 0; }
            }
            .enhancement-notification {
                position: relative;
                overflow: hidden;
                transition: ${STYLE.transitions.medium};
                backdrop-filter: blur(4px);
                -webkit-backdrop-filter: blur(4px);
                background: 'rgba(255, 255, 255, 0.1)',
                border: '1px solid rgba(255, 255, 255, 0.2)',
            }
            #enhancementFloatingUI {
              transition: opacity 0.2s ease, transform 0.2s ease, height 0.2s ease;
              height: auto;
              backdrop-filter: blur(8px);
              -webkit-backdrop-filter: blur(8px);
              background: 'rgba(255, 255, 255, 0.1)',
              border: '1px solid rgba(255, 255, 255, 0.2)',
            }
            #enhancementPanelContent {
                scrollbar-width: thin;
                scrollbar-color: ${STYLE.colors.border} transparent;
            }
            #enhancementPanelContent::-webkit-scrollbar {
                width: 6px;
            }

            #enhancementPanelContent::-webkit-scrollbar-thumb {
                background: ${STYLE.colors.primary};
                border-radius: 3px;
            }

            #enhancementPanelContent::-webkit-scrollbar-track {
                background: rgba(30, 0, 40, 0.4);
            }
            #enhancementFloatingUI[style*="display: none"] {
                display: block !important;
                opacity: 0;
                pointer-events: none;
                transform: translateY(10px);
            }
            #enhancementFloatingUI.dragging {
                cursor: grabbing;
                box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
                transition: none;
            }
            @keyframes floatIn {
                0% { opacity: 0; transform: translateY(10px); }
                100% { opacity: 1; transform: translateY(0); }
            }
            #enhancementFloatingUI:not([style*="display: none"]) {
                animation: floatIn 0.2s ease-out;
            }
            @keyframes fadeInOut {
                0% { opacity: 0; transform: translateX(-50%) translateY(10px); }
                20% { opacity: 1; transform: translateX(-50%) translateY(0); }
                80% { opacity: 1; transform: translateX(-50%) translateY(0); }
                100% { opacity: 0; transform: translateX(-50%) translateY(-10px); }
            }
            @keyframes mythicPulse {
                0% {
                    background-position: 0% 50%;
                    transform: scale(1);
                    box-shadow: 0 0 8px #ff0033;
                }
                50% {
                    background-position: 100% 50%;
                    transform: scale(1.05);
                    box-shadow: 0 0 16px #ff2200, 0 0 24px #ff2200;
                }
                100% {
                    background-position: 0% 50%;
                    transform: scale(1);
                    box-shadow: 0 0 8px #ff0033;
                }
            }
        `;
        document.head.appendChild(style);
    }

    function initializeFloatingUI() {
        const checkReady = setInterval(() => {
            if (document.body && typeof item_hrid_to_name !== "undefined") {
                clearInterval(checkReady);
                setupKeyboardShortcut();

                if (localStorage.getItem("enhancementUIVisible") !== "false") {
                    createFloatingUI();
                    updateFloatingUI();
                }
            }
        }, 500);
    }

    // Start everything
    addGlobalStyles();
    initializeTesting();
    initializeFloatingUI();
    hookWS();


    console.log("Enhancement Notifier v2.6 loaded - Optimized Floating UI");
})();