Addon + for Bodega Bot

Adds functionality to Bodega Bot Users including a game window

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

function _newArrowCheck(n, r) {
  if (n !== r) throw new TypeError("Cannot instantiate an arrow function");
}
// ==UserScript==
// @name         Addon + for Bodega Bot
// @namespace    http://tampermonkey.net/
// @version      3.5
// @description  Adds functionality to Bodega Bot Users including a game window
// @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
    var 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
    var 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
    var 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
    var 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' },
        { label: '🎮', action: toggleGameWindow, title: 'Toggle Game Window' }
    ];

    // Create additional buttons
    buttonConfigs.forEach(config => {
        var 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
            var 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', () => {
        var 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
    var isDraggingMain = false;
    var 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) {
            var x = e.clientX - mainOffsetX;
            var y = e.clientY - mainOffsetY;

            // Confine within viewport
            var maxX = window.innerWidth - mainButton.offsetWidth;
            var 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 => {
            var link = document.createElement('a');
            link.download = 'screenshot.png';
            link.href = canvas.toDataURL();
            link.click();

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

    // GroupTube functionality
    var groupTubeWindow = null;

    function toggleGroupTube() {
        if (groupTubeWindow) {
            groupTubeWindow.style.display = groupTubeWindow.style.display === 'none' ? 'block' : 'none';
            var status = groupTubeWindow.style.display === 'none' ? 'hidden' : 'visible';
            var feedbackButton = Array.from(additionalButtons.children).find(button => button.title === 'Toggle GroupTube');
            if (feedbackButton) {
                feedbackButton.title = 'Toggle GroupTube';
            }
            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';

        var 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);

        var 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 = '14px';
        closeButton.style.cursor = 'pointer';
        closeButton.style.padding = '5px 10px';
        closeButton.style.borderRadius = '5px';
        closeButton.onclick = () => groupTubeWindow.style.display = 'none';
        groupTubeWindow.appendChild(closeButton);

        container.appendChild(groupTubeWindow);

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

        // Add resize functionality to GroupTube window
        var resizeHandle = document.createElement('div');
        resizeHandle.style.position = 'absolute';
        resizeHandle.style.bottom = '0';
        resizeHandle.style.right = '0';
        resizeHandle.style.width = '20px';
        resizeHandle.style.height = '20px';
        resizeHandle.style.cursor = 'se-resize';
        resizeHandle.style.backgroundColor = 'rgb(0 0 0 / 20%)';
        groupTubeWindow.appendChild(resizeHandle);

        dragHandle.addEventListener('mousedown', initDrag, false);
        resizeHandle.addEventListener('mousedown', initResize, false);
        window.addEventListener('mousemove', doDragResize, false);
        window.addEventListener('mouseup', stopDragResize, false);

        var isDragging = false;
        var isResizing = false;
        var startX, startY, startWidth, startHeight;

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

        function initResize(e) {
            isResizing = true;
            startX = e.clientX;
            startY = e.clientY;
            startWidth = parseInt(document.defaultView.getComputedStyle(groupTubeWindow).width, 10);
            startHeight = parseInt(document.defaultView.getComputedStyle(groupTubeWindow).height, 10);
        }

        function doDragResize(e) {
            if (isDragging) {
                var newX = e.clientX - startX;
                var newY = e.clientY - startY;
                newX = Math.max(0, Math.min(newX, window.innerWidth - groupTubeWindow.offsetWidth));
                newY = Math.max(0, Math.min(newY, window.innerHeight - groupTubeWindow.offsetHeight));
                groupTubeWindow.style.left = newX + 'px';
                groupTubeWindow.style.top = newY + 'px';
            }
            if (isResizing) {
                var newWidth = startWidth + e.clientX - startX;
                var newHeight = startHeight + e.clientY - startY;
                newWidth = Math.max(200, Math.min(newWidth, window.innerWidth - groupTubeWindow.offsetLeft));
                newHeight = Math.max(200, Math.min(newHeight, window.innerHeight - groupTubeWindow.offsetTop));
                groupTubeWindow.style.width = newWidth + 'px';
                groupTubeWindow.style.height = newHeight + 'px';
            }
        }

        function stopDragResize() {
            isDragging = false;
            isResizing = false;
        }
    }

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

    function reloadGroupTube() {
        if (groupTubeWindow) {
            var iframe = groupTubeWindow.querySelector('iframe');
            if (iframe) {
                iframe.src = iframe.src;
            }
        }
    }
    // Game Window functionality
    var gameWindow = null;

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

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

var urlBar = document.createElement('input');
urlBar.type = 'text';
urlBar.placeholder = 'Enter game URL';
urlBar.style.width = 'calc(80% - 100px)';
urlBar.style.padding = '5px';
urlBar.style.margin = '5px';
        urlBar.value = 'https://skribblio.online/skribbl-games-io';

var loadButton = document.createElement('button');
loadButton.innerText = 'Load';
loadButton.style.width = 'calc(30% - 100px)';
loadButton.style.padding = '5px';
loadButton.style.margin = '5px';

var iframe = document.createElement('iframe');
iframe.style.width = '100%';
iframe.style.height = 'calc(100% - 50px)';
iframe.style.border = 'none';
iframe.style.marginTop = '10px';
iframe.src = 'https://skribblio.online/skribbl-games-io';

loadButton.onclick = function() {
    iframe.src = urlBar.value;
};

var 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 = '14px';
        closeButton.style.cursor = 'pointer';
        closeButton.style.padding = '5px 10px';
        closeButton.style.borderRadius = '5px';
        closeButton.onclick = () => gameWindow.style.display = 'none';

        gameWindow.appendChild(urlBar);
        gameWindow.appendChild(loadButton);
        gameWindow.appendChild(iframe);
        gameWindow.appendChild(closeButton);

        container.appendChild(gameWindow);

        // Add drag functionality to Game window
        var dragHandle = document.createElement('div');
        dragHandle.style.position = 'absolute';
        dragHandle.style.top = '0';
        dragHandle.style.left = '0';
        dragHandle.style.width = 'calc(100% - 30px)';
        dragHandle.style.height = '5px';
        dragHandle.style.cursor = 'move';
        gameWindow.appendChild(dragHandle);

        // Add resize functionality to Game window
        var resizeHandle = document.createElement('div');
        resizeHandle.style.position = 'absolute';
        resizeHandle.style.bottom = '0';
        resizeHandle.style.right = '0';
        resizeHandle.style.width = '20px';
        resizeHandle.style.height = '20px';
        resizeHandle.style.cursor = 'se-resize';
        resizeHandle.style.backgroundColor = 'rgb(0 0 0 / 20%)';
        gameWindow.appendChild(resizeHandle);

        dragHandle.addEventListener('mousedown', initGameDrag, false);
        resizeHandle.addEventListener('mousedown', initGameResize, false);
        window.addEventListener('mousemove', doGameDragResize, false);
        window.addEventListener('mouseup', stopGameDragResize, false);

        var isGameDragging = false;
        var isGameResizing = false;
        var gameStartX, gameStartY, gameStartWidth, gameStartHeight;

        function initGameDrag(e) {
            isGameDragging = true;
            gameStartX = e.clientX - gameWindow.offsetLeft;
            gameStartY = e.clientY - gameWindow.offsetTop;
        }

        function initGameResize(e) {
            isGameResizing = true;
            gameStartX = e.clientX;
            gameStartY = e.clientY;
            gameStartWidth = parseInt(document.defaultView.getComputedStyle(gameWindow).width, 10);
            gameStartHeight = parseInt(document.defaultView.getComputedStyle(gameWindow).height, 10);
        }

        function doGameDragResize(e) {
            if (isGameDragging) {
                var newX = e.clientX - gameStartX;
                var newY = e.clientY - gameStartY;
                newX = Math.max(0, Math.min(newX, window.innerWidth - gameWindow.offsetWidth));
                newY = Math.max(0, Math.min(newY, window.innerHeight - gameWindow.offsetHeight));
                gameWindow.style.left = newX + 'px';
                gameWindow.style.top = newY + 'px';
            }
            if (isGameResizing) {
                var newWidth = gameStartWidth + e.clientX - gameStartX;
                var newHeight = gameStartHeight + e.clientY - gameStartY;
                newWidth = Math.max(200, Math.min(newWidth, window.innerWidth - gameWindow.offsetLeft));
                newHeight = Math.max(200, Math.min(newHeight, window.innerHeight - gameWindow.offsetTop));
                gameWindow.style.width = newWidth + 'px';
                gameWindow.style.height = newHeight + 'px';
            }
        }

        function stopGameDragResize() {
            isGameDragging = false;
            isGameResizing = false;
        }
    }

    // Command functionality
    var 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'
        ]
    };

    var 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)
        var 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';

        var 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 (let [category, categoryCommands] of Object.entries(commands)) {
            let 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 => {
                let commandButton = document.createElement('button');
                commandButton.innerText
                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 and resizable
        var isDraggingCmd = false;
        var isResizingCmd = false;
        var cmdStartX, cmdStartY, cmdStartWidth, cmdStartHeight;

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

        var cmdResizeHandle = document.createElement('div');
        cmdResizeHandle.style.position = 'absolute';
        cmdResizeHandle.style.bottom = '0';
        cmdResizeHandle.style.right = '0';
        cmdResizeHandle.style.width = '20px';
        cmdResizeHandle.style.height = '20px';
        cmdResizeHandle.style.cursor = 'se-resize';
        cmdResizeHandle.style.backgroundColor = 'rgb(0 0 0 / 20%)';
        commandWindow.appendChild(cmdResizeHandle);

        cmdDragHandle.addEventListener('mousedown', initCmdDrag, false);
        cmdResizeHandle.addEventListener('mousedown', initCmdResize, false);
        window.addEventListener('mousemove', doCmdDragResize, false);
        window.addEventListener('mouseup', stopCmdDragResize, false);

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

        function initCmdResize(e) {
            isResizingCmd = true;
            cmdStartX = e.clientX;
            cmdStartY = e.clientY;
            cmdStartWidth = parseInt(document.defaultView.getComputedStyle(commandWindow).width, 10);
            cmdStartHeight = parseInt(document.defaultView.getComputedStyle(commandWindow).height, 10);
        }

        function doCmdDragResize(e) {
            if (isDraggingCmd) {
                var newX = e.clientX - cmdStartX;
                var newY = e.clientY - cmdStartY;
                newX = Math.max(0, Math.min(newX, window.innerWidth - commandWindow.offsetWidth));
                newY = Math.max(0, Math.min(newY, window.innerHeight - commandWindow.offsetHeight));
                commandWindow.style.left = newX + 'px';
                commandWindow.style.top = newY + 'px';
                commandWindow.style.transform = 'none';
            }
            if (isResizingCmd) {
                var newWidth = cmdStartWidth + e.clientX - cmdStartX;
                var newHeight = cmdStartHeight + e.clientY - cmdStartY;
                newWidth = Math.max(200, Math.min(newWidth, window.innerWidth - commandWindow.offsetLeft));
                newHeight = Math.max(200, Math.min(newHeight, window.innerHeight - commandWindow.offsetTop));
                commandWindow.style.width = newWidth + 'px';
                commandWindow.style.height = newHeight + 'px';
                commandWindow.style.maxWidth = 'none';
                commandWindow.style.maxHeight = 'none';
            }
        }

        function stopCmdDragResize() {
            isDraggingCmd = false;
            isResizingCmd = false;
        }
    }

    // Ensure the window stays within bounds when the browser is resized
    window.addEventListener('resize', adjustWindowPositions);

    function adjustWindowPositions() {
        if (commandWindow) {
            var rect = commandWindow.getBoundingClientRect();
            var newX = rect.left;
            var newY = rect.top;
            var newWidth = rect.width;
            var newHeight = rect.height;

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

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

            commandWindow.style.left = newX + 'px';
            commandWindow.style.top = newY + 'px';
            commandWindow.style.width = newWidth + 'px';
            commandWindow.style.height = newHeight + 'px';
        }

        if (groupTubeWindow) {
            var rect = groupTubeWindow.getBoundingClientRect();
            var newX = rect.left;
            var newY = rect.top;
            var newWidth = rect.width;
            var newHeight = rect.height;

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

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

            groupTubeWindow.style.left = newX + 'px';
            groupTubeWindow.style.top = newY + 'px';
            groupTubeWindow.style.width = newWidth + 'px';
            groupTubeWindow.style.height = newHeight + 'px';
        }

    if (gameWindow) {
        var rect = gameWindow.getBoundingClientRect();
        var newX = rect.left;
        var newY = rect.top;
        var newWidth = rect.width;
        var newHeight = rect.height;

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

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

        gameWindow.style.left = newX + 'px';
        gameWindow.style.top = newY + 'px';
        gameWindow.style.width = newWidth + 'px';
        gameWindow.style.height = newHeight + 'px';

        }
    }
})();