fix a bug where if the user enocouters an error it would still wouild be makred as ongoing trivia

This commit is contained in:
Ayden Jahola 2024-09-06 00:00:30 +01:00
parent 50bfb9c6e3
commit d693d2f714
No known key found for this signature in database
GPG key ID: 71DD90AE4AE92742

View file

@ -43,152 +43,167 @@ module.exports = {
// Add the user to the set of active trivia players // Add the user to the set of active trivia players
ongoingTrivia.add(userId); ongoingTrivia.add(userId);
const categoryId = interaction.options.getString("category"); try {
const categoryName = categoryId === "15" ? "Video Games" : "Anime & Manga"; const categoryId = interaction.options.getString("category");
const categoryName =
categoryId === "15" ? "Video Games" : "Anime & Manga";
// Fetch a trivia question from the cache or the API // Fetch a trivia question from the cache or the API
let triviaQuestion = await TriviaQuestion.findOne({ let triviaQuestion = await TriviaQuestion.findOne({
last_served: { $lt: new Date(Date.now() - QUESTION_EXPIRY) }, // Fetch questions not served recently last_served: { $lt: new Date(Date.now() - QUESTION_EXPIRY) }, // Fetch questions not served recently
category: categoryName, // Filter by category
}).sort({ last_served: 1 });
if (!triviaQuestion || Date.now() - lastApiCall >= API_INTERVAL) {
// Fetch a new trivia question from OTDB
const response = await axios.get(
`https://opentdb.com/api.php?amount=1&category=${categoryId}`
);
triviaQuestion = response.data.results[0];
lastApiCall = Date.now();
// Save the new trivia question to MongoDB
await TriviaQuestion.create({
question: decode(triviaQuestion.question),
correct_answer: decode(triviaQuestion.correct_answer),
incorrect_answers: triviaQuestion.incorrect_answers.map(decode),
category: categoryName, // Include the category
last_served: null, // Initially not served
});
// Fetch the newly created question
triviaQuestion = await TriviaQuestion.findOne({
question: decode(triviaQuestion.question),
category: categoryName, // Filter by category category: categoryName, // Filter by category
}); }).sort({ last_served: 1 });
}
if (triviaQuestion) { if (!triviaQuestion || Date.now() - lastApiCall >= API_INTERVAL) {
triviaQuestion.last_served = new Date(); // Fetch a new trivia question from OTDB
await triviaQuestion.save(); const response = await axios.get(
} `https://opentdb.com/api.php?amount=1&category=${categoryId}`
const question = decode(triviaQuestion.question);
const correctAnswer = decode(triviaQuestion.correct_answer);
const incorrectAnswers = triviaQuestion.incorrect_answers.map(decode);
let allAnswers = [...incorrectAnswers, correctAnswer];
// Handle True/False questions specifically
if (triviaQuestion.type === "boolean") {
allAnswers = ["True", "False"];
}
allAnswers = allAnswers.sort(() => Math.random() - 0.5); // Shuffle answers
// Create a mapping of numbers to answers
const answerMap = allAnswers.reduce((map, answer, index) => {
map[index + 1] = answer;
return map;
}, {});
// Create an embed with the trivia question and numbered options
const triviaEmbed = new EmbedBuilder()
.setColor("#0099ff")
.setTitle("Trivia Question")
.setDescription(question)
.addFields(
Object.entries(answerMap).map(([number, answer]) => ({
name: `Option ${number}`,
value: answer,
inline: true,
}))
)
.setTimestamp()
.setFooter({
text: `${guild.name} | Answer within ${timeLimit / 1000} seconds`,
iconURL: guild.iconURL(),
});
await interaction.reply({
embeds: [triviaEmbed],
});
// Create a message collector specific to the user
const answerFilter = (response) => {
const userInput = response.content.trim();
const userAnswerNumber = parseInt(userInput, 10);
const userAnswerText =
allAnswers.includes(userInput) ||
(answerMap[userAnswerNumber] &&
answerMap[userAnswerNumber] === correctAnswer);
// Check if the input is a number within valid range or a text that matches one of the options
return (
response.author.id === userId &&
(userAnswerText || (userAnswerNumber >= 1 && userAnswerNumber <= 4))
);
};
const answerCollector = interaction.channel.createMessageCollector({
filter: answerFilter,
max: 1,
time: timeLimit,
});
answerCollector.on("collect", async (message) => {
const userInput = message.content.trim();
const userAnswerNumber = parseInt(userInput, 10);
const userAnswer = answerMap[userAnswerNumber] || userInput;
let resultMessage = "Incorrect! Better luck next time.";
if (userAnswer === correctAnswer) {
resultMessage = "Correct!";
}
// Update leaderboard
let userScore = await Leaderboard.findOne({ userId });
if (!userScore) {
userScore = new Leaderboard({
userId,
username,
gamesPlayed: 1,
correctAnswers: userAnswer === correctAnswer ? 1 : 0,
});
} else {
userScore.gamesPlayed += 1;
if (userAnswer === correctAnswer) {
userScore.correctAnswers += 1;
}
}
await userScore.save();
await interaction.followUp(
`${resultMessage} <@${userId}> You've answered ${userScore.correctAnswers} questions correctly out of ${userScore.gamesPlayed} games.`
);
// Remove user from the ongoing trivia set once the game is finished
ongoingTrivia.delete(userId);
});
answerCollector.on("end", (collected, reason) => {
if (reason === "time") {
interaction.followUp(
`<@${userId}> Time's up! You didn't answer in time.`
); );
// Remove user from the ongoing trivia set when the game times out triviaQuestion = response.data.results[0];
ongoingTrivia.delete(userId); lastApiCall = Date.now();
// Save the new trivia question to MongoDB
await TriviaQuestion.create({
question: decode(triviaQuestion.question),
correct_answer: decode(triviaQuestion.correct_answer),
incorrect_answers: triviaQuestion.incorrect_answers.map(decode),
category: categoryName, // Include the category
last_served: null, // Initially not served
});
// Fetch the newly created question
triviaQuestion = await TriviaQuestion.findOne({
question: decode(triviaQuestion.question),
category: categoryName, // Filter by category
});
} }
});
if (triviaQuestion) {
triviaQuestion.last_served = new Date();
await triviaQuestion.save();
}
const question = decode(triviaQuestion.question);
const correctAnswer = decode(triviaQuestion.correct_answer);
const incorrectAnswers = triviaQuestion.incorrect_answers.map(decode);
let allAnswers = [...incorrectAnswers, correctAnswer];
// Handle True/False questions specifically
if (triviaQuestion.type === "boolean") {
allAnswers = ["True", "False"];
}
allAnswers = allAnswers.sort(() => Math.random() - 0.5); // Shuffle answers
// Create a mapping of numbers to answers
const answerMap = allAnswers.reduce((map, answer, index) => {
map[index + 1] = answer;
return map;
}, {});
// Create an embed with the trivia question and numbered options
const triviaEmbed = new EmbedBuilder()
.setColor("#0099ff")
.setTitle("Trivia Question")
.setDescription(question)
.addFields(
Object.entries(answerMap).map(([number, answer]) => ({
name: `Option ${number}`,
value: answer,
inline: true,
}))
)
.setTimestamp()
.setFooter({
text: `${guild.name} | Answer within ${timeLimit / 1000} seconds`,
iconURL: guild.iconURL(),
});
await interaction.reply({
embeds: [triviaEmbed],
});
// Create a message collector specific to the user
const answerFilter = (response) => {
const userInput = response.content.trim();
const userAnswerNumber = parseInt(userInput, 10);
const userAnswerText =
allAnswers.includes(userInput) ||
(answerMap[userAnswerNumber] &&
answerMap[userAnswerNumber] === correctAnswer);
// Check if the input is a number within valid range or a text that matches one of the options
return (
response.author.id === userId &&
(userAnswerText || (userAnswerNumber >= 1 && userAnswerNumber <= 4))
);
};
const answerCollector = interaction.channel.createMessageCollector({
filter: answerFilter,
max: 1,
time: timeLimit,
});
answerCollector.on("collect", async (message) => {
const userInput = message.content.trim();
const userAnswerNumber = parseInt(userInput, 10);
const userAnswer = answerMap[userAnswerNumber] || userInput;
let resultMessage = "Incorrect! Better luck next time.";
if (userAnswer === correctAnswer) {
resultMessage = "Correct!";
}
// Update leaderboard
let userScore = await Leaderboard.findOne({ userId });
if (!userScore) {
userScore = new Leaderboard({
userId,
username,
gamesPlayed: 1,
correctAnswers: userAnswer === correctAnswer ? 1 : 0,
});
} else {
userScore.gamesPlayed += 1;
if (userAnswer === correctAnswer) {
userScore.correctAnswers += 1;
}
}
await userScore.save();
await interaction.followUp(
`${resultMessage} <@${userId}> You've answered ${userScore.correctAnswers} questions correctly out of ${userScore.gamesPlayed} games.`
);
// Remove user from the ongoing trivia set once the game is finished
ongoingTrivia.delete(userId);
});
answerCollector.on("end", (collected, reason) => {
if (reason === "time") {
interaction.followUp(
`<@${userId}> Time's up! You didn't answer in time.`
);
// Remove user from the ongoing trivia set when the game times out
ongoingTrivia.delete(userId);
}
});
} catch (error) {
console.error("Error fetching trivia question:", error);
// Inform the user about the error and let them retry
await interaction.reply({
content:
"There was an error fetching your trivia question. Please try again later.",
ephemeral: true,
});
// Remove the user from the ongoing trivia set in case of an error
ongoingTrivia.delete(userId);
}
}, },
}; };