const { Isolate } = require('isolated-vm') const { Server } = require('socket.io') const util = require('util') const { stylize } = require('./colors') const randomstring = require('randomstring') const ChatMessage = require('prismarine-chat')('1.20.1') const mc = require('minecraft-protocol') const moment = require('moment-timezone') const crypto = require('crypto') const nbt = require('prismarine-nbt') const BRIDGE_PREFIX = 'function:' const io = new Server(3069) io.on('connection', (socket) => { let functions let proxy const handler = { get (target, prop) { if (!target[prop]) throw new Error(`Function "${prop}" not available`) return (...args) => target[prop](...args) } } socket.on('setFunctions', (jsonArray) => { const parsed = JSON.parse(jsonArray) functions = {} for (const eachFuntion of parsed) { functions[eachFuntion] = (...args) => { socket.emit(BRIDGE_PREFIX + eachFuntion, ...args) return new Promise((resolve) => { socket.once(`functionOutput:${eachFuntion}`, (message, parseJSON) => { if (parseJSON) resolve(JSON.parse(message)) else resolve(message) }) }) } } proxy = new Proxy(functions, handler) resetVM() }) const isolate = new Isolate({ memoryLimit: 256 }) let context async function resetVM () { context = await isolate.createContext() // TODO: fix // const global = context.global // await global.set('this', global.derefInto()) // await global.set('global', global.derefInto()) // await global.set('bridge', () => { return proxy }) // await global.set('randomstring', () => randomstring) // await global.set('ChatMessage', () => ChatMessage) // await global.set('mc', () => mc) // await global.set('moment', () => moment) // await global.set('crypto', () => crypto) // await global.set('nbt', () => nbt) } resetVM() socket.on('runCode', async (transactionId, code) => { try { const output = await context.eval(code, { timeout: 1000 }) socket.emit('codeOutput', transactionId, false, util.inspect(output, { stylize })) } catch (e) { socket.emit('codeOutput', transactionId, true, e.toString()) } }) socket.on('reset', resetVM) }) process.on('uncaughtException', (e) => { console.log(`Caught an uncaught exception!\n${e.stack}`) })