Пример #1
0
    async def decks(self, ctx, *, color: str = ""):
        """Show all registered decks, categorized by color combination. If a color combination is specified in WUBRG format, filter the results by that color combination. For example, to show only Esper decks, use WUB as the color combination (order does not matter)."""

        if not color:
            emsg = embed.msg(title="Registered Decks")
            colors = utils.get_all_color_combinations()
            for color in colors:
                example = self.bot.db.find_one_deck_by_color(color)
                if not example:
                    continue
                decks = self.bot.db.find_decks_by_color(color)
                emsg.add_field(name=example["color_name"],
                               value=("\n".join(
                                   [deck["name"] for deck in decks])))
                if (len(emsg.fields) == 9):
                    await ctx.send(embed=emsg)
                    emsg = embed.msg(title="Registered Decks")
            if len(emsg.fields) > 0:
                await ctx.send(embed=emsg)
        else:
            example = self.bot.db.find_one_deck_by_color(color)
            if not example:
                await ctx.send(embed=embed.error(
                    description=
                    "No decks found with the specified color combination."))
            else:
                decks = self.bot.db.find_decks_by_color(color)
                emsg = embed.msg(
                    title=f"Registered {example['color_name']} Decks",
                    description=("\n".join(deck["name"] for deck in decks)))
                await ctx.send(embed=emsg)
Пример #2
0
    async def use(self, ctx, *, deck_name: str = ""):
        """Set your current deck to the specified deck. 
        The deck must be a registered deck. A list of all registered decks can be viewed with the `decks` command. If the desired deck is not being tracked, Rogue can be used as a placeholder."""

        user = ctx.message.author
        action_description = f"`{ctx.prefix}decks`\n`{ctx.prefix}decks [color set]`"
        if not deck_name:
            emsg = embed.error(description="No deck specified.") \
                        .add_field(name="Actions", value=action_description)
            await ctx.send(embed=emsg)
            return
        if deck_name.lower() == "rogue":
            official_name = "Rogue"
        else:
            deck = self.bot.db.find_deck(deck_name)
            if not deck:
                emsg = embed.error(description=f"{deck_name} is not a recognized deck.") \
                            .add_field(name="Actions", value=action_description)
                await ctx.send(embed=emsg)
                return
            else:
                official_name = deck["name"]
        self.bot.db.set_deck(official_name, user, ctx.message.guild)
        await ctx.send(embed=embed.msg(
            description=f"Deck set to {official_name} for **{user.name}**"))
Пример #3
0
    async def game(self, ctx, *, game_id: str=""):
        """Get the details of a game. Details include the date it was logged, who the players were, what decks were played, who won the match, and the confirmation status of the match."""

        if not game_id:
            await ctx.send(embed=embed.error(description="No game id specified"))
            return
        match = self.bot.db.find_match(game_id, ctx.message.guild)
        if not match:
            await ctx.send(embed=embed.error(description=f"`{game_id}` does not exist"))
            return

        winner = next((i for i in match["players"] if i["user_id"] == match["winner"]), None)
        date = datetime.fromtimestamp(match["timestamp"])
        if match["status"] == stc.ACCEPTED:
            status_symbol = emojis.accepted
        elif match["status"] == stc.PENDING:
            status_symbol = emojis.pending
        else:
            status_symbol = emojis.disputed
        emsg = embed.msg(title=f"Game id: {game_id}") \
                    .add_field(name="Date (UTC)", value=date.strftime("%Y-%m-%d")) \
                    .add_field(name="Winner", value=winner["name"]) \
                    .add_field(name="Status", value=status_symbol)

        if match['replay_link']:
            emsg.add_field(name="Replay", value=match['replay_link'])
        
        emsg.description = self._make_game_table(ctx, match)
        await ctx.send(embed=emsg)
Пример #4
0
    async def deny(self, ctx, *, game_id: str=""):
        """Dispute a match result. This will notify league admins that the match result requires attention. League admins may resolve the match by either accepting or removing it. If you created the match and there is an error (ie. mentioned the wrong players), then the `remove` command is more appropriate to undo the logged match and log the correct result."""

        user = ctx.message.author
        member = self.bot.db.find_member(user.id, ctx.message.guild)
        if not member["pending"]:
            await ctx.send(embed=embed.info(description="No pending matches to deny"))
            return
        if not game_id:
            await ctx.send(embed=embed.error(description="You must specify a game id to dispute it"))
            return

        match = self.bot.db.find_match(game_id, ctx.message.guild)
        if not match:
            await ctx.send(embed=embed.error(description=f"`{game_id}` does not exist"))
            return
        player = next((i for i in match["players"] if i["user_id"] == user.id), None)
        if not player:
            await ctx.send(embed=embed.error(description="Only participants can deny a match"))
            return

        if match["status"] == stc.ACCEPTED:
            await ctx.send(embed=embed.error(description="Accepted matches cannot be denied"))
        elif match["status"] == stc.DISPUTED:
            await ctx.send(embed=embed.info(description="This match has already been marked for review"))
        else:
            self.bot.db.set_match_status(stc.DISPUTED, game_id, ctx.message.guild)
            self.bot.db.unconfirm_match_for_user(game_id, user.id, ctx.message.guild)
            admin_role = self.bot.db.get_admin_role(ctx.message.guild)
            mention = "" if not admin_role else admin_role.mention
            await ctx.send(embed=embed.msg(
                description=f"{mention} Match `{game_id}` has been marked as **disputed**")
            )
Пример #5
0
    async def pending(self, ctx):
        """Display a list of all your pending matches. Use the `remind` command instead to alert players to confirm your pending matches."""

        user = ctx.message.author
        guild = ctx.message.guild
        player = self.bot.db.find_member(user.id, guild)
        if not player["pending"]:
            emsg = embed.msg(description="You have no pending, unconfirmed matches.")
            await ctx.send(embed=emsg)
            return
        emsg = embed.msg(
            title = "Pending Matches",
            description = ", ".join(player["pending"])
        ).add_field(
            name="Actions", 
            value=f"`{ctx.prefix}status [game id]`\n`{ctx.prefix}confirm [game id]`\n`{ctx.prefix}deny [game id]`"
        )
        await ctx.send(embed=emsg)
Пример #6
0
    async def _add_user(self, ctx, *, user: discord.User):
        """Add a user to the database."""

        guild = ctx.message.guild
        if self.bot.db.add_member(user, guild):
            emsg = embed.msg(
                description=
                f"Registered **{user.name}** to the {guild.name} league")
        else:
            emsg = embed.error(
                description=f"**{user.name}** is already registered")
        await ctx.send(embed=emsg)
Пример #7
0
    async def remind(self, ctx):
        """Send an alert to each player to confirm your pending matches.
        This will pull your list of pending matches and mention all players in each match that has not yet confirmed the result."""

        member = self.bot.db.find_member(ctx.message.author.id, ctx.message.guild)
        if not member["pending"]:
            await ctx.send(embed=embed.msg(description="You have no pending matches"))
            return
        pending_matches = self.bot.db.find_matches({"game_id": {"$in": member["pending"]}}, ctx.message.guild)
        for match in pending_matches:
            unconfirmed = [
                await self.bot.get_user_info(player["user_id"]) for player in match["players"] 
                if not player["confirmed"]
            ]
            mentions = " ".join([user.mention for user in unconfirmed])
            emsg = embed.msg(
                title=f"Game id: {match['game_id']}",
                description=(f"{mentions}\n" \
                             f"Please confirm this match by saying: `{ctx.prefix}confirm {match['game_id']}`")
            )
            await ctx.send(embed=emsg)
Пример #8
0
 async def register(self, ctx):
     """Register to this guild's EDH league to participate in match tracking."""
         
     user = ctx.message.author
     guild = ctx.message.guild
     if self.bot.db.add_member(user, guild):
         emsg = embed.msg(
             description = "Registered **{}** to the {} league".format(user.name, guild.name)
         )
     else:
         emsg = embed.error(
             description = "**{}** is already registered".format(user.name)
         )
     await ctx.send(embed=emsg)
Пример #9
0
    async def remove(self, ctx, *, game_id: str=""):
        """Removes a match from the tracking system.
        This should only be used if a match is known to be invalid. Only pending matches can be rejected. This command can only be used by an admin or the player who logged the match."""

        if not game_id:
            await ctx.send(embed=embed.error(description="No game id specified"))
            return
        match = self.bot.db.find_match(game_id, ctx.message.guild)
        if not match:
            await ctx.send(embed=embed.error(description=f"`{game_id}` does not exist"))
            return
        if match["status"] == stc.ACCEPTED:
            await ctx.send(embed=embed.error(description="Cannot override an accepted match"))
            return
        if not (match["winner"] == ctx.message.author.id or checks.is_admin(ctx)):
            await ctx.send(embed=embed.error(description="Only a league admin or the match winner can remove a match"))
            return

        self.bot.db.delete_match(game_id, ctx.message.guild)
        await ctx.send(embed=embed.msg(description=f"`{game_id}` has been removed"))
Пример #10
0
    async def log(self, ctx):
        """Add a match to the tracking system. 
        A match must have exactly 4 players. To log a match, the winner should invoke this command and mention the 3 players that lost. The match will be entered into the tracking system in PENDING state. Only after all players have confirmed the result will the match be accepted."""

        winner = ctx.message.author
        losers = ctx.message.mentions
        players = [winner] + losers

        if not await self._are_players_registered(ctx, players):
            return
        if not await self._has_enough_players(ctx, players):
            return

        game_id = self.bot.db.add_match(ctx, winner, players)
        player_mentions = " ".join([player.mention for player in players])
        emsg = embed.msg(
            title=f'Game id: {game_id}',
            description=f"Match has been logged and awaiting confirmation from {player_mentions}"
        ).add_field(name="Actions", value=f"`{ctx.prefix}confirm` | `{ctx.prefix}deny`")
        await ctx.send(embed=emsg)
Пример #11
0
    async def _confirm_deck(self, ctx, player, game_id):
        if not player["deck"]:
            emsg = embed.error(
                description=(f"No deck specified for **{ctx.message.author.name}**\n" \
                             f"Set your deck with `{ctx.prefix}use`, then type `{ctx.prefix}confirm` again")
            )
            await ctx.send(embed=emsg)
            return False

        emsg = embed.msg(
            description=f"{ctx.message.author.mention} Was **{player['deck']}** the deck you piloted?"
        )
        bot_msg = await ctx.send(embed=emsg)
        
        if await self._has_confirmed_deck(bot_msg, ctx):
            return True

        await ctx.send(embed=embed.error(
            description=f"Set your deck with the `{ctx.prefix}use` command, then type `{ctx.prefix}confirm` again")
        )
        return False
Пример #12
0
 async def on_guild_join(self, guild):
     emsg = embed.msg(description=(
         "Please create a role and assign that role as the league " +
         "admin using `set_admin [role name]`"))
     await guild.owner.send(embed=emsg)
     self.db.setup_indices(guild)