// ==UserScript==
// @name Pastel Live 2.0
// @namespace https://github.com/GameSketchers/Pastel-Live
// @version 2.0.2
// @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=*
// @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==
// ==>>>> https://gartic.io/pastel <<<<== //
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,randomColor]=[
(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)}),
w=>`rgb(${Math.floor(Math.random()*256)},${Math.floor(Math.random()*256)},${Math.floor(Math.random()*256)},0.20)`
];
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","/pastel"].some(p=>document.URL.includes(p))&&(()=>{
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{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-container {display:flex;flex-direction:column;align-items:center;gap:10px}.PastelLive-btn-row{display:flex;justify-content:center;gap:10px}#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-btn-row button:disabled{background:#3a3a4f !important;color:#999 !important;cursor:not-allowed !important;box-shadow:inset 0 0 8px #000 !important}#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}.PastelLive2-search-container{max-width:1200px;width:100%;padding:15px 20px;border-radius:15px;box-shadow:0 10px 30px rgba(0,0,0,0.3);align-items:center;margin:0 auto;margin-bottom:20px;box-sizing:border-box}.PastelLive2-search-input-container{display:flex;gap:12px;align-items:center;justify-content:center;margin-bottom:15px}.PastelLive2-search-input{flex:1;max-width:500px;padding:12px 16px;border:2px solid rgba(255,255,255,0.1);border-radius:10px;background:rgba(26,32,44,0.8);color:#e2e8f0;font-size:16px}.PastelLive2-search-input:focus{outline:none;border-color:#4299e1;box-shadow:0 0 0 3px rgba(66,153,225,0.3)}.PastelLive2-player-list{width:100%;height:70vh;padding:0 25px 25px 25px;box-sizing:border-box;display:grid;grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));grid-gap:20px;overflow-y:auto;overflow-x:hidden}.PastelLive2-player-list::-webkit-scrollbar{width:8px}.PastelLive2-player-list::-webkit-scrollbar-track{border-radius:4px}.PastelLive2-player-list::-webkit-scrollbar-thumb{border-radius:4px}.PastelLive2-player-card{height:80px;position:relative;background-color:#fff;border-radius:5px;padding:10px;box-shadow:0 2px 4px rgba(0,0,0,0.1);display:flex;align-items:center;cursor:pointer;transition:transform 0.3s ease}.PastelLive2-player-card:hover{transform:translateY(-3px);box-shadow:0 8px 20px rgba(0,0,0,0.4);border-color:#4299e1}.PastelLive2-player-avatar{width:60px;height:60px;border-radius:50%;margin-right:10px}.PastelLive2-player-info{flex:1}.PastelLive2-player-name{font-weight:bold;font-size:16px;color:#e0e0e0;margin-bottom:5px;text-shadow:1px 1px 2px rgba(0,0,0,0.6)}.PastelLive2-player-id{font-size:14px;color:#888;margin-bottom:5px}.PastelLive2-player-status{font-size:14px;color:#888}.PastelLive2-win {position:absolute;left:0;bottom:0;width:36px;height:36px;background-image:url(https://gartic.io/static/images/new/trofeu.svg);background-size:contain;background-repeat:no-repeat;background-position:center;display:flex;align-items:center;justify-content:center}.PastelLive2-win span{display:inline-block;transform:translateY(-4px);font-family:"NunitoBlack";font-size:12px;color:#043172}.PastelLive2-search-info{display:flex;justify-content:center;gap:20px;margin-top:15px;flex-wrap:wrap}.PastelLive2-search-info h5{margin:0;padding:6px 12px;background:rgba(45,55,72,0.6);border-radius:6px;color:#a0aec0;font-size:12px;border:1px solid rgba(255,255,255,0.1)}`)
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.2</span></h1>
<p class="PastelLive-subtitle">Select Language & Start</p>
<select id="PastelLive-lang">
<option value="all">All Languages</option>
<option value="2">English</option>
<option value="8">Türkçe</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-container">
<button id="PastelLive-proxyBtn">Get Proxy (0)</button>
<div class="PastelLive-btn-row">
<button id="PastelLive-liveBtn">Live</button>
<button id="PastelLive-whowhereBtn">Who Where</button>
</div>
</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>
<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="PastelLive2-search-container">
<div class="PastelLive2-search-input-container">
<input type="text" class="PastelLive2-search-input" placeholder="Oyuncu arayın">
</div>
<div class="PastelLive2-search-info">
<h5 class="PastelLive2-players-log">oyuncu: 0</h5>
<h5 class="PastelLive2-rooms-log">odalar: 0</h5>
<h5 class="PastelLive2-searchspeed-log">arama hızı: </h5>
</div>
</div>
<div class="PastelLive2-player-list"></div>
</main>
`;
document.documentElement.prepend(overlay);
class PastelLive {
CURRENT_VERSION = "2.0.2"
proxies=GM_getValue("PastelLive-Proxies");
servers={"server07":"c","server06":"Y","server05":"U","server04":"Q","server03":"M","server02":"I","server01":"E"};
proxylist=["198.23.160.245","217.154.250.99","38.135.25.236","104.223.85.164","45.136.30.85","205.185.122.126","38.135.25.235"]
static ProxyRotator=class{constructor(proxyList=[]){if(!Array.isArray(proxyList)||proxyList.length===0){throw new Error("Proxy listesi boş olamaz.")};this.proxyList=proxyList;this.index=0}nextProxy(){const proxy=this.proxyList[this.index];this.index=(this.index+1)%this.proxyList.length;return proxy}}
static PlayerSt=class{
map=new Map();
constructor(list=[]){list.forEach(p=>this.map.set(String(p.id),p.name))}
add=q=>this.map.set(String(q.id),q.name);
getName=w=>this.map.get(String(w))??null;
remove=y=>this.map.delete(String(y));
update=(u,a)=>this.map.has(String(u))&&this.map.set(String(u),a);
}
odalar=0;
oyuncular=0;
whmod=!1;
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.liveTitle = overlay.querySelector(".PastelLive-mainTitle")
this.playerslog2 = overlay.querySelector(".PastelLive2-players-log")
this.roomslog2 = overlay.querySelector(".PastelLive2-rooms-log")
this.searchspeedlog2 = overlay.querySelector(".PastelLive2-searchspeed-log")
this.app = overlay.querySelector("#PastelLive-app");
this.app2 = overlay.querySelector("#PastelLive-app:nth-of-type(2)");
this.activePlayersSpan = overlay.querySelector("#PastelLive-activePlayers");
this.activeRoomsSpan = overlay.querySelector("#PastelLive-activeRooms");
this.liveButton = overlay.querySelector("#PastelLive-liveBtn");
this.whowhereButton = overlay.querySelector("#PastelLive-whowhereBtn");
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.langSelect = overlay.querySelector("#PastelLive-lang")
this.langSelect.addEventListener("change",()=>{GM_setValue("PastelLive-lang",this.langSelect.value)});
this.initEvents();
this.proxyRotator = new PastelLive.ProxyRotator(this.proxylist);
GM_getValue("version")!==this.CURRENT_VERSION&&(GM_setValue("version",this.CURRENT_VERSION),GM_setValue("PastelLive",{}),GM_setValue("PastelLive-Proxies",[]),GM_setValue("iframe-msg",[]),location.reload());
if (this.proxies === undefined){this.proxies=[];GM_setValue("PastelLive-Proxies", this.proxies)}
if (Array.isArray(this.proxies)&&this.proxies.length===0){
this.liveButton.disabled=!0;
this.whowhereButton.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,poss}=yua.proxy,{iframeMode,room}=yua,host=this.proxyRotator.nextProxy();
return new Promise((ok, fail)=>{const hdr=`__poss@${host}=${poss};__cpc=${cpc}`,
yurl=`https://${ip}/server?check=1&v3=1&room=${room}&__pot=aHR0cHM6Ly9nYXJ0aWMuaW8&__cpo=${btoa(`https://${host}`)}`;
GM_req({method:"GET",url:yurl,headers:{...baseHeaders,Cookie:hdr},
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:hdr,"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({info:{ip,cpc,room},response:null})}
}});}});});
}
initEvents(){
this.searchInput.addEventListener("input",()=>this.filterPlayers());
this.roomInput.addEventListener("input",()=>this.filterPlayers());
this.msgSearchInput.addEventListener("input",()=>this.filterChat());
this.liveButton.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.whowhereButton.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.whmod=!0;
this.playerSearchGO(lang)
this.startScreen.style.display = "none";
this.liveTitle.style.display = "none"
this.searchspeedlog2.innerText = `arama hızı: x${this.proxies.length}`
this.app2.style.display = "block";
});
this.proxyButton.addEventListener('click',()=>{
this.liveButton.disabled=!0;
this.proxyButton.disabled=!0;
this.whowhereButton.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));
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(resolve=>{
const c=[],t=setTimeout(()=>resolve(c),30e3);
const h=(_,u)=>{try{const ip=new URL(u).hostname;
GM_req({method:"GET",url:u,headers:baseHeaders,
onload:r1=>{const cpc=r1.responseHeaders.match(/set-cookie:\s*__cpc=([^;\r\n]+)/i)?.[1];
if(!cpc) return;
GM_req({method:"POST",url:`https://${ip}/?__cpo=aHR0cHM6Ly9wcm94eW9yYi5jb20`,headers:{...baseHeaders,Cookie:`__cpc=${cpc}`},
onload:r2=>{const poss=r2.responseText.match(/\\"initialToken\\":\\"([^\\]+)\\"/)?.[1];
if(!poss) return;
c.push({ip,cookie:`${cpc};`,poss:`${poss}`});
if(c.length>=targets.length){clearTimeout(t);GM_removeValueChangeListener?.('iframe-msg',h);resolve(c)}
}});}});}catch(e){console.error("proxy handler error", e)}};
GM_onMessage('iframe-msg',h)});
this.proxies.push(...proxiesWithCookies);
GM_setValue("PastelLive-Proxies",this.proxies);
this.proxyButton.textContent=`Get Proxy (${this.proxies.length})`;
this.proxyButton.disabled=!9;
this.liveButton.disabled=!8;
this.whowhereButton.disabled=!7;
document.querySelectorAll('iframe')?.forEach(f=>f.remove());
console.log("✅ Added proxies:", proxiesWithCookies);
}catch(err){console.error(err)}
}
getSocialMedia=(url)=>{
const socialMedia=(url.match(/discordapp|redditmedia|googleusercontent|twimg\.com|gartic\.io|facebook|fbsbx\.com|userapi\.com/i)||[''])[0].toLowerCase();
const mediaMap={
"discordapp":"Discord",
"redditmedia":"Reddit",
"googleusercontent":"Google",
"twimg.com":"Twitter",
"facebook":"Facebook",
"fbsbx.com":"Facebook",
"userapi.com":"Vkontakte",
"gartic.io":"Gartic",
};
return mediaMap[socialMedia]||null;
};
handlePlayerData(data,code){
const cardColor = randomColor();
const playerList = this.overlay.querySelector(".PastelLive2-player-list");
const playersLog = this.overlay.querySelector(".PastelLive2-players-log");
const roomsLog = this.overlay.querySelector(".PastelLive2-rooms-log");
const fragment = document.createDocumentFragment();
data[5].forEach(player=>{
const foto = player.foto??"https://gartic.io/static/images/avatar/svg/"+player.avatar+".svg";
const card = Object.assign(document.createElement("div"),{
className: "PastelLive2-player-card",
innerHTML:'<img class="PastelLive2-player-avatar" src="'+foto+'">'+'<div class="PastelLive2-player-info">'+
'<div class="PastelLive2-player-name">'+player.nick+'</div>'+
'<a href="https://gartic.io/'+code+'" target="_blank" class="PastelLive2-player-id">#'+code+'</a>'+
'<div class="PastelLive2-player-status"><span class="PastelLive2-status">'+this.getSocialMedia(foto)+'</span></div>'+
'</div>'+
(player.vitorias?'<span class="PastelLive2-win"><span>'+player.vitorias+'</span></span>':'')
});
card.setAttribute("name", player.id);
card.style.backgroundColor = cardColor;
//card.addEventListener("click", () => this.createPopup(player, foto, data[4], data[5].length));
fragment.appendChild(card);
playersLog.innerText = `oyuncular: ${++this.oyuncular}`;
});
playerList.appendChild(fragment);
roomsLog.innerText = `odalar: ${++this.odalar}`;
}
addMessage(author,text,room){
const msg = document.createElement("div");
msg.className = "PastelLive-msg";
msg.innerHTML = `<b>${room}${author}:</b> ${text}`;
this.messagesContainer.appendChild(msg);
this.filterChat()
}
filterPlayers(){
const q = this.searchInput.value.toLowerCase(),
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,succ,proc=6){
let server=(()=>{try{return new URL(servertext).hostname.split(".")[0]}catch{return null}})()??`server0${proc}`;
const scode = this.servers[server];
const roomid = inf.room.substring(2)
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}"}]`);
!this.whmod&&websocket.send(`42[46,0]`);
const ping=()=>{
if(websocket.readyState===WebSocket.OPEN){
websocket.send("2");
setTimeout(ping,7e3);
}
};
!this.whmod&&ping();
};
websocket.onmessage=e=>{
try{
if (!e.data.startsWith("42")) return;
const data=JSON.parse(e.data.slice(2));
if(data[0]==="5"){inf.roomdetails=`(${data[4].tema.split(" ")[0]} ${data[4].codigo.slice(-3)}) ~ `;this.whmod?(()=>{websocket.close();this.handlePlayerData(data,inf.room)})():(()=>{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}`})()}
if(!servertext||data[1]==6){websocket.close();
if(!servertext&&this.whmod){console.error("asdsaddsa",proc);const nextProcMap={6:2,2:5,5:4,4:3,3:1,1:7},nextProc=nextProcMap[proc];
nextProc&&setTimeout(()=>this.startLiveRoomAction(inf,!7,succ,nextProc),200)}}
!this.whmod&&data[0]==="11"&&this.addMessage(this.plst.getName(data[1]),data[2],inf.roomdetails)
}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! 🌟\nIP: "+d.ip+"\nRoom: "+d.room+"\nServer: "+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)")}
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({
...(this.whmod&&{minProcessTime:100,maxProcessTime:200}),
onStart:system=>console.log("▶️ Kuyruk baslatildi."),
onProcess:(system, im, stats)=>{
this.checkDeepProxy(im.qw.yua)
.then(({info,response})=>{this.logRoomServer(info,response);this.startLiveRoomAction(info,response,true);})
.catch(({info,response})=>{this.startLiveRoomAction(info,!7,!6)});
},
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{
this.langSelect.value = await GM_getValue("PastelLive-lang", "all");
const existing = await GM_getValue('PastelLive');
if(existing&&(typeof existing!=="object"||Object.keys(existing).length>0))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();
})();
})();