コード例 #1
0
    async def _unregister(self, ctx, *, handle: str):
        if not discord_.has_admin_privilege(ctx):
            await discord_.send_message(
                ctx,
                f"{ctx.author.mention} you require 'manage server' permission or one of the "
                f"following roles: {', '.join(ADMIN_PRIVILEGE_ROLES)} to use this command"
            )
            return
        tournament_info = self.db.get_tournament_info(ctx.guild.id)
        if not tournament_info:
            await discord_.send_message(
                ctx, "There is no ongoing tournament in the server currently")
            return
        if tournament_info.status != 0:
            await discord_.send_message(ctx,
                                        "The tournament has already begun")
            return
        registrants = self.db.get_registrants(ctx.guild.id)

        res = self.db.remove_registrant_by_handle(ctx.guild.id, handle)
        if not res:
            await discord_.send_message(
                ctx,
                f"The user with handle `{handle}` has not registered for the tournament"
            )
            return
        await ctx.send(embed=discord.Embed(
            description=
            f"Successfully unregistered from the tournament. `{MAX_REGISTRANTS - len(registrants) + 1}` slots left.",
            color=discord.Color.green()))
コード例 #2
0
    async def match_invalidate(self, ctx, idx: int):
        if not discord_.has_admin_privilege(ctx):
            await discord_.send_message(
                ctx,
                f"{ctx.author.mention} you require 'manage server' permission or one of the "
                f"following roles: {', '.join(ADMIN_PRIVILEGE_ROLES)} to use this command"
            )
            return

        tournament_info = self.db.get_tournament_info(ctx.guild.id)

        if not tournament_info:
            await discord_.send_message(
                ctx, "There is no ongoing tournament in the server currently")
            return
        if tournament_info.status != 2:
            await discord_.send_message(
                ctx,
                "The tournament has not begun yet, type `.tournament begin` to start the tournament"
            )
            return

        matches_resp = await self.api.get_tournament_matches(tournament_info.id
                                                             )

        if not matches_resp or 'errors' in matches_resp:
            await discord_.send_message(
                ctx, "Some error occurred, try again later")
            if matches_resp and 'errors' in matches_resp:
                logging_channel = await self.client.fetch_channel(
                    os.environ.get("LOGGING_CHANNEL"))
                await logging_channel.send(
                    f"Error in match_invalidate: {ctx.guild.id} {matches_resp['errors']}"
                )
            return

        match_id = None

        for match in matches_resp:
            if match['match']['state'] == 'complete' and match['match'][
                    'suggested_play_order'] == idx:
                match_id = match['match']['id']

        if match_id:
            await self.api.invalidate_match(tournament_info.id, match_id)
            await discord_.send_message(
                ctx,
                f"Invalidated match number `{idx}`. All future matches whose results was dependent on this match have also been reset"
            )
        else:
            await discord_.send_message(ctx,
                                        f"Couldn't find match number `{idx}`")
コード例 #3
0
ファイル: round.py プロジェクト: pseudocoder10/Lockout-Bot
 async def _invalidate(self, ctx, member: discord.Member):
     if not discord_.has_admin_privilege(ctx):
         await discord_.send_message(
             ctx,
             f"{ctx.author.mention} you require 'manage server' permission or one of the "
             f"following roles: {', '.join(ADMIN_PRIVILEGE_ROLES)} to use this command"
         )
         return
     if not self.db.in_a_round(ctx.guild.id, member.id):
         await discord_.send_message(ctx,
                                     f"{member.mention} is not in a round")
         return
     self.db.delete_round(ctx.guild.id, member.id)
     await discord_.send_message(ctx, f"Round deleted")
コード例 #4
0
ファイル: matches.py プロジェクト: pseudocoder10/Lockout-Bot
 async def _invalidate(self, ctx, member: discord.Member):
     if not discord_.has_admin_privilege(ctx):
         await discord_.send_message(
             ctx,
             f"{ctx.author.mention} you require 'manage server' permission or one of the "
             f"following roles: {', '.join(ADMIN_PRIVILEGE_ROLES)} to use this command"
         )
         return
     if not self.db.in_a_match(ctx.guild.id, member.id):
         await discord_.send_message(
             ctx, f"User {member.mention} is not in a match.")
         return
     self.db.delete_match(ctx.guild.id, member.id)
     await ctx.send(
         embed=discord.Embed(description="Match has been invalidated",
                             color=discord.Color.green()))
コード例 #5
0
    async def setup(self, ctx, tournament_type: int, *, tournament_name: str):
        """
        **tournament_name:** Alpha-numeric string (Max 50 characters)
        **tournament_type:** Integer (0: single elimination, 1: double elimination, 2: swiss)
        """
        if not discord_.has_admin_privilege(ctx):
            await discord_.send_message(
                ctx,
                f"{ctx.author.mention} you require 'manage server' permission or one of the "
                f"following roles: {', '.join(ADMIN_PRIVILEGE_ROLES)} to use this command"
            )
            return
        if len(tournament_name) not in range(1, 51):
            await discord_.send_message(
                ctx, "The tournament name should be 50 character max")
            return
        if any([not ch.isalnum() and ch != ' ' for ch in tournament_name]):
            await discord_.send_message(
                ctx,
                "The tournament name should contain only alpha-numeric characters"
            )
            return
        if tournament_type not in range(0, 3):
            await discord_.send_message(
                ctx,
                "Tournament type should be either 0, 1 or 2. (0: single elimination, 1: double elimination, 2: swiss)"
            )
            return
        if self.db.get_tournament_info(ctx.guild.id):
            await discord_.send_message(
                ctx, "A tournament is already in progress in this server!")
            return

        self.db.add_tournament(ctx.guild.id, tournament_name, tournament_type,
                               0, "-", 0)
        types = ["Single Elimination", "Double Elimination", "Swiss"]

        desc = f"""
               Initialised a {types[tournament_type]} tournament. 
               To register, type `.tournament register` (Max registrations: **{MAX_REGISTRANTS}**)
               To unregister, type `.tournament unregister`
               To start the tournament, type `.tournament begin` 
               """
        embed = discord.Embed(description=desc, color=discord.Color.green())
        embed.set_author(name=tournament_name)
        await ctx.send(embed=embed)
コード例 #6
0
    async def remove(self, ctx, member: discord.Member):
        if not discord_.has_admin_privilege(ctx):
            await discord_.send_message(
                ctx,
                f"{ctx.author.mention} you require 'manage server' permission or one of the "
                f"following roles: {', '.join(ADMIN_PRIVILEGE_ROLES)} to use this command"
            )
            return
        if not self.db.get_handle(ctx.guild.id, member.id):
            await discord_.send_message(
                ctx, f"Handle for {member.mention} not set")
            return

        self.db.remove_handle(ctx.guild.id, member.id)
        await ctx.send(embed=Embed(
            description=f"Handle for {member.mention} removed successfully",
            color=Color.green()))
コード例 #7
0
ファイル: handles.py プロジェクト: pseudocoder10/Lockout-Bot
    async def set(self, ctx, member: discord.Member, handle: str):
        if not discord_.has_admin_privilege(ctx):
            await discord_.send_message(
                ctx,
                f"{ctx.author.mention} you require 'manage server' permission or one of the "
                f"following roles: {', '.join(ADMIN_PRIVILEGE_ROLES)} to use this command"
            )
            return

        data = await self.cf.check_handle(handle)
        if not data[0]:
            await discord_.send_message(ctx, data[1])
            return

        handle = data[1]['handle']
        if self.db.get_handle(ctx.guild.id, member.id):
            await discord_.send_message(
                ctx,
                f"Handle for user {member.mention} already set to {self.db.get_handle(ctx.guild.id, member.id)}"
            )
            return

        # all conditions met
        data = data[1]
        if "rating" not in data:
            rating = 0
            rank = "unrated"
        else:
            rating = data['rating']
            rank = data['rank']
        self.db.add_handle(ctx.guild.id, member.id, handle, rating)
        self.db.add_rated_user(ctx.guild.id, member.id)
        embed = discord.Embed(
            description=
            f'Handle for user {member.mention} successfully set to [{handle}](https://codeforces.com/profile/{handle})',
            color=Color(cf_colors[rank.lower()]))
        embed.add_field(name='Rank', value=f'{rank}', inline=True)
        embed.add_field(name='Rating', value=f'{rating}', inline=True)
        embed.set_thumbnail(url=f"{data['titlePhoto']}")
        await ctx.send(embed=embed)
コード例 #8
0
    async def delete_(self, ctx):
        if not discord_.has_admin_privilege(ctx):
            await discord_.send_message(
                ctx,
                f"{ctx.author.mention} you require 'manage server' permission or one of the "
                f"following roles: {', '.join(ADMIN_PRIVILEGE_ROLES)} to use this command"
            )
            return
        tournament_info = self.db.get_tournament_info(ctx.guild.id)
        if not tournament_info:
            await discord_.send_message(
                ctx, "There is no ongoing tournament in the server currently")
            return

        resp = await discord_.get_time_response(
            self.client, ctx,
            "Are you sure you want to delete the tournament? This action is irreversable. Type `1` for yes and `0` for no",
            30, ctx.author, [0, 1])
        if resp[0] and resp[1] == 1:
            if tournament_info.status != 0:
                await self.api.delete_tournament(tournament_info.id)
            self.db.delete_tournament(ctx.guild.id)
            await discord_.send_message(ctx, "Tournament has been deleted")
コード例 #9
0
    async def forcedraw(self, ctx, *, handle: str):
        if not discord_.has_admin_privilege(ctx):
            await discord_.send_message(
                ctx,
                f"{ctx.author.mention} you require 'manage server' permission or one of the "
                f"following roles: {', '.join(ADMIN_PRIVILEGE_ROLES)} to use this command"
            )
            return

        tournament_info = self.db.get_tournament_info(ctx.guild.id)

        if not tournament_info:
            await discord_.send_message(
                ctx, "There is no ongoing tournament in the server currently")
            return
        if tournament_info.status != 2:
            await discord_.send_message(
                ctx,
                "The tournament has not begun yet, type `.tournament begin` to start the tournament"
            )
            return

        if tournament_info.type != 2:
            await discord_.send_message(
                ctx, "This command can only be used for swiss tournaments")
            return

        registrants = self.db.get_registrants(ctx.guild.id)
        challonge_id = None

        for user in registrants:
            if user.handle.lower() == handle.lower():
                challonge_id = user.challonge_id

        if not challonge_id:
            await discord_.send_message(
                ctx,
                f"User with handle `{handle}` has not registered for the tournament"
            )
            return

        matches_resp = await self.api.get_tournament_matches(tournament_info.id
                                                             )

        if not matches_resp or 'errors' in matches_resp:
            await discord_.send_message(
                ctx, "Some error occurred, try again later")
            if matches_resp and 'errors' in matches_resp:
                logging_channel = await self.client.fetch_channel(
                    os.environ.get("LOGGING_CHANNEL"))
                await logging_channel.send(
                    f"Error in forcewin match fetching: {ctx.guild.id} {matches_resp['errors']}"
                )
            return

        match_id = None
        player1_id = None
        for match in matches_resp:
            if match['match']['state'] != 'open':
                continue
            if match['match']['player1_id'] == challonge_id or match['match'][
                    'player2_id'] == challonge_id:
                match_id = match['match']['id']
                player1_id = match['match']['player1_id']
                break

        if not match_id:
            await discord_.send_message(
                ctx, f"Couldn't find a match for handle `{handle}`")
            return

        scores = await discord_.get_seq_response(
            self.client, ctx,
            f"{ctx.author.mention} enter 2 space seperated integers denoting the scores of the players",
            30, 2, ctx.author, [0, 10000])
        if not scores[0]:
            return

        if challonge_id != player1_id:
            scores[1][0], scores[1][1] = scores[1][1], scores[1][0]

        resp = await self.api.post_match_results(
            tournament_info.id, match_id, f"{scores[1][0]}-{scores[1][1]}",
            "tie")
        if not resp or 'errors' in resp:
            await discord_.send_message(
                ctx, "Some error occurred, try again later")
            if resp and 'errors' in resp:
                logging_channel = await self.client.fetch_channel(
                    os.environ.get("LOGGING_CHANNEL"))
                await logging_channel.send(
                    f"Error in forcedraw match score reporting: {ctx.guild.id} {resp['errors']}"
                )
        else:
            await discord_.send_message(
                ctx, f"Match involving `{handle}` has been drawn")

            if await tournament_helper.validate_tournament_completion(
                    tournament_info.guild, self.api, self.db):
                await self.api.finish_tournament(tournament_info.id)
                winner_handle = await tournament_helper.get_winner(
                    tournament_info.id, self.api)
                await ctx.send(embed=tournament_helper.tournament_over_embed(
                    tournament_info.guild, winner_handle, self.db))
                self.db.delete_tournament(tournament_info.guild)
                self.db.add_to_finished_tournaments(tournament_info,
                                                    winner_handle)
コード例 #10
0
    async def begin(self, ctx):
        if not discord_.has_admin_privilege(ctx):
            await discord_.send_message(
                ctx,
                f"{ctx.author.mention} you require 'manage server' permission or one of the "
                f"following roles: {', '.join(ADMIN_PRIVILEGE_ROLES)} to use this command"
            )
            return
        tournament_info = self.db.get_tournament_info(ctx.guild.id)
        if not tournament_info:
            await discord_.send_message(
                ctx, "There is no ongoing tournament in the server currently")
            return

        if tournament_info.status == 2:
            await discord_.send_message(
                ctx,
                f"The tournament has already begun! Type `.tournament matches` or `.tournament info` to view details about the tournament"
            )
            return

        registrants = self.db.get_registrants(ctx.guild.id)
        if not registrants or len(registrants) < 2:
            await discord_.send_message(
                ctx, "Not enough registrants for the tournament yet")
            return

        logging_channel = await self.client.fetch_channel(
            os.environ.get("LOGGING_CHANNEL"))

        if tournament_info.status == 0:
            resp = await discord_.get_time_response(
                self.client, ctx,
                "Are you sure you want to start the tournament? No new registrations will be allowed once the tournament has started. Type `1` for yes and `0` for no",
                30, ctx.author, [0, 1])
            if not resp[0] or resp[1] == 0:
                ctx.command.reset_cooldown(ctx)
                return
            await ctx.send(f"Setting up tournament...")
            tournament_resp = await self.api.add_tournament(tournament_info)
            if not tournament_resp or 'errors' in tournament_resp:
                ctx.command.reset_cooldown(ctx)
                await discord_.send_message(
                    ctx, "Some error occurred, try again later")
                if tournament_resp and 'errors' in tournament_resp:
                    await logging_channel.send(
                        f"Error in tournament setup: {ctx.guild.id} {tournament_resp['errors']}"
                    )
                return

            # api takes some time to register tournament id
            await asyncio.sleep(5)
            await ctx.send(f"Adding participants...")
            participants_resp = await self.api.bulk_add_participants(
                tournament_resp['tournament']['id'], [{
                    "name":
                    f"{registrants[i].handle} ({registrants[i].rating})",
                    "seed": i + 1
                } for i in range(len(registrants))])

            if not participants_resp or 'errors' in participants_resp:
                ctx.command.reset_cooldown(ctx)
                await discord_.send_message(
                    ctx, "Some error occurred, try again later")
                if participants_resp and 'errors' in participants_resp:
                    await logging_channel.send(
                        f"Error in bulk adding participants: {ctx.guild.id} {participants_resp['errors']}"
                    )
                await self.api.delete_tournament(
                    tournament_resp['tournament']['id'])
                return

            await asyncio.sleep(5)
            await ctx.send("Enabling brackets predictions...")
            predictions_resp = await self.api.open_for_predictions(
                tournament_resp['tournament']['id'])

            if not predictions_resp or 'errors' in predictions_resp:
                ctx.command.reset_cooldown(ctx)
                await discord_.send_message(
                    ctx, "Some error occurred, try again later")
                if predictions_resp and 'errors' in predictions_resp:
                    await logging_channel.send(
                        f"Error in enabling predictions: {ctx.guild.id} {predictions_resp['errors']}"
                    )
                await self.api.delete_tournament(
                    tournament_resp['tournament']['id'])
                return

            self.db.update_tournament_params(
                tournament_resp['tournament']['id'],
                tournament_resp['tournament']['url'], 1, ctx.guild.id)
            for data in participants_resp:
                self.db.map_user_to_challongeid(
                    ctx.guild.id,
                    registrants[data['participant']['seed'] - 1].discord_id,
                    data['participant']['id'])

            desc = ""
            desc += f"The tournament has been setup. You can find the brackets [here](https://challonge.com/{tournament_resp['tournament']['url']})\n"
            desc += f"You can now make predictions on each of the brackets and climb up the predictions leaderboard. Make new predictions [here](https://challonge.com/tournaments/{tournament_resp['tournament']['id']}/predictions/new)\n\n"
            desc += f"Note that the tournament has **not** started yet. Once everyone has made their predictions, type `.tournament begin` for the tournament to officially begin\n\n"

            desc += f"**Tournament type**: {['Single Elimination', 'Double Elimination', 'Swiss'][tournament_info.type]}\n"
            desc += f"**Number of registrations**: {len(registrants)}"

            embed = discord.Embed(description=desc,
                                  color=discord.Color.green())
            embed.set_author(name=tournament_info.name)
            await ctx.send(embed=embed)
            ctx.command.reset_cooldown(ctx)
        else:
            await ctx.send(f"Starting the tournament...")
            tournament_resp = await self.api.start_tournament(
                tournament_info.id)
            if not tournament_resp or 'errors' in tournament_resp:
                ctx.command.reset_cooldown(ctx)
                await discord_.send_message(
                    ctx, "Some error occurred, try again later")
                if tournament_resp and 'errors' in tournament_resp:
                    await logging_channel.send(
                        f"Error in tournament setup: {ctx.guild.id} {tournament_resp['errors']}"
                    )
                return

            self.db.update_tournament_params(tournament_info.id,
                                             tournament_info.url, 2,
                                             ctx.guild.id)

            desc = f"The tournament has officially begun! View brackets on this [link](https://challonge.com/{tournament_info.url})\n\n"
            desc += f"To play tournament matches just use the `.round` command of the bot and challenge someone to a round. \n" \
                   f"If the round is part of the tournament, then the bot will ask whether you want the result of the round " \
                   f"to be counted in the tournament. \nIn case of a draw, you will have to play the round again. GLHF!\n\n"
            desc += f"**Some useful commands**:\n\n"
            desc += f"`.tournament matches`: View a list of future matches of the tournament\n"
            desc += f"`.tournament info`: View general info about the tournament\n"
            desc += f"`.tournament forcewin <handle>`: Grant victory to a user without conducting the match\n"
            desc += f"`.tournament invalidate`: Invalidate the tournament\n"

            embed = discord.Embed(description=desc,
                                  color=discord.Color.green())
            embed.set_author(name=tournament_info.name)
            await ctx.send(embed=embed)