CamGirl Find More

Find more about your favorite camgirl

// ==UserScript==
// @name         CamGirl Find More
// @namespace    https://greasyfork.org/fr/users/1468290-payamarre
// @version      1.1
// @license MIT
// @description  Find more about your favorite camgirl
// @author       NoOne
// @match        https://stripchat.com/*
// @match        https://*.stripchat.com/*
// @match        https://chaturbate.com/*
// @match        https://*.chaturbate.com/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    const common = {
        getModelName() {
            const path = window.location.pathname.split('/');
            const model = path[1];
            if (model && !['female', 'male', 'trans', 'new', 'tags', 'login', 'signup'].includes(model)) {
                return model;
            }
            return null;
        },

        createButton(id, svg, onClick, className = '') {
            const a = document.createElement('a');
            a.href = '#';
            a.className = className;
            a.innerHTML = svg;
            a.id = id;
            a.addEventListener('click', e => {
                e.preventDefault();
                onClick();
            });
            return a;
        }
    };

    function initStripchat() {
        let buttonsInserted = false;

        function insertButtons() {
            if (buttonsInserted) return true;

            const modelName = common.getModelName();
            if (!modelName) return false;

            const targetWrapper = document.querySelector('.view-cam-buttons-wrapper');
            if (!targetWrapper || !targetWrapper.parentNode) return false;

            ['scfinder-button', 'recume-button', 'search-button'].forEach(id => {
                const oldBtn = document.getElementById(id);
                if (oldBtn) oldBtn.remove();
            });

            const scfinderBtn = common.createButton(
                'scfinder-button',
                `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="24" height="24">
                  <path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
                </svg>`,
                () => window.open(`https://camgirlfinder.net/models/sc/${modelName}`, '_blank'),
                'scfinder-tab'
            );

            const recumeBtn = common.createButton(
                'recume-button',
                `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="24" height="24">
                  <path stroke-linecap="round" stroke-linejoin="round" d="m15.75 10.5 4.72-4.72a.75.75 0 0 1 1.28.53v11.38a.75.75 0 0 1-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25h-9A2.25 2.25 0 0 0 2.25 7.5v9a2.25 2.25 0 0 0 2.25 2.25Z" />
                </svg>`,
                () => window.open(`https://recu.me/performer/${modelName}`, '_blank'),
                'scfinder-tab'
            );

            const searchBtn = common.createButton(
                'search-button',
                `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="24" height="24">
                  <path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 0 1 3 12c0-1.605.42-3.113 1.157-4.418" />
                </svg>`,
                () => {
                    const urls = [
                        `https://www.google.com/search?q=%22${modelName}%22&num=10&uact=5`,
                        `https://yandex.com/search/?text=%22${modelName}%22`,
                        `https://recu.me/performer/${modelName}`,
                        `https://camgirlfinder.net/models/sc/${modelName}`,
                        `https://btdig.com/search?order=0&q="${modelName}"`
                    ];
                    urls.forEach((url, index) => {
                        setTimeout(() => window.open(url, '_blank'), index * 200);
                    });
                },
                'scfinder-tab'
            );

            const buttonGroup = document.createElement('div');
            buttonGroup.style.display = 'flex';
            buttonGroup.style.gap = '18px';
            buttonGroup.style.alignItems = 'center';
            buttonGroup.appendChild(scfinderBtn);
            buttonGroup.appendChild(recumeBtn);
            buttonGroup.appendChild(searchBtn);

            targetWrapper.parentNode.insertBefore(buttonGroup, targetWrapper);

            buttonsInserted = true;
            return true;
        }

        const css =
            `.scfinder-tab {
                display: inline-flex !important;
                justify-content: center;
                align-items: center;
                width: 40px;
                height: 40px;
                border-radius: 50%;
                border: 2px solid #feb601;
                background-color: inherit;
                color: inherit;
                transition: background-color 0.2s, color 0.2s, stroke 0.2s;
                cursor: pointer;
            }

            .scfinder-tab:hover {
                background-color: #feb601;
                border: 2px solid #feb601;
            }

            .scfinder-tab:hover svg {
                stroke: black;
            }

            .scfinder-tab svg {
                width: 24px;
                height: 24px;
                stroke: currentColor;
            }`;
        const style = document.createElement('style');
        style.textContent = css;
        document.head.appendChild(style);

        const observer = new MutationObserver(() => insertButtons());
        observer.observe(document.body, { childList: true, subtree: true });
        setTimeout(insertButtons, 1000);
    }

    function initChaturbate() {
        const css =
            `.cgfinder-tab {
                height: 16px;
                position: relative;
                overflow: hidden;
                border-radius: 4px 4px 0px 0px;
                text-decoration: none;
                margin-right: 2px;
                font-family: UbuntuMedium, Helvetica, Arial, sans-serif;
                font-size: 13px;
                padding: 4px 8px;
                float: left;
                display: block;
                margin-top: -2px;
                background-color: inherit;
                color: inherit;
                transition: background-color 0.2s, color 0.2s;
            }

            .cgfinder-tab:hover {
                background-color: var(--cgfinder-hover-bg, #202c39);
                color: var(--cgfinder-hover-color, #f47321);
            }

            .cgfinder-tab svg {
                vertical-align: middle;
                stroke: currentColor;
            }`;
        const style = document.createElement('style');
        style.textContent = css;
        document.head.appendChild(style);

        const nativeTab = document.querySelector('.tabBar a');
        if (nativeTab) {
            nativeTab.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
            const clone = nativeTab.cloneNode(true);
            clone.style.position = 'absolute';
            clone.style.left = '-9999px';
            document.body.appendChild(clone);

            const hoverStyles = getComputedStyle(clone);
            document.documentElement.style.setProperty('--cgfinder-hover-bg', hoverStyles.backgroundColor);
            document.documentElement.style.setProperty('--cgfinder-hover-color', hoverStyles.color);
            clone.remove();
        }

        let currentModel = null;

        function insertChaturbateButtons() {
            const modelName = common.getModelName();
            if (!modelName) return;

            const tabBar = document.querySelector('.tabBar');
            if (!tabBar) return;

            ['cgfinder-button', 'recume-button', 'search-button'].forEach(id => {
                const el = document.getElementById(id);
                if (el) el.remove();
            });

            const cgfinderBtn = common.createButton(
                'cgfinder-button',
                `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="14" height="14">
                  <path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
                </svg>`,
                () => window.open(`https://camgirlfinder.net/models/cb/${modelName}`, '_blank'),
                'cgfinder-tab'
            );

            const recumeBtn = common.createButton(
                'recume-button',
                `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="14" height="14">
                  <path stroke-linecap="round" stroke-linejoin="round" d="m15.75 10.5 4.72-4.72a.75.75 0 0 1 1.28.53v11.38a.75.75 0 0 1-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25h-9A2.25 2.25 0 0 0 2.25 7.5v9a2.25 2.25 0 0 0 2.25 2.25Z" />
                </svg>`,
                () => window.open(`https://recu.me/performer/${modelName}`, '_blank'),
                'cgfinder-tab'
            );

            const searchBtn = common.createButton(
                'search-button',
                `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="14" height="14">
                  <path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 0 1 3 12c0-1.605.42-3.113 1.157-4.418" />
                </svg>`,
                () => {
                    const urls = [
                        `https://www.google.com/search?q=%22${modelName}%22&num=10&uact=5`,
                        `https://yandex.com/search/?text=%22${modelName}%22`,
                        `https://recu.me/performer/${modelName}`,
                        `https://camgirlfinder.net/models/cb/${modelName}`,
                        `https://btdig.com/search?order=0&q="${modelName}"`
                    ];
                    urls.forEach((url, i) => setTimeout(() => window.open(url, '_blank'), i * 200));
                },
                'cgfinder-tab'
            );

            tabBar.insertBefore(searchBtn, tabBar.firstChild);
            tabBar.insertBefore(recumeBtn, tabBar.firstChild);
            tabBar.insertBefore(cgfinderBtn, tabBar.firstChild);
        }

        function checkAndInject() {
            const newModel = common.getModelName();
            if (newModel && newModel !== currentModel) {
                currentModel = newModel;
                insertChaturbateButtons();
            }
        }

        setInterval(checkAndInject, 1000);
    }

    const host = window.location.hostname;
    if (host.includes('stripchat')) {
        initStripchat();
    } else if (host.includes('chaturbate')) {
        initChaturbate();
    }

})();