UNPKG

discord.js-akinator-jp

Version:

アキネーターのコマンドを作ることができます。

282 lines (246 loc) 13.4 kB
const Discord = require("discord.js"); const { Aki } = require("aki-api"); const games = new Set(); const attemptingGuess = new Set(); /** * @param {Discord.Message} message The Message Sent by the User. * @param {Discord.Client} client The Discord Client. * @param {"en" | "ar" | "cn" | "de" | "es" | "fr" | "il" | "it" | "jp" | "kr" | "nl" | "pl" | "pt" | "ru" | "tr" | "id"} region (OPTIONAL): The Region/Language Code you want Akinator to Use. Defaults to "en". * @returns Discord.js Akinator Game * @async * @example * const Discord = require("discord.js"); * const client = new Discord.Client(); * const akinator = require("discord.js-akinator"); * * const PREFIX = "!"; * * client.on("message", async message => { * if(message.content.startsWith(`${PREFIX}akinator`)) { * akinator(message, client) * } * }); */ module.exports = async function (message, client, region) { try { // error handling if (!message) return console.log("Discord.js Akinator Error: メッセージ引数がundefined(nullish)です'"); if (!client) return console.log("Discord.js Akinator Error: Client引数がundefined(nullish)です"); if (!region) region = "jp" if (!message.id || !message.channel || !message.channel.id || !message.author) throw new Error("メッセージ引数の値が間違っています") if (!client.user.id || !client.user) throw new Error("Client引数の値が間違っています") if (!message.guild) throw new Error("DMでは使えません") // defining for easy use let usertag = message.author.tag let avatar = message.author.displayAvatarURL() // check if a game is being hosted by the player if (games.has(message.author.id)) { let alreadyPlayingEmbed = new Discord.MessageEmbed() .setAuthor(usertag, avatar) .setTitle(`❌あなたはすでにゲームをプレイしています`) .setDescription("**あなたはすでにゲームが始まっています。`S`または`Stop`と投稿することで停止できます。**") .setColor("RED") return message.channel.send({ embed: alreadyPlayingEmbed }) } // adding the player into the game games.add(message.author.id) let startingEmbed = new Discord.MessageEmbed() .setAuthor(usertag, avatar) .setTitle(`ゲームスタート中`) .setDescription("**あと3秒でゲームが始まります。**") .setColor("RANDOM") let startingMessage = await message.channel.send({ embed: startingEmbed }) // starts the game let aki = new Aki(region) await aki.start(); let notFinished = true; let stepsSinceLastGuess = 0; let hasGuessed = false; let noResEmbed = new Discord.MessageEmbed() .setAuthor(usertag, avatar) .setTitle(`ゲーム終了`) .setDescription(`**${message.author.username}、1分間操作がなかったためゲームが終了しました。**`) .setColor("RANDOM") let akiEmbed = new Discord.MessageEmbed() .setAuthor(usertag, avatar) .setTitle(`質問 ${aki.currentStep + 1}`) .setDescription(`**進行状況: 0%\n${aki.question}**`) .addField("送信してください", "**y** または **Yes**(はい)\n**n** または **No**(いいえ)\n**i** または **IDK**(わからない)\n**p** または **Probably**(たぶんそう/一部そう)\n**pn** または **Probably Not**(多分違う/一部違う)\n**b** または **Back**(戻る)") .setFooter(`「S」か「Stop」でゲーム終了`) .setColor("RANDOM") await startingMessage.delete(); let akiMessage = await message.channel.send({ embed: akiEmbed }); // if message was deleted, quit the player from the game client.on("messageDelete", async deletedMessage => { if (deletedMessage.id == akiMessage.id) { notFinished = false; games.delete(message.author.id) attemptingGuess.delete(message.guild.id) await aki.win() return; } }) // repeat while the game is not finished while (notFinished) { if (!notFinished) return; stepsSinceLastGuess = stepsSinceLastGuess + 1 if (((aki.progress >= 95 && (stepsSinceLastGuess >= 10 || hasGuessed == false)) || aki.currentStep >= 78) && (!attemptingGuess.has(message.guild.id))) { attemptingGuess.add(message.guild.id) await aki.win(); stepsSinceLastGuess = 0; hasGuessed = true; let guessEmbed = new Discord.MessageEmbed() .setAuthor(usertag, avatar) .setTitle(`私は${Math.round(aki.progress)}%完了して考えたキャラクターは...`) .setDescription(`**${aki.answers[0].name}**\n${aki.answers[0].description}\n\nこのキャラクターですか? **(y/Yes か n/No で回答)**`) .addField("ランキング", `**${aki.answers[0].ranking}位**`, true) .addField("質問数", `**${aki.currentStep}**`, true) .setImage(aki.answers[0].absolute_picture_path) .setColor("RANDOM") await akiMessage.edit({ embed: guessEmbed }); // valid answers if the akinator sends the last question const guessFilter = x => { return (x.author.id === message.author.id && ([ "y", "yes", "n", "no" ].includes(x.content.toLowerCase()))); } await message.channel.awaitMessages(guessFilter, { max: 1, time: 60000 }) .then(async responses => { if (!responses.size) { return akiMessage.edit({ embed: noResEmbed }); } const guessAnswer = String(responses.first()).toLowerCase(); await responses.first().delete(); attemptingGuess.delete(message.guild.id) // if they answered yes if (guessAnswer == "y" || guessAnswer == "yes") { let finishedGameCorrect = new Discord.MessageEmbed() .setAuthor(usertag, avatar) .setTitle(`よくやった!`) .setDescription(`**${message.author.username}、私はもう一度正しいと思いました!**`) .addField("キャラクター", `**${aki.answers[0].name}**`, true) .addField("ランキング", `**#${aki.answers[0].ranking}**`, true) .addField("何番目の質問?", `**${aki.currentStep}**`, true) .setColor("RANDOM") await akiMessage.edit({ embed: finishedGameCorrect }) notFinished = false; games.delete(message.author.id) return; // otherwise } else if (guessAnswer == "n" || guessAnswer == "no") { if (aki.currentStep >= 78) { let finishedGameDefeated = new Discord.MessageEmbed() .setAuthor(usertag, avatar) .setTitle(`よくやった!`) .setDescription(`**${message.author.username}、ブラボー!あなたに負けてしまった...**`) .setColor("RANDOM") await akiMessage.edit({ embed: finishedGameDefeated }) notFinished = false; games.delete(message.author.id) } else { aki.progress = 50 } } }); } if (!notFinished) return; let updatedAkiEmbed = new Discord.MessageEmbed() .setAuthor(usertag, avatar) .setTitle(`質問${aki.currentStep + 1}`) .setDescription(`**進行状況${Math.round(aki.progress)}%\n${aki.question}**`) .addField("送信してください", "**y** または **Yes**(はい)\n**n** または **No**(いいえ)\n**i** または **IDK**(わからない)\n**p** または **Probably**(たぶんそう/一部そう)\n**pn** または **Probably Not**(多分違う/一部違う)\n**b** または **Back**(戻る)") .setFooter(`\`S\`または\`Stop\`でゲーム終了`) .setColor("RANDOM") akiMessage.edit({ embed: updatedAkiEmbed }) // all valid answers when answering a regular akinator question const filter = x => { return (x.author.id === message.author.id && ([ "y", "yes", "n", "no", "i", "idk", "i", "dont know", "don't know", "p", "probably", "pn", "probably not", "b", "back", "s", "stop" ].includes(x.content.toLowerCase()))); } await message.channel.awaitMessages(filter, { max: 1, time: 60000 }) .then(async responses => { if (!responses.size) { await aki.win() notFinished = false; games.delete(message.author.id) return akiMessage.edit({ embed: noResEmbed }) } const answer = String(responses.first()).toLowerCase().replace("'", ""); // assign points for the possible answers given const answers = { "y": 0, "yes": 0, "n": 1, "no": 1, "i": 2, "idk": 2, "dont know": 2, "don't know": 2, "i": 2, "p": 3, "probably": 3, "pn": 4, "probably not": 4, } let thinkingEmbed = new Discord.MessageEmbed() .setAuthor(usertag, avatar) .setTitle(`質問${aki.currentStep + 1}`) .setDescription(`**進行状況: ${Math.round(aki.progress)}%\n${aki.question}**`) .addField("送信してください", "**y** または **Yes**(はい)\n**n** または **No**(いいえ)\n**i** または **IDK**(わからない)\n**p** または **Probably**(たぶんそう/一部そう)\n**pn** または **Probably Not**(多分違う/一部違う)\n**b** または **Back**(戻る)") .setFooter(`考え中です...少し待ってね`) .setColor("RANDOM") await akiMessage.edit({ embed: thinkingEmbed }) await responses.first().delete(); if (answer == "b" || answer == "back") { if (aki.currentStep >= 1) { await aki.back(); } // stop the game if the user selected to stop } else if (answer == "s" || answer == "stop") { games.delete(message.author.id) let stopEmbed = new Discord.MessageEmbed() .setAuthor(usertag, avatar) .setTitle(`ゲーム終了`) .setDescription(`**${message.author.username}、ゲームを終了しました!**`) .setColor("RANDOM") await aki.win() await akiMessage.edit({ embed: stopEmbed }) notFinished = false; } else { await aki.step(answers[answer]); } if (!notFinished) return; }); } } catch (e) { // log any errors that come attemptingGuess.delete(message.guild.id) games.delete(message.guild.id) if (e == "DiscordAPIError: Unknown Message") return; console.log(`Discord.js Akinator Error: ${e}`) } }