您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds search bar and filters to FlatMMO market page
// ==UserScript== // @name FlatMMO Market Search + Filters // @namespace http://tampermonkey.net/ // @version 1.7 // @description Adds search bar and filters to FlatMMO market page // @author Carlos // @license MIT // @match https://flatmmo.com/market/ // @grant none // ==/UserScript== (function() { 'use strict'; function addSearchFilters() { const table = document.getElementById('postingsTable'); if (!table) return false; // Table not found yet // Prevent adding filters multiple times if (document.getElementById('market-search-container')) return true; // Create container for controls const container = document.createElement('div'); container.id = 'market-search-container'; // Mark container so we don't add twice container.style.display = 'flex'; container.style.flexWrap = 'wrap'; container.style.justifyContent = 'center'; container.style.gap = '10px'; container.style.margin = '15px 0'; // Search input const searchInput = document.createElement('input'); searchInput.type = 'text'; searchInput.placeholder = 'Search items or usernames...'; searchInput.style.padding = '10px'; searchInput.style.fontSize = '16px'; searchInput.style.borderRadius = '5pt'; searchInput.style.border = '1px solid black'; searchInput.style.minWidth = '250px'; container.appendChild(searchInput); // Buying/Selling filter dropdown const typeFilter = document.createElement('select'); typeFilter.style.padding = '10px'; typeFilter.style.fontSize = '16px'; typeFilter.style.borderRadius = '5pt'; typeFilter.style.border = '1px solid black'; typeFilter.innerHTML = ` <option value="all">All Types</option> <option value="BUYING">Buying</option> <option value="SELLING">Selling</option> `; container.appendChild(typeFilter); // Online status filter dropdown const onlineFilter = document.createElement('select'); onlineFilter.style.padding = '10px'; onlineFilter.style.fontSize = '16px'; onlineFilter.style.borderRadius = '5pt'; onlineFilter.style.border = '1px solid black'; onlineFilter.innerHTML = ` <option value="all">All Online Status</option> <option value="online">Online Only</option> <option value="offline">Offline Only</option> `; container.appendChild(onlineFilter); // Min price input const priceMin = document.createElement('input'); priceMin.type = 'number'; priceMin.min = 0; priceMin.placeholder = 'Min price'; priceMin.style.padding = '10px'; priceMin.style.fontSize = '16px'; priceMin.style.borderRadius = '5pt'; priceMin.style.border = '1px solid black'; priceMin.style.width = '100px'; container.appendChild(priceMin); // Max price input const priceMax = document.createElement('input'); priceMax.type = 'number'; priceMax.min = 0; priceMax.placeholder = 'Max price'; priceMax.style.padding = '10px'; priceMax.style.fontSize = '16px'; priceMax.style.borderRadius = '5pt'; priceMax.style.border = '1px solid black'; priceMax.style.width = '100px'; container.appendChild(priceMax); // Insert controls above table table.parentNode.insertBefore(container, table); // Filtering logic function filterRows() { const searchText = searchInput.value.toLowerCase(); const typeValue = typeFilter.value; const onlineValue = onlineFilter.value; const minPrice = priceMin.value ? parseFloat(priceMin.value) : null; const maxPrice = priceMax.value ? parseFloat(priceMax.value) : null; for (const row of table.tBodies[0].rows) { const username = row.cells[0].textContent.toLowerCase(); const onlineStatus = row.cells[1].textContent.includes('✓') ? 'online' : 'offline'; const type = row.cells[4].textContent.toUpperCase(); let priceText = row.cells[6].textContent.trim(); let priceNum = parseFloat(priceText.match(/[\d,.]+/)); if (isNaN(priceNum)) priceNum = 0; const itemName = row.cells[3].getAttribute('title').toLowerCase(); const matchesSearch = username.includes(searchText) || itemName.includes(searchText); const matchesType = (typeValue === 'all') || (type === typeValue); const matchesOnline = (onlineValue === 'all') || (onlineValue === onlineStatus); const matchesMin = (minPrice === null) || (priceNum >= minPrice); const matchesMax = (maxPrice === null) || (priceNum <= maxPrice); if (matchesSearch && matchesType && matchesOnline && matchesMin && matchesMax) { row.style.display = ''; } else { row.style.display = 'none'; } } } // Add listeners searchInput.addEventListener('input', filterRows); typeFilter.addEventListener('change', filterRows); onlineFilter.addEventListener('change', filterRows); priceMin.addEventListener('input', filterRows); priceMax.addEventListener('input', filterRows); // Run initially filterRows(); return true; // Filters added successfully } // Wait for the table to exist, check every 500ms function waitForTable() { if (!addSearchFilters()) { setTimeout(waitForTable, 500); } } waitForTable(); })();