From d624602a1db03968d3f712b5b3c308aa7031f53f Mon Sep 17 00:00:00 2001 From: Niels Simenon Date: Tue, 8 Nov 2022 22:21:43 +0100 Subject: [PATCH] Added JavaScript 'game'. --- package-lock.json | 56 +++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/games/javascript.js | 49 ++++++++++++++++++++++++++++++++++++ src/play.js | 2 +- 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/games/javascript.js diff --git a/package-lock.json b/package-lock.json index a6278e4..e6d1828 100755 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "simple-node-logger": "^21.8.12", "string-similarity": "^4.0.4", "tensify": "^0.0.4", + "vm2": "^3.9.11", "ws": "^8.2.3", "yargs": "^17.2.1" }, @@ -3666,6 +3667,40 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "node_modules/vm2": { + "version": "3.9.11", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.11.tgz", + "integrity": "sha512-PFG8iJRSjvvBdisowQ7iVF580DXb1uCIiGaXgm7tynMR1uTBlv7UJlB1zdv5KJ+Tmq1f0Upnj3fayoEOPpCBKg==", + "dependencies": { + "acorn": "^8.7.0", + "acorn-walk": "^8.2.0" + }, + "bin": { + "vm2": "bin/vm2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/vm2/node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/vm2/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -6699,6 +6734,27 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "vm2": { + "version": "3.9.11", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.11.tgz", + "integrity": "sha512-PFG8iJRSjvvBdisowQ7iVF580DXb1uCIiGaXgm7tynMR1uTBlv7UJlB1zdv5KJ+Tmq1f0Upnj3fayoEOPpCBKg==", + "requires": { + "acorn": "^8.7.0", + "acorn-walk": "^8.2.0" + }, + "dependencies": { + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + } + } + }, "w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", diff --git a/package.json b/package.json index 2dddda1..59a12d7 100755 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "simple-node-logger": "^21.8.12", "string-similarity": "^4.0.4", "tensify": "^0.0.4", + "vm2": "^3.9.11", "ws": "^8.2.3", "yargs": "^17.2.1" }, diff --git a/src/games/javascript.js b/src/games/javascript.js new file mode 100644 index 0000000..55f808d --- /dev/null +++ b/src/games/javascript.js @@ -0,0 +1,49 @@ +'use strict'; + +const { NodeVM } = require('vm2'); +const util = require('util'); +const crypto = require('crypto'); +const timers = require('timers'); + +const style = require('../utils/style'); + +const vm = new NodeVM({ + console: 'inherit', + sandbox: { + util, + crypto, + timers, + }, +}); + +const vmConsole = []; + +vm.on('console.log', (data, ...args) => { + vmConsole.push(data); + console.log(args); +}); + +async function onCommand(args, context) { + const script = args.join(' '); + + context.logger.info(`JavaScript ran by ${context.user.username}: ${script}`); + + try { + const result = await vm.run(script, { + sandbox: { + console: { + log: () => console.log('console loggin!'), + }, + }, + }); + + context.sendMessage(`${style.green('')} ${result} | ${vmConsole.join(' ')}`, context.room.id); + } catch (error) { + context.sendMessage(`${style.red(`<${error.name}>`)} ${error.message}`, context.room.id); + } +} + +module.exports = { + onCommand, + commands: ['js', '>'], +}; diff --git a/src/play.js b/src/play.js index 213c04b..5ce6dd1 100755 --- a/src/play.js +++ b/src/play.js @@ -197,7 +197,7 @@ function getMessageRoom(message, bot) { function onMessage(message, bot, games) { const body = message.originalBody || message.body; - const [, command, subcommand] = body?.match(new RegExp(`^${config.prefix}(\\w+)(?:\\:(\\w+))?`)) || []; + const [, command, subcommand] = body?.match(new RegExp(`^${config.prefix}([\\w>]+)(?:\\:(\\w+))?`)) || []; const user = getMessageUser(message, bot); const room = getMessageRoom(message, bot);