Implement trivia welcome screen with category picker

This commit is contained in:
2022-12-21 17:59:25 +01:00
parent d4c3afbddd
commit 1c19f3c07f
13 changed files with 184 additions and 40 deletions

View File

@@ -1,14 +1,19 @@
package wtf.beatrice.hidekobot.util;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
import net.dv8tion.jda.api.interactions.components.selections.SelectOption;
import org.apache.commons.text.StringEscapeUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.objects.TriviaQuestion;
import wtf.beatrice.hidekobot.objects.TriviaScore;
import wtf.beatrice.hidekobot.objects.fun.TriviaCategory;
import wtf.beatrice.hidekobot.objects.fun.TriviaQuestion;
import wtf.beatrice.hidekobot.objects.fun.TriviaScore;
import wtf.beatrice.hidekobot.runnables.TriviaTask;
import java.io.BufferedReader;
import java.io.IOException;
@@ -18,11 +23,13 @@ import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class TriviaUtil
{
private final static String link = "https://opentdb.com/api.php?amount=10&type=multiple";
private final static String triviaLink = "https://opentdb.com/api.php?amount=10&type=multiple&category=";
private final static String categoriesLink = "https://opentdb.com/api_category.php";
public static List<String> channelsRunningTrivia = new ArrayList<>();
@@ -32,7 +39,10 @@ public class TriviaUtil
// first string is the channelId, the list contain all score records for that channel
public static HashMap<String, List<TriviaScore>> channelAndScores = new HashMap<>();
public static JSONObject fetchTrivia()
public static String getTriviaLink(int categoryId) {return triviaLink + categoryId; }
public static String getCategoriesLink() {return categoriesLink; }
public static JSONObject fetchJson(String link)
{
try {
URL url = new URL(link);
@@ -54,7 +64,7 @@ public class TriviaUtil
return null;
}
public static List<TriviaQuestion> getQuestions(JSONObject jsonObject)
public static List<TriviaQuestion> parseQuestions(JSONObject jsonObject)
{
List<TriviaQuestion> questions = new ArrayList<>();
@@ -82,6 +92,23 @@ public class TriviaUtil
return questions;
}
public static List<TriviaCategory> parseCategories(JSONObject jsonObject)
{
List<TriviaCategory> categories = new ArrayList<>();
JSONArray categoriesArray = jsonObject.getJSONArray("trivia_categories");
for(Object categoryObject : categoriesArray)
{
JSONObject categoryJson = (JSONObject) categoryObject;
String name = categoryJson.getString("name");
int id = categoryJson.getInt("id");
categories.add(new TriviaCategory(name, id));
}
return categories;
}
public static void handleAnswer(ButtonInteractionEvent event, AnswerType answerType)
{
User user = event.getUser();
@@ -150,6 +177,59 @@ public class TriviaUtil
}
}
public static void handleMenuSelection(StringSelectInteractionEvent event)
{
// check if the user interacting is the same one who ran the command
if(!(Cache.getDatabaseSource().isUserTrackedFor(event.getUser().getId(), event.getMessageId())))
{
event.reply("❌ You did not run this command!").setEphemeral(true).queue();
return;
}
// todo: we shouldn't use this method, since it messes with the database... look at coin reflip
CommandUtil.disableExpired(event.getMessageId());
SelectOption pickedOption = event.getInteraction().getSelectedOptions().get(0);
String categoryName = pickedOption.getLabel();
String categoryIdString = pickedOption.getValue();
Integer categoryId = Integer.parseInt(categoryIdString);
TriviaCategory category = new TriviaCategory(categoryName, categoryId);
startTrivia(event, category);
}
public static void startTrivia(StringSelectInteractionEvent event, TriviaCategory category)
{
User author = event.getUser();
Message message = event.getMessage();
MessageChannel channel = message.getChannel();
if(TriviaUtil.channelsRunningTrivia.contains(channel.getId()))
{
// todo nicer looking
// todo: also what if the bot stops (database...?)
// todo: also what if the message is already deleted
Message err = event.reply("Trivia is already running here!").complete().retrieveOriginal().complete();
Cache.getTaskScheduler().schedule(() -> err.delete().queue(), 10, TimeUnit.SECONDS);
return;
} else {
// todo nicer looking
event.reply("Starting new Trivia session!").queue();
}
TriviaTask triviaTask = new TriviaTask(author, channel, category);
ScheduledFuture<?> future =
Cache.getTaskScheduler().scheduleAtFixedRate(triviaTask,
0,
15,
TimeUnit.SECONDS);
triviaTask.setScheduledFuture(future);
TriviaUtil.channelsRunningTrivia.add(channel.getId());
}
public enum AnswerType {
CORRECT, WRONG
}