Greasy Fork

WebSocket消息额外监听脚本

在网页已有WebSocket基础上额外监听消息

当前为 2024-12-06 提交的版本,查看 最新版本

// ==UserScript==
// @name WebSocket消息额外监听脚本
// @namespace http://yournamespace.com/
// @version 0.18
// @description 在网页已有WebSocket基础上额外监听消息
// @author Your Name
// @match https://www.milkywayidle.com/*
// @grant none
// @license MIT
// ==/UserScript==

(function () {
    'use strict';

    const MAX_MESSAGES = 20; // 最大显示消息数量

    // 延迟初始化脚本
    window.addEventListener('load', () => {
        // 创建消息显示区域
        const createMessageDisplay = () => {
            const messageBox = document.createElement('div');
            messageBox.id = 'ws-message-box';
            messageBox.style.position = 'fixed';
            messageBox.style.top = '10px';
            messageBox.style.left = '10px';
            messageBox.style.width = '400px';
            messageBox.style.height = '200px';
            messageBox.style.resize = 'both';
            messageBox.style.overflow = 'hidden'; // 避免超出内容显示
            messageBox.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
            messageBox.style.color = '#fff';
            messageBox.style.zIndex = '9999';
            messageBox.style.border = '1px solid rgba(255, 255, 255, 0.5)';
            messageBox.style.borderRadius = '5px';
            messageBox.style.boxShadow = '0px 2px 5px rgba(0, 0, 0, 0.5)';
            messageBox.innerHTML = `
                <div id="ws-header" style="padding: 5px; background: rgba(255, 255, 255, 0.1); cursor: move; border-bottom: 1px solid rgba(255, 255, 255, 0.2);">
                    <button id="clear-messages" style="padding: 5px; font-size: 12px;">Clear</button>
                    <input id="filter-keyword" type="text" placeholder="Filter by keyword" style="flex: 1; padding: 5px; font-size: 12px; margin-left: 5px;"/>
                </div>
                <div id="ws-messages" style="padding: 10px; max-height: calc(100% - 40px); overflow-y: auto;"></div>`;
            document.body.appendChild(messageBox);

            makeDraggable(messageBox, document.getElementById('ws-header')); // 使消息框通过顶部区域可拖动
        };

        // 添加消息到显示区域,限制最大消息数量
        const appendMessage = (message) => {
            const messagesContainer = document.getElementById('ws-messages');
            const filterKeyword = document.getElementById('filter-keyword').value.trim();

            if (messagesContainer) {
                // 仅显示符合过滤条件的消息
                if (!filterKeyword || message.includes(filterKeyword)) {
                    const messageElement = document.createElement('div');
                    messageElement.textContent = message;
                    messagesContainer.appendChild(messageElement);

                    // 限制显示的最大消息数量
                    const allMessages = messagesContainer.children;
                    if (allMessages.length > MAX_MESSAGES) {
                        messagesContainer.removeChild(allMessages[0]);
                    }

                    messagesContainer.scrollTop = messagesContainer.scrollHeight; // 确保新消息可见
                }
            }
        };

        // 清除所有消息
        const clearMessages = () => {
            const messagesContainer = document.getElementById('ws-messages');
            if (messagesContainer) {
                messagesContainer.innerHTML = '';
            }
        };

        // 使消息框通过指定区域可拖动
        const makeDraggable = (element, dragHandle) => {
            let isDragging = false;
            let offsetX, offsetY;

            dragHandle.addEventListener('mousedown', (e) => {
                isDragging = true;
                offsetX = e.clientX - element.offsetLeft;
                offsetY = e.clientY - element.offsetTop;
                document.body.style.userSelect = 'none'; // 禁止选中文本
            });

            document.addEventListener('mousemove', (e) => {
                if (isDragging) {
                    element.style.left = `${e.clientX - offsetX}px`;
                    element.style.top = `${e.clientY - offsetY}px`;
                }
            });

            document.addEventListener('mouseup', () => {
                isDragging = false;
                document.body.style.userSelect = ''; // 恢复文本选择
            });
        };

        // 初始化消息显示区域
        createMessageDisplay();

        // 绑定按钮事件
        document.getElementById('clear-messages').addEventListener('click', clearMessages);

        // 绑定关键词筛选实时更新
        document.getElementById('filter-keyword').addEventListener('input', () => {
            const keyword = document.getElementById('filter-keyword').value.trim();
            const messagesContainer = document.getElementById('ws-messages');
            const allMessages = Array.from(messagesContainer.children);
            allMessages.forEach((msg) => {
                msg.style.display = keyword && !msg.textContent.includes(keyword) ? 'none' : 'block';
            });
        });

        // 保存原始的 WebSocket 构造函数
        const OriginalWebSocket = window.WebSocket;

        // 重写 WebSocket 构造函数
        window.WebSocket = function (...args) {
            const ws = new OriginalWebSocket(...args);

            // 监听消息事件
            ws.addEventListener('message', (event) => {
                console.log('WebSocket Message:', event.data);
                appendMessage(event.data); // 将消息显示在页面上
            });

            return ws;
        };

        // 保留 WebSocket 的其余属性和方法
        window.WebSocket.prototype = OriginalWebSocket.prototype;

        console.log('WebSocket hijacking initialized with optimized message display!');
    });
})();