// ==UserScript==
// @name mooket
// @namespace http://tampermonkey.net/
// @version 20250425.4.3
// @description 银河奶牛历史价格(包含强化物品)history(enhancement included) price for milkywayidle
// @author IOMisaka
// @match https://www.milkywayidle.com/*
// @match https://test.milkywayidle.com/*
// @icon https://www.milkywayidle.com/favicon.svg
// @grant none
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js
// @run-at document-start
// @license MIT
// ==/UserScript==
(function () {
'use strict';
let injectSpace = "mwi";//use window.mwi to access the injected object
if (window[injectSpace]) return;//已经注入
let mwi = {//供外部调用的接口
//由于脚本加载问题,注入有可能失败
//修改了hookCallback,添加了回调前和回调后处理
version: "0.4.0",//版本号,未改动原有接口只更新最后一个版本号,更改了接口会更改次版本号,主版本暂时不更新,等稳定之后再考虑主版本号更新
MWICoreInitialized: false,//是否初始化完成,完成会还会通过window发送一个自定义事件 MWICoreInitialized
game: null,//注入游戏对象,可以直接访问游戏中的大量数据和方法以及消息事件等
lang: null,//语言翻译, 例如中文物品lang.zh.translation.itemNames['/items/coin']
buffCalculator: null,//注入buff计算对象buffCalculator.mergeBuffs()合并buffs,计算加成效果等
alchemyCalculator: null,//注入炼金计算对象
//////非注入接口,保证可以使用的功能//////
///需要等待加载完成才能使用
coreMarket: null,//coreMarket.marketData 格式{"/items/apple_yogurt:0":{ask,bid,time}}
initCharacterData: null,
initClientData: JSON.parse(localStorage.getItem("initClientData") || "{}"),
get character() { return this.game?.state?.character || this.initCharacterData?.character },
///不需要等待加载的
get isZh() { return localStorage.getItem("i18nextLng")?.startsWith("zh"); },//是否中文
/* marketJson兼容接口 */
get marketJson() {
return this.MWICoreInitialized && new Proxy(this.coreMarket, {
get(coreMarket, prop) {
if (prop === "market") {
return new Proxy(coreMarket, {
get(coreMarket, itemHridOrName) {
return coreMarket.getItemPrice(itemHridOrName);
}
});
}
return null;
}
});
},
itemNameToHridDict: null,//物品名称反查表
ensureItemHrid: function (itemHridOrName) {
let itemHrid = this.itemNameToHridDict[itemHridOrName];
if (itemHrid) return itemHrid;
if (itemHridOrName?.startsWith("/items/")) return itemHridOrName;
return null;
},//各种名字转itemHrid,找不到返回原itemHrid或者null
getItemDetail: function (itemHrid) {
return this.initClientData?.itemDetailMap && this.initClientData.itemDetailMap[itemHrid];
},
hookMessage: hookMessage,//hook 游戏websocket消息 例如聊天消息mwi.hookMessage("chat_message_received",obj=>{console.log(obj)})
hookCallback: hookCallback,//hook回调,可以hook游戏处理事件调用前后,方便做统计处理? 例如聊天消息mwi.hookCallback("handleMessageChatMessageReceived",obj=>{console.log("before")},obj=>{console.log("after")})
fetchWithTimeout: fetchWithTimeout,//带超时的fetch
};
window[injectSpace] = mwi;
async function patchScript(node) {
try {
const scriptUrl = node.src;
node.remove();
const response = await fetch(scriptUrl);
if (!response.ok) throw new Error(`Failed to fetch script: ${response.status}`);
let sourceCode = await response.text();
// Define injection points as configurable patterns
const injectionPoints = [
{
pattern: "Ca.a.use",
replacement: `window.${injectSpace}.lang=Oa;Ca.a.use`,
description: "注入语言翻译对象"
},
{
pattern: "class lp extends s.a.Component{constructor(e){var t;super(e),t=this,",
replacement: `class lp extends s.a.Component{constructor(e){var t;super(e),t=this,window.${injectSpace}.game=this,`,
description: "注入游戏对象"
},
{
pattern: "var Q=W;",
replacement: `window.${injectSpace}.buffCalculator=W;var Q=W;`,
description: "注入buff计算对象"
},
{
pattern: "class Dn",
replacement: `window.${injectSpace}.alchemyCalculator=Mn;class Dn`,
description: "注入炼金计算对象"
},
{
pattern: "var z=q;",
replacement: `window.${injectSpace}.actionManager=q;var z=q;`,
description: "注入动作管理对象"
}
];
injectionPoints.forEach(({ pattern, replacement, description }) => {
if (sourceCode.includes(pattern)) {
sourceCode = sourceCode.replace(pattern, replacement);
console.info(`MWICore injecting: ${description}`);
} else {
console.warn(`MWICore injecting failed: ${description}`);
}
});
const newNode = document.createElement('script');
newNode.textContent = sourceCode;
document.body.appendChild(newNode);
console.info('MWICore patched successfully.')
} catch (error) {
console.error('MWICore patching failed:', error);
}
}
new MutationObserver((mutationsList, obs) => {
mutationsList.forEach((mutationRecord) => {
for (const node of mutationRecord.addedNodes) {
if (node.src) {
if (node.src.search(/.*main\..*\.chunk.js/) === 0) {
console.info("patching:" + node.src)
obs.disconnect();
patchScript(node);
}
}
}
});
}).observe(document, { childList: true, subtree: true });
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
try {
let obj = JSON.parse(message);
if (obj?.type) {
if (obj.type === "init_character_data") {
mwi.initCharacterData = obj;
} else if (obj.type === "init_client_data") {
mwi.initClientData = obj;
}
dispatchEvent(new CustomEvent("MWI_" + obj.type, { detail: obj }));
}
} catch { console.error("dispatch error."); }
return message;
}
}
hookWS();
/**
* Hook游戏消息在处理之前,随时可用
* @param {string} message.type 消息类型,ws钩子,必定可用,仅在游戏处理之前调用beforeFunc
* @param {Function} beforeFunc 前处理函数
*/
function hookMessage(messageType, beforeFunc) {
if (messageType && beforeFunc) {
//游戏websocket消息hook
addEventListener("MWI_" + messageType, (e) => beforeFunc(e.detail));
} else {
console.warn("messageType or beforeFunc is missing");
}
}
/**
* Hook游戏回调函数,仅在游戏注入成功时可用,会调用beforeFunc和afterFunc
* @param {string} callbackProp 游戏处理回调函数名mwi.game.handleMessage*,仅当注入成功时可用,会调用beforeFunc和afterFunc
* @param {Function} beforeFunc 前处理函数
* @param {Function} afterFunc 后处理函数
*/
function hookCallback(callbackProp, beforeFunc, afterFunc) {
if (callbackProp && mwi?.game) {//优先使用游戏回调hook
const targetObj = mwi.game;
const originalCallback = targetObj[callbackProp];
if (!originalCallback || !targetObj) {
throw new Error(`Callback ${callbackProp} does not exist`);
}
targetObj[callbackProp] = function (...args) {
// 前处理
try {
if (beforeFunc) beforeFunc(...args);
} catch { }
// 原始回调函数调用
const result = originalCallback.apply(this, args);
// 后处理
try {
if (afterFunc) afterFunc(result, ...args);
} catch { }
return result;
};
// 返回取消Hook的方法
return () => {
targetObj[callbackProp] = originalCallback;
};
} else {
console.warn("hookCallback error");
}
}
/**
* 带超时功能的fetch封装
* @param {string} url - 请求URL
* @param {object} options - fetch选项
* @param {number} timeout - 超时时间(毫秒),默认10秒
* @returns {Promise} - 返回fetch的Promise
*/
function fetchWithTimeout(url, options = {}, timeout = 10000) {
// 创建AbortController实例
const controller = new AbortController();
const { signal } = controller;
// 设置超时计时器
const timeoutId = setTimeout(() => {
controller.abort(new Error(`请求超时: ${timeout}ms`));
}, timeout);
// 合并选项,添加signal
const fetchOptions = {
...options,
signal
};
// 发起fetch请求
return fetch(url, fetchOptions)
.then(response => {
// 清除超时计时器
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP错误! 状态码: ${response.status}`);
}
return response;
})
.catch(error => {
// 清除超时计时器
clearTimeout(timeoutId);
// 如果是中止错误,重新抛出超时错误
if (error.name === 'AbortError') {
throw new Error(`请求超时: ${timeout}ms`);
}
throw error;
});
}
function staticInit() {
/*静态初始化,手动提取的游戏数据*/
mwi.lang = {
en: {
translation: {
...{
itemNames: {
'/items/coin': 'Coin',
'/items/task_token': 'Task Token',
'/items/chimerical_token': 'Chimerical Token',
'/items/sinister_token': 'Sinister Token',
'/items/enchanted_token': 'Enchanted Token',
'/items/pirate_token': 'Pirate Token',
'/items/cowbell': 'Cowbell',
'/items/bag_of_10_cowbells': 'Bag Of 10 Cowbells',
'/items/purples_gift': 'Purple\'s Gift',
'/items/small_meteorite_cache': 'Small Meteorite Cache',
'/items/medium_meteorite_cache': 'Medium Meteorite Cache',
'/items/large_meteorite_cache': 'Large Meteorite Cache',
'/items/small_artisans_crate': 'Small Artisan\'s Crate',
'/items/medium_artisans_crate': 'Medium Artisan\'s Crate',
'/items/large_artisans_crate': 'Large Artisan\'s Crate',
'/items/small_treasure_chest': 'Small Treasure Chest',
'/items/medium_treasure_chest': 'Medium Treasure Chest',
'/items/large_treasure_chest': 'Large Treasure Chest',
'/items/chimerical_chest': 'Chimerical Chest',
'/items/sinister_chest': 'Sinister Chest',
'/items/enchanted_chest': 'Enchanted Chest',
'/items/pirate_chest': 'Pirate Chest',
'/items/blue_key_fragment': 'Blue Key Fragment',
'/items/green_key_fragment': 'Green Key Fragment',
'/items/purple_key_fragment': 'Purple Key Fragment',
'/items/white_key_fragment': 'White Key Fragment',
'/items/orange_key_fragment': 'Orange Key Fragment',
'/items/brown_key_fragment': 'Brown Key Fragment',
'/items/stone_key_fragment': 'Stone Key Fragment',
'/items/dark_key_fragment': 'Dark Key Fragment',
'/items/burning_key_fragment': 'Burning Key Fragment',
'/items/chimerical_entry_key': 'Chimerical Entry Key',
'/items/chimerical_chest_key': 'Chimerical Chest Key',
'/items/sinister_entry_key': 'Sinister Entry Key',
'/items/sinister_chest_key': 'Sinister Chest Key',
'/items/enchanted_entry_key': 'Enchanted Entry Key',
'/items/enchanted_chest_key': 'Enchanted Chest Key',
'/items/pirate_entry_key': 'Pirate Entry Key',
'/items/pirate_chest_key': 'Pirate Chest Key',
'/items/donut': 'Donut',
'/items/blueberry_donut': 'Blueberry Donut',
'/items/blackberry_donut': 'Blackberry Donut',
'/items/strawberry_donut': 'Strawberry Donut',
'/items/mooberry_donut': 'Mooberry Donut',
'/items/marsberry_donut': 'Marsberry Donut',
'/items/spaceberry_donut': 'Spaceberry Donut',
'/items/cupcake': 'Cupcake',
'/items/blueberry_cake': 'Blueberry Cake',
'/items/blackberry_cake': 'Blackberry Cake',
'/items/strawberry_cake': 'Strawberry Cake',
'/items/mooberry_cake': 'Mooberry Cake',
'/items/marsberry_cake': 'Marsberry Cake',
'/items/spaceberry_cake': 'Spaceberry Cake',
'/items/gummy': 'Gummy',
'/items/apple_gummy': 'Apple Gummy',
'/items/orange_gummy': 'Orange Gummy',
'/items/plum_gummy': 'Plum Gummy',
'/items/peach_gummy': 'Peach Gummy',
'/items/dragon_fruit_gummy': 'Dragon Fruit Gummy',
'/items/star_fruit_gummy': 'Star Fruit Gummy',
'/items/yogurt': 'Yogurt',
'/items/apple_yogurt': 'Apple Yogurt',
'/items/orange_yogurt': 'Orange Yogurt',
'/items/plum_yogurt': 'Plum Yogurt',
'/items/peach_yogurt': 'Peach Yogurt',
'/items/dragon_fruit_yogurt': 'Dragon Fruit Yogurt',
'/items/star_fruit_yogurt': 'Star Fruit Yogurt',
'/items/milking_tea': 'Milking Tea',
'/items/foraging_tea': 'Foraging Tea',
'/items/woodcutting_tea': 'Woodcutting Tea',
'/items/cooking_tea': 'Cooking Tea',
'/items/brewing_tea': 'Brewing Tea',
'/items/alchemy_tea': 'Alchemy Tea',
'/items/enhancing_tea': 'Enhancing Tea',
'/items/cheesesmithing_tea': 'Cheesesmithing Tea',
'/items/crafting_tea': 'Crafting Tea',
'/items/tailoring_tea': 'Tailoring Tea',
'/items/super_milking_tea': 'Super Milking Tea',
'/items/super_foraging_tea': 'Super Foraging Tea',
'/items/super_woodcutting_tea': 'Super Woodcutting Tea',
'/items/super_cooking_tea': 'Super Cooking Tea',
'/items/super_brewing_tea': 'Super Brewing Tea',
'/items/super_alchemy_tea': 'Super Alchemy Tea',
'/items/super_enhancing_tea': 'Super Enhancing Tea',
'/items/super_cheesesmithing_tea': 'Super Cheesesmithing Tea',
'/items/super_crafting_tea': 'Super Crafting Tea',
'/items/super_tailoring_tea': 'Super Tailoring Tea',
'/items/ultra_milking_tea': 'Ultra Milking Tea',
'/items/ultra_foraging_tea': 'Ultra Foraging Tea',
'/items/ultra_woodcutting_tea': 'Ultra Woodcutting Tea',
'/items/ultra_cooking_tea': 'Ultra Cooking Tea',
'/items/ultra_brewing_tea': 'Ultra Brewing Tea',
'/items/ultra_alchemy_tea': 'Ultra Alchemy Tea',
'/items/ultra_enhancing_tea': 'Ultra Enhancing Tea',
'/items/ultra_cheesesmithing_tea': 'Ultra Cheesesmithing Tea',
'/items/ultra_crafting_tea': 'Ultra Crafting Tea',
'/items/ultra_tailoring_tea': 'Ultra Tailoring Tea',
'/items/gathering_tea': 'Gathering Tea',
'/items/gourmet_tea': 'Gourmet Tea',
'/items/wisdom_tea': 'Wisdom Tea',
'/items/processing_tea': 'Processing Tea',
'/items/efficiency_tea': 'Efficiency Tea',
'/items/artisan_tea': 'Artisan Tea',
'/items/catalytic_tea': 'Catalytic Tea',
'/items/blessed_tea': 'Blessed Tea',
'/items/stamina_coffee': 'Stamina Coffee',
'/items/intelligence_coffee': 'Intelligence Coffee',
'/items/defense_coffee': 'Defense Coffee',
'/items/attack_coffee': 'Attack Coffee',
'/items/power_coffee': 'Power Coffee',
'/items/ranged_coffee': 'Ranged Coffee',
'/items/magic_coffee': 'Magic Coffee',
'/items/super_stamina_coffee': 'Super Stamina Coffee',
'/items/super_intelligence_coffee': 'Super Intelligence Coffee',
'/items/super_defense_coffee': 'Super Defense Coffee',
'/items/super_attack_coffee': 'Super Attack Coffee',
'/items/super_power_coffee': 'Super Power Coffee',
'/items/super_ranged_coffee': 'Super Ranged Coffee',
'/items/super_magic_coffee': 'Super Magic Coffee',
'/items/ultra_stamina_coffee': 'Ultra Stamina Coffee',
'/items/ultra_intelligence_coffee': 'Ultra Intelligence Coffee',
'/items/ultra_defense_coffee': 'Ultra Defense Coffee',
'/items/ultra_attack_coffee': 'Ultra Attack Coffee',
'/items/ultra_power_coffee': 'Ultra Power Coffee',
'/items/ultra_ranged_coffee': 'Ultra Ranged Coffee',
'/items/ultra_magic_coffee': 'Ultra Magic Coffee',
'/items/wisdom_coffee': 'Wisdom Coffee',
'/items/lucky_coffee': 'Lucky Coffee',
'/items/swiftness_coffee': 'Swiftness Coffee',
'/items/channeling_coffee': 'Channeling Coffee',
'/items/critical_coffee': 'Critical Coffee',
'/items/poke': 'Poke',
'/items/impale': 'Impale',
'/items/puncture': 'Puncture',
'/items/penetrating_strike': 'Penetrating Strike',
'/items/scratch': 'Scratch',
'/items/cleave': 'Cleave',
'/items/maim': 'Maim',
'/items/crippling_slash': 'Crippling Slash',
'/items/smack': 'Smack',
'/items/sweep': 'Sweep',
'/items/stunning_blow': 'Stunning Blow',
'/items/fracturing_impact': 'Fracturing Impact',
'/items/shield_bash': 'Shield Bash',
'/items/quick_shot': 'Quick Shot',
'/items/aqua_arrow': 'Aqua Arrow',
'/items/flame_arrow': 'Flame Arrow',
'/items/rain_of_arrows': 'Rain Of Arrows',
'/items/silencing_shot': 'Silencing Shot',
'/items/steady_shot': 'Steady Shot',
'/items/pestilent_shot': 'Pestilent Shot',
'/items/penetrating_shot': 'Penetrating Shot',
'/items/water_strike': 'Water Strike',
'/items/ice_spear': 'Ice Spear',
'/items/frost_surge': 'Frost Surge',
'/items/mana_spring': 'Mana Spring',
'/items/entangle': 'Entangle',
'/items/toxic_pollen': 'Toxic Pollen',
'/items/natures_veil': 'Nature\'s Veil',
'/items/life_drain': 'Life Drain',
'/items/fireball': 'Fireball',
'/items/flame_blast': 'Flame Blast',
'/items/firestorm': 'Firestorm',
'/items/smoke_burst': 'Smoke Burst',
'/items/minor_heal': 'Minor Heal',
'/items/heal': 'Heal',
'/items/quick_aid': 'Quick Aid',
'/items/rejuvenate': 'Rejuvenate',
'/items/taunt': 'Taunt',
'/items/provoke': 'Provoke',
'/items/toughness': 'Toughness',
'/items/elusiveness': 'Elusiveness',
'/items/precision': 'Precision',
'/items/berserk': 'Berserk',
'/items/elemental_affinity': 'Elemental Affinity',
'/items/frenzy': 'Frenzy',
'/items/spike_shell': 'Spike Shell',
'/items/arcane_reflection': 'Arcane Reflection',
'/items/vampirism': 'Vampirism',
'/items/revive': 'Revive',
'/items/insanity': 'Insanity',
'/items/invincible': 'Invincible',
'/items/fierce_aura': 'Fierce Aura',
'/items/aqua_aura': 'Aqua Aura',
'/items/sylvan_aura': 'Sylvan Aura',
'/items/flame_aura': 'Flame Aura',
'/items/speed_aura': 'Speed Aura',
'/items/critical_aura': 'Critical Aura',
'/items/gobo_stabber': 'Gobo Stabber',
'/items/gobo_slasher': 'Gobo Slasher',
'/items/gobo_smasher': 'Gobo Smasher',
'/items/spiked_bulwark': 'Spiked Bulwark',
'/items/werewolf_slasher': 'Werewolf Slasher',
'/items/griffin_bulwark': 'Griffin Bulwark',
'/items/gobo_shooter': 'Gobo Shooter',
'/items/vampiric_bow': 'Vampiric Bow',
'/items/cursed_bow': 'Cursed Bow',
'/items/gobo_boomstick': 'Gobo Boomstick',
'/items/cheese_bulwark': 'Cheese Bulwark',
'/items/verdant_bulwark': 'Verdant Bulwark',
'/items/azure_bulwark': 'Azure Bulwark',
'/items/burble_bulwark': 'Burble Bulwark',
'/items/crimson_bulwark': 'Crimson Bulwark',
'/items/rainbow_bulwark': 'Rainbow Bulwark',
'/items/holy_bulwark': 'Holy Bulwark',
'/items/wooden_bow': 'Wooden Bow',
'/items/birch_bow': 'Birch Bow',
'/items/cedar_bow': 'Cedar Bow',
'/items/purpleheart_bow': 'Purpleheart Bow',
'/items/ginkgo_bow': 'Ginkgo Bow',
'/items/redwood_bow': 'Redwood Bow',
'/items/arcane_bow': 'Arcane Bow',
'/items/stalactite_spear': 'Stalactite Spear',
'/items/granite_bludgeon': 'Granite Bludgeon',
'/items/furious_spear': 'Furious Spear',
'/items/regal_sword': 'Regal Sword',
'/items/chaotic_flail': 'Chaotic Flail',
'/items/soul_hunter_crossbow': 'Soul Hunter Crossbow',
'/items/sundering_crossbow': 'Sundering Crossbow',
'/items/frost_staff': 'Frost Staff',
'/items/infernal_battlestaff': 'Infernal Battlestaff',
'/items/jackalope_staff': 'Jackalope Staff',
'/items/rippling_trident': 'Rippling Trident',
'/items/blooming_trident': 'Blooming Trident',
'/items/blazing_trident': 'Blazing Trident',
'/items/cheese_sword': 'Cheese Sword',
'/items/verdant_sword': 'Verdant Sword',
'/items/azure_sword': 'Azure Sword',
'/items/burble_sword': 'Burble Sword',
'/items/crimson_sword': 'Crimson Sword',
'/items/rainbow_sword': 'Rainbow Sword',
'/items/holy_sword': 'Holy Sword',
'/items/cheese_spear': 'Cheese Spear',
'/items/verdant_spear': 'Verdant Spear',
'/items/azure_spear': 'Azure Spear',
'/items/burble_spear': 'Burble Spear',
'/items/crimson_spear': 'Crimson Spear',
'/items/rainbow_spear': 'Rainbow Spear',
'/items/holy_spear': 'Holy Spear',
'/items/cheese_mace': 'Cheese Mace',
'/items/verdant_mace': 'Verdant Mace',
'/items/azure_mace': 'Azure Mace',
'/items/burble_mace': 'Burble Mace',
'/items/crimson_mace': 'Crimson Mace',
'/items/rainbow_mace': 'Rainbow Mace',
'/items/holy_mace': 'Holy Mace',
'/items/wooden_crossbow': 'Wooden Crossbow',
'/items/birch_crossbow': 'Birch Crossbow',
'/items/cedar_crossbow': 'Cedar Crossbow',
'/items/purpleheart_crossbow': 'Purpleheart Crossbow',
'/items/ginkgo_crossbow': 'Ginkgo Crossbow',
'/items/redwood_crossbow': 'Redwood Crossbow',
'/items/arcane_crossbow': 'Arcane Crossbow',
'/items/wooden_water_staff': 'Wooden Water Staff',
'/items/birch_water_staff': 'Birch Water Staff',
'/items/cedar_water_staff': 'Cedar Water Staff',
'/items/purpleheart_water_staff': 'Purpleheart Water Staff',
'/items/ginkgo_water_staff': 'Ginkgo Water Staff',
'/items/redwood_water_staff': 'Redwood Water Staff',
'/items/arcane_water_staff': 'Arcane Water Staff',
'/items/wooden_nature_staff': 'Wooden Nature Staff',
'/items/birch_nature_staff': 'Birch Nature Staff',
'/items/cedar_nature_staff': 'Cedar Nature Staff',
'/items/purpleheart_nature_staff': 'Purpleheart Nature Staff',
'/items/ginkgo_nature_staff': 'Ginkgo Nature Staff',
'/items/redwood_nature_staff': 'Redwood Nature Staff',
'/items/arcane_nature_staff': 'Arcane Nature Staff',
'/items/wooden_fire_staff': 'Wooden Fire Staff',
'/items/birch_fire_staff': 'Birch Fire Staff',
'/items/cedar_fire_staff': 'Cedar Fire Staff',
'/items/purpleheart_fire_staff': 'Purpleheart Fire Staff',
'/items/ginkgo_fire_staff': 'Ginkgo Fire Staff',
'/items/redwood_fire_staff': 'Redwood Fire Staff',
'/items/arcane_fire_staff': 'Arcane Fire Staff',
'/items/eye_watch': 'Eye Watch',
'/items/snake_fang_dirk': 'Snake Fang Dirk',
'/items/vision_shield': 'Vision Shield',
'/items/gobo_defender': 'Gobo Defender',
'/items/vampire_fang_dirk': 'Vampire Fang Dirk',
'/items/knights_aegis': 'Knight\'s Aegis',
'/items/treant_shield': 'Treant Shield',
'/items/manticore_shield': 'Manticore Shield',
'/items/tome_of_healing': 'Tome Of Healing',
'/items/tome_of_the_elements': 'Tome Of The Elements',
'/items/watchful_relic': 'Watchful Relic',
'/items/bishops_codex': 'Bishop\'s Codex',
'/items/cheese_buckler': 'Cheese Buckler',
'/items/verdant_buckler': 'Verdant Buckler',
'/items/azure_buckler': 'Azure Buckler',
'/items/burble_buckler': 'Burble Buckler',
'/items/crimson_buckler': 'Crimson Buckler',
'/items/rainbow_buckler': 'Rainbow Buckler',
'/items/holy_buckler': 'Holy Buckler',
'/items/wooden_shield': 'Wooden Shield',
'/items/birch_shield': 'Birch Shield',
'/items/cedar_shield': 'Cedar Shield',
'/items/purpleheart_shield': 'Purpleheart Shield',
'/items/ginkgo_shield': 'Ginkgo Shield',
'/items/redwood_shield': 'Redwood Shield',
'/items/arcane_shield': 'Arcane Shield',
'/items/sinister_cape': 'Sinister Cape',
'/items/chimerical_quiver': 'Chimerical Quiver',
'/items/enchanted_cloak': 'Enchanted Cloak',
'/items/red_culinary_hat': 'Red Culinary Hat',
'/items/snail_shell_helmet': 'Snail Shell Helmet',
'/items/vision_helmet': 'Vision Helmet',
'/items/fluffy_red_hat': 'Fluffy Red Hat',
'/items/corsair_helmet': 'Corsair Helmet',
'/items/acrobatic_hood': 'Acrobatic Hood',
'/items/magicians_hat': 'Magician\'s Hat',
'/items/cheese_helmet': 'Cheese Helmet',
'/items/verdant_helmet': 'Verdant Helmet',
'/items/azure_helmet': 'Azure Helmet',
'/items/burble_helmet': 'Burble Helmet',
'/items/crimson_helmet': 'Crimson Helmet',
'/items/rainbow_helmet': 'Rainbow Helmet',
'/items/holy_helmet': 'Holy Helmet',
'/items/rough_hood': 'Rough Hood',
'/items/reptile_hood': 'Reptile Hood',
'/items/gobo_hood': 'Gobo Hood',
'/items/beast_hood': 'Beast Hood',
'/items/umbral_hood': 'Umbral Hood',
'/items/cotton_hat': 'Cotton Hat',
'/items/linen_hat': 'Linen Hat',
'/items/bamboo_hat': 'Bamboo Hat',
'/items/silk_hat': 'Silk Hat',
'/items/radiant_hat': 'Radiant Hat',
'/items/dairyhands_top': 'Dairyhand\'s Top',
'/items/foragers_top': 'Forager\'s Top',
'/items/lumberjacks_top': 'Lumberjack\'s Top',
'/items/cheesemakers_top': 'Cheesemaker\'s Top',
'/items/crafters_top': 'Crafter\'s Top',
'/items/tailors_top': 'Tailor\'s Top',
'/items/chefs_top': 'Chef\'s Top',
'/items/brewers_top': 'Brewer\'s Top',
'/items/alchemists_top': 'Alchemist\'s Top',
'/items/enhancers_top': 'Enhancer\'s Top',
'/items/gator_vest': 'Gator Vest',
'/items/turtle_shell_body': 'Turtle Shell Body',
'/items/colossus_plate_body': 'Colossus Plate Body',
'/items/demonic_plate_body': 'Demonic Plate Body',
'/items/anchorbound_plate_body': 'Anchorbound Plate Body',
'/items/maelstrom_plate_body': 'Maelstrom Plate Body',
'/items/marine_tunic': 'Marine Tunic',
'/items/revenant_tunic': 'Revenant Tunic',
'/items/griffin_tunic': 'Griffin Tunic',
'/items/kraken_tunic': 'Kraken Tunic',
'/items/icy_robe_top': 'Icy Robe Top',
'/items/flaming_robe_top': 'Flaming Robe Top',
'/items/luna_robe_top': 'Luna Robe Top',
'/items/royal_water_robe_top': 'Royal Water Robe Top',
'/items/royal_nature_robe_top': 'Royal Nature Robe Top',
'/items/royal_fire_robe_top': 'Royal Fire Robe Top',
'/items/cheese_plate_body': 'Cheese Plate Body',
'/items/verdant_plate_body': 'Verdant Plate Body',
'/items/azure_plate_body': 'Azure Plate Body',
'/items/burble_plate_body': 'Burble Plate Body',
'/items/crimson_plate_body': 'Crimson Plate Body',
'/items/rainbow_plate_body': 'Rainbow Plate Body',
'/items/holy_plate_body': 'Holy Plate Body',
'/items/rough_tunic': 'Rough Tunic',
'/items/reptile_tunic': 'Reptile Tunic',
'/items/gobo_tunic': 'Gobo Tunic',
'/items/beast_tunic': 'Beast Tunic',
'/items/umbral_tunic': 'Umbral Tunic',
'/items/cotton_robe_top': 'Cotton Robe Top',
'/items/linen_robe_top': 'Linen Robe Top',
'/items/bamboo_robe_top': 'Bamboo Robe Top',
'/items/silk_robe_top': 'Silk Robe Top',
'/items/radiant_robe_top': 'Radiant Robe Top',
'/items/dairyhands_bottoms': 'Dairyhand\'s Bottoms',
'/items/foragers_bottoms': 'Forager\'s Bottoms',
'/items/lumberjacks_bottoms': 'Lumberjack\'s Bottoms',
'/items/cheesemakers_bottoms': 'Cheesemaker\'s Bottoms',
'/items/crafters_bottoms': 'Crafter\'s Bottoms',
'/items/tailors_bottoms': 'Tailor\'s Bottoms',
'/items/chefs_bottoms': 'Chef\'s Bottoms',
'/items/brewers_bottoms': 'Brewer\'s Bottoms',
'/items/alchemists_bottoms': 'Alchemist\'s Bottoms',
'/items/enhancers_bottoms': 'Enhancer\'s Bottoms',
'/items/turtle_shell_legs': 'Turtle Shell Legs',
'/items/colossus_plate_legs': 'Colossus Plate Legs',
'/items/demonic_plate_legs': 'Demonic Plate Legs',
'/items/anchorbound_plate_legs': 'Anchorbound Plate Legs',
'/items/maelstrom_plate_legs': 'Maelstrom Plate Legs',
'/items/marine_chaps': 'Marine Chaps',
'/items/revenant_chaps': 'Revenant Chaps',
'/items/griffin_chaps': 'Griffin Chaps',
'/items/kraken_chaps': 'Kraken Chaps',
'/items/icy_robe_bottoms': 'Icy Robe Bottoms',
'/items/flaming_robe_bottoms': 'Flaming Robe Bottoms',
'/items/luna_robe_bottoms': 'Luna Robe Bottoms',
'/items/royal_water_robe_bottoms': 'Royal Water Robe Bottoms',
'/items/royal_nature_robe_bottoms': 'Royal Nature Robe Bottoms',
'/items/royal_fire_robe_bottoms': 'Royal Fire Robe Bottoms',
'/items/cheese_plate_legs': 'Cheese Plate Legs',
'/items/verdant_plate_legs': 'Verdant Plate Legs',
'/items/azure_plate_legs': 'Azure Plate Legs',
'/items/burble_plate_legs': 'Burble Plate Legs',
'/items/crimson_plate_legs': 'Crimson Plate Legs',
'/items/rainbow_plate_legs': 'Rainbow Plate Legs',
'/items/holy_plate_legs': 'Holy Plate Legs',
'/items/rough_chaps': 'Rough Chaps',
'/items/reptile_chaps': 'Reptile Chaps',
'/items/gobo_chaps': 'Gobo Chaps',
'/items/beast_chaps': 'Beast Chaps',
'/items/umbral_chaps': 'Umbral Chaps',
'/items/cotton_robe_bottoms': 'Cotton Robe Bottoms',
'/items/linen_robe_bottoms': 'Linen Robe Bottoms',
'/items/bamboo_robe_bottoms': 'Bamboo Robe Bottoms',
'/items/silk_robe_bottoms': 'Silk Robe Bottoms',
'/items/radiant_robe_bottoms': 'Radiant Robe Bottoms',
'/items/enchanted_gloves': 'Enchanted Gloves',
'/items/pincer_gloves': 'Pincer Gloves',
'/items/panda_gloves': 'Panda Gloves',
'/items/magnetic_gloves': 'Magnetic Gloves',
'/items/dodocamel_gauntlets': 'Dodocamel Gauntlets',
'/items/sighted_bracers': 'Sighted Bracers',
'/items/marksman_bracers': 'Marksman Bracers',
'/items/chrono_gloves': 'Chrono Gloves',
'/items/cheese_gauntlets': 'Cheese Gauntlets',
'/items/verdant_gauntlets': 'Verdant Gauntlets',
'/items/azure_gauntlets': 'Azure Gauntlets',
'/items/burble_gauntlets': 'Burble Gauntlets',
'/items/crimson_gauntlets': 'Crimson Gauntlets',
'/items/rainbow_gauntlets': 'Rainbow Gauntlets',
'/items/holy_gauntlets': 'Holy Gauntlets',
'/items/rough_bracers': 'Rough Bracers',
'/items/reptile_bracers': 'Reptile Bracers',
'/items/gobo_bracers': 'Gobo Bracers',
'/items/beast_bracers': 'Beast Bracers',
'/items/umbral_bracers': 'Umbral Bracers',
'/items/cotton_gloves': 'Cotton Gloves',
'/items/linen_gloves': 'Linen Gloves',
'/items/bamboo_gloves': 'Bamboo Gloves',
'/items/silk_gloves': 'Silk Gloves',
'/items/radiant_gloves': 'Radiant Gloves',
'/items/collectors_boots': 'Collector\'s Boots',
'/items/shoebill_shoes': 'Shoebill Shoes',
'/items/black_bear_shoes': 'Black Bear Shoes',
'/items/grizzly_bear_shoes': 'Grizzly Bear Shoes',
'/items/polar_bear_shoes': 'Polar Bear Shoes',
'/items/centaur_boots': 'Centaur Boots',
'/items/sorcerer_boots': 'Sorcerer Boots',
'/items/cheese_boots': 'Cheese Boots',
'/items/verdant_boots': 'Verdant Boots',
'/items/azure_boots': 'Azure Boots',
'/items/burble_boots': 'Burble Boots',
'/items/crimson_boots': 'Crimson Boots',
'/items/rainbow_boots': 'Rainbow Boots',
'/items/holy_boots': 'Holy Boots',
'/items/rough_boots': 'Rough Boots',
'/items/reptile_boots': 'Reptile Boots',
'/items/gobo_boots': 'Gobo Boots',
'/items/beast_boots': 'Beast Boots',
'/items/umbral_boots': 'Umbral Boots',
'/items/cotton_boots': 'Cotton Boots',
'/items/linen_boots': 'Linen Boots',
'/items/bamboo_boots': 'Bamboo Boots',
'/items/silk_boots': 'Silk Boots',
'/items/radiant_boots': 'Radiant Boots',
'/items/small_pouch': 'Small Pouch',
'/items/medium_pouch': 'Medium Pouch',
'/items/large_pouch': 'Large Pouch',
'/items/giant_pouch': 'Giant Pouch',
'/items/gluttonous_pouch': 'Gluttonous Pouch',
'/items/guzzling_pouch': 'Guzzling Pouch',
'/items/necklace_of_efficiency': 'Necklace Of Efficiency',
'/items/fighter_necklace': 'Fighter Necklace',
'/items/ranger_necklace': 'Ranger Necklace',
'/items/wizard_necklace': 'Wizard Necklace',
'/items/necklace_of_wisdom': 'Necklace Of Wisdom',
'/items/necklace_of_speed': 'Necklace Of Speed',
'/items/philosophers_necklace': 'Philosopher\'s Necklace',
'/items/earrings_of_gathering': 'Earrings Of Gathering',
'/items/earrings_of_essence_find': 'Earrings Of Essence Find',
'/items/earrings_of_armor': 'Earrings Of Armor',
'/items/earrings_of_regeneration': 'Earrings Of Regeneration',
'/items/earrings_of_resistance': 'Earrings Of Resistance',
'/items/earrings_of_rare_find': 'Earrings Of Rare Find',
'/items/earrings_of_critical_strike': 'Earrings Of Critical Strike',
'/items/philosophers_earrings': 'Philosopher\'s Earrings',
'/items/ring_of_gathering': 'Ring Of Gathering',
'/items/ring_of_essence_find': 'Ring Of Essence Find',
'/items/ring_of_armor': 'Ring Of Armor',
'/items/ring_of_regeneration': 'Ring Of Regeneration',
'/items/ring_of_resistance': 'Ring Of Resistance',
'/items/ring_of_rare_find': 'Ring Of Rare Find',
'/items/ring_of_critical_strike': 'Ring Of Critical Strike',
'/items/philosophers_ring': 'Philosopher\'s Ring',
'/items/basic_task_badge': 'Basic Task Badge',
'/items/advanced_task_badge': 'Advanced Task Badge',
'/items/expert_task_badge': 'Expert Task Badge',
'/items/celestial_brush': 'Celestial Brush',
'/items/cheese_brush': 'Cheese Brush',
'/items/verdant_brush': 'Verdant Brush',
'/items/azure_brush': 'Azure Brush',
'/items/burble_brush': 'Burble Brush',
'/items/crimson_brush': 'Crimson Brush',
'/items/rainbow_brush': 'Rainbow Brush',
'/items/holy_brush': 'Holy Brush',
'/items/celestial_shears': 'Celestial Shears',
'/items/cheese_shears': 'Cheese Shears',
'/items/verdant_shears': 'Verdant Shears',
'/items/azure_shears': 'Azure Shears',
'/items/burble_shears': 'Burble Shears',
'/items/crimson_shears': 'Crimson Shears',
'/items/rainbow_shears': 'Rainbow Shears',
'/items/holy_shears': 'Holy Shears',
'/items/celestial_hatchet': 'Celestial Hatchet',
'/items/cheese_hatchet': 'Cheese Hatchet',
'/items/verdant_hatchet': 'Verdant Hatchet',
'/items/azure_hatchet': 'Azure Hatchet',
'/items/burble_hatchet': 'Burble Hatchet',
'/items/crimson_hatchet': 'Crimson Hatchet',
'/items/rainbow_hatchet': 'Rainbow Hatchet',
'/items/holy_hatchet': 'Holy Hatchet',
'/items/celestial_hammer': 'Celestial Hammer',
'/items/cheese_hammer': 'Cheese Hammer',
'/items/verdant_hammer': 'Verdant Hammer',
'/items/azure_hammer': 'Azure Hammer',
'/items/burble_hammer': 'Burble Hammer',
'/items/crimson_hammer': 'Crimson Hammer',
'/items/rainbow_hammer': 'Rainbow Hammer',
'/items/holy_hammer': 'Holy Hammer',
'/items/celestial_chisel': 'Celestial Chisel',
'/items/cheese_chisel': 'Cheese Chisel',
'/items/verdant_chisel': 'Verdant Chisel',
'/items/azure_chisel': 'Azure Chisel',
'/items/burble_chisel': 'Burble Chisel',
'/items/crimson_chisel': 'Crimson Chisel',
'/items/rainbow_chisel': 'Rainbow Chisel',
'/items/holy_chisel': 'Holy Chisel',
'/items/celestial_needle': 'Celestial Needle',
'/items/cheese_needle': 'Cheese Needle',
'/items/verdant_needle': 'Verdant Needle',
'/items/azure_needle': 'Azure Needle',
'/items/burble_needle': 'Burble Needle',
'/items/crimson_needle': 'Crimson Needle',
'/items/rainbow_needle': 'Rainbow Needle',
'/items/holy_needle': 'Holy Needle',
'/items/celestial_spatula': 'Celestial Spatula',
'/items/cheese_spatula': 'Cheese Spatula',
'/items/verdant_spatula': 'Verdant Spatula',
'/items/azure_spatula': 'Azure Spatula',
'/items/burble_spatula': 'Burble Spatula',
'/items/crimson_spatula': 'Crimson Spatula',
'/items/rainbow_spatula': 'Rainbow Spatula',
'/items/holy_spatula': 'Holy Spatula',
'/items/celestial_pot': 'Celestial Pot',
'/items/cheese_pot': 'Cheese Pot',
'/items/verdant_pot': 'Verdant Pot',
'/items/azure_pot': 'Azure Pot',
'/items/burble_pot': 'Burble Pot',
'/items/crimson_pot': 'Crimson Pot',
'/items/rainbow_pot': 'Rainbow Pot',
'/items/holy_pot': 'Holy Pot',
'/items/celestial_alembic': 'Celestial Alembic',
'/items/cheese_alembic': 'Cheese Alembic',
'/items/verdant_alembic': 'Verdant Alembic',
'/items/azure_alembic': 'Azure Alembic',
'/items/burble_alembic': 'Burble Alembic',
'/items/crimson_alembic': 'Crimson Alembic',
'/items/rainbow_alembic': 'Rainbow Alembic',
'/items/holy_alembic': 'Holy Alembic',
'/items/celestial_enhancer': 'Celestial Enhancer',
'/items/cheese_enhancer': 'Cheese Enhancer',
'/items/verdant_enhancer': 'Verdant Enhancer',
'/items/azure_enhancer': 'Azure Enhancer',
'/items/burble_enhancer': 'Burble Enhancer',
'/items/crimson_enhancer': 'Crimson Enhancer',
'/items/rainbow_enhancer': 'Rainbow Enhancer',
'/items/holy_enhancer': 'Holy Enhancer',
'/items/milk': 'Milk',
'/items/verdant_milk': 'Verdant Milk',
'/items/azure_milk': 'Azure Milk',
'/items/burble_milk': 'Burble Milk',
'/items/crimson_milk': 'Crimson Milk',
'/items/rainbow_milk': 'Rainbow Milk',
'/items/holy_milk': 'Holy Milk',
'/items/cheese': 'Cheese',
'/items/verdant_cheese': 'Verdant Cheese',
'/items/azure_cheese': 'Azure Cheese',
'/items/burble_cheese': 'Burble Cheese',
'/items/crimson_cheese': 'Crimson Cheese',
'/items/rainbow_cheese': 'Rainbow Cheese',
'/items/holy_cheese': 'Holy Cheese',
'/items/log': 'Log',
'/items/birch_log': 'Birch Log',
'/items/cedar_log': 'Cedar Log',
'/items/purpleheart_log': 'Purpleheart Log',
'/items/ginkgo_log': 'Ginkgo Log',
'/items/redwood_log': 'Redwood Log',
'/items/arcane_log': 'Arcane Log',
'/items/lumber': 'Lumber',
'/items/birch_lumber': 'Birch Lumber',
'/items/cedar_lumber': 'Cedar Lumber',
'/items/purpleheart_lumber': 'Purpleheart Lumber',
'/items/ginkgo_lumber': 'Ginkgo Lumber',
'/items/redwood_lumber': 'Redwood Lumber',
'/items/arcane_lumber': 'Arcane Lumber',
'/items/rough_hide': 'Rough Hide',
'/items/reptile_hide': 'Reptile Hide',
'/items/gobo_hide': 'Gobo Hide',
'/items/beast_hide': 'Beast Hide',
'/items/umbral_hide': 'Umbral Hide',
'/items/rough_leather': 'Rough Leather',
'/items/reptile_leather': 'Reptile Leather',
'/items/gobo_leather': 'Gobo Leather',
'/items/beast_leather': 'Beast Leather',
'/items/umbral_leather': 'Umbral Leather',
'/items/cotton': 'Cotton',
'/items/flax': 'Flax',
'/items/bamboo_branch': 'Bamboo Branch',
'/items/cocoon': 'Cocoon',
'/items/radiant_fiber': 'Radiant Fiber',
'/items/cotton_fabric': 'Cotton Fabric',
'/items/linen_fabric': 'Linen Fabric',
'/items/bamboo_fabric': 'Bamboo Fabric',
'/items/silk_fabric': 'Silk Fabric',
'/items/radiant_fabric': 'Radiant Fabric',
'/items/egg': 'Egg',
'/items/wheat': 'Wheat',
'/items/sugar': 'Sugar',
'/items/blueberry': 'Blueberry',
'/items/blackberry': 'Blackberry',
'/items/strawberry': 'Strawberry',
'/items/mooberry': 'Mooberry',
'/items/marsberry': 'Marsberry',
'/items/spaceberry': 'Spaceberry',
'/items/apple': 'Apple',
'/items/orange': 'Orange',
'/items/plum': 'Plum',
'/items/peach': 'Peach',
'/items/dragon_fruit': 'Dragon Fruit',
'/items/star_fruit': 'Star Fruit',
'/items/arabica_coffee_bean': 'Arabica Coffee Bean',
'/items/robusta_coffee_bean': 'Robusta Coffee Bean',
'/items/liberica_coffee_bean': 'Liberica Coffee Bean',
'/items/excelsa_coffee_bean': 'Excelsa Coffee Bean',
'/items/fieriosa_coffee_bean': 'Fieriosa Coffee Bean',
'/items/spacia_coffee_bean': 'Spacia Coffee Bean',
'/items/green_tea_leaf': 'Green Tea Leaf',
'/items/black_tea_leaf': 'Black Tea Leaf',
'/items/burble_tea_leaf': 'Burble Tea Leaf',
'/items/moolong_tea_leaf': 'Moolong Tea Leaf',
'/items/red_tea_leaf': 'Red Tea Leaf',
'/items/emp_tea_leaf': 'Emp Tea Leaf',
'/items/catalyst_of_coinification': 'Catalyst Of Coinification',
'/items/catalyst_of_decomposition': 'Catalyst Of Decomposition',
'/items/catalyst_of_transmutation': 'Catalyst Of Transmutation',
'/items/prime_catalyst': 'Prime Catalyst',
'/items/snake_fang': 'Snake Fang',
'/items/shoebill_feather': 'Shoebill Feather',
'/items/snail_shell': 'Snail Shell',
'/items/crab_pincer': 'Crab Pincer',
'/items/turtle_shell': 'Turtle Shell',
'/items/marine_scale': 'Marine Scale',
'/items/treant_bark': 'Treant Bark',
'/items/centaur_hoof': 'Centaur Hoof',
'/items/luna_wing': 'Luna Wing',
'/items/gobo_rag': 'Gobo Rag',
'/items/goggles': 'Goggles',
'/items/magnifying_glass': 'Magnifying Glass',
'/items/eye_of_the_watcher': 'Eye Of The Watcher',
'/items/icy_cloth': 'Icy Cloth',
'/items/flaming_cloth': 'Flaming Cloth',
'/items/sorcerers_sole': 'Sorcerer\'s Sole',
'/items/chrono_sphere': 'Chrono Sphere',
'/items/frost_sphere': 'Frost Sphere',
'/items/panda_fluff': 'Panda Fluff',
'/items/black_bear_fluff': 'Black Bear Fluff',
'/items/grizzly_bear_fluff': 'Grizzly Bear Fluff',
'/items/polar_bear_fluff': 'Polar Bear Fluff',
'/items/red_panda_fluff': 'Red Panda Fluff',
'/items/magnet': 'Magnet',
'/items/stalactite_shard': 'Stalactite Shard',
'/items/living_granite': 'Living Granite',
'/items/colossus_core': 'Colossus Core',
'/items/vampire_fang': 'Vampire Fang',
'/items/werewolf_claw': 'Werewolf Claw',
'/items/revenant_anima': 'Revenant Anima',
'/items/soul_fragment': 'Soul Fragment',
'/items/infernal_ember': 'Infernal Ember',
'/items/demonic_core': 'Demonic Core',
'/items/griffin_leather': 'Griffin Leather',
'/items/manticore_sting': 'Manticore Sting',
'/items/jackalope_antler': 'Jackalope Antler',
'/items/dodocamel_plume': 'Dodocamel Plume',
'/items/griffin_talon': 'Griffin Talon',
'/items/acrobats_ribbon': 'Acrobat\'s Ribbon',
'/items/magicians_cloth': 'Magician\'s Cloth',
'/items/chaotic_chain': 'Chaotic Chain',
'/items/cursed_ball': 'Cursed Ball',
'/items/royal_cloth': 'Royal Cloth',
'/items/knights_ingot': 'Knight\'s Ingot',
'/items/bishops_scroll': 'Bishop\'s Scroll',
'/items/regal_jewel': 'Regal Jewel',
'/items/sundering_jewel': 'Sundering Jewel',
'/items/marksman_brooch': 'Marksman Brooch',
'/items/corsair_crest': 'Corsair Crest',
'/items/damaged_anchor': 'Damaged Anchor',
'/items/maelstrom_plating': 'Maelstrom Plating',
'/items/kraken_leather': 'Kraken Leather',
'/items/kraken_fang': 'Kraken Fang',
'/items/butter_of_proficiency': 'Butter Of Proficiency',
'/items/thread_of_expertise': 'Thread Of Expertise',
'/items/branch_of_insight': 'Branch Of Insight',
'/items/gluttonous_energy': 'Gluttonous Energy',
'/items/guzzling_energy': 'Guzzling Energy',
'/items/milking_essence': 'Milking Essence',
'/items/foraging_essence': 'Foraging Essence',
'/items/woodcutting_essence': 'Woodcutting Essence',
'/items/cheesesmithing_essence': 'Cheesesmithing Essence',
'/items/crafting_essence': 'Crafting Essence',
'/items/tailoring_essence': 'Tailoring Essence',
'/items/cooking_essence': 'Cooking Essence',
'/items/brewing_essence': 'Brewing Essence',
'/items/alchemy_essence': 'Alchemy Essence',
'/items/enhancing_essence': 'Enhancing Essence',
'/items/swamp_essence': 'Swamp Essence',
'/items/aqua_essence': 'Aqua Essence',
'/items/jungle_essence': 'Jungle Essence',
'/items/gobo_essence': 'Gobo Essence',
'/items/eyessence': 'Eyessence',
'/items/sorcerer_essence': 'Sorcerer Essence',
'/items/bear_essence': 'Bear Essence',
'/items/golem_essence': 'Golem Essence',
'/items/twilight_essence': 'Twilight Essence',
'/items/abyssal_essence': 'Abyssal Essence',
'/items/chimerical_essence': 'Chimerical Essence',
'/items/sinister_essence': 'Sinister Essence',
'/items/enchanted_essence': 'Enchanted Essence',
'/items/pirate_essence': 'Pirate Essence',
'/items/task_crystal': 'Task Crystal',
'/items/star_fragment': 'Star Fragment',
'/items/pearl': 'Pearl',
'/items/amber': 'Amber',
'/items/garnet': 'Garnet',
'/items/jade': 'Jade',
'/items/amethyst': 'Amethyst',
'/items/moonstone': 'Moonstone',
'/items/sunstone': 'Sunstone',
'/items/philosophers_stone': 'Philosopher\'s Stone',
'/items/crushed_pearl': 'Crushed Pearl',
'/items/crushed_amber': 'Crushed Amber',
'/items/crushed_garnet': 'Crushed Garnet',
'/items/crushed_jade': 'Crushed Jade',
'/items/crushed_amethyst': 'Crushed Amethyst',
'/items/crushed_moonstone': 'Crushed Moonstone',
'/items/crushed_sunstone': 'Crushed Sunstone',
'/items/crushed_philosophers_stone': 'Crushed Philosopher\'s Stone',
'/items/shard_of_protection': 'Shard Of Protection',
'/items/mirror_of_protection': 'Mirror Of Protection'
},
}
}
},
zh: {
translation: {
...{
itemNames: {
'/items/coin': '金币',
'/items/task_token': '任务代币',
'/items/chimerical_token': '奇幻代币',
'/items/sinister_token': '阴森代币',
'/items/enchanted_token': '秘法代币',
'/items/pirate_token': '海盗代币',
'/items/cowbell': '牛铃',
'/items/bag_of_10_cowbells': '牛铃袋 (10个)',
'/items/purples_gift': '小紫牛的礼物',
'/items/small_meteorite_cache': '小陨石舱',
'/items/medium_meteorite_cache': '中陨石舱',
'/items/large_meteorite_cache': '大陨石舱',
'/items/small_artisans_crate': '小工匠匣',
'/items/medium_artisans_crate': '中工匠匣',
'/items/large_artisans_crate': '大工匠匣',
'/items/small_treasure_chest': '小宝箱',
'/items/medium_treasure_chest': '中宝箱',
'/items/large_treasure_chest': '大宝箱',
'/items/chimerical_chest': '奇幻宝箱',
'/items/sinister_chest': '阴森宝箱',
'/items/enchanted_chest': '秘法宝箱',
'/items/pirate_chest': '海盗宝箱',
'/items/blue_key_fragment': '蓝色钥匙碎片',
'/items/green_key_fragment': '绿色钥匙碎片',
'/items/purple_key_fragment': '紫色钥匙碎片',
'/items/white_key_fragment': '白色钥匙碎片',
'/items/orange_key_fragment': '橙色钥匙碎片',
'/items/brown_key_fragment': '棕色钥匙碎片',
'/items/stone_key_fragment': '石头钥匙碎片',
'/items/dark_key_fragment': '黑暗钥匙碎片',
'/items/burning_key_fragment': '燃烧钥匙碎片',
'/items/chimerical_entry_key': '奇幻钥匙',
'/items/chimerical_chest_key': '奇幻宝箱钥匙',
'/items/sinister_entry_key': '阴森钥匙',
'/items/sinister_chest_key': '阴森宝箱钥匙',
'/items/enchanted_entry_key': '秘法钥匙',
'/items/enchanted_chest_key': '秘法宝箱钥匙',
'/items/pirate_entry_key': '海盗钥匙',
'/items/pirate_chest_key': '海盗宝箱钥匙',
'/items/donut': '甜甜圈',
'/items/blueberry_donut': '蓝莓甜甜圈',
'/items/blackberry_donut': '黑莓甜甜圈',
'/items/strawberry_donut': '草莓甜甜圈',
'/items/mooberry_donut': '哞莓甜甜圈',
'/items/marsberry_donut': '火星莓甜甜圈',
'/items/spaceberry_donut': '太空莓甜甜圈',
'/items/cupcake': '纸杯蛋糕',
'/items/blueberry_cake': '蓝莓蛋糕',
'/items/blackberry_cake': '黑莓蛋糕',
'/items/strawberry_cake': '草莓蛋糕',
'/items/mooberry_cake': '哞莓蛋糕',
'/items/marsberry_cake': '火星莓蛋糕',
'/items/spaceberry_cake': '太空莓蛋糕',
'/items/gummy': '软糖',
'/items/apple_gummy': '苹果软糖',
'/items/orange_gummy': '橙子软糖',
'/items/plum_gummy': '李子软糖',
'/items/peach_gummy': '桃子软糖',
'/items/dragon_fruit_gummy': '火龙果软糖',
'/items/star_fruit_gummy': '杨桃软糖',
'/items/yogurt': '酸奶',
'/items/apple_yogurt': '苹果酸奶',
'/items/orange_yogurt': '橙子酸奶',
'/items/plum_yogurt': '李子酸奶',
'/items/peach_yogurt': '桃子酸奶',
'/items/dragon_fruit_yogurt': '火龙果酸奶',
'/items/star_fruit_yogurt': '杨桃酸奶',
'/items/milking_tea': '挤奶茶',
'/items/foraging_tea': '采摘茶',
'/items/woodcutting_tea': '伐木茶',
'/items/cooking_tea': '烹饪茶',
'/items/brewing_tea': '冲泡茶',
'/items/alchemy_tea': '炼金茶',
'/items/enhancing_tea': '强化茶',
'/items/cheesesmithing_tea': '奶酪锻造茶',
'/items/crafting_tea': '制作茶',
'/items/tailoring_tea': '缝纫茶',
'/items/super_milking_tea': '超级挤奶茶',
'/items/super_foraging_tea': '超级采摘茶',
'/items/super_woodcutting_tea': '超级伐木茶',
'/items/super_cooking_tea': '超级烹饪茶',
'/items/super_brewing_tea': '超级冲泡茶',
'/items/super_alchemy_tea': '超级炼金茶',
'/items/super_enhancing_tea': '超级强化茶',
'/items/super_cheesesmithing_tea': '超级奶酪锻造茶',
'/items/super_crafting_tea': '超级制作茶',
'/items/super_tailoring_tea': '超级缝纫茶',
'/items/ultra_milking_tea': '究极挤奶茶',
'/items/ultra_foraging_tea': '究极采摘茶',
'/items/ultra_woodcutting_tea': '究极伐木茶',
'/items/ultra_cooking_tea': '究极烹饪茶',
'/items/ultra_brewing_tea': '究极冲泡茶',
'/items/ultra_alchemy_tea': '究极炼金茶',
'/items/ultra_enhancing_tea': '究极强化茶',
'/items/ultra_cheesesmithing_tea': '究极奶酪锻造茶',
'/items/ultra_crafting_tea': '究极制作茶',
'/items/ultra_tailoring_tea': '究极缝纫茶',
'/items/gathering_tea': '采集茶',
'/items/gourmet_tea': '美食茶',
'/items/wisdom_tea': '经验茶',
'/items/processing_tea': '加工茶',
'/items/efficiency_tea': '效率茶',
'/items/artisan_tea': '工匠茶',
'/items/catalytic_tea': '催化茶',
'/items/blessed_tea': '福气茶',
'/items/stamina_coffee': '耐力咖啡',
'/items/intelligence_coffee': '智力咖啡',
'/items/defense_coffee': '防御咖啡',
'/items/attack_coffee': '攻击咖啡',
'/items/power_coffee': '力量咖啡',
'/items/ranged_coffee': '远程咖啡',
'/items/magic_coffee': '魔法咖啡',
'/items/super_stamina_coffee': '超级耐力咖啡',
'/items/super_intelligence_coffee': '超级智力咖啡',
'/items/super_defense_coffee': '超级防御咖啡',
'/items/super_attack_coffee': '超级攻击咖啡',
'/items/super_power_coffee': '超级力量咖啡',
'/items/super_ranged_coffee': '超级远程咖啡',
'/items/super_magic_coffee': '超级魔法咖啡',
'/items/ultra_stamina_coffee': '究极耐力咖啡',
'/items/ultra_intelligence_coffee': '究极智力咖啡',
'/items/ultra_defense_coffee': '究极防御咖啡',
'/items/ultra_attack_coffee': '究极攻击咖啡',
'/items/ultra_power_coffee': '究极力量咖啡',
'/items/ultra_ranged_coffee': '究极远程咖啡',
'/items/ultra_magic_coffee': '究极魔法咖啡',
'/items/wisdom_coffee': '经验咖啡',
'/items/lucky_coffee': '幸运咖啡',
'/items/swiftness_coffee': '迅捷咖啡',
'/items/channeling_coffee': '吟唱咖啡',
'/items/critical_coffee': '暴击咖啡',
'/items/poke': '破胆之刺',
'/items/impale': '透骨之刺',
'/items/puncture': '破甲之刺',
'/items/penetrating_strike': '贯心之刺',
'/items/scratch': '爪影斩',
'/items/cleave': '分裂斩',
'/items/maim': '血刃斩',
'/items/crippling_slash': '致残斩',
'/items/smack': '重碾',
'/items/sweep': '重扫',
'/items/stunning_blow': '重锤',
'/items/fracturing_impact': '碎裂冲击',
'/items/shield_bash': '盾击',
'/items/quick_shot': '快速射击',
'/items/aqua_arrow': '流水箭',
'/items/flame_arrow': '烈焰箭',
'/items/rain_of_arrows': '箭雨',
'/items/silencing_shot': '沉默之箭',
'/items/steady_shot': '稳定射击',
'/items/pestilent_shot': '疫病射击',
'/items/penetrating_shot': '贯穿射击',
'/items/water_strike': '流水冲击',
'/items/ice_spear': '冰枪术',
'/items/frost_surge': '冰霜爆裂',
'/items/mana_spring': '法力喷泉',
'/items/entangle': '缠绕',
'/items/toxic_pollen': '剧毒粉尘',
'/items/natures_veil': '自然菌幕',
'/items/life_drain': '生命吸取',
'/items/fireball': '火球',
'/items/flame_blast': '熔岩爆裂',
'/items/firestorm': '火焰风暴',
'/items/smoke_burst': '烟爆灭影',
'/items/minor_heal': '初级自愈术',
'/items/heal': '自愈术',
'/items/quick_aid': '快速治疗术',
'/items/rejuvenate': '群体治疗术',
'/items/taunt': '嘲讽',
'/items/provoke': '挑衅',
'/items/toughness': '坚韧',
'/items/elusiveness': '闪避',
'/items/precision': '精确',
'/items/berserk': '狂暴',
'/items/elemental_affinity': '元素增幅',
'/items/frenzy': '狂速',
'/items/spike_shell': '尖刺防护',
'/items/arcane_reflection': '奥术反射',
'/items/vampirism': '吸血',
'/items/revive': '复活',
'/items/insanity': '疯狂',
'/items/invincible': '无敌',
'/items/fierce_aura': '物理光环',
'/items/aqua_aura': '流水光环',
'/items/sylvan_aura': '自然光环',
'/items/flame_aura': '火焰光环',
'/items/speed_aura': '速度光环',
'/items/critical_aura': '暴击光环',
'/items/gobo_stabber': '哥布林长剑',
'/items/gobo_slasher': '哥布林关刀',
'/items/gobo_smasher': '哥布林狼牙棒',
'/items/spiked_bulwark': '尖刺重盾',
'/items/werewolf_slasher': '狼人关刀',
'/items/griffin_bulwark': '狮鹫重盾',
'/items/gobo_shooter': '哥布林弹弓',
'/items/vampiric_bow': '吸血弓',
'/items/cursed_bow': '咒怨之弓',
'/items/gobo_boomstick': '哥布林火棍',
'/items/cheese_bulwark': '奶酪重盾',
'/items/verdant_bulwark': '翠绿重盾',
'/items/azure_bulwark': '蔚蓝重盾',
'/items/burble_bulwark': '深紫重盾',
'/items/crimson_bulwark': '绛红重盾',
'/items/rainbow_bulwark': '彩虹重盾',
'/items/holy_bulwark': '神圣重盾',
'/items/wooden_bow': '木弓',
'/items/birch_bow': '桦木弓',
'/items/cedar_bow': '雪松弓',
'/items/purpleheart_bow': '紫心弓',
'/items/ginkgo_bow': '银杏弓',
'/items/redwood_bow': '红杉弓',
'/items/arcane_bow': '神秘弓',
'/items/stalactite_spear': '石钟长枪',
'/items/granite_bludgeon': '花岗岩大棒',
'/items/furious_spear': '狂怒长枪',
'/items/regal_sword': '君王之剑',
'/items/chaotic_flail': '混沌连枷',
'/items/soul_hunter_crossbow': '灵魂猎手弩',
'/items/sundering_crossbow': '裂空之弩',
'/items/frost_staff': '冰霜法杖',
'/items/infernal_battlestaff': '炼狱法杖',
'/items/jackalope_staff': '鹿角兔之杖',
'/items/rippling_trident': '涟漪三叉戟',
'/items/blooming_trident': '绽放三叉戟',
'/items/blazing_trident': '炽焰三叉戟',
'/items/cheese_sword': '奶酪剑',
'/items/verdant_sword': '翠绿剑',
'/items/azure_sword': '蔚蓝剑',
'/items/burble_sword': '深紫剑',
'/items/crimson_sword': '绛红剑',
'/items/rainbow_sword': '彩虹剑',
'/items/holy_sword': '神圣剑',
'/items/cheese_spear': '奶酪长枪',
'/items/verdant_spear': '翠绿长枪',
'/items/azure_spear': '蔚蓝长枪',
'/items/burble_spear': '深紫长枪',
'/items/crimson_spear': '绛红长枪',
'/items/rainbow_spear': '彩虹长枪',
'/items/holy_spear': '神圣长枪',
'/items/cheese_mace': '奶酪钉头锤',
'/items/verdant_mace': '翠绿钉头锤',
'/items/azure_mace': '蔚蓝钉头锤',
'/items/burble_mace': '深紫钉头锤',
'/items/crimson_mace': '绛红钉头锤',
'/items/rainbow_mace': '彩虹钉头锤',
'/items/holy_mace': '神圣钉头锤',
'/items/wooden_crossbow': '木弩',
'/items/birch_crossbow': '桦木弩',
'/items/cedar_crossbow': '雪松弩',
'/items/purpleheart_crossbow': '紫心弩',
'/items/ginkgo_crossbow': '银杏弩',
'/items/redwood_crossbow': '红杉弩',
'/items/arcane_crossbow': '神秘弩',
'/items/wooden_water_staff': '木制水法杖',
'/items/birch_water_staff': '桦木水法杖',
'/items/cedar_water_staff': '雪松水法杖',
'/items/purpleheart_water_staff': '紫心水法杖',
'/items/ginkgo_water_staff': '银杏水法杖',
'/items/redwood_water_staff': '红杉水法杖',
'/items/arcane_water_staff': '神秘水法杖',
'/items/wooden_nature_staff': '木制自然法杖',
'/items/birch_nature_staff': '桦木自然法杖',
'/items/cedar_nature_staff': '雪松自然法杖',
'/items/purpleheart_nature_staff': '紫心自然法杖',
'/items/ginkgo_nature_staff': '银杏自然法杖',
'/items/redwood_nature_staff': '红杉自然法杖',
'/items/arcane_nature_staff': '神秘自然法杖',
'/items/wooden_fire_staff': '木制火法杖',
'/items/birch_fire_staff': '桦木火法杖',
'/items/cedar_fire_staff': '雪松火法杖',
'/items/purpleheart_fire_staff': '紫心火法杖',
'/items/ginkgo_fire_staff': '银杏火法杖',
'/items/redwood_fire_staff': '红杉火法杖',
'/items/arcane_fire_staff': '神秘火法杖',
'/items/eye_watch': '掌上监工',
'/items/snake_fang_dirk': '蛇牙短剑',
'/items/vision_shield': '视觉盾',
'/items/gobo_defender': '哥布林防御者',
'/items/vampire_fang_dirk': '吸血鬼短剑',
'/items/knights_aegis': '骑士盾',
'/items/treant_shield': '树人盾',
'/items/manticore_shield': '蝎狮盾',
'/items/tome_of_healing': '治疗之书',
'/items/tome_of_the_elements': '元素之书',
'/items/watchful_relic': '警戒遗物',
'/items/bishops_codex': '主教法典',
'/items/cheese_buckler': '奶酪圆盾',
'/items/verdant_buckler': '翠绿圆盾',
'/items/azure_buckler': '蔚蓝圆盾',
'/items/burble_buckler': '深紫圆盾',
'/items/crimson_buckler': '绛红圆盾',
'/items/rainbow_buckler': '彩虹圆盾',
'/items/holy_buckler': '神圣圆盾',
'/items/wooden_shield': '木盾',
'/items/birch_shield': '桦木盾',
'/items/cedar_shield': '雪松盾',
'/items/purpleheart_shield': '紫心盾',
'/items/ginkgo_shield': '银杏盾',
'/items/redwood_shield': '红杉盾',
'/items/arcane_shield': '神秘盾',
'/items/sinister_cape': '阴森斗篷',
'/items/chimerical_quiver': '奇幻箭袋',
'/items/enchanted_cloak': '秘法披风',
'/items/red_culinary_hat': '红色厨师帽',
'/items/snail_shell_helmet': '蜗牛壳头盔',
'/items/vision_helmet': '视觉头盔',
'/items/fluffy_red_hat': '蓬松红帽子',
'/items/corsair_helmet': '掠夺者头盔',
'/items/acrobatic_hood': '杂技师兜帽',
'/items/magicians_hat': '魔术师帽',
'/items/cheese_helmet': '奶酪头盔',
'/items/verdant_helmet': '翠绿头盔',
'/items/azure_helmet': '蔚蓝头盔',
'/items/burble_helmet': '深紫头盔',
'/items/crimson_helmet': '绛红头盔',
'/items/rainbow_helmet': '彩虹头盔',
'/items/holy_helmet': '神圣头盔',
'/items/rough_hood': '粗糙兜帽',
'/items/reptile_hood': '爬行动物兜帽',
'/items/gobo_hood': '哥布林兜帽',
'/items/beast_hood': '野兽兜帽',
'/items/umbral_hood': '暗影兜帽',
'/items/cotton_hat': '棉帽',
'/items/linen_hat': '亚麻帽',
'/items/bamboo_hat': '竹帽',
'/items/silk_hat': '丝帽',
'/items/radiant_hat': '光辉帽',
'/items/dairyhands_top': '挤奶工上衣',
'/items/foragers_top': '采摘者上衣',
'/items/lumberjacks_top': '伐木工上衣',
'/items/cheesemakers_top': '奶酪师上衣',
'/items/crafters_top': '工匠上衣',
'/items/tailors_top': '裁缝上衣',
'/items/chefs_top': '厨师上衣',
'/items/brewers_top': '饮品师上衣',
'/items/alchemists_top': '炼金师上衣',
'/items/enhancers_top': '强化师上衣',
'/items/gator_vest': '鳄鱼马甲',
'/items/turtle_shell_body': '龟壳胸甲',
'/items/colossus_plate_body': '巨像胸甲',
'/items/demonic_plate_body': '恶魔胸甲',
'/items/anchorbound_plate_body': '锚定胸甲',
'/items/maelstrom_plate_body': '怒涛胸甲',
'/items/marine_tunic': '海洋皮衣',
'/items/revenant_tunic': '亡灵皮衣',
'/items/griffin_tunic': '狮鹫皮衣',
'/items/kraken_tunic': '克拉肯皮衣',
'/items/icy_robe_top': '冰霜袍服',
'/items/flaming_robe_top': '烈焰袍服',
'/items/luna_robe_top': '月神袍服',
'/items/royal_water_robe_top': '皇家水系袍服',
'/items/royal_nature_robe_top': '皇家自然系袍服',
'/items/royal_fire_robe_top': '皇家火系袍服',
'/items/cheese_plate_body': '奶酪胸甲',
'/items/verdant_plate_body': '翠绿胸甲',
'/items/azure_plate_body': '蔚蓝胸甲',
'/items/burble_plate_body': '深紫胸甲',
'/items/crimson_plate_body': '绛红胸甲',
'/items/rainbow_plate_body': '彩虹胸甲',
'/items/holy_plate_body': '神圣胸甲',
'/items/rough_tunic': '粗糙皮衣',
'/items/reptile_tunic': '爬行动物皮衣',
'/items/gobo_tunic': '哥布林皮衣',
'/items/beast_tunic': '野兽皮衣',
'/items/umbral_tunic': '暗影皮衣',
'/items/cotton_robe_top': '棉布袍服',
'/items/linen_robe_top': '亚麻袍服',
'/items/bamboo_robe_top': '竹袍服',
'/items/silk_robe_top': '丝绸袍服',
'/items/radiant_robe_top': '光辉袍服',
'/items/dairyhands_bottoms': '挤奶工下装',
'/items/foragers_bottoms': '采摘者下装',
'/items/lumberjacks_bottoms': '伐木工下装',
'/items/cheesemakers_bottoms': '奶酪师下装',
'/items/crafters_bottoms': '工匠下装',
'/items/tailors_bottoms': '裁缝下装',
'/items/chefs_bottoms': '厨师下装',
'/items/brewers_bottoms': '饮品师下装',
'/items/alchemists_bottoms': '炼金师下装',
'/items/enhancers_bottoms': '强化师下装',
'/items/turtle_shell_legs': '龟壳腿甲',
'/items/colossus_plate_legs': '巨像腿甲',
'/items/demonic_plate_legs': '恶魔腿甲',
'/items/anchorbound_plate_legs': '锚定腿甲',
'/items/maelstrom_plate_legs': '怒涛腿甲',
'/items/marine_chaps': '航海皮裤',
'/items/revenant_chaps': '亡灵皮裤',
'/items/griffin_chaps': '狮鹫皮裤',
'/items/kraken_chaps': '克拉肯皮裤',
'/items/icy_robe_bottoms': '冰霜袍裙',
'/items/flaming_robe_bottoms': '烈焰袍裙',
'/items/luna_robe_bottoms': '月神袍裙',
'/items/royal_water_robe_bottoms': '皇家水系袍裙',
'/items/royal_nature_robe_bottoms': '皇家自然系袍裙',
'/items/royal_fire_robe_bottoms': '皇家火系袍裙',
'/items/cheese_plate_legs': '奶酪腿甲',
'/items/verdant_plate_legs': '翠绿腿甲',
'/items/azure_plate_legs': '蔚蓝腿甲',
'/items/burble_plate_legs': '深紫腿甲',
'/items/crimson_plate_legs': '绛红腿甲',
'/items/rainbow_plate_legs': '彩虹腿甲',
'/items/holy_plate_legs': '神圣腿甲',
'/items/rough_chaps': '粗糙皮裤',
'/items/reptile_chaps': '爬行动物皮裤',
'/items/gobo_chaps': '哥布林皮裤',
'/items/beast_chaps': '野兽皮裤',
'/items/umbral_chaps': '暗影皮裤',
'/items/cotton_robe_bottoms': '棉袍裙',
'/items/linen_robe_bottoms': '亚麻袍裙',
'/items/bamboo_robe_bottoms': '竹袍裙',
'/items/silk_robe_bottoms': '丝绸袍裙',
'/items/radiant_robe_bottoms': '光辉袍裙',
'/items/enchanted_gloves': '附魔手套',
'/items/pincer_gloves': '蟹钳手套',
'/items/panda_gloves': '熊猫手套',
'/items/magnetic_gloves': '磁力手套',
'/items/dodocamel_gauntlets': '渡渡驼护手',
'/items/sighted_bracers': '瞄准护腕',
'/items/marksman_bracers': '神射护腕',
'/items/chrono_gloves': '时空手套',
'/items/cheese_gauntlets': '奶酪护手',
'/items/verdant_gauntlets': '翠绿护手',
'/items/azure_gauntlets': '蔚蓝护手',
'/items/burble_gauntlets': '深紫护手',
'/items/crimson_gauntlets': '绛红护手',
'/items/rainbow_gauntlets': '彩虹护手',
'/items/holy_gauntlets': '神圣护手',
'/items/rough_bracers': '粗糙护腕',
'/items/reptile_bracers': '爬行动物护腕',
'/items/gobo_bracers': '哥布林护腕',
'/items/beast_bracers': '野兽护腕',
'/items/umbral_bracers': '暗影护腕',
'/items/cotton_gloves': '棉手套',
'/items/linen_gloves': '亚麻手套',
'/items/bamboo_gloves': '竹手套',
'/items/silk_gloves': '丝手套',
'/items/radiant_gloves': '光辉手套',
'/items/collectors_boots': '收藏家靴',
'/items/shoebill_shoes': '鲸头鹳鞋',
'/items/black_bear_shoes': '黑熊鞋',
'/items/grizzly_bear_shoes': '棕熊鞋',
'/items/polar_bear_shoes': '北极熊鞋',
'/items/centaur_boots': '半人马靴',
'/items/sorcerer_boots': '巫师靴',
'/items/cheese_boots': '奶酪靴',
'/items/verdant_boots': '翠绿靴',
'/items/azure_boots': '蔚蓝靴',
'/items/burble_boots': '深紫靴',
'/items/crimson_boots': '绛红靴',
'/items/rainbow_boots': '彩虹靴',
'/items/holy_boots': '神圣靴',
'/items/rough_boots': '粗糙靴',
'/items/reptile_boots': '爬行动物靴',
'/items/gobo_boots': '哥布林靴',
'/items/beast_boots': '野兽靴',
'/items/umbral_boots': '暗影靴',
'/items/cotton_boots': '棉靴',
'/items/linen_boots': '亚麻靴',
'/items/bamboo_boots': '竹靴',
'/items/silk_boots': '丝靴',
'/items/radiant_boots': '光辉靴',
'/items/small_pouch': '小袋子',
'/items/medium_pouch': '中袋子',
'/items/large_pouch': '大袋子',
'/items/giant_pouch': '巨大袋子',
'/items/gluttonous_pouch': '贪食之袋',
'/items/guzzling_pouch': '暴饮之囊',
'/items/necklace_of_efficiency': '效率项链',
'/items/fighter_necklace': '战士项链',
'/items/ranger_necklace': '射手项链',
'/items/wizard_necklace': '巫师项链',
'/items/necklace_of_wisdom': '经验项链',
'/items/necklace_of_speed': '速度项链',
'/items/philosophers_necklace': '贤者项链',
'/items/earrings_of_gathering': '采集耳环',
'/items/earrings_of_essence_find': '精华发现耳环',
'/items/earrings_of_armor': '护甲耳环',
'/items/earrings_of_regeneration': '恢复耳环',
'/items/earrings_of_resistance': '抗性耳环',
'/items/earrings_of_rare_find': '稀有发现耳环',
'/items/earrings_of_critical_strike': '暴击耳环',
'/items/philosophers_earrings': '贤者耳环',
'/items/ring_of_gathering': '采集戒指',
'/items/ring_of_essence_find': '精华发现戒指',
'/items/ring_of_armor': '护甲戒指',
'/items/ring_of_regeneration': '恢复戒指',
'/items/ring_of_resistance': '抗性戒指',
'/items/ring_of_rare_find': '稀有发现戒指',
'/items/ring_of_critical_strike': '暴击戒指',
'/items/philosophers_ring': '贤者戒指',
'/items/basic_task_badge': '基础任务徽章',
'/items/advanced_task_badge': '高级任务徽章',
'/items/expert_task_badge': '专家任务徽章',
'/items/celestial_brush': '星空刷子',
'/items/cheese_brush': '奶酪刷子',
'/items/verdant_brush': '翠绿刷子',
'/items/azure_brush': '蔚蓝刷子',
'/items/burble_brush': '深紫刷子',
'/items/crimson_brush': '绛红刷子',
'/items/rainbow_brush': '彩虹刷子',
'/items/holy_brush': '神圣刷子',
'/items/celestial_shears': '星空剪刀',
'/items/cheese_shears': '奶酪剪刀',
'/items/verdant_shears': '翠绿剪刀',
'/items/azure_shears': '蔚蓝剪刀',
'/items/burble_shears': '深紫剪刀',
'/items/crimson_shears': '绛红剪刀',
'/items/rainbow_shears': '彩虹剪刀',
'/items/holy_shears': '神圣剪刀',
'/items/celestial_hatchet': '星空斧头',
'/items/cheese_hatchet': '奶酪斧头',
'/items/verdant_hatchet': '翠绿斧头',
'/items/azure_hatchet': '蔚蓝斧头',
'/items/burble_hatchet': '深紫斧头',
'/items/crimson_hatchet': '绛红斧头',
'/items/rainbow_hatchet': '彩虹斧头',
'/items/holy_hatchet': '神圣斧头',
'/items/celestial_hammer': '星空锤子',
'/items/cheese_hammer': '奶酪锤子',
'/items/verdant_hammer': '翠绿锤子',
'/items/azure_hammer': '蔚蓝锤子',
'/items/burble_hammer': '深紫锤子',
'/items/crimson_hammer': '绛红锤子',
'/items/rainbow_hammer': '彩虹锤子',
'/items/holy_hammer': '神圣锤子',
'/items/celestial_chisel': '星空凿子',
'/items/cheese_chisel': '奶酪凿子',
'/items/verdant_chisel': '翠绿凿子',
'/items/azure_chisel': '蔚蓝凿子',
'/items/burble_chisel': '深紫凿子',
'/items/crimson_chisel': '绛红凿子',
'/items/rainbow_chisel': '彩虹凿子',
'/items/holy_chisel': '神圣凿子',
'/items/celestial_needle': '星空针',
'/items/cheese_needle': '奶酪针',
'/items/verdant_needle': '翠绿针',
'/items/azure_needle': '蔚蓝针',
'/items/burble_needle': '深紫针',
'/items/crimson_needle': '绛红针',
'/items/rainbow_needle': '彩虹针',
'/items/holy_needle': '神圣针',
'/items/celestial_spatula': '星空锅铲',
'/items/cheese_spatula': '奶酪锅铲',
'/items/verdant_spatula': '翠绿锅铲',
'/items/azure_spatula': '蔚蓝锅铲',
'/items/burble_spatula': '深紫锅铲',
'/items/crimson_spatula': '绛红锅铲',
'/items/rainbow_spatula': '彩虹锅铲',
'/items/holy_spatula': '神圣锅铲',
'/items/celestial_pot': '星空壶',
'/items/cheese_pot': '奶酪壶',
'/items/verdant_pot': '翠绿壶',
'/items/azure_pot': '蔚蓝壶',
'/items/burble_pot': '深紫壶',
'/items/crimson_pot': '绛红壶',
'/items/rainbow_pot': '彩虹壶',
'/items/holy_pot': '神圣壶',
'/items/celestial_alembic': '星空蒸馏器',
'/items/cheese_alembic': '奶酪蒸馏器',
'/items/verdant_alembic': '翠绿蒸馏器',
'/items/azure_alembic': '蔚蓝蒸馏器',
'/items/burble_alembic': '深紫蒸馏器',
'/items/crimson_alembic': '绛红蒸馏器',
'/items/rainbow_alembic': '彩虹蒸馏器',
'/items/holy_alembic': '神圣蒸馏器',
'/items/celestial_enhancer': '星空强化器',
'/items/cheese_enhancer': '奶酪强化器',
'/items/verdant_enhancer': '翠绿强化器',
'/items/azure_enhancer': '蔚蓝强化器',
'/items/burble_enhancer': '深紫强化器',
'/items/crimson_enhancer': '绛红强化器',
'/items/rainbow_enhancer': '彩虹强化器',
'/items/holy_enhancer': '神圣强化器',
'/items/milk': '牛奶',
'/items/verdant_milk': '翠绿牛奶',
'/items/azure_milk': '蔚蓝牛奶',
'/items/burble_milk': '深紫牛奶',
'/items/crimson_milk': '绛红牛奶',
'/items/rainbow_milk': '彩虹牛奶',
'/items/holy_milk': '神圣牛奶',
'/items/cheese': '奶酪',
'/items/verdant_cheese': '翠绿奶酪',
'/items/azure_cheese': '蔚蓝奶酪',
'/items/burble_cheese': '深紫奶酪',
'/items/crimson_cheese': '绛红奶酪',
'/items/rainbow_cheese': '彩虹奶酪',
'/items/holy_cheese': '神圣奶酪',
'/items/log': '原木',
'/items/birch_log': '白桦原木',
'/items/cedar_log': '雪松原木',
'/items/purpleheart_log': '紫心原木',
'/items/ginkgo_log': '银杏原木',
'/items/redwood_log': '红杉原木',
'/items/arcane_log': '神秘原木',
'/items/lumber': '木板',
'/items/birch_lumber': '白桦木板',
'/items/cedar_lumber': '雪松木板',
'/items/purpleheart_lumber': '紫心木板',
'/items/ginkgo_lumber': '银杏木板',
'/items/redwood_lumber': '红杉木板',
'/items/arcane_lumber': '神秘木板',
'/items/rough_hide': '粗糙兽皮',
'/items/reptile_hide': '爬行动物皮',
'/items/gobo_hide': '哥布林皮',
'/items/beast_hide': '野兽皮',
'/items/umbral_hide': '暗影皮',
'/items/rough_leather': '粗糙皮革',
'/items/reptile_leather': '爬行动物皮革',
'/items/gobo_leather': '哥布林皮革',
'/items/beast_leather': '野兽皮革',
'/items/umbral_leather': '暗影皮革',
'/items/cotton': '棉花',
'/items/flax': '亚麻',
'/items/bamboo_branch': '竹子',
'/items/cocoon': '蚕茧',
'/items/radiant_fiber': '光辉纤维',
'/items/cotton_fabric': '棉花布料',
'/items/linen_fabric': '亚麻布料',
'/items/bamboo_fabric': '竹子布料',
'/items/silk_fabric': '丝绸',
'/items/radiant_fabric': '光辉布料',
'/items/egg': '鸡蛋',
'/items/wheat': '小麦',
'/items/sugar': '糖',
'/items/blueberry': '蓝莓',
'/items/blackberry': '黑莓',
'/items/strawberry': '草莓',
'/items/mooberry': '哞莓',
'/items/marsberry': '火星莓',
'/items/spaceberry': '太空莓',
'/items/apple': '苹果',
'/items/orange': '橙子',
'/items/plum': '李子',
'/items/peach': '桃子',
'/items/dragon_fruit': '火龙果',
'/items/star_fruit': '杨桃',
'/items/arabica_coffee_bean': '低级咖啡豆',
'/items/robusta_coffee_bean': '中级咖啡豆',
'/items/liberica_coffee_bean': '高级咖啡豆',
'/items/excelsa_coffee_bean': '特级咖啡豆',
'/items/fieriosa_coffee_bean': '火山咖啡豆',
'/items/spacia_coffee_bean': '太空咖啡豆',
'/items/green_tea_leaf': '绿茶叶',
'/items/black_tea_leaf': '黑茶叶',
'/items/burble_tea_leaf': '紫茶叶',
'/items/moolong_tea_leaf': '哞龙茶叶',
'/items/red_tea_leaf': '红茶叶',
'/items/emp_tea_leaf': '虚空茶叶',
'/items/catalyst_of_coinification': '点金催化剂',
'/items/catalyst_of_decomposition': '分解催化剂',
'/items/catalyst_of_transmutation': '转化催化剂',
'/items/prime_catalyst': '至高催化剂',
'/items/snake_fang': '蛇牙',
'/items/shoebill_feather': '鲸头鹳羽毛',
'/items/snail_shell': '蜗牛壳',
'/items/crab_pincer': '蟹钳',
'/items/turtle_shell': '乌龟壳',
'/items/marine_scale': '海洋鳞片',
'/items/treant_bark': '树皮',
'/items/centaur_hoof': '半人马蹄',
'/items/luna_wing': '月神翼',
'/items/gobo_rag': '哥布林抹布',
'/items/goggles': '护目镜',
'/items/magnifying_glass': '放大镜',
'/items/eye_of_the_watcher': '观察者之眼',
'/items/icy_cloth': '冰霜织物',
'/items/flaming_cloth': '烈焰织物',
'/items/sorcerers_sole': '魔法师鞋底',
'/items/chrono_sphere': '时空球',
'/items/frost_sphere': '冰霜球',
'/items/panda_fluff': '熊猫绒',
'/items/black_bear_fluff': '黑熊绒',
'/items/grizzly_bear_fluff': '棕熊绒',
'/items/polar_bear_fluff': '北极熊绒',
'/items/red_panda_fluff': '小熊猫绒',
'/items/magnet': '磁铁',
'/items/stalactite_shard': '钟乳石碎片',
'/items/living_granite': '花岗岩',
'/items/colossus_core': '巨像核心',
'/items/vampire_fang': '吸血鬼之牙',
'/items/werewolf_claw': '狼人之爪',
'/items/revenant_anima': '亡者之魂',
'/items/soul_fragment': '灵魂碎片',
'/items/infernal_ember': '地狱余烬',
'/items/demonic_core': '恶魔核心',
'/items/griffin_leather': '狮鹫之皮',
'/items/manticore_sting': '蝎狮之刺',
'/items/jackalope_antler': '鹿角兔之角',
'/items/dodocamel_plume': '渡渡驼之翎',
'/items/griffin_talon': '狮鹫之爪',
'/items/acrobats_ribbon': '杂技师彩带',
'/items/magicians_cloth': '魔术师织物',
'/items/chaotic_chain': '混沌锁链',
'/items/cursed_ball': '诅咒之球',
'/items/royal_cloth': '皇家织物',
'/items/knights_ingot': '骑士之锭',
'/items/bishops_scroll': '主教卷轴',
'/items/regal_jewel': '君王宝石',
'/items/sundering_jewel': '裂空宝石',
'/items/marksman_brooch': '神射胸针',
'/items/corsair_crest': '掠夺者徽章',
'/items/damaged_anchor': '破损船锚',
'/items/maelstrom_plating': '怒涛甲片',
'/items/kraken_leather': '克拉肯皮革',
'/items/kraken_fang': '克拉肯之牙',
'/items/butter_of_proficiency': '精通之油',
'/items/thread_of_expertise': '专精之线',
'/items/branch_of_insight': '洞察之枝',
'/items/gluttonous_energy': '贪食能量',
'/items/guzzling_energy': '暴饮能量',
'/items/milking_essence': '挤奶精华',
'/items/foraging_essence': '采摘精华',
'/items/woodcutting_essence': '伐木精华',
'/items/cheesesmithing_essence': '奶酪锻造精华',
'/items/crafting_essence': '制作精华',
'/items/tailoring_essence': '缝纫精华',
'/items/cooking_essence': '烹饪精华',
'/items/brewing_essence': '冲泡精华',
'/items/alchemy_essence': '炼金精华',
'/items/enhancing_essence': '强化精华',
'/items/swamp_essence': '沼泽精华',
'/items/aqua_essence': '海洋精华',
'/items/jungle_essence': '丛林精华',
'/items/gobo_essence': '哥布林精华',
'/items/eyessence': '眼精华',
'/items/sorcerer_essence': '法师精华',
'/items/bear_essence': '熊熊精华',
'/items/golem_essence': '魔像精华',
'/items/twilight_essence': '暮光精华',
'/items/abyssal_essence': '地狱精华',
'/items/chimerical_essence': '奇幻精华',
'/items/sinister_essence': '阴森精华',
'/items/enchanted_essence': '秘法精华',
'/items/pirate_essence': '海盗精华',
'/items/task_crystal': '任务水晶',
'/items/star_fragment': '星光碎片',
'/items/pearl': '珍珠',
'/items/amber': '琥珀',
'/items/garnet': '石榴石',
'/items/jade': '翡翠',
'/items/amethyst': '紫水晶',
'/items/moonstone': '月亮石',
'/items/sunstone': '太阳石',
'/items/philosophers_stone': '贤者之石',
'/items/crushed_pearl': '珍珠碎片',
'/items/crushed_amber': '琥珀碎片',
'/items/crushed_garnet': '石榴石碎片',
'/items/crushed_jade': '翡翠碎片',
'/items/crushed_amethyst': '紫水晶碎片',
'/items/crushed_moonstone': '月亮石碎片',
'/items/crushed_sunstone': '太阳石碎片',
'/items/crushed_philosophers_stone': '贤者之石碎片',
'/items/shard_of_protection': '保护碎片',
'/items/mirror_of_protection': '保护之镜'
}
}
}
}
};
mwi.itemNameToHridDict = {};
Object.entries(mwi.lang.en.translation.itemNames).forEach(([k, v]) => { mwi.itemNameToHridDict[v] = k });
Object.entries(mwi.lang.zh.translation.itemNames).forEach(([k, v]) => { mwi.itemNameToHridDict[v] = k });
}
function injectedInit() {
/*注入成功,使用游戏数据*/
mwi.itemNameToHridDict = {};
Object.entries(mwi.lang.en.translation.itemNames).forEach(([k, v]) => { mwi.itemNameToHridDict[v] = k });
Object.entries(mwi.lang.zh.translation.itemNames).forEach(([k, v]) => { mwi.itemNameToHridDict[v] = k });
mwi.MWICoreInitialized = true;
window.dispatchEvent(new CustomEvent("MWICoreInitialized"))
console.info("MWICoreInitialized");
}
staticInit();
new Promise(resolve => {
let count = 0;
const interval = setInterval(() => {
count++;
if (count > 30) { clearInterval(interval) }//最多等待30秒
if (mwi.game && mwi.lang && mwi?.game?.state?.character?.gameMode) {//等待必须组件加载完毕后再初始化
clearInterval(interval);
resolve();
}
}, 1000);
}).then(() => {
injectedInit();
});
class ReconnectWebSocket {
constructor(url, options = {}) {
this.url = url; // WebSocket 服务器地址
this.reconnectInterval = options.reconnectInterval || 10000; // 重连间隔(默认 5 秒)
this.heartbeatInterval = options.heartbeatInterval || 60000; // 心跳间隔(默认 60 秒)
this.maxReconnectAttempts = options.maxReconnectAttempts || 9999999; // 最大重连次数
this.reconnectAttempts = 0; // 当前重连次数
this.ws = null; // WebSocket 实例
this.heartbeatTimer = null; // 心跳定时器
this.isManualClose = false; // 是否手动关闭连接
// 绑定事件处理器
this.onOpen = options.onOpen || (() => { });
this.onMessage = options.onMessage || (() => { });
this.onClose = options.onClose || (() => { });
this.onError = options.onError || (() => { });
this.connect();
}
// 连接 WebSocket
connect() {
this.ws = new WebSocket(this.url);
// WebSocket 打开事件
this.ws.onopen = () => {
console.info('WebMooket connected');
this.reconnectAttempts = 0; // 重置重连次数
this.startHeartbeat(); // 启动心跳
this.onOpen();
};
// WebSocket 消息事件
this.ws.onmessage = (event) => {
this.onMessage(event.data);
};
// WebSocket 关闭事件
this.ws.onclose = () => {
console.warn('WebMooket disconnected');
this.stopHeartbeat(); // 停止心跳
this.onClose();
if (!this.isManualClose) {
this.reconnect();
}
};
// WebSocket 错误事件
this.ws.onerror = (error) => {
console.error('WebMooket error:', error);
this.onError(error);
};
}
// 启动心跳
startHeartbeat() {
this.heartbeatTimer = setInterval(() => {
if (this.ws.readyState === WebSocket.OPEN) {
//this.ws.send("ping");
}
}, this.heartbeatInterval);
}
// 停止心跳
stopHeartbeat() {
if (this.heartbeatTimer) {
clearInterval(this.heartbeatTimer);
this.heartbeatTimer = null;
}
}
// 自动重连
reconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
console.info(`Reconnecting in ${this.reconnectInterval / 1000} seconds...`);
setTimeout(() => {
this.reconnectAttempts++;
this.connect();
}, this.reconnectInterval);
} else {
console.error('Max reconnection attempts reached');
}
}
// 发送消息
send(data) {
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(data);
} else {
console.warn('WebMooket is not open');
}
}
// 手动关闭连接
close() {
this.isManualClose = true;
this.ws.close();
}
}
/*实时市场模块*/
const HOST = "https://mooket.qi-e.top";
const MWIAPI_URL = "https://raw.githubusercontent.com/holychikenz/MWIApi/main/milkyapi.json";
class CoreMarket {
marketData = {};//市场数据,带强化等级,存储格式{"/items/apple_yogurt:0":{ask,bid,time}}
fetchTimeDict = {};//记录上次API请求时间,防止频繁请求
ttl = 300;//缓存时间,单位秒
trade_ws = null;
constructor() {
//core data
let marketDataStr = localStorage.getItem("MWICore_marketData") || "{}";
this.marketData = JSON.parse(marketDataStr);
//mwiapi data
let mwiapiJsonStr = localStorage.getItem("MWIAPI_JSON") || localStorage.getItem("MWITools_marketAPI_json");
let mwiapiObj = null;
if (mwiapiJsonStr) {
mwiapiObj = JSON.parse(mwiapiJsonStr);
this.mergeMWIData(mwiapiObj);
}
if (!mwiapiObj || Date.now() / 1000 - mwiapiObj.time > 600) {//超过10分才更新
fetch(MWIAPI_URL).then(res => {
res.text().then(mwiapiJsonStr => {
mwiapiObj = JSON.parse(mwiapiJsonStr);
this.mergeMWIData(mwiapiObj);
//更新本地缓存数据
localStorage.setItem("MWIAPI_JSON", mwiapiJsonStr);//更新本地缓存数据
console.info("MWIAPI_JSON updated:", new Date(mwiapiObj.time * 1000).toLocaleString());
})
});
}
//市场数据更新
hookMessage("market_item_order_books_updated", obj => this.handleMessageMarketItemOrderBooksUpdated(obj, true));
hookMessage("init_character_data", (msg) => {
if (msg.character.gameMode === "standard") {//标准模式才连接ws服务器,铁牛模式不连接ws服务器)
if (!this.trade_ws) {
this.trade_ws = new ReconnectWebSocket(`${HOST}/market/ws`);
this.trade_ws.onMessage = (data) => {
if (data === "ping") { return; }//心跳包,忽略
let obj = JSON.parse(data);
if (obj && obj.type === "market_item_order_books_updated") {
this.handleMessageMarketItemOrderBooksUpdated(obj, false);//收到市场服务器数据,不上传
} else if (obj && obj.type === "ItemPrice") {
this.processItemPrice(obj);
} else {
console.warn("unknown message:", data);
}
}
}
} else {
this.trade_ws?.disconnect();//断开连接
this.trade_ws = null;
}
});
setInterval(() => { this.save(); }, 1000 * 600);//十分钟保存一次
}
handleMessageMarketItemOrderBooksUpdated(obj, upload = false) {
//更新本地,游戏数据不带时间戳,市场服务器数据带时间戳
let timestamp = obj.time || parseInt(Date.now() / 1000);
let itemHrid = obj.marketItemOrderBooks.itemHrid;
obj.marketItemOrderBooks?.orderBooks?.forEach((item, enhancementLevel) => {
let bid = item.bids?.length > 0 ? item.bids[0].price : -1;
let ask = item.asks?.length > 0 ? item.asks[0].price : -1;
this.updateItem(itemHrid + ":" + enhancementLevel, { bid: bid, ask: ask, time: timestamp });
});
obj.time = timestamp;//添加时间戳
//上报数据
if (this.trade_ws) {//标准模式走ws
if (!upload) return;//只在game收到消息的时候上报
this.trade_ws.send(JSON.stringify(obj));//ws上报
} else {//铁牛上报
fetchWithTimeout(`${HOST}/market/upload/order`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(obj)
});
}
}
/**
* 合并MWIAPI数据,只包含0级物品
*
* @param obj 包含市场数据的对象
*/
mergeMWIData(obj) {
Object.entries(obj.market).forEach(([itemName, price]) => {
let itemHrid = mwi.ensureItemHrid(itemName);
if (itemHrid) this.updateItem(itemHrid + ":" + 0, { bid: price.bid, ask: price.ask, time: obj.time }, false);//本地更新
});
this.save();
}
mergeCoreDataBeforeSave() {
let obj = JSON.parse(localStorage.getItem("MWICore_marketData") || "{}");
Object.entries(obj).forEach(([itemHridLevel, priceObj]) => {
this.updateItem(itemHridLevel, priceObj, false);//本地更新
});
//不保存,只合并
}
save() {//保存到localStorage
this.mergeCoreDataBeforeSave();//从其他角色合并保存的数据
localStorage.setItem("MWICore_marketData", JSON.stringify(this.marketData));
}
/**
* 部分特殊物品的价格
* 例如金币固定1,牛铃固定为牛铃袋/10的价格
* @param {string} itemHrid - 物品hrid
* @returns {Price|null} - 返回对应商品的价格对象,如果没有则null
*/
getSpecialPrice(itemHrid) {
switch (itemHrid) {
case "/items/coin":
return { bid: 1, ask: 1, time: Date.now() / 1000 };
case "/items/cowbell": {
let cowbells = this.getItemPrice("/items/bag_of_10_cowbells");
return cowbells && { bid: cowbells.bid / 10, ask: cowbells.ask / 10, time: cowbells.time };
}
case "/items/bag_of_10_cowbells":return null;//走普通get,这里返回空
case "/items/task_crystal": {//固定点金收益5000,这里计算可能有bug
return { bid: 5000, ask: 5000, time: Date.now() / 1000 }
}
default:
let itemDetail = mwi.getItemDetail(itemHrid);
if (itemDetail?.categoryHrid === "/item_categories/loot") {//宝箱陨石
let totalAsk = 0;
let totalBid = 0;
let minTime = Date.now() / 1000;
this.getOpenableItems(itemHrid)?.forEach(openItem => {
let price = this.getItemPrice(openItem.itemHrid);
if (price) minTime = Math.min(minTime, price.time);
totalAsk += (price?.ask || 0) * openItem.count;//可以算平均价格
totalBid += (price?.bid || 0) * openItem.count;
});
return { bid: totalBid, ask: totalAsk, time: minTime };
}
if(mwi.character?.gameMode !== "standard"){//其他物品都按点金分解价值
return {ask:itemDetail.sellPrice*5*0.7, bid:itemDetail.sellPrice*5*0.7, time: Date.now() / 1000};//铁牛模式显示物品价值使用点金价格*几率
}
return null;
}
}
getOpenableItems(itemHrid) {
let items = [];
for (let openItem of mwi.initClientData.openableLootDropMap[itemHrid]) {
if (openItem.itemHrid === "/items/purples_gift") continue;//防止循环
items.push({
itemHrid: openItem.itemHrid,
count: (openItem.minCount + openItem.maxCount) / 2 * openItem.dropRate
});
}
return items;
}
/**
* 获取商品的价格
*
* @param {string} itemHridOrName 商品HRID或名称
* @param {number} [enhancementLevel=0] 装备强化等级,普通商品默认为0
* @param {boolean} [peek=false] 是否只查看本地数据,不请求服务器数据
* @returns {number|null} 返回商品的价格,如果商品不存在或无法获取价格则返回null
*/
getItemPrice(itemHridOrName, enhancementLevel = 0, peek = false) {
let itemHrid = mwi.ensureItemHrid(itemHridOrName);
if (!itemHrid) return null;
let specialPrice = this.getSpecialPrice(itemHrid);
if (specialPrice) return specialPrice;
let itemHridLevel = itemHrid + ":" + enhancementLevel;
let priceObj = this.marketData[itemHridLevel];
if (peek) return priceObj;
if (Date.now() / 1000 - this.fetchTimeDict[itemHridLevel] < this.ttl) return priceObj;//1分钟内直接返回本地数据,防止频繁请求服务器
this.fetchTimeDict[itemHridLevel] = Date.now() / 1000;
this.trade_ws?.send(JSON.stringify({ type: "GetItemPrice", name: itemHrid, level: enhancementLevel }));
return priceObj;
}
processItemPrice(resObj) {
let itemHridLevel = resObj.name + ":" + resObj.level;
let priceObj = { bid: resObj.bid, ask: resObj.ask, time: resObj.time };
if (resObj.ttl) this.ttl = resObj.ttl;//更新ttl
this.updateItem(itemHridLevel, priceObj);
}
updateItem(itemHridLevel, priceObj, isFetch = true) {
let localItem = this.marketData[itemHridLevel];
if (isFetch) this.fetchTimeDict[itemHridLevel] = Date.now() / 1000;//fetch时间戳
if (!localItem || localItem.time < priceObj.time) {//服务器数据更新则更新本地数据
let risePercent = 0;
if (localItem) {
let oriPrice = (localItem.ask + localItem.bid);
let newPrice = (priceObj.ask + priceObj.bid);
if (oriPrice != 0) risePercent = newPrice / oriPrice - 1;
}
this.marketData[itemHridLevel] = { rise: risePercent, ask: priceObj.ask, bid: priceObj.bid, time: priceObj.time };//更新本地数据
dispatchEvent(new CustomEvent("MWICoreItemPriceUpdated"), priceObj);//触发事件
}
}
resetRise() {
Object.entries(this.marketData).forEach(([k, v]) => {
v.rise = 0;
});
}
save() {
localStorage.setItem("MWICore_marketData", JSON.stringify(this.marketData));
}
}
mwi.coreMarket = new CoreMarket();
/*历史数据模块*/
function mooket() {
mwi.hookMessage("market_listings_updated", obj => {
obj.endMarketListings.forEach(order => {
if (order.filledQuantity == 0) return;//没有成交的订单不记录
let key = order.itemHrid + "_" + order.enhancementLevel;
let tradeItem = trade_history[key] || {}
if (order.isSell) {
tradeItem.sell = order.price;
} else {
tradeItem.buy = order.price;
}
trade_history[key] = tradeItem;
});
if (mwi.character?.gameMode === "standard") {//只记录标准模式的数据,因为铁牛不能交易
localStorage.setItem("mooket_trade_history", JSON.stringify(trade_history));//保存挂单数据
}
});
let trade_history = JSON.parse(localStorage.getItem("mooket_trade_history") || "{}");
let cur_day = 1;
let curHridName = null;
let curLevel = 0;
let curShowItemName = null;
let chartWidth = 500;
let chartHeight = 280
let configStr = localStorage.getItem("mooket_config");
let config = configStr ? JSON.parse(configStr) : { "dayIndex": 0, "visible": true, "filter": { "bid": true, "ask": true, "mean": true } };
cur_day = config.day;//读取设置
window.onresize = function () {
checkSize();
};
function checkSize() {
if (window.innerWidth < window.innerHeight) {//竖屏,强制设置
config.w = chartWidth = window.innerWidth * 0.8;
config.h = chartHeight = chartWidth * 0.6;
} else {
chartWidth = 400;
chartHeight = 250;
}
}
checkSize();
// 创建容器元素并设置样式和位置
const container = document.createElement('div');
container.style.border = "1px solid #ccc"; //边框样式
container.style.backgroundColor = config.bgcolor || "#000";
container.style.position = "fixed";
container.style.zIndex = 10000;
container.style.top = `${Math.max(0, Math.min(config.y || 0, window.innerHeight - 50))}px`; //距离顶部位置
container.style.left = `${Math.max(0, Math.min(config.x || 0, window.innerWidth - 50))}px`; //距离左侧位置
container.style.width = `${Math.max(0, Math.min(config.w || chartWidth, window.innerWidth))}px`; //容器宽度
container.style.height = `${Math.max(0, Math.min(config.h || chartHeight, window.innerHeight))}px`; //容器高度
container.style.resize = "both";
container.style.overflow = "auto";
container.style.display = "none";
container.style.flexDirection = "column";
container.style.flex = "1";
container.style.minHeight = "33px";
container.style.minWidth = "68px";
container.style.cursor = "move";
container.style.userSelect = "none";
let mouseDragging = false;
let touchDragging = false;
let offsetX, offsetY;
let resizeEndTimer = null;
container.addEventListener("resize", () => {
if (resizeEndTimer) clearTimeout(resizeEndTimer);
resizeEndTimer = setTimeout(save_config, 1000);
});
container.addEventListener("mousedown", function (e) {
if (mouseDragging || touchDragging) return;
const rect = container.getBoundingClientRect();
if (container.style.resize === "both" && (e.clientX > rect.right - 10 && e.clientY > rect.bottom - 10)) return;
mouseDragging = true;
offsetX = e.clientX - container.offsetLeft;
offsetY = e.clientY - container.offsetTop;
});
document.addEventListener("mousemove", function (e) {
if (mouseDragging) {
var newX = e.clientX - offsetX;
var newY = e.clientY - offsetY;
if (newX < 0) newX = 0;
if (newY < 0) newY = 0;
if (newX > window.innerWidth - container.offsetWidth) newX = window.innerWidth - container.offsetWidth;
if (newY > window.innerHeight - container.offsetHeight) newY = window.innerHeight - container.offsetHeight;
container.style.left = newX + "px";
container.style.top = newY + "px";
}
});
document.addEventListener("mouseup", function () {
if (mouseDragging) {
mouseDragging = false;
save_config();
}
});
container.addEventListener("touchstart", function (e) {
if (mouseDragging || touchDragging) return;
const rect = container.getBoundingClientRect();
let touch = e.touches[0];
if (container.style.resize === "both" && (e.clientX > rect.right - 10 && e.clientY > rect.bottom - 10)) return;
touchDragging = true;
offsetX = touch.clientX - container.offsetLeft;
offsetY = touch.clientY - container.offsetTop;
});
document.addEventListener("touchmove", function (e) {
if (touchDragging) {
let touch = e.touches[0];
var newX = touch.clientX - offsetX;
var newY = touch.clientY - offsetY;
if (newX < 0) newX = 0;
if (newY < 0) newY = 0;
if (newX > window.innerWidth - container.offsetWidth) newX = window.innerWidth - container.offsetWidth;
if (newY > window.innerHeight - container.offsetHeight) newY = window.innerHeight - container.offsetHeight;
container.style.left = newX + "px";
container.style.top = newY + "px";
}
});
document.addEventListener("touchend", function () {
if (touchDragging) {
touchDragging = false;
save_config();
}
});
document.body.appendChild(container);
const ctx = document.createElement('canvas');
ctx.id = "myChart";
container.appendChild(ctx);
// 创建下拉菜单并设置样式和位置
let wrapper = document.createElement('div');
wrapper.style.position = 'absolute';
wrapper.style.top = '5px';
wrapper.style.right = '16px';
wrapper.style.fontSize = '14px';
//wrapper.style.backgroundColor = '#fff';
wrapper.style.flexShrink = 0;
container.appendChild(wrapper);
const days = [1, 3, 7, 14, 30, 180, 360];
const dayTitle = ['1天', '3天', '1周', '2周', '1月', '半年', '一年'];
cur_day = days[config.dayIndex];
let select = document.createElement('select');
select.style.cursor = 'pointer';
select.style.verticalAlign = 'middle';
select.onchange = function () {
config.dayIndex = days.indexOf(parseInt(this.value));
if (curHridName) requestItemPrice(curHridName, this.value, curLevel);
save_config();
};
for (let i = 0; i < days.length; i++) {
let option = document.createElement('option');
option.value = days[i];
option.text = dayTitle[i];
if (i === config.dayIndex) option.selected = true;
select.appendChild(option);
}
wrapper.appendChild(select);
// 创建一个容器元素并设置样式和位置
const leftContainer = document.createElement('div');
leftContainer.style.padding = '2px'
leftContainer.style.display = 'flex';
leftContainer.style.flexDirection = 'row';
leftContainer.style.alignItems = 'center'
container.appendChild(leftContainer);
//添加一个btn隐藏canvas和wrapper
let btn_close = document.createElement('input');
btn_close.type = 'button';
btn_close.value = '📈隐藏';
btn_close.style.margin = 0;
btn_close.style.cursor = 'pointer';
leftContainer.appendChild(btn_close);
let picker = document.createElement('input');
picker.type = 'color';
picker.style.cursor = 'pointer';
picker.style.width = '20px';
picker.style.height = '20px';
picker.style.padding = "0"
picker.style.verticalAlign = "middle"
picker.onchange = function () {
container.style.backgroundColor = this.value;
config.bgcolor = this.value;
save_config();
}
wrapper.appendChild(picker);
//一个固定的文本显示买入卖出历史价格
let price_info = document.createElement('div');
price_info.style.fontSize = '14px';
price_info.title = "我的最近买/卖价格"
price_info.style.width = "max-content";
price_info.style.whiteSpace = "nowrap";
price_info.style.lineHeight = '25px';
price_info.style.display = 'none';
price_info.style.marginLeft = '5px';
let buy_price = document.createElement('span');
let sell_price = document.createElement('span');
price_info.appendChild(buy_price);
price_info.appendChild(sell_price);
buy_price.style.color = 'red';
sell_price.style.color = 'lime';
leftContainer.appendChild(price_info);
let lastWidth;
let lastHeight;
btn_close.onclick = toggle;
function toggle() {
if (wrapper.style.display === 'none') {
wrapper.style.display = ctx.style.display = 'block';
container.style.resize = "both";
btn_close.value = '📈隐藏';
leftContainer.style.position = 'absolute'
leftContainer.style.top = '1px';
leftContainer.style.left = '1px';
container.style.width = lastWidth;
container.style.height = lastHeight;
config.visible = true;
save_config();
} else {
lastWidth = container.style.width;
lastHeight = container.style.height;
wrapper.style.display = ctx.style.display = 'none';
container.style.resize = "none";
container.style.width = "auto";
container.style.height = "auto";
btn_close.value = '📈显示';
leftContainer.style.position = 'relative'
leftContainer.style.top = 0;
leftContainer.style.left = 0;
config.visible = false;
save_config();
}
};
let chart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: '市场',
data: [],
backgroundColor: 'rgba(255,99,132,0.2)',
borderColor: 'rgba(255,99,132,1)',
borderWidth: 1
}]
},
options: {
onClick: save_config,
responsive: true,
maintainAspectRatio: false,
pointRadius: 0,
pointHitRadius: 20,
scales: {
y: {
beginAtZero: false,
ticks: {
// 自定义刻度标签格式化
callback: showNumber
}
}
},
plugins: {
title: {
display: true,
text: "",
color: "cornflowerblue",
font: {
size: 15,
weight: 'bold',
}
}
}
}
});
function requestItemPrice(itemHridName, day = 1, level = 0) {
if (!itemHridName) return;
if (curHridName === itemHridName && curLevel === level && cur_day === day) return;//防止重复请求
curHridName = itemHridName;
curLevel = level;
cur_day = day;
curShowItemName = mwi.isZh ?
mwi.lang.zh.translation.itemNames[itemHridName] : mwi.lang.en.translation.itemNames[itemHridName];
curShowItemName += curLevel > 0 ? "+" + curLevel : "";
let time = day * 3600 * 24;
//const HOST = "https://mooket.qi-e.top";上面定义了
if (curLevel > 0 || day < 2) {
const params = new URLSearchParams();
params.append("name", curHridName);
params.append("level", curLevel);
params.append("time", time);
fetch(`${HOST}/market/item/history?${params}`).then(res => {
res.json().then(data => updateChart(data, cur_day));
})
}//新api
else {//旧api
let itemNameEN = mwi.lang.en.translation.itemNames[itemHridName];
fetch(`${HOST}/market`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: itemNameEN,
time: time
})
}).then(res => {
res.json().then(data => updateChart(data, cur_day));
})
}
}
function formatTime(timestamp, range) {
const date = new Date(timestamp * 1000);
const pad = n => n.toString().padStart(2, '0');
// 获取各时间组件
const hours = pad(date.getHours());
const minutes = pad(date.getMinutes());
const day = pad(date.getDate());
const month = pad(date.getMonth() + 1);
const shortYear = date.getFullYear().toString().slice(-2);
// 根据时间范围选择格式
switch (parseInt(range)) {
case 1: // 1天:只显示时间
return `${hours}:${minutes}`;
case 3: // 3天:日+时段
return `${hours}:${minutes}`;
case 7: // 7天:月/日 + 时段
return `${day}.${hours}`;
case 14: // 14天:月/日 + 时段
return `${day}.${hours}`;
case 30: // 30天:月/日
return `${month}/${day}`;
default: // 180天:年/月
return `${shortYear}/${month}`;
}
}
function showNumber(num) {
if (isNaN(num)) return num;
if (num === 0) return "0"; // 单独处理0的情况
const absNum = Math.abs(num);
//num保留一位小数
if (num < 1) return num.toFixed(2);
return absNum >= 1e10 ? `${(num / 1e9).toFixed(1)}B` :
absNum >= 1e7 ? `${(num / 1e6).toFixed(1)}M` :
absNum >= 1e5 ? `${Math.floor(num / 1e3)}K` :
`${Math.floor(num)}`;
}
//data={'bid':[{time:1,price:1}],'ask':[{time:1,price:1}]}
function updateChart(data, day) {
//字段名差异
data.bid = data.bid || data.bids
data.ask = data.ask || data.asks;
//过滤异常元素
for (let i = data.bid.length - 1; i >= 0; i--) {
if (data.bid[i].price < 0 && data.ask[i].price < 0) {//都小于0,认为是异常数据,直接删除
data.bid.splice(i, 1);
data.ask.splice(i, 1);
} else {//小于0则设置为0
data.bid[i].price = Math.max(0, data.bid[i].price);
data.ask[i].price = Math.max(0, data.ask[i].price);
}
}
//timestamp转日期时间
//根据day输出不同的时间表示,<3天显示时分,<=7天显示日时,<=30天显示月日,>30天显示年月
//显示历史价格
let enhancementLevel = document.querySelector(".MarketplacePanel_infoContainer__2mCnh .Item_enhancementLevel__19g-e")?.textContent.replace("+", "") || "0";
let tradeName = curHridName + "_" + parseInt(enhancementLevel);
if (trade_history[tradeName]) {
let buy = trade_history[tradeName].buy || "none";
let sell = trade_history[tradeName].sell || "none";
price_info.style.display = "inline-block";
let levelStr = enhancementLevel > 0 ? "(+" + enhancementLevel + ")" : "";
price_info.innerHTML = `<span style="color:red">${showNumber(buy)}</span>/<span style="color:green">${showNumber(sell)}</span>${levelStr}`;
container.style.minWidth = price_info.clientWidth + 70 + "px";
} else {
price_info.style.display = "none";
container.style.minWidth = "68px";
}
let labels = data.bid.map(x => formatTime(x.time, day));
chart.data.labels = labels;
let sma = [];
let sma_size = 6;
let sma_window = [];
for (let i = 0; i < data.bid.length; i++) {
sma_window.push((data.bid[i].price + data.ask[i].price) / 2);
if (sma_window.length > sma_size) sma_window.shift();
sma.push(sma_window.reduce((a, b) => a + b, 0) / sma_window.length);
}
chart.options.plugins.title.text = curShowItemName
chart.data.datasets = [
{
label: mwi.isZh ? '买一' : "bid1",
data: data.bid.map(x => x.price),
borderColor: '#ff3300',
backgroundColor: '#ff3300',
borderWidth: 1.5
},
{
label: mwi.isZh ? '卖一' : "ask1",
data: data.ask.map(x => x.price),
borderColor: '#00cc00',
backgroundColor: '#00cc00',
borderWidth: 1.5
},
{
label: mwi.isZh ? '均线' : "mean",
data: sma,
borderColor: '#ff9900',
borderWidth: 3,
tension: 0.5,
fill: true
}
];
chart.setDatasetVisibility(0, config.filter.ask);
chart.setDatasetVisibility(1, config.filter.bid);
chart.setDatasetVisibility(2, config.filter.mean);
chart.update()
}
function save_config() {
if (chart && chart.data && chart.data.datasets && chart.data.datasets.length == 3) {
config.filter.ask = chart.getDatasetMeta(0).visible;
config.filter.bid = chart.getDatasetMeta(1).visible;
config.filter.mean = chart.getDatasetMeta(2).visible;
}
config.x = Math.max(0, Math.min(container.getBoundingClientRect().x, window.innerWidth - 50));
config.y = Math.max(0, Math.min(container.getBoundingClientRect().y, window.innerHeight - 50));
if (container.style.width != "auto") {
config.w = container.clientWidth;
config.h = container.clientHeight;
}
localStorage.setItem("mooket_config", JSON.stringify(config));
}
setInterval(() => {
if (document.querySelector(".MarketplacePanel_marketplacePanel__21b7o")?.checkVisibility()) {
container.style.display = "block"
try {
let currentItem = document.querySelector(".MarketplacePanel_currentItem__3ercC");
let level = currentItem?.querySelector(".Item_enhancementLevel__19g-e");
let itemHrid = mwi.ensureItemHrid(currentItem?.querySelector(".Icon_icon__2LtL_")?.ariaLabel);
requestItemPrice(itemHrid, cur_day, parseInt(level?.textContent.replace("+", "") || "0"))
} catch (e) {
console.error(e)
}
} else {
container.style.display = "none"
}
}, 500);
//setInterval(updateInventoryStatus, 60000);
toggle();
console.info("mooket 初始化完成");
}
new Promise(resolve => {
let count = 0;
const interval = setInterval(() => {
count++;
if (count > 30) { clearInterval(interval) }//最多等待30秒
if (document.body) {//等待必须组件加载完毕后再初始化
clearInterval(interval);
resolve();
}
}, 1000);
}).then(() => {
mooket();
});
})();