自定义的不和谐游戏第一次运行良好,但第二次搞砸了



我制作了一个不和谐的自定义游戏。它从scramble-words.json文件中的单词列表中抓取单词并对其进行加扰。这些单词会被放入文本聊天中,玩游戏的用户必须尝试找到实际单词。它会删除自你开始游戏以来发送的所有新消息,并在游戏处于活动状态时保持频道清洁。你必须键入这个词,如果它是正确的,你就得了一分。

第一次运行命令时,代码运行良好。第二次出现错误UnhandledPromiseRejectionWarning: DiscordAPIError: Unknown Message和您在新游戏中发送的每一条消息。

我试着查找它是否需要我将games = {}变量指定为常量,但我不认为这是问题所在,我想不出它还能是什么。

const { words } = require('./scramble-words.json');
const Discord = require('discord.js');
/*const example = {
channelId: {
message:'message object',
stage: 'string',
counter: 'number',
currentWord: 'string',
remainingWords: ['words here'],
points: {
userId: 'points'
}
}
}*/
const games = {}
const stages = {
'STARTING': (counter, topic) => {
return `-----------------------------**Game**------------------------------nA new "${topic} Scramble" game is starting in ${counter}s!`
},
'IN_GAME': (word, topic) => {
let scrambledWord = '';
if(topic === "Brawlhalla"){
topic = "Brawlhalla related thing"
}
scrambledWord = shuffle(word);
return `-----------------------------**Game**------------------------------nWhat ${topic} is this?nn **${scrambledWord}**`
},
'ENDING': (points) => {
const sorted = Object.keys(points).sort((a, b) => {
return points[b] - points[a]
})
let embed = new Discord.MessageEmbed();
embed.setTitle('**POINTS**')
.setDescription(`**The game is now over! Here's how everyone did!**`);
var results = `n`
var firstPlace = points[sorted[0]]
var secondPlace = null
var thirdPlace = null
var leftover = null
for(const key of sorted) {
var amount = points[key]
if(leftover){
results += `<@${key}> had ${amount} point${amount === 1 ? '' : 's'}n`
} else if(thirdPlace) {
if(thirdPlace === amount) {
results += `:third_place: <@${key}> had ${amount} point${amount === 1 ? '' : 's'}n`
} else {
results += `n`
results += `<@${key}> had ${amount} point${amount === 1 ? '' : 's'}n`
leftover = amount
}
} else if(secondPlace) {
if(secondPlace === amount) {
results += `:second_place: <@${key}> had ${amount} point${amount === 1 ? '' : 's'}n`
} else {
results += `n`
results += `:third_place: <@${key}> had ${amount} point${amount === 1 ? '' : 's'}n`
thirdPlace = amount
}

} else if(firstPlace) {

if(firstPlace === amount) {
results += `:first_place: <@${key}> had ${amount} point${amount === 1 ? '' : 's'}n`

} else {
results += `n`
results += `:second_place: <@${key}> had ${amount} point${amount === 1 ? '' : 's'}n`
secondPlace = amount

}

}
}
if(results === `n`){
return embed.setTimestamp().addField(`**Nobody got points you losers**`, "  ");
} else {
return embed.setTimestamp().addField(`**Here's how everyone did**`, results)
}
}
}
const selectWord = (game) => {
game.currentWord = game.remainingWords[Math.floor(Math.random() * game.remainingWords.length)]
const index = game.remainingWords.indexOf(game.currentWord);
game.remainingWords.splice(index, 1);

game.currentWord = game.currentWord.toLowerCase().charAt(0).toUpperCase() + game.currentWord.toLowerCase().substring(1);
}
const gameLoop = async () => {
for(const key in games) {
const game = games[key];
const { message, stage } = game;
const gameLength = 2.345
if(stage === 'STARTING') {
let string = stages[stage](game.counter, game.topic)
message.edit(string)
if(game.counter <= 0) {
game.stage = 'IN_GAME'
game.counter = 60 * gameLength
selectWord(game)

string = stages[game.stage](game.currentWord, game.topic)
message.edit(string)

}
} else if (stage === 'IN_GAME') {
if(game.counter <= 0) {
game.stage = 'ENDING'
if(game.topic === "Brawlhalla")
{
game.topic === "Brawlhalla related thing"

}
const string = `-----------------------------**Game**------------------------------nThe last ${game.topic} was: ${game.currentWord}n------------------------------**End**-------------------------------`
message.edit(string)
embed = stages[game.stage](game.points);
message.channel.send(embed)
await delete games[key]
await delete game
return
}
}
--game.counter
}
setTimeout(gameLoop, 1000)

}
module.exports = {
scramble(member, channel, content, guild, message, { reply }, client) {
/*if(!member.hasPermission('ADMINISTRATOR')){
reply(true, `You don't have permission to execute this command!`)
return;
}*/
if(channel.name !== "scramble-games" && channel.name !== "games"){

reply(true, `You can only do this command in a channel called "scramble-games" or "games"`);
return;
}
if(games[channel.id]){
return;
}
message.delete();
var chosenCategory= []
if(content[0]){
if(content[0].toLowerCase() === "pokemon"){
if(content[1]){
var numbers = content[1].split('')
if(!isNaN(content[1])){
for(var i = 0; i < numbers.length; i++){
if(numbers[i] === "1") {
chosenCategory = chosenCategory.concat(pokemonGeneration1)
} else if(numbers[i] === "2") {
chosenCategory = chosenCategory.concat(pokemonGeneration2)
} else if(numbers[i] === "3") {
chosenCategory = chosenCategory.concat(pokemonGeneration3)

} else if(numbers[i] === "4") {
chosenCategory = chosenCategory.concat(pokemonGeneration4)

} else if(numbers[i] === "5") {
chosenCategory = chosenCategory.concat(pokemonGeneration5)

} else if(numbers[i] === "6") {
chosenCategory = chosenCategory.concat(pokemonGeneration6)

} else if(numbers[i] === "7") {
chosenCategory = chosenCategory.concat(pokemonGeneration7)

} else if(numbers[i] === "8") {
chosenCategory = chosenCategory.concat(pokemonGeneration8)

} else {
reply(true, `The numbers you gave had a number that is higher than 8. There are only 8 gens. Try again but keep the numbers you give under 8`)
return;
}
}
} else {
reply(true, `If you want to specify gens you have to give numbers only! example: 1456 will give gens 1, 4, 5 and 6`)
return;
}
} else {
chosenCategory = chosenCategory.concat(pokemonGeneration1, pokemonGeneration2, pokemonGeneration3, pokemonGeneration4, pokemonGeneration5, pokemonGeneration6, pokemonGeneration7, pokemonGeneration8)
}
topics = "Pokemon"

} else if (content[0].toLowerCase() === "brawlhalla" || content[0].toLowerCase() === "brawl"){

chosenCategory = chosenCategory.concat(BrawlhallaLegends, BrawlhallaWeapons, BrawlhallaWords, BrawlhallaColors, BrawlhallaStances, BrawlhallaChests, BrawlhallaGamemodes)
topics = "Brawlhalla"

} else {
reply(true, `That's not a valid topic for this game!`);
return
}
} else {
chosenCategory = words
topics = "Random Word"

}
channel.send('Preparing Game...').then((message) => {
games[channel.id] = {
message,
stage: 'STARTING',
counter: 10,
remainingWords: [...chosenCategory],
points: {},
topic: topics
}
});
gameLoop(channel)
client.on('message', message => {
const { channel, content, member } = message;
const { id } = channel
const game = games[id];
if(game && game.currentWord && !member.user.bot) {
checkWord(game, member, message, content);
}
if (game && !message.author.bot) {
message.delete();
}
return;
});
}
}
function checkWord(game, member, message, content){
if(game.stage === 'IN_GAME' && content.toLowerCase() === game.currentWord.toLowerCase()) {
const owo = game.currentWord;
game.currentWord = null;
const seconds = 3;
const { points } = game
points[member.id]  = points[member.id] || 0
message.reply(`You got it!n The correct answer was: **${owo}**n +1 point (${++points[member.id]} total)`).then(newMessage => {
newMessage.delete({
timeout: 1000 * seconds

});
});
setTimeout(() => {
if(game.stage === 'IN_GAME') {
selectWord(game)
const string = stages[game.stage](game.currentWord, game.topic)
game.message.edit(string);
}
}, 1000 * seconds);
}
}
function shuffle(word) {
var wordArray = word.split(' ');
var output = []
for(var i = 0; i < wordArray.length; i++) {
var array = wordArray[i].split('');
var currentIndex = array.length;
var temporaryValue;
var randomIndex;

// While there remain elements to shuffle...
while (0 !== currentIndex) {

// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;

// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
output = output.concat(array)
if(!i + 1 === wordArray.length){
output.push(' ');

}
}

return output.join('');
}

这也是json文件,所以你可以自己尝试游戏

{

"words": [
"Provincial",
"Grudge",
"Foundation",
"Carry",
"Fight",
"Belt",
"Perforate",
"Obstacle",
"Hide",
"Lesson",
"Car",
"Building",
"Mourning",
"Debut",
"Sunrise",
"Scatter",
"Clash",
"Equation",
"Performer",
"Ask",
"Butterfly",
"Medieval",
"Think",
"Minimum",
"Play",
"Sofa",
"Minority",
"Friend",
"Protect",
"Mess",
"Disability",
"Planet",
"Federation",
"Film",
"Vegetarian",
"Utter",
"Polish",
"Ankle",
"Calendar",
"Extreme",
"Student",
"Barrier",
"Motif",
"Solo",
"Toast",
"Steel",
"Speaker",
"Concede",
"Suit",
"gimping",
"Weal",
"Affords",
"Palship",
"Trefoil",
"Kirtled",
"Jaybirds",
"Shires",
"Gobbling",
"Puffery",
"Bag",
"Idoneous",
"Aerates",
"Kitchens",
"Zorils",
"Students",
"Idles",
"Howe",
"Veenas",
"Airship",
"Olefins",
"Munsters",
"Polemics",
"Lentos",
"Snog",
"Fusel",
"Giglot",
"Pinafore",
"Snowiest",
"Saxtuba",
"Division",
"Mantlet",
"Nurtures",
"Geoponic",
"Civvies",
"Trommels",
"Engraver",
"Know",
"Gummoses",
"Disbands",
"Parse",
"Donator",
"Minces",
"Lofted",
"Punters",
"Lie",
"Rune",
"Dottiest",
"Mib",
"Enwraps",
"Bizzes",
"Nitride",
"Ire",
"Bricole",
"Bigness",
"Roadeos",
"Midriffs",
"Fallers",
"Postcode",
"Sterigma",
"Duvetyne",
"Alumroot",
"Purins",
"Pricking",
"Deluders",
"Postcoup",
"Daggas",
"Rallies",
"Vocably",
"Gravida",
"Eluded",
"Dicyclic",
"Starers",
"Afflatus",
"Misbind",
"Coadmire",
"Overrule",
"Marquis",
"Pogromed",
"Dulled",
"Lantana",
"Garotte",
"Keek",
"Dhak",
"Mescals",
"Trichite",
"Theurgic",
"Cretins",
"Codicils",
"Depside",
"Cadres",
"Desium",
"Indene",
"Depicted",
"Opticist",
"Hoptoad",
"Jacking",
"Girasole",
"Wedeln",
"Pull"
]
}

删除消息,然后尝试获取该消息,或在方法中使用该消息时,会出现未知消息错误。我可以在您的代码中看到2个message#delete方法,这些方法几乎总是导致这些错误的原因。仔细查看代码,找到要删除消息的位置,并确保之后没有使用任何与该消息有关的内容。这里的帖子显示了这些错误是如何发生的。

我可以看出这个错误会引发的一个原因,如果你在游戏中迭代,你在第一个游戏中使用message#delete,程序运行良好,然后在所有其他迭代中,它会引发这个错误。这是因为message#delete正在尝试删除已删除的消息(即,当您在第一个游戏中第一次删除它时)。

最新更新