DF Quick Search

Auto click items to search in Dead Frontier market

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         DF Quick Search
// @namespace    http://tampermonkey.net/
// @version      1.4
// @description  Auto click items to search in Dead Frontier market
// @author       SHUN
// @license      SHUN
// @match        *://fairview.deadfrontier.com/onlinezombiemmo/*
// @match        *://*.deadfrontier.com/onlinezombiemmo/*
// @grant        none
// @icon         https://i.imgur.com/wDmstST.png
// @run-at       document-end
// DF Quick Search
// ==/UserScript==

(function() {
    'use strict';

    console.log('DF Quick Search script started');

    // Wait for page load
    setTimeout(init, 2000);

    function init() {
        const isMarketPage = window.location.href.includes('page=35');
        console.log('Market page:', isMarketPage);

        // Only activate features on market page
        if (isMarketPage) {
            console.log('Enabling auto-search features');

            setupRightClickSearch();
            setupDoubleClickSearch();
            setupSearchBoxListener();
            addInstructions(); // Add instructions only on market page
        } else {
            console.log('Not market page - script inactive');
            return;
        }
    }

    // Setup right-click function (market page only)
    function setupRightClickSearch() {
        document.addEventListener('contextmenu', function(e) {
            const itemElement = findItemElement(e.target);
            if (!itemElement) return;

            e.preventDefault();

            const itemInfo = extractItemInfo(itemElement);
            if (itemInfo && itemInfo.name) {
                console.log('Right-click item:', itemInfo.name);
                autoSearchInMarket(itemInfo.name);
            }
        });
    }

    // Setup double-click function (market page only)
    function setupDoubleClickSearch() {
        document.addEventListener('dblclick', function(e) {
            const itemElement = findItemElement(e.target);
            if (!itemElement) return;

            const itemInfo = extractItemInfo(itemElement);
            if (itemInfo && itemInfo.name) {
                console.log('Double-click item:', itemInfo.name);
                autoSearchInMarket(itemInfo.name);
            }
        });
    }

    // Setup search box listener (market page only)
    function setupSearchBoxListener() {
        setInterval(() => {
            const searchBox = findSearchBox();
            if (searchBox) {
                searchBox.setAttribute('data-autosearch', 'enabled');
                searchBox.title = 'Auto-search enabled (Click items to auto-fill)';
            }
        }, 1000);
    }

    // Find item element
    function findItemElement(element) {
        if (element.classList && (
            element.classList.contains('item') ||
            element.classList.contains('fakeItem') ||
            element.parentElement?.classList?.contains('fakeItem')
        )) {
            return element.classList.contains('item') ? element : element.parentElement;
        }

        let current = element;
        while (current && current !== document.body) {
            if (current.classList && (
                current.classList.contains('item') ||
                current.classList.contains('fakeItem')
            )) {
                return current;
            }
            current = current.parentElement;
        }

        return null;
    }

    // Extract item information
    function extractItemInfo(itemElement) {
        try {
            if (itemElement.dataset.type) {
                const itemId = itemElement.dataset.type;
                const itemName = getItemNameFromId(itemId);
                return {
                    id: itemId,
                    name: itemName
                };
            }

            const textElements = itemElement.querySelectorAll('.itemName, .item-name, .name');
            for (const elem of textElements) {
                if (elem.textContent && elem.textContent.trim()) {
                    return {
                        name: elem.textContent.trim()
                    };
                }
            }

            if (itemElement.textContent && itemElement.textContent.trim()) {
                const text = itemElement.textContent.trim();
                const cleanName = cleanItemName(text);
                if (cleanName) {
                    return { name: cleanName };
                }
            }

            return null;
        } catch (e) {
            console.error('Extract item info failed:', e);
            return null;
        }
    }

    // Get item name from ID
    function getItemNameFromId(itemId) {
        if (window.globalData && window.globalData[itemId]) {
            return window.globalData[itemId].name || itemId;
        }
        return itemId;
    }

    // Clean item name
    function cleanItemName(text) {
        const patterns = [
            /\$[\d,]+/g,
            /\d+\s*x\s*\d+/g,
            /\([^)]+\)/g,
            /\[[^\]]+\]/g,
            /\d+$/g,
            /buy$/i,
            /sell$/i,
            /\s+/g
        ];

        let cleaned = text;
        patterns.forEach(pattern => {
            cleaned = cleaned.replace(pattern, ' ');
        });

        cleaned = cleaned.trim();

        return cleaned.length > 2 ? cleaned : text.trim();
    }

    // Find search box
    function findSearchBox() {
        const selectors = [
            'input[name="searchField"]',
            'input[id*="search"]',
            'input[placeholder*="Search"]',
            'input[placeholder*="search"]',
            'input[type="text"]',
            'input[type="search"]',
            '#searchField',
            '.searchField',
            'input[name*="search"]'
        ];

        for (const selector of selectors) {
            const element = document.querySelector(selector);
            if (element && element.tagName === 'INPUT') {
                return element;
            }
        }

        return null;
    }

    // Auto search in market
    function autoSearchInMarket(itemName) {
        console.log('Searching:', itemName);

        const searchBox = findSearchBox();
        if (!searchBox) {
            console.log('Search box not found');
            showNotification(`Search box not found: ${itemName}`, 'warning');
            copyToClipboard(itemName);
            return;
        }

        searchBox.value = itemName;
        triggerEvents(searchBox);
        clickSearchButton();
        showNotification(`Searching: ${itemName}`, 'success');
    }

    // Trigger input events
    function triggerEvents(inputElement) {
        const events = ['input', 'change', 'keyup', 'keydown'];
        events.forEach(eventType => {
            inputElement.dispatchEvent(new Event(eventType, {
                bubbles: true,
                cancelable: true
            }));
        });
    }

    // Click search button
    function clickSearchButton() {
        const buttons = document.querySelectorAll('button, input[type="submit"], input[type="button"]');

        for (const button of buttons) {
            const btnText = (button.textContent || button.value || '').toLowerCase();
            const btnId = (button.id || '').toLowerCase();
            const btnName = (button.name || '').toLowerCase();

            if (btnText.includes('search') ||
                btnText.includes('find') ||
                btnText.includes('go') ||
                btnId.includes('search') ||
                btnName.includes('search')) {

                setTimeout(() => {
                    button.click();
                    console.log('Clicked search button');
                }, 300);
                return true;
            }
        }

        const searchBox = findSearchBox();
        if (searchBox) {
            const form = searchBox.closest('form');
            if (form) {
                setTimeout(() => {
                    form.submit();
                    console.log('Form submitted');
                }, 300);
                return true;
            }
        }

        return false;
    }

    // Copy to clipboard
    function copyToClipboard(text) {
        try {
            const textarea = document.createElement('textarea');
            textarea.value = text;
            textarea.style.position = 'fixed';
            textarea.style.opacity = '0';
            document.body.appendChild(textarea);
            textarea.select();
            document.execCommand('copy');
            document.body.removeChild(textarea);
            console.log('Copied to clipboard:', text);
        } catch (e) {
            console.error('Copy failed:', e);
        }
    }

    // Show notification (center top)
    function showNotification(message, type) {
        const oldNotification = document.getElementById('df-auto-search-notification');
        if (oldNotification) oldNotification.remove();

        const notification = document.createElement('div');
        notification.id = 'df-auto-search-notification';
        notification.textContent = message;

        notification.style.cssText = `
            position: fixed !important;
            top: 20px !important;
            left: 50% !important;
            transform: translateX(-50%) !important;
            padding: 12px 20px !important;
            background-color: ${type === 'success' ? '#28a745' : '#ff9900'} !important;
            color: white !important;
            border-radius: 5px !important;
            z-index: 10000 !important;
            box-shadow: 0 3px 15px rgba(0,0,0,0.4) !important;
            font-weight: bold !important;
            animation: fadeInOut 3s forwards !important;
            white-space: nowrap !important;
            text-align: center !important;
        `;

        const style = document.createElement('style');
        style.textContent = `
            @keyframes fadeInOut {
                0% { opacity: 0; transform: translateX(-50%) translateY(-20px); }
                10% { opacity: 1; transform: translateX(-50%) translateY(0); }
                90% { opacity: 1; transform: translateX(-50%) translateY(0); }
                100% { opacity: 0; transform: translateX(-50%) translateY(-20px); }
            }
        `;
        document.head.appendChild(style);

        document.body.appendChild(notification);
        setTimeout(() => notification.remove(), 3000);
    }

    // Add instructions ONLY on market page
    function addInstructions() {
        const instructions = document.createElement('div');
        instructions.innerHTML = `
            <div style="
                position: fixed;
                bottom: 10px;
                right: 10px;
                background: rgba(0,0,0,0.8);
                color: white;
                padding: 10px;
                border-radius: 5px;
                font-size: 12px;
                z-index: 9998;
                max-width: 200px;
                border: 1px solid #ff9900;
            ">
                <strong>🔍 Auto Search</strong><br>
                • Right-click item: Auto search<br>
                • Double-click item: Auto search<br>
                • Item name auto-fills search box
            </div>
        `;
        document.body.appendChild(instructions);

        // Auto hide after 10 seconds
        setTimeout(() => {
            instructions.style.opacity = '0.5';
            instructions.style.cursor = 'pointer';
            instructions.onclick = () => instructions.remove();
        }, 10000);
    }

})();