async def end(self): embed = self.score.embed() winners = [get_best_username(Storage().get(self.plugin), x) for x in self.score.winners()] # Übergangslösung points = self.score.points() for user in points: self.plugin.update_ladder(user, points[user]) msgkey = "quiz_end" if len(winners) > 1: msgkey = "quiz_end_pl" elif len(winners) == 0: msgkey = "quiz_end_no_winner" winners = utils.format_andlist(winners, ands=Lang.lang(self.plugin, "and"), emptylist=Lang.lang(self.plugin, "nobody")) msg = Lang.lang(self.plugin, msgkey, winners) if msg is None: await self.channel.send(embed=embed) elif embed is None: await self.channel.send(msg) else: await self.channel.send(msg, embed=embed) self.plugin.end_quiz(self.channel)
async def end(self): embed = self.score.embed() winners = [get_best_username(Storage().get(self.plugin), x) for x in self.score.winners()] msgkey = "quiz_end" if len(winners) > 1: msgkey = "quiz_end_pl" elif len(winners) == 0: msgkey = "quiz_end_no_winner" winners = utils.format_andlist(winners, ands=Lang.lang(self.plugin, "and"), emptylist=Lang.lang(self.plugin, "nobody")) msg = Lang.lang(self.plugin, msgkey, winners) if msg is None: await self.channel.send(embed=embed) elif embed is None: await self.channel.send(msg) else: await self.channel.send(msg, embed=embed) if self.ranked: for player in self.registered_participants: self.plugin.update_ladder(player, self.score.calc_points(player)) self.plugin.end_quiz(self.channel)
async def eval(self): """ Is called when the question is over. Evaluates scores and cancels the timer. :return: """ self.plugin.logger.debug("Ending question") # End timeout timer if self.current_question_timer is not None: try: self.current_question_timer.cancel() except utils.HasAlreadyRun: self.plugin.logger.warning("This should really, really not happen.") self.current_question_timer = None else: # We ran into a timeout and need to give that function time to communicate this fact await asyncio.sleep(1) if self.current_reaction_listener is not None: self.current_reaction_listener.unregister() question = self.quizapi.current_question() # Normalize answers for el in self.registered_participants: if len(self.registered_participants[el]) != 1: self.registered_participants[el] = None else: self.registered_participants[el] = self.registered_participants[el][0] # Increment scores correctly_answered = [] for user in self.registered_participants: if question.check_answer(self.registered_participants[user], emoji=True): correctly_answered.append(user) for user in correctly_answered: self.score.increase(user, self.current_question, totalcorr=len(correctly_answered)) correct = [get_best_username(Storage().get(self.plugin), el) for el in correctly_answered] correct = utils.format_andlist(correct, Lang.lang(self.plugin, "and"), Lang.lang(self.plugin, "nobody")) if self.config["emoji_in_pose"]: ca = question.correct_answer_emoji else: ca = question.correct_answer_letter await self.channel.send(Lang.lang(self.plugin, "points_question_done", ca, correct)) # Reset answers list for user in self.registered_participants: self.registered_participants[user] = [] await asyncio.sleep(self.config["question_cooldown"]) self.state = Phases.QUESTION
async def timeout(self, question): """ :param question: Question object of the question that was running at timer start time. """ if self.current_question != question or self.state != Phases.QUESTION: # We are out of date self.plugin.logger.debug("Timeout warning out of date") return self.current_question_timer = None self.plugin.logger.debug("Question timeout") msg = Lang.lang(self.plugin, "points_timeout", self.quizapi.current_question_index(), utils.format_andlist(self.havent_answered_hr(), ands=Lang.lang(self.plugin, "and"))) self.state = Phases.EVAL await self.channel.send(msg)
async def collecting_phase(self): assert len(self.participants) > 1 msg = [utils.get_best_username(el.user) for el in self.participants] msg = utils.format_andlist(msg, ands=Lang.lang(self, "and")) msg = Lang.lang(self, "list_participants", msg) await self.channel.send(msg) shuffled = self.participants.copy() utils.trueshuffle(shuffled) for i in range(len(self.participants)): self.participants[i].assign(shuffled[i]) for el in self.participants: await el.init_dm()
async def timeout_warning(self, question): """ :param question: Question object of the question that was running at timer start time. """ if self.current_question != question or self.state != Phases.QUESTION: # We are out of date self.plugin.logger.debug("Timeout warning out of date") return self.plugin.logger.debug("Question timeout warning") self.current_question_timer = utils.AsyncTimer(self.plugin.bot, self.config["points_quiz_question_timeout"] // 2, self.timeout, self.current_question) msg = Lang.lang(self.plugin, "points_timeout_warning", utils.format_andlist(self.havent_answered_hr(), ands=Lang.lang(self.plugin, "and")), self.config["points_quiz_question_timeout"] // 2) panic = not self.havent_answered_hr() await self.channel.send(msg) if panic: await self.channel.send("I know this should not happen. Please leave a !complain, thank you very much.")
async def statuscmd(self, ctx): if self.statemachine.state == State.IDLE: await ctx.send(Lang.lang(self, "not_running")) return elif self.statemachine.state == State.REGISTER: await ctx.send(Lang.lang(self, "status_aborting")) return elif self.statemachine.state == State.DELIVER: await ctx.send(Lang.lang(self, "status_delivering")) return elif self.statemachine.state == State.ABORT: await ctx.send(Lang.lang(self, "status_aborting")) return assert self.statemachine.state == State.COLLECT waitingfor = [] for el in self.participants: if el.chosen is None: waitingfor.append(utils.get_best_username(el.user)) wf = utils.format_andlist(waitingfor, ands=Lang.lang(self, "and"), emptylist=Lang.lang(self, "nobody")) await ctx.send(Lang.lang(self, "waiting_for", wf))
async def registering_phase(self): self.logger.debug("Starting registering phase") self.postgame = False reaction = Lang.lang(self, "reaction_signup") to = self.config["register_timeout"] msg = Lang.lang( self, "registering", reaction, to, utils.sg_pl(to, Lang.lang(self, "minute_sg"), Lang.lang(self, "minute_pl"))) msg = await self.channel.send(msg) try: await msg.add_reaction(Lang.lang(self, "reaction_signup")) except HTTPException: # Unable to add reaction, therefore unable to begin the game await self.channel.send("PANIC") self.statemachine.state = State.ABORT return await asyncio.sleep(to * 60) # Consume signup reactions self.participants = [] await msg.remove_reaction(Lang.lang(self, "reaction_signup"), self.bot.user) signup_msg = discord.utils.get(self.bot.cached_messages, id=msg.id) reaction = None for el in signup_msg.reactions: if el.emoji == Lang.lang(self, "reaction_signup"): reaction = el break candidates = [] blocked = [] if reaction is not None: async for user in reaction.users(): if user == self.bot.user: continue if self.bot.dm_listener.is_blocked(user): blocked.append(utils.get_best_username(user)) else: candidates.append(user) if blocked: blocked = utils.format_andlist(blocked, ands=Lang.lang(self, "and")) await self.channel.send(Lang.lang(self, "dmblocked", blocked)) self.statemachine.state = State.ABORT return for el in candidates: try: self.participants.append(Participant(self, el)) except RuntimeError: await msg.add_reaction(Lang.CMDERROR) self.statemachine.state = State.ABORT return players = len(self.participants) if players <= 1: await self.channel.send(Lang.lang(self, "no_participants")) self.statemachine.state = State.ABORT else: self.statemachine.state = State.COLLECT