AutoVerify and Chat Compact

AutoVerify StumbleChat and chat compact style

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         AutoVerify and Chat Compact
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  AutoVerify StumbleChat and chat compact style
// @author       MeKLiN
// @match        https://stumblechat.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=stumblechat.com
// @grant        none
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(function() {
    let css = `
        .message .nickname ~ .content {
            display: inline-block;
            top: -7px;
            position: relative;
            margin-left: 2px;
            margin-right: 1em;
        }
        .content + .content {
            display: inline-block!important;
            margin-right: 1em;
        }
        .message .nickname ~ .content span {
            line-height: 1.5em;
        }
    `;
    if (typeof GM_addStyle !== "undefined") {
      GM_addStyle(css);
    } else {
      let styleNode = document.createElement("style");
      styleNode.appendChild(document.createTextNode(css));
      (document.querySelector("head") || document.documentElement).appendChild(styleNode);
    }
})();

var scripts = document.getElementsByTagName("script");
var script = null;
var found = false;

for (var i = 0; i < scripts.length; i++) {
    script = scripts[i];
    if (/^jQuery.*\.js$/i.test(script.src)) {
        found = true;
        break;
    }
}

if (!found) {
    try {
        $ || jQuery || $ === jQuery;
        found = true;
    } catch (err) {

    }
}

if (!found) {
    // inject jQuery.
    script = document.createElement("script");
    script.type = "text/javascript";

    var protocol = /^https:/i.test(document.location) ? "https" : "http";
    script.src = protocol + "://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
    document.getElementsByTagName("body")[0].appendChild(script);
}

// Define App globally
window.App = {
    Init: () => {
        // Define the behavior of App.Init() here
        console.log('App.Init() called');
    }
};

class VerifyScript {
    constructor() {
        this.observeDOM();
        this.setupConsoleOverlay();
        this.clickCount = 0;
    }

    clickVerifyButton = (verifyButton) => {
        this.clickCount++;
        this.logToOverlay(`Attempting to click VERIFY button ${this.clickCount} time(s)...`);
        if (verifyButton) {
            this.logToOverlay('VERIFY button found.');
            // Remove any existing event listeners on the button
            verifyButton.removeEventListener('click', this.clickVerifyButton);
            // Manually create and dispatch a click event
            const clickEvent = new MouseEvent('click', {
                bubbles: true,
                cancelable: true,
                view: window
            });
            this.logToOverlay('Before dispatchEvent');
            verifyButton.dispatchEvent(clickEvent);
            this.logToOverlay('After dispatchEvent');

            if (this.clickCount < 3) {
                setTimeout(() => {
                    if (this.isMouseLocked()) {
                        this.sendMouseUp();
                    }
                    this.clickVerifyButton(verifyButton);
                }, 500); // Delay between clicks
            } else if (this.clickCount === 3) {
                // After the third click, call App.Init()
                this.logToOverlay('Third click completed, calling App.Init()...');
                setTimeout(() => {
                    this.logToOverlay('Calling App.Init()...');
                    App.Init();
                }, 500); // Adjust the delay as needed
            }
        } else {
            this.logToOverlay('VERIFY button not found.');
        }
    }

    isMouseLocked = () => {
        return document.pointerLockElement === document.body ||
            document.mozPointerLockElement === document.body ||
            document.webkitPointerLockElement === document.body;
    }

    sendMouseUp = () => {
        this.logToOverlay('Mouse is locked, sending mouseup command...');
        const mouseUpEvent = new MouseEvent('mouseup', {
            bubbles: true,
            cancelable: true,
            view: window
        });
        document.body.dispatchEvent(mouseUpEvent);
    }

    observeDOM = () => {
        this.logToOverlay('Setting up MutationObserver...');
        const observer = new MutationObserver((mutationsList) => {
            this.logToOverlay(`Mutation observed... ${mutationsList.length} mutation(s) in total.`);
            for (const mutation of mutationsList) {
                this.logToOverlay(`Mutation type: ${mutation.type}`);
                this.logToOverlay(`Mutation target: ${mutation.target.outerHTML}`);
                this.logToOverlay(`Added nodes: ${mutation.addedNodes.length}`);
                mutation.addedNodes.forEach((node) => {
                    if (node instanceof HTMLElement) {
                        this.logToOverlay(`Added node: ${node.nodeName}`);
                        // Check if the added node is the VERIFY button
                        if (node.id === 'interact') {
                            // Add a slight delay to ensure modal visibility
                            setTimeout(() => {
                                // If so, click the button without scrolling
                                this.clickVerifyButton(node);
                                // Attempt other ways to click the button
                                document.querySelector('#modal #interact').click(); // First attempt
                                document.querySelector('#modal button#interact').click(); // Second attempt

                                // Additional attempts
                                node.click(); // Third attempt
                                const customClickEvent = new CustomEvent('click', { bubbles: true });
                                node.dispatchEvent(customClickEvent); // Fourth attempt
                                const mouseDownEvent = new MouseEvent('mousedown', { bubbles: true });
                                node.dispatchEvent(mouseDownEvent);
                                const mouseUpEvent = new MouseEvent('mouseup', { bubbles: true });
                                node.dispatchEvent(mouseUpEvent); // Fifth attempt
                                node.parentElement.click(); // Sixth attempt
                                console.log(`Attempt ${this.clickCount + 6}: jQuery click`);
                                $(node).trigger('click'); // Seventh attempt
                                console.log(`Attempt ${this.clickCount + 7}: Focus and simulate Enter key`);
                                node.focus();
                                const keyboardEvent = new KeyboardEvent('keydown', { key: 'Enter' });
                                node.dispatchEvent(keyboardEvent); // Eighth attempt
                                const pointerDownEvent = new PointerEvent('pointerdown', { bubbles: true });
                                node.dispatchEvent(pointerDownEvent);
                                const pointerUpEvent = new PointerEvent('pointerup', { bubbles: true });
                                node.dispatchEvent(pointerUpEvent); // Ninth attempt
                                const touchEvent = new TouchEvent('touchstart', { bubbles: true });
                                node.dispatchEvent(touchEvent); // Tenth attempt
                            }, 500); // Adjust the delay as needed
                        }
                    }
                });
                this.logToOverlay(`Removed nodes: ${mutation.removedNodes.length}`);
                mutation.removedNodes.forEach((node) => {
                    this.logToOverlay(`Removed node: ${node.nodeName}`);
                });
            }
        });

        // Start observing changes in the sc-modal element
        this.logToOverlay('Attempting to observe sc-modal element...');
        const scModal = document.querySelector('#modal');
        if (scModal) {
            this.logToOverlay('sc-modal element found. Starting observation...');
            observer.observe(scModal, { childList: true, subtree: true });
        } else {
            this.logToOverlay('sc-modal element not found.');
        }
    }

    setupConsoleOverlay = () => {
        const consoleOverlay = document.createElement('div');
        consoleOverlay.setAttribute('id', 'console-overlay');
        consoleOverlay.style.position = 'fixed';
        consoleOverlay.style.top = '10px';
        consoleOverlay.style.left = '10px';
        consoleOverlay.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
        consoleOverlay.style.padding = '10px';
        consoleOverlay.style.border = '1px solid #ccc';
        consoleOverlay.style.zIndex = '9999';

        // Minimize button
        const minimizeButton = document.createElement('button');
        minimizeButton.textContent = 'Minimize';
        minimizeButton.style.position = 'absolute';
        minimizeButton.style.top = '5px';
        minimizeButton.style.right = '5px';
        minimizeButton.addEventListener('click', () => {
            consoleOverlay.style.display = 'none';
        });
        consoleOverlay.appendChild(minimizeButton);

        document.body.appendChild(consoleOverlay);
        this.consoleOverlay = consoleOverlay;
    }

    logToOverlay = (message) => {
        const logEntry = document.createElement('div');
        logEntry.textContent = message;
        if (this.consoleOverlay) {
            this.consoleOverlay.appendChild(logEntry);
        }
        console.log(message);
    }
}

// Start the script
new VerifyScript();