您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
显示 WebSocket 收发的 JSON 数据,并支持手动发包和屏蔽指定类型
当前为
// ==UserScript== // @name [MWI] WebSocket 双向日志查看器 // @namespace http://tampermonkey.net/ // @version 1.0.0 // @description 显示 WebSocket 收发的 JSON 数据,并支持手动发包和屏蔽指定类型 // @author XIxixi297 // @license MIT // @match https://www.milkywayidle.com/* // @match https://test.milkywayidle.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=milkywayidle.com // @grant none // @run-at document-start // ==/UserScript== (function () { 'use strict'; // 全局 WebSocket 实例存储 window.wsInstances = []; window.currentWS = null; // 屏蔽列表 - 存储需要屏蔽的 type,支持持久化 const STORAGE_KEY = 'ws_blocked_types'; // 从localStorage加载屏蔽列表 function loadBlockedTypes() { try { const stored = localStorage.getItem(STORAGE_KEY); return stored ? new Set(JSON.parse(stored)) : new Set(); } catch (e) { console.warn('加载屏蔽列表失败,使用空列表:', e); return new Set(); } } // 保存屏蔽列表到localStorage function saveBlockedTypes() { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(Array.from(window.wsBlockedTypes))); } catch (e) { console.error('保存屏蔽列表失败:', e); } } window.wsBlockedTypes = loadBlockedTypes(); const OriginalWebSocket = window.WebSocket; window.WebSocket = new Proxy(OriginalWebSocket, { construct(target, args) { const ws = new target(...args); const url = args[0]; // 保存到全局变量 window.wsInstances.push(ws); window.currentWS = ws; // 最新的连接 // 拦截 .send() const originalSend = ws.send; ws.send = function (data) { try { const parsed = JSON.parse(data); const msgType = parsed.type || '未知类型'; // 检查是否需要屏蔽 if (!window.wsBlockedTypes.has(msgType)) { console.groupCollapsed(`%c→ 发送: ${msgType}`, 'color: #03A9F4; font-weight: bold;'); console.log(parsed); console.groupEnd(); } } catch (e) { console.log('%c→ 发送非JSON:', 'color: #03A9F4;', data); } return originalSend.call(this, data); }; // 拦截 .onmessage ws.addEventListener("message", function (event) { try { const parsed = JSON.parse(event.data); const msgType = parsed.type || '未知类型'; // 检查是否需要屏蔽 if (!window.wsBlockedTypes.has(msgType)) { console.groupCollapsed(`%c← 接收: ${msgType}`, 'color: #4CAF50; font-weight: bold;'); console.log(parsed); console.groupEnd(); } } catch (e) { console.log('%c← 接收非JSON:', 'color: #4CAF50;', event.data); } }); ws.addEventListener("open", function () { console.info('%cWebSocket 连接已建立: ' + url, 'color: gray;'); }); ws.addEventListener("close", function (e) { console.warn('%cWebSocket 连接关闭', 'color: orange;', e); // 从数组中移除关闭的连接 const index = window.wsInstances.indexOf(ws); if (index > -1) { window.wsInstances.splice(index, 1); } if (window.currentWS === ws) { window.currentWS = window.wsInstances[window.wsInstances.length - 1] || null; } }); ws.addEventListener("error", function (e) { console.error('%cWebSocket 错误', 'color: red;', e); }); return ws; } }); // 便捷发包函数 window.sendWS = function(data) { if (!window.currentWS) { console.error('没有可用的 WebSocket 连接'); return false; } if (window.currentWS.readyState !== WebSocket.OPEN) { console.error('WebSocket 连接未打开'); return false; } const jsonData = typeof data === 'string' ? data : JSON.stringify(data); window.currentWS.send(jsonData); console.log('%c✅ 手动发送成功:', 'color: #FF9800; font-weight: bold;', data); return true; }; // 显示所有 WebSocket 连接 window.listWS = function() { console.log('%cWebSocket 连接列表:', 'color: #9C27B0; font-weight: bold;'); window.wsInstances.forEach((ws, index) => { const status = ws.readyState === WebSocket.OPEN ? '✅打开' : ws.readyState === WebSocket.CONNECTING ? '🔄连接中' : ws.readyState === WebSocket.CLOSING ? '🔄关闭中' : '❌已关闭'; console.log(`[${index}] ${ws.url} - ${status}`); }); console.log('当前活跃连接:', window.currentWS?.url || '无'); }; // 切换当前 WebSocket window.switchWS = function(index) { if (index >= 0 && index < window.wsInstances.length) { window.currentWS = window.wsInstances[index]; console.log('%c切换到 WebSocket:', 'color: #9C27B0;', window.currentWS.url); } else { console.error('无效的索引'); } }; // 添加屏蔽类型 window.blockType = function(type) { if (typeof type === 'string') { window.wsBlockedTypes.add(type); saveBlockedTypes(); console.log('%c🚫 已屏蔽类型:', 'color: #F44336; font-weight: bold;', type); } else if (Array.isArray(type)) { type.forEach(t => window.wsBlockedTypes.add(t)); saveBlockedTypes(); console.log('%c🚫 已屏蔽类型:', 'color: #F44336; font-weight: bold;', type); } else { console.error('类型必须是字符串或字符串数组'); } }; // 移除屏蔽类型 window.unblockType = function(type) { if (typeof type === 'string') { window.wsBlockedTypes.delete(type); saveBlockedTypes(); console.log('%c✅ 已取消屏蔽类型:', 'color: #4CAF50; font-weight: bold;', type); } else if (Array.isArray(type)) { type.forEach(t => window.wsBlockedTypes.delete(t)); saveBlockedTypes(); console.log('%c✅ 已取消屏蔽类型:', 'color: #4CAF50; font-weight: bold;', type); } else { console.error('类型必须是字符串或字符串数组'); } }; // 显示当前屏蔽列表 window.listBlockedTypes = function() { if (window.wsBlockedTypes.size === 0) { console.log('%c当前没有屏蔽任何类型', 'color: #607D8B;'); } else { console.log('%c当前屏蔽的类型:', 'color: #F44336; font-weight: bold;'); Array.from(window.wsBlockedTypes).forEach((type, index) => { console.log(` [${index + 1}] ${type}`); }); } }; // 清空屏蔽列表 window.clearBlockedTypes = function() { const count = window.wsBlockedTypes.size; window.wsBlockedTypes.clear(); saveBlockedTypes(); console.log(`%c✅ 已清空屏蔽列表 (共清除 ${count} 个类型)`, 'color: #4CAF50; font-weight: bold;'); }; console.info('%c[MWI WS Logger] WebSocket 拦截器已启用 - 增强版', 'color: purple; font-weight: bold;'); // 显示加载的屏蔽列表 if (window.wsBlockedTypes.size > 0) { console.info(`%c已加载 ${window.wsBlockedTypes.size} 个屏蔽类型:`, 'color: #FF9800; font-weight: bold;', Array.from(window.wsBlockedTypes)); } console.info('%c使用方法:', 'color: #2196F3; font-weight: bold;'); console.info('%c sendWS({type: "messageType", data: "your data"}) - 发送消息', 'color: #2196F3;'); console.info('%c listWS() - 查看所有 WebSocket 连接', 'color: #2196F3;'); console.info('%c switchWS(index) - 切换当前连接', 'color: #2196F3;'); console.info('%c blockType("typeName") - 屏蔽指定类型的消息', 'color: #F44336;'); console.info('%c blockType(["type1", "type2"]) - 屏蔽多个类型', 'color: #F44336;'); console.info('%c unblockType("typeName") - 取消屏蔽指定类型', 'color: #4CAF50;'); console.info('%c listBlockedTypes() - 查看当前屏蔽列表', 'color: #607D8B;'); console.info('%c clearBlockedTypes() - 清空所有屏蔽', 'color: #607D8B;'); })();