Cheapest Price By Unit

Simple sort by unit button for Dead Frontier Marketplace - Find cheap credits based on the price of 1 credit!

目前為 2025-05-06 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Cheapest Price By Unit
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  Simple sort by unit button for Dead Frontier Marketplace - Find cheap credits based on the price of 1 credit!
// @author       Lucky11
// @match        https://fairview.deadfrontier.com/onlinezombiemmo/index.php?page=35
// @icon         https://www.google.com/s2/favicons?sz=64&domain=deadfrontier.com
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Function to create the button and add the Unit Price column
    function createSortButton() {
        // Check if the button already exists to avoid duplicates
        if (document.getElementById('sortButton')) return;

        const btn = document.createElement('button');
        btn.id = 'sortButton'; // Set an ID for the button
        btn.style.position = 'absolute';
        btn.style.left = '608px';
        btn.style.width = 'max-content'; // This will override the previous width
        btn.innerText = 'Sort/1';
        btn.style.cursor = 'pointer';

        // Add click event
        btn.addEventListener('click', () => {
            sortItemsByPricePerCredit();
        });

        const salePriceSpan = document.querySelector('#tradesLabels span:nth-child(4)');

        if (salePriceSpan) {
            salePriceSpan.insertAdjacentElement('afterend', btn);
        }

        // Add Unit Price header
        const unitPriceHeader = document.createElement('span');
        unitPriceHeader.innerText = 'Unit Price';
        unitPriceHeader.style.position = 'absolute';
        unitPriceHeader.style.left = '100px'; // Adjust position as needed
        unitPriceHeader.style.width = 'max-content';
        salePriceSpan.insertAdjacentElement('afterend', unitPriceHeader);
    }

    // Function to parse item data and sort
    function sortItemsByPricePerCredit() {
        const items = Array.from(document.querySelectorAll('.fakeItem'));

        // Map items to objects with price per credit
        const itemData = items.map(item => {
            const priceStr = item.querySelector('.salePrice')?.innerText || '';
            const priceNum = parseFloat(priceStr.replace(/[^0-9.]/g, '')) || 0;

            const quantityStr = item.querySelector('.itemName')?.dataset?.cash || '';
            const quantityAttr = item.dataset?.quantity || '';
            const quantity = parseInt(quantityAttr) || 1; // Fallback to 1 if quantity is not found

            // Calculate price per credit
            const pricePerCreditItem = priceNum / quantity;

            // Calculate unit price
            const unitPrice = priceNum / quantity;

            // Add unit price to the item element
            //const unitPriceDiv = document.createElement('div');

            // Check if the unit price div already exists
            let unitPriceDiv = item.querySelector('.unitPrice');
            if (!unitPriceDiv) {
                // Create unit price div if it doesn't exist
                unitPriceDiv = document.createElement('div');
                unitPriceDiv.className = 'unitPrice';
                item.appendChild(unitPriceDiv);
            }

            unitPriceDiv.className = 'unitPrice';
            //const formattedUnitPrice = `$${unitPrice.toFixed(0)}`; // Format to 0 decimal places with dollar sign
            const formattedUnitPrice = `$${Math.round(unitPrice).toLocaleString()}`;
            unitPriceDiv.innerText = formattedUnitPrice; // Set the formatted price
            unitPriceDiv.style.position = 'absolute'; // Set position to absolute
            unitPriceDiv.style.left = '115px'; // Set left position
            unitPriceDiv.style.color = '#FFCC00'; // Set text color to yellow
            item.appendChild(unitPriceDiv);


            return {
                element: item,
                pricePerCredit: pricePerCreditItem
            };
        });

        itemData.sort((a, b) => a.pricePerCredit - b.pricePerCredit);

        // Reorder DOM
        const parent = document.querySelector('.marketDataHolder');
        if (parent) {
            // Remove all items
            parent.innerHTML = '';
            // Append sorted items
            itemData.forEach(data => {
                parent.appendChild(data.element);
            });
        }
    }

    /*
     * Code below of this script is derived from the "Dead Frontier - Fast Services" script by Shrike00
     * Original source: https://update.greasyfork.org/scripts/472536/Dead%20Frontier%20-%20Fast%20Services.user.js
     * Copyright (c) Shrike00
     * Licensed under the MIT License.
     */
    // Initial button creation and observer setup
    function waitForItemDisplay(callback, timeout) {
        const start = performance.now();
        const check = setInterval(function() {
            if (document.getElementById("itemDisplay") !== null) {
                clearInterval(check);
                callback();
            } else if (performance.now() - start > timeout) {
                clearInterval(check);
            }
        }, 100);
    }
    function main() {
        waitForItemDisplay(function() {
            // Initial addition of button.
            createSortButton();
            // Mutation observer to check for changes to the marketplace child nodes, re-adding the event listener
            // whenever the selectMarket element is re-added (which happens when the market tab is changed).
            const callback = function(mutationList, observer) {
                for (const record of mutationList) {
                    const element = record.addedNodes[0];
                    if (element !== undefined && element.id === "selectMarket") {
                        createSortButton();
                    }
                }
            }
            const observer = new MutationObserver(callback);
            const marketplace = document.getElementById("marketplace");
            observer.observe(marketplace, {childList: true});
        }, 5000);
    }

    main();

})();