Greasy Fork

Greasy Fork is available in English.

[银河奶牛]仓库物品收藏和快速切换角色

仓库物品收藏管理和快速切换角色||Added a favorite button to the item menu and 4 characters buttons to the main page.

// ==UserScript==
// @name         [银河奶牛]仓库物品收藏和快速切换角色
// @name:en      MWI Item Favorites Manager && Quickly Switch Characters
// @namespace    http://tampermonkey.net/
// @version      test0.22
// @description  仓库物品收藏管理和快速切换角色||Added a favorite button to the item menu and 4 characters buttons to the main page.
// @description:en  Added a favorite button to the item menu and 4 characters buttons to the main page.
// @icon         https://www.milkywayidle.com/favicon.svg
// @author       Meoling
// @license      MIT
// @match        https://www.milkywayidle.com/*
// @match        https://test.milkywayidle.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==


(function() {
    'use strict';

    // 获取当前角色名
    function getCharacterName() {
        const headerInfo = document.querySelector('.Header_info__26fkk');
        if (!headerInfo) return null;
        const nameElement = headerInfo.querySelector('.CharacterName_name__1amXp');
        return nameElement ? nameElement.textContent.trim() : null;
    }

    // 保存收藏物品到本地存储
    function saveFavoritesToLocalStorage(itemName, categoryName) {
        const characterName = getCharacterName();
        if (!characterName) return;
        const storageKey = `mw_favorites_${characterName}`;
        const favorites = loadFavoritesFromLocalStorage();

        // 检查是否已存在相同物品
        const existingIndex = favorites.findIndex(item => item.name === itemName);
        if (existingIndex === -1) {
            favorites.push({name: itemName, category: categoryName});
            localStorage.setItem(storageKey, JSON.stringify(favorites));
        }
    }

    // 从本地存储加载收藏物品
    function loadFavoritesFromLocalStorage() {
        const characterName = getCharacterName();
        if (!characterName) return [];
        const storageKey = `mw_favorites_${characterName}`;
        return JSON.parse(localStorage.getItem(storageKey)) || [];
    }

    // 创建仓库收藏分类
    function addFavoritesCategory() {
        // 查找仓库的所有分类容器
        const firstContainer = document.querySelector('.Inventory_items__6SXv0');
        const inventoryContainers = firstContainer.querySelectorAll(':scope > div');
        if (inventoryContainers && inventoryContainers.length > 0) {
            const existingFavorites = firstContainer.querySelector('#favorites-category');
            if (existingFavorites) {
                return;
            }

            // 创建新的收藏分类
            const favoritesContainer = document.createElement('div');

            // 复制现有分类的结构
            const itemGridHTML = `
                <div class="Inventory_itemGrid__20YAH">
                    <div class="Inventory_label__XEOAx">
                        <span class="Inventory_categoryButton__35s1x">收藏</span>
                    </div>
                    <!-- 这里将来会添加收藏的物品 -->
                </div>
            `;
            favoritesContainer.innerHTML = itemGridHTML;
            favoritesContainer.id = 'favorites-category';

            // 将收藏分类添加到仓库的最前面
            if (firstContainer) {
                firstContainer.insertBefore(favoritesContainer, firstContainer.firstChild);
                //console.log('收藏分类已添加');
            }
        }
    }

    // 添加仓库收藏按钮
    function addFavoriteButton(menuContainer) {
        // 检查是否已存在收藏按钮
        const existingButton = menuContainer.querySelector('.favorite-button');
        if (existingButton) {
            return;
        }
        const favoriteButton = document.createElement('button');
        favoriteButton.className = 'Button_button__1Fe9z Button_fullWidth__17pVU favorite-button';
        favoriteButton.textContent = '收藏/取消收藏';

        // 添加点击事件
        favoriteButton.addEventListener('click', function() {
            // 获取当前物品名称
            const itemName = menuContainer.querySelector('.Item_name__2C42x').textContent.trim();
            const characterName = getCharacterName();
            if (!characterName) return;
            const favorites = loadFavoritesFromLocalStorage();
            const itemIndex = favorites.findIndex(item => item.name === itemName);
            const isFavorite = itemIndex !== -1;

            if (isFavorite) {
                const itemCategory = favorites[itemIndex].category;
                favorites.splice(itemIndex, 1);
                localStorage.setItem(`mw_favorites_${characterName}`, JSON.stringify(favorites));
                const favoritesGrid = document.querySelector('#favorites-category .Inventory_itemGrid__20YAH');
                const existingItem = favoritesGrid.querySelector(`svg[aria-label="${itemName}"]`);
                if (existingItem) {
                    const inventoryItem = document.querySelector(`.Inventory_items__6SXv0 .Item_itemContainer__x7kH1 svg[aria-label="${itemName}"]`);
                    if (!inventoryItem) {
                        console.log('未在仓库中找到该物品');
                        return;
                    }
                    const itemContainer = inventoryItem.closest('.Item_itemContainer__x7kH1');
                    if (!itemContainer) {
                        console.log('无法获取物品容器');
                        return;
                    }

                    const categorySpan = [...document.querySelectorAll('.Inventory_categoryButton__35s1x')]
                        .find(span => span.textContent.trim() === itemCategory);
                    if (categorySpan) {
                        const categoryGrid = categorySpan.closest('.Inventory_itemGrid__20YAH');
                        if (categoryGrid) {
                            categoryGrid.appendChild(itemContainer);
                        }
                    }
                    refresh();
                    //existingItem.closest('.Item_itemContainer__x7kH1').remove();
                }
            } else {
                const inventoryItem = document.querySelector(`.Inventory_items__6SXv0 .Item_itemContainer__x7kH1 svg[aria-label="${itemName}"]`);
                if (!inventoryItem) {
                    console.log('未在仓库中找到该物品');
                    return;
                }
                const itemContainer = inventoryItem.closest('.Item_itemContainer__x7kH1');
                if (!itemContainer) {
                    console.log('无法获取物品容器');
                    return;
                }
                const categoryGrid = itemContainer.closest('.Inventory_itemGrid__20YAH');
                const categoryName = categoryGrid ?
                    categoryGrid.querySelector('.Inventory_categoryButton__35s1x')?.textContent.trim() :
                    '未知分类';
                saveFavoritesToLocalStorage(itemName, categoryName);
                const favoritesGrid = document.querySelector('#favorites-category .Inventory_itemGrid__20YAH');
                if (!favoritesGrid) {
                    console.log('未找到收藏分类');
                    return;
                }
                const existingItem = favoritesGrid.querySelector(`svg[aria-label="${itemName}"]`);
                if (!existingItem) {
                    favoritesGrid.appendChild(itemContainer);
                }
            }
        });
        menuContainer.appendChild(favoriteButton);
    }

    // 添加市场的分类容器(未完成)
    function addMarketFavoritesCategory() {

    }

    // 刷新函数,当DOM变化时调用
    function refresh() {
        const inventoryContainer = document.querySelector('.Inventory_items__6SXv0');
        if (inventoryContainer) {
            addFavoritesCategory();
            const favorites = loadFavoritesFromLocalStorage();
            const favoritesGrid = document.querySelector('#favorites-category .Inventory_itemGrid__20YAH');
            if (favoritesGrid) {
                favorites.forEach(item => {
                    const inventoryItem = document.querySelector(`.Inventory_items__6SXv0 .Item_itemContainer__x7kH1 svg[aria-label="${item.name}"]`);
                    if (inventoryItem) {
                        const itemContainer = inventoryItem.closest('.Item_itemContainer__x7kH1');
                        const existingItem = favoritesGrid.querySelector(`svg[aria-label="${item.name}"]`);
                        if (!existingItem && itemContainer) {
                            favoritesGrid.appendChild(itemContainer);
                        }
                    }
                });
            }
        }

        // 检查是否出现物品菜单
        const itemMenu = document.querySelector('.Item_actionMenu__2yUcG');
        if (itemMenu) {
            addFavoriteButton(itemMenu);
        }


        //市场物品的收藏(未完成)
        const marketContainer = document.querySelector('.MarketplacePanel_itemSelectionTabsContainer__kd2R2');
        if (marketContainer) {
        addMarketFavoritesCategory();
        }
    }

    // 设置MutationObserver监听DOM变化
    const config = { attributes: true, childList: true, subtree: true };

    const observer = new MutationObserver(function (mutationsList, observer) {
        refresh();
    });
    observer.observe(document, config);



    //快速切换角色
    // 按钮文本数组(可自定义每个按钮的文字)
    const buttonTexts = ['标准', '铁牛1', '铁牛2', '铁牛3'];
    // 按钮链接数组(为每个按钮设置不同的链接)
    const buttonLinks = [
        'https://www.milkywayidle.com/game?characterId=XXXXXX',
        'https://www.milkywayidle.com/game?characterId=XXXXXX',
        'https://www.milkywayidle.com/game?characterId=XXXXXX',
        'https://www.milkywayidle.com/game?characterId=XXXXXX'
    ];

    // 创建四个按钮,设置按钮样式
    const buttonContainer = document.createElement('div');
    buttonContainer.style.position = 'fixed';
    buttonContainer.style.top = '10px';
    buttonContainer.style.left = '73%';
    buttonContainer.style.transform = 'translateX(-50%)';
    buttonContainer.style.zIndex = '9999';
    buttonContainer.style.display = 'flex';
    buttonContainer.style.gap = '10px';
    for (let i = 0; i < 4; i++) {
        const button = document.createElement('a');
        button.textContent = buttonTexts[i];
        button.href = buttonLinks[i];
        button.style.padding = '4px 8px';
        button.style.backgroundColor = 'rgba(48, 63, 159, 0.3)';
        button.style.color = 'rgba(255, 255, 255, 0.9)';
        button.style.border = '1px solid rgba(255, 255, 255, 0.2)';
        button.style.borderRadius = '3px';
        button.style.fontSize = '12px';
        button.style.backdropFilter = 'blur(2px)';
        button.style.boxShadow = '0 1px 3px rgba(0,0,0,0.1)';
        button.style.textDecoration = 'none';
        button.style.cursor = 'pointer';
        button.style.whiteSpace = 'nowrap';
        button.addEventListener('mouseover', function() {
        this.style.backgroundColor = 'rgba(26, 35, 126, 0.5)';
        this.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)';
        });
        button.addEventListener('mouseout', function() {
        this.style.backgroundColor = 'rgba(48, 63, 159, 0.3)';
        this.style.boxShadow = '0 1px 3px rgba(0,0,0,0.1)';
        });
        buttonContainer.appendChild(button);
    }
    document.body.appendChild(buttonContainer);

})();