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와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==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;
        }
    }

})();