Esempio n. 1
0
 async def nonracepreset(self, ctx, preset, hints=False):
     seed, preset_dict = await get_preset(preset,
                                          hints=hints,
                                          spoilers="on",
                                          tournament=False)
     if not seed:
         raise SahasrahBotException(
             'Could not generate game.  Maybe preset does not exist?')
     embed = await seed.embed(emojis=self.bot.emojis)
     await ctx.send(embed=embed)
Esempio n. 2
0
    async def custom(self, ctx, tournament: bool = True):
        try:
            if not ctx.message.attachments[0].filename.endswith('.json'):
                raise SahasrahBotException(
                    'File should have a .json extension.')
        except IndexError as err:
            raise SahasrahBotException(
                'You must attach a customizer save json file.') from err

        customizer_settings = await get_customizer_json(
            ctx.message.attachments[0].url)

        settings = pyz3r.customizer.convert2settings(customizer_settings,
                                                     tournament=tournament)

        seed = await alttpr(customizer=True, settings=settings)

        embed = await seed.embed(emojis=self.bot.emojis)
        await ctx.send(embed=embed)
Esempio n. 3
0
async def get_preset(preset,
                     hints=False,
                     nohints=False,
                     spoilers="off",
                     tournament=True,
                     randomizer='alttpr'):
    # make sure someone isn't trying some path traversal shennaniganons
    basename = os.path.basename(f'{preset}.yaml')

    try:
        async with aiofiles.open(
                os.path.join(f"presets/{randomizer}", basename)) as f:
            preset_dict = yaml.safe_load(await f.read())
        if preset_dict.get('festive') and not await config.get(
                0, 'FestiveMode') == "true":
            raise PresetNotFoundException(
                f'Could not find preset {preset}.  See a list of available presets at <https://l.synack.live/presets>'
            )
    except FileNotFoundError as err:
        raise PresetNotFoundException(
            f'Could not find preset {preset}.  See a list of available presets at <https://l.synack.live/presets>'
        ) from err

    if preset_dict.get('randomizer', randomizer) == 'alttpr':
        if hints:
            preset_dict['settings']['hints'] = 'on'
        elif nohints:
            preset_dict['settings']['hints'] = 'off'

        preset_dict['settings']['tournament'] = tournament
        preset_dict['settings']['spoilers'] = spoilers

        seed = await alttpr(customizer=preset_dict.get('customizer', False),
                            festive=preset_dict.get('festive', False),
                            settings=preset_dict['settings'])
        hash_id = seed.hash
    elif preset_dict.get('randomizer', randomizer) in ['sm', 'smz3']:
        preset_dict['settings']['race'] = "true" if tournament else "false"
        seed = await pyz3r.sm(randomizer=randomizer,
                              settings=preset_dict['settings'])
        hash_id = seed.slug_id
    else:
        raise SahasrahBotException(
            f'Randomizer {randomizer} is not supported.')

    await audit.insert_generated_game(
        randomizer=randomizer,
        hash_id=hash_id,
        permalink=seed.url,
        settings=preset_dict['settings'],
        gentype='preset',
        genoption=preset,
        customizer=1 if preset_dict.get('customizer', False) else 0)
    return seed, preset_dict
Esempio n. 4
0
 async def srl(self, ctx, nick):
     user = await nick_verifier.get_irc_user(nick)
     if user:
         if await nick_verifier.send_key(ctx.author.id, nick):
             await ctx.send(
                 "A private message has been sent to you in SRL by SahasrahBot.  Please click the link in the message sent to you.\n\nIf you have not received this message, please contact Synack for assistance.\n\nThanks!"
             )
     else:
         raise SahasrahBotException(
             "The user specified is not logged into SRL. Please ensure your logged into SRL and identified by NickServ."
         )
Esempio n. 5
0
async def generate_preset(preset_dict,
                          preset=None,
                          hints=False,
                          nohints=False,
                          spoilers="off",
                          tournament=True,
                          allow_quickswap=False):
    randomizer = preset_dict.get('randomizer', 'alttpr')
    settings = preset_dict['settings']

    if randomizer == 'alttpr':
        if hints:
            settings['hints'] = 'on'
        elif nohints:
            settings['hints'] = 'off'

        settings['tournament'] = tournament
        settings['spoilers'] = spoilers

        if allow_quickswap:
            settings['allow_quickswap'] = True

        if preset_dict.get('customizer', False):
            for i in preset_dict.get('forced_locations', {}):
                settings['l'][random.choice(i['locations'])] = i['item']

        seed = await alttpr(customizer=preset_dict.get('customizer', False),
                            festive=preset_dict.get('festive', False),
                            settings=settings)
        hash_id = seed.hash

    elif randomizer in ['sm', 'smz3']:
        settings['race'] = "true" if tournament else "false"
        seed = await pyz3r.sm(
            randomizer=randomizer,
            settings=settings,
            baseurl=SMZ3_ENVIRONMENTS[preset_dict.get('env',
                                                      'live')][randomizer],
        )
        hash_id = seed.slug_id

    else:
        raise SahasrahBotException(
            f'Randomizer {randomizer} is not supported.')

    await audit.insert_generated_game(
        randomizer=randomizer,
        hash_id=hash_id,
        permalink=seed.url,
        settings=settings,
        gentype='preset',
        genoption=preset,
        customizer=1 if preset_dict.get('customizer', False) else 0)
    return seed
Esempio n. 6
0
 async def quickswaprace(self, ctx, preset, hints=False):
     seed, _ = await get_preset(preset,
                                hints=hints,
                                spoilers="off",
                                tournament=True,
                                allow_quickswap=True)
     if not seed:
         raise SahasrahBotException(
             'Could not generate game.  Maybe preset does not exist?')
     embed = await seed.embed(emojis=self.bot.emojis)
     await ctx.send(embed=embed)
Esempio n. 7
0
 async def mystery_custom(self, ctx):
     if ctx.message.attachments:
         content = await ctx.message.attachments[0].read()
         weights = yaml.safe_load(content)
         await randomgame(ctx=ctx,
                          weights=weights,
                          weightset='custom',
                          tournament=True,
                          spoilers="mystery")
     else:
         raise SahasrahBotException("You must supply a valid yaml file.")
Esempio n. 8
0
 async def spoiler(self, ctx, preset):
     seed, _, spoiler_log_url = await generate_spoiler_game(preset)
     if not seed:
         raise SahasrahBotException(
             'Could not generate game.  Maybe preset does not exist?')
     embed = await seed.embed(emojis=self.bot.emojis)
     embed.insert_field_at(0,
                           name="Spoiler Log URL",
                           value=spoiler_log_url,
                           inline=False)
     await ctx.send(embed=embed)
Esempio n. 9
0
    async def role_create(self, ctx, group_id: int, role_name: discord.Role, name, description, emoji, protect_mentions: bool = True):
        existing_roles = await role.get_group_roles(group_id, ctx.guild.id)
        if len(existing_roles) >= 20:
            raise SahasrahBotException(
                'No more than 20 roles can be on a group.  Please create a new group.')

#        if discord.utils.find(lambda e: str(e) == emoji, ctx.bot.emojis) is None and not is_emoji(emoji):
#            raise SahasrahBotException(
#                'Custom emoji is not available to this bot.')

        await role.create_role(ctx.guild.id, group_id, role_name.id, name, emoji, description, protect_mentions)
        await refresh_bot_message(ctx, group_id)
Esempio n. 10
0
 async def random_custom(self, ctx, tournament: bool = True):
     if ctx.message.attachments:
         content = await ctx.message.attachments[0].read()
         weights = yaml.safe_load(content)
         await randomgame(ctx=ctx,
                          weights=weights,
                          weightset='custom',
                          tournament=tournament,
                          spoilers="off",
                          festive=False)
     else:
         raise SahasrahBotException("You must supply a valid yaml file.")
Esempio n. 11
0
 async def preset_custom(self, ctx, tournament: bool = True):
     if ctx.message.attachments:
         content = await ctx.message.attachments[0].read()
         preset_dict = yaml.safe_load(content)
         seed = await generate_preset(preset_dict,
                                      preset='custom',
                                      spoilers="off",
                                      tournament=True)
     else:
         raise SahasrahBotException("You must supply a valid yaml file.")
     embed = await seed.embed(emojis=self.bot.emojis)
     await ctx.send(embed=embed)
Esempio n. 12
0
    async def host(
        self,
        ctx: discord.ApplicationContext,
        multidata: Option(discord.Attachment, "Multiworld data",
                          required=True),
        use_server_options: Option(bool, "Use server options?") = False,
    ):
        """
        Uploads a multiworld file to the Bonta Multiworld server.
        """
        data = {
            'multidata_url': multidata.url,
            'admin': ctx.author.id,
            'use_server_options': use_server_options,
            'meta': {
                'channel':
                None if isinstance(ctx.channel, discord.DMChannel) else
                ctx.channel.name,
                'guild':
                ctx.guild.name if ctx.guild else None,
                'multidata_url':
                multidata.url,
                'name':
                f'{ctx.author.name}#{ctx.author.discriminator}'
            }
        }
        try:
            multiworld = await http.request_json_post(
                url='http://localhost:5000/game', data=data, returntype='json')
        except ClientResponseError as err:
            raise SahasrahBotException(
                'Unable to generate host using the provided multidata.  Ensure you\'re using the latest version of the mutiworld (<https://github.com/Bonta0/ALttPEntranceRandomizer/tree/multiworld_31>)!'
            ) from err

        if not multiworld.get('success', True):
            raise SahasrahBotException(
                f"Unable to generate host using the provided multidata.  {multiworld.get('description', '')}"
            )

        await ctx.respond(embed=make_embed(multiworld))
Esempio n. 13
0
    async def mwmsg(self, ctx, token, msg):
        result = await http.request_generic(url=f'http://localhost:5000/game/{token}', method='get', returntype='json')

        if not result.get('success', True):
            raise SahasrahBotException("That game does not exist.")

        if not (result['admin'] == ctx.author.id or (
            (discord.utils.get(ctx.author.roles, id=507932829527703554) or discord.utils.get(ctx.author.roles, id=482266765137805333)) and result['meta']['guild'] == "CommunautΓ© ALttPR francophone")
        ):
            raise SahasrahBotException('You must be the creator of the game to send messages to it.')

        data = {
            'msg': msg
        }
        response = await http.request_json_put(url=f'http://localhost:5000/game/{token}/msg', data=data, returntype='json')

        if response.get('success', True) is False:
            raise SahasrahBotException(response.get(
                'error', 'Unknown error occured while processing message.'))

        if 'resp' in response and response['resp'] is not None:
            await ctx.reply(response['resp'])
Esempio n. 14
0
    async def mwmsg(self, ctx, token, msg):
        result = await http.request_generic(
            url=f'http://localhost:5000/game/{token}',
            method='get',
            returntype='json')

        if not result['admin'] == ctx.author.id:
            raise SahasrahBotException(
                'You must be the creater of the game to send messages to it.')

        data = {'msg': msg}
        await http.request_json_put(
            url=f'http://localhost:5000/game/{token}/msg', data=data)
Esempio n. 15
0
    async def send_player_message(self, name: str, player: discord.Member, embed: discord.Embed):
        if self.rtgg_handler is None:
            raise SahasrahBotException("No RaceTime.gg handler associated with this tournament game.")

        if player is None:
            await self.audit_channel.send(f"@here could not send DM to {name}", allowed_mentions=discord.AllowedMentions(everyone=True))
            await self.rtgg_handler.send_message(f"Could not send DM to {name}.  Please contact a Tournament Moderator for assistance.")
        try:
            await player.send(embed=embed)
        except discord.HTTPException:
            if self.audit_channel:
                await self.audit_channel.send(f"@here could not send DM to {player.name}#{player.discriminator}", allowed_mentions=discord.AllowedMentions(everyone=True))
            await self.rtgg_handler.send_message(f"Could not send DM to {player.name}#{player.discriminator}.  Please contact a Tournament Moderator for assistance.")
Esempio n. 16
0
    async def get_csrf_token(self):
        async with aiohttp.ClientSession(cookie_jar=jar) as session:
            try:
                async with session.request(method='get',
                                           url=self.base_url,
                                           raise_for_status=True) as resp:
                    soup = BeautifulSoup(await resp.text(),
                                         features="html5lib")
            except Exception as e:
                raise SahasrahBotException(
                    "Unable to acquire CSRF token.  Please contact Synack for help."
                ) from e

            return soup.find('input', {'name': 'csrfmiddlewaretoken'})['value']
Esempio n. 17
0
async def create_group(guild_id, channel_id, message_id, name, description,
                       bot_managed: int):
    existing_groups = await orm.select(
        'SELECT id from reaction_group WHERE channel_id = %s and message_id=%s and guild_id = %s;',
        [channel_id, message_id, guild_id])

    if len(existing_groups) > 0:
        raise SahasrahBotException(
            'Group already exists for specified message.')

    await orm.execute(
        'INSERT into reaction_group (`guild_id`,`channel_id`,`message_id`,`name`,`description`,`bot_managed`) values (%s, %s, %s, %s, %s, %s)',
        [guild_id, channel_id, message_id, name, description, bot_managed])
    await aiocache.SimpleMemoryCache().clear(namespace="role")
Esempio n. 18
0
 async def convertcustomizer(self, ctx):
     if ctx.message.attachments:
         content = await ctx.message.attachments[0].read()
         customizer_save = json.loads(content)
         settings = pyz3r.customizer.convert2settings(customizer_save)
         preset_dict = {
             'customizer': True,
             'goal_name': "REPLACE WITH SRL GOAL STRING",
             'randomizer': 'alttpr',
             'settings': settings
         }
         await ctx.send(file=discord.File(
             io.StringIO(yaml.dump(preset_dict)), filename=f"output.yaml"))
     else:
         raise SahasrahBotException("You must supply a valid yaml file.")
Esempio n. 19
0
    async def kisspriest(self, ctx, count=10):
        if count > 10 or count < 1:
            raise SahasrahBotException(
                "Number of games generated must be between 1 and 10.")

        seeds = await create_priestmode(count=count,
                                        genclass=alttprDiscordClass)
        embed = discord.Embed(title='Kiss Priest Games',
                              color=discord.Color.blurple())
        for idx, seed in enumerate(seeds):
            embed.add_field(
                name=seed.data['spoiler']['meta'].get('name', f"Game {idx}"),
                value=
                f"{seed.url}\n{seed.build_file_select_code(self.bot.emojis)}",
                inline=False)
        await ctx.send(embed=embed)
Esempio n. 20
0
    async def create_bingo_room(self,
                                room_name,
                                passphrase,
                                game_type,
                                variant_type=None,
                                lockout_mode='1',
                                seed='',
                                custom_json='',
                                is_spectator='on',
                                hide_card='on'):
        csrftoken = await self.get_csrf_token()
        data = {
            'csrfmiddlewaretoken': csrftoken,
            'nickname': self.nickname,
            'room_name': room_name,
            'passphrase': passphrase,
            'game_type': game_type,
            'lockout_mode': lockout_mode,
            'seed': seed,
            'custom_json': custom_json,
            'is_spectator': is_spectator,
            'hide_card': hide_card
        }

        if variant_type is not None:
            data['variant_type'] = variant_type

        async with aiohttp.ClientSession(cookie_jar=jar) as session:
            async with session.request(method='post',
                                       url=BINGOSYNC_BASE_URL,
                                       headers={
                                           'Origin': BINGOSYNC_BASE_URL,
                                           'Referer': BINGOSYNC_BASE_URL
                                       },
                                       allow_redirects=False,
                                       raise_for_status=True,
                                       data=data) as resp:
                jar.save('data/bingosync.cookie')
                print(await resp.text())
                if resp.status == 302:
                    self.room_id: str = resp.headers['Location'].split("/")[-1]
                    self.password = data['passphrase']
                else:
                    raise SahasrahBotException(
                        "Unable to create BingoSync room!")
Esempio n. 21
0
async def generate_preset(preset_dict,
                          preset=None,
                          hints=False,
                          nohints=False,
                          spoilers="off",
                          tournament=True,
                          allow_quickswap=False):
    randomizer = preset_dict.get('randomizer', 'alttpr')

    if randomizer == 'alttpr':
        if hints:
            preset_dict['settings']['hints'] = 'on'
        elif nohints:
            preset_dict['settings']['hints'] = 'off'

        preset_dict['settings']['tournament'] = tournament
        preset_dict['settings']['spoilers'] = spoilers

        if allow_quickswap:
            preset_dict['settings']['allow_quickswap'] = True

        seed = await alttpr(customizer=preset_dict.get('customizer', False),
                            festive=preset_dict.get('festive', False),
                            settings=preset_dict['settings'])
        hash_id = seed.hash
    elif randomizer in ['sm', 'smz3']:
        preset_dict['settings']['race'] = "true" if tournament else "false"
        seed = await pyz3r.sm(randomizer=randomizer,
                              settings=preset_dict['settings'],
                              baseurl='https://sm.samus.link'
                              if randomizer == 'sm' else 'https://samus.link')
        hash_id = seed.slug_id
    else:
        raise SahasrahBotException(
            f'Randomizer {randomizer} is not supported.')

    await audit.insert_generated_game(
        randomizer=randomizer,
        hash_id=hash_id,
        permalink=seed.url,
        settings=preset_dict['settings'],
        gentype='preset',
        genoption=preset,
        customizer=1 if preset_dict.get('customizer', False) else 0)
    return seed
Esempio n. 22
0
    def get_player_discords(self):
        player_list = []
        for match in ['match1', 'match2']:
            if self.episode[match] is None:
                continue
            for player in self.episode[match]['players']:
                try:
                    if not player.get('discordId', '') == '':
                        member = self.guild.get_member(int(player['discordId']))
                    else:
                        member = self.guild.get_member_named(player['discordTag'])
                    
                    if member is None:
                        raise SahasrahBotException(f"Unable to resolve Discord User for {player['displayName']} ({player['discordTag']}).  Please contact a moderator for help.")
                    player_list.append(member)
                except discord.HTTPException:
                    pass

        return player_list
Esempio n. 23
0
    async def _roll_general(self):
        self.spoiler_log_url = None

        if self.gen_type == 'preset':
            self.preset = WEEKDATA[self.week]['preset']
            self.seed, self.preset_dict = await preset.get_preset(
                self.preset, nohints=True, allow_quickswap=True)
        elif self.gen_type == 'mystery':
            self.weightset = WEEKDATA[self.week]['weightset']
            self.seed = await mystery.generate_random_game(
                weightset=self.weightset, spoilers="mystery", tournament=True)
        elif self.gen_type == 'spoiler':
            self.preset = WEEKDATA[self.week]['preset']
            self.studyperiod = WEEKDATA[self.week]['studyperiod']
            self.seed, self.preset_dict, self.spoiler_log_url = await spoilers.generate_spoiler_game(
                WEEKDATA[self.week]['preset'])
        else:
            raise SahasrahBotException(
                'Week type not found, something went horribly wrong...')
Esempio n. 24
0
async def create_role(guild_id, reaction_group_id, role_id, name, emoji, description, protect_mentions: int):
    ids = await orm.select(
        'SELECT id from reaction_group WHERE id = %s and guild_id = %s;',
        [reaction_group_id, guild_id]
    )
    await aiocache.SimpleMemoryCache().clear(namespace="role")

    existing_roles = await orm.select(
        'SELECT id from reaction_role WHERE emoji = %s and reaction_group_id = %s',
        [emoji, ids[0]['id']]
    )
    # do something else if this already exists
    if len(existing_roles) > 0:
        raise SahasrahBotException('Emoji already exists on group.')

    await orm.execute(
        'INSERT into reaction_role (`guild_id`, `reaction_group_id`, `role_id`, `name`, `emoji`, `description`, `protect_mentions`) values (%s, %s, %s, %s, %s, %s, %s)',
        [guild_id, reaction_group_id, role_id, name,
            emoji, description, protect_mentions]
    )
    await aiocache.SimpleMemoryCache().clear(namespace="role")
Esempio n. 25
0
    async def create_embeds(self):
        if self.rtgg_handler is None:
            raise SahasrahBotException(
                "No RaceTime.gg handler associated with this tournament game.")

        self.embed = await self.seed.embed(name=self.race_info,
                                           notes=self.versus,
                                           emojis=discordbot.emojis)

        self.tournament_embed = await self.seed.tournament_embed(
            name=self.race_info, notes=self.versus, emojis=discordbot.emojis)

        self.tournament_embed.insert_field_at(
            0,
            name='RaceTime.gg',
            value=self.rtgg_handler.bot.http_uri(
                self.rtgg_handler.data['url']),
            inline=False)
        self.embed.insert_field_at(0,
                                   name='RaceTime.gg',
                                   value=self.rtgg_handler.bot.http_uri(
                                       self.rtgg_handler.data['url']),
                                   inline=False)

        if self.broadcast_channels:
            self.tournament_embed.insert_field_at(
                0,
                name="Broadcast Channels",
                value=', '.join([
                    f"[{a}](https://twitch.tv/{a})"
                    for a in self.broadcast_channels
                ]),
                inline=False)
            self.embed.insert_field_at(0,
                                       name="Broadcast Channels",
                                       value=', '.join([
                                           f"[{a}](https://twitch.tv/{a})"
                                           for a in self.broadcast_channels
                                       ]),
                                       inline=False)
Esempio n. 26
0
    async def preset(
        self,
        ctx: ApplicationContext,
        preset: Option(str,
                       description="The preset you want generate.",
                       required=True,
                       autocomplete=autocomplete_alttpr),
        race: Option(str,
                     description="Is this a race? (default no)",
                     choices=["yes", "no"],
                     required=False,
                     default="no"),
        hints: Option(str,
                      description="Enable hints? (default no)",
                      choices=["yes", "no"],
                      required=False,
                      default="no"),
        allow_quickswap: Option(str,
                                description="Allow quickswap? (default yes)",
                                choices=["yes", "no"],
                                required=False,
                                default="yes"),
    ):
        """
        Generates an ALTTP Randomizer game on https://alttpr.com
        """
        await ctx.defer()
        seed = await generator.ALTTPRPreset(preset).generate(
            hints=hints == "yes",
            spoilers="off" if race == "yes" else "on",
            tournament=race == "yes",
            allow_quickswap=allow_quickswap == "yes")
        if not seed:
            raise SahasrahBotException(
                'Could not generate game.  Maybe preset does not exist?')
        embed = await seed.embed(emojis=self.bot.emojis)
        embed.insert_field_at(0, name="Preset", value=preset, inline=False)

        await ctx.respond(embed=embed)
Esempio n. 27
0
    async def importroles(self, ctx, mode=None):
        if ctx.message.attachments:
            content = await ctx.message.attachments[0].read()
            role_import_list = csv.DictReader(
                io.StringIO(content.decode()))
            for i in role_import_list:
                try:
                    role_obj = await commands.RoleConverter().convert(ctx, i['role'])
                except commands.BadArgument:
                    await ctx.reply(f"Failed to find role identified by {i['role']}")
                    continue

                try:
                    member_obj = await commands.MemberConverter().convert(ctx, i['member'])
                except commands.BadArgument:
                    await ctx.reply(f"Failed to find member identified by {i['member']}")
                    continue

                if not mode == "dry":
                    await member_obj.add_roles(role_obj)
        else:
            raise SahasrahBotException("You must supply a valid csv file.")
Esempio n. 28
0
    async def alttprstats(self, ctx, raw: bool = False):
        if ctx.message.attachments:
            sram = await ctx.message.attachments[0].read()
            parsed = parse_sram(sram)
            if raw:
                await ctx.send(file=discord.File(
                    io.StringIO(json.dumps(parsed, indent=4)),
                    filename=
                    f"stats_{parsed['meta'].get('filename', 'alttpr').strip()}.txt"
                ))
            else:
                embed = discord.Embed(
                    title=
                    f"ALTTPR Stats for \"{parsed['meta'].get('filename', '').strip()}\"",
                    description=
                    f"Collection Rate {parsed['stats'].get('collection rate')}",
                    color=discord.Color.blue())
                embed.add_field(
                    name="Time",
                    value=
                    (f"Total Time: {parsed['stats'].get('total time', None)}\n"
                     f"Lag Time: {parsed['stats'].get('lag time', None)}\n"
                     f"Menu Time: {parsed['stats'].get('menu time', None)}\n\n"
                     f"First Sword: {parsed['stats'].get('first sword', None)}\n"
                     f"Flute Found: {parsed['stats'].get('flute found', None)}\n"
                     f"Mirror Found: {parsed['stats'].get('mirror found', None)}\n"
                     f"Boots Found: {parsed['stats'].get('boots found', None)}\n"
                     ),
                    inline=False)
                embed.add_field(
                    name="Important Stats",
                    value=
                    (f"Bonks: {parsed['stats'].get('bonks', None)}\n"
                     f"Deaths: {parsed['stats'].get('deaths', None)}\n"
                     f"Revivals: {parsed['stats'].get('faerie revivals', None)}\n"
                     f"Overworld Mirrors: {parsed['stats'].get('overworld mirrors', None)}\n"
                     f"Rupees Spent: {parsed['stats'].get('rupees spent', None)}\n"
                     f"Save and Quits: {parsed['stats'].get('save and quits', None)}\n"
                     f"Screen Transitions: {parsed['stats'].get('screen transitions', None)}\n"
                     f"Times Fluted: {parsed['stats'].get('times fluted', None)}\n"
                     f"Underworld Mirrors: {parsed['stats'].get('underworld mirrors', None)}\n"
                     ))
                embed.add_field(
                    name="Misc Stats",
                    value=
                    (f"Swordless Bosses: {parsed['stats'].get('swordless bosses', None)}\n"
                     f"Fighter Sword Bosses: {parsed['stats'].get('fighter sword bosses', None)}\n"
                     f"Master Sword Bosses: {parsed['stats'].get('master sword bosses', None)}\n"
                     f"Tempered Sword Bosses: {parsed['stats'].get('tempered sword bosses', None)}\n"
                     f"Golden Sword Bosses: {parsed['stats'].get('golden sword bosses', None)}\n\n"
                     f"Heart Containers: {parsed['stats'].get('heart containers', None)}\n"
                     f"Heart Containers: {parsed['stats'].get('heart pieces', None)}\n"
                     f"Mail Upgrade: {parsed['stats'].get('mails', None)}\n"
                     f"Bottles: {parsed['equipment'].get('bottles', None)}\n"
                     f"Silver Arrows: {parsed['equipment'].get('silver arrows', None)}\n"
                     ))
                if not parsed.get('hash id', 'none') == 'none':
                    seed = await alttpr(hash_id=parsed.get('hash id', 'none'))
                    embed.add_field(name='File Select Code',
                                    value=seed.build_file_select_code(
                                        emojis=ctx.bot.emojis),
                                    inline=False)
                    embed.add_field(name='Permalink',
                                    value=seed.url,
                                    inline=False)

                await ctx.send(embed=embed)
        else:
            raise SahasrahBotException("You must attach an SRAM file.")
Esempio n. 29
0
 async def qualmulti(self, ctx, raceid):
     race = await get_race(raceid)
     if race == {}:
         raise SahasrahBotException('That race does not exist.')
     for multi in build_multistream_links(race):
         await ctx.send(multi)
Esempio n. 30
0
    async def handle_multiworld(self, ctx, preset, randomizer):
        await fetch_preset(preset, randomizer=randomizer)

        embed = discord.Embed(
            title=f'{randomizer.upper()} Multiworld Game',
            description=
            ('A new multiworld game has been initiated, react with πŸ‘ to join.\n'
             'When everyone is ready, the game creator can react with βœ… to create a session.\n'
             'The game creator can react with ❌ to cancel this game.'),
            color=discord.Color.dark_blue())
        embed.add_field(name="Status", value="πŸ‘ Open for entry", inline=False)
        embed.add_field(
            name="Preset",
            value=
            f"[{preset.lower()}](https://github.com/tcprescott/sahasrahbot/blob/master/presets/{randomizer.lower()}/{preset.lower()}.yaml)",
            inline=False)
        embed.add_field(name="Players", value="No players yet.", inline=False)

        msg = await ctx.send(embed=embed)

        await msg.add_reaction('πŸ‘')
        await msg.add_reaction("βœ…")
        await msg.add_reaction("❌")

        def add_check(reaction, user):
            return str(reaction.emoji) in [
                'πŸ‘', 'βœ…', '❌'
            ] and reaction.message.id == msg.id and not user.id == self.bot.user.id

        def remove_check(reaction, user):
            return str(
                reaction.emoji
            ) == 'πŸ‘' and reaction.message.id == msg.id and not user.id == self.bot.user.id

        timeout_start = time.time()
        close = False
        roll = True
        timeout = 1800
        while time.time() < timeout_start + timeout and not close:
            try:
                pending_tasks = [
                    self.bot.wait_for('reaction_add', check=add_check),
                    self.bot.wait_for('reaction_remove', check=remove_check)
                ]
                done_tasks, pending_tasks = await asyncio.wait(
                    pending_tasks,
                    return_when=asyncio.FIRST_COMPLETED,
                    timeout=5)

                for task in pending_tasks:
                    task.cancel()

                for task in done_tasks:
                    reaction, user = await task
                    if str(reaction.emoji) == 'βœ…' and user == ctx.author:
                        close = True
                    if str(reaction.emoji) == '❌' and user == ctx.author:
                        close = True
                        roll = False
                    elif str(reaction.emoji) == 'πŸ‘':
                        r = discord.utils.get(reaction.message.reactions,
                                              emoji='πŸ‘')
                        players = await r.users().flatten()
                        p_list = [
                            p.name for p in players
                            if not p.id == self.bot.user.id
                        ]
                        if len(p_list) > 0:
                            embed.set_field_at(2,
                                               name="Players",
                                               value='\n'.join(p_list))
                        else:
                            embed.set_field_at(2,
                                               name="Players",
                                               value='No players yet.')
            except asyncio.TimeoutError:
                pass
            embed.set_field_at(
                0,
                name="Status",
                value=
                f"πŸ‘ Open for entry, auto-close in {round((timeout_start + timeout) - time.time(), 0)}s"
            )
            await msg.edit(embed=embed)

        if not roll:
            embed.set_field_at(0, name="Status", value="❌ Cancelled.")
            await msg.edit(embed=embed)
            return

        embed.set_field_at(0,
                           name="Status",
                           value="⌚ Game closed for entry.  Rolling...")
        await msg.edit(embed=embed)

        r = discord.utils.get(reaction.message.reactions, emoji='πŸ‘')
        reaction_users = await r.users().flatten()

        if len(reaction_users) < 3:
            embed.set_field_at(0,
                               name="Status",
                               value="❌ Too few players.  Cancelled.")
            await msg.edit(embed=embed)
            raise SahasrahBotException(
                "You must have at least two players to create a multiworld.")

        players = [p for p in players if not p.id == self.bot.user.id]

        seed = await generate_multiworld(preset, [p.name for p in players],
                                         tournament=False,
                                         randomizer=randomizer)

        dm_embed = discord.Embed(title=f'{randomizer.upper()} Multiworld Game')
        dm_embed.add_field(name="Players",
                           value='\n'.join([p.name for p in players]),
                           inline=False)
        dm_embed.add_field(name="Game Room", value=seed.url, inline=False)

        for player in players:
            try:
                await player.send(embed=dm_embed)
            except discord.HTTPException:
                await ctx.send(f"Unable to send DM to {player.mention}!")

        embed.set_field_at(0,
                           name="Status",
                           value="βœ… Game started!  Check your DMs.")
        await msg.edit(embed=embed)