// ==UserScript== // @name Steam Pirate & Misc Links Dropdowns // @namespace http://tampermonkey.net/ // @version 1.8-min // @description Adds dropdown menus with links to game download/forum/cheat/filehost sites on Steam app pages. Fixes dropdown opening and cutoff issues. Improves search link reliability. Use responsibly and legally. // @author AndreyUA (enhanced by AI) // @match https://store.steampowered.com/app/* // @icon https://store.steampowered.com/favicon.ico // @grant GM_addStyle // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; const findSites = [ { name: "Rutracker", searchUrl: "https://rutracker.org/forum/tracker.php?nm={searchTerm}" }, { name: "CS.RIN.RU", searchUrl: "https://cs.rin.ru/forum/search.php?keywords={searchTerm}&terms=all&author=&sc=1&sf=titleonly&sr=topics&sk=t&sd=d&st=0&ch=300&t=0&submit=Search" }, { name: "Online-Fix.me", searchUrl: "https://online-fix.me/index.php?do=search&subaction=search&story={searchTerm}" }, { name: "FitGirl Repacks", searchUrl: "https://fitgirl-repacks.site/?s={searchTerm}" }, { name: "DODI Repacks", searchUrl: "https://dodi-repacks.site/?s={searchTerm}" }, { name: "GOG-Games", searchUrl: "https://gog-games.to/?s={searchTerm}" }, { name: "SteamRIP", searchUrl: "https://steamrip.com/?s={searchTerm}" }, { name: "Torrminatorr Forum", searchUrl: "https://forum.torrminatorr.com/search.php?keywords={searchTerm}&terms=all&author=&sc=1&sf=titleonly&sr=topics&sk=t&sd=d&st=0&ch=300&t=0&submit=Search" }, { name: "SteamGG", searchUrl: "https://steamgg.net/?s={searchTerm}" }, { name: "KaosKrew", searchUrl: "https://www.kaoskrew.org/search.php?keywords={searchTerm}&terms=all&author=&sc=1&sf=titleonly&sr=topics&sk=t&sd=d&st=0&ch=300&t=0&submit=Search" }, ]; const miscContentConfig = [ { type: 'header', text: 'Cheats & Saves' }, { type: 'link', name: "FearLess Cheat Engine", searchUrl: "https://fearlessrevolution.com/search.php?keywords={searchTerm}" }, { type: 'link', name: "FLiNG Trainer", searchUrl: "https://flingtrainer.com/search/{searchTerm}/" }, { type: 'link', name: "MegaGames", searchUrl: "https://megagames.com/results?titles={searchTerm}" }, { type: 'separator' }, { type: 'header', text: 'Recommended Filehosts' }, { type: 'link', name: "Buzzheavier", url: "https://buzzheavier.com/" }, { type: 'link', name: "Datanodes", url: "https://datanodes.to/" }, { type: 'link', name: "Gofile", url: "https://gofile.io/" }, { type: 'link', name: "KrakenFiles", url: "https://krakenfiles.com/" }, { type: 'link', name: "MediaFire", url: "https://www.mediafire.com/" }, { type: 'link', name: "PixelDrain", url: "https://pixeldrain.com/" }, ]; function sanitizeGameTitle(title) { if (!title) return ''; let cleanTitle = title.replace(/™|®|©/g, '').trim(); const suffixPatterns = [ /\s*[:\-–—]?\s+(Remastered|Remake|Definitive|Ultimate|Deluxe|GOTY|Game of the Year|Anniversary|Enhanced|Complete|Gold|Premium|Collectors|Extended|Legacy)\s+(Collection|Edition|Cut)?\s*$/i, /\s*\(?(VR)\)?\s*$/i, /\s+-\s+(Remastered|Definitive|etc...)\s*$/i, /\s+\d{4}\s*$/ ]; suffixPatterns.forEach(pattern => { cleanTitle = cleanTitle.replace(pattern, '').trim(); }); cleanTitle = cleanTitle.replace(/^Call of Duty®$/, 'Call of Duty'); return cleanTitle; } function getGameTitle() { const titleElement = document.getElementById('appHubAppName'); if (titleElement) return titleElement.textContent.trim(); const pageTitle = document.title; const match = pageTitle.match(/^(.*?)\s+on Steam$/); if (match && match[1]) return match[1].trim(); return ''; } function createDropdownButton(buttonText, contentConfig, gameTitle = '', containerClass = '') { const container = document.createElement('div'); container.className = `pirate-links-container ${containerClass}`; container.style.position = 'relative'; container.style.display = 'inline-block'; container.style.marginRight = '4px'; container.style.verticalAlign = 'top'; const button = document.createElement('a'); button.href = '#'; button.className = 'btnv6_blue_hoverfade btn_medium pirate-links-button'; button.innerHTML = `${buttonText}`; const dropdownPanel = document.createElement('div'); dropdownPanel.className = 'popup_block_new pirate-links-dropdown'; dropdownPanel.style.position = 'absolute'; dropdownPanel.style.visibility = 'hidden'; dropdownPanel.style.display = 'none'; dropdownPanel.style.zIndex = '1501'; dropdownPanel.style.minWidth = '180px'; const dropdownContent = document.createElement('div'); dropdownContent.className = 'popup_body popup_menu'; contentConfig.forEach(item => { if (item.type === 'header') { const header = document.createElement('div'); header.className = 'popup_menu_subheader pirate-links-subheader'; header.textContent = item.text; dropdownContent.appendChild(header); } else if (item.type === 'separator') { const separator = document.createElement('div'); separator.className = 'pirate-links-separator'; dropdownContent.appendChild(separator); } else if (item.type === 'link') { const link = document.createElement('a'); link.className = 'popup_menu_item'; let href = item.url || '#'; if (item.searchUrl && gameTitle) { href = item.searchUrl.replace('{searchTerm}', encodeURIComponent(gameTitle)); } link.href = href; link.textContent = item.name; link.target = '_blank'; link.rel = 'noopener noreferrer'; dropdownContent.appendChild(link); } }); dropdownPanel.appendChild(dropdownContent); document.body.appendChild(dropdownPanel); container.appendChild(button); button.addEventListener('click', (event) => { event.preventDefault(); event.stopPropagation(); const isCurrentlyVisible = dropdownPanel.style.display === 'block'; document.querySelectorAll('.pirate-links-dropdown').forEach(panel => { if (panel !== dropdownPanel) { panel.style.display = 'none'; panel.style.visibility = 'hidden'; } }); if (isCurrentlyVisible) { dropdownPanel.style.display = 'none'; dropdownPanel.style.visibility = 'hidden'; } else { try { const buttonRect = button.getBoundingClientRect(); const panelHeight = dropdownPanel.offsetHeight; const panelWidth = dropdownPanel.offsetWidth; const spaceBelow = window.innerHeight - buttonRect.bottom; const spaceAbove = buttonRect.top; let panelTop = 0; let panelLeft = buttonRect.left + window.scrollX; if (panelHeight > spaceBelow - 10 && panelHeight <= spaceAbove) { panelTop = buttonRect.top + window.scrollY - panelHeight - 2; } else { panelTop = buttonRect.bottom + window.scrollY + 2; } dropdownPanel.style.top = `${panelTop}px`; dropdownPanel.style.left = `${panelLeft}px`; dropdownPanel.style.width = `${Math.max(buttonRect.width, 180)}px`; dropdownPanel.style.right = 'auto'; dropdownPanel.style.bottom = 'auto'; dropdownPanel.style.display = 'block'; dropdownPanel.style.visibility = 'visible'; } catch (error) { console.error("Error during positioning:", error); dropdownPanel.style.top = (button.getBoundingClientRect().bottom + window.scrollY + 2) + 'px'; dropdownPanel.style.left = (button.getBoundingClientRect().left + window.scrollX) + 'px'; dropdownPanel.style.display = 'block'; dropdownPanel.style.visibility = 'visible'; } } }); return container; } const globalClickListener = (e) => { let clickedInsideButtonOrPanel = false; document.querySelectorAll('.pirate-links-container').forEach(container => { if (container.contains(e.target)) { clickedInsideButtonOrPanel = true; } }); document.querySelectorAll('.pirate-links-dropdown').forEach(panel => { if (panel.contains(e.target)) { clickedInsideButtonOrPanel = true; } }); if (!clickedInsideButtonOrPanel) { document.querySelectorAll('.pirate-links-dropdown').forEach(panel => { panel.style.display = 'none'; panel.style.visibility = 'hidden'; }); } }; document.addEventListener('click', globalClickListener); const originalGameTitle = getGameTitle(); if (!originalGameTitle) { console.error("Steam Pirate/Misc Links: Could not determine game title."); return; } const sanitizedGameTitle = sanitizeGameTitle(originalGameTitle); // console.log("Steam Pirate/Misc Links | Original Title:", originalGameTitle, "| Sanitized:", sanitizedGameTitle); // Commented out console log const findButtonContainer = createDropdownButton( 'Find...', findSites.map(site => ({ type: 'link', ...site })), sanitizedGameTitle, 'find-button-container' ); const miscButtonContainer = createDropdownButton( 'Misc', miscContentConfig, sanitizedGameTitle, 'misc-button-container' ); const insertionPointFind = document.querySelector('.apphub_OtherSiteInfo'); if (insertionPointFind && findButtonContainer) { const communityHubButton = insertionPointFind.querySelector('a[href*="steamcommunity.com/app/"]'); if (communityHubButton) { findButtonContainer.style.verticalAlign = 'middle'; insertionPointFind.insertBefore(findButtonContainer, communityHubButton); } else { findButtonContainer.style.verticalAlign = 'middle'; insertionPointFind.insertAdjacentElement('afterbegin', findButtonContainer); } } else { console.error("Steam Pirate/Misc Links: Could not find insertion point for 'Find...' button (.apphub_OtherSiteInfo)."); } const insertionPointMisc = document.getElementById('shareEmbedRow'); if (insertionPointMisc && miscButtonContainer) { const reportButton = insertionPointMisc.querySelector('#ReportAppBtn'); if (reportButton) { miscButtonContainer.style.verticalAlign = 'bottom'; miscButtonContainer.style.marginLeft = '4px'; insertionPointMisc.insertBefore(miscButtonContainer, reportButton); } else { miscButtonContainer.style.verticalAlign = 'bottom'; insertionPointMisc.appendChild(miscButtonContainer); } } else { console.error("Steam Pirate/Misc Links: Could not find insertion point for 'Misc' button (#shareEmbedRow)."); } GM_addStyle(` .pirate-links-button span { vertical-align: middle; } .pirate-links-dropdown { background-color: #171d25; border: 1px solid #000; box-shadow: 0 0 12px rgba(0,0,0,0.7); color: #c7d5e0; border-radius: 3px; position: absolute; } .pirate-links-dropdown .popup_menu_item { display: block; padding: 6px 12px; color: #c7d5e0; text-decoration: none; font-size: 13px; white-space: nowrap; } .pirate-links-dropdown .popup_menu_item:hover { background-color: #c7d5e0; color: #1b2838; border-radius: 2px; } .pirate-links-subheader { padding: 8px 12px 4px 12px; color: #5b9ace; font-weight: bold; font-size: 11px; text-transform: uppercase; border-top: 1px solid #3a3f44; } .pirate-links-subheader:first-child { border-top: none; padding-top: 6px; } .pirate-links-separator { height: 1px; background-color: #3a3f44; margin: 4px 0; } `); // console.log("Steam Pirate & Misc Links Dropdowns loaded successfully (v1.8-min)."); // Commented out console log })();