我正在构建一个在node.js中包装terraria服务器的discord bot,以便服务器用户可以重启服务器和类似的操作。我已经设法完成了一半的工作,但我似乎无法创建一个命令来在terraria服务器上执行命令。我已经将它设置为将命令写入子进程的stdin,并且一些基本的调试验证它确实存在,但是没有任何事情发生。
在子进程stdin的Node.js文档中,它表示" 请注意,如果子进程等待读取其所有输入,则子进程将不会继续,直到此流已通过end关闭()&#34。这看起来很可能是问题,因为调用它上面的end()函数确实会按预期发送命令。也就是说,似乎很难相信我无法在不必关闭stdin的情况下继续向stdin发送命令。
这实际上是问题,如果是这样,我有什么选择解决它?我的代码可能在下面找到。
const discordjs = require("discord.js");
const child_process = require("child_process");
const tokens = require("./tokens");
const client = new discordjs.Client();
const terrariaServerPath = "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Terraria\\TerrariaServer.exe"
const terrariaArgs = ['-port', '7777', "-maxplayers", "8", "-world", "test.wld"]
var child = child_process.spawn(terrariaServerPath, terrariaArgs);
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('disconnect', () => {
client.destroy();
});
client.on('message', msg => {
if (msg.channel.name === 'terraria') {
var msgSplit = msg.content.split(" ");
if (msgSplit[0] === "!restart") {
child.kill();
child = child_process.spawn(terrariaServerPath, terrariaArgs);
registerStdio();
msg.reply("restarting server")
}
if (msgSplit[0] === "!exec") {
msg.reply(msgSplit[1]);
child.stdin.write(msgSplit[1] + "\n");
child.stdin.end();
}
}
});
client.login(tokens.discord_token);
var registerStdio = function () {
child.stdout.on('data', (data) => {
console.log(`${data}`);
});
child.stderr.on('data', (data) => {
console.error(`${data}`);
});
}
registerStdio();
答案 0 :(得分:1)
我能够通过使用库node-pty来解决问题。尽管我可以说,问题是子进程没有读取stdin本身,我无法刷新它。 Node-pty创建一个可以写入而不是stdin的虚拟终端对象。此对象不缓冲写入,因此任何输入都会立即发送到程序。