WHOWHERE V2 GM

WhoWhere V2 GM_xmlhttpRequest for Gartic.io

Устаревшая версия за 04.09.2025. Перейдите к последней версии.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         WHOWHERE V2 GM
// @namespace    http://tampermonkey.net/
// @version      2.2
// @description  WhoWhere V2 GM_xmlhttpRequest for Gartic.io
// @author       ᴊᴜsᴛ ᴀʟɪᴋᴏᴏ
// @match        *://gartic.io/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=gartic.io
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {
    'use strict';

    console.log('Gartic.io WhoWhere GM hazirdir!');

    // --- UI ELEMENTLERI ---
    const overlay = document.createElement('div');
    overlay.className = 'overlay';

    const header = document.createElement('header');
    header.innerHTML = '<h2>WhoWhere V2 by ᴊᴜsᴛ ᴀʟɪᴋᴏᴏ</h2>';
    overlay.append(header);

    const p = document.createElement('p');
    p.textContent = 'Hazırki Otağlar';
    overlay.append(p);

    const closeButton = document.createElement('button');
    closeButton.textContent = 'Bağla';
    closeButton.style.cssText = 'position: fixed; top: 10px; right: 10px; padding: 5px 10px; background-color: darkred; color: white; border: none; border-radius: 5px; cursor: pointer;';
    overlay.append(closeButton);

    const openButton = document.createElement('button');
    openButton.textContent = 'Aç';
    openButton.style.cssText = 'position: fixed; bottom: 10px; right: 10px; padding: 5px 10px; background-color: darkgreen; color: white; border: none; border-radius: 5px; cursor: pointer; display: none; z-index: 9999;';
    document.body.append(openButton);

    closeButton.onclick = () => {
        overlay.style.display = 'none';
        openButton.style.display = 'block';
    };
    openButton.onclick = () => {
        overlay.style.display = 'block';
        openButton.style.display = 'none';
    };

    const select = document.createElement('select');
    select.id = 'lg';
    select.innerHTML = `
        <option value="23" selected>Azərbaycanca</option>
        <option value="2">English</option>
        <option value="8">Türkçe</option>
        <option value="7">Русский</option>
    `;
    overlay.append(select);

    const flexDiv = document.createElement('div');
    flexDiv.className = 'flex';
    overlay.append(flexDiv);

    const totalCountDisplay = document.createElement('div');
    totalCountDisplay.style.cssText = 'position: fixed; top: 50px; left: 10px; background-color: darkslateblue; color: white; padding: 5px 10px; border-radius: 5px; z-index: 9999;';
    document.body.append(totalCountDisplay);

    document.body.prepend(overlay);

    // --- STIL ---
    const style = document.createElement('style');
    style.textContent = `
        .overlay { position: fixed; top:0; left:0; width:100%; height:100%; background-color:gray; color:#f0f0f0; z-index:9999; overflow-y:auto; text-align:center; padding:20px; }
        .flex { display:flex; justify-content:center; flex-wrap:wrap; gap:8px; margin-top:1rem; }
        .flex-child { background-color:darkgray; padding:8px 12px; min-width:150px; border-radius:30px; }
        .flex-child img { width:25px; height:25px; border-radius:50%; border:1px solid #666; }
        .users .user-info { display:flex; align-items:center; margin-bottom:4px; }
        .users .user-info p { margin-left:4px; font-size:12px; overflow-wrap:anywhere; }
        select { font-size:16px; padding:5px; border-radius:30px; background-color:darkslateblue; color:white; }
    `;
    document.head.append(style);

    // --- FUNKSIYA ---
    let roomIds = [];

    function f(lang) {
        GM_xmlhttpRequest({
            method: "GET",
            url: `https://gartic.io/req/list?search=&language[]=${lang}`,
            onload: function(response) {
                const data = JSON.parse(response.responseText);
                const active = data.filter(room => room.quant > 0);
                if (active.length === 0) {
                    flexDiv.innerHTML = '<h2>Seçilən dildə otağ yoxdur.</h2>';
                    totalCountDisplay.textContent = '';
                    return;
                }

                flexDiv.innerHTML = '';
                roomIds = [];

                active.forEach((room, k) => {
                    roomIds.push(room.id);

                    const flc = document.createElement('div');
                    flc.classList.add('flex-child');
                    flexDiv.appendChild(flc);

                    const roomTag = document.createElement('h3');
                    roomTag.innerText = room.id.slice(1);

                    const roomSubjIcon = document.createElement('img');
                    roomSubjIcon.src = `https://gartic.io/static/images/subjects/${room.subject}.svg`;

                    const inRoomPlayers = document.createElement('p');
                    inRoomPlayers.innerText = `${room.quant} / ${room.max} ・ ${room.points} / ${room.goal}`;

                    const users = document.createElement('div');
                    users.classList.add('users');

                    const viewBtn = document.createElement('a');
                    viewBtn.href = `https://gartic.io/${room.code}/viewer`;
                    viewBtn.target = '_blank';
                    viewBtn.innerText = 'Otağı izlə';

                    const joinBtn = document.createElement('a');
                    joinBtn.href = `https://gartic.io/${room.code}`;
                    joinBtn.target = '_blank';
                    joinBtn.innerText = 'Otağa daxil ol';

                    flc.append(roomTag, roomSubjIcon, inRoomPlayers, users, viewBtn, joinBtn);

                    // WebSocket ilə istifadəçi məlumatı
                    GM_xmlhttpRequest({
                        method: "GET",
                        url: `https://gartic.io/serverViewer?room=${room.code}`,
                        onload: function(rs) {
                            const dt = rs.responseText;
                            const s = dt.slice(15,16);
                            const ws = new WebSocket(`wss://server0${s}.gartic.io/socket.io/?EIO=3&transport=websocket`);

                            ws.onopen = () => {
                                ws.send(`42["12",{"v":20000,"sala":"${room.id}"}]`);
                            };
                            ws.onmessage = (m) => {
                                try {
                                    const d = JSON.parse(m.data.slice(2));
                                    if(d[0] == 5) {
                                        for(let i=0;i<d[5].length;i++){
                                            const userB = document.createElement('div');
                                            userB.classList.add('user-info');

                                            const userPp = document.createElement('img');
                                            userPp.src = d[5][i].foto || 'https://gartic.io/static/images/avatar/svg/0.svg';

                                            const userName = document.createElement('p');
                                            userName.innerText = d[5][i].nick;

                                            userB.append(userPp, userName);
                                            users.append(userB);
                                        }
                                    }
                                } catch(e){ console.error(e); }
                            };
                        }
                    });

                });

                totalCountDisplay.innerText = `Total Otağ: ${active.length}, Total User: ${active.reduce((acc,curr)=>acc+curr.quant,0)}`;
            }
        });
    }

    select.onchange = function(){ f(this.value); }
    f('23'); // default Azərbaycan dili

})();