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);
    }

})();