diff --git a/ChatLogger.js b/ChatLogger.js index c60b39d..6d6b0db 100644 --- a/ChatLogger.js +++ b/ChatLogger.js @@ -11,6 +11,7 @@ const server = http.createServer(app); const io = new Server(server); const vec3 = require('vec3'); + const reset = false; // Create an interface for reading input from the console const rl = readline.createInterface({ @@ -24,7 +25,58 @@ const scriptsPath = path.join(__dirname, 'scripts'); return fs.readdirSync(scriptsPath); }; + + const getConfigFiles = () => { + const configsPath = path.join(__dirname, 'configs'); + return fs.readdirSync(configsPath); + }; + + const getConfigContent = (fileName) => { + const filePath = path.join(__dirname, 'configs', fileName); + return fs.readFileSync(filePath, 'utf8'); + }; + + // Function to edit a file in the /configs/ directory + const editConfigFile = (data) => { + const filePath = path.join(__dirname, 'configs', data.name); + + // Check if data.code is already an object + const jsonData = typeof data.code === 'string' ? JSON.parse(data.code) : data.code; + + const txtContent = Object.entries(jsonData) + .map(([key, value]) => `${key}: ${value}`) + .join('\n'); + + fs.writeFileSync(filePath, txtContent, 'utf8'); + }; + + // Function to delete a file from the /configs/ directory + const deleteConfigFile = (fileName) => { + const filePath = path.join(__dirname, 'configs', fileName); + fs.unlinkSync(filePath); + }; + + // Function to create a new file in the /configs/ directory + const createConfigFile = (data) => { + const filePath = path.join(__dirname, 'configs', data.name); + + // Check if data.code is already an object + const jsonData = typeof data.code === 'string' ? JSON.parse(data.code) : data.code; + + const txtContent = Object.entries(jsonData) + .map(([key, value]) => `${key}: ${value}`) + .join('\n'); + + fs.writeFileSync(filePath, txtContent, 'utf8'); + }; + +const renameConfigFile = (data) => { + const oldPath = path.join(__dirname, 'configs', data.oldName); + const newPath = path.join(__dirname, 'configs', data.newName); + fs.renameSync(oldPath, newPath); +} + const getScriptContent = (fileName) => { const filePath = path.join(__dirname, 'scripts', fileName); return fs.readFileSync(filePath, 'utf8'); @@ -87,6 +139,10 @@ const renameScriptFile = (data) => { // Function to get bot settings from user input const getBotSettingsFromUser = async () => { + if (reset == true) { + return config; + } + else { const prefix = (await askQuestion('Enter a prefix for commands ("!!" if left empty): ') || '!!'); const serverIP = await askQuestion('Enter server IP: '); const serverPort = (await askQuestion('Enter server port (25565 if left empty): ')) || '25565'; @@ -148,6 +204,7 @@ const renameScriptFile = (data) => { prefix, }; }; + }; // Delay function const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); @@ -162,9 +219,10 @@ const renameScriptFile = (data) => { let usernames = []; // Initialize usernames array if (configFileName) { - const configPath = path.join(__dirname, 'configs', configFileName); + const configPath = path.join(__dirname, 'configs', `${configFileName}.clc`); if (fs.existsSync(configPath)) { config = readConfigFile(configPath); + io.emit('config.selected', configPath) console.log(config) // Parse config data properly and set defaults @@ -199,7 +257,7 @@ const renameScriptFile = (data) => { }; io.emit('config', config); } else { - console.log(chalk.red(`Config file "${configFileName}" not found in /configs folder.`)); + console.log(chalk.red(`Config file "${configFileName.replace('.clc', '')}" not found in /configs folder.`)); return; } } else { @@ -296,6 +354,7 @@ const renameScriptFile = (data) => { } break; + case 'br': bot.dig(bot.blockAtCursor(7)); break; @@ -672,6 +731,38 @@ const { } }); + socket.on('config.set', (data) => { + config = data; + io.emit('config', config); + console.log(config) + }); + + socket.on('config.new', (data) => { + createConfigFile(data) + }); + + socket.on('config.rename', (data) => { + renameConfigFile(data) + }); + + socket.on('config.edit', (data) => { + editConfigFile(data) + }); + + socket.on('config.delete', (data) => { + deleteConfigFile(data) + }); + + socket.on('config.read', (data) => { + const configContent = readConfigFile(data) + socket.emit('config.send', configContent) + }); + + io.emit('config.list', getConfigFiles()); + socket.on('config.get_list', () => { + socket.emit('config.list', getConfigFiles()); + }); + socket.on('script.new', (data) => { createScriptFile(data) }); @@ -752,6 +843,7 @@ const { //actually fixed it now // Listen for commands from trusted users in chat + bot.on('chat', (username, message) => { if (message.startsWith(prefix) && trustedUsers.includes(username)) { const command = message.slice(prefix.length).trim(); @@ -797,4 +889,12 @@ const { }; // Start the bot - runBot().catch(console.error); \ No newline at end of file + runBot().catch(console.error); +io.on('config.set', (configData) => { + bots.forEach(bot => bot.quit()); + bots = []; + reset = true; + config = configData; + + runBot().catch(console.error); + }) \ No newline at end of file diff --git a/configs/Example.clc b/configs/Example.clc new file mode 100644 index 0000000..f69d56c --- /dev/null +++ b/configs/Example.clc @@ -0,0 +1,11 @@ +serverIP: localhost +serverPort: 25565 +version: 1.20.4 +bot_amount: 1 +useLogin: false +username: Bot +password: Password +useFiltering: true +whitelistedWords: word1, word2 +trustedUsers: player1, player2 +prefix: && \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 95afeb0..e787dac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "express": "^4.21.1", "fs": "^0.0.1-security", "http": "^0.0.1-security", - "mineflayer": "^4.0.0", + "mineflayer": "^4.21.0", "proxy-agent": "^6.4.0", "readline": "^1.3.0", "socket.io": "^4.8.0", @@ -1345,9 +1345,9 @@ } }, "node_modules/minecraft-data": { - "version": "3.69.0", - "resolved": "https://registry.npmjs.org/minecraft-data/-/minecraft-data-3.69.0.tgz", - "integrity": "sha512-FGpjH/8ABfIuHm53253MZZVLwfVgLuRl4wrYz91TNoT14a+pMPH7igNxdpBmKayhiO7VO0ox/ZISkCOj6S/isA==", + "version": "3.76.0", + "resolved": "https://registry.npmjs.org/minecraft-data/-/minecraft-data-3.76.0.tgz", + "integrity": "sha512-aqWonoe5h7to5iEfjUmG5r5F0K3FwrnF9c1YzxbALyOyRUujm2a/G5GJ4TfuoEslVp9dJ7OYVHLJfOS9aD/Twg==", "license": "MIT" }, "node_modules/minecraft-folder-path": { @@ -1357,9 +1357,9 @@ "license": "MIT" }, "node_modules/minecraft-protocol": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/minecraft-protocol/-/minecraft-protocol-1.47.0.tgz", - "integrity": "sha512-IHL8faXLLIWv1O+2v2NgyKlooilu/OiSL9orI8Kqed/rZvVOrFPzs2PwMAYjpQX9gxLPhiSU19KqZ8CjfNuqhg==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/minecraft-protocol/-/minecraft-protocol-1.49.0.tgz", + "integrity": "sha512-NqaW4mdcFSdfozNRzM4pZC18LrdpeUCWUDv+Ozem9VsPsHCx+u+pfI3wkxZPOmLfC3f1nfKiF/f6EwK+VxovoA==", "license": "BSD-3-Clause", "dependencies": { "@types/readable-stream": "^4.0.0", @@ -1369,7 +1369,7 @@ "endian-toggle": "^0.0.0", "lodash.get": "^4.1.2", "lodash.merge": "^4.3.0", - "minecraft-data": "^3.55.0", + "minecraft-data": "^3.75.0", "minecraft-folder-path": "^1.2.0", "node-fetch": "^2.6.1", "node-rsa": "^0.4.2", @@ -1377,7 +1377,7 @@ "prismarine-chat": "^1.10.0", "prismarine-nbt": "^2.5.0", "prismarine-realms": "^1.2.0", - "protodef": "^1.8.0", + "protodef": "^1.17.0", "readable-stream": "^4.1.0", "uuid-1345": "^1.0.1", "yggdrasil": "^1.4.0" @@ -1387,26 +1387,26 @@ } }, "node_modules/mineflayer": { - "version": "4.20.1", - "resolved": "https://registry.npmjs.org/mineflayer/-/mineflayer-4.20.1.tgz", - "integrity": "sha512-QMMNPx4IyZE7ydAzjvGLQLCnQNUOfkk1qVZKxTTS9q3qPTAewz4GhsVUBtbQ8LSbHthe5RcQ1Sgxs4wlIma/Qw==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/mineflayer/-/mineflayer-4.21.0.tgz", + "integrity": "sha512-0DiMOVan0u9ikZRzeTwXwXRJ+wXxsUTooG6TDVRKBYKAy99yRvIMVCrbarUcZuGhhQdEyeItC3+VwyfbU539NA==", "license": "MIT", "dependencies": { - "minecraft-data": "^3.56.0", - "minecraft-protocol": "^1.47.0", + "minecraft-data": "^3.76.0", + "minecraft-protocol": "^1.49.0", "prismarine-biome": "^1.1.1", "prismarine-block": "^1.17.0", "prismarine-chat": "^1.7.1", "prismarine-chunk": "^1.34.0", "prismarine-entity": "^2.3.0", - "prismarine-item": "^1.14.0", + "prismarine-item": "^1.15.0", "prismarine-nbt": "^2.0.0", "prismarine-physics": "^1.8.0", "prismarine-recipe": "^1.3.0", - "prismarine-registry": "^1.5.0", + "prismarine-registry": "^1.8.0", "prismarine-windows": "^2.9.0", "prismarine-world": "^3.6.0", - "protodef": "^1.14.0", + "protodef": "1.17.0", "typed-emitter": "^1.0.0", "vec3": "^0.1.7" }, @@ -1666,9 +1666,9 @@ } }, "node_modules/prismarine-item": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/prismarine-item/-/prismarine-item-1.14.0.tgz", - "integrity": "sha512-udQHYGJ05klFe8Kkc0TOmwoXj5Xl1ZPgHVoMbGUAFB9exN4TFxEa1A39vkSYhxP5Et9PNufQQvFBFVom0nXikA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/prismarine-item/-/prismarine-item-1.15.0.tgz", + "integrity": "sha512-DysyiCzaI8S7PpRLFylAZnQo2CppXiBbaUp+8rhK+EzvzmMdS+D1/oETQm9ysB5Jw9eCer6iWGMgzZXxJE5+/w==", "license": "MIT", "dependencies": { "prismarine-nbt": "^2.0.0", @@ -1715,12 +1715,12 @@ } }, "node_modules/prismarine-registry": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/prismarine-registry/-/prismarine-registry-1.7.0.tgz", - "integrity": "sha512-yyva0FpWI078nNeMhx8ekVza5uUTYhEv+C+ADu3wUQXiG8qhXkvrf0uzsnhTgZL8BLdsi2axgCEiKw9qSKIuxQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/prismarine-registry/-/prismarine-registry-1.8.0.tgz", + "integrity": "sha512-BLvvjuVdjp2wQQ6c0wMnc5oszY+dUxCVKvXVBRNK51qYE1X239imzJIRT6gkLC8nFSQR6mtcuOENIBwoIHLs0A==", "license": "MIT", "dependencies": { - "minecraft-data": "^3.0.0", + "minecraft-data": "^3.70.0", "prismarine-nbt": "^2.0.0" } }, @@ -1766,15 +1766,15 @@ } }, "node_modules/protodef": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/protodef/-/protodef-1.15.0.tgz", - "integrity": "sha512-bZ2Omw8dT+DACjJHLrBWZlqN4MlT9g9oSpJDdkUAJOStUzgJp+Zn42FJfPUdwutUxjaxA0PftN0PDlNa2XbneA==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/protodef/-/protodef-1.17.0.tgz", + "integrity": "sha512-mnpNPV3xwu63u3NwZuXM1RCp979vjHxUGHzVrb6dxbvof5Fx+b8Rs0G0c3xtEuFDreGAMWS7VrlNkDUDBMsFWQ==", "license": "MIT", "dependencies": { "lodash.get": "^4.4.2", "lodash.reduce": "^4.6.0", "protodef-validator": "^1.3.0", - "readable-stream": "^3.0.3" + "readable-stream": "^4.4.0" }, "engines": { "node": ">=14" @@ -1792,20 +1792,6 @@ "protodef-validator": "cli.js" } }, - "node_modules/protodef/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -2304,12 +2290,6 @@ "punycode": "^2.1.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", diff --git a/package.json b/package.json index 7786866..1e94780 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "express": "^4.21.1", "fs": "^0.0.1-security", "http": "^0.0.1-security", - "mineflayer": "^4.0.0", + "mineflayer": "^4.21.0", "proxy-agent": "^6.4.0", "readline": "^1.3.0", "socket.io": "^4.8.0", diff --git a/public/bots/index.html b/public/bots/index.html index a65092c..5a4c148 100644 --- a/public/bots/index.html +++ b/public/bots/index.html @@ -14,7 +14,7 @@

ChatLogger

- + diff --git a/public/configs/index.html b/public/configs/index.html new file mode 100644 index 0000000..bb4c670 --- /dev/null +++ b/public/configs/index.html @@ -0,0 +1,82 @@ + + + + + + + + + ChatLogger Control Panel + + +
+
+

ChatLogger

+ + + + + + +
+ +
+
+
+
+ Server IP: +
+
+ Server Port: +
+
+ Version: +
+
+ Bot Amount: +
+
+ Use Login: +
+
+ Password: +
+
+ Bot Username: +
+
+ Use Filtering: +
+
+ Whitelisted Words: +
+
+ Trusted Users: +
+
+ Prefix: +
+
+
+
+ + + + +
+
+
+
+
+
+ + + + +
+
+
+ + + + diff --git a/public/configs/script.js b/public/configs/script.js new file mode 100644 index 0000000..087b026 --- /dev/null +++ b/public/configs/script.js @@ -0,0 +1,378 @@ + const socket = io(); + + const tabButtons = document.querySelectorAll('.tab-button'); + const tabContents = document.querySelectorAll('.tab-content'); + const configsDiv = document.getElementById('configs'); + const configName = document.getElementById('config-name'); + const buttonImport = document.getElementById('button-import'); + const buttonNew = document.getElementById('button-new'); + const buttonSave = document.getElementById('button-save'); + const buttonDelete = document.getElementById('button-delete'); + const buttonRefrash = document.getElementById('button-refresh'); + const buttonSet = document.getElementById('button-set'); + let config = {}; + let selectedConfig = ''; + var MainConfig = {}; + var ConfigList = []; + +const configButtons = document.querySelectorAll('.config') +configButtons.forEach(button => { + button.addEventListener('click', () => { + readConfig(button.textContent + '.clc') + }) +}) + + + + + // Tab functionality + tabButtons.forEach(button => { + button.addEventListener('click', () => { + const tabName = button.getAttribute('data-tab'); + window.location.href = `/${tabName}`; + }); + }); + + // Socket Event Listeners + socket.on('config', (config) => { + console.log('Received config:', config); + // Update your UI with the config data + MainConfig = config; + }); + + socket.on('config.list', (list) => { + console.log('Received config list:', list); + // Update your UI with the config data + ConfigList = list; + }); + +getList(); + + /** + * Sanitizes input to prevent XSS attacks. + * @param {string} str - The string to sanitize. + * @returns {string} - The sanitized string. + */ + function sanitize(str) { + const temp = document.createElement('div'); + temp.textContent = str; + return temp.innerHTML; + } + + function sendCommand(command) { + socket.emit('command', command); + } + + function getList() { + socket.emit('config.get_list'); + socket.on('config.list', (list) => { + // Update your UI with the config data + ConfigList = list; + + // Create buttons for each config + configsDiv.innerHTML = ''; // Clear existing content + list.forEach(configName => { + const button = document.createElement('button'); + button.className = 'config'; + button.textContent = configName.replace('.clc', ''); + button.setAttribute('onclick', `readConfig('${configName}')`); + configsDiv.appendChild(button); + }); + }); + } + + function createConfig(data) { + socket.emit('config.new', data); + getList(); + + } + function editConfig(data) { + if (data.oldName !== data.newName) { + socket.emit('config.rename', { oldName: data.oldName, newName: data.newName }); + selectedConfig = data.newName; + } + socket.emit('config.edit', { name: data.newName, code: data.code }); + getList(); + } + + function editConfigFromWeb() { + const data = { + serverIP: document.querySelector('#serverIP input').value, + serverPort: document.querySelector('#serverPort input').value, + version: document.querySelector('#version input').value, + bot_amount: document.querySelector('#bot_amount input').value, + useLogin: document.querySelector('#useLogin input[type="checkbox"]').checked.toString(), + username: document.querySelector('#username input').value, + password: document.querySelector('#password input').value, + useFiltering: document.querySelector('#useFiltering input[type="checkbox"]').checked.toString(), + whitelistedWords: document.querySelector('#whitelistedWords input').value, + trustedUsers: document.querySelector('#trustedUsers input').value, + prefix: document.querySelector('#prefix input').value + }; + + editConfig({ + oldName: selectedConfig, + newName: `${configName.value}.clc`, + code: data + }); + } + function deleteConfig(data) { + console.log(`deleted ${data}`) + socket.emit('config.delete', data); + getList(); + if (selectedConfig === data) { + resetConfig(); + } + } + + + + +// Add event listener for 'Delete' key on config buttons +document.addEventListener('keydown', function(event) { + if (event.key === 'Delete' && event.target.classList.contains('config')) { + event.preventDefault(); + const configName = event.target.textContent + '.clc'; + deleteConfig(configName); + } +}); + +function generateUniqueName(baseName, existingNames) { + let newName = baseName; + let counter = 1; + while (existingNames.includes(newName)) { + newName = `${baseName.replace('.clc', `(${counter}).clc`)}`; + counter++; + } + return newName; +} + + function createConfigFromWeb() { + + socket.emit('config.get_list'); + socket.once('config.list', (list) => { + const uniqueName = generateUniqueName('new_config.clc', list); + createConfig(data={name: uniqueName, code: { + "serverIP": "localhost", + "serverPort": "25565", + "version": "1.20.4", + "bot_amount": "1", + "useLogin": "true", + "username": "Bot1", + "password": "Password", + "useFiltering": "true", + "whitelistedWords": "word1, word2", + "trustedUsers": "player1, player2", + "prefix": "!!" + }}); + }); + } + + function handleKey(event) { + if (event.key === 'Enter') { + editConfigFromWeb(); + } + } + document.querySelectorAll('#serverIP input, #serverPort input, #version input, #bot_amount input, #useLogin input, #password input, #username input, #useFiltering input, #whitelistedWords input, #trustedUsers input, #prefix input, #configName').forEach(input => { + input.addEventListener('keypress', handleKey); + }); + + + +function importConfig(data) { + socket.emit('config.get_list'); + socket.once('config.list', (list) => { + const uniqueName = generateUniqueName(data.name, list); + const convertedContent = convertToJSON(data.content); + createConfig({name: uniqueName, code: convertedContent}); + }); +} + +function convertToJSON(text) { + const lines = text.split('\n'); + const jsonObject = {}; + + lines.forEach(line => { + const [key, value] = line.trim().split(':').map(item => item.trim()); + if (key && value) { + jsonObject[key] = value; + } + }); + + return JSON.stringify(jsonObject, null, 2); +} + +function importConfigFromWeb() { + buttonImport.onchange = function(event) { + const file = event.target.files[0]; + if (file) { + console.log('File selected:', file.name); + const reader = new FileReader(); + reader.onload = function(e) { + const content = e.target.result; + importScript({name: file.name, content: content}); + }; + reader.readAsText(file); + } + }; + + fileInput.click(); +} + +document.getElementById('config-import-btn').addEventListener('click', function() { + document.getElementById('config-import').click(); +}); + +document.getElementById('config-import').addEventListener('change', function() { + console.log('File selected:', this.files[0].name); + const file = event.target.files[0]; + if (file) { + const reader = new FileReader(); + reader.onload = function(e) { + const content = e.target.result; + importConfig({name: file.name, content: content}); + }; + reader.readAsText(file); + } + // You can add your file import logic here +}); + + + +// Add event listener for Ctrl+S on the whole document +document.addEventListener('keydown', function(event) { + if (event.ctrlKey && event.key === 's') { + event.preventDefault(); // Prevent the default save action + editConfigFromWeb(); + } +}); + + + function deleteConfigFromWeb() { + deleteConfig(selectedConfig); + } + + function setConfigFromWeb() { + const data = { + serverIP: document.querySelector('#serverIP input').value, + serverPort: document.querySelector('#serverPort input').value, + version: document.querySelector('#version input').value, + bot_amount: document.querySelector('#bot_amount input').value, + useLogin: document.querySelector('#useLogin input[type="checkbox"]').checked.toString(), + username: document.querySelector('#username input').value, + password: document.querySelector('#password input').value, + useFiltering: document.querySelector('#useFiltering input[type="checkbox"]').checked.toString(), + whitelistedWords: document.querySelector('#whitelistedWords input').value, + trustedUsers: document.querySelector('#trustedUsers input').value, + prefix: document.querySelector('#prefix input').value + }; + + socket.emit('config.set', data); + config = data; + } + + let configSendListener = null; + + function readConfig(data) { + // Remove previous listener if it exists + if (configSendListener) { + socket.off('config.send', configSendListener); + } + + // Create new listener + configSendListener = (configContent) => { + configName.value = data.replace('.clc', ''); + selectedConfig = data; + console.log(configContent) + const configButtons = document.querySelectorAll('.config'); + configButtons.forEach(button => { + if (button.innerText === selectedConfig.replace('.clc', '')) { + button.id = 'selectedConfig'; + } else { + button.removeAttribute('id'); + } + }); + setConfigFromJSON(configContent); + }; + + // Add the new listener + socket.on('config.send', configSendListener); + + // Emit the read request + socket.emit('config.read', `configs/${data}`); + } + + function setConfig(data) { + socket.emit('config.set', data); + } + + +// Get the necessary elements +const useFilteringCheckbox = document.querySelector('#useFiltering input[type="checkbox"]'); +const whitelistedWordsInput = document.querySelector('#whitelistedWords input[type="text"]'); +const useLoginCheckbox = document.querySelector('#useLogin input[type="checkbox"]'); +const passwordInput = document.querySelector('#password input[type="text"]'); + +// Add event listener for the useFiltering checkbox +useFilteringCheckbox.addEventListener('change', function() { + whitelistedWordsInput.disabled = !this.checked; +}); + +// Add event listener for the useLogin checkbox +useLoginCheckbox.addEventListener('change', function() { + passwordInput.disabled = !this.checked; +}); + +// Initial state setup +whitelistedWordsInput.disabled = !useFilteringCheckbox.checked; +passwordInput.disabled = !useLoginCheckbox.checked; + + +function setConfigFromJSON(data) { + document.querySelector('#serverIP input').value = data.serverIP || ''; + document.querySelector('#serverPort input').value = data.serverPort || ''; + document.querySelector('#version input').value = data.version || ''; + document.querySelector('#bot_amount input').value = data.bot_amount || ''; + + const useLoginCheckbox = document.querySelector('#useLogin input[type="checkbox"]'); + useLoginCheckbox.checked = data.useLogin === 'true'; + document.querySelector('#password input').disabled = !useLoginCheckbox.checked; + + document.querySelector('#username input').value = data.username || ''; + document.querySelector('#password input').value = data.password || ''; + + const useFilteringCheckbox = document.querySelector('#useFiltering input[type="checkbox"]'); + useFilteringCheckbox.checked = data.useFiltering === 'true'; + + const whitelistedWordsInput = document.querySelector('#whitelistedWords input'); + whitelistedWordsInput.value = data.whitelistedWords || ''; + whitelistedWordsInput.disabled = !useFilteringCheckbox.checked; + + document.querySelector('#trustedUsers input').value = data.trustedUsers || ''; + document.querySelector('#prefix input').value = data.prefix || ''; +} + +function resetConfig() { + document.querySelector('#serverIP input').value = ''; + document.querySelector('#serverPort input').value = ''; + document.querySelector('#version input').value = ''; + document.querySelector('#bot_amount input').value = ''; + + const useLoginCheckbox = document.querySelector('#useLogin input[type="checkbox"]'); + useLoginCheckbox.checked = false; + document.querySelector('#password input').disabled = true; + document.querySelector('#password input').value = ''; + + document.querySelector('#username input').value = ''; + + const useFilteringCheckbox = document.querySelector('#useFiltering input[type="checkbox"]'); + useFilteringCheckbox.checked = false; + + const whitelistedWordsInput = document.querySelector('#whitelistedWords input'); + whitelistedWordsInput.value = ''; + whitelistedWordsInput.disabled = true; + + document.querySelector('#trustedUsers input').value = ''; + document.querySelector('#prefix input').value = ''; + selectedConfig = ''; +} \ No newline at end of file diff --git a/public/configs/style.css b/public/configs/style.css new file mode 100644 index 0000000..e37deaa --- /dev/null +++ b/public/configs/style.css @@ -0,0 +1,327 @@ + body { + font-family: "Comfortaa", sans-serif; + font-optical-sizing: auto; + font-style: normal; + background-image: url("/images/bg.png"); + color: #ecf0f1; + margin: 0; + padding: 20px; + background-repeat: no-repeat; + background-size: cover; + background-attachment: fixed; + } + + h3 { + text-align: left; + margin-top: 17px; + margin-right: 10px; + font-size: 20px; + } + + #command-input { + border-radius: 7px; + padding: 10px; + width: calc(100% - 20px); + max-width: 1178px; + color: white ; + background-color: rgba(0, 0, 0, 0.432); + overflow-y: scroll; + -ms-overflow-style: none; + scrollbar-width: none; + } + + #send-button { + padding: 10px 20px; + border: none; + border-radius: 4px; + background-color: #3498db; + color: #ffffff; + cursor: pointer; + } + + #send-button:hover { + background-color: #2980b9; + } + + #main { + margin: 0; + padding: 20px; + border-radius: 0; + overflow-y: auto; + scrollbar-width: none; + -ms-overflow-style: none; + background-color: rgba(0, 0, 0, 0.308); + background-size: cover; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100%; + box-sizing: border-box; + } + + #main-middle { + max-height: 700px; + max-width: 1200px; + width: 100%; + margin: 70px auto 0; + padding: 20px; + border-radius: 7px; + align-content: space-evenly; + overflow-y: auto; + scrollbar-width: none; + -ms-overflow-style: none; + background-color: rgba(0, 0, 0, 0.63); + box-sizing: border-box; + } + + #config-content { + border-radius: 7px; + padding: 10px; + height: 50vh; + overflow-y: auto; + scrollbar-width: none; + -ms-overflow-style: none; + background-color: rgba(0, 0, 0, 0.452); + box-sizing: border-box; + max-height: 80vh; + max-width: 1200px; + width: 100%; + color: white; + } + + #config-content::-webkit-scrollbar { + display: none; + } + + .log-message { + margin-bottom: 10px; + } + + .status { + color: #f1c40f; + } + + .error { + color: #e74c3c; + } + + .chat { + color: #2ecc71; + } + + .filtered { + color: #9b59b6; + } + + #tabs { + display: flex; + flex-wrap: wrap; + justify-content: center; + margin-bottom: 20px; + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1000; + height: 60px; + width: 100%; + background-color: rgba(0, 0, 0, 0.63); + } + + button { + padding: 10px 20px; + margin: 5px; + border: none; + border-radius: 7px; + background-color: rgba(0, 0, 0, 0.377); + color: #ecf0f1; + cursor: pointer; + font-family: "Comfortaa", sans-serif; + font-size: 14px; + transition: background-color 0.3s ease; + } + + button:hover { + background-color: rgba(0, 0, 0, 0.8); + } + + .tab-content { + display: none; + } + + .tab-content.active { + display: block; + } + + @media (max-width: 600px) { + #tabs { + flex-direction: column; + } + + .tab-button { + width: 100%; + margin: 5px 0; + } + } + +#tab-chosen { + background-color: rgba(0, 0, 0, 0.8); +} + +input { + padding: 10px; + margin: 5px; + border: none; + border-radius: 7px; + background-color: rgba(0, 0, 0, 0.377); + color: #ecf0f1; + font-family: "Comfortaa", sans-serif; + font-size: 14px; + transition: background-color 0.3s ease; +} + +input:focus { + outline: none; + background-color: rgba(0, 0, 0, 0.8); +} + +input::placeholder { + color: rgba(236, 240, 241, 0.7); +} + +@media (max-width: 600px) { + input { + width: calc(100% - 10px); + } +} + +#config { + display: flex; + grid-template-columns: 1fr auto; + gap: 10px; + flex-direction: row; +} + +#config-content { + grid-column: 1 / -1; +} + +#bar_buttons { + display: flex; + justify-content: flex-start; + gap: 10px; + flex-direction: row; +} + +#configs_bar { + display: flex; + justify-content: flex-start; + gap: 10px; + flex-direction: column; +} + +#buttons { + margin-top: 10px; + display: flex; + gap: 10px; +} + +@media (max-width: 600px) { + #config { + grid-template-columns: 1fr; + } + + #buttons { + flex-direction: column; + } +} + +#config-new { + max-height: 40px; +} +#config-import { + max-height: 40px; +} + +#configs { + justify-items: right; + display: grid; + align-items: right; + align-self: right; + align-content: right; + max-height: 40vh; + overflow-y: auto; + scrollbar-width: none; + -ms-overflow-style: none; +} + +#configs::-webkit-scrollbar { + display: none; +} + +#selectedConfig { + background-color: rgba(0, 0, 0, 0.8); +} + #config-import-btn { + padding: 10px 20px; + margin: 5px; + border: none; + border-radius: 7px; + background-color: rgba(0, 0, 0, 0.377); + color: #ecf0f1; + cursor: pointer; + font-family: "Comfortaa", sans-serif; + font-size: 14px; + transition: background-color 0.3s ease; + } + + #config-import-btn:hover { + background-color: rgba(0, 0, 0, 0.8); + } + + #config-import { + display: none; + } + + + #config-content input[type="text"], + #config-content input[type="number"] { + width: 100%; + padding: 10px; + margin: 5px 0; + border: none; + border-radius: 7px; + background-color: rgba(0, 0, 0, 0.377); + color: #ecf0f1; + font-family: "Comfortaa", sans-serif; + font-size: 14px; + transition: background-color 0.3s ease; + } + + #config-content input[type="text"]:focus, + #config-content input[type="number"]:focus { + background-color: rgba(0, 0, 0, 0.8); + outline: none; + } + + #config-content input[type="checkbox"] { + margin-right: 10px; + cursor: pointer; + } + + #config-content div { + margin-bottom: 15px; + color: #ecf0f1; + font-family: "Comfortaa", sans-serif; + font-size: 16px; + } + + #config-content { + padding: 20px; + background-color: rgba(0, 0, 0, 0.2); + border-radius: 10px; + } + \ No newline at end of file diff --git a/public/index.html b/public/index.html index 85a0de7..05e68a7 100644 --- a/public/index.html +++ b/public/index.html @@ -13,7 +13,7 @@

ChatLogger

- + diff --git a/public/info/index.html b/public/info/index.html index 9c5724d..e1767b1 100644 --- a/public/info/index.html +++ b/public/info/index.html @@ -14,7 +14,7 @@

ChatLogger

- + diff --git a/public/logs/index.html b/public/logs/index.html index 4500eb4..1adafaa 100644 --- a/public/logs/index.html +++ b/public/logs/index.html @@ -13,7 +13,7 @@

ChatLogger

- + diff --git a/public/scripts/index.html b/public/scripts/index.html index 6821c38..d844c8b 100644 --- a/public/scripts/index.html +++ b/public/scripts/index.html @@ -14,12 +14,11 @@

ChatLogger

- + -
@@ -28,7 +27,7 @@

ChatLogger

- +
diff --git a/start_bot.bat b/start_bot.bat index ffb2005..60f7d84 100644 --- a/start_bot.bat +++ b/start_bot.bat @@ -1 +1,2 @@ +start http://localhost:3000 node ./ChatLogger.js \ No newline at end of file