您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Real online, allows canvas online
// ==UserScript== // @name Pixel sites real online // @namespace https://pixels.fun // @version 1.8 // @license MIT // @description Real online, allows canvas online // @author small bee // @match *://*.fun/* // @grant none // @run-at document-end // ==/UserScript== (function() { 'use strict'; let lastSum = 0; let textNode = null; let observer = null; async function updateOnlineCount() { try { const res = await fetch('/api/shards', { credentials: 'same-origin' }); if (!res.ok) return; const data = await res.json(); let sum = 0; data.forEach(item => { if (Array.isArray(item) && item[1]) { Object.entries(item[1]).forEach(([k, v]) => { if (k !== 'total' && typeof v === 'number') sum += v; }); } }); const span = document.querySelector('.onlinebox span[title="Total Online Users"]'); if (!span) return; if (!textNode) { textNode = Array.from(span.childNodes).find(n => n.nodeType === Node.TEXT_NODE); if (!textNode) { textNode = document.createTextNode(''); span.insertBefore(textNode, span.firstChild); } } lastSum = sum; textNode.textContent = lastSum; } catch (err) { console.error('updateOnlineCount error', err); } } function observeTextNode() { if (observer) observer.disconnect(); if (!textNode) return; observer = new MutationObserver(mutations => { const span = textNode.parentNode; if (span.getAttribute('title') !== 'Total Online Users') return; for (const m of mutations) { if (m.type === 'characterData' && m.target === textNode) { if (m.target.nodeValue !== String(lastSum)) { console.warn('Blocked external change to online count:', m.target.nodeValue); m.target.nodeValue = String(lastSum); } } } }); observer.observe(textNode, { characterData: true }); } async function showCanvasOnline() { const div = document.querySelector('.onlinebox'); if (!div) return; div.addEventListener('click', async () => { const span = div.querySelector('span[title="Total Online Users"]'); if (!span || span.querySelectorAll('svg').length < 2) return; const hash = window.location.hash; const match = /^#([a-z0-9])/i.exec(hash); if (!match) return; const letter = match[1]; try { const meRes = await fetch('/api/me', { credentials: 'same-origin' }); if (!meRes.ok) return; const me = await meRes.json(); const canvases = me.canvases || {}; let canvasId = null; for (const [id, info] of Object.entries(canvases)) { if (info.ident === letter) { canvasId = id; break; } } if (canvasId === null) return; const shardsRes = await fetch('/api/shards', { credentials: 'same-origin' }); if (!shardsRes.ok) return; const shards = await shardsRes.json(); let onlineCount = null; for (const item of shards) { if (Array.isArray(item) && item[1] && item[1][canvasId] != null) { onlineCount = item[1][canvasId]; break; } } if (onlineCount == null) return; span.setAttribute('title', 'Online Users on Canvas'); if (!textNode) { textNode = Array.from(span.childNodes).find(n => n.nodeType === Node.TEXT_NODE); if (!textNode) { textNode = document.createTextNode(''); span.insertBefore(textNode, span.firstChild); } } lastSum = onlineCount; textNode.textContent = lastSum; observeTextNode(); } catch (err) { console.error('showCanvasOnline error', err); } }); } updateOnlineCount().then(observeTextNode); setInterval(updateOnlineCount, 15000); showCanvasOnline(); })();