Greasy Fork

来自缓存

显示RW奖励价值

Show value of RW rewards.

// ==UserScript==
// @name         显示RW奖励价值
// @namespace    http://tampermonkey.net/
// @version      1.4
// @description  Show value of RW rewards.
// @author       bot_7420 [2937420]
// @match        https://www.torn.com/war.php?step=rankreport*
// @run-at       document-start
// @grant        GM.xmlHttpRequest
// @connect      api.torn.com
// ==/UserScript==

(function () {
    "use strict";

    let API_KEY = localStorage.getItem("APIKey");
    let marketValueMap = new Map();
    let pointMarketValue = 0;

    const checkRows = async () => {
        const selectedElements = document.querySelectorAll("div.memberBonusRow___XJqsX");
        if (selectedElements.length == 2) {
            console.log("RWAwardValue: found rows");
            clearInterval(timer);
            await valueRow(selectedElements[0]);
            await valueRow(selectedElements[1]);
        }
    };
    let timer = setInterval(checkRows, 200);

    async function valueRow(row) {
        let startingIndex = row.innerText.indexOf("bonus respect, ") + 15;
        let awardsString = row.innerText.substring(startingIndex, row.innerText.length);
        console.log("RWAwardValue: " + awardsString);

        let rowTotalValue = 0;
        let totalBB = 0;
        const backgroundColor = document.body.classList.contains("dark-mode") ? "#002800" : "#b5e7a0";
        let appendInnerHTML = `<div style="background-color: ${backgroundColor};">`;

        for (const item of awardsString.split(", ")) {
            if (item.includes("points")) {
                const pointValue = await valuePoint();
                const numOfPoints = parseInt(item.substring(0, item.indexOf(" ")).replace(",", ""));
                rowTotalValue += pointValue * numOfPoints;
                const resultString = item + " (" + numberFormatter(pointValue) + " each)<br>";
                appendInnerHTML += resultString;
            } else if (item.includes("Armor Cache")) {
                const cacheValue = await valueCache(1118);
                rowTotalValue += cacheValue * parseInt(item.substring(0, item.indexOf("x")));
                totalBB += 60 * parseInt(item.substring(0, item.indexOf("x")));
                const resultString = item + " (" + numberFormatter(cacheValue) + " each)<br>";
                appendInnerHTML += resultString;
            } else if (item.includes("Melee Cache")) {
                const cacheValue = await valueCache(1119);
                rowTotalValue += cacheValue * parseInt(item.substring(0, item.indexOf("x")));
                totalBB += 30 * parseInt(item.substring(0, item.indexOf("x")));
                const resultString = item + " (" + numberFormatter(cacheValue) + " each)<br>";
                appendInnerHTML += resultString;
            } else if (item.includes("Small Arms Cache")) {
                const cacheValue = await valueCache(1120);
                rowTotalValue += cacheValue * parseInt(item.substring(0, item.indexOf("x")));
                totalBB += 20 * parseInt(item.substring(0, item.indexOf("x")));
                const resultString = item + " (" + numberFormatter(cacheValue) + " each)<br>";
                appendInnerHTML += resultString;
            } else if (item.includes("Medium Arms Cache")) {
                const cacheValue = await valueCache(1121);
                rowTotalValue += cacheValue * parseInt(item.substring(0, item.indexOf("x")));
                totalBB += 50 * parseInt(item.substring(0, item.indexOf("x")));
                const resultString = item + " (" + numberFormatter(cacheValue) + " each)<br>";
                appendInnerHTML += resultString;
            } else if (item.includes("Heavy Arms Cache")) {
                const cacheValue = await valueCache(1122);
                rowTotalValue += cacheValue * parseInt(item.substring(0, item.indexOf("x")));
                totalBB += 70 * parseInt(item.substring(0, item.indexOf("x")));
                const resultString = item + " (" + numberFormatter(cacheValue) + " each)<br>";
                appendInnerHTML += resultString;
            }
        }

        appendInnerHTML += "Total value: " + numberFormatter(rowTotalValue, 2) + " (" + totalBB + " Bunker Bucks)";
        appendInnerHTML += `</div>`;
        row.innerHTML += appendInnerHTML;
    }

    function valueCache(itemId) {
        if (marketValueMap.has(itemId)) {
            return marketValueMap.get(itemId);
        }

        return new Promise((resolve, reject) => {
            GM.xmlHttpRequest({
                url: `https://api.torn.com/torn/${itemId}?selections=items&key=${API_KEY}`,
                method: "POST",
                synchronous: true,
                onload: async (response) => {
                    if (response.status == 200) {
                        const body = JSON.parse(response.responseText);
                        let marketValue = body.items[itemId].market_value;
                        if (!marketValue || marketValue <= 0) {
                            marketValue = await valueCacheBazaar(itemId);
                        }
                        marketValueMap.set(itemId, marketValue);
                        resolve(marketValue);
                    } else {
                        console.error("RWAwardValue: valueCache API fetch onload with HTTP status " + response.status);
                        resolve(0);
                    }
                },
                onabort: () => {
                    console.error("RWAwardValue: valueCache API fetch onabort");
                    resolve(0);
                },
                onerror: () => {
                    console.error("RWAwardValue: valueCache API fetch onerror");
                    resolve(0);
                },
                ontimeout: () => {
                    console.error("RWAwardValue: valueCache API fetch ontimeout");
                    resolve(0);
                },
            });
        });
    }

    function valueCacheBazaar(itemId) {
        return new Promise((resolve, reject) => {
            GM.xmlHttpRequest({
                url: `https://api.torn.com/market/${itemId}?selections=bazaar&key=${API_KEY}`,
                method: "POST",
                synchronous: true,
                onload: (response) => {
                    if (response.status == 200) {
                        const body = JSON.parse(response.responseText);
                        const bazaarValue = body.bazaar[0].cost;
                        resolve(bazaarValue);
                    } else {
                        console.error("RWAwardValue: valueCacheBazaar API fetch onload with HTTP status " + response.status);
                        resolve(0);
                    }
                },
                onabort: () => {
                    console.error("RWAwardValue: valueCacheBazaar API fetch onabort");
                    resolve(0);
                },
                onerror: () => {
                    console.error("RWAwardValue: valueCacheBazaar API fetch onerror");
                    resolve(0);
                },
                ontimeout: () => {
                    console.error("RWAwardValue: valueCacheBazaar API fetch ontimeout");
                    resolve(0);
                },
            });
        });
    }

    function valuePoint() {
        if (pointMarketValue > 0) {
            return pointMarketValue;
        }

        return new Promise((resolve, reject) => {
            GM.xmlHttpRequest({
                url: `https://api.torn.com/market/?selections=pointsmarket&key=${API_KEY}`,
                method: "POST",
                synchronous: true,
                onload: (response) => {
                    if (response.status == 200) {
                        const body = JSON.parse(response.responseText);
                        pointMarketValue = body.pointsmarket[Object.keys(body.pointsmarket)[1]].cost;
                        resolve(pointMarketValue);
                    } else {
                        console.error("RWAwardValue: valuePoint API fetch onload with HTTP status " + response.status);
                        resolve(0);
                    }
                },
                onabort: () => {
                    console.error("RWAwardValue: valuePoint API fetch onabort");
                    resolve(0);
                },
                onerror: () => {
                    console.error("RWAwardValue: valuePoint API fetch onerror");
                    resolve(0);
                },
                ontimeout: () => {
                    console.error("RWAwardValue: valuePoint API fetch ontimeout");
                    resolve(0);
                },
            });
        });
    }

    function numberFormatter(num, digits = 1) {
        const lookup = [
            { value: 1, symbol: "" },
            { value: 1e3, symbol: "k" },
            { value: 1e6, symbol: "M" },
            { value: 1e9, symbol: "B" },
        ];
        const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
        var item = lookup
            .slice()
            .reverse()
            .find(function (item) {
                return num >= item.value;
            });
        return item ? (num / item.value).toFixed(digits).replace(rx, "$1") + item.symbol : "0";
    }
})();