SimCompanies-Torn

Enhancements for SimCompanies web game. Complies with scripting rules of the game.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         SimCompanies-Torn
// @namespace    http://tampermonkey.net/
// @version      1.9
// @description  Enhancements for SimCompanies web game. Complies with scripting rules of the game.
// @author       MOBIL SUPER (bot_7420)
// @match        https://www.simcompanies.com/*
// @require      https://cdn.bootcdn.net/ajax/libs/Chart.js/4.4.0/chart.umd.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/chartjs-adapter-date-fns.bundle.min.js
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @connect      simcotools.app
// @run-at       document-start
// ==/UserScript==

(function () {
    "use strict";

    const CustomExchangeInputPrices = [0, 3840, 2880, 60]; // 交易所页面,自定义输入购买数量按钮
    const CustomProductionTimeInputs = ["8am", "10pm", "6hr", "12hr"]; // 生产页面,自定义输入生产时间按钮
    const ContractDiscount = 0.98; // 出售商品页面,合同MP价折扣

    let pageSpecifiedTimersList = [];
    let notesElement = null;
    let lastCompanyJson = null;

    let lastKnownURL = "";
    const mainCheckingURLLoop = () => {
        const currentURL = window.location.href;
        if (currentURL !== lastKnownURL) {
            handleURLChange(currentURL);
            lastKnownURL = currentURL;
        }
    };

    // Hook XMLHttpRequest https://www.simcompanies.com/api/v2/companies-by-company/0/XXXXXX/
    (function (open) {
        XMLHttpRequest.prototype.open = function () {
            this.addEventListener(
                "readystatechange",
                function () {
                    if (this.responseURL.indexOf("/companies-by-company/") != -1 && this.readyState === 4) {
                        const json = JSON.parse(this.response);
                        lastCompanyJson = json;
                    }
                },
                false
            );
            open.apply(this, arguments);
        };
    })(XMLHttpRequest.prototype.open);

    window.onload = () => {
        console.log("SimCompanies-Torn: onload");
        while (pageSpecifiedTimersList.length > 0) {
            clearInterval(pageSpecifiedTimersList.pop());
        }
        global_addCSS();
        global_addNavButtons();
        const currentURL = window.location.href;
        lastKnownURL = currentURL;
        handleURLChange(currentURL);
        setInterval(mainCheckingURLLoop, 1000);
    };

    function handleURLChange(currentURL) {
        console.log("SimCompanies-Torn: handleURLChange");
        while (pageSpecifiedTimersList.length > 0) {
            clearInterval(pageSpecifiedTimersList.pop());
        }
        if (currentURL.includes("/landscape/")) {
            handleLandscape();
        } else if (
            currentURL.includes("/warehouse/") &&
            currentURL !== "https://www.simcompanies.com/zh/headquarters/warehouse/" &&
            !currentURL.includes("/warehouse/incoming-contracts/") &&
            !currentURL.includes("/warehouse/outgoing-contracts/") &&
            !currentURL.includes("/warehouse/stats/") &&
            !currentURL.includes("/warehouse/research/")
        ) {
            handleWarehouseItem();
        } else if (currentURL.includes("/b/")) {
            handleCustomHourInput();
        } else if (currentURL.includes("/market/resource/")) {
            // 交易所 高亮6件最近访问物品
            handleExchangeHighlightRecent();
            // 交易所 自定义输入价格
            handleExchangeCustomInputPrices();
        } else if (currentURL.includes("/company/0/") || currentURL.includes("/company/1/")) {
            // 公司资料页
            handleProfilePage();
        }
    }

    async function handleSimcoToolsAPI() {
        const checkElementExist = () => {
            const selectedElem = document.querySelector(`input.css-1whp23o.form-control[name="quantity"]`);
            if (selectedElem) {
                clearInterval(timer);
                const parent = document.querySelector(`div.css-10klw3m.col-sm-8.col-xs-12`);
                let container = document.querySelector(`div#script_market_container`);
                if (!container) {
                    container = document.createElement("div");
                    container.id = "script_market_container";
                    container.style.padding = "0px 5px";
                    parent.insertBefore(container, parent.firstChild);
                } else {
                    container.innerHTML = "";
                }

                let realm = 0;
                if (document.querySelector(`div.css-inxa61.e1uuitfi4 img[alt*="企业家"]`)) {
                    realm = 1;
                }
                const array = window.location.href.split("/");
                let itemId = array[array.length - 2];
                console.log("SimCompanies-Torn: handleSimcoToolsAPI " + realm + " " + itemId);

                GM_xmlhttpRequest({
                    method: "GET",
                    url: `https://simcotools.app/api/v3/resources/${itemId}?realm=${realm}`,
                    headers: {
                        "Content-Type": "application/json",
                    },
                    onload: function (response) {
                        const json = JSON.parse(response.response);
                        const p = document.createElement("p");
                        let text =
                            "当前: $" +
                            json.latest_price.toFixed(3) +
                            "<br>日均: $" +
                            json.prices_resume.average.toFixed(3) +
                            "&nbsp;&nbsp;&nbsp;最高: $" +
                            json.prices_resume.max.toFixed(3) +
                            "&nbsp;&nbsp;&nbsp;最低: $" +
                            json.prices_resume.min.toFixed(3);
                        p.innerHTML = text;
                        p.style.fontSize = "18px";
                        container.insertBefore(p, container.firstChild);
                    },
                });

                // Add chart
                GM_xmlhttpRequest({
                    method: "GET",
                    url: `https://simcotools.app/api/v3/resources/${itemId}/history?realm=${realm}&quality=null&date=&period=3&comparison=1`,
                    headers: {
                        "Content-Type": "application/json",
                    },
                    onload: function (response3) {
                        GM_xmlhttpRequest({
                            method: "GET",
                            url: `https://simcotools.app/api/v3/resources/${itemId}/records?realm=${realm}&quality=null&date=&period=1&comparison=previous`,
                            headers: {
                                "Content-Type": "application/json",
                            },
                            onload: function (response0) {
                                const json3 = JSON.parse(response3.response);
                                const json0 = JSON.parse(response0.response);
                                let dataThreeMonths = json3.history;
                                for (const record of json0.records) {
                                    record.average = record.price;
                                }
                                let dataOneDay = json0.records;
                                let dataOneMonth = [];
                                for (let i = dataThreeMonths.length - 1; i > dataThreeMonths.length - 31; i--) {
                                    dataOneMonth.push(dataThreeMonths[i]);
                                }

                                const div = document.createElement("div");
                                div.style.width = "100%";
                                div.style.height = "240px";
                                const canvas = document.createElement("canvas");
                                canvas.id = "script_market_canvas";
                                div.appendChild(canvas);
                                container.appendChild(div);
                                buildChart(canvas, [dataOneDay, dataOneMonth, dataThreeMonths]);
                            },
                        });
                    },
                });
            }
        };
        let timer = setInterval(checkElementExist, 100);
    }

    function buildChart(canvas, data) {
        new Chart(canvas, {
            type: "line",
            data: {
                datasets: [
                    {
                        label: "1 Day",
                        data: data[0],
                        pointRadius: 0,
                    },
                    {
                        label: "1 Month",
                        data: data[1],
                        pointRadius: 0,
                        hidden: true,
                    },
                    {
                        label: "3 Months",
                        data: data[2],
                        pointRadius: 0,
                        hidden: true,
                    },
                ],
            },
            options: {
                parsing: {
                    xAxisKey: "date",
                    yAxisKey: "average",
                },
                scales: {
                    x: {
                        type: "time",
                        time: {
                            tooltipFormat: "yyyy/MM/dd HH:mm",
                            displayFormats: {
                                day: "MM/dd",
                            },
                        },
                    },
                },
                plugins: {
                    legend: {
                        onClick: (e, legendItem, legend) => {
                            let index = legendItem.datasetIndex;
                            let ci = legend.chart;
                            ci.data.datasets.forEach(function (e, i) {
                                let meta = ci.getDatasetMeta(i);
                                if (i !== index) {
                                    meta.hidden = true;
                                } else {
                                    meta.hidden = false;
                                }
                            });
                            ci.update();
                        },
                    },
                },
            },
        });
    }

    function handleProfilePage() {
        const checkElementExist = () => {
            const selectedElems = document.querySelectorAll(`div.css-1156ixp.e1addz3e7 div.css-7ip5xj.e1addz3e6 div`);
            if (selectedElems.length > 10) {
                clearInterval(timer);
                let list = [];
                for (const elem of selectedElems) {
                    if (elem.querySelector(`span`)) {
                        list.push(elem.querySelector(`span`).querySelector(`span`).innerText);
                    }
                }
                const map = list.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map());
                const sortedMap = new Map([...map.entries()].sort((a, b) => b[1] - a[1]));
                let totalBuildingNum = 0;
                map.forEach((value) => {
                    totalBuildingNum += value;
                });
                let totalBuildingLevel = Number(document.querySelectorAll(`table.css-n6qpdi.et7yomk6`)[2].querySelectorAll(`tr`)[1].querySelectorAll(`td`)[1].innerHTML.replace(",", "")) / 100;
                let averageBuildingLevel = (totalBuildingLevel / totalBuildingNum).toFixed(1);

                const container = document.createElement("div");
                const div = document.createElement("div");
                const span = document.createElement("span");
                span.innerHTML = "建筑总数量: " + totalBuildingNum + "&emsp;总建筑等级: " + totalBuildingLevel + "&emsp;平均建筑等级: " + averageBuildingLevel;
                span.style.fontSize = "25px";
                span.style.padding = "5px 5px";
                span.style.background = "#FFC107";
                span.style.zIndex = "300";
                span.style.position = "relative";
                div.appendChild(span);
                container.appendChild(div);
                for (const [key, value] of sortedMap) {
                    const div = document.createElement("div");
                    const span = document.createElement("span");
                    span.innerHTML = key + " X " + value;
                    span.style.fontSize = "22px";
                    span.style.padding = "5px 5px";
                    span.style.background = "#FFC107";
                    span.style.zIndex = "300";
                    span.style.position = "relative";
                    div.appendChild(span);
                    container.appendChild(div);
                }
                const board = document.querySelector(`div.css-1156ixp.e1addz3e7 div.css-7ip5xj.e1addz3e6`);
                board.insertBefore(container, board.firstChild);

                // 移动展柜至下方
                const row = document.querySelector(`div.col-md-8 > div.row`);
                const target = row.querySelector(`div.col-sm-12`);
                if (target) {
                    target.parentNode.appendChild(target);
                }

                // API查询历史数据
                const id = lastCompanyJson.company.id;
                const name = lastCompanyJson.company.company;
                const level = lastCompanyJson.company.level;
                const realmId = lastCompanyJson.company.realmId;
                console.log("SimCompanies-Torn: handleProfilePage " + realmId + " " + id + " " + name);
                GM_xmlhttpRequest({
                    method: "GET",
                    url: `https://simcotools.app/api/v2/companies/${realmId}/${id}`,
                    headers: {
                        "Content-Type": "application/json",
                    },
                    onload: function (response) {
                        const valueList = JSON.parse(response.response).historical;
                        let average = 0;
                        let size = valueList.length > 7 ? 7 : valueList.length - 1;
                        for (let i = 0; i < size; i++) {
                            average += valueList[valueList.length - 1 - i].value - valueList[valueList.length - 2 - i].value;
                        }
                        average /= size;

                        const div = document.createElement("div");
                        const span = document.createElement("span");
                        span.innerHTML = name + " [" + id + "]&emsp;公司等级: " + level + "&emsp;近一周日均增长: $" + numberAddCommas(average.toFixed(0));
                        span.style.fontSize = "25px";
                        span.style.padding = "5px 5px";
                        span.style.background = "#FFC107";
                        span.style.zIndex = "300";
                        span.style.position = "relative";
                        div.appendChild(span);
                        container.insertBefore(div, container.firstChild);
                    },
                });
            }
        };
        let timer = setInterval(checkElementExist, 100);
    }

    function handleExchangeHighlightRecent() {
        const checkElementExist = () => {
            const selectedElems = document.querySelectorAll(`a.hover-effect.css-k8l72z`);
            if (selectedElems.length > 50) {
                const recentExchangeItemsString = localStorage.getItem("recentlyVisitedExchangeResources");
                const recentExchangeItems = JSON.parse(recentExchangeItemsString);
                for (const elem of selectedElems) {
                    elem.classList.remove("script-highlighted");
                }
                let markedNum = 0;
                for (const itemId of recentExchangeItems) {
                    if (markedNum < 6) {
                        markedNum++;
                        const target = document.querySelector(`div.css-hf83mx a.hover-effect.css-k8l72z[href*="/resource/${itemId}/"]`);
                        target.classList.add("script-highlighted");
                    }
                }
            }
        };
        const tempTimer = setInterval(checkElementExist, 1000);
        pageSpecifiedTimersList.push(tempTimer);
    }

    function handleExchangeCustomInputPrices() {
        const checkElementExist = () => {
            const selectedElem = document.querySelector(`input.css-1whp23o.form-control[name="quantity"]`);
            if (selectedElem) {
                clearInterval(timer);
                for (const price of CustomExchangeInputPrices) {
                    let a = document.createElement("a");
                    let linkText = document.createTextNode(" " + price + " ");
                    a.style.padding = "10px 5px";
                    a.appendChild(linkText);
                    a.onclick = () => {
                        setInput(selectedElem, price);
                    };
                    selectedElem.parentNode.parentNode.parentNode.appendChild(a);
                }
                // 显示SimcoTools API信息
                handleSimcoToolsAPI();
            }
        };
        let timer = setInterval(checkElementExist, 100);
    }

    function setInput(inputNode, value) {
        let lastValue = inputNode.value;
        inputNode.value = value;
        let event = new Event("input", { bubbles: true });
        event.simulated = true;
        if (inputNode._valueTracker) inputNode._valueTracker.setValue(lastValue);
        inputNode.dispatchEvent(event);
    }

    function handleCustomHourInput() {
        const checkElementExist = () => {
            const selectedElems = document.querySelectorAll("h3 > svg");
            let isReady = selectedElems.length > 0;
            if (isReady) {
                selectedElems.forEach((node) => {
                    isReady = isReady && node?.parentElement?.parentElement?.querySelector("div > button")?.parentElement;
                });
            }
            if (isReady) {
                clearInterval(timer);
                selectedElems.forEach((node) => {
                    let targetNode = node.parentElement.parentElement.querySelector("div > button").parentElement;
                    for (const text of CustomProductionTimeInputs) {
                        let newNode = document.createElement("button");
                        newNode.className = "script_custom_hour_button";
                        Object.assign(newNode, { type: "button", role: "button" });
                        newNode.onclick = (e) => {
                            let target_node = e.target.parentElement.parentElement.querySelector("input");
                            let target_text = e.target.innerText;
                            target_node.click();
                            setInput(target_node, target_text);
                            e.preventDefault();
                        };
                        let commonClass = targetNode.querySelector("button").className;
                        newNode.className += ` ${commonClass}`;
                        newNode.innerText = text;
                        targetNode.prepend(newNode);
                    }
                });
            }
        };
        let timer = setInterval(checkElementExist, 100);
    }

    function handleWarehouseItem() {
        const checkElementExist = () => {
            const table = document.querySelector(`.css-1vwotq4.e12j7voa6`);
            const input = document.querySelector(`input[name="price"]`);
            const amountSpans = document.querySelectorAll(`div.css-81vhsj.e12j7voa12 span.css-14is9qy.e12j7voa17`);
            if (table && input && !input.classList.contains("script_checked")) {
                // 出售时自动填价 当前MP
                let exchangePrice = Number(table.querySelector("span.css-rnnx2x").nextSibling.nextSibling.textContent.replace(",", ""));
                let discountedPrice = exchangePrice * ContractDiscount;
                exchangePrice = exchangePrice.toFixed(3);
                discountedPrice = discountedPrice.toFixed(3);
                input.classList.add("script_checked");

                let elem = document.createElement("a");
                let linkText = document.createTextNode("当前MP = $" + exchangePrice);
                elem.appendChild(linkText);
                elem.onclick = () => {
                    setInput(input, exchangePrice);
                };
                elem.style.display = "block";
                input.parentNode.insertBefore(elem, input.nextSibling);

                let elem2 = document.createElement("a");
                let linkText2 = document.createTextNode("当前MP-" + ((1 - ContractDiscount) * 100).toFixed(0) + "% = $" + discountedPrice);
                elem2.appendChild(linkText2);
                elem2.onclick = () => {
                    setInput(input, discountedPrice);
                };
                elem2.style.display = "block";
                elem.parentNode.insertBefore(elem2, elem.nextSibling);

                if (document.querySelector(`h3.css-bi2xxi.e1bf4c272`).innerText === "收件方") {
                    setInput(input, discountedPrice);
                    elem2.style.background = "#FFC107";
                } else {
                    setInput(input, exchangePrice);
                    elem.style.background = "#FFC107";
                }
            } else if (table && input && input.classList.contains("script_checked") && !input.classList.contains("script_checked_2") && amountSpans[0].classList.contains("script_checked")) {
                // 出售时自动填价 日均MP
                let avg = Number(amountSpans[0].getAttribute("script-avg-mp").replace(",", ""));
                let discountedAvg = avg * ContractDiscount;
                avg = avg.toFixed(3);
                discountedAvg = discountedAvg.toFixed(3);
                input.classList.add("script_checked_2");

                let elem = document.createElement("a");
                let linkText = document.createTextNode("日均MP = $" + avg);
                elem.appendChild(linkText);
                elem.onclick = () => {
                    setInput(input, avg);
                };
                elem.style.display = "block";
                input.parentNode.appendChild(elem);

                let elem2 = document.createElement("a");
                let linkText2 = document.createTextNode("日均MP-" + ((1 - ContractDiscount) * 100).toFixed(0) + "% = $" + discountedAvg);
                elem2.appendChild(linkText2);
                elem2.onclick = () => {
                    setInput(input, discountedAvg);
                };
                elem2.style.display = "block";
                input.parentNode.appendChild(elem2);

                if (document.querySelector(`h3.css-bi2xxi.e1bf4c272`).innerText === "收件方") {
                    elem2.style.background = "#FFC107";
                } else {
                    elem.style.background = "#FFC107";
                }
            } else if (table && amountSpans.length >= 2 && !amountSpans[0].classList.contains("script_checked")) {
                // 查看单个商品时 显示预估总价值
                amountSpans[0].classList.add("script_checked");
                let exchangePrice = Number(table.querySelector("span.css-rnnx2x").nextSibling.nextSibling.textContent.replace(",", ""));
                let discountedPrice = exchangePrice * 0.97;
                let itemAmount = Number(amountSpans[0].textContent.replace(",", ""));
                let totalValue = discountedPrice * itemAmount;
                totalValue = totalValue.toFixed(0);
                const newContainer = document.createElement("span");
                const newTextNode = document.createTextNode("(当前MP-3%总价值 $" + numberAddCommas(totalValue) + ")");
                newContainer.appendChild(newTextNode);
                newContainer.style.background = "#FFC107";
                newContainer.style.fontSize = "18px";
                amountSpans[0].nextSibling.nextSibling.after(newContainer);

                // 查看单个商品时 显示API图表
                const parent = document.querySelector(`div.css-1iegaby.e12j7voa18 > div.row`).children[1];
                let container = document.querySelector(`div#script_market_container`);
                if (!container) {
                    container = document.createElement("div");
                    container.id = "script_market_container";
                    container.style.padding = "0px 5px";
                    parent.insertBefore(container, parent.firstChild);
                } else {
                    container.innerHTML = "";
                }

                let realm = 0;
                if (document.querySelector(`div.css-inxa61.e1uuitfi4 img[alt*="企业家"]`)) {
                    realm = 1;
                }
                const array = table.parentNode.href.split("/");
                let itemId = array[array.length - 2];
                console.log("SimCompanies-Torn: handleSimcoToolsAPI " + realm + " " + itemId);

                GM_xmlhttpRequest({
                    method: "GET",
                    url: `https://simcotools.app/api/v3/resources/${itemId}?realm=${realm}`,
                    headers: {
                        "Content-Type": "application/json",
                    },
                    onload: function (response) {
                        const json = JSON.parse(response.response);
                        amountSpans[0].setAttribute("script-avg-mp", json.prices_resume.average.toFixed(3));
                        const p = document.createElement("p");
                        let text =
                            "当前: $" +
                            json.latest_price.toFixed(3) +
                            "<br>日均: $" +
                            json.prices_resume.average.toFixed(3) +
                            "&nbsp;&nbsp;&nbsp;最高: $" +
                            json.prices_resume.max.toFixed(3) +
                            "&nbsp;&nbsp;&nbsp;最低: $" +
                            json.prices_resume.min.toFixed(3);
                        p.innerHTML = text;
                        p.style.fontSize = "18px";
                        container.insertBefore(p, container.firstChild);
                    },
                });

                // Add chart
                GM_xmlhttpRequest({
                    method: "GET",
                    url: `https://simcotools.app/api/v3/resources/${itemId}/history?realm=${realm}&quality=null&date=&period=3&comparison=1`,
                    headers: {
                        "Content-Type": "application/json",
                    },
                    onload: function (response3) {
                        GM_xmlhttpRequest({
                            method: "GET",
                            url: `https://simcotools.app/api/v3/resources/${itemId}/records?realm=${realm}&quality=null&date=&period=1&comparison=previous`,
                            headers: {
                                "Content-Type": "application/json",
                            },
                            onload: function (response0) {
                                const json3 = JSON.parse(response3.response);
                                const json0 = JSON.parse(response0.response);
                                let dataThreeMonths = json3.history;
                                for (const record of json0.records) {
                                    record.average = record.price;
                                }
                                let dataOneDay = json0.records;
                                let dataOneMonth = [];
                                for (let i = dataThreeMonths.length - 1; i > dataThreeMonths.length - 31; i--) {
                                    dataOneMonth.push(dataThreeMonths[i]);
                                }

                                const div = document.createElement("div");
                                div.style.width = "100%";
                                div.style.height = "240px";
                                const canvas = document.createElement("canvas");
                                canvas.id = "script_market_canvas";
                                div.appendChild(canvas);
                                container.appendChild(div);
                                buildChart(canvas, [dataOneDay, dataOneMonth, dataThreeMonths]);
                            },
                        });
                    },
                });
            }
        };
        const tempTimer = setInterval(checkElementExist, 500);
        pageSpecifiedTimersList.push(tempTimer);
    }

    function handleLandscape() {
        const checkElementExist = () => {
            if (document.getElementsByClassName("test-headquarters").length > 0) {
                clearInterval(timer);
                // 移除氪金加速建造按钮
                landscape_removeRush();
                // 高亮闲置建筑
                landscape_highlightIdleBuildings();
                const tempTimer = setInterval(landscape_highlightIdleBuildings, 2000);
                pageSpecifiedTimersList.push(tempTimer);
                // 移动收菜图标
                landscape_moveGatheringIcons();
                const tempTimer2 = setInterval(landscape_moveGatheringIcons, 2000);
                pageSpecifiedTimersList.push(tempTimer2);
            }
        };
        let timer = setInterval(checkElementExist, 100);
    }

    function landscape_moveGatheringIcons() {
        const icons = document.querySelectorAll("img.css-hqao0z.ejaaut33");
        for (const icon of icons) {
            if (!icon.classList.contains("script_moved_to_top_right")) {
                icon.classList.add("script_moved_to_top_right");
            }
        }
    }

    function landscape_removeRush() {
        const banners = document.querySelectorAll(".link-button.css-lgo4vi");
        for (const elm of banners) {
            elm.style.display = "none";
        }
    }

    function landscape_highlightIdleBuildings() {
        const buildingBlocks = document.querySelector(".css-fgicw8.e1addz3e6").querySelectorAll(`a[href*="/b/"]`);
        for (const building of buildingBlocks) {
            const namePlate = building.querySelector(`span.display-on-hover.css-de40ak.eofzx9a3`);
            if (namePlate.style.display === "block") {
                namePlate.querySelector(`span.css-11ivg5k`).style.background = "#FFC107";
            }
        }
    }

    function global_addCSS() {
        // 百科 宽屏
        GM_addStyle(`
        div.container.css-q9fi5t.ef8ljhx0 {
            width: 100% !important;
        }`);

        // 百科 左右栏比例1:1
        GM_addStyle(`
        div.container.css-q9fi5t.ef8ljhx0 .col-md-4:has(> :last-child:nth-child(1)) {
            width: 50% !important;
        }`);
        GM_addStyle(`
        div.container.css-q9fi5t.ef8ljhx0 .col-md-8:has(> :last-child:nth-child(1)) {
            width: 50% !important;
        }`);

        // 百科 左侧栏减少空白
        GM_addStyle(`
        div.css-1pbe8e5 div.col-xs-3.css-d2zl4q{
            width: 63px !important;
            padding-right: 2px !important;
            padding-left: 2px !important;
        }`);

        // 交易所 宽屏
        GM_addStyle(`
        .css-fbokx6 {
            width: 100% !important;
        }`);

        // 交易所 左右栏比例1:1
        GM_addStyle(`
        div.css-1nu3wfe div.css-fbokx6.container .col-sm-4 {
            width: 50% !important;
        }`);
        GM_addStyle(`
        div.css-1nu3wfe div.css-fbokx6.container .col-sm-8 {
            width: 50% !important;
        }`);

        // 交易所 左侧栏显示物品名称
        GM_addStyle(`
        .css-1luaoxw {
            display: block !important;
        }`);

        // 交易所 左侧栏减少空白
        GM_addStyle(`
        h4.css-0 {
            margin-top: 3px !important;
            margin-bottom: 3px !important;
        }`);
        GM_addStyle(`
        h4.css-o7rt0f {
            margin-top: 3px !important;
            margin-bottom: 3px !important;
        }`);

        // 交易所 隐藏最近访问栏
        GM_addStyle(`
        .css-1a75jih {
            display: none !important;
        }`);

        // 顶部自定义导航按钮样式
        GM_addStyle(`
        .script-nav-1 {
            margin-left: 50px;
            font-size: 18px;
            position: absolute;
            top: 50%;
            -ms-transform: translateY(-50%);
            transform: translateY(-50%);
            color: rgb(184,184,184);
        }`);
        GM_addStyle(`
        .script-nav-2 {
            margin-left: 100px;
            font-size: 18px;
            position: absolute;
            top: 50%;
            -ms-transform: translateY(-50%);
            transform: translateY(-50%);
            color: rgb(184,184,184);
        }`);

        // 收菜图标移动
        GM_addStyle(`
        .script_moved_to_top_right {
            position:fixed !important;
            top:80% !important;
            border:1px solid black !important;
            z-index: 300 !important;
        }`);

        // 聊天弹窗
        GM_addStyle(`
        .css-1tvnvpv {
            left: 5px !important;
            bottom: 5px !important;
            max-width: 350px !important;
            width: 100% !important;
            z-index: 300 !important;
        }`);
        GM_addStyle(`
        .css-lwisbd {
            height: 43px !important;
            margin-top: 2px !important;
        }`);
        GM_addStyle(`
        .chat-notifications .chat-notification img.logo {
            height: 33px !important;
            width: 33px !important;
        }`);

        // 高亮
        GM_addStyle(`
        .script-highlighted {
            background-color: #FFC107 !important;
        }`);

        // 记事本
        GM_addStyle(`
        .script-nav-3 {
            margin-left: 150px;
            font-size: 18px;
            position: absolute;
            top: 50%;
            -ms-transform: translateY(-50%);
            transform: translateY(-50%);
            color: rgb(184,184,184);
        }`);
        GM_addStyle(`
        textarea.script_notes {
            position:fixed;
            bottom:1%;
            right:1%;
            z-index: 200;
            font-size: 16px;
            background-color: #DCDCDC;
            max-width: 400px;
            max-height: 600px;
        }`);

        // 市场图表
        GM_addStyle(`
        div#script_market_container {
            width: 100%;
            height: 300px;
            background-color: #B2D7DA;
        }`);

        // 隐藏氪金促销图标
        GM_addStyle(`
        a.css-s50znf > div.css-xgljd5 {
            visibility: hidden;
        }`);
    }

    function global_addNavButtons() {
        const checkElementExist = () => {
            if (document.querySelector(".css-145d0e.e1kr4hqh1")) {
                clearInterval(timer);
                setTimeout(function () {
                    const selectedElem = document.querySelector(".css-145d0e.e1kr4hqh1");
                    let a1 = document.createElement("a");
                    let linkText1 = document.createTextNode("文库");
                    a1.appendChild(linkText1);
                    a1.onclick = () => {
                        let targetButton = document.querySelector(`a[aria-label="文库"]`);
                        if (!targetButton) {
                            document.querySelector(`.css-1ljhlhi`).click();
                            targetButton = document.querySelector(`a[aria-label="文库"]`);
                        }
                        targetButton.click();
                    };
                    a1.classList.add("script-nav-1");
                    selectedElem.parentNode.insertBefore(a1, selectedElem.nextSibling);

                    let a2 = document.createElement("a");
                    let linkText2 = document.createTextNode("百科");
                    a2.appendChild(linkText2);
                    a2.onclick = () => {
                        let targetButton = document.querySelector(`a[aria-label="百科"]`);
                        if (!targetButton) {
                            document.querySelector(`.css-1ljhlhi`).click();
                            targetButton = document.querySelector(`a[aria-label="百科"]`);
                        }
                        targetButton.click();
                    };
                    a2.classList.add("script-nav-2");
                    selectedElem.parentNode.insertBefore(a2, selectedElem.nextSibling);

                    let a3 = document.createElement("a");
                    let linkText3 = document.createTextNode("[笔记]");
                    a3.appendChild(linkText3);
                    a3.onclick = () => {
                        handleNotes();
                    };
                    a3.classList.add("script-nav-3");
                    selectedElem.parentNode.insertBefore(a3, selectedElem.nextSibling);
                }, 500);
            }
        };
        let timer = setInterval(checkElementExist, 100);
    }

    function handleNotes() {
        if (!notesElement) {
            const notesString = localStorage.getItem("script_notes");
            notesElement = document.createElement("textarea");
            notesElement.classList.add("script_notes");
            notesElement.setAttribute("cols", "40");
            notesElement.setAttribute("rows", "10");
            notesElement.setAttribute("placeholder", "笔记内容本地保存,重要信息请另行备份");
            notesElement.style.display = "block";
            notesElement.innerHTML = notesString;
            notesElement.addEventListener(
                "input",
                () => {
                    localStorage.setItem("script_notes", notesElement.value);
                },
                false
            );
            document.body.appendChild(notesElement);
        } else if (notesElement.style.display === "none") {
            notesElement.style.display = "block";
        } else {
            notesElement.style.display = "none";
        }
    }

    function numberAddCommas(x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }
})();