diff options
author | 2021-11-04 16:02:37 -0400 | |
---|---|---|
committer | 2022-02-09 18:13:37 -0500 | |
commit | a08e127f1535f63a24e785bfb1c16c445491303d (patch) | |
tree | 80770e3c989a59c1a3030961d1a74768c13b58a9 /bot | |
parent | kahoot style scoring, time limits, and bug fixes (diff) |
bug fixes
Diffstat (limited to 'bot')
-rw-r--r-- | bot/exts/events/trivianight/_questions.py | 13 | ||||
-rw-r--r-- | bot/exts/events/trivianight/_scoreboard.py | 6 | ||||
-rw-r--r-- | bot/exts/events/trivianight/trivianight.py | 75 |
3 files changed, 76 insertions, 18 deletions
diff --git a/bot/exts/events/trivianight/_questions.py b/bot/exts/events/trivianight/_questions.py index aaedf068..8f2f5571 100644 --- a/bot/exts/events/trivianight/_questions.py +++ b/bot/exts/events/trivianight/_questions.py @@ -1,3 +1,4 @@ +import logging from random import choice, randrange from time import perf_counter from typing import Optional, TypedDict, Union @@ -10,6 +11,8 @@ from bot.constants import Colours, NEGATIVE_REPLIES from ._scoreboard import Scoreboard +logger = logging.getLogger(__name__) + class UserScore: """Marker class for passing into the scoreboard to add points/record speed.""" @@ -93,7 +96,9 @@ class QuestionView(View): for button in self.buttons: self.add_item(button) - def create_current_question(self) -> Embed: + self.active_question = False + + def create_current_question(self) -> Union[Embed, None]: """Helper function to create the embed for the current question.""" question_embed = Embed( title=f"Question {self.current_question['number']}", @@ -110,6 +115,8 @@ class QuestionView(View): time_limit = self.current_question.get("time", 10) + self.active_question = True + return question_embed, time_limit def end_question(self) -> tuple[dict, Embed]: @@ -151,6 +158,8 @@ class QuestionView(View): time_limit = self.current_question.get("time", 10) question_points = self.current_question.get("points", 10) + self.active_question = False + return return_dict, answer_embed, time_limit, question_points @@ -183,7 +192,7 @@ class Questions: while "visited" in self.questions[question_number].keys(): question_number = randrange(0, len(self.questions)) else: - question_number = number + question_number = number - 1 self.questions[question_number]["visited"] = True self.view.current_question = self.questions[question_number] diff --git a/bot/exts/events/trivianight/_scoreboard.py b/bot/exts/events/trivianight/_scoreboard.py index 2adb5e37..076fd406 100644 --- a/bot/exts/events/trivianight/_scoreboard.py +++ b/bot/exts/events/trivianight/_scoreboard.py @@ -79,7 +79,7 @@ class ScoreboardView(View): name="Total Points", value=( f"You got {points_rank}{'th' if not (suffix := suffixes.get(points_rank[-1])) else suffix} place" - f" with {self.points[member.id]} points." + f" with {self.points[member.id]:.1f} points." ), inline=False ) @@ -108,12 +108,12 @@ class Scoreboard: """Class for the scoreboard for the Trivia Night event.""" def __setitem__(self, key: str, value: int): - if key.user_id not in self.view.points.keys(): + if value.get("points") and key.user_id not in self.view.points.keys(): self.view.points[key.user_id] = value["points"] else: self.view.points[key.user_id] += self.view.points[key.user_id] - if key.user_id not in self.view.speed.keys(): + if value.get("speed") and key.user_id not in self.view.speed.keys(): self.view.speed[key.user_id] = [1, value["speed"]] else: self.view.speed[key.user_id] = [ diff --git a/bot/exts/events/trivianight/trivianight.py b/bot/exts/events/trivianight/trivianight.py index 9973b6b1..46db8c74 100644 --- a/bot/exts/events/trivianight/trivianight.py +++ b/bot/exts/events/trivianight/trivianight.py @@ -1,12 +1,13 @@ import asyncio -from json import loads +from json import JSONDecodeError, loads from random import choice +from typing import Optional from discord import Embed from discord.ext import commands from bot.bot import Bot -from bot.constants import Colours, POSITIVE_REPLIES +from bot.constants import Colours, NEGATIVE_REPLIES, POSITIVE_REPLIES from ._questions import QuestionView, Questions from ._scoreboard import Scoreboard, ScoreboardView @@ -43,10 +44,27 @@ class TriviaNight(commands.Cog): await ctx.send(embed=cog_description) @trivianight.command() - async def load(self, ctx: commands.Context) -> None: + async def load(self, ctx: commands.Context, *, to_load: Optional[str]) -> None: """Load the JSON file provided into the questions.""" - json_text = (await ctx.message.attachments[0].read()).decode("utf8") - serialized_json = loads(json_text) + if ctx.message.attachments: + json_text = (await ctx.message.attachments[0].read()).decode("utf8") + elif to_load.startswith("https://discord.com/channels") or \ + to_load.startswith("https://discordapp.com/channels"): + channel_id, message_id = to_load.split("/")[-2:] + channel = await ctx.guild.fetch_channel(int(channel_id)) + message = await channel.fetch_message(int(message_id)) + if message.attachments: + json_text = (await message.attachments[0].read()).decode("utf8") + else: + json_text = message.content.replace("```", "").replace("json", "") + else: + json_text = message.content.replace("```", "").replace("json", "") + + try: + serialized_json = loads(json_text) + except JSONDecodeError: + raise commands.BadArgument("Invalid JSON") + for idx, question in enumerate(serialized_json): serialized_json[idx] = {**question, **{"description": self.unicodeify(question["description"])}} self.questions.view = QuestionView() @@ -64,7 +82,8 @@ class TriviaNight(commands.Cog): """Resets previous questions and scoreboards.""" self.scoreboard.view = ScoreboardView(self.bot) for question in self.questions.questions: - del question["visited"] + if "visited" in question.keys(): + del question["visited"] success_embed = Embed( title=choice(POSITIVE_REPLIES), @@ -76,20 +95,35 @@ class TriviaNight(commands.Cog): @trivianight.command() async def next(self, ctx: commands.Context) -> None: """Gets a random question from the unanswered question list and lets user choose the answer.""" + if self.questions.view.active_question is True: + error_embed = Embed( + title=choice(NEGATIVE_REPLIES), + description="There is already an ongoing question!", + color=Colours.soft_red + ) + await ctx.send(embed=error_embed) + return + next_question = self.questions.next_question() if isinstance(next_question, Embed): await ctx.send(embed=next_question) return (question_embed, time_limit), question_view = self.questions.current_question() - await ctx.send(embed=question_embed, view=question_view) + message = await ctx.send(embed=question_embed, view=question_view) + + for time_remaining in range(time_limit, -1, -1): + if self.questions.view.active_question is False: + await ctx.send(embed=self.questions.end_question()) + await message.edit(embed=question_embed, view=None) + return - for time_remaining in range(time_limit - 1, -1, -1): await asyncio.sleep(1) - if time_remaining % 5 == 0: + if time_remaining % 5 == 0 and time_remaining not in (time_limit, 0): await ctx.send(f"{time_remaining}s remaining") await ctx.send(embed=self.questions.end_question()) + await message.edit(embed=question_embed, view=None) @trivianight.command() async def question(self, ctx: commands.Context, question_number: int) -> None: @@ -100,14 +134,20 @@ class TriviaNight(commands.Cog): return (question_embed, time_limit), question_view = self.questions.current_question() - await ctx.send(embed=question_embed, view=question_view) + message = await ctx.send(embed=question_embed, view=question_view) + + for time_remaining in range(time_limit, -1, -1): + if self.questions.view.active_question is False: + await ctx.send(embed=self.questions.end_question()) + await message.edit(embed=question_embed, view=None) + return - for time_remaining in range(time_limit - 1, -1, -1): await asyncio.sleep(1) - if time_remaining % 5 == 0: + if time_remaining % 5 == 0 and time_remaining not in (time_limit, 0): await ctx.send(f"{time_remaining}s remaining") await ctx.send(embed=self.questions.end_question()) + await message.edit(embed=question_embed, view=None) @trivianight.command() async def list(self, ctx: commands.Context) -> None: @@ -121,7 +161,16 @@ class TriviaNight(commands.Cog): @trivianight.command() async def stop(self, ctx: commands.Context) -> None: """End the ongoing question to show the correct question.""" - await ctx.send(embed=self.questions.end_question()) + if self.questions.view.active_question is False: + error_embed = Embed( + title=choice(NEGATIVE_REPLIES), + description="There is not an ongoing question to stop!", + color=Colours.soft_red + ) + await ctx.send(embed=error_embed) + return + + self.questions.view.active_question = False @trivianight.command() async def end(self, ctx: commands.Context) -> None: |