// ==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
// @downloadURL https://update.greasyfork.icu/scripts/531682/%5B%E9%93%B6%E6%B2%B3%E5%A5%B6%E7%89%9B%5D%E4%BB%93%E5%BA%93%E7%89%A9%E5%93%81%E6%94%B6%E8%97%8F%E5%92%8C%E5%BF%AB%E9%80%9F%E5%88%87%E6%8D%A2%E8%A7%92%E8%89%B2.user.js
// @updateURL https://update.greasyfork.icu/scripts/531682/%5B%E9%93%B6%E6%B2%B3%E5%A5%B6%E7%89%9B%5D%E4%BB%93%E5%BA%93%E7%89%A9%E5%93%81%E6%94%B6%E8%97%8F%E5%92%8C%E5%BF%AB%E9%80%9F%E5%88%87%E6%8D%A2%E8%A7%92%E8%89%B2.meta.js
// ==/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 = `
`;
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);
})();