Steam/GOG Game Torrent Search Modal

Shows a modal window with buttons for searching games on torrent sites with links to sources of information about games: Steam, GOG, trackers, wikis, etc.

// ==UserScript==
// @name         Steam/GOG Game Torrent Search Modal
// @namespace    GPT
// @version      1.0.4
// @author       Wizzergod
// @description  Shows a modal window with buttons for searching games on torrent sites with links to sources of information about games: Steam, GOG, trackers, wikis, etc.
// @description:ru  Показывает модальное окно с кнопками для поиска игр на торрент-сайтах со ссылками на источники информации об играх: Steam, GOG, трекеры, вики и прочее
// @match        *://store.steampowered.*/app/*
// @exclude      *://steamcommunity.*/*
// @match        *://www.gog.com/*/game/*
// @match        *://store.steampowered.*/*
// @match        *://*.steampowered.*/*
// @exclude      *://*.steampowered.com/bundle/*
// @icon         https://bit.ly/3Jj2YMu
// @grant        GM_xmlhttpRequest
// @grant        unsafeWindow
// @grant        GM_addStyle
// @grant        GM_openInTab
// @run-at       document-body
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    // --- Styles ---
    GM_addStyle(`
        #gameLinksModal {
            position: fixed;
            top: 0; left: 0;
            width: 100%; height: 100%;
            background-color: rgba(0,0,0,0.75);
            z-index: 9999;
            display: none;
            justify-content: center;
            align-items: center;
        }
        #gameLinksModalContent {
            background: #1b1d23;
            color: white;
            padding: 20px;
            border-radius: 12px;
            max-height: 90vh;
            overflow-y: auto;
            width: 700px;
            box-shadow: 0 0 20px #000;
        }
        #gameLinksModalContent h2 {
            margin-top: 0;
            font-size: 1.5em;
        }
        .gameLinkSection {
            margin-top: 20px;
        }
        .gameLinkSection h3 {
            margin: 0 0 10px;
            border-bottom: 1px solid #444;
            padding-bottom: 5px;
            font-size: 1.2em;
        }
        .gameLinkBtn {
            display: inline-block;
            padding: 8px 14px;
            margin: 4px;
            border-radius: 6px;
            text-decoration: none;
            font-size: 13px;
            font-weight: bold;
            transition: background 0.3s;
        }
        .steamBtn { background: #5c7e10; color: white; }
        .steamBtn:hover { background: #4b670d; }

        .gogBtn { background: #0058a3; color: white; }
        .gogBtn:hover { background: #004080; }

        .otherBtn { background: #6e35a3; color: white; }
        .otherBtn:hover { background: #582980; }

        #closeGameLinksModal {
            float: right;
            background: transparent;
            border: none;
            color: white;
            font-size: 20px;
            cursor: pointer;
        }
        #openGameLinksBtn {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: #008669;
            color: white;
            padding: 12px 16px;
            border-radius: 50%;
            font-size: 20px;
            border: none;
            cursor: pointer;
            z-index: 9999;
            box-shadow: 0 0 10px rgba(0,0,0,0.5);
        }
    `);

    // --- Modal and buttons ---
    const modal = document.createElement("div");
    modal.id = "gameLinksModal";
    modal.innerHTML = `
        <div id="gameLinksModalContent">
            <button id="closeGameLinksModal">&times;</button>
            <h2>Steam/GOG Game Torrent Search, and more</h2>
            <div id="gameLinksContainer"></div>
        </div>
    `;
    document.body.appendChild(modal);

    const openBtn = document.createElement("button");
    openBtn.id = "openGameLinksBtn";
    openBtn.textContent = "🔍";
    document.body.appendChild(openBtn);

    document.getElementById("closeGameLinksModal").onclick = () => {
        modal.style.display = "none";
    };

    openBtn.onclick = () => {
        const title = document.querySelector('.apphub_AppName')?.innerText ||
                      document.querySelector('.apphub_sectionTab.active')?.innerText ||
                      document.title.split('on Steam')[0].trim();
        const html = buildLinks(title);
        document.getElementById("gameLinksContainer").innerHTML = html;
        modal.style.display = "flex";
    };

    // --- Gen links ---
    function buildLinks(title) {
        const encTitle = encodeURIComponent(title);
        const gameappid = document.querySelector('[data-appid]')?.getAttribute('data-appid') ||
                          document.querySelector('[data-miniprofile-appid]')?.getAttribute('data-miniprofile-appid') || '';

const sections = {
    Steam: [
        { label: 'STEAMDB', url: `https://steamdb.info/app/${gameappid}` },
        { label: 'Card Exchange', url: `https://www.steamcardexchange.net/index.php?gamepage-appid-${gameappid}` },
        { label: 'PCGamingWiki (AppID)', url: `https://www.pcgamingwiki.com/api/appid.php?appid=${gameappid}` },
    ],
    GOG: [
        { label: 'gogdb', url: `https://www.gogdb.org/products?search=${encTitle}` },
        { label: 'freegogpcgames', url: `https://freegogpcgames.com/?s=${encTitle}` },
        { label: 'gog-games', url: `https://gog-games.to/?q=${encTitle}` },
        { label: 'gogunlocked', url: `https://gogunlocked.com/?s=${encTitle}` }
    ],
    Torrents: [
        { label: 'rutracker', url: `https://rutracker.org/forum/tracker.php?nm=${encTitle}` },
        { label: '1337x', url: `https://1337x.to/search/${encTitle}/1/` },
        { label: 'thepiratebay', url: `https://thepiratebay.org/search.php?cat=401&q=${encTitle}` },
        { label: 'nnmclub', url: `https://nnmclub.to/forum/tracker.php?nm=${encTitle}` },
        { label: 'torrentdownloads.pro', url: `https://www.torrentdownloads.pro/search/?search=${encTitle}` },
        { label: 'torrentdownload.info', url: `https://www.torrentdownload.info/search?q=${encTitle}` },
        { label: 'catorrent', url: `https://catorrent.org/index.php?do=search&subaction=search&story=${encTitle}` },
        { label: 'gamestracker', url: `https://gamestracker.org/search/?q=${encTitle}` },
        { label: 'repack-games', url: `https://repack-games.ru/index.php?do=search&subaction=search&story=${encTitle}` },
        { label: 'byrut', url: `https://thebyrut.org/?do=search&subaction=search&story=${encTitle}` },
        { label: 'hisgames', url: `https://hisgames.org/search?searchphrase=all&searchword=${encTitle}` },
        { label: 'igrovaya', url: `https://igrovaya.org/?do=search&subaction=search&story=${encTitle}` },
        { label: 'thelastgame.club', url: `https://thelastgame.club/?do=search&subaction=search&story=${encTitle}` },
        { label: 'thelastgame.ru', url: `https://thelastgame.ru/?s=${encTitle}` },
        { label: 'thelastgame.org', url: `https://thelastgame.org/?do=search&subaction=search&story=${encTitle}` }
    ],
    Another: [
        { label: 'PCGamingWiki-SteamAppid', url: `https://www.pcgamingwiki.com/api/appid.php?appid=${gameappid}` },
        { label: 'PCGamingWiki (Title)', url: `https://www.pcgamingwiki.com/w/index.php?search=${encTitle}` },
        { label: 'small-games.info', url: `https://small-games.info/?go=search&search_text=${encTitle}` },
        { label: 'old-games', url: `https://www.old-games.ru/catalog/?gamename=${encTitle}` },
        { label: 'cs.rin', url: `https://cs.rin.ru/forum//search.php?st=0&sk=t&sd=d&sr=topics&terms=any&sf=titleonly&keywords=${encTitle}` },
        { label: 'f95zone - Adult 18+', url: `https://f95zone.to/search/search?keywords=${encTitle}` }

    ]
};


        return Object.entries(sections).map(([group, links]) => {
            const colorClass = group === 'Steam' ? 'steamBtn' : group === 'GOG' ? 'gogBtn' : 'otherBtn';
            return `
                <div class="gameLinkSection">
                    <h3>${group}</h3>
                    ${links.map(src => `<a class="gameLinkBtn ${colorClass}" target="_blank" rel="noopener noreferrer" href="${src.url}">${src.label}</a>`).join('')}
                </div>
            `;
        }).join('');
    }
})();