GarticFlix V1 Elite

Ultimate Gartic Experience

// ==UserScript==
// @name GarticFlix V1 Elite
// @namespace http://tampermonkey.net/
// @version v.11.0
// @description Ultimate Gartic Experience
// @author Akíra & ygn
// @match https://gartic.io/*
// @icon https://www.google.com/s2/favicons?domain=gartic.io
// @grant none
// ==/UserScript==

if (window.location.href.indexOf("?L") !== -1) {
    const styles = `
        @import url('https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&display=swap');
        
        :root {
            --bg-primary: #0f172a;
            --bg-secondary: #1e293b;
            --accent: #6366f1;
            --accent-hover: #4f46e5;
            --text: #e2e8f0;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Outfit', sans-serif;
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(20px); }
            to { opacity: 1; transform: translateY(0); }
        }

        @keyframes shimmer {
            0% { background-position: -1000px 0; }
            100% { background-position: 1000px 0; }
        }

        @keyframes float {
            0% { transform: translateY(0px); }
            50% { transform: translateY(-10px); }
            100% { transform: translateY(0px); }
        }

        .container {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100vh;
            background: var(--bg-primary);
            color: var(--text);
            overflow-y: auto;
            z-index: 9999;
            padding: 20px;
        }

        .header {
            background: linear-gradient(135deg, var(--accent), var(--accent-hover));
            padding: 20px;
            border-radius: 15px;
            text-align: center;
            margin-bottom: 20px;
            position: relative;
            overflow: hidden;
            animation: float 6s ease-in-out infinite;
        }

        .header::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            animation: shimmer 2s infinite;
        }

        .header h1 {
            font-size: 28px;
            font-weight: 700;
            color: white;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
            margin: 0;
        }

        .controls {
            background: var(--bg-secondary);
            border-radius: 15px;
            padding: 20px;
            margin-bottom: 20px;
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            animation: fadeIn 0.5s ease-out;
        }

        .control-input {
            width: 100%;
            padding: 12px;
            background: rgba(255,255,255,0.1);
            border: 2px solid var(--accent);
            border-radius: 10px;
            color: var(--text);
            font-size: 16px;
            transition: all 0.3s ease;
        }

        .control-input:focus {
            outline: none;
            border-color: var(--accent-hover);
            box-shadow: 0 0 15px rgba(99, 102, 241, 0.3);
        }

        .stats {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 15px;
            margin-bottom: 20px;
        }

        .stat-card {
            background: var(--bg-secondary);
            padding: 15px;
            border-radius: 10px;
            text-align: center;
        }

        .stat-value {
            font-size: 24px;
            font-weight: 700;
            color: var(--accent);
        }

        .stat-label {
            font-size: 14px;
            opacity: 0.8;
            margin-top: 5px;
        }

        .rooms-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
            gap: 20px;
            animation: fadeIn 0.6s ease-out;
        }

        .room-card {
            background: var(--bg-secondary);
            border-radius: 15px;
            padding: 20px;
            transition: all 0.3s ease;
            position: relative;
            overflow: hidden;
        }

        .room-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 20px rgba(0,0,0,0.2);
        }

        .room-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid rgba(99, 102, 241, 0.2);
        }

        .room-title {
            font-size: 18px;
            font-weight: 600;
            color: var(--accent);
        }

        .room-stats {
            font-size: 14px;
            opacity: 0.8;
        }

        .room-actions {
            display: flex;
            gap: 10px;
        }

        .btn {
            padding: 10px 20px;
            border-radius: 8px;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s ease;
            border: none;
            flex: 1;
            font-size: 14px;
        }

        .btn-primary {
            background: var(--accent);
            color: white;
        }

        .btn-primary:hover {
            background: var(--accent-hover);
            transform: translateY(-2px);
        }

        .btn-secondary {
            background: transparent;
            border: 2px solid var(--accent);
            color: var(--accent);
        }

        .btn-secondary:hover {
            background: var(--accent);
            color: white;
        }

        .users-grid {
            display: none;
            grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
            gap: 10px;
            margin-top: 15px;
            padding: 15px;
            background: rgba(0,0,0,0.2);
            border-radius: 10px;
            animation: fadeIn 0.3s ease-out;
        }

        .user-avatar {
            width: 60px;
            height: 60px;
            border-radius: 50%;
            cursor: pointer;
            transition: all 0.3s ease;
            border: 2px solid var(--accent);
        }

        .user-avatar:hover {
            transform: scale(1.1);
            border-color: var(--accent-hover);
        }

        .nickname-tooltip {
            position: absolute;
            background: var(--accent);
            color: white;
            padding: 5px 10px;
            border-radius: 5px;
            font-size: 12px;
            z-index: 1000;
            pointer-events: none;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        @media (max-width: 768px) {
            .controls {
                grid-template-columns: 1fr;
            }
            
            .rooms-grid {
                grid-template-columns: 1fr;
            }
        }
    `;

    document.head.innerHTML = `<style>${styles}</style>`;






















    const mainContainer = document.createElement("div");
    mainContainer.className = "container";
    mainContainer.innerHTML = `
        <div class="header">
            <h1>GarticFlix Elite</h1>
        </div>

        <div class="stats">
            <div class="stat-card">
                <div class="stat-value" id="totalRooms">0</div>
                <div class="stat-label">Aktif Odalar</div>
            </div>
            <div class="stat-card">
                <div class="stat-value" id="totalPlayers">0</div>
                <div class="stat-label">Toplam Oyuncu</div>
            </div>
            <div class="stat-card">
                <div class="stat-value" id="onlineUsers">0</div>
                <div class="stat-label">Çevrimiçi</div>
            </div>
        </div>

        <div class="controls">
            <input type="text" class="control-input" placeholder="Oda veya Oyuncu Ara..." onkeyup="window.filterRooms(this.value)">
            
            <select class="control-input theme-select" onchange="window.updateRooms()">
                <option value="">Tüm Temalar</option>
                <option value="1">Genel</option>
                <option value="28">Anime</option>
                <option value="30">Diğer</option>
                <option value="12">Oyunlar</option>
                <option value="24">Youtuber</option>
                <option value="11">LoL</option>
                <option value="2">Hayvanlar</option>
                <option value="31">Minecraft</option>
                <option value="4">Yiyecekler</option>
                <option value="9">Animasyon</option>
                <option value="35">Naruto</option>
                <option value="16">Bayraklar</option>
                <option value="10">Şarkılar</option>
                <option value="17">Futbol</option>
                <option value="26">Logo</option>
                <option value="5">Fiiller</option>
                <option value="33">FNAF</option>
                <option value="3">Nesneler</option>
                <option value="6">Ülkeler</option>
                <option value="7">Markalar</option>
                <option value="8">Filmler</option>
            </select>

            <select class="control-input lang-select" onchange="window.updateRooms()">
                <option value="8">Türkçe</option>
                <option value="2">English</option>
                <option value="3">Español</option>
                <option value="1">Português</option>
                <option value="7">Русский</option>
                <option value="13">Tiếng Việt</option>
                <option value="15">日本語</option>
                <option value="20">한국어</option>
                <option value="23">Azərbaycanca</option>
                <option value="45">Bahasa Indonesia</option>
                <option value="11">Čeština</option>
                <option value="14">Deutsch</option>
                <option value="4">Français</option>
                <option value="6">Italiano</option>
                <option value="44">Magyar</option>
                <option value="18">Nederlands</option>
                <option value="10">Polski</option>
                <option value="58">Română</option>
                <option value="22">Slovenčina</option>
                <option value="21">български език</option>
                <option value="40">עברית</option>
                <option value="19">العربية</option>
                <option value="34">فارسی</option>
                <option value="12">ภาษาไทย</option>
                <option value="16">中文 (简化字)</option>
                <option value="9">中文 (臺灣)</option>
                <option value="17">中文 (香港)</option>
            </select>
        </div>

        <div class="rooms-grid"></div>
    `;

    document.body.appendChild(mainContainer);

    let roomsData = [];
    let filteredRooms = [];

    function createRoomCard(room) {
        const card = document.createElement('div');
        card.className = 'room-card';
        card.innerHTML = `
            <div class="room-header">
                <div class="room-title">#${room.code}</div>
                <div class="room-stats">${room.quant}/${room.max} Oyuncu</div>
            </div>
            <div class="room-actions">
                <button class="btn btn-primary" onclick="window.joinRoom('${room.code}')">Katıl</button>
                <button class="btn btn-secondary" onclick="window.watchRoom('${room.code}')">İzle</button>
                <button class="btn btn-primary" onclick="window.showUsers('${room.code}')">Kullanıcılar</button>
            </div>
            <div class="users-grid" id="users-${room.code}"></div>
        `;
        return card;
    }

    window.filterRooms = (query) => {
        query = query.toLowerCase();
        filteredRooms = roomsData.filter(room => 
            room.code.toLowerCase().includes(query) ||
            (room.players && room.players.some(player => 
                player.nick.toLowerCase().includes(query)
            ))
        );
        updateRoomsDisplay();
    };

    window.updateRooms = () => {
        const theme = document.querySelector('.theme-select').value;
        const lang = document.querySelector('.lang-select').value;
        
        let url = `https://gartic.io/req/list?language[]=${lang}`;
        if (theme) url += `&subject[]=${theme}`;

        fetch(url)
            .then(response => response.json())
            .then(data => {
                roomsData = data;
                filteredRooms = data;
                updateRoomsDisplay();
                updateStats();
            });
    };

    function updateStats() {
        document.getElementById('totalRooms').textContent = roomsData.length;
        const totalPlayers = roomsData.reduce((acc, room) => acc + room.quant, 0);
        document.getElementById('totalPlayers').textContent = totalPlayers;
        document.getElementById('onlineUsers').textContent = totalPlayers + Math.floor(Math.random() * 100);
    }















    function updateRoomsDisplay() {
        const container = document.querySelector('.rooms-grid');
        container.innerHTML = '';
        filteredRooms.forEach(room => {
            container.appendChild(createRoomCard(room));
        });
    }

    window.joinRoom = (code) => {
        window.open(`https://gartic.io/${code}`, '_blank');
    };

    window.watchRoom = (code) => {
        window.open(`https://gartic.io/${code}/viewer`, '_blank');
    };

    window.showUsers = (roomCode) => {
        const usersGrid = document.getElementById(`users-${roomCode}`);
        const isVisible = usersGrid.style.display === 'grid';
        
        if (!isVisible) {
            usersGrid.style.display = 'grid';
            loadRoomUsers(roomCode);
        } else {
            usersGrid.style.display = 'none';
        }
    };

    function loadRoomUsers(roomCode) {
        const usersGrid = document.getElementById(`users-${roomCode}`);
        usersGrid.innerHTML = '';

        const servers = ['01', '02', '03', '04', '05', '06'];
        let connectedServer = false;

        function tryNextServer(index) {
            if (index >= servers.length || connectedServer) return;

            const ws = new WebSocket(`wss://server${servers[index]}.gartic.io/socket.io/?EIO=3&transport=websocket`);
            
            ws.onopen = () => {
                ws.send(`42[12,{"v":20000,"platform":0,"sala":"${roomCode.slice(-4)}"}]`);
            };

            ws.onmessage = (msg) => {
                if (msg.data.startsWith('42[5,')) {
                    try {
                        const data = JSON.parse(msg.data.slice(2));
                        if (data[0] === 5 && Array.isArray(data[5])) {
                            connectedServer = true;
                            displayUsers(data[5], usersGrid);
                            ws.close();
                        }
                    } catch (e) {
                        console.error('JSON parse error:', e);
                    }
                }
            };

            ws.onerror = () => {
                tryNextServer(index + 1);
            };

            ws.onclose = () => {
                if (!connectedServer) {
                    tryNextServer(index + 1);
                }
            };
        }

        tryNextServer(0);
    }

    function displayUsers(users, container) {
        users.forEach(user => {
            const userContainer = document.createElement('div');
            userContainer.style.position = 'relative';
            
            const avatar = document.createElement('img');
            avatar.className = 'user-avatar';
            avatar.src = user.foto || `https://gartic.io/static/images/avatar/svg/${user.avatar}.svg`;
            avatar.setAttribute('data-nick', user.nick);
            avatar.setAttribute('data-points', user.pontos || 0);
            
            avatar.addEventListener('mouseenter', showTooltip);
            avatar.addEventListener('mouseleave', hideTooltip);
            
            userContainer.appendChild(avatar);
            container.appendChild(userContainer);
        });
    }

    function showTooltip(event) {
        const avatar = event.target;
        const nick = avatar.getAttribute('data-nick');
        const points = avatar.getAttribute('data-points');

        const tooltip = document.createElement('div');
        tooltip.className = 'nickname-tooltip';
        tooltip.innerHTML = `
            <div>${nick}</div>
            <div style="font-size: 11px">${points} puan</div>
        `;

        const rect = avatar.getBoundingClientRect();
        tooltip.style.position = 'fixed';
        tooltip.style.left = `${rect.left + rect.width/2}px`;
        tooltip.style.top = `${rect.top - 10}px`;
        tooltip.style.transform = 'translate(-50%, -100%)';
        tooltip.style.opacity = '1';

        document.body.appendChild(tooltip);
        avatar.tooltip = tooltip;
    }

    function hideTooltip(event) {
        const tooltip = event.target.tooltip;
        if (tooltip) {
            tooltip.style.opacity = '0';
            setTimeout(() => tooltip.remove(), 200);
        }
    }

    
    window.updateRooms();
    setInterval(window.updateRooms, 5000);

    
    function handleResize() {
        const container = document.querySelector('.container');
        container.style.height = `${window.innerHeight}px`;
    }

    window.addEventListener('resize', handleResize);
    handleResize();

    
    let updateTimeout;
    window.filterRooms = (query) => {
        clearTimeout(updateTimeout);
        updateTimeout = setTimeout(() => {
            query = query.toLowerCase();
            filteredRooms = roomsData.filter(room => 
                room.code.toLowerCase().includes(query)
            );
            updateRoomsDisplay();
        }, 300);
    };
}