F95Zone Search Buttons for DLsite

Adds modern, well-aligned buttons to search for the current game, circle, and product ID on F95Zone, OtomiGames, and RyuuGames. Keeps "Circle: [Name]" on one line and places circle buttons side by side.

// ==UserScript==
// @name         F95Zone Search Buttons for DLsite
// @namespace    http://tampermonkey.net/
// @version      2.2
// @description  Adds modern, well-aligned buttons to search for the current game, circle, and product ID on F95Zone, OtomiGames, and RyuuGames. Keeps "Circle: [Name]" on one line and places circle buttons side by side.
// @author       FunkyJustin
// @match        https://www.dlsite.com/maniax/work/=/product_id/*
// @match        https://www.dlsite.com/pro/work/=/product_id/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Wait for page load
    window.addEventListener('load', createSearchButtons);

    function createSearchButtons() {
        // 1. Extract game/circle info
        const gameTitleEl = document.querySelector('h1#work_name');
        const circleNameEl = document.querySelector('span[itemprop="brand"] a');
        if (!gameTitleEl || !circleNameEl) return;

        const gameTitle = gameTitleEl.innerText.trim();
        const circleName = circleNameEl.innerText.trim();

        let productId = window.location.href.match(/product_id\/([^\/]+)/)[1] || '';
        productId = productId.replace('.html', '');

        // 2. Define URLs
        // F95Zone
        const f95zoneGameLink      = `https://f95zone.to/sam/latest_alpha/#/cat=games/page=1/search=${encodeURIComponent(gameTitle)}`;
        const f95zoneForumLink     = `https://f95zone.to/search/?q=${encodeURIComponent(gameTitle)}&t=post&c[child_nodes]=1&c[nodes][0]=2&c[title_only]=1&o=relevance`;
        const f95zoneCircleLink    = `https://f95zone.to/sam/latest_alpha/#/cat=games/page=1/creator=${encodeURIComponent(circleName)}`;
        const f95zoneProductIdLink = `https://f95zone.to/search/?q=${encodeURIComponent(productId)}`;

        // OtomiGames
        const otomiGamesSearchLink    = `https://otomi-games.com/?s=${encodeURIComponent(gameTitle)}`;
        const otomiGamesProductIdLink = `https://otomi-games.com/${productId}/`;

        // RyuuGames
        const ryuuGamesTitleLink      = `https://www.ryuugames.com/?s=${encodeURIComponent(gameTitle)}`;
        const ryuuGamesProductIdLink  = `https://www.ryuugames.com/?s=${encodeURIComponent(productId)}`;
        const ryuuGamesCircleLink     = `https://www.ryuugames.com/?s=${encodeURIComponent(circleName)}`;

        // 3. Common button styling
        const buttonBaseStyle = {
            display: 'inline-block',
            padding: '8px 16px',
            margin: '5px',
            color: '#fff',
            backgroundColor: '#009688',
            borderRadius: '4px',
            textDecoration: 'none',
            fontSize: '0.9rem',
            cursor: 'pointer',
            transition: 'background-color 0.3s ease'
        };

        function createButton(text, url) {
            const a = document.createElement('a');
            a.innerText = text;
            a.href = url;
            a.target = '_blank';
            Object.assign(a.style, buttonBaseStyle);
            // Hover effect
            a.addEventListener('mouseover', () => {
                a.style.backgroundColor = '#00796B';
            });
            a.addEventListener('mouseout', () => {
                a.style.backgroundColor = '#009688';
            });
            return a;
        }

        // 4. Create buttons
        // Title-based searches
        const f95GameBtn   = createButton('Search on F95Zone', f95zoneGameLink);
        const f95ForumBtn  = createButton('Search on F95Zone Forums', f95zoneForumLink);
        const f95PIDBtn    = createButton('Search Product ID on F95Zone', f95zoneProductIdLink);
        const otomiGameBtn = createButton('Search on OtomiGames', otomiGamesSearchLink);
        const otomiPIDBtn  = createButton('Search Product ID on OtomiGames', otomiGamesProductIdLink);
        const ryuuGameBtn  = createButton('Search on RyuuGames', ryuuGamesTitleLink);
        const ryuuPIDBtn   = createButton('Search Product ID on RyuuGames', ryuuGamesProductIdLink);

        // Circle-based searches
        const f95CircleBtn  = createButton('Search Circle on F95Zone', f95zoneCircleLink);
        const ryuuCircleBtn = createButton('Search Circle on RyuuGames', ryuuGamesCircleLink);

        // 5. Append Title Buttons in a Flex Container
        const titleContainer = document.querySelector('.base_title_br');
        if (titleContainer) {
            const titleFlex = document.createElement('div');
            titleFlex.style.display = 'flex';
            titleFlex.style.flexWrap = 'wrap';
            titleFlex.style.alignItems = 'center';
            titleFlex.style.marginTop = '10px';

            [f95GameBtn, f95ForumBtn, f95PIDBtn,
             otomiGameBtn, otomiPIDBtn,
             ryuuGameBtn, ryuuPIDBtn]
                .forEach(btn => titleFlex.appendChild(btn));

            titleContainer.appendChild(titleFlex);
        }

        // 6. Append Circle Buttons Side by Side
        // Insert right after the circle name, so "Circle: BLACK PANDA" remains on one line
        const circleButtonWrapper = document.createElement('span');
        circleButtonWrapper.style.display = 'inline-flex';
        circleButtonWrapper.style.flexWrap = 'nowrap';
        circleButtonWrapper.style.alignItems = 'center';
        circleButtonWrapper.style.marginLeft = '10px';
        // Add both buttons side by side
        circleButtonWrapper.appendChild(f95CircleBtn);
        circleButtonWrapper.appendChild(ryuuCircleBtn);

        circleNameEl.insertAdjacentElement('afterend', circleButtonWrapper);

        // 7. Auto-submit on F95Zone forum pages
        if (window.location.href === f95zoneForumLink || window.location.href === f95zoneProductIdLink) {
            window.onload = function() {
                setTimeout(function() {
                    const searchField = document.querySelector('.input[name="keywords"]');
                    if (searchField) {
                        searchField.value = gameTitle;
                        searchField.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
                    }
                }, 1000);
            };
        }
    }
})();