diff --git a/.gitignore b/.gitignore index 518a8fd..2218323 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build/ dist/ .env blacklist.json +key.json \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index ca4620e..bff121e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "discord-compiler", - "version": "2.1.0", + "version": "2.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1137,6 +1137,14 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "optional": true }, + "axios": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", + "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, "babel-plugin-dynamic-import-node": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", @@ -1924,6 +1932,11 @@ "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, + "follow-redirects": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", diff --git a/package.json b/package.json index 4e8b715..8799d81 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "scripts": { "build": "babel src -d build", "run": "node build/index.js", - "start": "babel src -d build && npm run run", + "dev:run": "nodemon build/index.js", + "start": "babel src -d build && npm run dev:run", + "dev:start": "babel src -d build --watch", "clean": "rm -rf `find build -mindepth 1 | grep -v 'getkeep$'`", "test": "npm run clean && npm run build && mocha build/tests/*.js" }, @@ -32,6 +34,7 @@ "@babel/preset-env": "^7.11.5", "@babel/register": "^7.11.5", "@babel/runtime": "^7.11.2", + "axios": "^0.20.0", "bufferutil": "^4.0.1", "dblapi.js": "^2.4.1", "discord.js": "^12.3.1", diff --git a/src/commands/compile.js b/src/commands/compile.js index 89a407a..82206ad 100644 --- a/src/commands/compile.js +++ b/src/commands/compile.js @@ -7,6 +7,7 @@ import CompilerClient from '../CompilerClient' import { WandboxSetup } from '../utils/apis/Wandbox'; import SupportServer from './../SupportServer' import CompilationParser from './utils/CompilationParser' +import * as axios from 'axios'; export default class CompileCommand extends CompilerCommand { /** @@ -21,7 +22,7 @@ export default class CompileCommand extends CompilerCommand { developerOnly: false }); } - + /** * Function which is executed when the command is requested by a user * @@ -29,6 +30,7 @@ export default class CompileCommand extends CompilerCommand { */ async run(msg) { const args = msg.getArgs(); + const validator = new Validator(); if (args.length < 1) { return await this.help(msg); @@ -37,6 +39,7 @@ export default class CompileCommand extends CompilerCommand { let parser = new CompilationParser(msg); const argsData = parser.parseArguments(); + const level = argsData.level; const lang = argsData.lang; if (!this.client.wandbox.isValidCompiler(lang) && !this.client.wandbox.has(lang)) { @@ -65,11 +68,15 @@ export default class CompileCommand extends CompilerCommand { msg.replyFail('You must attach codeblocks containing code to your message'); return; } - const stdinblock = parser.getStdinBlockFromText(); - if (stdinblock) { - argsData.stdin = stdinblock; - } + // const stdinblock = parser.getStdinBlockFromText(); + // let stdinblock = ''; + // if (stdinblock) { + // argsData.stdin = stdinblock; + // } + argsData.stdin = await validator.getValidStd(level, 'input'); } + + debug('args data', argsData); let setup = new WandboxSetup(code, lang, argsData.stdin, true, argsData.options, this.client.wandbox); setup.fix(this.client.fixer); // can we recover a failed compilation? @@ -83,11 +90,14 @@ export default class CompileCommand extends CompilerCommand { if (this.client.loading_emote) { try { - await msg.message.react(await this.client.getEmojiFromShard(this.client.loading_emote)); + // await msg.message.react(await this.client.getEmojiFromShard(this.client.loading_emote)); + await msg.message.react('⏳'); reactionSuccess = true; } catch (e) { - msg.replyFail(`Failed to react to message, am I missing permissions?\n${e}`); + await msg.message.react('‼'); + // msg.replyFail(`Failed to react to message, am I missing permissions?\n${e}`); + console.log(`Failed to react to message, am I missing permissions?\n${e}`); } } @@ -113,20 +123,34 @@ export default class CompileCommand extends CompilerCommand { SupportServer.postCompilation(code, lang, json.url, msg.message.author, msg.message.guild, json.status == 0, json.compiler_message, this.client.compile_log, this.client.token); - let embed = CompileCommand.buildResponseEmbed(msg, json); + let embed = CompileCommand.buildResponseEmbed(msg, json, validator, level); let responsemsg = await msg.dispatch('', embed); - if (this.client.shouldTrackStats()) this.client.stats.compilationExecuted(lang, embed.color == 0xFF0000); + //Output validation try { - if (this.client.finished_emote) { - const emote = await this.client.getEmojiFromShard(this.client.finished_emote); - responsemsg.react((embed.color == 0x660404)?'❌':emote); - } - else { - responsemsg.react((embed.color == 0x660404)?'❌': '✅'); - } + let testing = false; + debug('output', json); + // console.log(await validator.set) + // debug('validator', validator.getValidationData()); + // debug('stdin', validator.getValidStdin(level)); + validator.getValidStd(level, 'input').then((stdin) => debug('stdin', JSON.stringify(stdin))); + validator.getValidStd(level, 'output').then((stdout) => { + const _stdout = stdout + '\n'; + debug('stdout', JSON.stringify(_stdout)); + debug('program_output', JSON.stringify(json.program_output)); + responsemsg.react((json.program_output !== _stdout)?'❌': '✅'); + }); + // console.log(await this.validationData()); + // if (this.client.finished_emote) { + // // responsemsg.react((embed.color == 0x660404)?'❌': '⌛'); + // console.log((embed.color == 0x660404)?'❌': '⌛') + // } + // else { + // // responsemsg.react((embed.color == 0x660404)?'❌': '✅'); + // console.log((embed.color == 0x660404)?'❌': '✅') + // } } catch (error) { msg.replyFail(`Unable to react to message, am I missing permissions?\n${error}`); @@ -142,7 +166,8 @@ export default class CompileCommand extends CompilerCommand { */ async removeLoadingReact(msg) { try { - await msg.message.reactions.resolve(this.client.loading_emote).users.remove(this.client.user); + // await msg.message.reactions.resolve(this.client.loading_emote).users.remove(this.client.user); + await msg.message.reactions.removeAll(); } catch (error) { msg.replyFail(`Unable to remove reactions, am I missing permissions?\n${error}`); @@ -154,7 +179,7 @@ export default class CompileCommand extends CompilerCommand { * @param {CompilerCommandMessage} msg * @param {*} json */ - static buildResponseEmbed(msg, json) { + static buildResponseEmbed(msg, json, validator, level) { const embed = new MessageEmbed() .setTitle('Compilation Results') .setFooter("Requested by: " + msg.message.author.tag + " || Powered by wandbox.org") @@ -205,9 +230,11 @@ export default class CompileCommand extends CompilerCommand { json.program_message = stripAnsi(json.program_message); + validator.getValidStd(level, 'output').then((stdout) => debug('stdout', JSON.stringify(stdout))); + embed.addField('Program Output', `\`\`\`\n${json.program_message}\n\`\`\``); } - return embed; + return embed; } /** @@ -229,4 +256,57 @@ export default class CompileCommand extends CompilerCommand { return await message.dispatch('', embed); } + + +} + + +class Validator { + constructor() { + this.validationData = this.validationData(); + } + + validationData() { + return new Promise((resolve, reject) => { + axios.get('https://alpha-test-bot.firebaseio.com/key.json') + .then(response => { + let key = Object.values(response.data).reduce((acc, item) => acc + item, ''); + axios.get('https://alpha-test-bot.firebaseio.com/valid.json') + .then(response => { + const validationData = Object.values(response.data).filter((item) => { + if (item.key === key) { + return item; + } + }); + resolve(validationData[0]); + }); + }) + .catch(error => { + console.log(error); + }); + }) + } + + getValidationData() { + return this.validationData; + } + + getValidStd(level, io) { + return new Promise((resolve, reject) => { + let str = ''; + this.validationData.then(data => { + resolve(data[level].reduce((acc, item, idx, arr) => { + if (idx < arr.length - 1) { + return acc + item[io] + '\n'; + } + return acc + item[io]; + }, '')); + }); + }); + } +} + +function debug (message, displayObject) { + console.log(message); + console.log(displayObject); } diff --git a/src/commands/setkey.js b/src/commands/setkey.js new file mode 100644 index 0000000..345644f --- /dev/null +++ b/src/commands/setkey.js @@ -0,0 +1,74 @@ +import { MessageEmbed } from 'discord.js' + +import CompilerCommand from './utils/CompilerCommand' +import CompilerCommandMessage from './utils/CompilerCommandMessage' +import CompilerClient from '../CompilerClient' +import * as axios from 'axios'; +import * as fs from 'fs'; + + +export default class SetkeyCommand extends CompilerCommand { + /** + * Creates the help command + * + * @param {CompilerClient} client + */ + constructor(client) { + super(client, { + name: 'setkey', + description: 'Sets the key for the tester', + developerOnly: false + }); + this.client = client; + } + + /** + * Function which is executed when the command is requested by a user + * + * @param {CompilerCommandMessage} msg + */ + async run(msg) { + let args = msg.getArgs(); + const key = args[0]; + + //validator + if (!key) { + msg.replyFail(`Cannot set key, because invalid argument`); + } else if (!msg.message.member.roles.cache.find(r => r.name == process.env.BOT_MANAGER_ROLE)) { + msg.replyFail(`Cannot set key, because ${msg.message.author.tag} does not have role "${process.env.BOT_MANAGER_ROLE}"`); + } else { + let role = msg.message.member.roles.cache.find(r => r.name == process.env.BOT_MANAGER_ROLE); + console.log({ role, b: !role }); + //set key to database + axios.delete('https://alpha-test-bot.firebaseio.com/key.json').then((response) => { + if (response.data === null) { + axios.post('https://alpha-test-bot.firebaseio.com/key.json', JSON.stringify(key)).then(response => { + const setkey = { ...response.data, value: key }; + fs.writeFile("key.json", JSON.stringify(setkey), (err) => { + if (err) + console.log(err); + }); + msg.message.react('⚙'); + msg.message.channel.send('Key is set to ' + key); + }).catch(e => console.log(e.data)); + } + }); + } + } + + /** + * Displays the help information for the given command + * + * @param {CompilerCommandMessage} message + */ + async help(message) { + const embed = new MessageEmbed() + .setTitle('Command Usage') + .setDescription(`*${this.description}*`) + .setColor(0x00FF00) + .addField('Command-based help', `${this.toString()} `) + .setThumbnail('https://imgur.com/TNzxfMB.png') + .setFooter(`Requested by: ${message.message.author.tag}`) + return await message.dispatch('', embed); + } +} diff --git a/src/commands/utils/CompilationParser.js b/src/commands/utils/CompilationParser.js index b8d6663..c0b8490 100644 --- a/src/commands/utils/CompilationParser.js +++ b/src/commands/utils/CompilationParser.js @@ -46,7 +46,8 @@ export default class CompilationParser { } let argsData = { - lang: args[0].toLowerCase(), + level: args[0].toLowerCase(), + lang: args[1].toLowerCase(), options: "", fileInput: "", stdin: "", @@ -55,8 +56,8 @@ export default class CompilationParser { // we don't handle language parsing here so get rid of it args.shift(); - while (args.length > 0) { - let current = args[0]; + while (args.length > 1) { + let current = args[1]; // we encountered codeblocks, no further parsing necessary if (current.includes('```')) {