如何在触发 if 语句时更新对象 keys/values?
How can I update object keys/values when if statement is triggered?
我正在构建一个 Discord 机器人,它将允许用户创建自定义命令。
它是这样工作的,用户输入“!addcommand !commandname:command value”。然后程序将拆分字符串,并将 !commandname:command 值添加到 txt 文件中。每当有人在 discord 中输入 !commandname 时,机器人就会将 "command value" 输出到聊天中。
程序应该在触发 if 语句时检查新命令是否存在。但是,这似乎只是在第一次检查程序时 运行,这会导致除非重新启动程序,否则无法识别新命令。
注:
Client.on 收听频道,内容是 运行 每次聊天有人说什么。
!addcommand 似乎运行正常,我能够确认这些行正在按预期写入文件。
我不知道还能尝试什么。
主文件:
//Assume that requires etc are included
client.on('message', message => {
const pingCheck = message.content.charAt(0);
const commandCheck = message.content.split(" ");
if (pingCheck === "!") {
//Populates the list of custom commands. Must be done on every check, or new commands will not be recognized.
//Currently, this seems to only update once the service/program is restarted
var commandList = customCommands.returnPhrase();
//If the commandList object contains the correct key (stored in commandCheck[0]) such as !commandname, the bot will send the value "command value" as a string to the discord chat.
if (commandList.hasOwnProperty(commandCheck[0])) {
message.channel.send(commandList[commandCheck[0]]);
}
//If the key does not exist, the program then checks predefined commands. Other commands exist here, but for the purposes of this question I'll show only the !addcommand, which is used to create a new custom command.
else {
switch (commandCheck[0]) {
case "!addcommand":
//This checks that the command is formatted properly, "!commandname:commandvalue". If it does not start with ! or contain : somewhere in the string, it's probably an invalid format.
//Technically this still allows for a !:commandvalue format. I haven't implemented a check for this yet.
if (commandCheck[1].startsWith("!") && commandCheck[1].includes(":")) {
//While loop reconstructs the command key to be passed in, ignores slot 0 as this is the !addcommand
var gs = "";
var x = 1;
while (x < commandCheck.length) {
gs += gs +commandCheck[x] + " ";
x++;
}
gs = gs.slice(0,-1)+"\r\n"; //removes the last " " from the input string, and adds line-break
addCommands.addPhrase(gs);//passes reconstructed command to be added to commandlist.txt
message.channel.send("I have added " + commandCheck[1] + " to the command list.");
break;
}
default:
message.channel.send("I dont recognize that command.");
}
}
}
});
添加命令的模块:
const fs = require('fs');
var createCommand = {
addPhrase: function(x) {
fs.appendFile("commandlist.txt", x, function(err){
if(err) throw err;
console.log(err)
});
}
}
module.exports = createCommand;
填充自定义命令列表的模块:
const fs = require('fs');
var commandFile = fs.readFileSync('commandlist.txt','utf8');
var dataSplit = commandFile.split("\r\n");
var readCommand = {
returnPhrase: function(){
var splitSplit = {};
var i = 0;
//populates splitSplit with keys and values based on text file
while (i<dataSplit.length){
var newKey = dataSplit[i].split(':');
splitSplit[newKey[0]] = newKey[1];
i++
};
return splitSplit;
},
};
module.exports = readCommand;
更好的可读性:https://repl.it/repls/DarkvioletDeafeningAutomaticparallelization
预期:如果触发语句,每次都会填充 commandList
实际:commandList 填充第一次触发语句
每当有新命令进入时,您都会写入文件,但是当服务器启动时,您只会从中读取一次,因此您不会跟踪更改(直到您重新启动服务器,它将再次读取文件).现在理论上您可以监听文件更改然后重新加载,但这过于复杂了,文件系统并不是为了实现这一点。相反,只需将您的命令保存在一个对象中并导出一些用于添加/检查的方法:
let commands = {};
// ¹
module.exports = {
addCommand(key, value) {
commands[key] = value;
// ²
},
getValue(key) {
return commands[key];
}
};
现在当你添加一个命令时,它直接被添加到对象中,然后可以直接读出。
现在,由于对象不会在重新启动后保留下来,您将丢失所有命令。但这很容易修复:您可以在对象更新时将其反映到文件中,然后在每次启动时加载它。我没有为此创建自定义格式,而是使用 JSON。上面的代码可以轻松扩展:
// ¹
try {
commands = JSON.parse( fs.readFileSync("commands.txt") );
} catch(e) { /* ignore if file doesnt exist yet */ }
// ²
fs.writeFile("commands.txt", JSON.stringify(commands), err => {
if(err) console.error(err);
});
我将如何编写机器人:
const playerCommands = require("./commands.js");
const defaultCommands = {
addCommand(...pairs) {
let result = "";
for(const pair of pairs) {
const [name, value] = pair.split(":");
playerCommands.addCommand(name, value);
result += `${name} added with value ${value}\n`;
}
return result;
}
};
client.on('message', ({ content, channel }) => {
if(content[0] !== "!") return; // ignore non-commandd
const [commandName, ...args] = content.slice(1).split(" ");
if(defaultCommands[commandName])
return channel.send(defaultCommands[commandName](...args));
const value = playerCommands.getValue(commandName);
if(value) return channel.send(value);
return channel.send("Command not found!");
});
我正在构建一个 Discord 机器人,它将允许用户创建自定义命令。
它是这样工作的,用户输入“!addcommand !commandname:command value”。然后程序将拆分字符串,并将 !commandname:command 值添加到 txt 文件中。每当有人在 discord 中输入 !commandname 时,机器人就会将 "command value" 输出到聊天中。
程序应该在触发 if 语句时检查新命令是否存在。但是,这似乎只是在第一次检查程序时 运行,这会导致除非重新启动程序,否则无法识别新命令。
注:
Client.on 收听频道,内容是 运行 每次聊天有人说什么。
!addcommand 似乎运行正常,我能够确认这些行正在按预期写入文件。
我不知道还能尝试什么。
主文件:
//Assume that requires etc are included
client.on('message', message => {
const pingCheck = message.content.charAt(0);
const commandCheck = message.content.split(" ");
if (pingCheck === "!") {
//Populates the list of custom commands. Must be done on every check, or new commands will not be recognized.
//Currently, this seems to only update once the service/program is restarted
var commandList = customCommands.returnPhrase();
//If the commandList object contains the correct key (stored in commandCheck[0]) such as !commandname, the bot will send the value "command value" as a string to the discord chat.
if (commandList.hasOwnProperty(commandCheck[0])) {
message.channel.send(commandList[commandCheck[0]]);
}
//If the key does not exist, the program then checks predefined commands. Other commands exist here, but for the purposes of this question I'll show only the !addcommand, which is used to create a new custom command.
else {
switch (commandCheck[0]) {
case "!addcommand":
//This checks that the command is formatted properly, "!commandname:commandvalue". If it does not start with ! or contain : somewhere in the string, it's probably an invalid format.
//Technically this still allows for a !:commandvalue format. I haven't implemented a check for this yet.
if (commandCheck[1].startsWith("!") && commandCheck[1].includes(":")) {
//While loop reconstructs the command key to be passed in, ignores slot 0 as this is the !addcommand
var gs = "";
var x = 1;
while (x < commandCheck.length) {
gs += gs +commandCheck[x] + " ";
x++;
}
gs = gs.slice(0,-1)+"\r\n"; //removes the last " " from the input string, and adds line-break
addCommands.addPhrase(gs);//passes reconstructed command to be added to commandlist.txt
message.channel.send("I have added " + commandCheck[1] + " to the command list.");
break;
}
default:
message.channel.send("I dont recognize that command.");
}
}
}
});
添加命令的模块:
const fs = require('fs');
var createCommand = {
addPhrase: function(x) {
fs.appendFile("commandlist.txt", x, function(err){
if(err) throw err;
console.log(err)
});
}
}
module.exports = createCommand;
填充自定义命令列表的模块:
const fs = require('fs');
var commandFile = fs.readFileSync('commandlist.txt','utf8');
var dataSplit = commandFile.split("\r\n");
var readCommand = {
returnPhrase: function(){
var splitSplit = {};
var i = 0;
//populates splitSplit with keys and values based on text file
while (i<dataSplit.length){
var newKey = dataSplit[i].split(':');
splitSplit[newKey[0]] = newKey[1];
i++
};
return splitSplit;
},
};
module.exports = readCommand;
更好的可读性:https://repl.it/repls/DarkvioletDeafeningAutomaticparallelization
预期:如果触发语句,每次都会填充 commandList
实际:commandList 填充第一次触发语句
每当有新命令进入时,您都会写入文件,但是当服务器启动时,您只会从中读取一次,因此您不会跟踪更改(直到您重新启动服务器,它将再次读取文件).现在理论上您可以监听文件更改然后重新加载,但这过于复杂了,文件系统并不是为了实现这一点。相反,只需将您的命令保存在一个对象中并导出一些用于添加/检查的方法:
let commands = {};
// ¹
module.exports = {
addCommand(key, value) {
commands[key] = value;
// ²
},
getValue(key) {
return commands[key];
}
};
现在当你添加一个命令时,它直接被添加到对象中,然后可以直接读出。
现在,由于对象不会在重新启动后保留下来,您将丢失所有命令。但这很容易修复:您可以在对象更新时将其反映到文件中,然后在每次启动时加载它。我没有为此创建自定义格式,而是使用 JSON。上面的代码可以轻松扩展:
// ¹
try {
commands = JSON.parse( fs.readFileSync("commands.txt") );
} catch(e) { /* ignore if file doesnt exist yet */ }
// ²
fs.writeFile("commands.txt", JSON.stringify(commands), err => {
if(err) console.error(err);
});
我将如何编写机器人:
const playerCommands = require("./commands.js");
const defaultCommands = {
addCommand(...pairs) {
let result = "";
for(const pair of pairs) {
const [name, value] = pair.split(":");
playerCommands.addCommand(name, value);
result += `${name} added with value ${value}\n`;
}
return result;
}
};
client.on('message', ({ content, channel }) => {
if(content[0] !== "!") return; // ignore non-commandd
const [commandName, ...args] = content.slice(1).split(" ");
if(defaultCommands[commandName])
return channel.send(defaultCommands[commandName](...args));
const value = playerCommands.getValue(commandName);
if(value) return channel.send(value);
return channel.send("Command not found!");
});