首页 > 解决方案 > 我将如何在 discord.js 中执行执行 bot 命令?

问题描述

我正在尝试制作一个机器人命令(.e args),它允许您使用机器人命令执行任何代码。我该怎么做?我试过了:

cmd = message.content.slice(2);
cmd;

但是当我尝试输入 Discord 时它没有做任何事情,例如, .e message.channel.send("Hello world!") 我将如何使它工作?

标签: discord.js

解决方案


首先我想说这是一个非常糟糕的主意,我真的希望你知道你在做什么

然而,我已经将这个我自己作为我大学的 CTF(夺旗)挑战(由其他学生解决)。您可以在此处找到完整的源代码

现在,首先,您可以使用eval(cmd),但这是一个可怕的想法,因为这会使服务器暴露于代码注入攻击。因此,为避免这种情况,我们将使用 VM(虚拟机)。在这种情况下,我决定使用包vm2。最重要的是,我决定要授予对文件系统的访问权限(用于 CTF 挑战),但是授予对真正 FS 模块的访问权限会带来灾难,因此我决定使用memfs在内存中模拟 FS 模块。

注意:以下代码是用 typescript 编写的,它是 javascript 的超集。

// index.ts
import { Client, Message } from 'discord.js';
import * as fs from 'fs';
import { vol as mfs} from 'memfs';
import * as path from 'path';
import { VM } from 'vm2';

const fakeFileSystemRoot = path.join(__dirname, '..', 'fake_file_system');

mfs.fromJSON(
  fs.readdirSync(fakeFileSystemRoot)
  .map((fileName) => [fileName, fs.readFileSync(path.join(fakeFileSystemRoot, fileName)).toString('utf8')])
  .reduce((res, [fileName, file]) => ({...res, [fileName]: file}), {}),
);

const secrets = require(path.resolve(__dirname, '..', 'secrets.json'));

const client = new Client();

const handleMessage = (message: Message) => {
  if (message.channel.type.toLowerCase() !== 'dm') {
    return;
  }
  if (message.author.bot) {
    return;
  }

  const recursiveCatch = (cb) => {
    try {
      cb();
    } catch (err) {
      recursiveCatch(() => {
        const msg = String(err) || 'error message cannot be empty';
        message.channel.send(msg);
        console.log('Err:', msg);
      });
    }
  };

  recursiveCatch(() => {
    const out = [];
    const vm = new VM({
      eval: false,
      wasm: false,
      timeout: 100,
      sandbox: {
        console: {
          log: (...args: any[]) => out.push(args.map(String).join('')),
          info: (...args: any[]) => out.push(args.map(String).join('')),
          warn: (...args: any[]) => out.push(args.map(String).join('')),
          error: (...args: any[]) => out.push(args.map(String).join('')),
          debug: (...args: any[]) => out.push(args.map(String).join('')),
        },
        fs: {
          readSync: mfs.readSync.bind(mfs),
          readFileSync: mfs.readFileSync.bind(mfs),
          readdirSync: mfs.readdirSync.bind(mfs),
          statSync: mfs.statSync.bind(mfs),
          fstatSync: mfs.fstatSync.bind(mfs),
          lstatSync: mfs.lstatSync.bind(mfs),
        },
      },
    });
    console.log('In:', message.content);
    const returnValue = vm.run(message.content);
    out.push(returnValue);
    const outStr = out.join('\n');
    if (outStr.length > 0) {
      message.channel.send(outStr);
      console.log('Out:', outStr);
    }
  });
};

client.on('ready', () => {
  client.on('message', (message: Message) => handleMessage(message));
  client.on('messageUpdate', (oldMessage, newMessage: Message) => handleMessage(newMessage));
});

client.login(secrets.discord_token)
  .then(() => {
    console.info(`Login successful`);
  })
  .catch((err) => {
    console.error(`Login failed`);
    throw err;
  });

推荐阅读