async def _daily_do_execute(self, cmd, _): user = await userlib.get_user(discord_id=int(cmd.author.id), register=True) status = '' for dtype in DailyType: daily = DailyMgr().daily(dtype) today_number = daily.today_number character = dailytype.character(dtype, today_number) old_char = dailytype.character(dtype, today_number - 1) last_registered = await daily.registered_daily(user.user_id) days_since_registering = today_number - last_registered submitted = await daily.has_submitted(last_registered, user.user_id) if days_since_registering == 1 and not submitted and daily.within_grace_period: status += "You have not gotten today's {1} seed. You may still submit for yesterday's {2} daily, " \ "which is open for another {0}. ".format(daily.daily_grace_timestr, character, old_char) elif days_since_registering != 0: status += "You have not yet registered for the {0} daily: " \ "Use `.dailyseed` to get today's seed. ".format(character) elif submitted: status += "You have submitted to the {1} daily. " \ "The next daily opens in {0}. ".format(daily.next_daily_timestr, character) else: status += "You have not yet submitted to the {1} daily: Use `.dailysubmit` to submit a result. " \ "Today's {1} daily is open for another {0}. ".format(daily.daily_close_timestr, character) await cmd.channel.send('{0}: {1}'.format(cmd.author.mention, status))
async def _daily_do_execute(self, cmd, daily): user = await userlib.get_user(discord_id=int(cmd.author.id), register=True) last_submitted = await daily.submitted_daily(user.user_id) character = dailytype.character(daily.daily_type, last_submitted) if last_submitted == 0: await cmd.channel.send( "{0}: You've never submitted for a daily of this type.".format( cmd.author.mention)) elif not daily.is_open(last_submitted): await cmd.channel.send("{0}: The {1} {2} daily has closed.".format( cmd.author.mention, daily.daily_to_shortstr(last_submitted), character)) else: submission_string = await daily.parse_submission( daily_number=last_submitted, user_id=user.user_id, args=cmd.args) if submission_string: # parse succeeded await daily.update_leaderboard(last_submitted) await cmd.channel.send( "Reubmitted for {0}, {2}: You {1}.".format( daily.daily_to_shortstr(last_submitted), submission_string, character)) else: # parse failed await cmd.channel.send( "{0}: I had trouble parsing your submission. Please use one of the forms: `{1} 12:34.56` " "or `{1} death 4-4`.".format(cmd.author.mention, self.mention))
async def _daily_do_execute(self, cmd, daily): user = await userlib.get_user(discord_id=int(cmd.author.id), register=True) daily_number = await daily.submitted_daily(user.user_id) character = dailytype.character(daily.daily_type, daily_number) if daily_number == 0: await self.client.send_message( cmd.channel, "{0}: You've never submitted for {1} daily.".format( cmd.author.mention, daily.daily_type)) return if not daily.is_open(daily_number): await self.client.send_message( cmd.channel, "{0}: The {1} {2} daily has closed.".format( cmd.author.mention, daily.daily_to_shortstr(daily_number), character)) return await daily.delete_from_daily(daily_number, user.user_id) await self.client.send_message( cmd.channel, "Deleted your daily submission for {0}, {1}.".format( daily.daily_to_shortstr(daily_number), character)) await daily.update_leaderboard(daily_number)
async def leaderboard_text(self, daily_number: int, display_seed=False): """The text (results) for the leaderboard""" text = "``` \n" text += self.leaderboard_header(daily_number) + '\n' if display_seed: for row in await dailydb.get_daily_seed( daily_id=daily_number, daily_type=self.daily_type.value): text += "Seed: {}\n".format(row[0]) break no_entries = True rank = int(0) prior_result = '' # detect and handle ties rank_to_display = int(1) reverse_levelsort = dailytype.character( daily_type=self.daily_type, daily_number=daily_number) == 'Aria' daily_times = sorted( await dailydb.get_daily_times(daily_id=daily_number, daily_type=self.daily_type.value), key=lambda x: level.level_sortval(int(x[1]), reverse=reverse_levelsort), reverse=True) for row in daily_times: name = strutil.tickless(row[0]) lv = row[1] time = row[2] if lv == level.LEVEL_FINISHED: result_string = racetime.to_str(time) elif lv == level.LEVEL_NOS: continue else: result_string = level.to_str(lv) if result_string == '': result_string = "death" else: result_string = "death ({0})".format(result_string) rank += 1 no_entries = False # update the rank only if we've gotten a different result than the last entrant if result_string != prior_result: # kinda hacky to use a string comparison here, but works rank_to_display = rank prior_result = result_string text += '{0: >3}. {1: <24} {2}\n'.format(rank_to_display, name, result_string) if no_entries: text += 'No entries yet.\n' text += '```' return text
async def _daily_do_execute(self, cmd, daily): character = dailytype.character(daily.daily_type, daily.today_number) # noinspection PyUnresolvedReferences await self.client.send_message( cmd.channel, "Rules for the {0} speedrun daily:\n" "\N{BULLET} {0} seeded all zones; get the seed for the daily using `.dailyseed`.\n" "\N{BULLET} Run the seed blind. Make one attempt and submit the result (even if you die).\n" "\N{BULLET} No restriction on resolution, display settings, zoom, etc.\n" "\N{BULLET} Mods that disable leaderboard submission are not allowed (e.g. xml / music mods)." .format(character))
async def _daily_do_execute(self, cmd, daily): today_number = daily.today_number for arg in cmd.args: charname = arg.lstrip('-').capitalize() if charname in dailytype.rotating_daily_chars: days_until = dailytype.days_until(charname, today_number) if days_until == 0: await self.client.send_message( cmd.channel, 'The {0} daily is today!'.format(charname)) return elif days_until == 1: await self.client.send_message( cmd.channel, 'The {0} daily is tomorrow!'.format(charname)) return elif days_until is not None: date = datetime.datetime.utcnow().date( ) + datetime.timedelta(days=days_until) await self.client.send_message( cmd.channel, 'The {0} daily is in {1} days ({2}, {3}).'.format( charname, days_until, calendar.day_name[date.weekday()], date.strftime("%B %d"))) return # If here, there were no args, so get a schedule char_list_str = '' today_number = DailyMgr().daily(DailyType.ROTATING).today_number today_char = dailytype.character(DailyType.ROTATING, today_number) char_found = False for charname in dailytype.rotating_daily_chars: if charname == today_char: char_found = True if char_found: char_list_str += charname + ' -- ' for charname in dailytype.rotating_daily_chars: if charname == today_char: break else: char_list_str += charname + ' -- ' char_list_str = char_list_str[:-4] await self.client.send_message( cmd.channel, 'Upcoming characters, starting today: {0}.'.format(char_list_str))
async def _daily_do_execute(self, cmd, daily): user = await userlib.get_user(discord_id=int(cmd.author.id), register=True) daily_number = await daily.registered_daily(user.user_id) character = dailytype.character(daily.daily_type, daily_number) if daily_number == 0: await self.client.send_message( cmd.channel, "{0}: Please get today's {1} daily seed before submitting (use `.dailyseed`)." .format(cmd.author.mention, character)) return if not daily.is_open(daily_number): await self.client.send_message( cmd.channel, "{0}: Too late to submit for the {1} {2} daily. Get today's seed with `.dailyseed`." .format(cmd.author.mention, daily.daily_to_shortstr(daily_number), character)) return if await daily.has_submitted(daily_number, user.user_id): await self.client.send_message( cmd.channel, "{0}: You have already submitted for the {1} {2} daily. " "Use `.dailyresubmit` to edit your submission.".format( cmd.author.mention, daily.daily_to_shortstr(daily_number), character)) return submission_string = await daily.parse_submission( daily_number=daily_number, user_id=user.user_id, args=cmd.args) if not submission_string: await self.client.send_message( cmd.channel, "{0}: I had trouble parsing your submission. " "Please use one of the forms: `{1} 12:34.56` or `{1} death 4-4`." .format(cmd.author.mention, self.mention)) return await daily.update_leaderboard(daily_number) await self.client.send_message( cmd.channel, "Submitted for {0}, {2}: You {1}.".format( daily.daily_to_shortstr(daily_number), submission_string, character))
async def _daily_do_execute(self, cmd, daily): user = await userlib.get_user(discord_id=int(cmd.author.id), register=True) today = daily.today_number today_date = daily.daily_to_date(today) character = dailytype.character(daily.daily_type, today) if await daily.has_submitted(today, user.user_id): await cmd.channel.send( "{0}: You have already submitted for today's {1} daily.". format(cmd.author.mention, character)) else: await daily.register(today, user.user_id) seed = await daily.get_seed(today) await cmd.channel.send( "({0}) {2} speedrun seed: {1}. This is a single-attempt {2} seeded all zones run. (See `.dailyrules` " "for complete rules.)".format(today_date.strftime("%d %b"), seed, character))
async def on_new_daily(self) -> None: """Run when a new daily happens""" # Make the leaderboard message text = await self.leaderboard_text(self.today_number, display_seed=False) msg = await self.client.send_message(self._leaderboard_channel, text) await self.register_message(self.today_number, msg.id) # Update yesterday's leaderboard with the seed await self.update_leaderboard(self.today_number - 1, display_seed=True) # PM users with the daily_alert preference auto_pref = UserPrefs(daily_alert=True, race_alert=None) for member_id in await userdb.get_all_discord_ids_matching_prefs( auto_pref): member = server.find_member(discord_id=member_id) if member is not None: await self.register(self.today_number, member.id) await self.client.send_message( member, "({0}) Today's {2} speedrun seed: {1}".format( self.today_date.strftime("%d %b"), await self.get_seed(self.today_number), dailytype.character(self.daily_type, self.today_number)))
async def _daily_do_execute(self, cmd, _): rotating_daily = DailyMgr().daily(DailyType.ROTATING) character = dailytype.character(DailyType.ROTATING, rotating_daily.today_number) await cmd.channel.send('Today\'s character is {0}.'.format(character))