Pastel Live 2.0

Gartic.io Pastel Live – watch rooms, players and chat in real time.

目前為 2025-10-09 提交的版本,檢視 最新版本

// ==UserScript==
// @name             Pastel Live 2.0
// @namespace        https://github.com/GameSketchers/Pastel-Live
// @version          2.0
// @description      Gartic.io Pastel Live – watch rooms, players and chat in real time.
// @description:tr   Gartic.io Pastel Live – odalari, oyunculari ve sohbeti anlik takip et.
// @author           Qwyua
// @match            *://gartic.io/*
// @match            *://www.croxyproxy.com/*
// @match            *://*/__cpi.php?s=*
// @match            *://example.com/*
// @run-at           document-start
// @grant            GM_addStyle
// @grant            GM_setValue
// @grant            GM_getValue
// @grant            GM_addValueChangeListener
// @grant            GM_removeValueChangeListener
// @grant            GM_xmlhttpRequest
// @grant            unsafeWindow
// @connect          *
// @license          MIT
// ==/UserScript==

const W=unsafeWindow,B=W.__gmBus??=new EventTarget(),I=Symbol();Object.assign(W,{GM_scriptSendMessage:(c,...d)=>B.dispatchEvent(new CustomEvent(c,{detail:{from:I,data:d}})),GM_scriptOnMessage:(c,f)=>B.addEventListener(c,e=>e.detail.from!==I&&f?.(...e.detail.data))});
const {GM_scriptSendMessage, GM_scriptOnMessage}=W;
const baseHeaders={Accept:"*/*","Content-Type":"application/x-www-form-urlencoded","sec-ch-ua-mobile":"?0","sec-ch-ua-platform":"\"Windows\"","sec-fetch-dest":"document","sec-fetch-mode":"navigate","sec-fetch-site":"none","sec-fetch-user":"?1","upgrade-insecure-requests":"1"};
const [GM_onMessage,GM_sendMessage,getCookie,onBodyReady,observer,rand,GM_req]=[
    (k,c)=>GM_addValueChangeListener(k,(_,__,o)=>c(...o)),
    (k,...d)=>GM_setValue(k,d),
    c=>document.cookie.split("; ").find(e=>e.startsWith(c+"="))?.split("=")[1],
    cb=>document.body?cb():new MutationObserver((_,o)=>document.body&&(o.disconnect(),cb())).observe(document.documentElement,{childList:1}),
    (s,c)=>{const w=()=>{const e=document.querySelector(s);e&&(c(e),o.disconnect())};const o=new MutationObserver(w);document.body?o.observe(document.body,{childList:1,subtree:1}):new MutationObserver((_,m)=>{document.body&&(m.disconnect(),o.observe(document.body,{childList:1,subtree:1}))}).observe(document.documentElement,{childList:1})},
    _=>Math.floor(Math.random()*100)+1,
    q=>GM_xmlhttpRequest({...q,onerror:e=>console.error(e)})
];
document.URL.includes("/__cpi")&&window.self!==window.top&&(async()=>{try{GM_sendMessage('iframe-msg',`succes`,window.location.href)}catch(e){console.error("w",e)}})();
document.URL.includes("pr0xy")&&window.self!==window.top&&(window.name=window.location.search.split('=').pop())|observer('.fa.fa-arrow-right',btn=>btn.dispatchEvent(new MouseEvent("click",{bubbles:!0,button:0})));
document.URL.includes("/servers")&&window.self!==window.top&&observer('input[name=proxyServerId]',e=>{e.value=window.name;e.parentElement.submit()});
document.URL.includes("/requests?fso=")&&window.self!==window.top&&(console.log("wwww")|GM_sendMessage('iframe-msg', 'error'));
//document.URL.includes("")&&window.self!==window.top&&(async()=>{try{const[params,ip,token,reqNum,colors]=[new URL(location.href).searchParams,params.get("ip"),params.get("token"),params.get("req"),{"1":"red","2":"blue","3":"green","4":"orange","5":"purple"}];GM_scriptOnMessage(`req${reqNum}`,msg=>{console.log(`%cScript${reqNum} aldindi:%c${msg.slice(0,50)}`,`color:${colors[reqNum]||"black"};font-weight:bold`,"color:white;background:#222;padding:2px")})}catch(e){}})();
class GM_queue{#s=[];#t=[];#e=[];#i=0;#r=0;#h=!1;#o=!1;constructor({maxConcurrent:s=1,maxConcurrentDynamic:t=1,dynamicThreshold:e=0,retryCountPerItem:i=3,minProcessTime:r=200,maxProcessTime:h=800,retryDelay:o=150,waitForNextApproval:n=!1,onStart:a,onProcess:u,onProgress:m,onError:c,onErrorData:y,onPause:l,onResume:p,onClear:d,onEmpty:g,onFinish:P,onMaxError:w}={}){Object.assign(this,{maxConcurrent:s,maxConcurrentDynamic:t,dynamicThreshold:e,retryCountPerItem:i,minProcessTime:r,maxProcessTime:h,retryDelay:o,waitForNextApproval:n,onStart:a,onProcess:u,onProgress:m,onError:c,onErrorData:y,onPause:l,onResume:p,onClear:d,onEmpty:g,onFinish:P,onMaxError:w}),this.system={queue:this.#s,retryQueue:this.#t,processing:this.#e,done:[],errors:new Map,paused:this.#h,waitForNextApproval:this.waitForNextApproval,enqueue:this.enqueue.bind(this),pause:this.pause.bind(this),resume:this.resume.bind(this),clear:this.clear.bind(this),progress:this.progress.bind(this)}}enqueue(s){const t=s.id??crypto.randomUUID?.()??Math.random().toString(36).slice(2),e={data:s,id:t};this.#s.push(e),this.#r++,this.system.errors.set(t,0),this.onErrorData?.(this.system,s,t),this.#o||(this.#o=!0,this.onStart?.(this.system),this.#n())}async#n(){for(;this.#s.length||this.#t.length||this.#e.length;){if(this.#h){await this.#a();continue}const s=this.#r<this.dynamicThreshold?Math.min(this.maxConcurrentDynamic,this.maxConcurrent):this.maxConcurrent;for(;this.#e.length<s;){let t;if(this.#t.length)t=this.#t.shift();else{if(!this.#s.length)break;t=this.#s.shift()}const{data:e,id:i}=t;this.#e.push({data:e,id:i});const r=((this.#s.length+this.#t.length)/s).toFixed(1);this.onProcess?.(this.system,{qw:e,id:i},{eta:r,current:this.#i+1,total:this.#r});try{await this.#u(e),this.#i++,this.system.processing=this.#e,this.system.done.push({data:e,id:i});let s=!0;if(this.waitForNextApproval&&this.onProgress){const t=this.onProgress(this.system,(this.#i/this.#r*100).toFixed(0),{current:this.#i,total:this.#r,eta:r});s=t instanceof Promise?await t:t}else this.onProgress?.(this.system,(this.#i/this.#r*100).toFixed(0),{current:this.#i,total:this.#r,eta:r});if(!s){this.#s.unshift({data:e,id:i}),this.#e=this.#e.filter((s=>s.id!==i));break}}catch(s){const t=(this.system.errors.get(i)??0)+1;this.system.errors.set(i,t),this.onError?.(this.system,s,e,t),t<this.retryCountPerItem?(await this.#m(this.retryDelay),this.#t.push({data:e,id:i})):this.onMaxError?.(this.system,e,t,i)}finally{this.#e=this.#e.filter((s=>s.id!==i))}}this.#s.length||this.#t.length||this.#e.length||(this.onClear?.(this.system),this.onEmpty?.(this.system),this.onFinish?.(this.system,{current:this.#i,total:this.#r}),this.#c()),this.#e.length>=s&&await this.#m(10)}}pause(){this.#h=!0,this.system.paused=!0,this.onPause?.(this.system)}resume(){this.#h&&(this.#h=!1,this.system.paused=!1,this.onResume?.(this.system))}clear(){this.#s.length=0,this.#t.length=0,this.#e=[],this.system.queue=this.#s,this.system.retryQueue=this.#t,this.system.processing=this.#e,this.onClear?.(this.system)}progress(){return(this.#i/(this.#r||1)*100).toFixed(1)}async#u(s){const t=Math.floor(Math.random()*(this.maxProcessTime-this.minProcessTime)+this.minProcessTime);await this.#m(t)}async#m(s){return new Promise((t=>setTimeout(t,s)))}async#a(){for(;this.#h;)await this.#m(50)}#c(){this.#s=[],this.#t=[],this.#e=[],this.#i=0,this.#r=0,this.system.queue=this.#s,this.system.retryQueue=this.#t,this.system.processing=this.#e,this.system.done=[],this.system.errors=new Map,this.#o=!1,this.system.paused=!1}}
document.URL.includes("https://gartic.io/live") && (() => {
    GM_addStyle(`*{margin:0;padding:0;box-sizing:border-box}body{font-family:"Segoe UI",sans-serif;height:100vh;display:flex;flex-direction:column;background:linear-gradient(145deg,#1b1a2e,#161429 70%,#12101f);color:#eee;overflow:hidden}.PastelLive-mainTitle{font-size:2em;font-weight:700;text-align:center;padding:20px;background:linear-gradient(90deg,#c2a6f0,#8bbcd4);-webkit-background-clip:text;-webkit-text-fill-color:transparent;text-shadow:0 0 12px #221b3a,0 0 20px #2e224f}#PastelLive-startScreen {position: fixed;inset: 0;display: flex;flex-direction: column;justify-content: center;align-items: center;gap: 25px;background: linear-gradient(160deg, #0f0c29, #302b63, #24243e);color: #fff;z-index: 9999;font-family: "Segoe UI", sans-serif;animation: fadeIn 1s ease;user-select: none;}#PastelLive-startScreen h1 {font-size: 4.5em;color: #ff4e50;position: relative;display: inline-block;letter-spacing: 1px;}#PastelLive-startScreen h1 {font-size: 3.5em;background: linear-gradient(270deg, #fffb7d 20%, #ff4e50 40%, #f9d423 60%, #fffb7d 80%);background-size: 400% 100%;-webkit-background-clip: text;-webkit-text-fill-color: transparent;animation: shine 7s linear infinite;letter-spacing: 1px;}#PastelLive-version {margin-left:-17px;font-size: 0.20em;bottom: 0;right: 0;color: #ccc;text-shadow: none;}@keyframes shine {0% {background-position: 0% 0;}100% {background-position: 100% 0;}}.PastelLive-subtitle {font-size: 1.2em;color: #ccc;text-shadow: 0 0 6px #302b63;}#PastelLive-startScreen select {padding: 10px 20px;font-size: 1.1em;font-weight: 600;background: #1b1a2e;color: #fff;border: none;outline: none;box-shadow: inset 0 0 5px #ff4e50;transition: 0.2s;}#PastelLive-startScreen select:hover {box-shadow: inset 0 0 12px #f9d423;transform: scale(1.03);}.PastelLive-btn-row {display: flex;gap: 15px;}#PastelLive-startScreen button {padding: 12px 28px;font-size: 1.1em;font-weight: 700;background: linear-gradient(90deg, #ff4e50, #f9d423);color: #0f0c29;border: none;outline: none;cursor: pointer;transition: 0.25s;box-shadow: 0 0 8px #ff4e50, 0 0 12px #f9d423;}#PastelLive-startScreen button:hover {transform: scale(1.05);box-shadow: 0 0 15px #ff4e50, 0 0 20px #f9d423;}#PastelLive-startBtn:disabled {background: #3a3a4f;color: #999;cursor: not-allowed;box-shadow: inset 0 0 8px #000;}#PastelLive-proxyBtn {background: #1b1a2e;color: #f9d423;box-shadow: 0 0 8px #f9d423;transition: 0.25s;cursor: pointer;opacity: 0.9;}#PastelLive-proxyBtn:hover {transform: scale(1.05);box-shadow: 0 0 15px #f9d423, 0 0 20px #ff4e50;}#PastelLive-proxyBtn:disabled {background: #3a3a4f;color: #999;cursor: not-allowed;box-shadow: inset 0 0 8px #000;pointer-events: none;opacity: 0.7;}@keyframes fadeIn {from {opacity:0;}to {opacity:1;}}main.PastelLive-main{flex:1;display:none;grid-template-columns:2fr 1fr;gap:20px;padding:15px;overflow:hidden;opacity:0;animation:fadeIn 0.8s forwards}.PastelLive-left{display:flex;flex-direction:column;gap:12px;overflow:hidden}.PastelLive-filters{display:flex;gap:10px;align-items:center;background:#2a2a3e;padding:10px;border-radius:25px;box-shadow:0 0 8px #8bbcd4;flex-wrap:wrap;justify-content:space-between;opacity:0;animation:fadeIn 0.8s 0.2s forwards}.PastelLive-filters input{flex:2;padding:10px 14px;border-radius:20px;border:none;background:#212133;color:#eee;box-shadow:inset 0 0 6px #8bbcd4}.PastelLive-filters select{flex:1;padding:10px 14px;border-radius:20px;border:none;background:#212133;color:#eee;box-shadow:inset 0 0 6px #8bbcd4}#PastelLive-stats{display:flex;gap:10px;flex-direction:column;color:#c8b6ff;font-size:0.85em}.PastelLive-players{flex:1;overflow-y:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:15px;padding-right:5px;opacity:0;animation:fadeIn 0.8s 0.4s forwards}.PastelLive-card{background:#212133;border-radius:15px;padding:15px;text-align:center;cursor:pointer;transition:.25s;box-shadow:0 3px 10px #0007;display:flex;flex-direction:column;align-items:center}.PastelLive-card:hover{transform:translateY(-4px) scale(1.03);box-shadow:0 0 15px #c2a6f0,0 0 22px #8bbcd4}.PastelLive-avatar{width:60px;height:60px;border-radius:50%;margin-bottom:10px;background:linear-gradient(135deg,#c2a6f0,#8bbcd4);display:flex;align-items:center;justify-content:center;font-size:1.4em;color:#fff;text-shadow:0 0 3px #000}.PastelLive-name{font-size:1.05em;font-weight:600;margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.PastelLive-status{font-size:.85em}.PastelLive-online{color:#7fffd4}.PastelLive-offline{color:#ff9aa2}.PastelLive-chat{background:#1f1f30;border-radius:15px;display:flex;flex-direction:column;overflow:hidden;box-shadow:0 0 12px #000a;opacity:0;animation:fadeIn 0.8s 0.6s forwards}.PastelLive-chatHeader{background:linear-gradient(90deg, #5510c7, #210d65);padding:10px;color:#000;font-weight:600;font-size:1.1em;display:flex;justify-content:space-between;align-items:center;border-radius:12px 12px 0 0;box-shadow:0 0 10px #000a}.PastelLive-chatButtons{display:flex;gap:5px}.PastelLive-chatButtons button{padding:5px 10px;border:none;border-radius:15px;background:#2a2a3e;color:#fff;cursor:pointer;transition:.2s;box-shadow:0 0 6px #8bbcd4}.PastelLive-chatButtons button:hover{transform:scale(1.05);box-shadow:0 0 10px #c2a6f0}.PastelLive-searchMsg{padding:8px;background:#2a2a3e}.PastelLive-searchMsg input{width:100%;padding:10px;border-radius:20px;border:none;background:#212133;color:#eee;box-shadow:inset 0 0 6px #8bbcd4}.PastelLive-msgs{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:10px}.PastelLive-msg{background:#212133;border-radius:12px;padding:8px 12px;max-width:100%;box-shadow:0 0 5px #0007}.PastelLive-msg b{color:#c8b6ff;margin-right:6px}.PastelLive-players::-webkit-scrollbar,.PastelLive-msgs::-webkit-scrollbar{width:10px}.PastelLive-players::-webkit-scrollbar-track,.PastelLive-msgs::-webkit-scrollbar-track{background:#1f1f30;border-radius:10px}.PastelLive-players::-webkit-scrollbar-thumb,.PastelLive-msgs::-webkit-scrollbar-thumb{background:linear-gradient(180deg,#8bbcd4,#c2a6f0);border-radius:10px}.PastelLive-players::-webkit-scrollbar-thumb:hover,.PastelLive-msgs::-webkit-scrollbar-thumb:hover{background:linear-gradient(180deg,#c2a6f0,#8bbcd4)}@media(max-width:900px){main.PastelLive-main,#PastelLive-app.PastelLive-main {grid-template-columns:1fr;grid-template-rows:1fr 1fr;}}@media(max-width:500px){.PastelLive-players,#PastelLive-players {grid-template-columns:repeat(auto-fill,minmax(140px,1fr));}.PastelLive-avatar{width:55px;height:55px;font-size:1.2em;}}.PastelLive-credit{position:absolute;bottom:10px;left:10px;font-size:15px;color:#bbb;font-family:"Segoe UI",sans-serif;opacity:0.8}.PastelLive-credit a{color:#6cf;text-decoration:none;font-weight:600}.PastelLive-credit a:hover{text-decoration:underline}.PastelLive-credit .heart{color:#e25555;margin:0 2px}`)
    const overlay = Object.assign(document.createElement('div'), {id:'PastelLiveOverlay', style:'position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:999;background:#161429;overflow:hidden;display:flex;flex-direction:column;font-family:"Segoe UI",sans-serif;color:#eee;'});
    overlay.innerHTML = `
          <div class="PastelLive-mainTitle">Pastel Live</div>
        <div id="PastelLive-startScreen">
        <h1>Pastel Live
            <span id="PastelLive-version">v2.0</span>
        </h1>
         <p class="PastelLive-subtitle">Select Language & Start</p>
<select id="PastelLive-lang">
  <option value="8">Türkçe</option>
  <option value="all">All Languages</option>
  <option value="2">English</option>
  <option value="1">Português</option>
  <option value="45">Bahasa Indonesia</option>
  <option value="7">Русский</option>
  <option value="3">Español</option>
  <option value="19">العربية</option>
  <option value="23">Azərbaycanca</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="13">Tiếng Việt</option>
  <option value="21">български език</option>
  <option value="40">עברית</option>
  <option value="34">فارسی</option>
  <option value="12">ภาษาไทย</option>
  <option value="16">中文 (简化字)</option>
  <option value="9">中文 (臺灣)</option>
  <option value="17">中文 (香港)</option>
  <option value="15">日本語</option>
  <option value="20">한국어</option>
</select>

         <div class="PastelLive-btn-row">
           <button id="PastelLive-startBtn">Baslat</button>
           <button id="PastelLive-proxyBtn">Get Proxy (0)</button>
        </div>
  <div class="PastelLive-credit">
    GameSketchers • by <a href="https://github.com/GameSketchers/Pastel-Live" target="_blank">Qwyua</a>  <span class="heart">♥</span> with love
  </div>
      </div>
        <main id="PastelLive-app" class="PastelLive-main" style="display:none;flex:1;grid-template-columns:2fr 1fr;gap:20px;padding:15px;overflow:hidden;">
            <div class="PastelLive-left">
                <div class="PastelLive-filters">
                    <input id="PastelLive-search" placeholder="oyuncu ara">
                    <input id="PastelLive-roomCode" placeholder="oda kodu">
                    <div id="PastelLive-stats">
                        <span id="PastelLive-activePlayers">Aktif Oyuncular: 0</span>
                        <span id="PastelLive-activeRooms">Aktif Odalar: 0</span>
                    </div>
                </div>
                <div class="PastelLive-players" id="PastelLive-players"></div>
            </div>
            <div class="PastelLive-chat">
                <div class="PastelLive-chatHeader">Chat
                    <div class="PastelLive-chatButtons">
                        <button id="PastelLive-saveChat">Kaydet</button>
                        <button id="PastelLive-resetChat">Reset</button>
                    </div>
                </div>
                <div class="PastelLive-searchMsg"><input id="PastelLive-msgSearch" placeholder="mesaj ara"></div>
                <div class="PastelLive-msgs" id="PastelLive-msgs">
                </div>
            </div>
        </main>
    `;
    document.documentElement.prepend(overlay);

    class PastelLive {
        proxies = GM_getValue("PastelLive-Proxies");
        servers = {"server07":"c","server06":"Y","server05":"U","server04":"Q","server03":"M","server02":"I","server01":"E"};
       static PlayerSt =class{
        map=new Map();
        constructor(list=[]){list.forEach(p => this.map.set(String(p.id), p.name))}
        add = p => this.map.set(String(p.id), p.name);
        getName = id => this.map.get(String(id)) ?? null;
        remove = id => this.map.delete(String(id));
        update = (id, name) => this.map.has(String(id))&&this.map.set(String(id),name);
        }
        odalar=0;
        oyuncular=0;
        plst = new PastelLive.PlayerSt([]);
        constructor(overlay) {
            this.overlay = overlay;
            this.playersContainer = overlay.querySelector("#PastelLive-players");
            this.messagesContainer = overlay.querySelector("#PastelLive-msgs");
            this.startScreen = overlay.querySelector("#PastelLive-startScreen");
            this.app = overlay.querySelector("#PastelLive-app");
            this.activePlayersSpan = overlay.querySelector("#PastelLive-activePlayers");
            this.activeRoomsSpan = overlay.querySelector("#PastelLive-activeRooms");
            this.startButton = overlay.querySelector("#PastelLive-startBtn");
            this.proxyButton = overlay.querySelector("#PastelLive-proxyBtn")
            this.activePlayers = overlay.querySelector("#PastelLive-activePlayers")
            this.activeRooms = overlay.querySelector("#PastelLive-activeRooms")
            this.searchInput = overlay.querySelector("#PastelLive-search");
            this.roomInput = overlay.querySelector("#PastelLive-roomCode");
            this.msgSearchInput = overlay.querySelector("#PastelLive-msgSearch");
            this.initEvents();
            if (this.proxies === undefined){this.proxies=[];GM_setValue("PastelLive-Proxies", this.proxies)}
            if (Array.isArray(this.proxies)&&this.proxies.length===0){
                this.startButton.disabled=!0;
                this.proxies=[];
                GM_setValue("PastelLive-Proxies",this.proxies);
            }
            Array.isArray(this.proxies)&&this.proxies.length&&(()=>{
                const ws = new WebSocket(`wss://${this.proxies[0].ip}/__cpw.php?u=d3NzOi8vc2VydmVyMDYuZ2FydGljLmlvL3NvY2tldC5pby8/RUlPPTMmdHJhbnNwb3J0PXdlYnNvY2tldA==&o=aHR0cHM6Ly9nYXJ0aWMuaW8=`);
                ws.onopen=()=>{ws.close()};
                ws.onerror=()=>{GM_setValue("PastelLive-Proxies",this.proxies=[]);location.reload()};
            })();
            this.proxyButton.textContent = `Get Proxy (${this.proxies?.length||0})`;

        }

        checkDeepProxy(yua){const{ip,cookie:cpc}=yua.proxy,{iframeMode,room}=yua;
                            return new Promise((ok, fail)=>{
                            GM_req({method:"POST",url:`https://${ip}/?__cpo=aHR0cHM6Ly9wcm94eW9yYi5jb20`,headers:{...baseHeaders,Cookie:`__cpc=${cpc}`},onload:(r1)=>{
                            const token = r1.responseText.match(/\\"initialToken\\":\\"([^\\]+)\\"/)?.[1];
                            if(!token) return fail("Token bulunamadi");
                            GM_req({method: "POST",url:`https://${ip}/api/servers?__cpo=aHR0cHM6Ly9wcm94eW9yYi5jb20`,headers:{ ...baseHeaders,Cookie:`__cpc=${cpc}`,"x-stats-id":token},
                            data:new URLSearchParams({input:`https://gartic.io/server?check=1&v3=1&room=${room}`}).toString(),
                            onloadend:(r2)=>{const u=r2.responseText.match(/content="([^"]+)"/)?.[1];
                            if(!u)return fail("⚠️ URL bulunamadi");
                            GM_req({method:"POST",url:u,headers:{...baseHeaders,"x-stats-id":token},onloadend:(r3)=>{
                            const [url,poss,host]=(([u,p])=>[u,p,u.replace(/^https?:\/\//,"").split(/[\/:?]/)[0],])(r3.finalUrl.split("&__poss=")),
                            cookieHeader=`__poss@${host}=${poss};__cpc=${cpc}`,
                            fullURL=`https://${ip}/server?check=1&v3=1&room=${room}&__pot=aHR0cHM6Ly9nYXJ0aWMuaW8&__cpo=${btoa(`https://${host}`)}`;
                            GM_req({method:"GET",url:fullURL,headers:{...baseHeaders,Cookie:cookieHeader},
                            onloadend:(r4)=>{const finalURL=r4.responseText.match(/this\.permalink\s*=\s*this\.URI\(['"]([^'"]+)['"]\)/)?.[1];
                            if(!finalURL){ok({info:{ip,cpc,room},response:r4.responseText});return}
                            GM_req({method:"POST",url:finalURL,headers:{...baseHeaders,Cookie:cookieHeader,"Content-Type":"application/json"},
                            onloadend:(r5)=>{if(r5.responseText.includes("gartic.io:443?c")){ok({info:{ip,cpc,room},response:r4.responseText});return}
                            else{fail({message:"❌ Tüm asamalar tamamlanamadi",ip,room})}
                            }});}});}});}});}});});
        }

        initEvents() {
            this.searchInput.addEventListener("input",()=>this.filterPlayers());
            this.roomInput.addEventListener("input",()=>this.filterPlayers());
            this.msgSearchInput.addEventListener("input",()=>this.filterChat());
            this.startButton.addEventListener("click", () => {
            const lang = document.querySelector("#PastelLive-lang").value;
            if (lang === "all" && this.proxies.length < 50) {
            alert("To use this feature, you need at least 50 proxies.");
            return}
            this.startScreen.style.display = "none";
            this.app.style.display = "grid";
            this.playerSearchGO(lang);
             });
            this.proxyButton.addEventListener('click',()=>{
                this.startButton.disabled=!0;
                this.proxyButton.disabled=!0;
                this.addNewProxy()
            });

        }

        filterChat(){
            [...this.messagesContainer.children].forEach(msg => {
                msg.style.display = msg.textContent.toLowerCase().includes(this.msgSearchInput.value.toLowerCase()) ? "block" : "none";
            });

        }

        async addNewProxy() {
            try {
                const data = await GM_getValue('PastelLive');
                this.proxies=GM_getValue("PastelLive-Proxies");
                const list=data?.ProxyList??[];
                if (!list.length) return console.log('!asd');
                const existing=new Set(this.proxies?.map(p=>p.ip)??[]);
                console.log(existing)
                const limit=existing.size?15:10;
                const newProxies=list.map(x=>x.ip).filter(ip =>!existing.has(ip)).slice(0,limit);
                if (!newProxies.length) return console.log('!!asd');
                const targets=list.filter(x=>newProxies.includes(x.ip)).slice(0,15);
                console.log(targets)
                targets.forEach(x=>document.body.append(Object.assign(document.createElement`iframe`,{id:'proxy-iframe-'+x.id,style:'display:none!important;width:0;height:0;opacity:0;pointer-events:none;position:absolute;top:0;left:0;z-index:-9999',src:`https://www.croxyproxy.com/?pr0xy=true&proxyid=${x.id}`,sandbox:'allow-scripts allow-same-origin allow-forms allow-top-navigation'})));
                const proxiesWithCookies=await new Promise(r=>{
                    const c=[],t=setTimeout(()=>r(c),30e3),h=async(_,u)=>{try{
                        const cookie = await new Promise(s=>{GM_req({method:"GET", url:u, headers:baseHeaders, onload:r=>s(r.responseHeaders.match(/set-cookie:\s*__cpc=([^;\r\n]+)/i)?.[1]), onerror:e=>s(null)})});
                        c.push({ip:new URL(u).hostname,cookie});if(c.length>=targets.length){clearTimeout(t);GM_removeValueChangeListener?.('iframe-msg',h);r(c)}}catch{}};GM_onMessage('iframe-msg',h)})
                this.proxies??=[];
                this.proxies.push(...proxiesWithCookies);
                GM_setValue("PastelLive-Proxies",this.proxies);
                this.proxyButton.textContent=`Get Proxy (${this.proxies?.length||0})`;
                this.proxyButton.disabled=!1;
                this.startButton.disabled=!1;
                document.querySelectorAll('iframe')?.forEach(f=>f.remove());
            } catch (err) {
                console.error(err);
            }
        }

      addMessage(author, text) {
            const msg = document.createElement("div");
            msg.className = "PastelLive-msg";
            msg.innerHTML = `<b>${author}:</b> ${text}`;
            this.messagesContainer.appendChild(msg);
            this.filterChat()
        }
        filterPlayers() {
            const q = this.searchInput.value.toLowerCase();
            const r = this.roomInput.value.toLowerCase();
            [...this.playersContainer.children].forEach(card => {
                const name = card.querySelector(".PastelLive-name").textContent.toLowerCase();
                const room = card.querySelector(".PastelLive-status").textContent.toLowerCase();
                card.style.display = (name.includes(q) && room.includes(r)) ? "flex" : "none";
            });
            const visible = [...this.playersContainer.children].filter(c => c.style.display !== "none");
            this.activePlayersSpan.textContent = `Aktif Oyuncular: ${visible.length}`;
            this.activeRoomsSpan.textContent = `Aktif Odalar: ${new Set(visible.map(c => c.querySelector(".PastelLive-status").textContent)).size}`;
        }
        startLiveRoomAction(inf,servertext){
              const server = new URL(servertext).hostname.split(".")[0] || (console.log("❌ Hatalı proxy, spam riski!"), null);
              if (!server) return;
              const scode = this.servers[server];
              const roomid = inf.room.substring(2)
              console.log("Server bulundu:", server);
                const websocket = new WebSocket(`wss://${inf.ip}/__cpw.php?u=d3NzOi8vc2VydmVyMD${scode}uZ2FydGljLmlvL3NvY2tldC5pby8/RUlPPTMmdHJhbnNwb3J0PXdlYnNvY2tldA==&o=aHR0cHM6Ly9nYXJ0aWMuaW8=`);
                        websocket.onopen = () => {
                            websocket.send(`42[12,{"v":20000,"sala":"${roomid}"}]`);
                            websocket.send(`42[46,0]`);
                            const ping = () => {
                                if (websocket.readyState === WebSocket.OPEN) {
                                    websocket.send("2");
                                    setTimeout(ping, 7000);
                                }
                            };
                            ping();
                        };

                        websocket.onmessage = e => {
                            try {
                                if (!e.data.startsWith("42")) return;
                                const data = JSON.parse(e.data.slice(2));
                                if (data[0] === "5") {
                                    for (const player of data[5]) {
                                        this.plst.add({id:player.id,name:player.nick})
                                        this.addPlayer(
                                            player.foto ?? `https://gartic.io/static/images/avatar/svg/${player.avatar}.svg`,
                                            player.nick,
                                            inf.room
                                        );
                                        this.activePlayers.innerText = `oyuncular: ${++this.oyuncular}`;
                                    }
                                    this.activeRooms.innerText = `odalar: ${++this.odalar}`;
                                }
                                data[0]==="6"&&data[1]==6&&websocket.close()
                                data[0]==="11"&&this.addMessage(this.plst.getName(data[1]),data[2],inf.room)
                            } catch {}
                        };
                        websocket.onerror=e=>{};
        }

        addPlayer(avatar,name, room) {
            const card = Object.assign(document.createElement("div"),{className:"PastelLive-card"});
            card.append(
                Object.assign(document.createElement("img"),{className:"PastelLive-avatar",src:avatar}),
                Object.assign(document.createElement("div"),{className:"PastelLive-name",textContent:name}),
                Object.assign(document.createElement("div"),{className:"PastelLive-status",textContent:`Oda Kodu: ${room}`})
            );
            this.playersContainer.appendChild(card);
            this.filterPlayers();
        }


         logRoomServer(d,s){console.log("%c🌟 Live Room Started! 🌟\n\nIP: %c"+d.ip+"\nCPC: %c"+d.cpc+"\nRoom: %c"+d.room+"\nServer: %c"+s,"background: linear-gradient(90deg, #ff6ec4, #7873f5); color: white; font-size: 20px; font-weight: bold; padding: 10px 20px; border-radius: 10px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);","color: #ff6ec4; font-weight:bold; font-size:16px;","color: #7873f5; font-weight:bold; font-size:16px;","color: #00e676; font-weight:bold; font-size:16px;","color: #ffd700; font-weight:bold; font-size:16px;")}

         miniNotificationPopup=(()=>{let t,e;return a=>{t||(t=document.createElement("div"),Object.assign(t.style,{position:"fixed",top:"20px",right:"20px",background:"linear-gradient(135deg, #ff7e5f, #feb47b)",color:"#fff",padding:"15px 25px",borderRadius:"15px",boxShadow:"0 8px 25px rgba(0,0,0,0.4)",fontFamily:"Arial, sans-serif",fontSize:"16px",fontWeight:"bold",opacity:"0",transform:"translateX(50px)",transition:"opacity 0.5s ease, transform 0.5s ease",maxWidth:"350px",pointerEvents:"none",zIndex:9999}),document.body.appendChild(t)),t.textContent=a,t.style.opacity="1",t.style.transform="translateX(0)",e&&clearTimeout(e),e=setTimeout((()=>{t.style.opacity="0",t.style.transform="translateX(50px)"}),2500)}})();

        async playerSearchGO(languagecode){
            try {
                console.log("calisiyom abi")
                const langOrder=[23,1,8,2,9,7,45,13,11,16,19];
                const allRooms=[];
                for(const lang of"all"===languagecode?langOrder:[languagecode]){let a=await new Promise((a,e)=>{GM_xmlhttpRequest({method:"GET",url:`https://gartic.io/req/list?search=&language[]=${lang}`,onload(t){try{a(JSON.parse(t.responseText))}catch(r){e(r)}},onerror:a=>e(a)})});allRooms.push(...a.filter(({quant:a})=>a>0)),await new Promise(a=>setTimeout(a,1e3))}
                const proxies=await GM_getValue("PastelLive-Proxies");
                const roomCodes=allRooms.map(({code:o})=>o);
                const xmlplugins=["yua"];
                const proxyToRooms=roomCodes.map((o,e)=>({room:o,proxy:proxies[e%proxies.length],iframeMode:xmlplugins[e%xmlplugins.length]}));
                console.log(proxyToRooms)
                this.queue = new GM_queue({
                    onStart:system=>console.log("▶️ Kuyruk baslatildi."),
                    onProcess:(system, im, stats)=>{
                      //console.log(im)
                     this.checkDeepProxy(im.qw.yua)
                     .then(({ info, response }) => {
                     this.logRoomServer(info, response);
                     this.startLiveRoomAction(info, response);
                     })
                     .catch(error => {
                      console.error("Olumsuz:", error);//burayi halledicem sonraki surum
                     });

                    },
                   onProgress:(system,percent,stats)=>this.miniNotificationPopup(`📊 ${percent}% (${stats.current}/${stats.total})`)
                });

                for (const proxyToRoom of proxyToRooms){
                    const {ip,cookie:cpc}=proxyToRoom.proxy;
                    const {iframeMode,room}=proxyToRoom;
                    if("yua"!==iframeMode){let e=document.createElement("iframe");e.src="aHR0cHM6Ly86RC8/cmVxPSZpcD0mdG9rZW49",Object.assign(e.style,{display:"block",position:"fixed",bottom:"10px",right:"10px",width:"400px",height:"300px",zIndex:9999999999}),document.body.appendChild(e)}
                    else this.queue.enqueue({yua:proxyToRoom});
                }



            }catch(e){console.log(e)}
        }


        async initProxies() {
            try {
                const existing = await GM_getValue('PastelLive');
                if (existing) return console.log('PastelLive running...');
                const json = await (await fetch('https://raw.githubusercontent.com/Qwyua/ProxyModule/main/src/ProxyModuleList.json')).json();
                const newProxies = json?.proxyList?.filter(p=>p.active&&!p.ip.startsWith('51.'))??[];
                const data = {ProxyList:newProxies,runProxy:!0};
                await GM_setValue('PastelLive', data);
                console.log('PastelLive Started.', data);
            } catch (e) {
                console.error('PastelLive error!', e);
            }
        }
    }

    (async () => {
        const overlay = document.querySelector('#PastelLiveOverlay');
        const live = new PastelLive(overlay);
        await live.initProxies();
    })();


})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址