Addon + for Bodega Bot

Adds functionality to Bodega Bot Users

当前为 2024-08-10 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Addon + for Bodega Bot
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  Adds functionality to Bodega Bot Users
// @author       Bort
// @license
// @icon         https://media1.giphy.com/avatars/FeedMe1219/aBrdzB77IQ5c.gif
// @match        https://tinychat.com/room/*
// @match        https://tinychat.com/*
// @exclude      https://tinychat.com/settings/*
// @exclude      https://tinychat.com/subscription/*
// @exclude      https://tinychat.com/promote/*
// @exclude      https://tinychat.com/coins/*
// @exclude      https://tinychat.com/gifts*
// @grant        GM_setClipboard
// @require      https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js
// ==/UserScript==

(function() {
    'use strict';

    // Create container for the floating button
    const container = document.createElement('div');
    container.style.position = 'fixed';
    container.style.width = '100%';
    container.style.height = '100%';
    container.style.top = '0';
    container.style.left = '0';
    container.style.zIndex = '9999';
    container.style.pointerEvents = 'none';
    document.body.appendChild(container);

    // Create main floating button
    const mainButton = document.createElement('button');
    mainButton.className = 'floating-button';
    mainButton.innerText = '⚙️';
    mainButton.title = 'Open Settings';
    mainButton.style.position = 'fixed';
    mainButton.style.bottom = '20px';
    mainButton.style.left = '20px';
    mainButton.style.width = '40px';
    mainButton.style.height = '40px';
    mainButton.style.backgroundColor = 'rgb(0 0 0 / 20%)';
    mainButton.style.color = 'white';
    mainButton.style.border = 'none';
    mainButton.style.borderRadius = '50%';
    mainButton.style.cursor = 'pointer';
    mainButton.style.transition = 'all 0.3s';
    mainButton.style.zIndex = '10000';
    mainButton.style.fontSize = '20px';
    mainButton.style.display = 'flex';
    mainButton.style.alignItems = 'center';
    mainButton.style.justifyContent = 'center';
    mainButton.style.pointerEvents = 'auto';
    container.appendChild(mainButton);

    // Create container for additional buttons
    const additionalButtons = document.createElement('div');
    additionalButtons.className = 'additional-buttons';
    additionalButtons.style.display = 'none';
    additionalButtons.style.flexDirection = 'column';
    additionalButtons.style.position = 'fixed';
    additionalButtons.style.left = '20px';
    additionalButtons.style.bottom = '70px';
    additionalButtons.style.zIndex = '10001';
    additionalButtons.style.pointerEvents = 'auto';
    container.appendChild(additionalButtons);

    // Array of additional button configurations
    const buttonConfigs = [
        { label: '📷', action: takeScreenshot, title: 'Take Screenshot' },
        { label: '📺', action: toggleGroupTube, title: 'Toggle GroupTube' },
        { label: '🔍+', action: () => resizeGroupTube(1.1), title: 'Increase GroupTube Size' },
        { label: '🔍-', action: () => resizeGroupTube(0.9), title: 'Decrease GroupTube Size' },
        { label: '🔄', action: reloadGroupTube, title: 'Reload GroupTube' },
        { label: '📝', action: showCommands, title: 'Show Commands' }
    ];

    // Create additional buttons
    buttonConfigs.forEach(config => {
        const button = document.createElement('button');
        button.className = 'additional-button';
        button.innerText = config.label;
        button.title = config.title;
        button.style.backgroundColor = 'rgb(0 0 0 / 20%)';
        button.style.color = 'white';
        button.style.border = 'none';
        button.style.margin = '5px';
        button.style.padding = '10px';
        button.style.borderRadius = '5px';
        button.style.cursor = 'pointer';
        button.style.transition = 'all 0.3s';
        button.style.width = '40px';
        button.style.height = '40px';
        button.style.fontSize = '16px';
        button.style.display = 'flex';
        button.style.alignItems = 'center';
        button.style.justifyContent = 'center';
        additionalButtons.appendChild(button);

        // Add click event listener
        button.addEventListener('click', () => {
            config.action();

            // Provide visual feedback
            const originalColor = button.style.backgroundColor;
            button.style.backgroundColor = 'rgb(0 0 0 / 20%)';
            setTimeout(() => {
                button.style.backgroundColor = originalColor;
            }, 200);
        });

        // Hover effect for additional buttons
        button.addEventListener('mouseover', () => {
            button.style.backgroundColor = 'rgb(0 0 0 / 30%)';
        });
        button.addEventListener('mouseout', () => {
            button.style.backgroundColor = 'rgb(0 0 0 / 20%)';
        });
    });

    // Toggle additional buttons display on main button click
    mainButton.addEventListener('click', function() {
        const isExpanded = additionalButtons.style.display === 'flex';
        additionalButtons.style.display = isExpanded ? 'none' : 'flex';
        mainButton.style.transform = isExpanded ? 'rotate(0deg)' : 'rotate(180deg)';
    });

    // Allow dragging of the main button
    let isDraggingMain = false;
    let mainOffsetX, mainOffsetY;

    mainButton.addEventListener('mousedown', (e) => {
        isDraggingMain = true;
        mainOffsetX = e.clientX - mainButton.getBoundingClientRect().left;
        mainOffsetY = e.clientY - mainButton.getBoundingClientRect().top;
    });

    document.addEventListener('mousemove', (e) => {
        if (isDraggingMain) {
            const x = e.clientX - mainOffsetX;
            const y = e.clientY - mainOffsetY;

            // Confine within viewport
            const maxX = window.innerWidth - mainButton.offsetWidth;
            const maxY = window.innerHeight - mainButton.offsetHeight;

            mainButton.style.left = Math.max(0, Math.min(x, maxX)) + 'px';
            mainButton.style.bottom = Math.max(0, Math.min(window.innerHeight - y - mainButton.offsetHeight, maxY)) + 'px';

            // Move additional buttons along with the main button
            additionalButtons.style.left = mainButton.style.left;
            additionalButtons.style.bottom = (parseInt(mainButton.style.bottom) + mainButton.offsetHeight + 10) + 'px';
        }
    });

    document.addEventListener('mouseup', () => {
        isDraggingMain = false;
    });

    // Screenshot functionality
    function takeScreenshot() {
        html2canvas(document.body).then(canvas => {
            const link = document.createElement('a');
            link.download = 'screenshot.png';
            link.href = canvas.toDataURL();
            link.click();

            // Provide user feedback
            alerat('Screenshot saved!');
        });
    }

    // GroupTube functionality
    let groupTubeWindow = null;
    let isDragging = false;

    function toggleGroupTube() {
        if (groupTubeWindow) {
            groupTubeWindow.style.display = groupTubeWindow.style.display === 'none' ? 'block' : 'none';
            // Provide user feedback
            const status = groupTubeWindow.style.display === 'none' ? 'hidden' : 'visible';
            const feedbackButton = Array.from(additionalButtons.children).find(button => button.title === 'Toggle GroupTube');
            if (feedbackButton) {
                feedbackButton.title = `GroupTube is now ${status}`;
            }
            return;
        }

        groupTubeWindow = document.createElement('div');
        groupTubeWindow.style.position = 'fixed';
        groupTubeWindow.style.top = '10%';
        groupTubeWindow.style.left = '10%';
        groupTubeWindow.style.width = '80%';
        groupTubeWindow.style.height = '80%';
        groupTubeWindow.style.backgroundColor = '#222';
        groupTubeWindow.style.border = '2px solid rgb(0 0 0 / 20%)';
        groupTubeWindow.style.borderRadius = '10px';
        groupTubeWindow.style.zIndex = '10002';
        groupTubeWindow.style.overflow = 'hidden';
        groupTubeWindow.style.pointerEvents = 'auto';

        const iframe = document.createElement('iframe');
        iframe.src = 'https://group.tube/group/70d02ed5-df92-424b-bdcd-d0c60f8ad574?join';
        iframe.style.width = '100%';
        iframe.style.height = 'calc(100% - 30px)';
        iframe.style.border = 'none';
        iframe.style.pointerEvents = 'auto';
        groupTubeWindow.appendChild(iframe);

        const closeButton = document.createElement('button');
        closeButton.innerText = 'X';
        closeButton.style.position = 'absolute';
        closeButton.style.top = '1px';
        closeButton.style.right = '1px';
        closeButton.style.backgroundColor = 'rgb(0 0 0 / 20%)';
        closeButton.style.border = 'none';
        closeButton.style.color = '#fff';
        closeButton.style.fontSize = '1px';
        closeButton.style.cursor = 'pointer';
        closeButton.style.padding = '1px 1px';
        closeButton.style.borderRadius = '1px';
        closeButton.onclick = () => groupTubeWindow.style.display = 'none';
        groupTubeWindow.appendChild(closeButton);

        container.appendChild(groupTubeWindow);

        // Add drag functionality to GroupTube window
        const dragHandle = document.createElement('div');
        dragHandle.style.position = 'absolute';
        dragHandle.style.top = '0';
        dragHandle.style.left = '0';
        dragHandle.style.width = '100%';
        dragHandle.style.height = '12px';
        dragHandle.style.cursor = 'move';
        groupTubeWindow.appendChild(dragHandle);

        dragHandle.addEventListener('mousedown', initDrag, false);
        window.addEventListener('mousemove', doDrag, false);
        window.addEventListener('mouseup', stopDrag, false);

        let startX, startY;

        function initDrag(e) {
            startX = e.clientX - groupTubeWindow.offsetLeft;
            startY = e.clientY - groupTubeWindow.offsetTop;
            isDragging = true;
        }

        function doDrag(e) {
            if (isDragging) {
                groupTubeWindow.style.left = (e.clientX - startX) + 'px';
                groupTubeWindow.style.top = (e.clientY - startY) + 'px';
            }
        }

        function stopDrag() {
            isDragging = false;
        }
    }

    function resizeGroupTube(factor) {
        if (groupTubeWindow) {
            const currentWidth = groupTubeWindow.offsetWidth;
            const currentHeight = groupTubeWindow.offsetHeight;
            groupTubeWindow.style.width = (currentWidth * factor) + 'px';
            groupTubeWindow.style.height = (currentHeight * factor) + 'px';
        }
    }

    function reloadGroupTube() {
        if (groupTubeWindow) {
            const iframe = groupTubeWindow.querySelector('iframe');
            if (iframe) {
                iframe.src = iframe.src;
            }
        }
    }

    // Command functionality
    const commands = {
        'Owner Commands': [
          "!raid tc link",
          "!camsweep 5 - 30",
          "!closeall",
          "!kickall",
          "!version",
          "!whoisbot",
          "!bot",
          "!autokick (be careful!)",
          "!autoban (be careful!)"
        ],
        'Main Toggles': [
          "!greenroomtoggle",
          "!publiccommandtoggle",
          "!bottoggle",
          "!votetoggle",
          "!greetmodetoggle",
          "!imgurtoggle",
          "!raidtoggle",
          "!avatartoggle",
          "!notificationtoggle",
          "!popuptoggle",
          "!soundmetertoggle",
          "!timestamptoggle",
          "!remindertoggle"
        ],
        'User Management': [
          "!autokick (be careful!)",
          "!autoban (be careful!)",
          "!userban user",
          "!nickban nick",
          "!userkick user",
          "!nickkick nick",
          "!userclose user",
          "!nickclose nick"
        ],
        'Green Room': [
          "!greenroomlist",
          "!greenroomlistclear",
          "!greenroomadd user",
          "!greenroomremove #",
          "!greenroomignorelist",
          "!greenroomignorelistclear",
          "!greenroomignoreadd user",
          "!greenroomignoreremove #"
        ],
        'YouTube Controls': [
          "!ytapi apikey",
          "!ytbypass link (no playlists)",
          "!yt link | keyword",
          "!ytskip",
          "!ytclear",
          "!ytlink",
          "!ytkeyword",
          "!ytqueue"
        ],
        'Ban Management': [
          "!userbanlist",
          "!userbanlistclear",
          "!userbanadd user",
          "!userbanremove #",
          "!nickbanlist",
          "!nickbanlistclear",
          "!nickbanadd nick",
          "!nickbanremove #",
          "!bankeywordlist",
          "!bankeywordlistclear",
          "!bankeywordadd keyword | phrase",
          "!bankeywordremove #"
        ],
        'Kick Management': [
          "!userkicklist",
          "!userkicklistclear",
          "!userkickadd user",
          "!userkickremove #",
          "!nickkicklist",
          "!nickkicklistclear",
          "!nickkickadd nick",
          "!nickkickremove #",
          "!kickkeywordlist",
          "!kickkeywordlistclear",
          "!kickkeywordadd keyword | phrase",
          "!kickkeywordremove #"
        ],
        'Operator Management': [
          "!oplist",
          "!oplistclear",
          "!opadd user | -all",
          "!opremove #",
          "!optoggle"
        ],
        'Moderator Management': [
          "!modlist",
          "!modlistclear",
          "!modadd user",
          "!modremove #"
        ],
        'Jr. Moderator Commands': [
          "!userban user",
          "!nickban nick",
          "!userkick user",
          "!nickkick nick",
          "!userclose user",
          "!nickclose nick"
        ],
        'List Management': [
          "!lists",
          "!listsclear",
          "!userlist",
          "!mentionlist",
          "!mentionlistclear",
          "!mentionadd keyword",
          "!mentionremove #",
          "!ignorelist",
          "!ignorelistclear",
          "!ignoreadd user",
          "!ignoreremove #",
          "!hiddencameralist",
          "!hiddencameralistclear",
          "!hiddencameraadd user",
          "!hiddencameraremove #",
          "!greetlist",
          "!greetlistclear",
          "!greetadd user | -all",
          "!greetremove #",
          "!ttslist",
          "!ttslistclear",
          "!ttsadd user | -all | -event",
          "!ttsremove #",
          "!highlightlist",
          "!highlightlistclear",
          "!highlightadd user",
          "!highlightremove #",
          "!reminderlist",
          "!reminderlistclear",
          "!reminderadd user",
          "!reminderremove #",
          "!safelist",
          "!safelistclear",
          "!safeadd user",
          "!saferemove #"
        ],
        'Settings and Utilities': [
          "!fps 1 - 60",
          "!clr",
          "!clrall",
          "!settings",
          "!share"
        ],
        'Fun Commands': [
          "!coin",
          "!advice",
          "!8ball question",
          "!roll #",
          "!chuck",
          "!dad",
          "!vote user"
        ],
        'Trivia Game': [
          "!gameview",
          "!trivia",
          "!triviahelp",
          "!triviahost",
          "!triviaskip",
          "!triviaend",
          "!triviascore",
          "!triviaplayerlist",
          "!triviaplayerlistclear",
          "!triviaadd question answer",
          "!triviaremove #",
          "!triviaplayeradd player",
          "!triviaplayerremove player"
        ],
        'Fish Game': [
          "!gameview",
          "!fish",
          "!fishhelp",
          "!fishhost",
          "!fishupgrade",
          "!fishstop",
          "!fishstats",
          "!fishinventory",
          "!fishequip bait | rod",
          "!fishevent",
          "!fishleaderboard"
        ]
    };

    let commandWindow = null;

    function showCommands() {
        if (commandWindow) {
            commandWindow.style.display = commandWindow.style.display === 'none' ? 'block' : 'none';
            return;
        }

        commandWindow = document.createElement('div');
        commandWindow.style.position = 'fixed';
        commandWindow.style.top = '50%';
        commandWindow.style.left = '50%';
        commandWindow.style.transform = 'translate(-50%, -50%)';
        commandWindow.style.width = '90%';
        commandWindow.style.height = '80%';
        commandWindow.style.maxWidth = '800px';
        commandWindow.style.maxHeight = '600px';
        commandWindow.style.overflowY = 'auto';
        commandWindow.style.backgroundColor = 'rgba(34, 34, 34, 0.9)';
        commandWindow.style.color = '#fff';
        commandWindow.style.padding = '20px';
        commandWindow.style.borderRadius = '10px';
        commandWindow.style.zIndex = '10002';
        commandWindow.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)';
        commandWindow.style.pointerEvents = 'auto';

        // Add custom scrollbar styles
        commandWindow.style.scrollbarWidth = 'thin';
        commandWindow.style.scrollbarColor = 'rgba(85, 85, 85, 0.5) rgba(34, 34, 34, 0.3)';

        // For Webkit browsers (Chrome, Safari)
        const styleElement = document.createElement('style');
        styleElement.textContent = `
            #commandWindow::-webkit-scrollbar {
                width: 8px;
            }
            #commandWindow::-webkit-scrollbar-track {
                background: rgba(34, 34, 34, 0.3);
            }
            #commandWindow::-webkit-scrollbar-thumb {
                background-color: rgba(85, 85, 85, 0.5);
                border-radius: 4px;
            }
        `;
        document.head.appendChild(styleElement);
        commandWindow.id = 'commandWindow';

        const closeButton = document.createElement('button');
        closeButton.innerText = 'X';
        closeButton.style.position = 'absolute';
        closeButton.style.top = '10px';
        closeButton.style.right = '10px';
        closeButton.style.backgroundColor = 'transparent';
        closeButton.style.border = 'none';
        closeButton.style.color = '#fff';
        closeButton.style.fontSize = '20px';
        closeButton.style.cursor = 'pointer';
        closeButton.onclick = () => commandWindow.style.display = 'none';
        commandWindow.appendChild(closeButton);

        for (const [category, categoryCommands] of Object.entries(commands)) {
            const categoryTitle = document.createElement('h3');
            categoryTitle.innerText = category;
            categoryTitle.style.marginTop = '20px';
            categoryTitle.style.marginBottom = '10px';
            categoryTitle.style.fontSize = '18px';
            categoryTitle.style.color = '#007bff';
            commandWindow.appendChild(categoryTitle);

            categoryCommands.forEach(command => {
                const commandButton = document.createElement('button');
                commandButton.innerText = command;
                commandButton.style.display = 'block';
                commandButton.style.width = '100%';
                commandButton.style.padding = '10px';
                commandButton.style.marginBottom = '5px';
                commandButton.style.backgroundColor = 'rgba(68, 68, 68, 0.8)';
                commandButton.style.border = 'none';
                commandButton.style.color = '#fff';
                commandButton.style.textAlign = 'left';
                commandButton.style.cursor = 'pointer';
                commandButton.style.borderRadius = '5px';
                commandButton.style.transition = 'all 0.3s';
                commandButton.style.fontSize = '14px';

                commandButton.addEventListener('mouseover', () => {
                    commandButton.style.backgroundColor = 'rgba(85, 85, 85, 0.8)';
                });

                commandButton.addEventListener('mouseout', () => {
                    commandButton.style.backgroundColor = 'rgba(68, 68, 68, 0.8)';
                });

                commandButton.onclick = () => {
                    GM_setClipboard(command);
                    commandButton.style.backgroundColor = 'rgba(0, 123, 255, 0.8)';
                    commandButton.innerText = 'Copied!';
                    setTimeout(() => {
                        commandButton.style.backgroundColor = 'rgba(68, 68, 68, 0.8)';
                        commandButton.innerText = command;
                    }, 1000);
                };

                commandWindow.appendChild(commandButton);
            });
        }

        container.appendChild(commandWindow);

        // Make command window draggable
        let isDraggingCmd = false;
        let cmdStartX, cmdStartY;

        const cmdDragHandle = document.createElement('div');
        cmdDragHandle.style.position = 'absolute';
        cmdDragHandle.style.top = '0';
        cmdDragHandle.style.left = '0';
        cmdDragHandle.style.width = '100%';
        cmdDragHandle.style.height = '30px';
        cmdDragHandle.style.cursor = 'move';
        cmdDragHandle.style.backgroundColor = 'rgb(0 0 0 / 20%)';
        commandWindow.insertBefore(cmdDragHandle, commandWindow.firstChild);

        cmdDragHandle.addEventListener('mousedown', initCmdDrag, false);
        window.addEventListener('mousemove', doCmdDrag, false);
        window.addEventListener('mouseup', stopCmdDrag, false);

        function initCmdDrag(e) {
            isDraggingCmd = true;
            cmdStartX = e.clientX - commandWindow.offsetLeft;
            cmdStartY = e.clientY - commandWindow.offsetTop;
        }

        function doCmdDrag(e) {
            if (!isDraggingCmd) return;

            let newX = e.clientX - cmdStartX;
            let newY = e.clientY - cmdStartY;

            // Confine the window within the viewport
            const rect = commandWindow.getBoundingClientRect();
            newX = Math.max(0, Math.min(newX, window.innerWidth - rect.width));
            newY = Math.max(0, Math.min(newY, window.innerHeight - rect.height));

            commandWindow.style.left = newX + 'px';
            commandWindow.style.top = newY + 'px';
            commandWindow.style.transform = 'none';
        }

        function stopCmdDrag() {
            isDraggingCmd = false;
        }
    }

    // Ensure the window stays within bounds when the browser is resized
    window.addEventListener('resize', adjustCommandWindowPosition);
    function adjustCommandWindowPosition() {
        if (commandWindow) {
            const rect = commandWindow.getBoundingClientRect();
            let newX = rect.left;
            let newY = rect.top;

            if (rect.right > window.innerWidth) {
                newX = window.innerWidth - rect.width;
            }
            if (rect.bottom > window.innerHeight) {
                newY = window.innerHeight - rect.height;
            }

            newX = Math.max(0, newX);
            newY = Math.max(0, newY);

            commandWindow.style.left = newX + 'px';
            commandWindow.style.top = newY + 'px';
        }
    }

})();