首页 > 解决方案 > NodeJs 中的 Discord 机器人

问题描述

我正在尝试使我的代码更短,但我找不到如何做到这一点,因为我不是以英语为母语的人,我无法用我的语言找到答案,所以我问你。(它是一个管理我的私人服务器的不和谐机器人,所以我不必给我的朋友 ssh 访问权限)


//req
require('dotenv').config()
//dc bot shell
const Discord = require("discord.js");
const client = new Discord.Client();
const PREFIX = 'sv';
//ssh2
const { readFileSync } = require('fs');
const { Client } = require('ssh2');
var Clientssh = require('ssh2').Client;
var password = 'XYZ'
var conn = new Client();
//wol
var wol = require('wake_on_lan');
//boot par
var booting = 'ssh2 error. the server is off'
var powerstate = '?'
//deus vult con
const activities = [
    "https://hugelolcdn.com/i/633510.png",
    "https://www.memesmonkey.com/images/memesmonkey/2e/2e7c8b624eb66aa0379ff63f0356bbb7.jpeg",
    "https://www.memesmonkey.com/images/memesmonkey/e3/e3971008ad98286718c12f4f1c4da9f3.jpeg",
    "https://www.memesmonkey.com/images/memesmonkey/0f/0fc831250be89c50245df919f564e50e.jpeg",
    "https://hugelolcdn.com/i/633510.png"
  ];
  length = 5;
//start
var booting = 'ssh2 error. the server is off'
var errmax = 0
const game = [
    '', ' mc', ' mcf', ' rust', ' ark'
]
//rply
const rply = [
    '', 'started', 'Ah shit, here we go again.', 'bb', 'z z z Z', 'SEE YOU SPACE COWBOY ...'
]
//ssh coms
const sshcoms = [
    '', 'sudo docker start', 'sudo docker restart','sudo docker stop', 'sudo shutdown -h now', 'sudo reboot -h now'
]
//action
var act0 = 0
var act1 = 0
var act2 = 0
var timeout = 0
//ssh coommands
const commands = {
        'sv sleep': {
            sshcoms: 'sudo reboot -h now',
            rply: 'SEE YOU SPACE COWBOY ...'
        },
        'sv hard reboot': {
            sshcoms: 'sudo reboot -h now',
            rply: 'started mc'
        },
        //start
        'sv start mc': {
            sshcoms: 'sudo docker start mc',
            rply: 'started mc'
        },
        'sv start mcf': {
            sshcoms: 'sudo docker start mcf',
            rply: 'started mcf'
        },
        'sv start ark': {
            sshcoms: 'sudo docker start ark',
            rply: 'started ark'
        },
        'sv start rust': {
            sshcoms: 'sudo docker start rust',
            rply: 'started rust '
        },
        //restart
        'sv restart mc': {
            sshcoms: 'sudo docker restart mc',
            rply: 'restared mc'
        },
        'sv restart mcf': {
            sshcoms: 'sudo docker restart mcf',
            rply: 'restarted mcf'
        },
        'sv restart ark': {
            sshcoms: 'sudo docker restart ark',
            rply: 'restarted ark'
        },
        'sv restart rust': {
            sshcoms: 'sudo docker start rust',
            rply: 'restarted rust '
        },
        //stop
        'sv stop mc': {
            sshcoms: 'sudo docker stop mc',
            rply: 'bb'
        },
        'sv stop mcf': {
            sshcoms: 'sudo docker stop mcf',
            rply: 'bb'
        },
        'sv stop ark': {
            sshcoms: 'sudo docker stop ark',
            rply: 'bb'
        },
        'sv stop rust': {
            sshcoms: 'sudo docker stop rust',
            rply: 'bb'
        },
  }
//msg sys
client.on('message', msg => {
    if (msg.author.bot){//bot catcher
        return;  
    } else {
        if (msg.content.startsWith(PREFIX)){//prefix
            if (msg.content.includes('wakeup')){
                act2 = 0;
                wol.wake('XYZ');
                wol.wake('XYZ', function(error) {
                    if (error) {
                    msg.reply('wol error. hmm yea thats a crit error call/write the admin');//handle error
                    } else {//done sending packets
                        msg.reply('server is powering on wait a min');
                        booting = 'ssh2 error. the server is booting';
                    }   
                });
                var magic_packet = wol.createMagicPacket('XYZ');
            };
            if (msg.content.includes('sleep')){
                booting = 'ssh2 error. the server is off';
                msg.reply(rply[4]);
                act2 = 4
            };
            if (msg.content.includes('hard reboot')){
                msg.reply(rply[5]);
                act2 = 5
            };
            //start game server
            if (msg.content.includes('sv start')){
                errmax = 0;
                act1 = 1;
                act2 = 1;
                if (msg.content === 'sv start mc'){
                    act0 = 1;
                    msg.reply(rply[act1].concat(game[act0]));
                };
                if (msg.content === 'sv start mcf'){
                    act0 = 2;
                    msg.reply(rply[act1].concat(game[act0]));
                };
                if (msg.content === 'sv start rust'){
                    act0 = 3;
                    msg.reply(rply[act1].concat(game[act0]));
                };
                if (msg.content === 'sv start ark'){
                    act0 = 4;
                    msg.reply(rply[act1].concat(game[act0]));
                };
            };
            //restart game server
            if (msg.content.includes('sv restart')){
                errmax = 0;
                act1 = 2;
                act2 = 2;
                if (msg.content === 'sv restart mc'){
                    act0 = 1;
                    msg.reply(rply[act1].concat(game[act0]));
                };
                if (msg.content === 'sv restart mcf'){
                    act0 = 2;
                    msg.reply(rply[act1].concat(game[act0]));
                };
                if (msg.content === 'sv restart rust'){
                    act0 = 3;
                    msg.reply(rply[act1].concat(game[act0]));
                };
                if (msg.content === 'sv restart ark'){
                    act0 = 4;
                    msg.reply(rply[act1].concat(game[act0]));
                };
            };
            //stop game server
            if (msg.content.includes('sv stop')){
                errmax = 0;
                act1 = 3;
                act2 = 3;
                if (msg.content === 'sv stop mc'){
                    act0 = 1;
                    msg.reply(rply[act1].concat(game[act0]));
                };
                if (msg.content === 'sv stop mcf'){
                    act0 = 2;
                    msg.reply(rply[act1].concat(game[act0]));
                };
                if (msg.content === 'sv stop rust'){
                    act0 = 3;
                    msg.reply(rply[act1].concat(game[act0]));
                };
                if (msg.content === 'sv stop ark'){
                    act0 = 4;
                    msg.reply(rply[act1].concat(game[act0]));
                };
            };
            if (msg.content.includes('deus lo vult')){
                const randomIndex = Math.floor(Math.random() * (activities.length - 1) + 1);
                const filerp = activities[randomIndex];
                msg.reply('DEUS LO VULT!!!', {files: [filerp]});
            };
            if (msg.content.includes('desu lo vult sk sk')){
                msg.reply('desu lo vult???', {files: ["https://www.memesmonkey.com/images/memesmonkey/2e/2e00978777e2cd6e504eca19f29e99cd.png"]});
            };
            if (act2 === 0){
                return;
            } else {
                sshcommand = sshcoms[act2].concat(game[act0]);
                conn.on('ready', function() {
                    console.log('Client :: ready');
                    conn.exec(sshcommand, { pty: true }, function(err, stream) {//commandpart
                      if (err) throw err;
                      stream.on('close', function(code, signal) {
                        console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
                        conn.end();
                      }).on('data', function(data) {
                        if (data.indexOf(':') >= data.length - 2) {
                        stream.write(password + '\n');//password
                        }
                        else {
                            console.log('STDOUT: ' + data);
                        }
                      }).stderr.on('data', function(data) {
                        console.log('STDERR: ' + data);
                      });
                    });
                    //ssh connect
                  }).connect({
                  host: 'XYZ',
                  port: 22,
                  username: 'XYZ',
                  privateKey: readFileSync('XYZ'),     
                  });
                    //error handler
                    conn.on('error', function(e) {
                        if(errmax === 0){
                            msg.reply( booting );
                            errmax = 1;
                        } else {
                            return;
                        }
                    });
            };
        };
    };
});
client.login('XYZ');

这是我的代码的一部分,我想让它看起来像:

const massage =[
"server sleep",
"server hard reboot",
x
y
z
]
const sshcoms =[
x
y
z
]
const rply =[
x
y
z
]

Checking part

所以我希望整个检查部分都在一个操作中,如果是按摩[1],则使 sshcoms[1] 和 rply[1] 不在 15 个 if 语句中,我现在可以将它们放在 3 个父组中,开始停止并重新启动,然后仍然需要 5-7 次检查一次可以完成的工作。

标签: javascriptnode.js

解决方案


您可以将命令映射到参数。

const commands = {
  'server hard reboot': {
    sshcoms: 'sudo reboot -h now',
    reply: 'SEE YOU SPACE COWBOY ...',
    act2: 5
  },
  'server start mc': {
    sshcoms: 'sudo docker start mc',
    reply: 'started mc',
    act0: 1
  }
}

const msgContent = 'server start mc';

const commandActions = commands[msgContent];

const performAction = (action, param) => {
  console.log({action, param});
}

if(commandActions){
  const cmdActionArr = Object.entries(commandActions);
  
  cmdActionArr.forEach(([cmd, action]) => performAction(cmd, action))
 }

您应该将不同的配置保存在它自己的地图中,然后在地图中为每个命令指定覆盖。然后,您可以遍历所选命令中的配置并在主配置对象上覆盖它们。您应该能够在任何地方获取配置。

client.on('message', msg => {
    if (msg.author.bot){//bot catcher
        return;  
    } else {
        configs = {
            act0: 0,
            act1: 2,
            reply: '',
            sshcom: '',
            ...
        };

        const commandConfigs = commands[msg.content];
        Object.entries(commandConfigs).forEach(([config, value]) => {
            configs[config] = value;
        });

        const reply = configs.reply;

推荐阅读