Ranged Way Idle

死亡提醒、强制刷新MWITools的价格、私信提醒音、自动任务排序、显示购买预付金/出售可获金/待领取金额、显示任务价值、商店物品价值、默哀法师助手

当前为 2025-08-20 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Ranged Way Idle
// @namespace    http://tampermonkey.net/
// @version      2.9
// @description  死亡提醒、强制刷新MWITools的价格、私信提醒音、自动任务排序、显示购买预付金/出售可获金/待领取金额、显示任务价值、商店物品价值、默哀法师助手
// @author       AlphB
// @match        https://www.milkywayidle.com/*
// @match        https://test.milkywayidle.com/*
// @grant        GM_notification
// @grant        GM_getValue
// @grant        GM_setValue
// @icon         https://www.google.com/s2/favicons?sz=64&domain=milkywayidle.com
// @grant        none
// @license      CC-BY-NC-SA-4.0
// ==/UserScript==

(function () {
    const config = {
        notifyDeath: {enable: true, desc: "战斗中角色死亡时发送通知"},
        forceUpdateMarketPrice: {enable: true, desc: "进入市场时,强制更新MWITools的市场价格(依赖MWITools)"},
        notifyWhisperMessages: {enable: false, desc: "接受到私信时播放提醒音"},
        listenKeywordMessages: {enable: false, desc: "中文频道消息含有关键词时播放提醒音"},
        matchByRegex: {enable: false, desc: "改用正则表达式匹配中文频道消息(依赖上一条功能)"},
        autoTaskSort: {enable: true, desc: "自动点击MWI TaskManager的任务排序按钮(依赖MWI TaskManager)"},
        showMarketListingsFunds: {enable: true, desc: "显示购买预付金/出售可获金/待领取金额"},
        mournForMagicWayIdle: {enable: true, desc: "在控制台默哀法师助手"},
        showTaskValue: {enable: true, desc: "显示任务期望奖励和任务代币的价值(依赖食用工具)"},
        debugPrintMessages: {enable: false, desc: "控制台打印所有消息(不推荐打开)"},
        keywords: [],
    }
    const globalVariable = {
        battleData: {
            players: null,
            lastNotifyTime: 0,
        },
        characterID: null,
        whisperAudio: new Audio(`https://upload.thbwiki.cc/d/d1/se_bonus2.mp3`),
        keywordAudio: new Audio(`https://upload.thbwiki.cc/c/c9/se_pldead00.mp3`),
        market: {
            hasFundsElement: false,
            sellValue: null,
            buyValue: null,
            unclaimedValue: null,
            sellListings: null,
            buyListings: null
        },
        task: {
            taskListElement: null,
            taskShopElement: null,
            taskTokenValueData: null,
            hasTaskValueElement: false,
            hasTaskShopValueElement: false,
            taskValueElements: [],
            taskShopElements: [],
            tokenValue: {
                Bid: null,
                Ask: null
            }
        }
    };


    init();

    function init() {
        readConfig();
        // 任务代币计算功能需要食用工具
        if (!('Edible_Tools' in localStorage) ||
            !JSON.parse(localStorage.getItem('Edible_Tools')) ||
            (!("Chest_Drop_Data" in JSON.parse(localStorage.getItem('Edible_Tools'))))) {
            config.showTaskValue.enable = false;
            saveConfig({showTaskValue: false});
        }
        // 更新市场价格需要MWITools支持
        if (!('MWITools_marketAPI_json' in localStorage) ||
            !JSON.parse(localStorage.getItem('MWITools_marketAPI_json')) ||
            (!("marketData" in JSON.parse(localStorage.getItem('MWITools_marketAPI_json'))))) {
            config.forceUpdateMarketPrice.enable = false;
            saveConfig({forceUpdateMarketPrice: false});
        }
        globalVariable.whisperAudio.volume = 0.4;
        globalVariable.keywordAudio.volume = 0.4;
        let observer = new MutationObserver(function () {
            if (config.showMarketListingsFunds.enable) showMarketListingsFunds();
            if (config.autoTaskSort.enable) autoClickTaskSortButton();
            if (config.showTaskValue.enable) {
                showTaskValue();
                showTaskShopItemValue();
            }
            showConfigMenu();
        });
        observer.observe(document, {childList: true, subtree: true});
        if (config.showTaskValue.enable) {
            globalVariable.task.taskTokenValueData = getTaskTokenValue();
        }
        if (config.mournForMagicWayIdle.enable) {
            console.log("为法师助手默哀");
        }

        const oriGet = Object.getOwnPropertyDescriptor(MessageEvent.prototype, "data").get;

        function hookedGet() {
            const socket = this.currentTarget;
            if (!(socket instanceof WebSocket) || !socket.url ||
                (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);
            return handleMessage(message);
        }

        Object.defineProperty(MessageEvent.prototype, "data", {
            get: hookedGet,
            configurable: true,
            enumerable: true
        });
    }

    function readConfig() {
        const localConfig = localStorage.getItem("ranged_way_idle_config");
        if (localConfig) {
            const localConfigObj = JSON.parse(localConfig);
            for (let key in localConfigObj) {
                if (config.hasOwnProperty(key) && key !== 'keywords') {
                    config[key].enable = localConfigObj[key];
                }
            }
            config.keywords = localConfigObj.keywords;
        }
    }

    function saveConfig(obj) {
        // 仅保存enable开关和keywords
        const saveConfigObj = {};
        const configMenu = document.querySelectorAll("div#ranged_way_idle_config_menu input");
        if (configMenu.length === 0) return;
        for (const checkbox of configMenu) {
            config[checkbox.id].enable = checkbox.checked;
            saveConfigObj[checkbox.id] = checkbox.checked;
        }
        for (let key in obj) {
            saveConfigObj[key] = obj[key];
        }
        saveConfigObj.keywords = config.keywords;
        localStorage.setItem("ranged_way_idle_config", JSON.stringify(saveConfigObj));
    }

    function showConfigMenu() {
        const targetNode = document.querySelector("div.SettingsPanel_profileTab__214Bj");
        if (targetNode) {
            if (!targetNode.querySelector("#ranged_way_idle_config_menu")) {
                // enable开关部分
                targetNode.insertAdjacentHTML("beforeend", `<div id="ranged_way_idle_config_menu"></div>`);
                const insertElem = targetNode.querySelector("div#ranged_way_idle_config_menu");
                insertElem.insertAdjacentHTML(
                    "beforeend",
                    `<div style="float: left;" id="ranged_way_idle_config">${
                        "Ranged Way Idle 设置(刷新后生效)"
                    }</div></br>`
                );
                insertElem.insertAdjacentHTML(
                    "beforeend",
                    `<div style="float: left;" id="ranged_way_idle_config">${
                        "若刷新后选项变化或仍不生效,说明插件不兼容,可能是因为未安装插件或版本过久"
                    }</div></br>`
                );
                for (let key in config) {
                    if (key === 'keywords') continue;
                    insertElem.insertAdjacentHTML(
                        "beforeend",
                        `<div style="float: left;">
                                   <input type="checkbox" id="${key}" ${config[key].enable ? "checked" : ""}>${config[key].desc}
                               </div></br>`
                    );
                }
                insertElem.addEventListener("change", saveConfig);

                // 控制 keywords 列表
                const container = document.createElement('div');
                container.style.marginTop = '20px';
                container.classList.add("ranged_way_idle_keywords_config_menu")
                const input = document.createElement('input');
                input.type = 'text';
                input.style.width = '200px';
                input.placeholder = 'Ranged Way Idle 监听' + (config.matchByRegex.enable ? '正则' : '关键词');
                const button = document.createElement('button');
                button.textContent = '添加';
                const listContainer = document.createElement('div');
                listContainer.style.marginTop = '10px';
                container.appendChild(input);
                container.appendChild(button);
                container.appendChild(listContainer);
                targetNode.insertBefore(container, targetNode.nextSibling);

                function renderList() {
                    listContainer.innerHTML = '';
                    config.keywords.forEach((item, index) => {
                        const itemDiv = document.createElement('div');
                        itemDiv.textContent = item;
                        itemDiv.style.margin = 'auto';
                        itemDiv.style.width = '200px';
                        itemDiv.style.cursor = 'pointer';
                        itemDiv.addEventListener('click', () => {
                            config.keywords.splice(index, 1);
                            renderList();
                        });
                        listContainer.appendChild(itemDiv);
                    });
                    saveConfig();
                }

                renderList();
                button.addEventListener('click', () => {
                    const newItem = input.value.trim();
                    if (newItem) {
                        config.keywords.push(newItem);
                        input.value = '';
                        saveConfig();
                        renderList();
                    }
                });
            }
        }
    }

    function handleMessage(message) {
        try {
            if (config.debugPrintMessages.enable) console.log(message);
            const obj = JSON.parse(message);
            if (!obj) return message;
            switch (obj.type) {
                case "init_character_data":
                    globalVariable.market.sellListings = {};
                    globalVariable.market.buyListings = {};
                    updateMarketListings(obj.myMarketListings);
                    globalVariable.characterID = obj.character.id;
                    break;
                case "market_listings_updated":
                    updateMarketListings(obj.endMarketListings);
                    break;
                case "new_battle":
                    if (config.notifyDeath.enable) initBattle(obj);
                    break;
                case "battle_updated":
                    if (config.notifyDeath.enable) checkDeath(obj);
                    break;
                case "market_item_order_books_updated":
                    if (config.forceUpdateMarketPrice.enable) marketPriceUpdate(obj);
                    break;
                case "quests_updated":
                    for (let e of globalVariable.task.taskValueElements) {
                        e.remove();
                    }
                    globalVariable.task.taskValueElements = [];
                    globalVariable.task.hasTaskValueElement = false;
                    break;
                case "chat_message_received":
                    handleChatMessage(obj);
                    break;
            }
        } catch (e) {
            console.error(e);
        }
        return message;
    }

    function notifyDeath(name) {
        // 如果间隔小于60秒,强制不播报
        const nowTime = Date.now();
        if (nowTime - globalVariable.battleData.lastNotifyTime < 60000) return;
        globalVariable.battleData.lastNotifyTime = nowTime;
        new Notification('🎉🎉🎉喜报🎉🎉🎉', {body: `${name} 死了!`});
    }

    function initBattle(obj) {
        // 处理战斗中各个玩家的角色名,供播报死亡信息
        globalVariable.battleData.players = [];
        for (let player of obj.players) {
            globalVariable.battleData.players.push({
                name: player.name, isAlive: player.currentHitpoints > 0,
            });
            if (player.currentHitpoints === 0) {
                notifyDeath(player.name);
            }
        }
    }

    function checkDeath(obj) {
        // 检查玩家是否死亡
        if (!globalVariable.battleData.players) return;
        for (let key in obj.pMap) {
            const index = parseInt(key);
            if (globalVariable.battleData.players[index].isAlive && obj.pMap[key].cHP === 0) {
                // 角色 活->死 时发送提醒
                globalVariable.battleData.players[index].isAlive = false;
                notifyDeath(globalVariable.battleData.players[index].name);
            } else if (obj.pMap[key].cHP > 0) {
                globalVariable.battleData.players[index].isAlive = true;
            }
        }
    }

    function marketPriceUpdate(obj) {
        // 强制刷新MWITools的市场价格数据
        if (config.showTaskValue.enable) {
            globalVariable.task.taskTokenValueData = getTaskTokenValue();
        }
        const marketAPIjson = JSON.parse(localStorage.getItem('MWITools_marketAPI_json'));
        if (!('MWITools_marketAPI_json' in localStorage) ||
            !JSON.parse(localStorage.getItem('MWITools_marketAPI_json')) ||
            (!("marketData" in JSON.parse(localStorage.getItem('MWITools_marketAPI_json'))))) return;
        const itemHrid = obj.marketItemOrderBooks.itemHrid;
        if (!(itemHrid in marketAPIjson.marketData)) return;
        const orderBooks = obj.marketItemOrderBooks.orderBooks;
        for (let enhanceLevel in orderBooks) {
            if (!(enhanceLevel in marketAPIjson.marketData[itemHrid])) {
                marketAPIjson.marketData[itemHrid][enhanceLevel] = {a: 0, b: 0};
            }
            const ask = orderBooks[enhanceLevel].asks;
            if (ask && ask.length) {
                marketAPIjson.marketData[itemHrid][enhanceLevel].a = Math.min(...ask.map(listing => listing.price));
            }
            const bid = orderBooks[enhanceLevel].bids;
            if (bid && ask.length) {
                marketAPIjson.marketData[itemHrid][enhanceLevel].b = Math.max(...bid.map(listing => listing.price));
            }
        }
        // 将修改后结果写回marketAPI缓存,完成对marketAPI价格的强制修改
        localStorage.setItem("MWITools_marketAPI_json", JSON.stringify(marketAPIjson));
    }

    function handleChatMessage(obj) {
        // 处理聊天信息
        if (obj.message.chan === "/chat_channel_types/whisper") {
            if (config.notifyWhisperMessages.enable && obj.message.rId === globalVariable.characterID) {
                console.log(globalVariable.characterID);
                console.log(obj.message.rId);
                globalVariable.whisperAudio.play();
            }
        } else if (obj.message.chan === "/chat_channel_types/chinese") {
            if (config.listenKeywordMessages.enable) {
                for (let keyword of config.keywords) {
                    if (!config.matchByRegex.enable && obj.message.m.includes(keyword)) {
                        globalVariable.keywordAudio.play();
                    } else if (config.matchByRegex.enable) {
                        const regex = new RegExp(keyword, "g");
                        if (regex.test(obj.message.m)) {
                            globalVariable.keywordAudio.play();
                        }
                    }
                }

            }
        }
    }

    function autoClickTaskSortButton() {
        // 点击MWI TaskManager的任务排序按钮
        const targetElement = document.querySelector('#TaskSort');
        if (targetElement && targetElement.textContent !== '手动排序') {
            targetElement.click();
            targetElement.textContent = '手动排序';
        }
    }

    function formatCoinValue(num) {
        if (isNaN(num)) return "NaN";
        if (num >= 1e13) {
            return Math.floor(num / 1e12) + "T";
        } else if (num >= 1e10) {
            return Math.floor(num / 1e9) + "B";
        } else if (num >= 1e7) {
            return Math.floor(num / 1e6) + "M";
        } else if (num >= 1e4) {
            return Math.floor(num / 1e3) + "K";
        }
        return num.toString();
    }

    function updateMarketListings(obj) {
        // 更新市场价格
        for (let listing of obj) {
            if (listing.status === "/market_listing_status/cancelled") {
                delete globalVariable.market[listing.isSell ? "sellListings" : "buyListings"][listing.id];
                continue
            }
            const tax = (listing.itemHrid === "/items/bag_of_10_cowbells") ? 0.82 : 0.98;
            globalVariable.market[listing.isSell ? "sellListings" : "buyListings"][listing.id] = {
                itemHrid: listing.itemHrid,
                price: (listing.orderQuantity - listing.filledQuantity) * (listing.isSell ? Math.floor(listing.price * tax) : listing.price),
                unclaimedCoinCount: listing.unclaimedCoinCount,
            }
        }
        globalVariable.market.buyValue = 0;
        globalVariable.market.sellValue = 0;
        globalVariable.market.unclaimedValue = 0;
        for (let id in globalVariable.market.buyListings) {
            const listing = globalVariable.market.buyListings[id];
            globalVariable.market.buyValue += listing.price;
            globalVariable.market.unclaimedValue += listing.unclaimedCoinCount;
        }
        for (let id in globalVariable.market.sellListings) {
            const listing = globalVariable.market.sellListings[id];
            globalVariable.market.sellValue += listing.price;
            globalVariable.market.unclaimedValue += listing.unclaimedCoinCount;
        }
        globalVariable.market.hasFundsElement = false;
    }

    function showMarketListingsFunds() {
        // 如果已经存在节点,不必更新
        if (globalVariable.market.hasFundsElement) return;
        const coinStackElement = document.querySelector("div.MarketplacePanel_coinStack__1l0UD");
        // 不在市场面板,不必更新
        if (coinStackElement) {
            coinStackElement.style.top = "0px";
            coinStackElement.style.left = "0px";
            let fundsElement = coinStackElement.parentNode.querySelector("div.fundsElement");
            while (fundsElement) {
                fundsElement.remove();
                fundsElement = coinStackElement.parentNode.querySelector("div.fundsElement");
            }
            makeNode("购买预付金", globalVariable.market.buyValue, ["125px", "0px"]);
            makeNode("出售可获金", globalVariable.market.sellValue, ["125px", "22px"]);
            makeNode("待领取金额", globalVariable.market.unclaimedValue, ["0px", "22px"]);
            globalVariable.market.hasFundsElement = true;
        }

        function makeNode(text, value, style) {
            let node = coinStackElement.cloneNode(true);
            node.classList.add("fundsElement");
            const countNode = node.querySelector("div.Item_count__1HVvv");
            const textNode = node.querySelector("div.Item_name__2C42x");
            if (countNode) countNode.textContent = formatCoinValue(value);
            if (textNode) textNode.innerHTML = `<span style="color: rgb(102,204,255); font-weight: bold;">${text}</span>`;
            node.style.left = style[0];
            node.style.top = style[1];
            coinStackElement.parentNode.insertBefore(node, coinStackElement.nextSibling);
        }
    }

    function getTaskTokenValue() {
        const chestDropData = JSON.parse(localStorage.getItem("Edible_Tools")).Chest_Drop_Data;
        const lootsName = ["大陨石舱", "大工匠匣", "大宝箱"];
        const bidValueList = [
            parseFloat(chestDropData["Large Meteorite Cache"]["期望产出Bid"]),
            parseFloat(chestDropData["Large Artisan's Crate"]["期望产出Bid"]),
            parseFloat(chestDropData["Large Treasure Chest"]["期望产出Bid"]),
        ]
        const askValueList = [
            parseFloat(chestDropData["Large Meteorite Cache"]["期望产出Ask"]),
            parseFloat(chestDropData["Large Artisan's Crate"]["期望产出Ask"]),
            parseFloat(chestDropData["Large Treasure Chest"]["期望产出Ask"]),
        ]
        const res = {
            bidValue: Math.max(...bidValueList),
            askValue: Math.max(...askValueList)
        }
        // bid和ask的最佳兑换选项
        res.bidLoots = lootsName[bidValueList.indexOf(res.bidValue)];
        res.askLoots = lootsName[askValueList.indexOf(res.askValue)];
        // bid和ask的任务代币价值
        res.bidValue = Math.round(res.bidValue / 30);
        res.askValue = Math.round(res.askValue / 30);
        // 小紫牛的礼物的额外价值计算
        res.giftValueBid = Math.round(parseFloat(chestDropData["Purple's Gift"]["期望产出Bid"]));
        res.giftValueAsk = Math.round(parseFloat(chestDropData["Purple's Gift"]["期望产出Ask"]));
        if (config.forceUpdateMarketPrice.enable) {
            const marketJSON = JSON.parse(localStorage.getItem("MWITools_marketAPI_json"));
            marketJSON.marketData["/items/task_token"] = {"0": {a: res.askValue, b: res.bidValue}};
            localStorage.setItem("MWITools_marketAPI_json", JSON.stringify(marketJSON));
        }
        res.rewardValueBid = res.bidValue + res.giftValueBid / 50;
        res.rewardValueAsk = res.askValue + res.giftValueAsk / 50;
        return res;
    }

    function showTaskValue() {
        globalVariable.task.taskListElement = document.querySelector("div.TasksPanel_taskList__2xh4k");
        // 如果不在任务面板,则销毁显示任务价值的元素
        if (!globalVariable.task.taskListElement) {
            globalVariable.task.taskValueElements = [];
            globalVariable.task.hasTaskValueElement = false;
            globalVariable.task.taskListElement = null;
            return;
        }
        // 如果已经存在任务价值的元素,不再更新
        if (globalVariable.task.hasTaskValueElement) return;
        globalVariable.task.hasTaskValueElement = true;
        const taskNodes = [...globalVariable.task.taskListElement.querySelectorAll("div.RandomTask_randomTask__3B9fA")];

        function convertKEndStringToNumber(str) {
            if (str.endsWith('K') || str.endsWith('k')) {
                return Number(str.slice(0, -1)) * 1000;
            } else {
                return Number(str);
            }
        }

        taskNodes.forEach(function (node) {
            const reward = node.querySelector("div.RandomTask_rewards__YZk7D");
            const coin = convertKEndStringToNumber(reward.querySelectorAll("div.Item_count__1HVvv")[0].innerText);
            const tokenCount = Number(reward.querySelectorAll("div.Item_count__1HVvv")[1].innerText);
            const newDiv = document.createElement("div");
            newDiv.textContent = `奖励期望收益: 
            ${formatCoinValue(coin + tokenCount * globalVariable.task.taskTokenValueData.rewardValueAsk)} / 
            ${formatCoinValue(coin + tokenCount * globalVariable.task.taskTokenValueData.rewardValueBid)}`;
            newDiv.style.color = "rgb(248,0,248)";
            newDiv.classList.add("rewardValue");
            node.querySelector("div.RandomTask_action__3eC6o").appendChild(newDiv);
            globalVariable.task.taskValueElements.push(newDiv);
        });
    }

    function showTaskShopItemValue() {
        globalVariable.task.taskShopElement = document.querySelector("div.TasksPanel_buyableGrid__2Ua51");
        // 如果不在商店面板,则销毁显示价值的元素
        if (!globalVariable.task.taskShopElement) {
            globalVariable.task.taskShopValueElements = [];
            globalVariable.task.hasTaskShopValueElement = false;
            globalVariable.task.taskShopElement = null;
            return;
        }
        // 如果已经存在价值的元素,不再更新
        if (globalVariable.task.hasTaskShopValueElement) return;
        globalVariable.task.hasTaskShopValueElement = true;
        const taskNodes = [...globalVariable.task.taskShopElement.querySelectorAll("div.TasksPanel_item__DWSpv")];

        function convertKEndStringToNumber(str) {
            if (str.endsWith('K') || str.endsWith('k')) {
                return Number(str.slice(0, -1)) * 1000;
            } else {
                return Number(str);
            }
        }

        const chestDropData = JSON.parse(localStorage.getItem("Edible_Tools")).Chest_Drop_Data;
        // parseFloat(chestDropData["Large Meteorite Cache"]["期望产出Bid"]),
        //     parseFloat(chestDropData["Large Artisan's Crate"]["期望产出Bid"]),
        //     parseFloat(chestDropData["Large Treasure Chest"]["期望产出Bid"]),
        taskNodes.forEach(function (node) {
            if (node.childNodes[2].textContent !== "30") return;
            const newDiv = document.createElement("div");
            if (node.childNodes[1].childNodes[0].childNodes[0].href.baseVal.endsWith("large_meteorite_cache")) {
                newDiv.textContent = `
            ${formatCoinValue(parseFloat(chestDropData["Large Meteorite Cache"]["期望产出Ask"]))} / 
            ${formatCoinValue(parseFloat(chestDropData["Large Meteorite Cache"]["期望产出Bid"]))}`;
            } else if (node.childNodes[1].childNodes[0].childNodes[0].href.baseVal.endsWith("large_artisans_crate")) {
                newDiv.textContent = `
            ${formatCoinValue(parseFloat(chestDropData["Large Artisan's Crate"]["期望产出Ask"]))} / 
            ${formatCoinValue(parseFloat(chestDropData["Large Artisan's Crate"]["期望产出Bid"]))}`;
            } else if (node.childNodes[1].childNodes[0].childNodes[0].href.baseVal.endsWith("large_treasure_chest")) {
                newDiv.textContent = `
            ${formatCoinValue(parseFloat(chestDropData["Large Treasure Chest"]["期望产出Ask"]))} / 
            ${formatCoinValue(parseFloat(chestDropData["Large Treasure Chest"]["期望产出Bid"]))}`;
            }
            newDiv.style.color = "rgb(248,0,248)";
            newDiv.classList.add("taskShopValue");
            node.childNodes[2].insertAdjacentElement('beforebegin', newDiv);
            globalVariable.task.taskShopValueElements.push(newDiv);
        });
    }
})();