您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
badge displaying when using the SteamDB extension in the steam inventory to display the badges, too tired to add more functionality tonight, there is a known bug where sometimes it wont fetch on first click, if that happens just click again
// ==UserScript== // @name Steam Inventory Card to Badge Info // @namespace github.com/encumber // @version 1.15 // @description badge displaying when using the SteamDB extension in the steam inventory to display the badges, too tired to add more functionality tonight, there is a known bug where sometimes it wont fetch on first click, if that happens just click again // @match https://steamcommunity.com/*/inventory* // @grant GM_xmlhttpRequest // @connect api.steamsets.com // @run-at document-idle // ==/UserScript== (function() { const API_SECRET = ''; //Steamsets API Key https://steamsets.com/settings/developer-apps // Inject CSS for badge styling and foil effect const style = document.createElement('style'); style.textContent = ` /* Common badge style for size and layout */ .steam-badge-item { margin: 4px; flex: 0 0 auto; text-align: center; font-family: Arial, sans-serif; font-size: 10px; /* Adjust size here globally */ width: 70px; /* Adjust width here globally */ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* Foil style with animated shine overlay */ .steam-badge-item.foil { position: relative; overflow: hidden; background-color: #222; border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 0 10px rgba(255, 255, 245, 0.1); } .steam-badge-item.foil::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient( 45deg, rgba(255, 255, 255, 0) 70%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0) 60% ); background-size: 300% 150%; animation: shine 60s linear infinite; pointer-events: none; } @keyframes shine { 0% { background-position: -100% 0; } 100% { background-position: 200% 0; } } `; document.head.appendChild(style); console.log("[BadgeScript] Script initialized."); function displayBadges(div, badges, appId) { // Remove all badge info blocks *not* for this appId document.querySelectorAll('.steamdb_badge_info_extended').forEach(node => { if (node.getAttribute('data-appid') !== String(appId)) { node.remove(); } }); // Check if info for this appId already exists; if yes, do nothing const existingForApp = document.querySelector('.steamdb_badge_info_extended[data-appid="' + appId + '"]'); if (existingForApp) { console.log('[BadgeScript] Badge info for appId', appId, 'already exists. Skipping creation.'); return; } // Create new info block const infoDiv = document.createElement('div'); infoDiv.className = 'steamdb_badge_info_extended'; infoDiv.setAttribute('data-appid', appId); Object.assign(infoDiv.style, { width: '316px', marginTop: '8px', padding: '8px', border: '1px solid #ccc', display: 'flex', flexWrap: 'wrap', justifyContent: 'center', boxSizing: 'border-box' }); // Sort badges: non-foil first, then foil badges = badges.filter(b => typeof b.baseLevel === 'number' && typeof b.isFoil === 'boolean'); badges.sort((a, b) => { if (a.isFoil === b.isFoil) { return a.baseLevel - b.baseLevel; } return a.isFoil ? 1 : -1; }); badges.forEach(badge => { const badgeEl = document.createElement('div'); badgeEl.className = 'steam-badge-item'; if (badge.isFoil) { badgeEl.classList.add('foil'); } const nameEl = document.createElement('div'); nameEl.textContent = badge.name || 'Badge'; Object.assign(nameEl.style, { fontWeight: 'bold', fontSize: '12px', width: '60px', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }); const badgeImage = badge.badgeImage.replace(/\?.*$/, ''); const imgUrl = `https://cdn.steamstatic.com/steamcommunity/public/images/items/${badge.appId}/${badgeImage}`; const imgEl = document.createElement('img'); imgEl.src = imgUrl; imgEl.style.maxWidth = '60px'; imgEl.style.maxHeight = '60px'; const scarcityEl = document.createElement('div'); scarcityEl.textContent = badge.scarcity || 'Scarcity'; scarcityEl.style.fontSize = '14px'; badgeEl.appendChild(nameEl); badgeEl.appendChild(imgEl); badgeEl.appendChild(scarcityEl); infoDiv.appendChild(badgeEl); }); div.parentNode.insertBefore(infoDiv, div.nextSibling); } function fetchBadgeData(div) { if (div.dataset.processed) { console.log("[BadgeScript] Already processed, skipping:", div); return; } div.dataset.processed = 'true'; console.log("[BadgeScript] Badge detected, will process after delay."); setTimeout(() => { const a = div.querySelector('a'); if (!a) { console.log("[BadgeScript] No link inside badge div after delay, skipping:", div); return; } const href = a.getAttribute('href'); const match = href.match(/\/(\d+)(?:\?.*)?$/); if (!match) { console.log("[BadgeScript] No appId found in href:", href); return; } const appId = parseInt(match[1], 10); console.log("[BadgeScript] AppId detected:", appId); // Skip if info for this appId already exists if (document.querySelector('.steamdb_badge_info_extended[data-appid="' + appId + '"]')) { console.log('[BadgeScript] Badge info for appId', appId, 'already exists. Skipping fetch.'); return; } // Fetch badge data GM_xmlhttpRequest({ method: 'POST', url: 'https://api.steamsets.com/v1/app.listBadges', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + API_SECRET }, data: JSON.stringify({ appId: appId }), onload: function(res) { console.log('GM_xmlhttpRequest status:', res.status); console.log('GM_xmlhttpRequest response:', res.responseText); if (res.status >= 200 && res.status < 300) { try { const data = JSON.parse(res.responseText); console.log('Parsed response:', data); if (data && data.badges) { displayBadges(div, data.badges, appId); } else { console.log("[BadgeScript] No badges in response for appId:", appId); } } catch (e) { console.error("[BadgeScript] JSON parse error:", e); } } else { console.error("[BadgeScript] Request failed with status:", res.status); } }, onerror: function(err) { console.error("[BadgeScript] GM_xmlhttpRequest error:", err); } }); }, 500); } // Setup DOM mutation observer const observer = new MutationObserver(mutations => { for (const m of mutations) { for (const node of m.addedNodes) { if (node.nodeType !== 1) continue; if (node.matches('div.steamdb_badge_info')) { console.log("[BadgeScript] Found badge div:", node); const hrefA = node.querySelector('a'); if (hrefA) { const href = hrefA.getAttribute('href'); const match = href.match(/\/(\d+)(?:\?.*)?$/); if (match) { const appId = parseInt(match[1], 10); // Remove info blocks for other appIds document.querySelectorAll('.steamdb_badge_info_extended').forEach(n => { if (n.getAttribute('data-appid') !== String(appId)) { n.remove(); } }); } } fetchBadgeData(node); } else { node.querySelectorAll('div.steamdb_badge_info').forEach(n => { console.log("[BadgeScript] Found nested badge div:", n); const hrefA = n.querySelector('a'); if (hrefA) { const href = hrefA.getAttribute('href'); const match = href.match(/\/(\d+)(?:\?.*)?$/); if (match) { const appId = parseInt(match[1], 10); // Remove info blocks for other appIds document.querySelectorAll('.steamdb_badge_info_extended').forEach(n2 => { if (n2.getAttribute('data-appid') !== String(appId)) { n2.remove(); } }); } } fetchBadgeData(n); }); } } } }); console.log("[BadgeScript] Starting MutationObserver"); observer.observe(document.body, { childList: true, subtree: true }); // Process existing badges at page load document.querySelectorAll('div.steamdb_badge_info').forEach(div => { console.log("[BadgeScript] Existing badge div:", div); const hrefA = div.querySelector('a'); if (hrefA) { const href = hrefA.getAttribute('href'); const match = href.match(/\/(\d+)(?:\?.*)?$/); if (match) { const appId = parseInt(match[1], 10); // Remove info blocks for other appIds document.querySelectorAll('.steamdb_badge_info_extended').forEach(n => { if (n.getAttribute('data-appid') !== String(appId)) { n.remove(); } }); } } fetchBadgeData(div); }); })();