Greasy Fork

Greasy Fork is available in English.

更好的商店界面

将相同报价的单子合并到一起,如果中间有自己的单子,则从该处隔开

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         更好的商店界面
// @namespace    http://tampermonkey.net/
// @version      1.4
// @description  将相同报价的单子合并到一起,如果中间有自己的单子,则从该处隔开
// @author       jxxzs
// @match        https://www.milkywayidle.com/game*
// @grant        none
// @run-at       document-idle
// @require      https://code.jquery.com/jquery-3.6.0.min.js
// ==/UserScript==

(async () => {
    'use strict';

    function WaitForElement(selector, $root = $(document), timeout = 30000) {
        return new Promise((resolve, reject) => {
            const interval = 100;
            let elapsed = 0;
            const timer = setInterval(() => {
                const element = $root.find(selector);
                if (element.length) {
                    clearInterval(timer);
                    resolve(element);
                } else {
                    elapsed += interval;
                    if (elapsed >= timeout) {
                        clearInterval(timer);
                        reject(new Error('元素未出现'));
                        console.warn('请刷新页面,重新加载脚本');
                    }
                }
            }, interval);
        });
    }

    // 监听 DOM 中某个元素出现,触发回调
    function OnElementAppear(selector, callback) {
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                mutation.addedNodes.forEach((node) => {
                    if (!(node instanceof HTMLElement)) return;

                    if ($(node).is(selector)) {
                        requestAnimationFrame(() => callback($(node)));
                    }

                    const $matches = $(node).find(selector);
                    if ($matches.length) {
                        $matches.each((_, el) => {
                            requestAnimationFrame(() => callback($(el)));
                        });
                    }
                });
            });
        });
        observer.observe(document.body, { childList: true, subtree: true });
    }

    // 把 "1.5K" "2M" "9999K" 转换成实际数字
    function ParseFormattedNumber(str) {
        str = str.trim().toUpperCase();
        const units = { "K": 1e3, "M": 1e6, "B": 1e9 };
        const match = str.match(/^([\d\.]+)([KMB]?)$/);

        if (!match) return parseFloat(str) || 0;
        let value = parseFloat(match[1]);
        let unit = match[2];

        if (unit && units[unit]) {
            value *= units[unit];
        }
        return value;
    }

    // 处理面板
    function HandlePanel($panel) {
        let lastPrice = null;
        let lastRow = null;

        $panel.find('tr').each(function () {
            const $tr = $(this);
            const $tds = $tr.find('td');

            // 第 1 个 td → count
            let countText = $tds.eq(0).clone().children().remove().end().text().trim();
            let count = ParseFormattedNumber(countText);

            // 不论合并与否,先把这一行的数量格式化
            $tds.eq(0).contents().filter(function () {
                return this.nodeType === 3; // 只修改纯文本
            }).first().replaceWith(count.toLocaleString("en-US"));

            // 判断是否是 "我的订单"
            const mineText = $tds.eq(0).find('div.MarketplacePanel_mine__3aG9I').text().trim();
            const isMine = mineText.length > 0;

            // 第 2 个 td → price
            let priceText = $tds.eq(1).find('span').first().text().trim();
            let price = ParseFormattedNumber(priceText);

            if (!isMine && lastPrice !== null && price === lastPrice) {
                // 合并逻辑:累加到上一行 count
                let prevText = lastRow.find('td').eq(0).clone().children().remove().end().text().trim();
                let prevCount = ParseFormattedNumber(prevText);

                let newCount = prevCount + count;
                lastRow.find('td').eq(0).contents().filter(function () {
                    return this.nodeType === 3;
                }).first().replaceWith(newCount.toLocaleString("en-US"));

                // 删除当前行
                $tr.remove();
            } else {
                lastPrice = price;
                lastRow = $tr;

                if (isMine) {
                    lastPrice = null;
                    lastRow = null;
                }
            }
        });
    }

    // 主逻辑
    (async () => {
        await WaitForElement('div.NavigationBar_navigationLinks__1XSSb');
        OnElementAppear('div.MarketplacePanel_orderBooksContainer__B4YE-', () => {
            const $panels = $('table.MarketplacePanel_orderBookTable__3zzrv');
            HandlePanel($panels.eq(0));
            HandlePanel($panels.eq(1));
        });
    })();
})();