Greasy Fork is available in English.

Auctionhouse Filter

Filter the auction house for only the weapons you desire

// ==UserScript==
// @name         Auctionhouse Filter
// @namespace    http://tampermonkey.net/
// @version      0.91
// @description  Filter the auction house for only the weapons you desire
// @author       olesien
// @match        https://www.torn.com/amarket*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=torn.com
// @grant        GM_addStyle
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';
    //Styles
    GM_addStyle ( `
   #auction-filter {
      border-radius: 10px;
      margin-bottom: 10px;
   }

   #auction-filter .filter-button {
      background-color: #333333;
      display: block;
      color: white;
      padding: 10px;
      border-radius: 10px;
   }

   #auction-filter .filter-button:hover {
      cursor: pointer;
      background-color: #333434;
   }

   #auction-filter .filter-form {
      display: flex;
      flex-flow: row wrap;
      padding: 10px;
   }

   #auction-filter .filter-div {
       padding: 5px;
       display: inline-block;
       width: 100px;
   }

   #auction-filter .filter-text {
       padding: 10px;
   }

   #auction-filter .field-form {
       display: flex;
   }

   #auction-filter .field-form .field-container {
           display: flex;
           align-items: center;
           gap: 10px;
   }

   #auction-filter .field-form .field-container input {
        padding: 5px;
        margin-left: 10px;
        width: 50px;
   }

   #auction-filter .filter-flex {
        display: flex;
        justify-content: space-even;
        flex-flow: row wrap;
        padding: 0.5rem;
   }

  `);
    //https://stackoverflow.com/questions/3219758/detect-changes-in-the-dom
    const observeDOM = (function(){
        const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

        return function( obj, callback ){
            if( !obj || obj.nodeType !== 1 ) return;

            if( MutationObserver ){
                // define a new observer
                var mutationObserver = new MutationObserver(callback)

                // have the observer observe foo for changes in children
                mutationObserver.observe( obj, { childList:true, subtree:true })
                return mutationObserver
            }

            // browser support fallback
            else if( window.addEventListener ){
                obj.addEventListener('DOMNodeInserted', callback, false)
                obj.addEventListener('DOMNodeRemoved', callback, false)
            }
        }
    })();

    window.addEventListener(
        "load",
        function () {
            //DOM has loaded

            setTimeout(() => {
                const auctionHouseTabsEl = document.querySelector("#auction-house-tabs");

                //Create item box
                const divEl = document.createElement("div");
                divEl.id = "auction-filter";
                divEl.className = "cont-gray";
                //Append to box
                auctionHouseTabsEl.insertBefore(divEl, auctionHouseTabsEl.firstChild);

                doIt();
                renderSettings();

                const pagination = document.querySelector(".pagination-wrap");
                observeDOM( pagination, function(m){
                    doIt();
                });
            }, 200);
        }, false);

    const bonusString = ".bonus-attachment-";
    const normalBonuses = ["demoralized", "freeze", "blindfire", "poisoned", "burning", "laceration", "severeburning", "spray", "emasculate", "hazardous", "storage", "toxin"]
    const rwBonuses = ["achilles", "assassinate", "backstab", "berserk", "bleed", "blindside", "bloodlust", "comeback", "conserve",
                       "cripple", "crusher", "cupid", "deadeye", "deadly", "disarm", "doubletap", "doubleedged", "empower", "eviscerate","execute", "expose",
                       "finale", "focus", "frenzy", "fury", "grace", "homerun", "irradiate", "motivation", "paralyzed", "parry", "penetrate", "plunder", "powerful","proficience",
                       "puncture", "quicken", "rage", "revitalize", "roshambo", "slow", "smurf", "specialist", "stricken", "stun", "suppress", "sureshot",
                       "throttle", "warlord", "weaken", "windup", "wither"]

    function renderSettings() {
        const divEl = document.getElementById("auction-filter");
        divEl.innerHTML =""; //Clear
        const hiddenString = localStorage.getItem('auction-filter-hidden');
        let hidden = hiddenString ? JSON.parse(hiddenString) : hiddenString;
        const pEl = document.createElement("button");
        pEl.className = "filter-button";

        const clickEvent = pEl.addEventListener("click", async (e) => {
            await localStorage.setItem('auction-filter-hidden', JSON.stringify(!hidden));
            renderSettings();
            pEl.removeEventListener(clickEvent); //Prevent duplicate listeners
        });

        pEl.innerText = `Filters`;
        //Add text
        divEl.appendChild(pEl);

        if (!hidden) {
            const textEl = document.createElement("p");
            textEl.innerText = "Bonus type";
            textEl.className = "filter-text";
            divEl.appendChild(textEl);

            const formEl = document.createElement("div");
            formEl.className = "filter-form";
            const setCheckbox = (value, title, main) => {
                const divEl = document.createElement("div");
                divEl.className = "filter-div";

                const checked = localStorage.getItem('checked-rw-' + value);
                const inputEl = document.createElement("input");
                inputEl.type = "checkbox";
                inputEl.id = "rw-" + value;
                inputEl.name = "rw-" + value;
                //inputEl.value = bonus;
                inputEl.checked = checked;

                inputEl.addEventListener('change', async function() {
                    if (!this.checked) {
                        await localStorage.removeItem('checked-rw-' + value);
                    } else {
                        await localStorage.setItem('checked-rw-' + value, String(this.checked));
                    }

                    doIt();
                });

                const labelEl = document.createElement("label");
                labelEl.for = "rw-" + value;
                labelEl.innerText = title
                labelEl.style.paddingLeft = "5px";
                labelEl.className = "t-gray-6";

                divEl.appendChild(inputEl);
                divEl.appendChild(labelEl);

                main.appendChild(divEl);
            }
            rwBonuses.forEach(bonus => {
                setCheckbox(bonus, bonus, formEl);
            })

            //Append to div
            divEl.appendChild(formEl);

            //One of US
            const miscEl = document.createElement("div");
            miscEl.className = "filter-flex";

            //Min damage / acc
            const dmgaccEl = document.createElement("div");
            const textEl2 = document.createElement("p");
            textEl2.innerText = "Min damage / accuracy ";
            textEl2.className = "filter-text";
            dmgaccEl.appendChild(textEl2);

            const formEl2 = document.createElement("div");
            formEl2.className = "field-form";
            const createField = (name, initial) => {
                const fieldContainer = document.createElement("div");
                fieldContainer.className = "field-container";

                const label = document.createElement("label");
                label.innerText = name;
                label.className = "filter-text";

                const input = document.createElement("input");
                input.type = "number";
                input.value = initial ?? "";
                label.appendChild(input);
                fieldContainer.appendChild(label);
                return {fieldContainer, input};
            }
            //Damage
            const damage = localStorage.getItem('auction-filter-damage');
            const {fieldContainer, input: damageInput} = createField("Damage", damage);

            //Accuracy
            const accuracy = localStorage.getItem('auction-filter-accuracy');
            const {fieldContainer: fieldContainer2, input: accuracyInput} = createField("Accuracy", accuracy);

            damageInput.addEventListener('input', async (e) => {
                console.log(damageInput.value);
                const value = Number(damageInput.value)
                if (!value || value <= 0 || value > 9999) {
                    await localStorage.removeItem('auction-filter-damage');
                } else {
                    await localStorage.setItem('auction-filter-damage', String(value));
                }
                doIt();
            });

            accuracyInput.addEventListener('input', async (e) => {
                console.log(accuracyInput.value);
                const value = Number(accuracyInput.value)
                if (!value || value <= 0 || value > 9999) {
                    await localStorage.removeItem('auction-filter-accuracy');
                } else {
                    await localStorage.setItem('auction-filter-accuracy', String(value));
                }
                doIt();
            });

            //append
            formEl2.appendChild(fieldContainer);
            formEl2.appendChild(fieldContainer2);

            dmgaccEl.appendChild(formEl2);
            miscEl.appendChild(dmgaccEl);

            //Rarity
            const rarityEl = document.createElement("div");
            const textEl3 = document.createElement("p");
            textEl3.innerText = "Rarity types ";
            textEl3.className = "filter-text";


            const formEl3 = document.createElement("div");
            formEl3.className = "field-form";

            setCheckbox("normal", "normal", formEl3);
            setCheckbox("yellow", "yellow", formEl3);
            setCheckbox("orange", "orange", formEl3);
            setCheckbox("red", "red", formEl3);

            rarityEl.appendChild(textEl3);

            rarityEl.appendChild(formEl3);

            miscEl.appendChild(rarityEl);

            divEl.appendChild(miscEl);

        }
    }
    function doIt() {
        const minDamage = localStorage.getItem('auction-filter-damage');
        const minAccuracy = localStorage.getItem('auction-filter-accuracy');

        const normal = localStorage.getItem('checked-rw-normal');
        const yellow = localStorage.getItem('checked-rw-yellow');
        const orange = localStorage.getItem('checked-rw-orange');
        const red = localStorage.getItem('checked-rw-red');

        const weaponsTabEl = document.querySelector(".ui-corner-top");
        if (!weaponsTabEl.classList.contains("active")) return;
        const auctionHouseTabsEl = document.querySelector("#auction-house-tabs");

        //const chosenBonuses = ["warlord", "weaken"]
        let chosenBonuses = rwBonuses.reduce((chosenBonuses, bonus) => {
            const checked = localStorage.getItem('checked-rw-' + bonus);
            if (checked) return [...chosenBonuses, bonus];
            return chosenBonuses;
        }, []);

        if (chosenBonuses.length === 0) chosenBonuses = rwBonuses;
        //Grab items
        const items = Array.from(auctionHouseTabsEl.querySelector(".items-list").children);

        items.forEach((itemEl) => {
            //#FF0000 <- Red
            //#FF8000 <- Orange
            //#FFBF00 <- Yellow
            if (itemEl.classList.contains("clear")) return;
            const hasRightBonuses = chosenBonuses.reduce((hasBonus, bonus) => {
                if (hasBonus) return hasBonus;
                return !!itemEl.querySelector(bonusString + bonus); //!! = convert to boolean true/false
            }, false);
            console.log(itemEl);
            const [damage, accuracy] = Array.from(itemEl.querySelector(".infobonuses").querySelectorAll(".label-value"))
            console.log(damage, accuracy);
            const hasMinDamage = Number(damage.innerText) >= Number(minDamage ?? 0);
            const hasMinAccuracy = Number(accuracy.innerText) >= Number(minAccuracy ?? 0);
            let hasRightRarity = false;
            const imgEl = itemEl.querySelector(".item-plate");
            const color = imgEl?.dataset?.color;
            if (!imgEl || !color) {
                //Default
                console.log("BELOW IS UNKNOWN");
                console.log(imgEl);
                hasRightRarity = true;
            } else {
                if (color === "FF0000" && red) hasRightRarity = true;
                if (color === "FF8000" && orange) hasRightRarity = true;
                if (color === "FFBF00" && yellow) hasRightRarity = true;
                if (color !== "FF0000" && color !== "FF8000" && color !== "FFBF00" && normal) hasRightRarity = true;
                if (!normal && !yellow && !orange && !red) hasRightRarity = true; //Unset
            }
            if (!hasRightBonuses || !hasMinDamage || !hasMinAccuracy || !hasRightRarity) {
                itemEl.style.display = "none";
            } else {
                itemEl.style.display = "inherit";
            }
        });
    }
})();