Torn Set Trade Helper

Ensures "Max Flower" and "Max Plushie" buttons always stay on the trade page, correctly handling both categories separately.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Torn Set Trade Helper
// @namespace    http://tampermonkey.net/
// @version      2.5.1
// @description  Ensures "Max Flower" and "Max Plushie" buttons always stay on the trade page, correctly handling both categories separately.
// @license      MIT
// @author       YoYo
// @match        https://www.torn.com/trade.php*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // Relevant Flowers & Plushies
    const RELEVANT_FLOWERS = [
        "African Violet", "Banana Orchid", "Ceibo Flower", "Cherry Blossom",
        "Crocus", "Dahlia", "Edelweiss", "Heather", "Orchid", "Peony", "Tribulus Omanense"
    ];

    const RELEVANT_PLUSHIES = [
        "Camel Plushie", "Chamois Plushie", "Jaguar Plushie", "Kitten Plushie",
        "Lion Plushie", "Monkey Plushie", "Nessie Plushie", "Panda Plushie",
        "Red Fox Plushie", "Sheep Plushie", "Stingray Plushie", "Teddy Bear Plushie", "Wolverine Plushie"
    ];

    let userInventory = { flower: [], plushie: [] };
    let lowestItem = { flower: null, plushie: null };

    function checkTradePage() {
        if (window.location.href.includes("trade.php#step=add")) {
            console.log("Trade page detected");
            addTradeButtons();
        }
    }

    function interceptInventoryData() {
        const open = XMLHttpRequest.prototype.open;
        XMLHttpRequest.prototype.open = function (method, url) {
            if (url.includes("inventory.php")) {
                this.addEventListener("load", function () {
                    try {
                        const responseText = this.responseText;
                        const jsonData = JSON.parse(responseText);
                        if (jsonData.list) {
                            processInventory(jsonData.list);
                        }
                    } catch (error) {
                        console.error("Error parsing inventory data:", error);
                    }
                });
            }
            return open.apply(this, arguments);
        };
    }

    function processInventory(items) {
        userInventory = { flower: [], plushie: [] };
        lowestItem = { flower: null, plushie: null };

        for (const item of items) {
            if (item.type2 === "Flower" && RELEVANT_FLOWERS.includes(item.name)) {
                const parsedItem = { name: item.name, quantity: parseInt(item.Qty, 10), id: item.armoryID };
                userInventory.flower.push(parsedItem);

                if (!lowestItem.flower || parsedItem.quantity < lowestItem.flower.quantity) {
                    lowestItem.flower = parsedItem;
                }
            } else if (item.type2 === "Plushie" && RELEVANT_PLUSHIES.includes(item.name)) {
                const parsedItem = { name: item.name, quantity: parseInt(item.Qty, 10), id: item.armoryID };
                userInventory.plushie.push(parsedItem);

                if (!lowestItem.plushie || parsedItem.quantity < lowestItem.plushie.quantity) {
                    lowestItem.plushie = parsedItem;
                }
            }
        }

        console.log("Updated Inventory:", userInventory);
        console.log("Lowest Items:", lowestItem);
    }

    function addTradeButtons() {
        const footerDiv = document.querySelector(".items-footer.clearfix");
        if (!footerDiv) return;

        ["flower", "plushie"].forEach(type => {
            if (!document.getElementById(`max-${type}-btn`)) {
                const button = document.createElement("input");
                button.type = "button";
                button.value = `Max ${type.charAt(0).toUpperCase() + type.slice(1)}`;
                button.classList.add("torn-btn", "left");
                button.id = `max-${type}-btn`;
                button.style.marginLeft = "10px";
                button.addEventListener("click", () => fillMaxItems(type));
                footerDiv.appendChild(button);
            }
        });
    }

    function fillMaxItems(type) {
        if (!lowestItem[type]) {
            alert(`No ${type}s found to add.`);
            console.log(`No ${type}s found.`);
            return;
        }

        const missingItems = (type === "flower" ? RELEVANT_FLOWERS : RELEVANT_PLUSHIES).filter(name =>
            !userInventory[type].some(item => item.name === name)
        );

        if (missingItems.length > 0) {
            alert(`⚠️ Missing: ${missingItems.join(", ")}\nTrade not updated.`);
            console.log(`Missing ${type}s: ${missingItems.join(", ")} - Trade action blocked.`);
            return;
        }

        const lowestQty = lowestItem[type].quantity - 1;
        console.log(`Setting all ${type}s to ${lowestQty}.`);

        document.querySelectorAll("li.clearfix[data-group='child']").forEach(item => {
            const nameElement = item.querySelector(".t-overflow");
            if (!nameElement) return;
            const itemName = nameElement.innerText.trim();

            // Correctly distinguish flowers and plushies
            if ((type === "flower" && !RELEVANT_FLOWERS.includes(itemName)) ||
                (type === "plushie" && !RELEVANT_PLUSHIES.includes(itemName))) {
                console.log(`Skipping non-relevant ${type}: ${itemName}`);
                return;
            }

            const inputField = item.querySelector("input[name='amount']");
            if (inputField) {
                inputField.value = lowestQty;
                inputField.dispatchEvent(new Event("input", { bubbles: true }));
                console.log(`Set ${itemName} to ${lowestQty}`);
            }
        });

        alert(`All ${type}s set to ${lowestQty}.`);
    }

    function observeDOMChanges() {
        const observer = new MutationObserver(() => addTradeButtons());
        observer.observe(document.body, { childList: true, subtree: true });
    }

    window.addEventListener("load", checkTradePage);
    window.addEventListener("hashchange", checkTradePage);
    interceptInventoryData();
    observeDOMChanges();
})();