dumo

Google Görsel Arama ve Gelişmiş Görsel Yansıtıcı (Sürükle, Yapıştır, Ara, Yansıt)

คุณจะต้องติดตั้งส่วนขยาย เช่น Tampermonkey, Greasemonkey หรือ Violentmonkey เพื่อติดตั้งสคริปต์นี้

You will need to install an extension such as Tampermonkey to install this script.

คุณจะต้องติดตั้งส่วนขยาย เช่น Tampermonkey หรือ Violentmonkey เพื่อติดตั้งสคริปต์นี้

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         dumo
// @namespace    http://tampermonkey.net/
// @version      4.1 - DÜZELTİLMİŞ ENTEGRE
// @description  Google Görsel Arama ve Gelişmiş Görsel Yansıtıcı (Sürükle, Yapıştır, Ara, Yansıt)
// @author       g & Ferres (Merged)
// @match        https://gartic.io/*
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @connect      googleapis.com
// @icon         https://www.google.com/s2/favicons?sz=64&domain=gartic.io
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // ==========================================
    // 1. GENEL AYARLAR VE API BİLGİLERİ
    // ==========================================
    const API_KEY = "AIzaSyBP6U28ngnKhCKYoYgkExWXNxHT_-MCJvQ";
    const SEARCH_ENGINE_ID = "d3a4fb1c91a394ccd";

    // Mobil kontrolü
    const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);

    // Değişkenler
    let overlayGorsel = null; // Ekrana basılan resim
    let menuAcik = false;     // Ayar menüsü durumu
    let searchPanelAcik = false; // Arama paneli durumu

    // ==========================================
    // 2. STİLLER (CSS)
    // ==========================================
    GM_addStyle(`
        /* Arama Paneli Stilleri */
        #babaSokucuPanel {
            position: fixed;
            top: ${isMobile ? '5px' : '10px'};
            left: 50%;
            transform: translateX(-50%);
            width: ${isMobile ? '95vw' : '320px'};
            max-width: ${isMobile ? '350px' : '320px'};
            background-color: #f1f1f1;
            border: 2px solid #888;
            border-radius: 8px;
            z-index: 9999;
            display: none;
            flex-direction: column;
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
            font-family: Arial, sans-serif;
            ${isMobile ? 'touch-action: none;' : ''}
        }
        #babaSokucuHeader {
            padding: ${isMobile ? '15px 10px' : '10px'};
            cursor: ${isMobile ? 'grab' : 'move'};
            z-index: 10000;
            background-color: #c0392b;
            color: white;
            border-top-left-radius: 6px;
            border-top-right-radius: 6px;
            text-align: center;
            font-weight: bold;
            font-size: ${isMobile ? '16px' : '14px'};
            user-select: none;
        }
        #babaSokucuContent {
            padding: ${isMobile ? '20px 15px' : '15px'};
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        #flagSearchInput {
            width: 95%;
            padding: ${isMobile ? '12px 8px' : '8px'};
            margin-bottom: ${isMobile ? '15px' : '10px'};
            border: 1px solid #ccc;
            border-radius: 4px;
            font-size: ${isMobile ? '16px' : '14px'};
        }
        #flagImageContainer {
            width: 100%;
            height: ${isMobile ? '200px' : '180px'};
            border: 1px dashed #ccc;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #fff;
            margin-top: 5px;
            overflow: hidden;
            position: relative;
        }
        #flagImage {
            max-width: 100%;
            max-height: 100%;
            display: none;
        }
        #searchButton {
            width: 100%;
            padding: ${isMobile ? '12px' : '8px'};
            background-color: #c0392b;
            color: white;
            border: none;
            border-radius: 4px;
            font-weight: bold;
            cursor: pointer;
            margin-top: 10px;
        }
        #btn-transfer-img {
            width: 100%;
            padding: 10px;
            background-color: #27ae60;
            color: white;
            border: none;
            border-radius: 4px;
            font-weight: bold;
            cursor: pointer;
            margin-top: 10px;
            display: none; /* Başlangıçta gizli */
        }
        #mobileToggleBtn {
            position: fixed;
            bottom: ${isMobile ? '80px' : '70px'};
            right: ${isMobile ? '20px' : '10px'};
            width: 50px;
            height: 50px;
            background-color: #c0392b;
            color: white;
            border: none;
            border-radius: 50%;
            font-size: 12px;
            font-weight: bold;
            cursor: pointer;
            z-index: 9998;
            box-shadow: 0 2px 6px rgba(0,0,0,0.3);
            display: flex;
            align-items: center;
            justify-content: center;
            text-align: center;
        }
    `);

    // ==========================================
    // 3. HTML ARAYÜZ OLUŞTURMA
    // ==========================================

    const overlayMenuHTML = `
        <div id="ressam-menu" style="
            position: fixed; top: 70px; left: 10px; background: rgba(0, 0, 0, 0.9); color: #00ff00;
            padding: 15px; border: 2px solid #00ff00; border-radius: 10px; z-index: 9999;
            font-family: sans-serif; box-shadow: 0 0 15px #00ff00; display: none; width: 240px;
        ">
            <h4 style="margin:0 0 10px 0; text-align:center; color:white;">YANSITMA AYARLARI</h4>
            <label style="font-size:12px; color:#ddd;">🔗 Link:</label>
            <input type="text" id="img-url" placeholder="https://..." style="width: 95%; background: #333; color: white; border: 1px solid #666; padding: 5px; margin-bottom: 5px;">
            <button id="btn-link-yukle" style="width:100%; background:#444; color:white; border:1px solid #666; cursor:pointer; margin-bottom:10px;">Linkten Yükle</button>
            <label style="font-size:12px; color:#ddd;">📂 Dosya:</label>
            <input type="file" id="img-upload" accept="image/*" style="width:100%; font-size:11px; margin-bottom:10px; color:white;">
            <label style="font-size:12px;">Saydamlık:</label>
            <input type="range" id="opacity-slider" min="0" max="1" step="0.1" value="0.5" style="width:100%;">
            <button id="btn-gizle" style="width: 100%; background: #ff3333; color: white; font-weight: bold; border: none; padding: 5px; cursor: pointer; margin-top: 10px; border-radius: 4px;">RESMİ KALDIR</button>
        </div>
    `;

    const toggleButtonHTML = `
        <button id="ressam-toggle-btn" style="
            position: fixed; top: 10px; left: 10px; width: 50px; height: 50px;
            background: #222; color: #00ff00; border: 2px solid #00ff00; border-radius: 50%;
            font-size: 24px; cursor: pointer; z-index: 10000; box-shadow: 0 0 10px #00ff00;
            display: flex; align-items: center; justify-content: center;
        ">🎨</button>
    `;

    const searchPanelElement = document.createElement('div');
    searchPanelElement.id = 'babaSokucuPanel';
    searchPanelElement.innerHTML = `
        <div id="babaSokucuHeader">📱 Google Görsel Arama</div>
        <div id="babaSokucuContent">
            <input type="text" id="flagSearchInput" placeholder="Kelimeyi yazın (örn: kedi)">
            <button id="searchButton">🔍 ARA</button>
            <div id="flagImageContainer">
                <img id="flagImage" src="" alt="Resim">
                <span id="infoText" style="color:#555; text-align:center; padding:10px; font-size:12px;">Google'daki ilk resim burada görünecek.</span>
            </div>
            <button id="btn-transfer-img">🎨 EKRANA YANSIT</button>
        </div>
    `;

    const searchToggleBtn = document.createElement('button');
    searchToggleBtn.id = 'mobileToggleBtn';
    searchToggleBtn.innerHTML = '🔍<br>ARA';

    const container = document.createElement('div');
    container.innerHTML = toggleButtonHTML + overlayMenuHTML;
    document.body.appendChild(container);
    document.body.appendChild(searchPanelElement);
    document.body.appendChild(searchToggleBtn);

    // ==========================================
    // YENİ EKLENEN: DOĞRU CANVAS'I BULMA SİSTEMİ
    // ==========================================
    function anaCanvasBul() {
        // Gartic ana çizim tahtasını genellikle id="canvas" ile belirtir
        let anaCanvas = document.getElementById('canvas');
        if (anaCanvas) return anaCanvas;

        // Eğer ID değişmişse, ekrandaki alan olarak EN BÜYÜK canvas'ı buluruz
        // Çünkü profil fotoğrafları küçük, çizim tahtası büyüktür.
        const tumCanvaslar = document.querySelectorAll('canvas');
        let enBuyukCanvas = null;
        let maksimumAlan = 0;

        tumCanvaslar.forEach(c => {
            const rect = c.getBoundingClientRect();
            const alan = rect.width * rect.height;
            if (alan > maksimumAlan) {
                maksimumAlan = alan;
                enBuyukCanvas = c;
            }
        });

        return enBuyukCanvas;
    }

    // ==========================================
    // 4. CORE FONKSİYONLAR (YANSITMA - Script 1)
    // ==========================================

    function gorseliBaslat(sourceUrl) {
        // Eski 'document.querySelector' yerine yeni fonksiyonumuzu kullanıyoruz
        const oyunCanvas = anaCanvasBul();

        if (!oyunCanvas) {
            alert('Çizim alanı (Oyun tahtası) bulunamadı! Lütfen oyuna/odaya girdiğinizden emin olun.');
            return;
        }

        if (!overlayGorsel) {
            overlayGorsel = document.createElement('img');
            overlayGorsel.style.position = 'absolute';
            overlayGorsel.style.pointerEvents = 'none';
            overlayGorsel.style.zIndex = '100';
            document.body.appendChild(overlayGorsel);
        }

        overlayGorsel.src = sourceUrl;
        overlayGorsel.style.display = 'block';

        const currentOpacity = document.getElementById('opacity-slider').value;
        overlayGorsel.style.opacity = currentOpacity;

        pozisyonGuncelle();

        const menu = document.getElementById('ressam-menu');
        menu.style.display = 'block';
        menuAcik = true;
    }

    function pozisyonGuncelle() {
        if (!overlayGorsel || overlayGorsel.style.display === 'none') return;

        // Eski kod yerine yine yeni fonksiyonu kullanıyoruz
        const oyunCanvas = anaCanvasBul();
        if (!oyunCanvas) return;

        const rect = oyunCanvas.getBoundingClientRect();
        const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
        const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;

        overlayGorsel.style.top = (rect.top + scrollTop) + 'px';
        overlayGorsel.style.left = (rect.left + scrollLeft) + 'px';
        overlayGorsel.style.width = rect.width + 'px';
        overlayGorsel.style.height = rect.height + 'px';
    }

    function dosyaOku(file) {
        if (!file || !file.type.startsWith('image/')) return;
        const reader = new FileReader();
        reader.onload = (e) => gorseliBaslat(e.target.result);
        reader.readAsDataURL(file);
    }

    // ==========================================
    // 5. CORE FONKSİYONLAR (ARAMA - Script 2)
    // ==========================================

    const flagSearchInput = document.getElementById('flagSearchInput');
    const flagImage = document.getElementById('flagImage');
    const infoText = document.getElementById('infoText');
    const transferButton = document.getElementById('btn-transfer-img');

    function searchGoogleImages(query) {
        if (!query) return;

        infoText.textContent = "Aranıyor...";
        infoText.style.display = 'block';
        flagImage.style.display = 'none';
        transferButton.style.display = 'none';

        const finalQuery = query;
        const apiUrl = `https://www.googleapis.com/customsearch/v1?key=${API_KEY}&cx=${SEARCH_ENGINE_ID}&q=${encodeURIComponent(finalQuery)}&searchType=image`;

        GM_xmlhttpRequest({
            method: "GET",
            url: apiUrl,
            onload: function(response) {
                const data = JSON.parse(response.responseText);
                if (data.error) {
                    infoText.textContent = "Hata oluştu.";
                    return;
                }
                if (data.items && data.items.length > 0) {
                    const imgLink = data.items[0].link;
                    flagImage.src = imgLink;
                    flagImage.style.display = 'block';
                    infoText.style.display = 'none';

                    // Resim bulundu, transfer butonunu göster ve linki ata
                    transferButton.style.display = 'block';
                    transferButton.onclick = function() {
                        gorseliBaslat(imgLink);
                    };

                } else {
                    infoText.textContent = "Resim bulunamadı.";
                }
            },
            onerror: function() {
                infoText.textContent = "Bağlantı hatası.";
            }
        });
    }

    // ==========================================
    // 6. EVENT LISTENER'LAR (OLAYLAR)
    // ==========================================

    document.getElementById('ressam-toggle-btn').addEventListener('click', () => {
        const menu = document.getElementById('ressam-menu');
        menuAcik = !menuAcik;
        menu.style.display = menuAcik ? 'block' : 'none';
    });

    document.getElementById('btn-link-yukle').addEventListener('click', () => {
        const url = document.getElementById('img-url').value;
        if (url) gorseliBaslat(url);
    });

    document.getElementById('img-upload').addEventListener('change', (e) => {
        if (e.target.files[0]) dosyaOku(e.target.files[0]);
    });

    document.getElementById('btn-gizle').addEventListener('click', () => {
        if (overlayGorsel) {
            overlayGorsel.style.display = 'none';
            overlayGorsel.src = '';
        }
    });

    document.getElementById('opacity-slider').addEventListener('input', (e) => {
        if (overlayGorsel) overlayGorsel.style.opacity = e.target.value;
    });

    searchToggleBtn.onclick = function() {
        const panel = document.getElementById('babaSokucuPanel');
        searchPanelAcik = !searchPanelAcik;
        panel.style.display = searchPanelAcik ? 'flex' : 'none';
    };

    document.addEventListener('keydown', (e) => {
        if (e.key === 'Insert') {
            searchToggleBtn.click();
        }
    });

    document.getElementById('searchButton').addEventListener('click', () => {
        searchGoogleImages(flagSearchInput.value.trim());
    });

    flagSearchInput.addEventListener('keyup', (e) => {
        if (e.key === 'Enter') searchGoogleImages(flagSearchInput.value.trim());
    });

    window.addEventListener('paste', (e) => {
        const items = (e.clipboardData || e.originalEvent.clipboardData).items;
        for (let item of items) {
            if (item.type.indexOf('image') === 0) {
                const blob = item.getAsFile();
                dosyaOku(blob);
            }
        }
    });

    window.addEventListener('dragover', (e) => e.preventDefault());
    window.addEventListener('drop', (e) => {
        e.preventDefault();
        if (e.dataTransfer.files[0]) dosyaOku(e.dataTransfer.files[0]);
    });

    window.addEventListener('resize', pozisyonGuncelle);
    setInterval(pozisyonGuncelle, 1000);

    dragElement(document.getElementById('babaSokucuPanel'));

    function dragElement(elmnt) {
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
        const header = document.getElementById('babaSokucuHeader');
        if(!header) return;

        header.onmousedown = dragMouseDown;
        if(isMobile) header.ontouchstart = dragTouchStart;

        function dragMouseDown(e) {
            e.preventDefault();
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            document.onmousemove = elementDrag;
        }

        function dragTouchStart(e) {
            const touch = e.touches[0];
            pos3 = touch.clientX;
            pos4 = touch.clientY;
            document.ontouchend = closeDragElement;
            document.ontouchmove = elementDragTouch;
        }

        function elementDrag(e) {
            e.preventDefault();
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
            updatePos();
        }

        function elementDragTouch(e) {
            const touch = e.touches[0];
            pos1 = pos3 - touch.clientX;
            pos2 = pos4 - touch.clientY;
            pos3 = touch.clientX;
            pos4 = touch.clientY;
            updatePos();
        }

        function updatePos() {
            elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
            elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
            elmnt.style.transform = 'none';
        }

        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
            document.ontouchend = null;
            document.ontouchmove = null;
        }
    }

})();