From 4e1214a312f9cfa8347e6b27d7744f812d4d3b18 Mon Sep 17 00:00:00 2001 From: ION606 Date: Mon, 18 Jul 2022 20:44:38 +0300 Subject: [PATCH] Added the 'trivia' commands --- .gitignore | 3 +- commands/games/trivia.js | 157 ++++++++++++++++++++++++++ commands/games/trivia_categories.json | 28 +++++ commands/utils/jsonFormatters.js | 1 + package-lock.json | 11 ++ package.json | 1 + 6 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 commands/games/trivia.js create mode 100644 commands/games/trivia_categories.json diff --git a/.gitignore b/.gitignore index 8a01abc..12bb89f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,4 @@ config.json *.txt !spec/LevelsXP.txt *.sqlite -temp.js -trivia.js \ No newline at end of file +temp.js \ No newline at end of file diff --git a/commands/games/trivia.js b/commands/games/trivia.js new file mode 100644 index 0000000..80f7836 --- /dev/null +++ b/commands/games/trivia.js @@ -0,0 +1,157 @@ +const request = require('request'); +const fetch = require('node-fetch'); +const categoriesJSON = require('./trivia_categories.json').trivia_categories; +const { decode } = require('html-entities'); +const { MongoClient, ServerApiVersion } = require('mongodb'); + + +const categories = new Map(); +for (i in categoriesJSON) { + categories.set(categoriesJSON[i].name, categoriesJSON[i].id); +} +// const { jsonToMapRecursive, mapToTableRecursive } = require('../utils/jsonFormatters.js'); + + +function changeDB(bot, message, m) { + try { + const client = new MongoClient(bot.mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 }); + client.connect(err => { + const dbo = client.db(message.guild.id).collection('trivia'); + //Game Over + if (m == null) { + return dbo.deleteOne({ channel: message.channel.id }); + } + + dbo.findOne({ channel: message.channel.id }).then((doc) => { + if (doc) { + dbo.updateOne({ channel: message.channel.id }, {$set: { m: Object.fromEntries(m) }}); + } else{ + dbo.insertOne({ channel: message.channel.id, m: Object.fromEntries(m) }); + } + }); + + }); + + } catch (err) { + console.log(err); + } +} + + + + + +/** + * @param {*} message + * @param {Map} m + * @param {int} time + */ +function startTrivia(message, m, time, bot) { + const obj = m.values().next().value; + const question = obj.question; + const answer = obj.answer; + console.log(answer); + + const filter = (response) => { + // return item.answers.some(answer => answer.toLowerCase() === response.content.toLowerCase()); + return (response.content.toLowerCase() == answer.toLowerCase()); + }; + + message.reply({ content: question, fetchReply: true }) + .then(() => { + //time: 1000 = 1 second + message.channel.awaitMessages({ filter, max: 10, time: time }) // , errors: ['time'] + .then((collected) => { + if (collected.size > 0) { + message.reply(`${collected.first().author} got the correct answer (${answer})!`); + } else { + message.reply('Tsk Tsk, looks like nobody got the answer this time.'); + } + + changeDB(bot, message, null); + }) + .catch((collected) => { + console.log(collected); + message.reply('Tsk Tsk, looks like nobody got the answer this time.'); + changeDB(bot, message, null); + }); + }); +} + + +//Add shuffle button + +module.exports = { + name: 'trivia', + description: 'Play a game of Trivia with yourself or others! - (use _trivia help_)', + async execute(message, args, Discord, Client, bot) { + const difficult = ['easy', 'medium', 'hard']; + let inputs = ['easy', '']; + + if (args[0] && difficult.includes(args[0].toLowerCase())) { + inputs[0] = args[0].toLowerCase(); + } else if (args[0] == 'help') { + let temp = `Use ${bot.prefix}trivia [difficulty (easy, medium, hard)] [topic] [time]\n`; + temp += '**__Trivia Categories__**\n'; + m.forEach((val, key) => { + temp += `_${key}_\n`; + }) + temp += '_Please copy and paste the FULL NAME if you want to use a category'; + + return message.reply(temp); + } + + if (args[1] && Array.from(categories.keys()).includes(args[1])) { + inputs[1] = categories.get(args[1]); + } + + // Get all categories mapped to their ids + // const a = await fetch('https://opentdb.com/api_category.php'); + // const json = await a.json(); + // console.log(json); + + var url = `https://opentdb.com/api.php?amount=${5}&difficulty=${inputs[0]}&type=multiple`; + if (inputs[1] != '') { + url += `&category=${inputs[1]}`; + } + + request(url, function (error, response, body) { + if (!error && response.statusCode == 200) { + // const m = new Map(body); + let s = body.replace('{"response_code":0,"results":[', ''); + s = s.substring(0, s.length - 2); + let queries = s.split('},'); + + const m = new Map(); + let i = 0; + + queries.forEach((query, ind) => { + query = query.substring(1, s.length - 2); + if (query.endsWith('}')) { query = query.substring(0, s.length - 2); } + + // console.log(decode(query)); + query = decode(query); + + //Get the answer (may have "" in it) + const question = query.substring(query.indexOf('question":') + 10, query.indexOf('","correct_answer')); + // console.log(`Q: ${question}\n\nActual: ${query}\n---------------------------------------`); + + let q = query.split('","'); + // queries[ind] = q; + + q[5] = q[5].split(':[')[1]; + + let obj = { question: q[3].split(':"')[1], answer: q[4].split(':"')[1], incorrect: [ q[5].replaceAll('"', ''), q[6].replaceAll('"', ''), q[7].replaceAll(']}', '').replaceAll(']', '').replaceAll('"', '') ] } + m.set(i, obj); + i ++; + }); + + const time = args[2] || (difficult[0].indexOf(inputs[0]) + 1) * 10000; + changeDB(bot, message, m); + startTrivia(message, m, time, bot); + } + }) + + + } +} \ No newline at end of file diff --git a/commands/games/trivia_categories.json b/commands/games/trivia_categories.json new file mode 100644 index 0000000..c2895d0 --- /dev/null +++ b/commands/games/trivia_categories.json @@ -0,0 +1,28 @@ +{ + "trivia_categories": [ + { "id": 9, "name": "General Knowledge" }, + { "id": 10, "name": "Entertainment: Books" }, + { "id": 11, "name": "Entertainment: Film" }, + { "id": 12, "name": "Entertainment: Music" }, + { "id": 13, "name": "Entertainment: Musicals & Theatres" }, + { "id": 14, "name": "Entertainment: Television" }, + { "id": 15, "name": "Entertainment: Video Games" }, + { "id": 16, "name": "Entertainment: Board Games" }, + { "id": 17, "name": "Science & Nature" }, + { "id": 18, "name": "Science: Computers" }, + { "id": 19, "name": "Science: Mathematics" }, + { "id": 20, "name": "Mythology" }, + { "id": 21, "name": "Sports" }, + { "id": 22, "name": "Geography" }, + { "id": 23, "name": "History" }, + { "id": 24, "name": "Politics" }, + { "id": 25, "name": "Art" }, + { "id": 26, "name": "Celebrities" }, + { "id": 27, "name": "Animals" }, + { "id": 28, "name": "Vehicles" }, + { "id": 29, "name": "Entertainment: Comics" }, + { "id": 30, "name": "Science: Gadgets" }, + { "id": 31, "name": "Entertainment: Japanese Anime & Manga" }, + { "id": 32, "name": "Entertainment: Cartoon & Animations" } + ] +} \ No newline at end of file diff --git a/commands/utils/jsonFormatters.js b/commands/utils/jsonFormatters.js index 0e19554..2fc1278 100644 --- a/commands/utils/jsonFormatters.js +++ b/commands/utils/jsonFormatters.js @@ -72,3 +72,4 @@ function mapToTableRecursive(inp, layer = 1) { +module.exports = { jsonToMapRecursive, mapToTableRecursive } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a5c0de7..676a161 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "ffmpeg": "^0.0.4", "ffmpeg-static": "^5.0.0", "hastebin-gen": "^2.0.5", + "html-entities": "^2.3.3", "libsodium-wrappers": "^0.7.10", "mal-scraper": "^2.11.4", "mongoose": "^6.3.2", @@ -1488,6 +1489,11 @@ "node-fetch": "^2.6.0" } }, + "node_modules/html-entities": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + }, "node_modules/htmlparser2": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", @@ -6719,6 +6725,11 @@ "node-fetch": "^2.6.0" } }, + "html-entities": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + }, "htmlparser2": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", diff --git a/package.json b/package.json index 116986d..86b6621 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "ffmpeg": "^0.0.4", "ffmpeg-static": "^5.0.0", "hastebin-gen": "^2.0.5", + "html-entities": "^2.3.3", "libsodium-wrappers": "^0.7.10", "mal-scraper": "^2.11.4", "mongoose": "^6.3.2",