您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork镜像 is available in English.
Интерфейс для управления командами ботов с поддержкой категорий и сортировки
当前为
// ==UserScript== // @name BotMenu Client Indev // @namespace http://tampermonkey.net/ // @version 4.2 // @description:ru Интерфейс для управления командами ботов с поддержкой категорий и сортировки // @description:en Interface for bot team management with support for categorization and sorting // @author gtnntg // @match *://multiplayerpiano.net/* // @license ARC // @grant none // @description Интерфейс для управления командами ботов с поддержкой категорий и сортировки // ==/UserScript== /*global MPP*/ (function () { 'use strict'; const botsData = {}; // Хранение данных ботов { botId: { name, categories, userRank } } // Создаём контейнер для вкладок и кнопок const container = document.createElement('div'); container.id = 'bot-menu'; container.style.position = 'fixed'; container.style.bottom = '20px'; container.style.right = '10px'; container.style.width = '300px'; container.style.maxHeight = '500px'; container.style.minHeight = '50px'; container.style.backgroundColor = '#121212'; container.style.color = '#fff'; container.style.border = '1px solid #333'; container.style.borderRadius = '8px'; container.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.5)'; container.style.padding = '10px'; container.style.overflowY = 'auto'; container.style.zIndex = '10000'; container.style.display = 'block'; document.body.appendChild(container); // Кнопка сворачивания const toggleButton = document.createElement('button'); toggleButton.innerText = '⮝'; toggleButton.style.alignSelf = 'flex-end'; toggleButton.style.backgroundColor = '#333'; toggleButton.style.color = '#fff'; toggleButton.style.border = 'none'; toggleButton.style.borderRadius = '4px'; toggleButton.style.cursor = 'pointer'; toggleButton.style.marginBottom = '10px'; toggleButton.onclick = toggleContainer; container.appendChild(toggleButton); const QButton = document.createElement('button'); QButton.innerText = '🔎'; QButton.style.alignSelf = 'flex'; QButton.style.backgroundColor = '#333'; QButton.style.color = '#fff'; QButton.style.border = 'none'; QButton.style.borderRadius = '4px'; QButton.style.marginLeft = '10px'; QButton.style.cursor = 'pointer'; QButton.style.marginBottom = '10px'; QButton.onclick = Requestcommands; container.appendChild(QButton); const tabs = document.createElement('div'); // Контейнер для вкладок tabs.id = 'bot-tabs'; tabs.style.display = 'flex'; tabs.style.flexWrap = 'wrap'; tabs.style.marginBottom = '10px'; container.appendChild(tabs); const commandsContainer = document.createElement('div'); // Контейнер для кнопок команд commandsContainer.id = 'commands-container'; commandsContainer.style.display = 'none'; commandsContainer.style.padding = '10px'; commandsContainer.style.borderTop = '1px solid #555'; commandsContainer.style.marginTop = '10px'; container.appendChild(commandsContainer); let isCollapsed = false; // Сворачивание/разворачивание контейнера function toggleContainer() { isCollapsed = !isCollapsed; if (isCollapsed) { tabs.style.display = 'none'; commandsContainer.style.display = 'none'; toggleButton.innerText = '⮟'; container.style.maxHeight = '50px'; } else { tabs.style.display = 'flex'; toggleButton.innerText = '⮝'; container.style.maxHeight = '500px'; } } function Requestcommands() { MPP.client.sendArray([{ m: "custom", data: { m: "BotMenuClient", language: localStorage.getItem('language'), type: "Requestcommands" }, target: { mode: "subscribed" }, }]); sendmsg('Запрос на команды был отправлен всем ботам находящиеся в данной комнате','Bot Menu Client','Bot Menu Client','#0066ff') } function botsend(botId,message) { MPP.client.sendArray([{ m: "custom", data: { m: "BotMenuClient", language: localStorage.getItem('language'), type: "msg", message:message, }, target: { mode: "id" , id: botId}, }]); } function sendmsg(msg,name,id,color) { MPP.chat.receive({ "m": "a", "t": Date.now(), "a": msg, "p": { "_id": id, "name": name, "color": color, "id": id } }); } // Функция для добавления новой вкладки function addTab(botId, botName) { const tab = document.createElement('button'); tab.innerText = botName; tab.style.padding = '5px 10px'; tab.style.margin = '5px 5px 0 0'; tab.style.border = '1px solid #444'; tab.style.borderRadius = '5px'; tab.style.backgroundColor = '#2e2e2e'; tab.style.color = '#fff'; tab.style.cursor = 'pointer'; tab.style.flex = '1 0 auto'; tab.setAttribute('data-id', botId); // Присваиваем data-id для идентификации tab.onclick = () => showCommands(botId); tabs.appendChild(tab); } // Функция для отображения команд function showCommands(botId) { commandsContainer.innerHTML = ''; // Очищаем контейнер команд commandsContainer.style.display = 'block'; // Показываем контейнер const botData = botsData[botId]; if (!botData) return; // Если данных нет, выходим // Сортируем категории по позиции botData.categories.sort((a, b) => a.position - b.position); // Обрабатываем каждую категорию botData.categories.forEach((category) => { if (botData.userRank >= category.requiredRank) { // Проверяем ранг пользователя const categoryTitle = document.createElement('h4'); categoryTitle.innerText = category.name; // Название категории categoryTitle.style.marginTop = '10px'; categoryTitle.style.color = category.categoryColor ? category.categoryColor : '#aaa'; commandsContainer.appendChild(categoryTitle); // Обрабатываем команды внутри категории category.commands.forEach((cmd) => { const commandBlock = document.createElement('div'); // Блок для команды commandBlock.style.display = 'flex'; commandBlock.style.flexDirection = 'column'; commandBlock.style.marginBottom = '10px'; const btn = document.createElement('button'); // Кнопка команды btn.innerText = cmd.label; btn.title = cmd.description; btn.style.padding = '8px'; btn.style.border = '1px solid #ccc'; btn.style.borderRadius = '5px'; btn.style.backgroundColor = '#e0e0e0'; btn.style.cursor = 'pointer'; const inputs = []; // Массив для хранения полей ввода // Если команда имеет параметры, создаем поля ввода if (cmd.parameters && cmd.parameters.length > 0) { cmd.parameters.forEach(param => { const Input = document.createElement('input'); Input.type = 'text'; Input.placeholder = `Введите ${param}`; Input.style.marginBottom = '5px'; Input.style.backgroundColor = '#333'; Input.style.color = '#fff'; Input.style.borderRadius = '4px'; commandBlock.appendChild(Input); inputs.push(Input); // Добавляем поле в массив }); } // Обработчик нажатия на кнопку btn.onclick = () => { if (!cmd.message) { let finalCommand = cmd.command; // Изначальная команда // Проверяем, заполнены ли все параметры for (let i = 0; i < inputs.length; i++) { const value = inputs[i].value.trim(); if (!value) { sendmsg(`Параметр "${cmd.parameters[i]}" не может быть пустым!`,'Bot Menu Client (Error)','Bot Menu Client','#0066ff') return; // Отменяем выполнение, если параметр пуст } finalCommand = finalCommand.replace(`[${cmd.parameters[i]}]`, value); // Заменяем параметр } // Вставляем готовую команду в чат const chatInput = document.querySelector('#chat-input'); if (chatInput) { chatInput.value = finalCommand; chatInput.focus(); // Устанавливаем фокус на чат } else { console.error('Chat input not found!'); } } else { let msguser = cmd.message botsend(botId,msguser) } }; commandBlock.appendChild(btn); // Добавляем кнопку в блок команды commandsContainer.appendChild(commandBlock); // Добавляем блок команды в контейнер }); } }); } // Делает контейнер перетаскиваемым class BotChatPanel { constructor() { this.createPanel(); } createPanel() { this.panel = document.createElement("div"); this.panel.id = "bot-chat-panel"; this.panel.style.position = "fixed"; this.panel.style.bottom = "20px"; this.panel.style.right = "20px"; this.panel.style.width = "300px"; this.panel.style.height = "400px"; this.panel.style.background = "#222"; this.panel.style.color = "#fff"; this.panel.style.borderRadius = "10px"; this.panel.style.padding = "10px"; this.panel.style.overflowY = "auto"; this.panel.style.display = "none"; this.panel.style.boxShadow = "0 0 10px rgba(0,0,0,0.5)"; const closeButton = document.createElement("button"); closeButton.innerText = "✖"; closeButton.style.position = "absolute"; closeButton.style.top = "5px"; closeButton.style.right = "5px"; closeButton.style.background = "transparent"; closeButton.style.color = "#fff"; closeButton.style.border = "none"; closeButton.style.cursor = "pointer"; closeButton.onclick = () => this.panel.style.display = "none"; this.panel.appendChild(closeButton); document.body.appendChild(this.panel); } showMessage(botName, botColor, message) { const messageDiv = document.createElement("div"); messageDiv.style.padding = "5px"; messageDiv.style.borderBottom = "1px solid #444"; const botLabel = document.createElement("span"); botLabel.innerText = `[${botName}] `; botLabel.style.color = botColor; botLabel.style.fontWeight = "bold"; const textSpan = document.createElement("span"); textSpan.innerText = message; messageDiv.appendChild(botLabel); messageDiv.appendChild(textSpan); this.panel.appendChild(messageDiv); this.panel.style.display = "block"; } } // Создаем панель const botChat = new BotChatPanel(); // Функция для обработки сообщений с directsend function handleCommandResponse(response) { if (response.directsend === "true") { botChat.showMessage(response.botName, response.botColor, response.message); } else { console.log("Обычный ответ в чат", response.message); } } function makeDraggable(element) { let offsetX = 0, offsetY = 0, mouseDown = false; element.addEventListener('mousedown', (e) => { mouseDown = true; offsetX = e.clientX - element.offsetLeft; offsetY = e.clientY - element.offsetTop; }); document.addEventListener('mousemove', (e) => { if (!mouseDown) return; element.style.left = `${e.clientX - offsetX}px`; element.style.top = `${e.clientY - offsetY}px`; }); document.addEventListener('mouseup', () => { mouseDown = false; }); } makeDraggable(container); // Обработчик входящих сообщений MPP.client.on('custom', (data) => { if (!data.data || data.data.m !== 'BotMenu') return; const { botName, categories, userRank } = data.data; const botId = data.p; if (!botId || !botName || !Array.isArray(categories)) { console.debug('Invalid bot data received:', data.data); return; } // Проверяем, есть ли данные для бота if (!botsData[botId]) { botsData[botId] = { name: botName, categories: [], userRank }; // Обрабатываем категории categories.forEach((category) => { const { categoryName, position, commands, requiredRank } = category; botsData[botId].categories.push({ name: categoryName, position, commands, requiredRank }); }); addTab(botId, botName); // Добавляем вкладку для бота sendmsg(`Данные были получены с ${botName}`,'Bot Menu Client','Bot Menu Client','#0066ff') } else { // Обновляем существующие данные botsData[botId].categories = categories.map((category) => ({ name: category.categoryName, position: category.position, commands: category.commands, requiredRank: category.requiredRank })); botsData[botId].userRank = userRank; sendmsg(`Данные бота ${botName} были обновлены`,'Bot Menu Client','Bot Menu Client','#0066ff'); } }); // При подключении отправляем +custom MPP.client.on('hi', () => { MPP.client.sendArray([{ m: '+custom' }]); }); })();