Sleazy Fork is available in English.

Zalp's Dumpster Diver

Highlights items on the market that are cheaper than their recycling value. One's trash is another's treasure. Prices updated as of 2025-05-10.

// ==UserScript==
// @name         Zalp's Dumpster Diver
// @namespace    http://hammockc.at/
// @version      2025-05-17
// @description  Highlights items on the market that are cheaper than their recycling value. One's trash is another's treasure. Prices updated as of 2025-05-10.
// @author       simplyzalp [2691559]
// @homepageURL  https://www.torn.com/profiles.php?XID=2691559
// @match        https://www.torn.com/page.php?sid=ItemMarket*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=torn.com
// @grant        none
// @license      GPL-3.0-or-later
// ==/UserScript==

(function() {
    'use strict';

    const RECYCLING_PRICES = { // sourced from the Recycling Center wiki
        "Afro Comb": 30000,
        "Beach Ball": 10,
        "Bleaching Tray": 200,
        "Boat Engine": 75500,
        "Broom": 20,
        "Bull Semen": 25000,
        "Bunch of Black Roses": 300,
        "Bunch of Carnations": 15,
        "Bunch of Flowers": 3,
        "Car Battery": 450,
        "Cigar Cutter": 300,
        "Clippers": 220,
        "Compass": 1750,
        "Cosmetics Case": 200,
        "Crazy Straw": 10,
        "Daffodil": 5,
        "Dart Board": 500,
        "Dentures": 2200,
        "Detergent": 35,
        "Dozen Roses": 250,
        "DVD Player": 25,
        "Family Photo": 1,
        "Fire Hydrant": 15000,
        "Fishing Rod": 8000,
        "Floor Cleaner": 35,
        "Formaldehyde": 125,
        "Funeral Wreath": 75,
        "Grain": 150,
        "Hard Drive": 65,
        "Hockey Stick": 300,
        "Headphones": 250,
        "Jade Buddha": 10000,
        "Jigsaw Puzzle": 30,
        "Lipstick": 10,
        "Lubricant": 15,
        "Magazine": 5,
        "Maneki Neko": 35000,
        "Mayan Statue": 350,
        "Microwave": 150,
        "Mix CD": 5,
        "Model Space Ship": 13000,
        "Model Spine": 4000,
        "Mop": 20,
        "Mouthwash": 10,
        "Nodding Turtle": 500,
        "Notepad": 10,
        "Oxygen Tank": 200,
        "Pack of Cuban Cigars": 295,
        "Pack of Music CDs": 20,
        "Pele Charm": 1800,
        "Perfume": 2000,
        "Persian Rug": 22000,
        "Phone Card": 30,
        "Picture Frame": 200,
        "Razor Wire": 4325,
        "RS232 Cable": 15,
        "Scalp Massager": 700,
        "Scrap Metal": 50,
        "Sensu": 300,
        "Sextant": 15000,
        "Shampoo": 20,
        "Shaving Foam": 15,
        "Ship in a Bottle": 25000,
        "Silver Cutlery Set": 2700,
        "Single Red Rose": 100,
        "Snowboard": 4000,
        "Soap on a Rope": 10,
        "Soccer Ball": 30,
        "Stamp Collection": 30000,
        "Stapler": 20,
        "Steel Drum": 1000,
        "Subway Pass": 2000,
        "Tailor's Dummy": 7500,
        "Tin Can": 1,
        "Tire": 90,
        "Towel": 20,
        "Tractor Part": 6500,
        "Travel Mug": 30,
        "Umbrella": 75,
        "Vitamins": 50,
        "Yakitori Lantern": 3000,
        "Yucca Plant": 7500,
    };

    const VERBOSE = false; // if true, prints additional console log messages for debugging.

    function noop() { return; }
    function debugLog(msg) { if (VERBOSE) { console.log(msg); } }
    function debugWarn(msg) { if (VERBOSE)  { console.log(msg); } }
    const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));


    function checkRecyclingProfits() {
        let marketItemElts = document.querySelectorAll('div[class^=itemTile]');
        for (let e of marketItemElts) {
            let thisItemRecyclingCost = -1;
            let itemNameElt = e.querySelector('div[class^=name]');
            if (itemNameElt == null) {
                console.warn('Could not find the name element for this market item. (This is probably a bug. Sorry!)');
                continue; // continues to next market item
            }
            for (const [key, value] of Object.entries(RECYCLING_PRICES)) {
                debugLog(key);
                debugWarn(itemNameElt.innerHTML);
                if (key == itemNameElt.innerHTML) {
                    thisItemRecyclingCost = value;
                    break; // market item was matched, so no need to keep looking
                }
                // only reached if the current market item's name is not in RECYCLING_PRICES
                debugLog('Item was not found in the recycling list.');
            }
            let itemCostElt = e.querySelector('div[class^=priceAndTotal] span:not([class])');
            if (itemCostElt == null) {
                console.warn('Could not find the price element for this market item. (This is probably a bug. Sorry!)');
                continue; // continues to next market item
            }
            let junkCharsRegex = /(,|\$|\n)/g;
            let thisItemMarketCost = Number(itemCostElt.innerHTML.replaceAll(junkCharsRegex,''));

            if (thisItemMarketCost < thisItemRecyclingCost) {
                e.style.backgroundColor = 'darkred';
                let profitElt = document.createElement('div');
                profitElt.style.fontWeight = 'bold';
                profitElt.innerHTML = `(+$${thisItemRecyclingCost - thisItemMarketCost})`;
                itemCostElt.appendChild(profitElt);
            }
        }
        console.log('Recycling price check complete.');
    }


    let logoHeight = document.querySelector('a.logo-link').style.height;

    let triggerElt = document.createElement('div');
    triggerElt.style.cssText = 'display: block; position: fixed; top: 100px; left: 0; width: 30px; height: 30px; background-color: #441; color: #080; font-size: 24px;  line-height: 30px; text-align: center; cursor: pointer;';
    triggerElt.innerText = '$?';
    triggerElt.addEventListener('click', checkRecyclingProfits);

    document.querySelector('body').appendChild(triggerElt);
    console.log("Zalp's Dumpster Diver loaded successfully. Happy hunting!");

})();