Torn Buy Filter

A script to highlight items in the item market when they are listed below a specified threshold.

// ==UserScript==
// @name         Torn Buy Filter
// @version      0.5.2
// @description  A script to highlight items in the item market when they are listed below a specified threshold.
// @author       Galdyr
// @match        https://www.torn.com/page.php?sid=ItemMarket*
// @exclude      https://www.googletagmanager.com/*
// @exclude      https://td.doubleclick.net/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=torn.com
// @grant        none
// @namespace    https://gf.qytechs.cn/users/1446982
// @license      MIT
// ==/UserScript==
 
(function() {
    'use strict';
 
    if (!window.location.href.startsWith("https://www.torn.com/page.php?sid=ItemMarket")) {
        return;
    }
 
    const buyFilters = JSON.parse(localStorage.getItem('buyFilters')) || {};
 
    function initializeBuyFilters() {
        const itemMarketRoot = document.querySelector('.itemListWrapper___ugBOt');
        if (!itemMarketRoot) {
            console.error('Item market root element not found.');
            return;
        }
 
        const itemElements = document.querySelectorAll('.itemTile___cbw7w');
        const filterOptionsBox = createFilterOptionsBox();
        const mainContent = itemMarketRoot.parentElement;
 
        mainContent.insertBefore(filterOptionsBox, mainContent.firstChild);
 
        // Match the filter box width to the item tile container.
        if (itemMarketRoot) {
            filterOptionsBox.style.width = itemMarketRoot.offsetWidth + 'px';
        }
 
        itemElements.forEach((itemElement) => {
            const itemId = getItemId(itemElement);
            if (itemId) {
                if (!document.getElementById(`filter-item-${itemId}`)) {
                    addBuyFilter(itemElement, itemId, filterOptionsBox);
                    addWatchCheckbox(itemElement, itemId);
                }
            }
        });
 
        highlightItems(); // Use highlightItems() to call both highlight functions
        setInterval(highlightItems, 1000);
    }
 
    function createFilterOptionsBox() {
        const filterOptionsBox = document.createElement('div');
        filterOptionsBox.id = 'filter-options-box';
        filterOptionsBox.style.marginTop = '10px';
        filterOptionsBox.style.borderBottom = '1px solid #ccc';
        filterOptionsBox.style.padding = '10px';
        filterOptionsBox.style.display = 'grid';
        filterOptionsBox.style.gridTemplateColumns = 'repeat(5, 1fr)'; // Fixed 5 columns
        filterOptionsBox.style.gap = '10px';
 
        const titleSpan = document.createElement('span');
        titleSpan.textContent = "Galdyr's Buy Filter";
        titleSpan.style.fontWeight = 'bold';
        filterOptionsBox.insertBefore(titleSpan, filterOptionsBox.firstChild);
 
        for (let i = 0; i < 3; i++) {
            const blankSpace = document.createElement('span');
            filterOptionsBox.insertBefore(blankSpace, filterOptionsBox.firstChild.nextSibling);
        }
 
        const collapseButton = document.createElement('span');
        collapseButton.id = 'collapse-button';
        collapseButton.textContent = '-';
        collapseButton.style.cursor = 'pointer';
        collapseButton.style.fontSize = '20px';
        collapseButton.style.fontWeight = 'bold';
        collapseButton.addEventListener('click', toggleFilters);
        filterOptionsBox.appendChild(collapseButton);
 
        return filterOptionsBox;
    }
 
    function toggleFilters() {
        const filterOptionsBox = document.getElementById('filter-options-box');
        const collapseButton = document.getElementById('collapse-button');
        filterOptionsBox.classList.toggle('collapsed');
        collapseButton.textContent = filterOptionsBox.classList.contains('collapsed') ? '+' : '-'; // Toggle icon
    }
 
    function getItemId(itemElement) {
        const actionsWrapper = itemElement.querySelector('.actionsWrapper___lfaJ0');
        if (actionsWrapper) {
            const buyButton = actionsWrapper.querySelector('.actionButton___pb_Da[aria-label*="Buy item"]');
            if (buyButton) {
                const ariaControls = buyButton.getAttribute('aria-controls');
                if (ariaControls) {
                    const itemId = ariaControls.split('-').pop();
                    return itemId;
                }
            }
        }
        return null;
    }
 
    function getItemName(itemElement) {
        const nameElement = itemElement.querySelector('.name___ukdHN');
        if (nameElement) {
            return nameElement.textContent;
        }
        return "Unknown Item";
    }
    
    function addBuyFilter(itemElement, itemId, filterOptionsBox) {
        const itemName = getItemName(itemElement);
        const filterDiv = document.createElement('div');
        filterDiv.id = `filter-item-${itemId}`;
        filterDiv.innerHTML = `<strong>${itemName}:</strong><br>
                                    <label style="margin-left: 20px;">Threshold:</label><br>
                                    <input type="number" class="buy-threshold" value="${buyFilters[itemId] && buyFilters[itemId].threshold ? buyFilters[itemId].threshold : 0}" style="margin-left: 20px;"><br>`;
    
        filterOptionsBox.appendChild(filterDiv);
    
        const thresholdInput = filterDiv.querySelector('.buy-threshold');
    
        thresholdInput.addEventListener('change', (event) => {
            if (buyFilters[itemId]) {
                buyFilters[itemId].threshold = parseInt(event.target.value, 10);
            } else {
                buyFilters[itemId] = { selected: false, threshold: parseInt(event.target.value, 10) };
            }
            localStorage.setItem('buyFilters', JSON.stringify(buyFilters)); // Save to localStorage
            highlightItems();
        });
    
    // Initialize buyFilters with stored or default values
    buyFilters[itemId] = buyFilters[itemId] || { selected: false, threshold: parseInt(thresholdInput.value, 10) };
    localStorage.setItem('buyFilters', JSON.stringify(buyFilters)); // Save to localStorage
    }

    function highlightItemTiles() {
        const itemElements = document.querySelectorAll('.itemTile___cbw7w');
        itemElements.forEach((itemElement) => {
            const itemId = getItemId(itemElement);
            if (itemId && buyFilters[itemId] && buyFilters[itemId].selected) {
                const itemPrice = getItemPrice(itemElement);
                if (itemPrice !== null && itemPrice <= buyFilters[itemId].threshold) {
                    itemElement.parentElement.style.backgroundColor = "#19166e";
                } else {
                    itemElement.parentElement.style.backgroundColor = "";
                }
            } else {
                itemElement.parentElement.style.backgroundColor = "";
            }
        });
    }

    function highlightSellerRows() {
        const sellerRows = document.querySelectorAll('.rowWrapper___me3Ox');
        sellerRows.forEach((rowElement) => {
            const sellerRow = rowElement.querySelector('.sellerRow___AI0m6');
            if (sellerRow) {
                const itemId = getItemId(sellerRow);
                if (itemId && buyFilters[itemId] && buyFilters[itemId].selected) {
                    const itemPrice = getItemPrice(sellerRow);
                    if (itemPrice !== null && itemPrice <= buyFilters[itemId].threshold) {
                        rowElement.style.backgroundColor = "#19166e";
                    } else {
                        rowElement.style.backgroundColor = "";
                    }
                } else {
                    rowElement.style.backgroundColor = "";
                }
            }
        });
    }

    function highlightItems() {
        highlightItemTiles();
        highlightSellerRows();
    }
 
    function getItemPrice(itemElement) {
        const priceElement = itemElement.querySelector('.priceAndTotal___eEVS7 span');
        if (priceElement) {
            const priceText = priceElement.textContent.replace(/[$,]/g, '');
            return parseInt(priceText, 10);
        }
        return null;
    }
 
    function addWatchCheckbox(itemElement, itemId) {
        const checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.classList.add('watch-checkbox');
        checkbox.checked = buyFilters[itemId] && buyFilters[itemId].selected ? buyFilters[itemId].selected : false;
        checkbox.style.position = 'absolute';
        checkbox.style.bottom = '5px';
        checkbox.style.left = '5px';
 
        itemElement.parentElement.style.position = 'relative';
        itemElement.parentElement.appendChild(checkbox);
 
        checkbox.addEventListener('change', (event) => {
            if (buyFilters[itemId]) {
                buyFilters[itemId].selected = event.target.checked;
            } else {
                buyFilters[itemId] = { selected: event.target.checked, threshold: 0 };
            }
            localStorage.setItem('buyFilters', JSON.stringify(buyFilters)); // Save to localStorage
            highlightItems();
        });
    }
 
    // Embed CSS for collapsing and input width
    const style = document.createElement('style');
    style.textContent = `
        #filter-options-box.collapsed {
            height: 30px;
            overflow: hidden;
            padding: 0 10px;
            border-bottom: none;
            transition: height 0.3s ease-in-out, padding 0.3s ease-in-out;
            width: 100%;
        }
        #filter-options-box > div {
            padding-top: 30px;
        }
 
        .buy-threshold {
            width: 80px; /* Adjust this value as needed */
        }
    `;
    document.head.appendChild(style);
 
    // Use MutationObserver to wait for the item list to load
    const observer = new MutationObserver((mutations) => {
        if (document.querySelector('.itemListWrapper___ugBOt')) {
            initializeBuyFilters();
            observer.disconnect();
        }
    });
 
    observer.observe(document.body, { childList: true, subtree: true });
 
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址