From c9e10b85b8dca76fedcca497ff6db569ad99020e Mon Sep 17 00:00:00 2001 From: "HerpieDerpie@example.com" Date: Tue, 19 Mar 2024 22:10:51 +0100 Subject: [PATCH] made it download exe, and made that work (scuffed in GO) --- example_bot/HOW TO RUN | 5 - example_bot/bot.js | 55 ----- example_bot/commands/utility/temp-file | 0 example_bot/install.bat | 2 - example_bot/package-lock.json | 269 ------------------------- example_bot/package.json | 5 - example_bot/run.bat | 2 - example_bot/updateCommands.js | 82 -------- httpdocs/project.html | 2 +- scripts/project.js | 17 +- server.js | 263 ++++++++++++++++++------ 11 files changed, 210 insertions(+), 492 deletions(-) delete mode 100755 example_bot/HOW TO RUN delete mode 100755 example_bot/bot.js delete mode 100755 example_bot/commands/utility/temp-file delete mode 100755 example_bot/install.bat delete mode 100755 example_bot/package-lock.json delete mode 100755 example_bot/package.json delete mode 100755 example_bot/run.bat delete mode 100755 example_bot/updateCommands.js diff --git a/example_bot/HOW TO RUN b/example_bot/HOW TO RUN deleted file mode 100755 index 027aa16..0000000 --- a/example_bot/HOW TO RUN +++ /dev/null @@ -1,5 +0,0 @@ -How to run your new amazing discord bot. - -First make sure you have node.js installed on your system, you can check with "node --version". - -After that run the install.bat file. it will install the required packages, it wont take very long. When thats done, you can run the run.bat file, it should make your discord bot come online! If it does not, please check your token and your bot id in the config.json file \ No newline at end of file diff --git a/example_bot/bot.js b/example_bot/bot.js deleted file mode 100755 index cbe5e4e..0000000 --- a/example_bot/bot.js +++ /dev/null @@ -1,55 +0,0 @@ -const { Client, Collection, Events, GatewayIntentBits } = require('discord.js'); -const { updateCommands } = require("./updateCommands"); -const { token } = require('./config.json'); -const fs = require('node:fs'); -const path = require('node:path'); - -const client = new Client({ intents: [GatewayIntentBits.Guilds] }); -updateCommands(); - - -/** REGISTER COMMANDS **/ -client.commands = new Collection(); -const foldersPath = path.join(__dirname, 'commands'); -const commandFolders = fs.readdirSync(foldersPath); - -for (const folder of commandFolders) { - const commandsPath = path.join(foldersPath, folder); - const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); - for (const file of commandFiles) { - const filePath = path.join(commandsPath, file); - const command = require(filePath); - if ('data' in command && 'execute' in command) { - client.commands.set(command.data.name, command); - } else { - console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); - } - } -} - -/** SLASH COMMAND HANDLER **/ -client.on(Events.InteractionCreate, async interaction => { - if (interaction.isChatInputCommand()) { - const command = client.commands.get(interaction.commandName); - if (command) { - try { - await command.execute(interaction); - } catch (error) { - console.error(error); - - if (!(interaction.replied || interaction.deferred)) { - await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true }); - } - } - } else { - console.error(`No command matching ${interaction.commandName} was found.`); - } - } - }); - -/** READY SEQUENCE **/ -client.once(Events.ClientReady, c => { - console.log(`Ready! Logged in as ${c.user.tag}`); -}); - -client.login(token); \ No newline at end of file diff --git a/example_bot/commands/utility/temp-file b/example_bot/commands/utility/temp-file deleted file mode 100755 index e69de29..0000000 diff --git a/example_bot/install.bat b/example_bot/install.bat deleted file mode 100755 index 0beeff2..0000000 --- a/example_bot/install.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -npm i discord.js \ No newline at end of file diff --git a/example_bot/package-lock.json b/example_bot/package-lock.json deleted file mode 100755 index 209bad4..0000000 --- a/example_bot/package-lock.json +++ /dev/null @@ -1,269 +0,0 @@ -{ - "name": "example_bot", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "discord.js": "^14.14.1" - } - }, - "node_modules/@discordjs/builders": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz", - "integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==", - "dependencies": { - "@discordjs/formatters": "^0.3.3", - "@discordjs/util": "^1.0.2", - "@sapphire/shapeshift": "^3.9.3", - "discord-api-types": "0.37.61", - "fast-deep-equal": "^3.1.3", - "ts-mixer": "^6.0.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.11.0" - } - }, - "node_modules/@discordjs/collection": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", - "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", - "engines": { - "node": ">=16.11.0" - } - }, - "node_modules/@discordjs/formatters": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz", - "integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==", - "dependencies": { - "discord-api-types": "0.37.61" - }, - "engines": { - "node": ">=16.11.0" - } - }, - "node_modules/@discordjs/rest": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz", - "integrity": "sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==", - "dependencies": { - "@discordjs/collection": "^2.0.0", - "@discordjs/util": "^1.0.2", - "@sapphire/async-queue": "^1.5.0", - "@sapphire/snowflake": "^3.5.1", - "@vladfrangu/async_event_emitter": "^2.2.2", - "discord-api-types": "0.37.61", - "magic-bytes.js": "^1.5.0", - "tslib": "^2.6.2", - "undici": "5.27.2" - }, - "engines": { - "node": ">=16.11.0" - } - }, - "node_modules/@discordjs/rest/node_modules/@discordjs/collection": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz", - "integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==", - "engines": { - "node": ">=18" - } - }, - "node_modules/@discordjs/util": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz", - "integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==", - "engines": { - "node": ">=16.11.0" - } - }, - "node_modules/@discordjs/ws": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz", - "integrity": "sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==", - "dependencies": { - "@discordjs/collection": "^2.0.0", - "@discordjs/rest": "^2.1.0", - "@discordjs/util": "^1.0.2", - "@sapphire/async-queue": "^1.5.0", - "@types/ws": "^8.5.9", - "@vladfrangu/async_event_emitter": "^2.2.2", - "discord-api-types": "0.37.61", - "tslib": "^2.6.2", - "ws": "^8.14.2" - }, - "engines": { - "node": ">=16.11.0" - } - }, - "node_modules/@discordjs/ws/node_modules/@discordjs/collection": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz", - "integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==", - "engines": { - "node": ">=18" - } - }, - "node_modules/@fastify/busboy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", - "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", - "engines": { - "node": ">=14" - } - }, - "node_modules/@sapphire/async-queue": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz", - "integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==", - "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@sapphire/shapeshift": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.3.tgz", - "integrity": "sha512-WzKJSwDYloSkHoBbE8rkRW8UNKJiSRJ/P8NqJ5iVq7U2Yr/kriIBx2hW+wj2Z5e5EnXL1hgYomgaFsdK6b+zqQ==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "lodash": "^4.17.21" - }, - "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@sapphire/snowflake": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz", - "integrity": "sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==", - "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@types/node": { - "version": "20.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.1.tgz", - "integrity": "sha512-T2qwhjWwGH81vUEx4EXmBKsTJRXFXNZTL4v0gi01+zyBmCwzE6TyHszqX01m+QHTEq+EZNo13NeJIdEqf+Myrg==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/ws": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz", - "integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@vladfrangu/async_event_emitter": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz", - "integrity": "sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ==", - "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/discord-api-types": { - "version": "0.37.61", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz", - "integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==" - }, - "node_modules/discord.js": { - "version": "14.14.1", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz", - "integrity": "sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==", - "dependencies": { - "@discordjs/builders": "^1.7.0", - "@discordjs/collection": "1.5.3", - "@discordjs/formatters": "^0.3.3", - "@discordjs/rest": "^2.1.0", - "@discordjs/util": "^1.0.2", - "@discordjs/ws": "^1.0.2", - "@sapphire/snowflake": "3.5.1", - "@types/ws": "8.5.9", - "discord-api-types": "0.37.61", - "fast-deep-equal": "3.1.3", - "lodash.snakecase": "4.1.1", - "tslib": "2.6.2", - "undici": "5.27.2", - "ws": "8.14.2" - }, - "engines": { - "node": ">=16.11.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" - }, - "node_modules/magic-bytes.js": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.5.0.tgz", - "integrity": "sha512-wJkXvutRbNWcc37tt5j1HyOK1nosspdh3dj6LUYYAvF6JYNqs53IfRvK9oEpcwiDA1NdoIi64yAMfdivPeVAyw==" - }, - "node_modules/ts-mixer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", - "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" - }, - "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/undici": { - "version": "5.27.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz", - "integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - } - } -} diff --git a/example_bot/package.json b/example_bot/package.json deleted file mode 100755 index 8b48b1d..0000000 --- a/example_bot/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "discord.js": "^14.14.1" - } -} diff --git a/example_bot/run.bat b/example_bot/run.bat deleted file mode 100755 index 31cb300..0000000 --- a/example_bot/run.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -node bot.js \ No newline at end of file diff --git a/example_bot/updateCommands.js b/example_bot/updateCommands.js deleted file mode 100755 index bbe5ecf..0000000 --- a/example_bot/updateCommands.js +++ /dev/null @@ -1,82 +0,0 @@ -const { REST, Routes } = require('discord.js'); -const { clientId, token } = require('./config.json'); -const fs = require('node:fs'); -const path = require('node:path'); - -const generateCommandFile = (command) => { - return `const { SlashCommandBuilder } = require('discord.js'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('${command.name}') - .setDescription('${command.description}'), - async execute(interaction) { - await interaction.reply('${command.response}'); - }, -}; -`; -}; - - - -const updateCommands = () => { - const commands = []; - const foldersPath = path.join(__dirname, 'commands'); - const utilityFolderPath = path.join(foldersPath, 'utility'); - - // Delete all files from ./commands/utility/ before creating new ones - fs.readdirSync(utilityFolderPath).forEach((file) => { - const filePath = path.join(utilityFolderPath, file); - fs.unlinkSync(filePath); - console.log(`Deleted ${file}`); - }); - - - // CREAYE ALL THE COMMAND FILES HERE (OVERWRITE THEM IF THEY ALREADY EXSIST) - const { commands: jsonCommands } = require('./config.json'); - for (const command of jsonCommands) { - const commandFileName = `${command.name}.js`; - const commandFilePath = path.join(foldersPath, `utility/${commandFileName}`); - - if (!fs.existsSync(commandFilePath)) { - // If the command file doesn't exist, create it - fs.writeFileSync(commandFilePath, generateCommandFile(command)); - console.log(`Created ${commandFileName}`); - } - } - - for (const folder of fs.readdirSync(foldersPath)) { - const commandsPath = path.join(foldersPath, folder); - const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); - for (const file of commandFiles) { - const filePath = path.join(commandsPath, file); - const command = require(filePath); - if ('data' in command && 'execute' in command) { - commands.push(command.data.toJSON()); - } else { - console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); - } - } - } - - const rest = new REST().setToken(token); - - (async () => { - try { - console.log(`⚙️ Started refreshing ${commands.length} application (/) commands.`); - - const data = await rest.put( - Routes.applicationCommands(clientId), - { body: commands }, - ); - - console.log(`✅ Successfully reloaded ${data.length} application (/) commands.`); - } catch (error) { - console.error(`❌ ${error}`); - } - })(); -} - -module.exports = { - updateCommands -} \ No newline at end of file diff --git a/httpdocs/project.html b/httpdocs/project.html index 6fe486a..b4dcec5 100755 --- a/httpdocs/project.html +++ b/httpdocs/project.html @@ -15,7 +15,7 @@

- +

Commands:

diff --git a/scripts/project.js b/scripts/project.js index 9cab80c..e9d0cc3 100755 --- a/scripts/project.js +++ b/scripts/project.js @@ -67,33 +67,30 @@ function exportProject() { return response.blob(); }) .then(blob => { - // Create a link element const link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); - - // Set the download attribute and trigger a click - link.download = `bot_builds_${getProjectId()}.zip`; + // Adjusted for .exe download; consider adjusting the filename as needed + link.download = `discordBot_${getProjectId()}.exe`; + document.body.appendChild(link); // Append to body to ensure visibility in some browsers link.click(); - - // Clean up + document.body.removeChild(link); // Clean up window.URL.revokeObjectURL(link.href); Swal.close(); - }) .then(() => { Swal.fire({ title: "Exported!", - text: "Your project has been exported.", + text: "Your project has been exported successfully.", icon: "success" }); - loadData(); + loadData(); // Reload or refresh data if necessary }) .catch(error => { console.error('Error:', error); Swal.fire({ title: "Export Failed", - text: "There was an error exporting your project.", + text: "There was an error exporting your project. Please try again.", icon: "error" }); }); diff --git a/server.js b/server.js index 772859e..c5a1fc7 100755 --- a/server.js +++ b/server.js @@ -9,6 +9,7 @@ const fs = require('fs-extra'); const path = require('path'); const archiver = require('archiver'); const mysql = require('mysql'); +const { exec } = require('child_process'); const {db} = require("./config.json") @@ -16,7 +17,7 @@ const {db} = require("./config.json") Creating some handy constants */ const documentRoot = `${__dirname}/httpdocs` -const webserverPort = 3000 +const webserverPort = 3002 @@ -209,7 +210,7 @@ app.post("/delete-command", requireLogin, (req, res)=> { con.query(sql, [commandId], (err, results)=>{ if (err) throw err; con.end(); - + res.status(200).send("true"); }) }) @@ -311,82 +312,222 @@ app.post("/rename-project", requireLogin, (req,res)=>{ }) -app.post("/export", requireLogin, (req, res) => { +app.post("/export", requireLogin, async (req, res) => { + console.log('Export request received.'); const projectId = req.query.id; const userId = req.session.userId; + console.log(`Project ID: ${projectId}, User ID: ${userId}`); const con = createConnection(); - const ownerCheck = "SELECT * FROM Projects WHERE project_id=? AND project_owner=?"; - con.query(ownerCheck, [projectId, userId], (err, results) => { - if (err) throw err; - if (results.length !== 1) return res.json({}); + con.query("SELECT * FROM Projects WHERE project_id=? AND project_owner=?", [projectId, userId], async (err, projectResults) => { + if (err) { + console.error('Error checking project owner:', err); + return res.status(500).send('Internal server error'); + } + if (projectResults.length !== 1) { + return res.status(404).send('Project not found or user is not the owner.'); + } - const data = results[0]; + const data = projectResults[0]; const botToken = data.bot_token; - const clientId = data.bot_id; - con.query("SELECT command_id, command_name, command_description, command_response FROM Commands WHERE project_id = ?", [projectId], (err, result) => { - if (err) throw err; - con.end(); + con.query("SELECT command_id, command_name, command_description, command_response FROM Commands WHERE project_id = ?", [projectId], async (err, commands) => { + if (err) { + console.error('Error querying commands:', err); + return res.status(500).send('Internal server error'); + } + try { + console.log("Started generating code"); + await generateGoCode(projectId, botToken, commands); + + console.log("Started compiling"); + await compileForWindows(projectId); - const commands = result.map(command => { - return { - name: command.command_name, - description: command.command_description, - response: command.command_response - }; - }); - - const jsonContent = { - token: botToken, - clientId: clientId, - commands: commands - }; - - const botBuildsPath = `./bot_builds/${projectId}`; - - // Create the directory if it doesn't exist - fs.ensureDirSync(botBuildsPath); - - // Copy everything from "./example_bot" to "./botBuilds/{id}/" - const exampleBotPath = "./example_bot"; - fs.copySync(exampleBotPath, botBuildsPath); - - // Write JSON to a file in the new directory - const configFile = path.join(botBuildsPath, "config.json"); - fs.writeFileSync(configFile, JSON.stringify(jsonContent, null, 2)); - - // Create a zip file - const outputZipPath = path.join(__dirname, `./bot_builds/${projectId}.zip`); - const outputZipStream = fs.createWriteStream(outputZipPath); - const archive = archiver('zip', { - zlib: { level: 9 } - }); - - outputZipStream.on('close', () => { - res.download(outputZipPath, (err) => { - if (err) throw err; - fs.removeSync(outputZipPath); - fs.removeSync(botBuildsPath); + // Assuming the compilation was successful, and .exe is ready. + const directoryPath = path.join('bot_builds', projectId.toString()); + const exePath = path.join(directoryPath, 'discordBot.exe'); + + console.log("Triggering download of the .exe file"); + res.download(exePath, 'discordBot.exe', (err) => { + if (err) { + console.error(`Error sending file: ${err}`); + return res.status(500).send('Failed to download the file.'); + } else { + console.log('Download initiated successfully.'); + cleanUp(projectId); + } }); - }); - - archive.on('error', (err) => { - throw err; - }); - - archive.pipe(outputZipStream); - archive.directory(botBuildsPath, false); - archive.finalize(); + } catch (error) { + console.error(error); + res.status(500).send('An error occurred during the export process.'); + } }); }); }); +/* +Some functions for creating the bot +*/ +function ensureDirectoryExists(directoryPath) { + return new Promise((resolve, reject) => { + console.log(`[ensureDirectoryExists] Ensuring directory exists: ${path.resolve(directoryPath)}`); + fs.mkdir(directoryPath, { recursive: true }, (err) => { + if (err) { + reject(`Error creating directory: ${err}`); + } else { + resolve(); + } + }); + }); +} + +function generateGoCode(projectId, botToken, commands) { + return new Promise((resolve, reject) => { + console.log(`[generateGoCode] Generating Go code for project ID: ${path.resolve(projectId)}`); + const directoryPath = path.join('bot_builds', projectId.toString()); + const filePath = path.join(directoryPath, 'discordBot.go'); + + ensureDirectoryExists(directoryPath).then(() => { + let goCode = ` +package main + +import ( + "fmt" + "github.com/bwmarrin/discordgo" + "os" + "os/signal" + "syscall" +) + +var ( + Token = "${botToken}" +) + +func main() { + dg, err := discordgo.New("Bot " + Token) + if err != nil { + fmt.Println("error creating Discord session,", err) + return + } + + dg.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) { + fmt.Println("Bot is up and running") + }) + + dg.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { + if i.Type == discordgo.InteractionApplicationCommand { + handleCommandInteraction(s, i) + } + }) + + err = dg.Open() + if err != nil { + fmt.Println("error opening connection,", err) + return + } + defer dg.Close() + + registerSlashCommands(dg) + + fmt.Println("Bot is now running. Press CTRL+C to exit.") + sc := make(chan os.Signal, 1) + signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill) + <-sc +} + +func registerSlashCommands(s *discordgo.Session) { + ${commands.map(command => `s.ApplicationCommandCreate(s.State.User.ID, "", &discordgo.ApplicationCommand{ + Name: "${command.command_name}", + Description: "${command.command_description}", + Type: discordgo.ChatApplicationCommand, + })`).join('\n\t')} +} + +func handleCommandInteraction(s *discordgo.Session, i *discordgo.InteractionCreate) { + ${commands.map(command => ` + if i.ApplicationCommandData().Name == "${command.command_name}" { + s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Content: "${command.command_response}", + }, + }) + }`).join('\n\t')} +} + + `; + + fs.writeFileSync(filePath, goCode); + console.log('Go source code generated.'); + resolve(); + }).catch(err => { + reject(err); + }); + }); +} + +function compileForWindows(projectId) { + return new Promise((resolve, reject) => { + const directoryPath = path.resolve('bot_builds', projectId.toString()); + const exePath = path.resolve(directoryPath, 'discordBot.exe'); + + console.log(`[compileForWindows] Directory path: ${directoryPath}`); + + if (!fs.existsSync(directoryPath)) { + reject(`Directory ${directoryPath} does not exist`); + return; + } + + const goModPath = path.resolve(directoryPath, 'go.mod'); + if (!fs.existsSync(goModPath)) { + const cmdInit = `go mod init discordBot && go get github.com/bwmarrin/discordgo`; + console.log(`Running command: ${cmdInit} in directory: ${directoryPath}`); + exec(cmdInit, { cwd: directoryPath }, (error, stdout, stderr) => { + if (error) { + reject(`Error initializing Go module or getting discordgo package: ${error.message}`); + return; + } + compile(); + }); + } else { + compile(); + } + + function compile() { + const cmdCompile = `GOOS=windows GOARCH=amd64 go build -o "${exePath}"`; + console.log(`Running command: ${cmdCompile} in directory: ${directoryPath}`); + exec(cmdCompile, { cwd: directoryPath }, (error, stdout, stderr) => { + if (error) { + reject(`Compilation error: ${error.message}`); + return; + } + console.log('Compilation for Windows completed.'); + resolve(); + }); + } + }); +} + +function cleanUp(projectId) { + return new Promise((resolve, reject) => { + const directoryPath = path.join('bot_builds', projectId.toString()); + + fs.rm(directoryPath, { recursive: true, force: true }, (err) => { + if (err) { + console.error(`Error removing directory: ${err}`); + reject(err); + } else { + console.log(`${directoryPath} was deleted recursively.`); + resolve(); + } + }); + }); +} /* Starting up the server. */ app.listen(webserverPort, () => { - console.log(`Bot Builder Online at http://localhost:${webserverPort}/`) + console.log(`Bot Builder Online at http://localhost:${webserverPort}/`) })