Stumblechat Stalker

Intercept WebSocket messages on StumbleChat and display them with tabs

目前为 2024-11-10 提交的版本。查看 最新版本

// ==UserScript==
// @name         Stumblechat Stalker
// @namespace    http://tampermonkey.net/
// @version      1.03
// @description  Intercept WebSocket messages on StumbleChat and display them with tabs
// @author       MeKLiN
// @match        https://stumblechat.com/room/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=stumblechat.com
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Create a function to display WebSocket messages under the appropriate tab
    function displayWebSocketMessage(message, tab) {
        const tabDiv = document.getElementById(tab);
        if (tabDiv) {
            const messageDiv = document.createElement("div");
            messageDiv.innerHTML = message;
            tabDiv.appendChild(messageDiv);
            tabDiv.scrollTop = tabDiv.scrollHeight; // Auto-scroll
        }
    }

    // Override WebSocket constructor to intercept WebSocket creation
    const originalWebSocket = window.WebSocket;
    window.WebSocket = function(url, protocols) {
        console.log('WebSocket URL:', url);

        // Call original WebSocket constructor
        const ws = new originalWebSocket(url, protocols);

        // Event listener for receiving messages
        ws.addEventListener('message', event => {
            try {
                const message = JSON.parse(event.data);
                // Filter messages by the "stumble" type (join, joined, msg, subscribe, publish)
                switch (message.stumble) {
                    case "join":
                        displayWebSocketMessage(JSON.stringify(message), "joinTab");
                        break;
                    case "joined":
                        displayWebSocketMessage(JSON.stringify(message), "joinedTab");
                        break;
                    case "msg":
                        displayWebSocketMessage(JSON.stringify(message), "msgTab");
                        break;
                    case "subscribe":
                        displayWebSocketMessage(JSON.stringify(message), "subscribeTab");
                        break;
                    case "publish":
                        displayWebSocketMessage(JSON.stringify(message), "publishTab");
                        break;
                    default:
                        console.log("Unhandled message type:", message.stumble);
                        break;
                }
            } catch (error) {
                console.error("Error processing WebSocket message:", error);
            }
        });

        return ws;
    };

    // Method to create the overlay container with tabs
    function createWebSocketTabs() {
        const overlayDiv = document.createElement("div");
        overlayDiv.style.position = "fixed";
        overlayDiv.style.top = "0";
        overlayDiv.style.left = "0";
        overlayDiv.style.zIndex = "9999";
        overlayDiv.style.backgroundColor = "#222";
        overlayDiv.style.color = "#fff";
        overlayDiv.style.padding = "10px";
        overlayDiv.style.borderRadius = "8px";
        overlayDiv.style.maxWidth = "400px";
        overlayDiv.style.maxHeight = "80vh";
        overlayDiv.style.overflowY = "auto";
        overlayDiv.style.display = "flex";
        overlayDiv.style.flexDirection = "column";
        overlayDiv.style.justifyContent = "flex-start";

        // Create Tabs
        const tabNames = ["join", "joined", "msg", "subscribe", "publish"];
        tabNames.forEach(tab => {
            const tabButton = document.createElement("button");
            tabButton.innerHTML = tab.charAt(0).toUpperCase() + tab.slice(1);
            tabButton.style.backgroundColor = "#444";
            tabButton.style.border = "none";
            tabButton.style.padding = "10px";
            tabButton.style.margin = "2px";
            tabButton.style.cursor = "pointer";
            tabButton.onclick = () => {
                showTab(tab); // Show the clicked tab
            };
            overlayDiv.appendChild(tabButton);
        });

        // Create divs for each tab
        const tabContentDivs = ["join", "joined", "msg", "subscribe", "publish"];
        tabContentDivs.forEach(tab => {
            const tabDiv = document.createElement("div");
            tabDiv.id = tab + "Tab";
            tabDiv.style.display = "none";
            tabDiv.style.padding = "10px";
            tabDiv.style.border = "1px solid #555";
            tabDiv.style.borderRadius = "5px";
            tabDiv.style.marginTop = "5px";
            tabDiv.style.maxHeight = "60vh";
            tabDiv.style.overflowY = "auto";
            overlayDiv.appendChild(tabDiv);
        });

        // Append the overlay to the body
        document.body.appendChild(overlayDiv);

        // Function to show the selected tab
        function showTab(tab) {
            tabContentDivs.forEach(tabName => {
                const tabDiv = document.getElementById(tabName + "Tab");
                tabDiv.style.display = tabName === tab ? "block" : "none";
            });
        }

        // Default to showing the "join" tab
        showTab("join");
    }

    // Call the function to create the WebSocket tabs
    createWebSocketTabs();

})();