// ==UserScript==
// @name [银河奶牛]食用工具
// @namespace http://tampermonkey.net/
// @version 0.459
// @description 开箱记录、箱子期望、离线统计、公会钉钉、食物警察、掉落追踪、强化统计
// @author Truth_Light
// @license Truth_Light
// @match https://www.milkywayidle.com/*
// @match https://test.milkywayidle.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=milkywayidle.com
// @grant GM.xmlHttpRequest
// @grant GM_registerMenuCommand
// @grant GM_openInTab
// @grant GM_setValue
// @grant GM_getValue
// @downloadURL none
// ==/UserScript==
(async function() {
'use strict';
const isCN = !['en'].some(lang =>localStorage.getItem("i18nextLng")?.toLowerCase()?.startsWith(lang));
const itemSelector = '.ItemDictionary_drop__24I5f';
const iconSelector = '.Icon_icon__2LtL_ use';
const chestNameSelector = '#root > div > div > div.Modal_modalContainer__3B80m > div.Modal_modal__1Jiep > div.ItemDictionary_modalContent__WvEBY > div.ItemDictionary_itemAndDescription__28_he > div.Item_itemContainer__x7kH1 > div > div > div > svg > use';
const MARKET_API_URL = "https://raw.githubusercontent.com/holychikenz/MWIApi/main/medianmarket.json";
let timer = null;
let formattedChestDropData = {};
let battlePlayerFood = {};
let battlePlayerLoot = {};
let battlePlayerData = {};
let battleDuration;
let battleRunCount;
let now_battle_map;
let enhancementLevel;
let currentEnhancingIndex = 1;
let enhancementData = {
[currentEnhancingIndex]: { "强化数据": {}, "其他数据": {} }
};
let item_icon_url
let marketData = JSON.parse(localStorage.getItem('MWITools_marketAPI_json'));
const init_Client_Data = localStorage.getItem('initClientData');
if (!init_Client_Data) return;
let init_Client_Data_;
try {
init_Client_Data_ = JSON.parse(init_Client_Data);
} catch (error) {
console.error('数据解析失败:', error);
return;
}
if (init_Client_Data_.type !== 'init_client_data') return;
const item_hrid_to_name = init_Client_Data_.itemDetailMap;
for (const key in item_hrid_to_name) {
if (item_hrid_to_name[key] && typeof item_hrid_to_name[key] === 'object' && item_hrid_to_name[key].name) {
item_hrid_to_name[key] = item_hrid_to_name[key].name;
}
}
const item_name_to_hrid = Object.fromEntries(
Object.entries(item_hrid_to_name).map(([key, value]) => [value, key])
);
const e2c = {"Coin":"金币","Task Token":"任务代币","Chimerical Token":"奇幻代币","Sinister Token":"阴森代币","Enchanted Token":"秘法代币","Cowbell":"牛铃","Bag Of 10 Cowbells":"牛铃袋 (10个)","Purple's Gift":"小紫牛的礼物","Small Meteorite Cache":"小陨石舱","Medium Meteorite Cache":"中陨石舱","Large Meteorite Cache":"大陨石舱","Small Artisan's Crate":"小工匠匣","Medium Artisan's Crate":"中工匠匣","Large Artisan's Crate":"大工匠匣","Small Treasure Chest":"小宝箱","Medium Treasure Chest":"中宝箱","Large Treasure Chest":"大宝箱","Chimerical Chest":"奇幻宝箱","Sinister Chest":"阴森宝箱","Enchanted Chest":"秘法宝箱","Blue Key Fragment":"蓝色钥匙碎片","Green Key Fragment":"绿色钥匙碎片","Purple Key Fragment":"紫色钥匙碎片","White Key Fragment":"白色钥匙碎片","Orange Key Fragment":"橙色钥匙碎片","Brown Key Fragment":"棕色钥匙碎片","Stone Key Fragment":"石头钥匙碎片","Dark Key Fragment":"黑暗钥匙碎片","Burning Key Fragment":"燃烧钥匙碎片","Chimerical Entry Key":"奇幻钥匙","Chimerical Chest Key":"奇幻宝箱钥匙","Sinister Entry Key":"阴森钥匙","Sinister Chest Key":"阴森宝箱钥匙","Enchanted Entry Key":"秘法钥匙","Enchanted Chest Key":"秘法宝箱钥匙","Donut":"甜甜圈","Blueberry Donut":"蓝莓甜甜圈","Blackberry Donut":"黑莓甜甜圈","Strawberry Donut":"草莓甜甜圈","Mooberry Donut":"哞莓甜甜圈","Marsberry Donut":"火星莓甜甜圈","Spaceberry Donut":"太空莓甜甜圈","Cupcake":"纸杯蛋糕","Blueberry Cake":"蓝莓蛋糕","Blackberry Cake":"黑莓蛋糕","Strawberry Cake":"草莓蛋糕","Mooberry Cake":"哞莓蛋糕","Marsberry Cake":"火星莓蛋糕","Spaceberry Cake":"太空莓蛋糕","Gummy":"软糖","Apple Gummy":"苹果软糖","Orange Gummy":"橙子软糖","Plum Gummy":"李子软糖","Peach Gummy":"桃子软糖","Dragon Fruit Gummy":"火龙果软糖","Star Fruit Gummy":"杨桃软糖","Yogurt":"酸奶","Apple Yogurt":"苹果酸奶","Orange Yogurt":"橙子酸奶","Plum Yogurt":"李子酸奶","Peach Yogurt":"桃子酸奶","Dragon Fruit Yogurt":"火龙果酸奶","Star Fruit Yogurt":"杨桃酸奶","Milking Tea":"挤奶茶","Foraging Tea":"采摘茶","Woodcutting Tea":"伐木茶","Cooking Tea":"烹饪茶","Brewing Tea":"冲泡茶","Alchemy Tea":"炼金茶","Enhancing Tea":"强化茶","Cheesesmithing Tea":"奶酪锻造茶","Crafting Tea":"制作茶","Tailoring Tea":"缝纫茶","Super Milking Tea":"超级挤奶茶","Super Foraging Tea":"超级采摘茶","Super Woodcutting Tea":"超级伐木茶","Super Cooking Tea":"超级烹饪茶","Super Brewing Tea":"超级冲泡茶","Super Alchemy Tea":"超级炼金茶","Super Enhancing Tea":"超级强化茶","Super Cheesesmithing Tea":"超级奶酪锻造茶","Super Crafting Tea":"超级制作茶","Super Tailoring Tea":"超级缝纫茶","Ultra Milking Tea":"究极挤奶茶","Ultra Foraging Tea":"究极采摘茶","Ultra Woodcutting Tea":"究极伐木茶","Ultra Cooking Tea":"究极烹饪茶","Ultra Brewing Tea":"究极冲泡茶","Ultra Alchemy Tea":"究极炼金茶","Ultra Enhancing Tea":"究极强化茶","Ultra Cheesesmithing Tea":"究极奶酪锻造茶","Ultra Crafting Tea":"究极制作茶","Ultra Tailoring Tea":"究极缝纫茶","Gathering Tea":"采集茶","Gourmet Tea":"美食茶","Wisdom Tea":"经验茶","Processing Tea":"加工茶","Efficiency Tea":"效率茶","Artisan Tea":"工匠茶","Catalytic Tea":"催化茶","Blessed Tea":"福气茶","Stamina Coffee":"耐力咖啡","Intelligence Coffee":"智力咖啡","Defense Coffee":"防御咖啡","Attack Coffee":"攻击咖啡","Power Coffee":"力量咖啡","Ranged Coffee":"远程咖啡","Magic Coffee":"魔法咖啡","Super Stamina Coffee":"超级耐力咖啡","Super Intelligence Coffee":"超级智力咖啡","Super Defense Coffee":"超级防御咖啡","Super Attack Coffee":"超级攻击咖啡","Super Power Coffee":"超级力量咖啡","Super Ranged Coffee":"超级远程咖啡","Super Magic Coffee":"超级魔法咖啡","Ultra Stamina Coffee":"究极耐力咖啡","Ultra Intelligence Coffee":"究极智力咖啡","Ultra Defense Coffee":"究极防御咖啡","Ultra Attack Coffee":"究极攻击咖啡","Ultra Power Coffee":"究极力量咖啡","Ultra Ranged Coffee":"究极远程咖啡","Ultra Magic Coffee":"究极魔法咖啡","Wisdom Coffee":"经验咖啡","Lucky Coffee":"幸运咖啡","Swiftness Coffee":"迅捷咖啡","Channeling Coffee":"吟唱咖啡","Critical Coffee":"暴击咖啡","Poke":"破胆之刺","Impale":"透骨之刺","Puncture":"破甲之刺","Penetrating Strike":"贯心之刺","Scratch":"爪影斩","Cleave":"分裂斩","Maim":"血刃斩","Crippling Slash":"致残斩","Smack":"重碾","Sweep":"重扫","Stunning Blow":"重锤","Quick Shot":"快速射击","Aqua Arrow":"流水箭","Flame Arrow":"烈焰箭","Rain Of Arrows":"箭雨","Silencing Shot":"沉默之箭","Steady Shot":"稳定射击","Pestilent Shot":"疫病射击","Penetrating Shot":"贯穿射击","Water Strike":"流水冲击","Ice Spear":"冰枪术","Frost Surge":"冰霜爆裂","Mana Spring":"法力喷泉","Entangle":"缠绕","Toxic Pollen":"剧毒粉尘","Nature's Veil":"自然菌幕","Fireball":"火球","Flame Blast":"熔岩爆裂","Firestorm":"火焰风暴","Smoke Burst":"烟爆灭影","Minor Heal":"初级自愈术","Heal":"自愈术","Quick Aid":"快速治疗术","Rejuvenate":"群体治疗术","Taunt":"嘲讽","Provoke":"挑衅","Toughness":"坚韧","Elusiveness":"闪避","Precision":"精确","Berserk":"狂暴","Elemental Affinity":"元素增幅","Frenzy":"狂速","Spike Shell":"尖刺防护","Arcane Reflection":"奥术反射","Vampirism":"吸血","Revive":"复活","Insanity":"疯狂","Invincible":"无敌","Fierce Aura":"物理光环","Aqua Aura":"流水光环","Sylvan Aura":"自然光环","Flame Aura":"火焰光环","Speed Aura":"速度光环","Critical Aura":"暴击光环","Gobo Stabber":"哥布林长剑","Gobo Slasher":"哥布林关刀","Gobo Smasher":"哥布林狼牙棒","Spiked Bulwark":"尖刺盾","Werewolf Slasher":"狼人关刀","Griffin Bulwark":"狮鹫重盾","Gobo Shooter":"哥布林弹弓","Vampiric Bow":"吸血弓","Cursed Bow":"咒怨之弓","Gobo Boomstick":"哥布林火棍","Cheese Bulwark":"奶酪重盾","Verdant Bulwark":"翠绿重盾","Azure Bulwark":"蔚蓝重盾","Burble Bulwark":"深紫重盾","Crimson Bulwark":"绛红重盾","Rainbow Bulwark":"彩虹重盾","Holy Bulwark":"神圣重盾","Wooden Bow":"木弓","Birch Bow":"桦木弓","Cedar Bow":"雪松弓","Purpleheart Bow":"紫心弓","Ginkgo Bow":"银杏弓","Redwood Bow":"红杉弓","Arcane Bow":"神秘弓","Stalactite Spear":"石钟长枪","Granite Bludgeon":"花岗岩大棒","Regal Sword":"君王之剑","Chaotic Flail":"混沌连枷","Soul Hunter Crossbow":"灵魂猎手弩","Sundering Crossbow":"裂空之弩","Frost Staff":"冰霜法杖","Infernal Battlestaff":"炼狱法杖","Jackalope Staff":"鹿角兔之杖","Cheese Sword":"奶酪剑","Verdant Sword":"翠绿剑","Azure Sword":"蔚蓝剑","Burble Sword":"深紫剑","Crimson Sword":"绛红剑","Rainbow Sword":"彩虹剑","Holy Sword":"神圣剑","Cheese Spear":"奶酪长枪","Verdant Spear":"翠绿长枪","Azure Spear":"蔚蓝长枪","Burble Spear":"深紫长枪","Crimson Spear":"绛红长枪","Rainbow Spear":"彩虹长枪","Holy Spear":"神圣长枪","Cheese Mace":"奶酪钉头锤","Verdant Mace":"翠绿钉头锤","Azure Mace":"蔚蓝钉头锤","Burble Mace":"深紫钉头锤","Crimson Mace":"绛红钉头锤","Rainbow Mace":"彩虹钉头锤","Holy Mace":"神圣钉头锤","Wooden Crossbow":"木弩","Birch Crossbow":"桦木弩","Cedar Crossbow":"雪松弩","Purpleheart Crossbow":"紫心弩","Ginkgo Crossbow":"银杏弩","Redwood Crossbow":"红杉弩","Arcane Crossbow":"神秘弩","Wooden Water Staff":"木制水法杖","Birch Water Staff":"桦木水法杖","Cedar Water Staff":"雪松水法杖","Purpleheart Water Staff":"紫心水法杖","Ginkgo Water Staff":"银杏水法杖","Redwood Water Staff":"红杉水法杖","Arcane Water Staff":"神秘水法杖","Wooden Nature Staff":"木制自然法杖","Birch Nature Staff":"桦木自然法杖","Cedar Nature Staff":"雪松自然法杖","Purpleheart Nature Staff":"紫心自然法杖","Ginkgo Nature Staff":"银杏自然法杖","Redwood Nature Staff":"红杉自然法杖","Arcane Nature Staff":"神秘自然法杖","Wooden Fire Staff":"木火法杖","Birch Fire Staff":"桦木火法杖","Cedar Fire Staff":"雪松火法杖","Purpleheart Fire Staff":"紫心火法杖","Ginkgo Fire Staff":"银杏火法杖","Redwood Fire Staff":"红杉火法杖","Arcane Fire Staff":"神秘火法杖","Eye Watch":"掌上监工","Snake Fang Dirk":"蛇牙短剑","Vision Shield":"视觉盾","Gobo Defender":"哥布林防御者","Vampire Fang Dirk":"吸血鬼短剑","Knight's Aegis":"骑士盾","Treant Shield":"树人盾","Manticore Shield":"蝎狮盾","Tome Of Healing":"治疗之书","Tome Of The Elements":"元素之书","Watchful Relic":"警戒遗物","Bishop's Codex":"主教法典","Cheese Buckler":"奶酪圆盾","Verdant Buckler":"翠绿圆盾","Azure Buckler":"蔚蓝圆盾","Burble Buckler":"深紫圆盾","Crimson Buckler":"绛红圆盾","Rainbow Buckler":"彩虹圆盾","Holy Buckler":"神圣圆盾","Wooden Shield":"木盾","Birch Shield":"桦木盾","Cedar Shield":"雪松盾","Purpleheart Shield":"紫心盾","Ginkgo Shield":"银杏盾","Redwood Shield":"红杉盾","Arcane Shield":"神秘盾","Sinister Cape":"阴森斗篷","Chimerical Quiver":"奇幻箭袋","Enchanted Cloak":"秘法披风","Red Culinary Hat":"红色厨师帽","Snail Shell Helmet":"蜗牛壳头盔","Vision Helmet":"视觉头盔","Fluffy Red Hat":"蓬松红帽子","Acrobatic Hood":"杂技师兜帽","Magician's Hat":"魔术师帽","Cheese Helmet":"奶酪头盔","Verdant Helmet":"翠绿头盔","Azure Helmet":"蔚蓝头盔","Burble Helmet":"深紫头盔","Crimson Helmet":"绛红头盔","Rainbow Helmet":"彩虹头盔","Holy Helmet":"神圣头盔","Rough Hood":"粗糙兜帽","Reptile Hood":"爬行动物兜帽","Gobo Hood":"哥布林兜帽","Beast Hood":"野兽兜帽","Umbral Hood":"暗影兜帽","Cotton Hat":"棉帽","Linen Hat":"亚麻帽","Bamboo Hat":"竹帽","Silk Hat":"丝帽","Radiant Hat":"光辉帽","Dairyhand's Top":"挤奶工上衣","Forager's Top":"采摘者上衣","Lumberjack's Top":"伐木工上衣","Cheesemaker's Top":"奶酪师上衣","Crafter's Top":"工匠上衣","Tailor's Top":"裁缝上衣","Chef's Top":"厨师上衣","Brewer's Top":"饮品师上衣","Alchemist's Top":"炼金师上衣","Enhancer's Top":"强化师上衣","Gator Vest":"鳄鱼马甲","Turtle Shell Body":"龟壳胸甲","Colossus Plate Body":"巨像胸甲","Demonic Plate Body":"恶魔胸甲","Marine Tunic":"海洋皮衣","Revenant Tunic":"亡灵皮衣","Griffin Tunic":"狮鹫皮衣","Icy Robe Top":"冰霜长袍","Flaming Robe Top":"烈焰长袍","Luna Robe Top":"月神长袍","Royal Water Robe Top":"皇家水系长袍","Royal Nature Robe Top":"皇家自然系长袍","Royal Fire Robe Top":"皇家火系长袍","Cheese Plate Body":"奶酪胸甲","Verdant Plate Body":"翠绿胸甲","Azure Plate Body":"蔚蓝胸甲","Burble Plate Body":"深紫胸甲","Crimson Plate Body":"绛红胸甲","Rainbow Plate Body":"彩虹胸甲","Holy Plate Body":"神圣胸甲","Rough Tunic":"粗糙皮衣","Reptile Tunic":"爬行动物皮衣","Gobo Tunic":"哥布林皮衣","Beast Tunic":"野兽皮衣","Umbral Tunic":"暗影皮衣","Cotton Robe Top":"棉布上衣","Linen Robe Top":"亚麻上衣","Bamboo Robe Top":"竹上衣","Silk Robe Top":"丝绸上衣","Radiant Robe Top":"光辉上衣","Dairyhand's Bottoms":"挤奶工下装","Forager's Bottoms":"采摘者下装","Lumberjack's Bottoms":"伐木工下装","Cheesemaker's Bottoms":"奶酪师下装","Crafter's Bottoms":"工匠下装","Tailor's Bottoms":"裁缝下装","Chef's Bottoms":"厨师下装","Brewer's Bottoms":"饮品师下装","Alchemist's Bottoms":"炼金师下装","Enhancer's Bottoms":"强化师下装","Turtle Shell Legs":"龟壳腿甲","Colossus Plate Legs":"巨像腿甲","Demonic Plate Legs":"恶魔腿甲","Marine Chaps":"航海皮裤","Revenant Chaps":"亡灵皮裤","Griffin Chaps":"狮鹫皮裤","Icy Robe Bottoms":"冰霜下装","Flaming Robe Bottoms":"烈焰下装","Luna Robe Bottoms":"月神下装","Royal Water Robe Bottoms":"皇家水系下装","Royal Nature Robe Bottoms":"皇家自然系下装","Royal Fire Robe Bottoms":"皇家火系下装","Cheese Plate Legs":"奶酪腿甲","Verdant Plate Legs":"翠绿腿甲","Azure Plate Legs":"蔚蓝腿甲","Burble Plate Legs":"深紫腿甲","Crimson Plate Legs":"绛红腿甲","Rainbow Plate Legs":"彩虹腿甲","Holy Plate Legs":"神圣腿甲","Rough Chaps":"粗糙皮裤","Reptile Chaps":"爬行动物皮裤","Gobo Chaps":"哥布林皮裤","Beast Chaps":"野兽皮裤","Umbral Chaps":"暗影皮裤","Cotton Robe Bottoms":"棉下装","Linen Robe Bottoms":"亚麻下装","Bamboo Robe Bottoms":"竹下装","Silk Robe Bottoms":"丝绸下装","Radiant Robe Bottoms":"光辉下装","Enchanted Gloves":"附魔手套","Pincer Gloves":"蟹钳手套","Panda Gloves":"熊猫手套","Magnetic Gloves":"磁力手套","Dodocamel Gauntlets":"渡渡驼护手","Sighted Bracers":"瞄准护腕","Chrono Gloves":"时空手套","Cheese Gauntlets":"奶酪护手","Verdant Gauntlets":"翠绿护手","Azure Gauntlets":"蔚蓝护手","Burble Gauntlets":"深紫护手","Crimson Gauntlets":"绛红护手","Rainbow Gauntlets":"彩虹护手","Holy Gauntlets":"神圣护手","Rough Bracers":"粗糙护腕","Reptile Bracers":"爬行动物护腕","Gobo Bracers":"哥布林护腕","Beast Bracers":"野兽护腕","Umbral Bracers":"暗影护腕","Cotton Gloves":"棉手套","Linen Gloves":"亚麻手套","Bamboo Gloves":"竹手套","Silk Gloves":"丝手套","Radiant Gloves":"光辉手套","Collector's Boots":"收藏家靴","Shoebill Shoes":"鲸头鹳鞋","Black Bear Shoes":"黑熊鞋","Grizzly Bear Shoes":"棕熊鞋","Polar Bear Shoes":"北极熊鞋","Centaur Boots":"半人马靴","Sorcerer Boots":"巫师靴","Cheese Boots":"奶酪靴","Verdant Boots":"翠绿靴","Azure Boots":"蔚蓝靴","Burble Boots":"深紫靴","Crimson Boots":"绛红靴","Rainbow Boots":"彩虹靴","Holy Boots":"神圣靴","Rough Boots":"粗糙靴","Reptile Boots":"爬行动物靴","Gobo Boots":"哥布林靴","Beast Boots":"野兽靴","Umbral Boots":"暗影靴","Cotton Boots":"棉靴","Linen Boots":"亚麻靴","Bamboo Boots":"竹靴","Silk Boots":"丝靴","Radiant Boots":"光辉靴","Small Pouch":"小袋子","Medium Pouch":"中袋子","Large Pouch":"大袋子","Giant Pouch":"巨大袋子","Gluttonous Pouch":"贪食之袋","Guzzling Pouch":"暴饮之囊","Necklace Of Efficiency":"效率项链","Fighter Necklace":"战士项链","Ranger Necklace":"射手项链","Wizard Necklace":"巫师项链","Necklace Of Wisdom":"经验项链","Necklace Of Speed":"速度项链","Philosopher's Necklace":"贤者项链","Earrings Of Gathering":"采集耳环","Earrings Of Essence Find":"精华发现耳环","Earrings Of Armor":"护甲耳环","Earrings Of Regeneration":"恢复耳环","Earrings Of Resistance":"抗性耳环","Earrings Of Rare Find":"稀有发现耳环","Earrings Of Critical Strike":"暴击耳环","Philosopher's Earrings":"贤者耳环","Ring Of Gathering":"采集戒指","Ring Of Essence Find":"精华发现戒指","Ring Of Armor":"护甲戒指","Ring Of Regeneration":"恢复戒指","Ring Of Resistance":"抗性戒指","Ring Of Rare Find":"稀有发现戒指","Ring Of Critical Strike":"暴击戒指","Philosopher's Ring":"贤者戒指","Basic Task Badge":"基础任务徽章","Advanced Task Badge":"高级任务徽章","Expert Task Badge":"专家任务徽章","Celestial Brush":"星空刷子","Cheese Brush":"奶酪刷子","Verdant Brush":"翠绿刷子","Azure Brush":"蔚蓝刷子","Burble Brush":"深紫刷子","Crimson Brush":"绛红刷子","Rainbow Brush":"彩虹刷子","Holy Brush":"神圣刷子","Celestial Shears":"星空剪刀","Cheese Shears":"奶酪剪刀","Verdant Shears":"翠绿剪刀","Azure Shears":"蔚蓝剪刀","Burble Shears":"深紫剪刀","Crimson Shears":"绛红剪刀","Rainbow Shears":"彩虹剪刀","Holy Shears":"神圣剪刀","Celestial Hatchet":"星空斧头","Cheese Hatchet":"奶酪斧头","Verdant Hatchet":"翠绿斧头","Azure Hatchet":"蔚蓝斧头","Burble Hatchet":"深紫斧头","Crimson Hatchet":"绛红斧头","Rainbow Hatchet":"彩虹斧头","Holy Hatchet":"神圣斧头","Celestial Hammer":"星空锤子","Cheese Hammer":"奶酪锤子","Verdant Hammer":"翠绿锤子","Azure Hammer":"蔚蓝锤子","Burble Hammer":"深紫锤子","Crimson Hammer":"绛红锤子","Rainbow Hammer":"彩虹锤子","Holy Hammer":"神圣锤子","Celestial Chisel":"星空凿子","Cheese Chisel":"奶酪凿子","Verdant Chisel":"翠绿凿子","Azure Chisel":"蔚蓝凿子","Burble Chisel":"深紫凿子","Crimson Chisel":"绛红凿子","Rainbow Chisel":"彩虹凿子","Holy Chisel":"神圣凿子","Celestial Needle":"星空针","Cheese Needle":"奶酪针","Verdant Needle":"翠绿针","Azure Needle":"蔚蓝针","Burble Needle":"深紫针","Crimson Needle":"绛红针","Rainbow Needle":"彩虹针","Holy Needle":"神圣针","Celestial Spatula":"星空锅铲","Cheese Spatula":"奶酪锅铲","Verdant Spatula":"翠绿锅铲","Azure Spatula":"蔚蓝锅铲","Burble Spatula":"深紫锅铲","Crimson Spatula":"绛红锅铲","Rainbow Spatula":"彩虹锅铲","Holy Spatula":"神圣锅铲","Celestial Pot":"星空壶","Cheese Pot":"奶酪壶","Verdant Pot":"翠绿壶","Azure Pot":"蔚蓝壶","Burble Pot":"深紫壶","Crimson Pot":"绛红壶","Rainbow Pot":"彩虹壶","Holy Pot":"神圣壶","Celestial Alembic":"星空蒸馏器","Cheese Alembic":"奶酪蒸馏器","Verdant Alembic":"翠绿蒸馏器","Azure Alembic":"蔚蓝蒸馏器","Burble Alembic":"深紫蒸馏器","Crimson Alembic":"绛红蒸馏器","Rainbow Alembic":"彩虹蒸馏器","Holy Alembic":"神圣蒸馏器","Celestial Enhancer":"星空强化器","Cheese Enhancer":"奶酪强化器","Verdant Enhancer":"翠绿强化器","Azure Enhancer":"蔚蓝强化器","Burble Enhancer":"深紫强化器","Crimson Enhancer":"绛红强化器","Rainbow Enhancer":"彩虹强化器","Holy Enhancer":"神圣强化器","Milk":"牛奶","Verdant Milk":"翠绿牛奶","Azure Milk":"蔚蓝牛奶","Burble Milk":"深紫牛奶","Crimson Milk":"绛红牛奶","Rainbow Milk":"彩虹牛奶","Holy Milk":"神圣牛奶","Cheese":"奶酪","Verdant Cheese":"翠绿奶酪","Azure Cheese":"蔚蓝奶酪","Burble Cheese":"深紫奶酪","Crimson Cheese":"绛红奶酪","Rainbow Cheese":"彩虹奶酪","Holy Cheese":"神圣奶酪","Log":"原木","Birch Log":"白桦原木","Cedar Log":"雪松原木","Purpleheart Log":"紫心原木","Ginkgo Log":"银杏原木","Redwood Log":"红杉原木","Arcane Log":"神秘原木","Lumber":"木板","Birch Lumber":"白桦木板","Cedar Lumber":"雪松木板","Purpleheart Lumber":"紫心木板","Ginkgo Lumber":"银杏木板","Redwood Lumber":"红杉木板","Arcane Lumber":"神秘木板","Rough Hide":"粗糙兽皮","Reptile Hide":"爬行动物皮","Gobo Hide":"哥布林皮","Beast Hide":"野兽皮","Umbral Hide":"暗影皮","Rough Leather":"粗糙皮革","Reptile Leather":"爬行动物皮革","Gobo Leather":"哥布林皮革","Beast Leather":"野兽皮革","Umbral Leather":"暗影皮革","Cotton":"棉花","Flax":"亚麻","Bamboo Branch":"竹子","Cocoon":"蚕茧","Radiant Fiber":"光辉纤维","Cotton Fabric":"棉花布料","Linen Fabric":"亚麻布料","Bamboo Fabric":"竹子布料","Silk Fabric":"丝绸","Radiant Fabric":"光辉布料","Egg":"鸡蛋","Wheat":"小麦","Sugar":"糖","Blueberry":"蓝莓","Blackberry":"黑莓","Strawberry":"草莓","Mooberry":"哞梅","Marsberry":"火星梅","Spaceberry":"太空梅","Apple":"苹果","Orange":"橙子","Plum":"李子","Peach":"桃子","Dragon Fruit":"火龙果","Star Fruit":"杨桃","Arabica Coffee Bean":"低级咖啡豆","Robusta Coffee Bean":"中级咖啡豆","Liberica Coffee Bean":"高级咖啡豆","Excelsa Coffee Bean":"特级咖啡豆","Fieriosa Coffee Bean":"火山咖啡豆","Spacia Coffee Bean":"太空咖啡豆","Green Tea Leaf":"绿茶叶","Black Tea Leaf":"黑茶叶","Burble Tea Leaf":"紫茶叶","Moolong Tea Leaf":"哞龙茶叶","Red Tea Leaf":"红茶叶","Emp Tea Leaf":"虚空茶叶","Catalyst Of Coinification":"点金催化剂","Catalyst Of Decomposition":"分解催化剂","Catalyst Of Transmutation":"转化催化剂","Prime Catalyst":"至高催化剂","Snake Fang":"蛇牙","Shoebill Feather":"鲸头鹳羽毛","Snail Shell":"蜗牛壳","Crab Pincer":"蟹钳","Turtle Shell":"乌龟壳","Marine Scale":"海洋鳞片","Treant Bark":"树皮","Centaur Hoof":"半人马蹄","Luna Wing":"月神翼","Gobo Rag":"哥布林抹布","Goggles":"护目镜","Magnifying Glass":"放大镜","Eye Of The Watcher":"观察者之眼","Icy Cloth":"冰霜织物","Flaming Cloth":"烈焰织物","Sorcerer's Sole":"魔法师鞋底","Chrono Sphere":"时空球","Frost Sphere":"冰霜球","Panda Fluff":"熊猫绒","Black Bear Fluff":"黑熊绒","Grizzly Bear Fluff":"棕熊绒","Polar Bear Fluff":"北极熊绒","Red Panda Fluff":"小熊猫绒","Magnet":"磁铁","Stalactite Shard":"钟乳石碎片","Living Granite":"花岗岩","Colossus Core":"巨像核心","Vampire Fang":"吸血鬼之牙","Werewolf Claw":"狼人之爪","Revenant Anima":"亡者之魂","Soul Fragment":"灵魂碎片","Infernal Ember":"地狱余烬","Demonic Core":"恶魔核心","Griffin Leather":"狮鹫之皮","Manticore Sting":"蝎狮之刺","Jackalope Antler":"鹿角兔之角","Dodocamel Plume":"渡渡驼之翎","Griffin Talon":"狮鹫之爪","Acrobat's Ribbon":"杂技师彩带","Magician's Cloth":"魔术师织物","Chaotic Chain":"混沌锁链","Cursed Ball":"诅咒之球","Royal Cloth":"皇家织物","Knight's Ingot":"骑士之锭","Bishop's Scroll":"主教卷轴","Regal Jewel":"君王宝石","Sundering Jewel":"裂空宝石","Butter Of Proficiency":"精通之油","Thread Of Expertise":"专精之线","Branch Of Insight":"洞察之枝","Gluttonous Energy":"贪食能量","Guzzling Energy":"暴饮能量","Milking Essence":"挤奶精华","Foraging Essence":"采摘精华","Woodcutting Essence":"伐木精华","Cheesesmithing Essence":"奶酪锻造精华","Crafting Essence":"制作精华","Tailoring Essence":"缝纫精华","Cooking Essence":"烹饪精华","Brewing Essence":"冲泡精华","Alchemy Essence":"炼金精华","Enhancing Essence":"强化精华","Swamp Essence":"沼泽精华","Aqua Essence":"海洋精华","Jungle Essence":"丛林精华","Gobo Essence":"哥布林精华","Eyessence":"眼精华","Sorcerer Essence":"法师精华","Bear Essence":"熊熊精华","Golem Essence":"魔像精华","Twilight Essence":"暮光精华","Abyssal Essence":"地狱精华","Chimerical Essence":"奇幻精华","Sinister Essence":"阴森精华","Enchanted Essence":"秘法精华","Task Crystal":"任务水晶","Star Fragment":"星光碎片","Pearl":"珍珠","Amber":"琥珀","Garnet":"石榴石","Jade":"翡翠","Amethyst":"紫水晶","Moonstone":"月亮石","Sunstone":"太阳石","Philosopher's Stone":"贤者之石","Crushed Pearl":"珍珠碎片","Crushed Amber":"琥珀碎片","Crushed Garnet":"石榴石碎片","Crushed Jade":"翡翠碎片","Crushed Amethyst":"紫水晶碎片","Crushed Moonstone":"月亮石碎片","Crushed Sunstone":"太阳石碎片","Crushed Philosopher's Stone":"贤者之石碎片","Shard Of Protection":"保护碎片","Mirror Of Protection":"保护之镜"}
let specialItemPrices = {
'Coin': { ask: 1, bid: 1 }, // 默认的特殊物品价值,包括 ask 和 bid 价值
'Cowbell': {
ask: getSpecialItemPrice('Bag Of 10 Cowbells', 'ask') / 10 || 32000,
bid: getSpecialItemPrice('Bag Of 10 Cowbells', 'bid') / 10 || 30000
},
'Chimerical Token': {
ask: getSpecialItemPrice('Chimerical Essence', 'ask') || 600,
bid: getSpecialItemPrice('Chimerical Essence', 'bid') || 600
},
'Sinister Token': {
ask: getSpecialItemPrice('Sinister Essence', 'ask') || 1100,
bid: getSpecialItemPrice('Sinister Essence', 'bid') || 1000
},
'Enchanted Token': {
ask: getSpecialItemPrice('Enchanted Essence', 'ask') || 1800,
bid: getSpecialItemPrice('Enchanted Essence', 'bid') || 1700
},
};
const auraAbilities = new Set([
'revive',
'insanity',
'invincible',
'fierce_aura',
'aqua_aura',
'sylvan_aura',
'flame_aura',
'speed_aura',
'critical_aura'
]);
//公会部分代码
const updataDealy = 24*60*60*1000; //数据更新时限
let rateXPDayMap = {};
async function fetchMarketData() {
return new Promise((resolve, reject) => {
GM.xmlHttpRequest({
method: 'GET',
url: MARKET_API_URL,
responseType: 'json',
timeout: 5000,
onload: function(response) {
if (response.status === 200) {
const data = JSON.parse(response.responseText);
console.log('从API获取到的数据:', data);
resolve(data);
} else {
console.error('获取数据失败。状态码:', response.status);
reject(new Error('数据获取失败'));
}
},
ontimeout: function() {
console.error('请求超时:超过5秒未能获取到数据');
reject(new Error('请求超时'));
},
onerror: function(error) {
console.error('获取数据时发生错误:', error);
reject(error);
}
});
});
}
hookWS();
initObserver();
try {
// 尝试从 API 获取数据
marketData = await fetchMarketData();
marketData.market.Coin.ask = 1;
marketData.market.Coin.bid = 1;
} catch (error) {
console.error('从 API 获取数据失败,尝试从本地存储获取数据。', error);
// 从本地存储获取数据
const marketDataStr = localStorage.getItem('MWITools_marketAPI_json');
marketData = JSON.parse(marketDataStr);
if (!marketData) {
alert('无法获取 market 数据');
} else {
console.log('从本地存储获取到的数据:', marketData);
}
}
function getSpecialItemPrice(itemName, priceType) {
if (marketData?.market?.[itemName]) {
const itemPrice = marketData.market[itemName][priceType];
if (itemPrice !== undefined && itemPrice !== -1) {
return itemPrice;
}
}
console.error(`未找到物品 ${itemName} 的 ${priceType} 价格信息`);
return null;
}
function getItemNameFromElement(element) {
const itemNameRaw = element.getAttribute('href').split('#').pop();
return formatItemName(itemNameRaw);
}
function formatItemName(itemNameRaw) {
return item_hrid_to_name[`/items/${itemNameRaw}`]
}
function formatPrice(value,n = 1) {
const isNegative = value < 0;
value = Math.abs(value);
if (value >= 1e13 / n) {
return (isNegative ? '-' : '') + (value / 1e12).toFixed(1) + 'T';
} else if (value >= 1e10 / n) {
return (isNegative ? '-' : '') + (value / 1e9).toFixed(1) + 'B';
} else if (value >= 1e7 / n) {
return (isNegative ? '-' : '') + (value / 1e6).toFixed(1) + 'M';
} else if (value >= 1e4 / n) {
return (isNegative ? '-' : '') + (value / 1e3).toFixed(1) + 'K';
} else {
return (isNegative ? '-' : '') + value.toFixed(0);
}
}
function parseQuantityString(quantityStr) {
const suffix = quantityStr.slice(-1);
const base = parseFloat(quantityStr.slice(0, -1));
if (suffix === 'K') {
return base * 1000;
} else if (suffix === 'M') {
return base * 1000000;
} else if (suffix === 'B') {
return base * 1000000000;
} else {
return parseFloat(quantityStr);
}
}
function recordChestOpening(modalElement) {
if (document.querySelector('.ChestStatistics')) {
return;
}
// 从本地存储读取数据
let edibleTools = JSON.parse(localStorage.getItem('Edible_Tools')) || {};
edibleTools.Chest_Open_Data = edibleTools.Chest_Open_Data || {};
let chestOpenData = edibleTools.Chest_Open_Data;
const chestDropData = edibleTools.Chest_Drop_Data;
const chestNameElement = modalElement.querySelector("div.Modal_modal__1Jiep > div.Inventory_modalContent__3ObSx > div.Item_itemContainer__x7kH1 > div > div > div.Item_iconContainer__5z7j4 > svg > use");
const chestCountElement = modalElement.querySelector("div.Modal_modal__1Jiep > div.Inventory_modalContent__3ObSx > div.Item_itemContainer__x7kH1 > div > div > div.Item_count__1HVvv");
if (chestNameElement && chestCountElement) {
const chestName = getItemNameFromElement(chestNameElement);
chestOpenData[chestName] = chestOpenData[chestName] || {};
let chestData = chestOpenData[chestName];
const chestCount = parseQuantityString(chestCountElement.textContent.trim());
chestData["总计开箱数量"] = (chestData["总计开箱数量"] || 0) + chestCount;
chestData["获得物品"] = chestData["获得物品"] || {};
const itemsContainer = modalElement.querySelector('.Inventory_gainedItems___e9t9');
const itemElements = itemsContainer.querySelectorAll('.Item_itemContainer__x7kH1');
let totalAskValue = 0;
let totalBidValue = 0;
itemElements.forEach(itemElement => {
const itemNameElement = itemElement.querySelector('.Item_iconContainer__5z7j4 use');
const itemQuantityElement = itemElement.querySelector('.Item_count__1HVvv');
if (itemNameElement && itemQuantityElement) {
const itemName = getItemNameFromElement(itemNameElement);
const itemQuantity = parseQuantityString(itemQuantityElement.textContent.trim());
const itemData = chestDropData[chestName].item[itemName] || {};
const itemAskValue = itemData["出售单价"] || 0;
const itemBidValue = itemData["收购单价"] || 0;
const color = itemData.Color || '';
itemQuantityElement.style.color = color;
const itemOpenTotalAskValue = itemAskValue * itemQuantity;
const itemOpenTotalBidValue = itemBidValue * itemQuantity;
chestData["获得物品"][itemName] = chestData["获得物品"][itemName] || {};
chestData["获得物品"][itemName]["数量"] = (chestData["获得物品"][itemName]["数量"] || 0) + itemQuantity;
chestData["获得物品"][itemName]["总计Ask价值"] = (chestData["获得物品"][itemName]["总计Ask价值"] || 0) + itemOpenTotalAskValue;
chestData["获得物品"][itemName]["总计Bid价值"] = (chestData["获得物品"][itemName]["总计Bid价值"] || 0) + itemOpenTotalBidValue;
totalAskValue += itemOpenTotalAskValue;
totalBidValue += itemOpenTotalBidValue;
}
});
chestData["总计开箱Ask"] = (chestData["总计开箱Ask"] || 0) + totalAskValue;
chestData["总计开箱Bid"] = (chestData["总计开箱Bid"] || 0) + totalBidValue;
// 计算本次开箱的偏差值
const differenceValue = totalBidValue - chestDropData[chestName]["期望产出Bid"] * chestCount;
// 更新累计偏差值
chestData["累计偏差值"] = (chestData["累计偏差值"] || 0) + differenceValue;
// 地牢开箱
let profitRange = null;
let profitColor = 'lime'; // 默认颜色
const chestCosts = {
"Chimerical Chest": {
keyAsk: getSpecialItemPrice('Chimerical Chest Key', 'ask') || 2700e3,
keyBid: getSpecialItemPrice('Chimerical Chest Key', 'bid') || 2600e3,
entryAsk: getSpecialItemPrice('Chimerical Entry Key', 'ask') || 350e3,
entryBid: getSpecialItemPrice('Chimerical Entry Key', 'bid') || 320e3
},
"Sinister Chest": {
keyAsk: getSpecialItemPrice('Sinister Chest Key', 'ask') || 3800e3,
keyBid: getSpecialItemPrice('Sinister Chest Key', 'bid') || 3500e3,
entryAsk: getSpecialItemPrice('Sinister Entry Key', 'ask') || 450e3,
entryBid: getSpecialItemPrice('Sinister Entry Key', 'bid') || 400e3
},
"Enchanted Chest": {
keyAsk: getSpecialItemPrice('Enchanted Chest Key', 'ask') || 5600e3,
keyBid: getSpecialItemPrice('Enchanted Chest Key', 'bid') || 5400e3,
entryAsk: getSpecialItemPrice('Enchanted Entry Key', 'ask') || 420e3,
entryBid: getSpecialItemPrice('Enchanted Entry Key', 'bid') || 400e3
}
};
if (chestCosts[chestName]) {
const { keyAsk, keyBid, entryAsk, entryBid } = chestCosts[chestName];
const minProfit = totalBidValue - (keyAsk + entryAsk) * chestCount;
const maxProfit = totalAskValue - (keyBid + entryBid) * chestCount;
profitRange = `${formatPrice(minProfit)}~${formatPrice(maxProfit)}`;
if (minProfit > 0 && maxProfit > 0) {
profitColor = 'lime';
} else if (minProfit < 0 && maxProfit < 0) {
profitColor = 'red';
} else {
profitColor = 'orange';
}
}
// 显示
const openChestElement = document.querySelector('.Inventory_modalContent__3ObSx');
const displayElement = document.createElement('div');
displayElement.classList.add('ChestStatistics');
displayElement.style.position = 'absolute';
displayElement.style.left = `${openChestElement.offsetLeft}px`;
displayElement.style.top = `${openChestElement.offsetTop}px`;
displayElement.style.fontSize = '12px';
displayElement.innerHTML = `
总计开箱次数:
${chestData["总计开箱数量"]}
本次开箱价值:
${formatPrice(totalAskValue)}/${formatPrice(totalBidValue)}
总计开箱价值:
${formatPrice(chestData["总计开箱Ask"])}/${formatPrice(chestData["总计开箱Bid"])}
`;
const expectedOutputElement = document.createElement('div');
expectedOutputElement.classList.add('ExpectedOutput');
expectedOutputElement.style.position = 'absolute';
expectedOutputElement.style.left = `${openChestElement.offsetLeft}px`;
expectedOutputElement.style.bottom = `${openChestElement.offsetTop}px`;
expectedOutputElement.style.fontSize = '12px';
expectedOutputElement.innerHTML = `
预计产出价值:
${formatPrice(chestDropData[chestName]["期望产出Ask"]*chestCount)}/${formatPrice(chestDropData[chestName]["期望产出Bid"]*chestCount)}
`;
const differenceOutputElement = document.createElement('div');
differenceOutputElement.classList.add('DifferenceOutput');
differenceOutputElement.style.position = 'absolute';
differenceOutputElement.style.right = `${openChestElement.offsetLeft}px`;
differenceOutputElement.style.bottom = `${openChestElement.offsetTop}px`;
differenceOutputElement.style.fontSize = '12px';
differenceOutputElement.style.color = differenceValue > 0 ? 'lime' : 'red';
differenceOutputElement.innerHTML = `
${differenceValue > 0 ? '高于期望价值:' : '低于期望价值:'}
${formatPrice(Math.abs(differenceValue))}
`;
// 创建并显示累计偏差值的元素
const cumulativeDifferenceElement = document.createElement('div');
cumulativeDifferenceElement.classList.add('CumulativeDifference');
cumulativeDifferenceElement.style.position = 'absolute';
cumulativeDifferenceElement.style.right = `${openChestElement.offsetLeft}px`;
cumulativeDifferenceElement.style.top = `${openChestElement.offsetTop}px`;
cumulativeDifferenceElement.style.fontSize = '12px';
cumulativeDifferenceElement.style.color = chestData["累计偏差值"] > 0 ? 'lime' : 'red';
cumulativeDifferenceElement.innerHTML = `
本次开箱利润
${profitRange ? `${profitRange}` : `${formatPrice(totalAskValue)}/${formatPrice(totalBidValue)}`}
累计${chestData["累计偏差值"] > 0 ? '高于期望:' : '低于期望:'}
${formatPrice(Math.abs(chestData["累计偏差值"]))}
`;
openChestElement.appendChild(displayElement);
openChestElement.appendChild(expectedOutputElement);
openChestElement.appendChild(differenceOutputElement);
openChestElement.appendChild(cumulativeDifferenceElement);
// 保存更新的数据到本地存储
localStorage.setItem('Edible_Tools', JSON.stringify(edibleTools));
}
}
function calculateTotalValues(itemElements) {
let totalAskValue = 0;
let totalBidValue = 0;
itemElements.forEach(itemElement => {
const itemNameElement = itemElement.querySelector('.Item_iconContainer__5z7j4 use');
const itemQuantityElement = itemElement.querySelector('.Item_count__1HVvv');
if (itemNameElement && itemQuantityElement) {
const itemName = getItemNameFromElement(itemNameElement);
const itemQuantity = parseQuantityString(itemQuantityElement.textContent.trim());
let askPrice = 0;
let bidPrice = 0;
let priceColor = '';
// 获取价格
if (specialItemPrices[itemName] && specialItemPrices[itemName].ask) {
askPrice = parseFloat(specialItemPrices[itemName].ask);
bidPrice = parseFloat(specialItemPrices[itemName].bid);
priceColor = '';
} else if (marketData?.market?.[itemName]) {
bidPrice = marketData.market[itemName].bid;
askPrice = marketData.market[itemName].ask;
} else {
console.log(`${itemName} 的价格未找到`);
}
const itemTotalAskValue = askPrice * itemQuantity;
const itemTotalBidValue = bidPrice * itemQuantity;
totalAskValue += itemTotalAskValue;
totalBidValue += itemTotalBidValue;
}
});
//console.log(totalAskValue);
return { totalAskValue, totalBidValue };
}
//更详细的战斗等级显示
const updateCombatLevel = () => {
const elements = document.querySelectorAll(".NavigationBar_currentExperience__3GDeX");
if (elements.length === 17) {
const levels = Array.from(elements).slice(10, 17).map(el => {
const levelText = parseInt(el.parentNode.parentNode.querySelector(".NavigationBar_textContainer__7TdaI .NavigationBar_level__3C7eR").textContent);
const decimalPart = parseFloat(el.style.width) / 100;
return { integerPart: levelText, decimalPart: decimalPart };
});
let [endurance, intelligence, attack, strength, defense, ranged, magic] = levels;
let combatTypeMax = Math.max(
0.5 * (attack.integerPart + strength.integerPart),
ranged.integerPart,
magic.integerPart
);
if (combatTypeMax !== 0.5 * (attack.integerPart + strength.integerPart)) {
attack.decimalPart = 0;
strength.decimalPart = 0;
}
if (combatTypeMax !== ranged.integerPart) ranged.decimalPart = 0;
if (combatTypeMax !== magic.integerPart) magic.decimalPart = 0;
let combatLevel = 0.2 * (endurance.integerPart + intelligence.integerPart + defense.integerPart) + 0.4 * combatTypeMax;
combatLevel = parseFloat(combatLevel.toFixed(2));
//console.log("combatLevel",combatLevel)
const integerPart = Math.floor(combatLevel);
const decimalPart = combatLevel - integerPart;
//console.log("integerPart",integerPart)
const list1 = [
endurance.decimalPart * 0.2,
intelligence.decimalPart * 0.2,
attack.decimalPart * 0.2,
strength.decimalPart * 0.2,
defense.decimalPart * 0.2,
ranged.decimalPart * 0.2,
magic.decimalPart * 0.2
];
const list2 = [
endurance.decimalPart * 0.2,
intelligence.decimalPart * 0.2,
attack.decimalPart * 0.2,
strength.decimalPart * 0.2,
defense.decimalPart * 0.2,
ranged.decimalPart * 0.2,
magic.decimalPart * 0.2,
ranged.decimalPart * 0.2,
magic.decimalPart * 0.2
];
//console.log("list1",list1,"\nlist2",list2)
list1.sort((a, b) => b - a);
list2.sort((a, b) => b - a);
if (decimalPart === 0.8) {
combatLevel += list1[0];
} else {
let total = 0;
const maxIterations = Math.floor((1 - decimalPart) / 0.2);
let iterations = 0;
for (const i of list2) {
if (iterations >= maxIterations) break;
if ((decimalPart + total + i) < 1) {
total += i;
} else {
break;
}
iterations++;
}
combatLevel = decimalPart + integerPart + total;
}
elements[15].parentNode.parentNode.parentNode.parentNode.parentNode.querySelector(".NavigationBar_nav__3uuUl .NavigationBar_level__3C7eR").textContent = combatLevel.toFixed(2);
}
};
window.setInterval(updateCombatLevel, 10000);
function OfflineStatistics(modalElement) {
const itemsContainer = modalElement.querySelectorAll(".OfflineProgressModal_itemList__26h-Y");
let timeContainer = null;
let getItemContainer = null;
let spendItemContainer = null;
itemsContainer.forEach(container => {
const labelElement = container.querySelector('.OfflineProgressModal_label__2HwFG');
if (labelElement) {
const textContent = labelElement.textContent.trim();
if (textContent.startsWith("Offline duration") || textContent.startsWith("你离线了") || textContent.startsWith("离线时间")) {
timeContainer = container;
} else if (textContent.startsWith("Items gained") || textContent.startsWith("获得物品:") || textContent.startsWith("获得物品")) {
getItemContainer = container;
} else if (textContent.startsWith("Items consumed") || textContent.startsWith("你消耗了:") || textContent.startsWith("消耗物品")) {
spendItemContainer = container;
}
}
});
let TotalSec = null;
if (timeContainer) {
const textContent = timeContainer.textContent;
const match = textContent.match(/(?:(\d+)d\s*)?(?:(\d+)h\s*)?(?:(\d+)m\s*)?(?:(\d+)s)/);
if (match) {
let days = parseInt(match[1], 10) || 0;
let hours = parseInt(match[2], 10) || 0;
let minutes = parseInt(match[3], 10) || 0;
let seconds = parseInt(match[4], 10) || 0;
TotalSec = days * 86400 + hours * 3600 + minutes * 60 + seconds;
}
}
let getitemtotalAskValue = 0;
let getitemtotalBidValue = 0;
if (getItemContainer) {
const getitemElements = getItemContainer.querySelectorAll('.Item_itemContainer__x7kH1');
const { totalAskValue, totalBidValue } = calculateTotalValues(getitemElements);
getitemtotalAskValue = totalAskValue;
getitemtotalBidValue = totalBidValue;
}
let spenditemtotalAskValue = 0;
let spenditemtotalBidValue = 0;
if (spendItemContainer) {
const spenditemElements = spendItemContainer.querySelectorAll('.Item_itemContainer__x7kH1');
const { totalAskValue, totalBidValue } = calculateTotalValues(spenditemElements);
spenditemtotalAskValue = totalAskValue;
spenditemtotalBidValue = totalBidValue;
}
if (timeContainer) {
const newElement = document.createElement('span');
newElement.textContent = `利润: ${formatPrice(getitemtotalBidValue - spenditemtotalAskValue,10)} [${formatPrice((getitemtotalBidValue - spenditemtotalAskValue) / (TotalSec / 3600) * 24,10)}/天]`;
newElement.style.color = 'gold';
newElement.style.whiteSpace = 'nowrap';
newElement.style.marginLeft = 'auto';
timeContainer.querySelector(':first-child').appendChild(newElement);
}
if (getItemContainer) {
const newElement = document.createElement('span');
newElement.textContent = `产出:[${formatPrice(getitemtotalAskValue)}/${formatPrice(getitemtotalBidValue)}]`;
newElement.style.float = 'right';
newElement.style.color = 'gold';
newElement.style.whiteSpace = 'nowrap';
getItemContainer.querySelector(':first-child').appendChild(newElement);
}
if (spendItemContainer) {
const newElement = document.createElement('span');
newElement.textContent = `成本:[${formatPrice(spenditemtotalAskValue)}/${formatPrice(spenditemtotalBidValue)}]`;
newElement.style.float = 'right';
newElement.style.color = 'gold';
newElement.style.whiteSpace = 'nowrap';
spendItemContainer.querySelector(':first-child').appendChild(newElement);
}
}
function initObserver() {
// 选择要观察的目标节点
const targetNode = document.body;
// 观察器的配置(需要观察子节点的变化)
const config = { childList: true, subtree: true };
// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(mutationsList => {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
// 监听到子节点变化
mutation.addedNodes.forEach(addedNode => {
// 检查是否是我们关注的 Modal_modalContainer__3B80m 元素被添加
if (addedNode.classList && addedNode.classList.contains('Modal_modalContainer__3B80m')) {
// Modal_modalContainer__3B80m 元素被添加,执行处理函数
//console.log("箱子被打开")
ShowChestPrice();
recordChestOpening(addedNode);
// 开始监听箱子图标的变化
startIconObserver();
}
if (addedNode.classList && addedNode.classList.contains('OfflineProgressModal_modalContainer__knnk7')) {
OfflineStatistics(addedNode);
console.log("离线报告已创建!")
}
if (addedNode.classList && addedNode.classList.contains('MainPanel_subPanelContainer__1i-H9')) {
if (addedNode.querySelector(".CombatPanel_combatPanel__QylPo")) {
addBattlePlayerFoodButton();
addBattlePlayerLootButton();
} else if (addedNode.querySelector('.EnhancingPanel_enhancingPanel__ysWpV')) {
updateEnhancementUI();
}
}
});
mutation.removedNodes.forEach(removedNode => {
// 检查是否是 Modal_modalContainer__3B80m 元素被移除
if (removedNode.classList && removedNode.classList.contains('Modal_modalContainer__3B80m')) {
// Modal_modalContainer__3B80m 元素被移除,停止监听箱子图标的变化
stopIconObserver();
}
});
}
}
});
// 以上述配置开始观察目标节点
observer.observe(targetNode, config);
// 定义箱子图标变化的观察器
let iconObserver = null;
// 开始监听箱子图标的变化
function startIconObserver() {
const chestNameElem = document.querySelector(chestNameSelector);
if (!chestNameElem) return;
// 创建一个观察器实例来监听图标的变化
iconObserver = new MutationObserver(() => {
// 当箱子图标变化时,执行处理函数
ShowChestPrice();
});
// 配置观察器的选项
const iconConfig = { attributes: true, attributeFilter: ['href'] };
// 以上述配置开始观察箱子图标节点
iconObserver.observe(chestNameElem, iconConfig);
}
// 停止监听箱子图标的变化
function stopIconObserver() {
if (iconObserver) {
iconObserver.disconnect();
iconObserver = null;
}
}
}
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.indexOf("api.milkywayidle.com/ws") <= -1 && socket.url.indexOf("api-test.milkywayidle.com/ws") <= -1) {
return oriGet.call(this);
}
const message = oriGet.call(this);
Object.defineProperty(this, "data", { value: message }); // Anti-loop
return handleMessage(message);
}
}
function addStatisticsButton() {
const waitForNavi = () => {
const targetNode = document.querySelector("div.NavigationBar_minorNavigationLinks__dbxh7");
if (targetNode) {
// 创建统计窗口按钮
let statsButton = document.createElement("div");
statsButton.setAttribute("class", "NavigationBar_minorNavigationLink__31K7Y");
statsButton.style.color = "gold";
statsButton.innerHTML = isCN ? "开箱统计" : "Chest Statistics";
statsButton.addEventListener("click", () => {
const edibleTools = JSON.parse(localStorage.getItem('Edible_Tools')) || {};
const openChestData = edibleTools.Chest_Open_Data || {};
createVisualizationWindow(openChestData);
});
// 创建食用工具按钮
let edibleToolsButton = document.createElement("div");
edibleToolsButton.setAttribute("class", "NavigationBar_minorNavigationLink__31K7Y");
edibleToolsButton.style.color = "gold";
edibleToolsButton.innerHTML = "食用工具";
edibleToolsButton.addEventListener("click", () => {
openSettings();
});
// 将按钮添加到目标节点
targetNode.insertAdjacentElement("afterbegin", statsButton);
targetNode.insertAdjacentElement("afterbegin", edibleToolsButton);
//获取图标url格式模板
item_icon_url = document.querySelector("div[class^='Item_itemContainer'] use")?.getAttribute("href")?.split("#")[0];
addBattlePlayerFoodButton();
addBattlePlayerLootButton();
} else {
setTimeout(waitForNavi, 200);
}
};
waitForNavi(); // 开始等待目标节点出现
}
//奶牛钉钉
function handleMessage(message) {
try {
let obj = JSON.parse(message);
if (obj && obj.type === "new_battle") {
processCombatConsumables(obj);
} else if (obj && obj.type === "init_character_data") {
now_battle_map = undefined;
processCharacterData(obj);
addStatisticsButton();
update_market_list(obj);
} else if (obj && obj.type === "action_completed" && obj.endCharacterAction) {
const actionHrid = obj.endCharacterAction.actionHrid;
if (actionHrid === "/actions/enhancing/enhance") {
processEnhancementData(obj);
} else if (actionHrid.startsWith("/actions/combat/")) {
now_battle_map = actionHrid;
}
} else if (obj && obj.type === "guild_updated") {
const Guild_ID = obj.guild.id;
const edibleTools = JSON.parse(localStorage.getItem('Edible_Tools')) || {};
edibleTools.Guild_Data = edibleTools.Guild_Data || {};
let storedData = edibleTools.Guild_Data || {};
// 判断是否已经存在旧数据
if (storedData[Guild_ID] && storedData[Guild_ID].guild_updated && storedData[Guild_ID].guild_updated.old.updatedAt) {
const oldUpdatedAt = new Date(storedData[Guild_ID].guild_updated.new.updatedAt);
const newUpdatedAt = new Date(obj.guild.updatedAt);
// 计算时间差(单位:毫秒)
const timeDifference = newUpdatedAt - oldUpdatedAt;
if (timeDifference >= updataDealy) {
// 更新老数据为新数据
storedData[Guild_ID].guild_updated.old = storedData[Guild_ID].guild_updated.new;
// 更新新数据为当前数据
storedData[Guild_ID].guild_updated.new = {
experience: obj.guild.experience,
level: obj.guild.level,
updatedAt: obj.guild.updatedAt
};
} else {
// 仅更新新数据
storedData[Guild_ID].guild_updated.new = {
experience: obj.guild.experience,
level: obj.guild.level,
updatedAt: obj.guild.updatedAt
};
}
//计算Δ
const Delta = {
Delta_Xp: storedData[Guild_ID].guild_updated.new.experience - storedData[Guild_ID].guild_updated.old.experience,
Delta_Level: storedData[Guild_ID].guild_updated.new.level - storedData[Guild_ID].guild_updated.old.level,
Delta_Time: (newUpdatedAt - new Date(storedData[Guild_ID].guild_updated.old.updatedAt)) / 1000, // 转换为秒
Rate_XP_Hours: (3600*(obj.guild.experience - storedData[Guild_ID].guild_updated.old.experience)/((newUpdatedAt - new Date(storedData[Guild_ID].guild_updated.old.updatedAt)) / 1000)).toFixed(2)
};
storedData[Guild_ID].guild_updated.Delta = Delta;
const Guild_TotalXp_div = document.querySelectorAll(".GuildPanel_value__Hm2I9")[1];
if (Guild_TotalXp_div) {
const xpText = isCN ? "经验值 / 小时" : "XP / Hour";
Guild_TotalXp_div.insertAdjacentHTML(
"afterend",
`
剩余时间: ${timeDisplay}
光环: ${transferAuraName}
${item}: ${lootItems[item].数量}
`; } } if (totalPrice > 0) { dataHtml += `总计价格: ${formatPrice(totalPrice)}
`; } dataHtml += '订单ID | 角色ID | 状态 | 类型 | 物品 | 数量 | 已交易数量 | 单价 | 贸易额 | 更新时间 | 操作 |
---|