commands.Context for the future
This commit is contained in:
		
							parent
							
								
									03bd13309e
								
							
						
					
					
						commit
						2cd594c36a
					
				| @ -3,13 +3,13 @@ from collections import defaultdict | ||||
| from random import choice | ||||
| 
 | ||||
| import discord | ||||
| from redbot.core import RedContext | ||||
| from discord.ext import commands | ||||
| 
 | ||||
| # Import all roles here | ||||
| from werewolf.roles.seer import Seer | ||||
| from werewolf.roles.vanillawerewolf import VanillaWerewolf | ||||
| from werewolf.roles.villager import Villager | ||||
| from werewolf.utils.menus import menu, prev_page, next_page, close_menu | ||||
| from redbot.core.utils.menus import menu, prev_page, next_page, close_menu | ||||
| 
 | ||||
| # All roles in this list for iterating | ||||
| 
 | ||||
| @ -181,7 +181,7 @@ async def encode(roles, rand_roles): | ||||
|     return out_code | ||||
| 
 | ||||
| 
 | ||||
| async def next_group(ctx: RedContext, pages: list, | ||||
| async def next_group(ctx: commands.Context, pages: list, | ||||
|                      controls: dict, message: discord.Message, page: int, | ||||
|                      timeout: float, emoji: str): | ||||
|     perms = message.channel.permissions_for(ctx.guild.me) | ||||
| @ -201,7 +201,7 @@ async def next_group(ctx: RedContext, pages: list, | ||||
|                       page=page, timeout=timeout) | ||||
| 
 | ||||
| 
 | ||||
| async def prev_group(ctx: RedContext, pages: list, | ||||
| async def prev_group(ctx: commands.Context, pages: list, | ||||
|                      controls: dict, message: discord.Message, page: int, | ||||
|                      timeout: float, emoji: str): | ||||
|     perms = message.channel.permissions_for(ctx.guild.me) | ||||
| @ -268,7 +268,7 @@ class GameBuilder: | ||||
|         self.rand_roles = [] | ||||
|         setup() | ||||
| 
 | ||||
|     async def build_game(self, ctx: RedContext): | ||||
|     async def build_game(self, ctx: commands.Context): | ||||
|         new_controls = { | ||||
|             '⏪': prev_group, | ||||
|             "⬅": prev_page, | ||||
| @ -286,7 +286,7 @@ class GameBuilder: | ||||
|         out = await encode(self.code, self.rand_roles) | ||||
|         return out | ||||
| 
 | ||||
|     async def list_roles(self, ctx: RedContext, pages: list, | ||||
|     async def list_roles(self, ctx: commands.Context, pages: list, | ||||
|                          controls: dict, message: discord.Message, page: int, | ||||
|                          timeout: float, emoji: str): | ||||
|         perms = message.channel.permissions_for(ctx.guild.me) | ||||
| @ -301,7 +301,7 @@ class GameBuilder: | ||||
|         return await menu(ctx, pages, controls, message=message, | ||||
|                           page=page, timeout=timeout) | ||||
| 
 | ||||
|     async def select_page(self, ctx: RedContext, pages: list, | ||||
|     async def select_page(self, ctx: commands.Context, pages: list, | ||||
|                           controls: dict, message: discord.Message, page: int, | ||||
|                           timeout: float, emoji: str): | ||||
|         perms = message.channel.permissions_for(ctx.guild.me) | ||||
|  | ||||
| @ -2,7 +2,7 @@ import asyncio | ||||
| import random | ||||
| 
 | ||||
| import discord | ||||
| from redbot.core import RedContext | ||||
| from discord.ext import commands | ||||
| 
 | ||||
| from werewolf.builder import parse_code | ||||
| from werewolf.player import Player | ||||
| @ -77,7 +77,7 @@ class Game: | ||||
|     #     for c_data in self.p_channels.values(): | ||||
|     #         asyncio.ensure_future(c_data["channel"].delete("Werewolf game-over")) | ||||
| 
 | ||||
|     async def setup(self, ctx: RedContext): | ||||
|     async def setup(self, ctx: commands.Context): | ||||
|         """ | ||||
|         Runs the initial setup | ||||
| 
 | ||||
| @ -673,7 +673,7 @@ class Game: | ||||
|     async def get_day_target(self, target_id, source=None): | ||||
|         return self.players[target_id]  # ToDo check source | ||||
| 
 | ||||
|     async def set_code(self, ctx: RedContext, game_code): | ||||
|     async def set_code(self, ctx: commands.Context, game_code): | ||||
|         if game_code is not None: | ||||
|             self.game_code = game_code | ||||
|         await ctx.send("Code has been set") | ||||
|  | ||||
| @ -1,134 +0,0 @@ | ||||
| import asyncio | ||||
| 
 | ||||
| import discord | ||||
| from redbot.core import RedContext | ||||
| 
 | ||||
| 
 | ||||
| async def menu(ctx: RedContext, pages: list, | ||||
|                controls: dict, | ||||
|                message: discord.Message = None, page: int = 0, | ||||
|                timeout: float = 30.0): | ||||
|     """ | ||||
|     An emoji-based menu | ||||
| 
 | ||||
|     .. note:: All pages should be of the same type | ||||
| 
 | ||||
|     .. note:: All functions for handling what a particular emoji does | ||||
|               should be coroutines (i.e. :code:`async def`). Additionally, | ||||
|               they must take all of the parameters of this function, in | ||||
|               addition to a string representing the emoji reacted with. | ||||
|               This parameter should be the last one, and none of the | ||||
|               parameters in the handling functions are optional | ||||
| 
 | ||||
|     Parameters | ||||
|     ---------- | ||||
|     ctx: RedContext | ||||
|         The command context | ||||
|     pages: `list` of `str` or `discord.Embed` | ||||
|         The pages of the menu. | ||||
|     controls: dict | ||||
|         A mapping of emoji to the function which handles the action for the | ||||
|         emoji. | ||||
|     message: discord.Message | ||||
|         The message representing the menu. Usually :code:`None` when first opening | ||||
|         the menu | ||||
|     page: int | ||||
|         The current page number of the menu | ||||
|     timeout: float | ||||
|         The time (in seconds) to wait for a reaction | ||||
| 
 | ||||
|     Raises | ||||
|     ------ | ||||
|     RuntimeError | ||||
|         If either of the notes above are violated | ||||
|     """ | ||||
|     if not all(isinstance(x, discord.Embed) for x in pages) and \ | ||||
|             not all(isinstance(x, str) for x in pages): | ||||
|         raise RuntimeError("All pages must be of the same type") | ||||
|     for key, value in controls.items(): | ||||
|         if not asyncio.iscoroutinefunction(value): | ||||
|             raise RuntimeError("Function must be a coroutine") | ||||
|     current_page = pages[page] | ||||
| 
 | ||||
|     if not message: | ||||
|         if isinstance(current_page, discord.Embed): | ||||
|             message = await ctx.send(embed=current_page) | ||||
|         else: | ||||
|             message = await ctx.send(current_page) | ||||
|         for key in controls.keys(): | ||||
|             await message.add_reaction(key) | ||||
|     else: | ||||
|         if isinstance(current_page, discord.Embed): | ||||
|             await message.edit(embed=current_page) | ||||
|         else: | ||||
|             await message.edit(content=current_page) | ||||
| 
 | ||||
|     def react_check(r, u): | ||||
|         return u == ctx.author and str(r.emoji) in controls.keys() | ||||
| 
 | ||||
|     try: | ||||
|         react, user = await ctx.bot.wait_for( | ||||
|             "reaction_add", | ||||
|             check=react_check, | ||||
|             timeout=timeout | ||||
|         ) | ||||
|     except asyncio.TimeoutError: | ||||
|         try: | ||||
|             await message.clear_reactions() | ||||
|         except discord.Forbidden:  # cannot remove all reactions | ||||
|             for key in controls.keys(): | ||||
|                 await message.remove_reaction(key, ctx.bot.user) | ||||
|         return None | ||||
| 
 | ||||
|     return await controls[react.emoji](ctx, pages, controls, | ||||
|                                        message, page, | ||||
|                                        timeout, react.emoji) | ||||
| 
 | ||||
| 
 | ||||
| async def next_page(ctx: RedContext, pages: list, | ||||
|                     controls: dict, message: discord.Message, page: int, | ||||
|                     timeout: float, emoji: str): | ||||
|     perms = message.channel.permissions_for(ctx.guild.me) | ||||
|     if perms.manage_messages:  # Can manage messages, so remove react | ||||
|         try: | ||||
|             await message.remove_reaction(emoji, ctx.author) | ||||
|         except discord.NotFound: | ||||
|             pass | ||||
|     if page == len(pages) - 1: | ||||
|         next_page = 0  # Loop around to the first item | ||||
|     else: | ||||
|         next_page = page + 1 | ||||
|     return await menu(ctx, pages, controls, message=message, | ||||
|                       page=next_page, timeout=timeout) | ||||
| 
 | ||||
| 
 | ||||
| async def prev_page(ctx: RedContext, pages: list, | ||||
|                     controls: dict, message: discord.Message, page: int, | ||||
|                     timeout: float, emoji: str): | ||||
|     perms = message.channel.permissions_for(ctx.guild.me) | ||||
|     if perms.manage_messages:  # Can manage messages, so remove react | ||||
|         try: | ||||
|             await message.remove_reaction(emoji, ctx.author) | ||||
|         except discord.NotFound: | ||||
|             pass | ||||
|     if page == 0: | ||||
|         page = len(pages) - 1  # Loop around to the last item | ||||
|     else: | ||||
|         page = page - 1 | ||||
|     return await menu(ctx, pages, controls, message=message, | ||||
|                       page=page, timeout=timeout) | ||||
| 
 | ||||
| 
 | ||||
| async def close_menu(ctx: RedContext, pages: list, | ||||
|                      controls: dict, message: discord.Message, page: int, | ||||
|                      timeout: float, emoji: str): | ||||
|     if message: | ||||
|         await message.delete() | ||||
|     return None | ||||
| 
 | ||||
| 
 | ||||
| DEFAULT_CONTROLS = { | ||||
|     "➡": next_page, | ||||
|     "⬅": prev_page, | ||||
|     "❌": close_menu, | ||||
| } | ||||
| @ -1,12 +1,12 @@ | ||||
| import discord | ||||
| from discord.ext import commands | ||||
| from redbot.core import Config, checks | ||||
| from redbot.core import RedContext | ||||
| 
 | ||||
| from redbot.core.bot import Red | ||||
| 
 | ||||
| from werewolf.builder import GameBuilder, role_from_name, role_from_alignment, role_from_category, role_from_id | ||||
| from werewolf.game import Game | ||||
| from werewolf.utils.menus import menu, DEFAULT_CONTROLS | ||||
| from redbot.core.utils.menus import menu, DEFAULT_CONTROLS | ||||
| 
 | ||||
| 
 | ||||
| class Werewolf: | ||||
| @ -36,7 +36,7 @@ class Werewolf: | ||||
|             del game | ||||
| 
 | ||||
|     @commands.command() | ||||
|     async def buildgame(self, ctx: RedContext): | ||||
|     async def buildgame(self, ctx: commands.Context): | ||||
|         gb = GameBuilder() | ||||
|         code = await gb.build_game(ctx) | ||||
| 
 | ||||
| @ -47,7 +47,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @checks.guildowner() | ||||
|     @commands.group() | ||||
|     async def wwset(self, ctx: RedContext): | ||||
|     async def wwset(self, ctx: commands.Context): | ||||
|         """ | ||||
|         Base command to adjust settings. Check help for command list. | ||||
|         """ | ||||
| @ -56,7 +56,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @wwset.command(name="list") | ||||
|     async def wwset_list(self, ctx: RedContext): | ||||
|     async def wwset_list(self, ctx: commands.Context): | ||||
|         """ | ||||
|         Lists current guild settings | ||||
|         """ | ||||
| @ -74,7 +74,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @wwset.command(name="role") | ||||
|     async def wwset_role(self, ctx: RedContext, role: discord.Role=None): | ||||
|     async def wwset_role(self, ctx: commands.Context, role: discord.Role=None): | ||||
|         """ | ||||
|         Assign the game role | ||||
|         This role should not be manually assigned | ||||
| @ -88,7 +88,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @wwset.command(name="category") | ||||
|     async def wwset_category(self, ctx: RedContext, category_id=None): | ||||
|     async def wwset_category(self, ctx: commands.Context, category_id=None): | ||||
|         """ | ||||
|         Assign the channel category | ||||
|         """ | ||||
| @ -105,7 +105,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @wwset.command(name="channel") | ||||
|     async def wwset_channel(self, ctx: RedContext, channel: discord.TextChannel=None): | ||||
|     async def wwset_channel(self, ctx: commands.Context, channel: discord.TextChannel=None): | ||||
|         """ | ||||
|         Assign the village channel | ||||
|         """ | ||||
| @ -118,7 +118,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @wwset.command(name="logchannel") | ||||
|     async def wwset_log_channel(self, ctx: RedContext, channel: discord.TextChannel=None): | ||||
|     async def wwset_log_channel(self, ctx: commands.Context, channel: discord.TextChannel=None): | ||||
|         """ | ||||
|         Assign the log channel | ||||
|         """ | ||||
| @ -130,7 +130,7 @@ class Werewolf: | ||||
|             await ctx.send("Game Log Channel has been set to **{}**".format(channel.mention)) | ||||
| 
 | ||||
|     @commands.group() | ||||
|     async def ww(self, ctx: RedContext): | ||||
|     async def ww(self, ctx: commands.Context): | ||||
|         """ | ||||
|         Base command for this cog. Check help for the commands list. | ||||
|         """ | ||||
| @ -139,7 +139,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @ww.command(name="new") | ||||
|     async def ww_new(self, ctx: RedContext, game_code=None): | ||||
|     async def ww_new(self, ctx: commands.Context, game_code=None): | ||||
|         """ | ||||
|         Create and join a new game of Werewolf | ||||
|         """ | ||||
| @ -151,7 +151,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @ww.command(name="join") | ||||
|     async def ww_join(self, ctx: RedContext): | ||||
|     async def ww_join(self, ctx: commands.Context): | ||||
|         """ | ||||
|         Joins a game of Werewolf | ||||
|         """ | ||||
| @ -166,7 +166,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @ww.command(name="code") | ||||
|     async def ww_code(self, ctx: RedContext, code): | ||||
|     async def ww_code(self, ctx: commands.Context, code): | ||||
|         """ | ||||
|         Adjust game code | ||||
|         """ | ||||
| @ -181,7 +181,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @ww.command(name="quit") | ||||
|     async def ww_quit(self, ctx: RedContext): | ||||
|     async def ww_quit(self, ctx: commands.Context): | ||||
|         """ | ||||
|         Quit a game of Werewolf | ||||
|         """ | ||||
| @ -192,7 +192,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @ww.command(name="start") | ||||
|     async def ww_start(self, ctx: RedContext): | ||||
|     async def ww_start(self, ctx: commands.Context): | ||||
|         """ | ||||
|         Checks number of players and attempts to start the game | ||||
|         """ | ||||
| @ -205,7 +205,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @ww.command(name="stop") | ||||
|     async def ww_stop(self, ctx: RedContext): | ||||
|     async def ww_stop(self, ctx: commands.Context): | ||||
|         """ | ||||
|         Stops the current game | ||||
|         """ | ||||
| @ -223,7 +223,7 @@ class Werewolf: | ||||
| 
 | ||||
|     @commands.guild_only() | ||||
|     @ww.command(name="vote") | ||||
|     async def ww_vote(self, ctx: RedContext, target_id: int): | ||||
|     async def ww_vote(self, ctx: commands.Context, target_id: int): | ||||
|         """ | ||||
|         Vote for a player by ID | ||||
|         """ | ||||
| @ -263,7 +263,7 @@ class Werewolf: | ||||
|             await ctx.send("Nothing to vote for in this channel") | ||||
| 
 | ||||
|     @ww.command(name="choose") | ||||
|     async def ww_choose(self, ctx: RedContext, data): | ||||
|     async def ww_choose(self, ctx: commands.Context, data): | ||||
|         """ | ||||
|         Arbitrary decision making | ||||
|         Handled by game+role | ||||
| @ -285,7 +285,7 @@ class Werewolf: | ||||
|         await game.choose(ctx, data) | ||||
| 
 | ||||
|     @ww.group(name="search") | ||||
|     async def ww_search(self, ctx: RedContext): | ||||
|     async def ww_search(self, ctx: commands.Context): | ||||
|         """ | ||||
|         Find custom roles by name, alignment, category, or ID | ||||
|         """ | ||||
| @ -293,7 +293,7 @@ class Werewolf: | ||||
|             await ctx.send_help() | ||||
| 
 | ||||
|     @ww_search.command(name="name") | ||||
|     async def ww_search_name(self, ctx: RedContext, *, name): | ||||
|     async def ww_search_name(self, ctx: commands.Context, *, name): | ||||
|         """Search for a role by name""" | ||||
|         if name is not None: | ||||
|             from_name = role_from_name(name) | ||||
| @ -303,7 +303,7 @@ class Werewolf: | ||||
|                 await ctx.send("No roles containing that name were found") | ||||
| 
 | ||||
|     @ww_search.command(name="alignment") | ||||
|     async def ww_search_alignment(self, ctx: RedContext, alignment: int): | ||||
|     async def ww_search_alignment(self, ctx: commands.Context, alignment: int): | ||||
|         """Search for a role by alignment""" | ||||
|         if alignment is not None: | ||||
|             from_alignment = role_from_alignment(alignment) | ||||
| @ -313,7 +313,7 @@ class Werewolf: | ||||
|                 await ctx.send("No roles with that alignment were found") | ||||
| 
 | ||||
|     @ww_search.command(name="category") | ||||
|     async def ww_search_category(self, ctx: RedContext, category: int): | ||||
|     async def ww_search_category(self, ctx: commands.Context, category: int): | ||||
|         """Search for a role by category""" | ||||
|         if category is not None: | ||||
|             pages = role_from_category(category) | ||||
| @ -323,7 +323,7 @@ class Werewolf: | ||||
|                 await ctx.send("No roles in that category were found") | ||||
| 
 | ||||
|     @ww_search.command(name="index") | ||||
|     async def ww_search_index(self, ctx: RedContext, idx: int): | ||||
|     async def ww_search_index(self, ctx: commands.Context, idx: int): | ||||
|         """Search for a role by ID""" | ||||
|         if idx is not None: | ||||
|             idx_embed = role_from_id(idx) | ||||
| @ -332,7 +332,7 @@ class Werewolf: | ||||
|             else: | ||||
|                 await ctx.send("Role ID not found") | ||||
| 
 | ||||
|     async def _get_game(self, ctx: RedContext, game_code=None): | ||||
|     async def _get_game(self, ctx: commands.Context, game_code=None): | ||||
|         guild: discord.Guild = ctx.guild | ||||
| 
 | ||||
|         if guild is None: | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Bobloy
						Bobloy