您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shows the market price for items on the Inventory, Quick Stock, and your Shop pages using ItemDB, with a Jellyneo link and price warning indicator.
// ==UserScript== // @name Neopets Item Price Tooltip (ItemDB + Jellyneo Link) // @namespace https://itemdb.com.br // @version 1.4.2 // @description Shows the market price for items on the Inventory, Quick Stock, and your Shop pages using ItemDB, with a Jellyneo link and price warning indicator. // @author FatalFlaw // @match *://www.neopets.com/quickstock.phtml* // @match *://www.neopets.com/inventory.phtml* // @match *://www.neopets.com/market.phtml* // @grant GM_xmlhttpRequest // @license MIT // @connect itemdb.com.br // @require https://code.jquery.com/jquery-3.6.0.min.js // ==/UserScript== (function () { 'use strict'; const intl = new Intl.NumberFormat(); // Function to fetch item price and calculate median from last 20 prices function fetchItemPrice(itemName, callback) { const itemSlug = itemName.toLowerCase().replace(/\s+/g, '-'); const itemPageUrl = `https://itemdb.com.br/item/${itemSlug}`; GM_xmlhttpRequest({ method: 'GET', url: itemPageUrl, onload: function (res) { if (res.status !== 200) { return callback('Error Fetching Price'); } const parser = new DOMParser(); const doc = parser.parseFromString(res.responseText, 'text/html'); const rows = Array.from(doc.querySelectorAll('table tbody tr')); const priceCells = []; let hasWarning = false; for (const row of rows) { const firstTd = row.querySelector('td:first-child'); if (!firstTd || !firstTd.textContent) continue; const text = firstTd.textContent.trim().replace(/,/g, '').replace(/[^\d]/g, ''); const price = parseInt(text, 10); if (!isNaN(price)) { priceCells.push(price); } const rowText = row.textContent.toLowerCase(); const containsKeyword = /(added|unavailable|quest|daily|pool)/.test(rowText); const containsLink = row.querySelector('a') !== null; if (containsKeyword || containsLink) { hasWarning = true; } if (priceCells.length >= 20) break; // Only take the first 20 valid prices } if (priceCells.length === 0) { return callback('No Price Data'); } priceCells.sort((a, b) => a - b); const mid = Math.floor(priceCells.length / 2); const median = priceCells.length % 2 === 0 ? Math.round((priceCells[mid - 1] + priceCells[mid]) / 2) : priceCells[mid]; const warningMark = hasWarning ? '!' : ''; const asteriskMark = priceCells.length < 20 ? '*' : ''; const priceText = `${intl.format(median)} NP${asteriskMark}${warningMark}`; callback(priceText); }, onerror: function () { callback('Error Fetching Price'); } }); } // Tooltip with Jellyneo link and red ! if suspicious function showTooltip(e, priceText, itemName) { const jellyNeoUrl = `https://items.jellyneo.net/search/?name=${encodeURIComponent(itemName)}`; const hasWarning = priceText.endsWith('!'); const hasAsterisk = priceText.includes('*'); let cleanText = priceText.replace('*', '').replace('!', ''); let indicators = ''; if (hasAsterisk) cleanText += '*'; if (hasWarning) indicators += '<span style="color:red;">!</span>'; const explanation = ` <div style="color:gray; font-size:10px; margin-top:2px;"> ${hasAsterisk ? '* Fewer than 20 prices<br>' : ''} ${hasWarning ? '<span style="color:red;">! Suspicious entry detected</span>' : ''} </div> `; const tooltip = $('<div class="price-tooltip"></div>') .html(`<a href="${jellyNeoUrl}" target="_blank" style="color:white; text-decoration:underline;"> ${cleanText} ${indicators} 🔍 </a>${explanation}`) .css({ position: 'absolute', top: e.pageY + 10 + 'px', left: e.pageX + 10 + 'px', padding: '5px', backgroundColor: 'rgba(0, 0, 0, 0.75)', borderRadius: '5px', fontSize: '12px', zIndex: 9999, cursor: 'pointer' }); $('body').append(tooltip); $(document).one('click', function () { tooltip.remove(); }); } // Highlight text and trigger price fetch let timeout; $(document).on('mouseup', function (e) { const selectedText = window.getSelection().toString().trim(); if (selectedText) { clearTimeout(timeout); timeout = setTimeout(function () { fetchItemPrice(selectedText, function (priceText) { showTooltip(e, priceText, selectedText); }); }, 300); // Delay lookup by 300ms } }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址