您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds functionality to Bodega Bot Users including a game window
当前为
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'; } } })();