forked from viveksantayana/geas-bot
		
	Finessed game create and delete commands
This commit is contained in:
		
							
								
								
									
										22
									
								
								app/bot.py
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								app/bot.py
									
									
									
									
									
								
							| @@ -42,6 +42,12 @@ lookupFile = os.getenv('LOOKUP') if os.getenv('LOOKUP').endswith('.yml') or os.g | |||||||
| if not os.path.exists(lookupFile): | if not os.path.exists(lookupFile): | ||||||
| 	yaml_dump({},lookupFile) | 	yaml_dump({},lookupFile) | ||||||
|  |  | ||||||
|  | # Locate or create GM lookup file. Same as above. | ||||||
|  | gmFile = os.getenv('GM') if os.getenv('GM').endswith('.yml') or os.getenv('GM').endswith('.yaml') else './data/gm.yml' | ||||||
|  |  | ||||||
|  | if not os.path.exists(gmFile): | ||||||
|  | 	yaml_dump({},gmFile) | ||||||
|  |  | ||||||
| # Locate Cogs Directory | # Locate Cogs Directory | ||||||
| cogsDir = 'cogs' | cogsDir = 'cogs' | ||||||
|  |  | ||||||
| @@ -114,7 +120,7 @@ def setConfig(guild:discord.Guild): | |||||||
| 			if not (role.is_bot_managed() or role.is_integration()) and role.permissions.administrator: | 			if not (role.is_bot_managed() or role.is_integration()) and role.permissions.administrator: | ||||||
| 				rDict['admin'].append(role.id) | 				rDict['admin'].append(role.id) | ||||||
| 	if 'timeslots' not in gDict or type(gDict['timeslots']) is not dict or None in gDict['timeslots']: | 	if 'timeslots' not in gDict or type(gDict['timeslots']) is not dict or None in gDict['timeslots']: | ||||||
| 		gDict['timeslots'] = [] | 		gDict['timeslots'] = {} | ||||||
| 	yaml_dump(conf, configFile) | 	yaml_dump(conf, configFile) | ||||||
|  |  | ||||||
| def clearConfig(guildKey:str): | def clearConfig(guildKey:str): | ||||||
| @@ -254,9 +260,15 @@ loadCogs('controlcommands') | |||||||
| loadCogs('events') | loadCogs('events') | ||||||
| loadCogs('botcommands') | loadCogs('botcommands') | ||||||
| loadCogs('slashcommands') | loadCogs('slashcommands') | ||||||
| if all([len(yaml_load(configFile)[x]['timeslots']) > 0 for x in yaml_load(configFile)]): | if yaml_load(configFile): | ||||||
| 	loadCog(f'./{cogsDir}/slashcommands/secondary/manipulate_timeslots.py') | 	if all([len(yaml_load(configFile)[x]['timeslots']) > 0 for x in yaml_load(configFile)]): | ||||||
| if all([len(yaml_load(configFile)[x]['membership']) > 0 for x in yaml_load(configFile)]): | 		loadCog(f'./{cogsDir}/slashcommands/secondary/manipulate_timeslots.py') | ||||||
| 	loadCog(f'./{cogsDir}/slashcommands/secondary/edit_membership.py') | 		if all(['bot' in yaml_load(configFile)[x]['roles'] for x in yaml_load(configFile)]): | ||||||
|  | 			loadCog(f'./{cogsDir}/slashcommands/secondary/game_setup.py') | ||||||
|  | 			if yaml_load(lookupFile): | ||||||
|  | 				if all([len(x) > 0 for x in yaml_load(lookupFile).values()]): | ||||||
|  | 					loadCog(f'./{cogsDir}/slashcommands/secondary/game_management.py') | ||||||
|  | 	if all([len(yaml_load(configFile)[x]['membership']) > 0 for x in yaml_load(configFile)]): | ||||||
|  | 		loadCog(f'./{cogsDir}/slashcommands/secondary/edit_membership.py') | ||||||
|  |  | ||||||
| client.run(os.getenv('TEST_3_TOKEN')) | client.run(os.getenv('TEST_3_TOKEN')) | ||||||
| @@ -19,7 +19,7 @@ class on_guild_role_delete(commands.Cog, name='On Guild Role Delete Events'): | |||||||
| 		conf = yaml_load(configFile) | 		conf = yaml_load(configFile) | ||||||
| 		#### Bot will only respond if the role is not a bot-managed role, and the role is an admin role | 		#### Bot will only respond if the role is not a bot-managed role, and the role is an admin role | ||||||
| 		if role.id in conf[str(role.guild.id)]['roles']['admin']: | 		if role.id in conf[str(role.guild.id)]['roles']['admin']: | ||||||
| 			conf[str(role.guild.id)]['roles']['adminroles'].remove(role.id) | 			conf[str(role.guild.id)]['roles']['admin'].remove(role.id) | ||||||
| 			yaml_dump(conf, configFile) | 			yaml_dump(conf, configFile) | ||||||
| 			#### If the role is one of the Admin roles and is deleted, updates the bot's config to delete that role, preventing unnecessary roles from accumulating. | 			#### If the role is one of the Admin roles and is deleted, updates the bot's config to delete that role, preventing unnecessary roles from accumulating. | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ from discord_slash.utils.manage_commands import create_choice, create_option, cr | |||||||
| from discord_slash.model import SlashCommandPermissionType | from discord_slash.model import SlashCommandPermissionType | ||||||
| import re | import re | ||||||
|  |  | ||||||
| from bot import configFile, yaml_load, yaml_dump, loadCog, unloadCog, reloadCog, cogsDir, slash | from bot import configFile, yaml_load, yaml_dump, loadCog, unloadCog, reloadCog, cogsDir, slash, lookupFile | ||||||
|  |  | ||||||
| ##### Configuration Cog | ##### Configuration Cog | ||||||
| class Configuration(commands.Cog, name='Configuration Commands'): | class Configuration(commands.Cog, name='Configuration Commands'): | ||||||
| @@ -63,21 +63,57 @@ class Configuration(commands.Cog, name='Configuration Commands'): | |||||||
| 					) | 					) | ||||||
| 				] | 				] | ||||||
| 			), | 			), | ||||||
|  | 			create_option( | ||||||
|  | 				name='role_exists', | ||||||
|  | 				description='Whether or not a role for this parameter already exists', | ||||||
|  | 				option_type=5, | ||||||
|  | 				required=True | ||||||
|  | 			), | ||||||
| 			create_option( | 			create_option( | ||||||
| 				name='role', | 				name='role', | ||||||
| 				description='The role assigned to the parameter.', | 				description='The role assigned to the parameter.', | ||||||
| 				option_type=8, | 				option_type=8, | ||||||
| 				required=True | 				required=False | ||||||
| 			) | 			) | ||||||
| 		] | 		] | ||||||
| 	) | 	) | ||||||
| 	async def _config_roles(self, ctx:SlashContext, key:str, role:discord.Role): | 	async def _config_roles(self, ctx:SlashContext, key:str, role_exists:bool, role:discord.Role=None): | ||||||
|  | 		if role_exists and role is None: | ||||||
|  | 			await ctx.send(f'```If the role you want to assign to `{key}` already exists, you must assign it. If it does not exist, the Bot will create one.```') | ||||||
|  | 			return | ||||||
|  | 		if not role_exists and role is not None: | ||||||
|  | 			await ctx.send(f'```You have specified a role to assign to `{key}` but have also specified it does not exist. If a role already exists, indicate it. If it does not exist, do not assign a role.```') | ||||||
|  | 			return | ||||||
|  | 		r = role | ||||||
|  | 		if not role_exists: | ||||||
|  | 			r = await ctx.guild.create_role( | ||||||
|  | 				name=key, | ||||||
|  | 				permissions=discord.Permissions(administrator=True) if key == 'committee' else discord.Permissions().none(), | ||||||
|  | 				reason=f'`/config roles` command issued by {ctx.author.display_name}', | ||||||
|  | 				colour = discord.Colour.orange() if key == 'bot' else discord.Colour.blue() if key == 'committee' else discord.Colour.default(), | ||||||
|  | 				hoist=True if key == 'committee' else None, | ||||||
|  | 			) | ||||||
|  | 		else: | ||||||
|  | 			await r.edit( | ||||||
|  | 				permissions=discord.Permissions(administrator=True) if key == 'committee' else discord.Permissions().none(), | ||||||
|  | 				reason=f'`/config roles` command issued by {ctx.author.display_name}', | ||||||
|  | 				colour = discord.Colour.orange() if key == 'bot' else discord.Colour.blue() if key == 'committee' else discord.Colour.default(), | ||||||
|  | 				hoist=True if key == 'committee' else None, | ||||||
|  | 			) | ||||||
| 		conf = yaml_load(configFile) | 		conf = yaml_load(configFile) | ||||||
| 		if 'roles' not in conf[str(ctx.guild.id)]: | 		if 'roles' not in conf[str(ctx.guild.id)]: | ||||||
| 			conf[str(ctx.guild.id)]['roles'] = {} | 			conf[str(ctx.guild.id)]['roles'] = {} | ||||||
| 		conf[str(ctx.guild.id)]['roles'][key] = int(role.id) | 		conf[str(ctx.guild.id)]['roles'][key] = int(r.id) | ||||||
| 		yaml_dump(conf, configFile) | 		yaml_dump(conf, configFile) | ||||||
| 		await ctx.send(f'```The `{key}` role for the guild `{ctx.guild.name}` has been set to `{role.name}`.```') | 		await ctx.send(f'```The `{key}` role for the guild `{ctx.guild.name}` has been set to `{r.name}`.```\n{r.mention}') | ||||||
|  | 		if all(['bot' in yaml_load(configFile)[x]['roles'] for x in yaml_load(configFile)]): | ||||||
|  | 			if all([len(yaml_load(configFile)[x]['timeslots']) > 0 for x in yaml_load(configFile)]): | ||||||
|  | 				if self.client.get_cog('Game Setup') is None: | ||||||
|  | 					loadCog(f'./{cogsDir}/slashcommands/secondary/game_setup.py') | ||||||
|  | 				if all([x for x in yaml_load(lookupFile).values()]): | ||||||
|  | 					if self.client.get_cog('Game Management') is None: | ||||||
|  | 						loadCog(f'./{cogsDir}/slashcommands/secondary/game_management.py') | ||||||
|  | 			await self.client.slash.sync_all_commands() | ||||||
|  |  | ||||||
| 	@cog_ext.cog_subcommand( | 	@cog_ext.cog_subcommand( | ||||||
| 		base='config', | 		base='config', | ||||||
| @@ -105,26 +141,51 @@ class Configuration(commands.Cog, name='Configuration Commands'): | |||||||
| 						value='mod' | 						value='mod' | ||||||
| 					), | 					), | ||||||
| 					create_choice( | 					create_choice( | ||||||
| 						name='SIgnup Channel', | 						name='Signup Channel', | ||||||
| 						value='signup' | 						value='signup' | ||||||
| 					) | 					) | ||||||
| 				] | 				] | ||||||
| 			), | 			), | ||||||
|  | 			create_option( | ||||||
|  | 				name='channel_exists', | ||||||
|  | 				description='Does the channel for this parameter already exist?', | ||||||
|  | 				option_type=5, | ||||||
|  | 				required=True | ||||||
|  | 			), | ||||||
| 			create_option( | 			create_option( | ||||||
| 				name='channel', | 				name='channel', | ||||||
| 				description='The channel assigned to the parameter.', | 				description='The channel assigned to the parameter.', | ||||||
| 				option_type=7, | 				option_type=7, | ||||||
| 				required=True | 				required=False | ||||||
| 			) | 			) | ||||||
| 		] | 		] | ||||||
| 	) | 	) | ||||||
| 	async def _config_channels(self, ctx:SlashContext, key:str, channel:discord.TextChannel): | 	async def _config_channels(self, ctx:SlashContext, key:str, channel_exists:bool, channel:discord.TextChannel=None): | ||||||
|  | 		if channel_exists and channel is None: | ||||||
|  | 			await ctx.send(f'```If the channel you want to assign to `{key}` already exists, you must assign it. If it does not exist, the Bot will create one.```') | ||||||
|  | 			return | ||||||
|  | 		if not channel_exists and channel is not None: | ||||||
|  | 			await ctx.send(f'```You have specified a channel to assign to `{key}` but have also specified it does not exist. If a channel already exists, indicate it. If it does not exist, do not assign a channel.```') | ||||||
|  | 			return | ||||||
|  | 		c = channel | ||||||
|  | 		if not channel_exists: | ||||||
|  | 			c = await ctx.guild.create_text_channel( | ||||||
|  | 				name=key, | ||||||
|  | 				overwrites={}, | ||||||
|  | 				reason=f'`/config channels` command issued by {ctx.author.display_name}' | ||||||
|  | 			) | ||||||
|  | 		else: | ||||||
|  | 			await c.edit( | ||||||
|  | 				name=key, | ||||||
|  | 				overwrites={}, | ||||||
|  | 				reason=f'`/config channels` command issued by {ctx.author.display_name}' | ||||||
|  | 			) | ||||||
| 		conf = yaml_load(configFile) | 		conf = yaml_load(configFile) | ||||||
| 		if 'channels' not in conf[str(ctx.guild.id)]: | 		if 'channels' not in conf[str(ctx.guild.id)]: | ||||||
| 			conf[str(ctx.guild.id)]['channels'] = {} | 			conf[str(ctx.guild.id)]['channels'] = {} | ||||||
| 		conf[str(ctx.guild.id)]['channels'][key] = int(channel.id) | 		conf[str(ctx.guild.id)]['channels'][key] = int(c.id) | ||||||
| 		yaml_dump(conf, configFile) | 		yaml_dump(conf, configFile) | ||||||
| 		await ctx.send(f'```The `{key}` channel for the guild `{ctx.guild.name}` has been set to `{channel.name}`.```') | 		await ctx.send(f'```The `{key}` channel for the guild `{ctx.guild.name}` has been set to `{c.name}`.\n\nAll permission overrides for the channel have been reset. Remember to set the appropriate permissions for your guild.```\n{c.mention}') | ||||||
|  |  | ||||||
| 	@cog_ext.cog_subcommand( | 	@cog_ext.cog_subcommand( | ||||||
| 		base='config', | 		base='config', | ||||||
| @@ -210,6 +271,13 @@ class Configuration(commands.Cog, name='Configuration Commands'): | |||||||
| 		if all([len(yaml_load(configFile)[x]['timeslots']) > 0 for x in yaml_load(configFile)]): | 		if all([len(yaml_load(configFile)[x]['timeslots']) > 0 for x in yaml_load(configFile)]): | ||||||
| 			if self.client.get_cog('Manipulate Timeslots') is None: | 			if self.client.get_cog('Manipulate Timeslots') is None: | ||||||
| 				loadCog(f'./{cogsDir}/slashcommands/secondary/manipulate_timeslots.py') | 				loadCog(f'./{cogsDir}/slashcommands/secondary/manipulate_timeslots.py') | ||||||
|  | 			if all(['bot' in yaml_load(configFile)[x]['roles'] for x in yaml_load(configFile)]): | ||||||
|  | 				if self.client.get_cog('Game Setup') is None: | ||||||
|  | 					loadCog(f'./{cogsDir}/slashcommands/secondary/game_setup.py') | ||||||
|  | 				if yaml_load(lookupFile): | ||||||
|  | 					if all([x for x in yaml_load(lookupFile).values()]): | ||||||
|  | 						if self.client.get_cog('Game Management') is None: | ||||||
|  | 							loadCog(f'./{cogsDir}/slashcommands/secondary/game_management.py') | ||||||
| 			await self.client.slash.sync_all_commands() | 			await self.client.slash.sync_all_commands() | ||||||
|  |  | ||||||
| 	@cog_ext.cog_subcommand( | 	@cog_ext.cog_subcommand( | ||||||
| @@ -245,7 +313,7 @@ class Configuration(commands.Cog, name='Configuration Commands'): | |||||||
| 	) | 	) | ||||||
| 	async def _config_membership_add(self, ctx:SlashContext, name:str, role_exists:bool, role:discord.Role=None): | 	async def _config_membership_add(self, ctx:SlashContext, name:str, role_exists:bool, role:discord.Role=None): | ||||||
| 		if role_exists and role is None: | 		if role_exists and role is None: | ||||||
| 			await ctx.send(f'```If the role for membership type `{name}` already exists, you must assign it. If it has not been assigned, the Bot will create one.```') | 			await ctx.send(f'```If the role for membership type `{name}` already exists, you must assign it. If it does not exist, the Bot will create one.```') | ||||||
| 			return | 			return | ||||||
| 		if not role_exists and role is not None: | 		if not role_exists and role is not None: | ||||||
| 			await ctx.send(f'```You have specified a role for `{name}` does not already exist but have also specified a role to assign. Please either assign a role if it exists, or leave it blank if does not.```') | 			await ctx.send(f'```You have specified a role for `{name}` does not already exist but have also specified a role to assign. Please either assign a role if it exists, or leave it blank if does not.```') | ||||||
| @@ -264,7 +332,8 @@ class Configuration(commands.Cog, name='Configuration Commands'): | |||||||
| 			r = await ctx.guild.create_role( | 			r = await ctx.guild.create_role( | ||||||
| 				name=name, | 				name=name, | ||||||
| 				permissions=discord.Permissions(read_messages=True,use_slash_commands=True), | 				permissions=discord.Permissions(read_messages=True,use_slash_commands=True), | ||||||
| 				mentionable=False | 				mentionable=False, | ||||||
|  | 				reason=f'`/config membership add` command issued by {ctx.author.display_name}' | ||||||
| 			) | 			) | ||||||
| 		if role is not None: | 		if role is not None: | ||||||
| 			await role.edit( | 			await role.edit( | ||||||
| @@ -281,5 +350,39 @@ class Configuration(commands.Cog, name='Configuration Commands'): | |||||||
| 				loadCog(f'./{cogsDir}/slashcommands/secondary/edit_membership.py') | 				loadCog(f'./{cogsDir}/slashcommands/secondary/edit_membership.py') | ||||||
| 			await self.client.slash.sync_all_commands() | 			await self.client.slash.sync_all_commands() | ||||||
|  |  | ||||||
|  | 	@cog_ext.cog_slash( | ||||||
|  | 		name='test', | ||||||
|  | 		description='testing options', | ||||||
|  | 		guild_ids=guild_ids, | ||||||
|  | 		options=[ | ||||||
|  | 			create_option( | ||||||
|  | 				name='required', | ||||||
|  | 				description='This option is mandatory', | ||||||
|  | 				option_type=3, | ||||||
|  | 				required=True | ||||||
|  | 			), | ||||||
|  | 			create_option( | ||||||
|  | 				name='not_required', | ||||||
|  | 				description='This option is not mandatory', | ||||||
|  | 				option_type=3, | ||||||
|  | 				required=False | ||||||
|  | 			), | ||||||
|  | 			create_option( | ||||||
|  | 				name='optional', | ||||||
|  | 				description='This option is optional', | ||||||
|  | 				option_type=3, | ||||||
|  | 				required=False | ||||||
|  | 			) | ||||||
|  | 		] | ||||||
|  | 	) | ||||||
|  | 	async def _test( | ||||||
|  | 		self, | ||||||
|  | 		ctx:SlashContext, | ||||||
|  | 		required:str, | ||||||
|  | 		not_required:str=None, | ||||||
|  | 		optional:str=None | ||||||
|  | 	): | ||||||
|  | 		await ctx.send(f'```You entered: name = {required}, not_required = {not_required}, and optional = {optional}```') | ||||||
|  |  | ||||||
| def setup(client): | def setup(client): | ||||||
| 	client.add_cog(Configuration(client)) | 	client.add_cog(Configuration(client)) | ||||||
| @@ -57,7 +57,7 @@ class EditMembership(commands.Cog, name='Edit Membership'): | |||||||
| 			yaml_dump(conf, configFile) | 			yaml_dump(conf, configFile) | ||||||
| 			await ctx.send(f'```Membership type {role.name} has been deleted for the guild `{ctx.guild.name}`.```') | 			await ctx.send(f'```Membership type {role.name} has been deleted for the guild `{ctx.guild.name}`.```') | ||||||
| 			await role.delete(reason=f'`/config membership remove` command issued by `{ctx.author.display_name}`.') | 			await role.delete(reason=f'`/config membership remove` command issued by `{ctx.author.display_name}`.') | ||||||
| 			if not all([len(yaml_load(configFile)[x]['membership']) > 0 for x in yaml_load(configFile)]): | 			if not any([x['membership'] for x in yaml_load(configFile).values()]): | ||||||
| 				unloadCog(f'./{cogsDir}/slashcommands/secondary/edit_membership.py') | 				unloadCog(f'./{cogsDir}/slashcommands/secondary/edit_membership.py') | ||||||
| 				await self.client.slash.sync_all_commands() | 				await self.client.slash.sync_all_commands() | ||||||
| 		elif len(conf[str(ctx.guild.id)]['membership']) > 0: | 		elif len(conf[str(ctx.guild.id)]['membership']) > 0: | ||||||
|   | |||||||
| @@ -9,170 +9,19 @@ from discord_slash.model import SlashCommandPermissionType | |||||||
| from discord_slash.client import SlashCommand | from discord_slash.client import SlashCommand | ||||||
| import re | import re | ||||||
|  |  | ||||||
| from bot import configFile, yaml_load, yaml_dump, reloadCog, cogsDir, unloadCog, dataFile, lookupFile | from bot import configFile, yaml_load, yaml_dump, reloadCog, cogsDir, unloadCog, dataFile, lookupFile, gmFile | ||||||
|  |  | ||||||
| #### Game Role and Channel Management Commands | class GameManagement(commands.Cog, name='Game Management'): | ||||||
|  |  | ||||||
| class GameSetup(commands.Cog, name='Game Setup'): |  | ||||||
| 	def __init__(self, client): | 	def __init__(self, client): | ||||||
| 		self.client = client | 		self.client = client | ||||||
|  |  | ||||||
| 	permissions={} | 	conf = yaml_load(configFile) | ||||||
| 	guild_ids = list(set.union(set([int(guildKey) for guildKey in yaml_load(configFile) if len(yaml_load(configFile)[guildKey]['timeslots']) > 0]),set([int(guildKey) for guildKey in yaml_load(configFile) if type(yaml_load(configFile)[guildKey]['roles']['bot']) is int]))) | 	lookup = yaml_load(lookupFile) | ||||||
| 	permissions[guildID] = [] | 	data = yaml_load(dataFile) | ||||||
| 	permissions[guildID].append(create_permission(id=conf[str(guildID)]['owner'],id_type=SlashCommandPermissionType.USER,permission=True)) |  | ||||||
| 	for admin in conf[str(guildID)]['roles']['admin']: |  | ||||||
| 		permissions[guildID].append(create_permission(id=admin,id_type=SlashCommandPermissionType.ROLE,permission=True)) |  | ||||||
|  |  | ||||||
| 	@cog_ext.cog_subcommand( | 	guild_ids= [ int(x) for x in list(lookup)] | ||||||
| 		base='game', |  | ||||||
| 		# subcommand_group='', |  | ||||||
| 		name='create', |  | ||||||
| 		description='Create a new game role and accompanying category, text, and voice channels.', |  | ||||||
| 		base_description='Commands for setting up and removing games on the Guild.', |  | ||||||
| 		base_default_permission=False, |  | ||||||
| 		base_permissions=permissions, |  | ||||||
| 		# subcommand_group_description='Adds a time slot available to the channel for games.', |  | ||||||
| 		guild_ids=guild_ids, |  | ||||||
| 		options=[ |  | ||||||
| 			create_option( |  | ||||||
| 				name='timeslot', |  | ||||||
| 				description='The timeslot code for when the game will run.', |  | ||||||
| 				option_type=3, |  | ||||||
| 				required=True |  | ||||||
| 			), |  | ||||||
| 			create_option( |  | ||||||
| 				name='gm', |  | ||||||
| 				description='The person who will be running the game.', |  | ||||||
| 				option_type=6, |  | ||||||
| 				required=True |  | ||||||
| 			), |  | ||||||
| 			create_option( |  | ||||||
| 				name='max_players', |  | ||||||
| 				description='The maximum number of players the GM can take.', |  | ||||||
| 				option_type=3, |  | ||||||
| 				required=True |  | ||||||
| 			), |  | ||||||
| 			create_option( |  | ||||||
| 				name='min_players', |  | ||||||
| 				description='The minimum number of players the GM can take.', |  | ||||||
| 				option_type=3, |  | ||||||
| 				required=False |  | ||||||
| 			), |  | ||||||
| 			create_option( |  | ||||||
| 				name='reserved_spaces', |  | ||||||
| 				description='The number of spaces the GM is reserving in the game.', |  | ||||||
| 				option_type=3, |  | ||||||
| 				required=False |  | ||||||
| 			), |  | ||||||
| 			create_option( |  | ||||||
| 				name='game_title', |  | ||||||
| 				description='What the game is called.', |  | ||||||
| 				option_type=3, |  | ||||||
| 				required=True |  | ||||||
| 			), |  | ||||||
| 			create_option( |  | ||||||
| 				name='system', |  | ||||||
| 				description='What system the game is using.', |  | ||||||
| 				option_type=3, |  | ||||||
| 				required=False |  | ||||||
| 			), |  | ||||||
| 			create_option( |  | ||||||
| 				name='platform', |  | ||||||
| 				description='What platform the game will be running on.', |  | ||||||
| 				option_type=3, |  | ||||||
| 				required=False |  | ||||||
| 			) |  | ||||||
| 		] |  | ||||||
| 	) |  | ||||||
| 	async def _game_create( |  | ||||||
| 		self, |  | ||||||
| 		ctx:SlashContext, |  | ||||||
| 		timeslot:str, |  | ||||||
| 		gm:discord.Member, |  | ||||||
| 		max_players:int, |  | ||||||
| 		game_title:str, |  | ||||||
| 		min_players:int=None, |  | ||||||
| 		reserved_spaces:int=None, |  | ||||||
| 		system:str=None, |  | ||||||
| 		platform:str=None |  | ||||||
| 	): |  | ||||||
| 		await ctx.channel.trigger_typing() |  | ||||||
| 		conf = yaml_load(configFile) |  | ||||||
| 		data = yaml_load(dataFile) |  | ||||||
| 		lookup = yaml_load(lookupFile) |  | ||||||
| 		guildStr = str(ctx.guild.id) |  | ||||||
| 		time =  re.sub(r"\W+",'', timeslot[:9].lower()) |  | ||||||
| 		if 'roles' not in conf[guildStr]: |  | ||||||
| 			conf[guildStr]['roles'] = {} |  | ||||||
| 		if 'bot' not in conf[guildStr]['roles']: |  | ||||||
| 			await ctx.send(f'```\`Bot` role for guild `{ctx.guild.name}` has not been defined. Cannot configure game.```') |  | ||||||
| 			return |  | ||||||
| 		if 'timeslots' not in conf[guildStr]: |  | ||||||
| 			conf[guildStr]['timeslots'] = {} |  | ||||||
| 		if time not in conf[guildStr]['timeslots']: |  | ||||||
| 			await ctx.send(f'```Time code `{timeslot}` is not recognised. Please enter a valid time code to register the game.```') |  | ||||||
| 			return |  | ||||||
| 		if guildStr not in data: |  | ||||||
| 			data[guildStr] = {} |  | ||||||
| 		if time not in data[guildStr]: |  | ||||||
| 			data[guildStr][time] = [] |  | ||||||
| 		r = await ctx.guild.create_role( |  | ||||||
| 			name=f'{time.upper}: {game_title}', |  | ||||||
| 			reason=f'/game create command issued by `{ctx.author.display_name}`', |  | ||||||
| 			mentionable=True, |  | ||||||
| 			permissions=discord.Permissions.none(), |  | ||||||
| 		) |  | ||||||
| 		permissions = { |  | ||||||
| 			ctx.guild.default_role: discord.PermissionOverwrite(read_messages=False), |  | ||||||
| 			r: discord.PermissionOverwrite(read_messages=True), |  | ||||||
| 			ctx.guild.get_role(conf[guildStr]['roles']['bot']): discord.PermissionOverwrite(read_messages=True), |  | ||||||
| 			gm: discord.PermissionOverwrite(read_messages=True, manage_messages=True, manage_channels=True, manage_permissions=True,priority_speaker=True,move_members=True,mute_members=True,deafen_members=True) |  | ||||||
| 		} |  | ||||||
| 		c = await ctx.guild.create_category( |  | ||||||
| 			name=f'{time.upper}: {game_title}', |  | ||||||
| 			overwrites=permissions, |  | ||||||
| 			reason=f'/game create command issued by `{ctx.author.display_name}`' |  | ||||||
| 		) |  | ||||||
| 		await c.create_voice_channel(name=f'voice: {game_title}', topic=f'Default voice channel for the game `{game_title}`` taking place at `{conf[guildStr]["timeslots"][time]}`, with GM `{gm.display_name}`.',reason=f'/game create command issued by `{ctx.author.display_name}`') |  | ||||||
| 		t = await c.create_text_channel( |  | ||||||
| 			name=f'text: {game_title}', |  | ||||||
| 			topic=f'Default text channel for the game `{game_title}`` taking place at `{conf[guildStr]["timeslots"][time]}`, with GM `{gm.display_name}`.', |  | ||||||
| 			reason=f'/game create command issued by `{ctx.author.display_name}`' |  | ||||||
| 		) |  | ||||||
| 		await ctx.send(f'```Roles and channels for the game `{game_title}` have been created.```\n{r.mention}') |  | ||||||
| 		output = f'```Hello {gm.display_name}! Yout game channels for `{game_title}` have been created.\nYou can ping your players or edit the game settings by interacting with the game role through the Bot commands. Have fun!```\n' |  | ||||||
| 		output = ''.join([output,f'```Game Title: {game_title}\n']) |  | ||||||
| 		output = ''.join([output,f'GM: {gm.display_name}\n']) |  | ||||||
| 		output = ''.join([output,f'Time: {conf[guildStr]["timeslots"][time]}\n']) |  | ||||||
| 		output = ''.join([output,f'System: {system}\n'if system is not None else '']) |  | ||||||
| 		output = ''.join([output,f'Max Players: {max_players}\n']) |  | ||||||
| 		output = ''.join([output,f'Min Players: {min_players}\n'if min_players is not None else '']) |  | ||||||
| 		output = ''.join([output,f'Reserved Spaces: {reserved_spaces}\n' if reserved_spaces is not None else '']) |  | ||||||
| 		output = ''.join([output,f'Platform: {platform}```' if platform is not None else '```']) |  | ||||||
| 		o = await t.send(output) |  | ||||||
| 		await o.pin(reason=f'/game create command issued by `{ctx.author.display_name}`') |  | ||||||
| 		tDict = {} |  | ||||||
| 		tDict['game_title'] = game_title |  | ||||||
| 		tDict['gm'] = gm.id |  | ||||||
| 		tDict['max_players'] = max_players |  | ||||||
| 		tDict['min_players'] = min_players |  | ||||||
| 		tDict['reserved_spaces'] = reserved_spaces |  | ||||||
| 		tDict['system'] = system |  | ||||||
| 		tDict['platform'] = platform |  | ||||||
| 		tDict['role'] = r.id |  | ||||||
| 		tDict['category'] = c.id |  | ||||||
| 		data[guildStr][time].append(tDict) |  | ||||||
| 		if guildStr not in lookup: |  | ||||||
| 			lookup[guildStr] = {} |  | ||||||
| 		lookup[guildStr][str(r.id)] = {} |  | ||||||
| 		lookup[guildStr][str(r.id)]['category'] = c.id |  | ||||||
| 		lookup[guildStr][str(r.id)]['gm'] = gm.id |  | ||||||
| 		lookup[guildStr][str(r.id)]['time'] = time |  | ||||||
| 		yaml_dump(data,dataFile) |  | ||||||
| 		yaml_dump(lookup,lookupFile) |  | ||||||
|  |  | ||||||
| 	### Move delete, Modify, and Reset commands to a separate secondary cog to enable when games exist? | ### Move delete, Modify, and Reset commands to a separate secondary cog to enable when games exist? | ||||||
| 	@cog_ext.cog_subcommand( | 	@cog_ext.cog_subcommand( | ||||||
| 		base='game', | 		base='game', | ||||||
| 		# subcommand_group='', | 		# subcommand_group='', | ||||||
| @@ -196,28 +45,50 @@ class GameSetup(commands.Cog, name='Game Setup'): | |||||||
| 		await ctx.channel.trigger_typing() | 		await ctx.channel.trigger_typing() | ||||||
| 		conf = yaml_load(configFile) | 		conf = yaml_load(configFile) | ||||||
| 		data = yaml_load(dataFile) | 		data = yaml_load(dataFile) | ||||||
|  | 		gms = yaml_load(gmFile) | ||||||
| 		lookup = yaml_load(lookupFile) | 		lookup = yaml_load(lookupFile) | ||||||
| 		guildStr = str(ctx.guild.id) | 		guildStr = str(ctx.guild.id) | ||||||
| 		if str(game_role.id) not in lookup[guildStr]: | 		if str(game_role.id) not in lookup[guildStr]: | ||||||
| 			await ctx.send(f'```This is not a valid game role. Please mention a role that is associated with a game..```') | 			await ctx.send(f'```This is not a valid game role. Please mention a role that is associated with a game.```') | ||||||
| 			return | 			return | ||||||
|  | 		game_title = lookup[guildStr][str(game_role.id)]['game_title'] | ||||||
| 		time = lookup[guildStr][str(game_role.id)]['time'] | 		time = lookup[guildStr][str(game_role.id)]['time'] | ||||||
| 		c = ctx.guild.get_channel(lookup[guildStr][str(game_role.id)]['category']) | 		c = ctx.guild.get_channel(lookup[guildStr][str(game_role.id)]['category']) | ||||||
|  | 		gm = lookup[guildStr][str(game_role.id)]['gm'] | ||||||
|  | 		channelsFound = False | ||||||
| 		for g in list(data[guildStr][time]): | 		for g in list(data[guildStr][time]): | ||||||
| 			if game_role.id in g.values(): | 			if game_role.id in g.values(): | ||||||
| 				data[guildStr][time].remove(g) | 				data[guildStr][time].remove(g) | ||||||
| 				break | 				break | ||||||
| 		for t in ctx.guild.text_channels: | 		if c is not None: | ||||||
| 			if t.category == c: | 			channelsFound = True | ||||||
| 				await t.delete(reason=f'/game delete command issued by `{ctx.author.display_name}`') | 			for t in ctx.guild.text_channels: | ||||||
| 		for v in ctx.guild.voice_channels: | 				if t.category == c: | ||||||
| 			if v.category == c: | 					await t.delete(reason=f'/game delete command issued by `{ctx.author.display_name}`') | ||||||
| 				await v.delete(reason=f'/game delete command issued by `{ctx.author.display_name}`') | 			for v in ctx.guild.voice_channels: | ||||||
| 		await c.delete(reason=f'/game delete command issued by `{ctx.author.display_name}`') | 				if v.category == c: | ||||||
|  | 					await v.delete(reason=f'/game delete command issued by `{ctx.author.display_name}`') | ||||||
|  | 			await c.delete(reason=f'/game delete command issued by `{ctx.author.display_name}`') | ||||||
| 		lookup[guildStr].pop(str(game_role.id), None) | 		lookup[guildStr].pop(str(game_role.id), None) | ||||||
|  | 		gm_m = await ctx.guild.fetch_member(gm) | ||||||
|  | 		output = f'The game `{game_title}` for timeslot `{conf[guildStr]["timeslots"][time]}` and with GM `{gm_m.display_name}` has been deleted.' | ||||||
|  | 		if channelsFound: | ||||||
|  | 			output = ''.join([output,' All associated text, voice, and category channels have been deleted.']) | ||||||
|  | 		else: | ||||||
|  | 			output = ''.join([output,' No associated text, voice, or category channels were found. Please delete them manually if they still persist.']) | ||||||
|  | 		await ctx.send(f'```{output}```') | ||||||
| 		await game_role.delete(reason=f'/game delete command issued by `{ctx.author.display_name}`') | 		await game_role.delete(reason=f'/game delete command issued by `{ctx.author.display_name}`') | ||||||
|  | 		gms[guildStr][str(gm)].remove(game_role.id) | ||||||
|  | 		if not gms[guildStr][str(gm)]: | ||||||
|  | 			gms[guildStr].pop(str(gm)) | ||||||
| 		yaml_dump(lookup, lookupFile) | 		yaml_dump(lookup, lookupFile) | ||||||
| 		yaml_dump(data, dataFile) | 		yaml_dump(data, dataFile) | ||||||
|  | 		yaml_dump(gms, gmFile) | ||||||
|  | 		if not any([x for x in yaml_load(lookupFile).values()]): | ||||||
|  | 			unloadCog(f'./{cogsDir}/slashcommands/secondary/game_management.py') | ||||||
|  | 			await self.client.slash.sync_all_commands() | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def setup(client): | def setup(client): | ||||||
| 	client.add_cog(GameSetup(client)) | 	client.add_cog(GameManagement(client)) | ||||||
							
								
								
									
										282
									
								
								app/cogs/slashcommands/secondary/game_setup.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										282
									
								
								app/cogs/slashcommands/secondary/game_setup.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,282 @@ | |||||||
|  | import os								# OS Locations | ||||||
|  | import yaml								# YAML parser for Bot config files | ||||||
|  | import asyncio							# Discord Py Dependency | ||||||
|  | import discord							# Main Lib | ||||||
|  | from discord.ext import commands		# Commands module | ||||||
|  | from discord_slash import SlashCommand, SlashContext, cog_ext, utils			# Slash Command Library | ||||||
|  | from discord_slash.utils.manage_commands import create_choice, create_option, create_permission	# Slash Command features | ||||||
|  | from discord_slash.model import SlashCommandPermissionType | ||||||
|  | from discord_slash.client import SlashCommand | ||||||
|  | import typing | ||||||
|  | import re | ||||||
|  |  | ||||||
|  | from bot import configFile, yaml_load, yaml_dump, reloadCog, cogsDir, unloadCog, dataFile, lookupFile, gmFile, loadCog | ||||||
|  |  | ||||||
|  | #### Game Role and Channel Setup Command | ||||||
|  |  | ||||||
|  | class GameSetup(commands.Cog, name='Game Setup'): | ||||||
|  | 	def __init__(self, client): | ||||||
|  | 		self.client = client | ||||||
|  | 	 | ||||||
|  | 	conf=yaml_load(configFile) | ||||||
|  | 	permissions={} | ||||||
|  | 	guild_ids = list(set.union(set([int(guildKey) for guildKey in yaml_load(configFile) if len(yaml_load(configFile)[guildKey]['timeslots']) > 0]),set([int(guildKey) for guildKey in yaml_load(configFile) if type(yaml_load(configFile)[guildKey]['roles']['bot']) is int]))) | ||||||
|  | 	for guildID in guild_ids: | ||||||
|  | 		permissions[guildID] = [] | ||||||
|  | 		permissions[guildID].append(create_permission(id=conf[str(guildID)]['owner'],id_type=SlashCommandPermissionType.USER,permission=True)) | ||||||
|  | 		for admin in conf[str(guildID)]['roles']['admin']: | ||||||
|  | 			permissions[guildID].append(create_permission(id=admin,id_type=SlashCommandPermissionType.ROLE,permission=True)) | ||||||
|  | 	permissions[guildID] = [] | ||||||
|  | 	permissions[guildID].append(create_permission(id=conf[str(guildID)]['owner'],id_type=SlashCommandPermissionType.USER,permission=True)) | ||||||
|  | 	for admin in conf[str(guildID)]['roles']['admin']: | ||||||
|  | 		permissions[guildID].append(create_permission(id=admin,id_type=SlashCommandPermissionType.ROLE,permission=True)) | ||||||
|  |  | ||||||
|  | 	@cog_ext.cog_subcommand( | ||||||
|  | 		base='game', | ||||||
|  | 		# subcommand_group='', | ||||||
|  | 		name='create', | ||||||
|  | 		description='Create a new game role and accompanying category, text, and voice channels.', | ||||||
|  | 		base_description='Commands for setting up and removing games on the Guild.', | ||||||
|  | 		base_default_permission=False, | ||||||
|  | 		base_permissions=permissions, | ||||||
|  | 		# subcommand_group_description='Adds a time slot available to the channel for games.', | ||||||
|  | 		guild_ids=guild_ids, | ||||||
|  | 		options=[ | ||||||
|  | 			create_option( | ||||||
|  | 				name='timeslot', | ||||||
|  | 				description='The timeslot code for when the game will run.', | ||||||
|  | 				option_type=3, | ||||||
|  | 				required=True | ||||||
|  | 			), | ||||||
|  | 			create_option( | ||||||
|  | 				name='gm', | ||||||
|  | 				description='The person who will be running the game.', | ||||||
|  | 				option_type=6, | ||||||
|  | 				required=True | ||||||
|  | 			), | ||||||
|  | 			create_option( | ||||||
|  | 				name='max_players', | ||||||
|  | 				description='The maximum number of players the GM can take.', | ||||||
|  | 				option_type=4, | ||||||
|  | 				required=True | ||||||
|  | 			), | ||||||
|  | 			create_option( | ||||||
|  | 				name='game_title', | ||||||
|  | 				description='What the game is called.', | ||||||
|  | 				option_type=3, | ||||||
|  | 				required=True | ||||||
|  | 			), | ||||||
|  | 			create_option( | ||||||
|  | 				name='min_players', | ||||||
|  | 				description='The minimum number of players the GM can take.', | ||||||
|  | 				option_type=4, | ||||||
|  | 				required=False | ||||||
|  | 			), | ||||||
|  | 			create_option( | ||||||
|  | 				name='reserved_spaces', | ||||||
|  | 				description='The number of spaces the GM is reserving in the game.', | ||||||
|  | 				option_type=4, | ||||||
|  | 				required=False | ||||||
|  | 			), | ||||||
|  | 			create_option( | ||||||
|  | 				name='system', | ||||||
|  | 				description='What system the game is using.', | ||||||
|  | 				option_type=3, | ||||||
|  | 				required=False | ||||||
|  | 			), | ||||||
|  | 			create_option( | ||||||
|  | 				name='platform', | ||||||
|  | 				description='What platform the game will be running on.', | ||||||
|  | 				option_type=3, | ||||||
|  | 				required=False | ||||||
|  | 			) | ||||||
|  | 		] | ||||||
|  | 	) | ||||||
|  | 	async def _game_create( | ||||||
|  | 		self, | ||||||
|  | 		ctx:SlashContext, | ||||||
|  | 		timeslot:str, | ||||||
|  | 		gm:discord.Member, | ||||||
|  | 		max_players:int, | ||||||
|  | 		game_title:str, | ||||||
|  | 		min_players: typing.Optional[int]=None, | ||||||
|  | 		reserved_spaces: typing.Optional[int]=None, | ||||||
|  | 		system:typing.Optional[str]= None, | ||||||
|  | 		platform:typing.Optional[str]=None | ||||||
|  | 	): | ||||||
|  | 		await ctx.channel.trigger_typing() | ||||||
|  | 		conf = yaml_load(configFile) | ||||||
|  | 		data = yaml_load(dataFile) | ||||||
|  | 		gms = yaml_load(gmFile) | ||||||
|  | 		lookup = yaml_load(lookupFile) | ||||||
|  | 		guildStr = str(ctx.guild.id) | ||||||
|  | 		time =  re.sub(r"\W+",'', timeslot[:9].lower()) | ||||||
|  | 		if 'roles' not in conf[guildStr]: | ||||||
|  | 			conf[guildStr]['roles'] = {} | ||||||
|  | 		if 'bot' not in conf[guildStr]['roles']: | ||||||
|  | 			await ctx.send(f'```\`Bot` role for guild `{ctx.guild.name}` has not been defined. Cannot configure game.```') | ||||||
|  | 			return | ||||||
|  | 		if 'timeslots' not in conf[guildStr]: | ||||||
|  | 			conf[guildStr]['timeslots'] = {} | ||||||
|  | 		if time not in conf[guildStr]['timeslots']: | ||||||
|  | 			await ctx.send(f'```Time code `{timeslot}` is not recognised. Please enter a valid time code to register the game. use `/config timeslots list` to get a list of valid time codes.```') | ||||||
|  | 			return | ||||||
|  | 		if min_players > max_players: | ||||||
|  | 			await ctx.send(f'```The minimum number of players cannot exceed the maximum number of players.```') | ||||||
|  | 			return | ||||||
|  | 		if reserved_spaces > max_players: | ||||||
|  | 			await ctx.send(f'```The number of reserved spaces cannot exceed the maximum number of players.```') | ||||||
|  | 			return | ||||||
|  | 		if guildStr not in lookup: | ||||||
|  | 			lookup[guildStr] = {} | ||||||
|  | 		if game_title in [x['game_title'] for x in lookup[guildStr].values()] and time in [x['time'] for x in lookup[guildStr].values()]: | ||||||
|  | 			await ctx.send(f'```Game `{game_title}` has already been created for the time slot `{conf[guildStr]["timeslots"][time]}`. Please avoud duplicates, or use the `modify` sub-command to edit the existing game.```') | ||||||
|  | 			return | ||||||
|  | 		if guildStr not in data: | ||||||
|  | 			data[guildStr] = {} | ||||||
|  | 		if time not in data[guildStr]: | ||||||
|  | 			data[guildStr][time] = [] | ||||||
|  | 		rExists, cExists = False, False | ||||||
|  | 		r = discord.utils.get(ctx.guild.roles, name=f'{time.upper()}: {game_title}') | ||||||
|  | 		if r is None: | ||||||
|  | 			r = await ctx.guild.create_role( | ||||||
|  | 				name=f'{time.upper()}: {game_title}', | ||||||
|  | 				reason=f'/game create command issued by `{ctx.author.display_name}`', | ||||||
|  | 				mentionable=True, | ||||||
|  | 				permissions=discord.Permissions.none(), | ||||||
|  | 			) | ||||||
|  | 		else: | ||||||
|  | 			rExists = True | ||||||
|  | 			await r.edit( | ||||||
|  | 				mentionable=True, | ||||||
|  | 				permissions=discord.Permissions.none(), | ||||||
|  | 				reason=f'/game create command issued by `{ctx.author.display_name}`', | ||||||
|  | 			) | ||||||
|  | 		await gm.add_roles(r) | ||||||
|  | 		permissions = { | ||||||
|  | 			ctx.guild.default_role: discord.PermissionOverwrite(read_messages=False), | ||||||
|  | 			r: discord.PermissionOverwrite(read_messages=True), | ||||||
|  | 			ctx.guild.get_role(conf[guildStr]['roles']['bot']): discord.PermissionOverwrite(read_messages=True), | ||||||
|  | 			gm: discord.PermissionOverwrite( | ||||||
|  | 				read_messages=True, | ||||||
|  | 				manage_messages=True, | ||||||
|  | 				manage_channels=True, | ||||||
|  | 				manage_permissions=True, | ||||||
|  | 				priority_speaker=True, | ||||||
|  | 				move_members=True, | ||||||
|  | 				mute_members=True, | ||||||
|  | 				deafen_members=True | ||||||
|  | 			) | ||||||
|  | 		} | ||||||
|  | 		c = discord.utils.get(ctx.guild.categories, name=f'{time.upper()}: {game_title}') | ||||||
|  | 		if c is None: | ||||||
|  | 			c = await ctx.guild.create_category( | ||||||
|  | 				name=f'{time.upper()}: {game_title}', | ||||||
|  | 				overwrites=permissions, | ||||||
|  | 				reason=f'/game create command issued by `{ctx.author.display_name}`' | ||||||
|  | 			) | ||||||
|  | 			await c.create_voice_channel( | ||||||
|  | 				name=f'voice: {game_title}', | ||||||
|  | 				topic=f'Default voice channel for the game `{game_title}`` taking place at `{conf[guildStr]["timeslots"][time]}`, with GM `{gm.display_name}`.', | ||||||
|  | 				reason=f'/game create command issued by `{ctx.author.display_name}`' | ||||||
|  | 			) | ||||||
|  | 			t = await c.create_text_channel( | ||||||
|  | 				name=f'text: {game_title}', | ||||||
|  | 				topic=f'Default text channel for the game `{game_title}`` taking place at `{conf[guildStr]["timeslots"][time]}`, with GM `{gm.display_name}`.', | ||||||
|  | 				reason=f'/game create command issued by `{ctx.author.display_name}`' | ||||||
|  | 			) | ||||||
|  | 		else: | ||||||
|  | 			cExists= True | ||||||
|  | 			await c.edit( | ||||||
|  | 				overwrites=permissions, | ||||||
|  | 				reason=f'/game create command issued by `{ctx.author.display_name}`', | ||||||
|  | 			) | ||||||
|  | 			tPos = len(ctx.guild.channels) | ||||||
|  | 			t = None | ||||||
|  | 			v = False | ||||||
|  | 			for tc in c.text_channels: | ||||||
|  | 				if tc.position <= tPos: | ||||||
|  | 					t, tPos = tc, tc.position | ||||||
|  | 				await t.edit( | ||||||
|  | 					sync_permissions=True, | ||||||
|  | 					reason=f'/game create command issued by `{ctx.author.display_name}`' | ||||||
|  | 				) | ||||||
|  | 			for vc in c.voice_channels: | ||||||
|  | 				await vc.edit( | ||||||
|  | 					sync_permissions=True, | ||||||
|  | 					reason=f'/game create command issued by `{ctx.author.display_name}`' | ||||||
|  | 				) | ||||||
|  | 				v = True | ||||||
|  | 			if t is None: | ||||||
|  | 				t = await c.create_text_channel( | ||||||
|  | 					name=f'text: {game_title}', | ||||||
|  | 					topic=f'Default text channel for the game `{game_title}`` taking place at `{conf[guildStr]["timeslots"][time]}`, with GM `{gm.display_name}`.', | ||||||
|  | 					reason=f'/game create command issued by `{ctx.author.display_name}`' | ||||||
|  | 				) | ||||||
|  | 			else: | ||||||
|  | 				pins = await t.pins | ||||||
|  | 				if pins: | ||||||
|  | 					hm = discord.utils.find(lambda x: x.text.startswith('```Hello ' and 'Your game channels for ' in x.text and x.author.id == self.client.user.id), pins) | ||||||
|  | 					await hm.delete() | ||||||
|  | 			if not v: | ||||||
|  | 				await c.create_voice_channel( | ||||||
|  | 					name=f'voice: {game_title}', | ||||||
|  | 					topic=f'Default voice channel for the game `{game_title}`` taking place at `{conf[guildStr]["timeslots"][time]}`, with GM `{gm.display_name}`.', | ||||||
|  | 					reason=f'/game create command issued by `{ctx.author.display_name}`' | ||||||
|  | 				) | ||||||
|  | 		result = f'Game `{game_title}` has been created for timeslot `{conf[guildStr]["timeslots"][time]}`` with GM `{gm.display_name}` and space for {max_players} players (with spaces {reserved_spaces} currently occupied).\n' | ||||||
|  | 		if not rExists: | ||||||
|  | 			result = ''.join([result,f'There was already a role that matched the game, so that role has been reconfigured.\n\nNote: Editing this role will synchronise changes with the game channels, and deleting the role will delete the game and all its data.\n\n']) | ||||||
|  | 		else: | ||||||
|  | 			result = ''.join([result,f'A role for the game has been created.\n']) | ||||||
|  | 		if not cExists: | ||||||
|  | 			result = ''.join([result,f'There was already a channel category that matched the game, so it has been reconfigured with the appropriate permissions and text and voice channels.\n\nNote: Editing this role will synchronise changes with the game channels, and deleting the role will delete the game and all its data.\n\n']) | ||||||
|  | 		else: | ||||||
|  | 			result = ''.join([result,f'A channel category with the appropriate text and voice channels has been created.\n']) | ||||||
|  | 		result = ''.join(['```',result,f'```\n{gm.mention} {r.mention} {t.mention}']) | ||||||
|  | 		output = f'```Hello {gm.display_name}! Your game channels for `{game_title}` have been created.\nYou can ping your players or edit the game settings by interacting with the game role through the Bot commands. Have fun!```\n' | ||||||
|  | 		output = ''.join([output,f'```Game Title: {game_title}\n']) | ||||||
|  | 		output = ''.join([output,f'GM: {gm.display_name}\n']) | ||||||
|  | 		output = ''.join([output,f'Time: {conf[guildStr]["timeslots"][time]}\n']) | ||||||
|  | 		output = ''.join([output,f'System: {system}\n'if system is not None else '']) | ||||||
|  | 		output = ''.join([output,f'Max Players: {max_players}\n']) | ||||||
|  | 		output = ''.join([output,f'Min Players: {min_players}\n'if min_players is not None else '']) | ||||||
|  | 		output = ''.join([output,f'Current Players: {reserved_spaces}\n' if reserved_spaces is not None else '0\n']) | ||||||
|  | 		output = ''.join([output,f'Platform: {platform}```' if platform is not None else '```']) | ||||||
|  | 		await ctx.send(result) | ||||||
|  | 		o = await t.send(output) | ||||||
|  | 		await o.pin(reason=f'/game create command issued by `{ctx.author.display_name}`') | ||||||
|  | 		gDict = {} | ||||||
|  | 		gDict['game_title'] = game_title | ||||||
|  | 		gDict['gm'] = gm.id | ||||||
|  | 		gDict['max_players'] = max_players | ||||||
|  | 		gDict['min_players'] = min_players | ||||||
|  | 		gDict['current_players'] = reserved_spaces | ||||||
|  | 		gDict['system'] = system | ||||||
|  | 		gDict['platform'] = platform | ||||||
|  | 		gDict['role'] = r.id | ||||||
|  | 		gDict['category'] = c.id | ||||||
|  | 		gDict['text_channel'] = t.id | ||||||
|  | 		gDict['header_message'] = o.id | ||||||
|  | 		data[guildStr][time].append(gDict) | ||||||
|  | 		lookup[guildStr][str(r.id)] = {} | ||||||
|  | 		lookup[guildStr][str(r.id)]['category'] = c.id | ||||||
|  | 		lookup[guildStr][str(r.id)]['gm'] = gm.id | ||||||
|  | 		lookup[guildStr][str(r.id)]['time'] = time | ||||||
|  | 		lookup[guildStr][str(r.id)]['game_title'] = game_title | ||||||
|  | 		if guildStr not in gms: | ||||||
|  | 			gms[guildStr] = {} | ||||||
|  | 		if str(gm.id) not in gms[guildStr]: | ||||||
|  | 			gms[guildStr][str(gm.id)] = [] | ||||||
|  | 		gms[guildStr][str(gm.id)].append(r.id) | ||||||
|  | 		yaml_dump(data,dataFile) | ||||||
|  | 		yaml_dump(lookup,lookupFile) | ||||||
|  | 		yaml_dump(gms,gmFile) | ||||||
|  | 		if all([x for x in yaml_load(lookupFile).values()]): | ||||||
|  | 			if self.client.get_cog('Game Management') is None: | ||||||
|  | 				loadCog(f'./{cogsDir}/slashcommands/secondary/game_management.py') | ||||||
|  | 				await self.client.slash.sync_all_commands() | ||||||
|  | 		# Enable the Game Management commands | ||||||
|  |  | ||||||
|  | def setup(client): | ||||||
|  | 	client.add_cog(GameSetup(client)) | ||||||
| @@ -56,8 +56,12 @@ class ManipulateTimeslots(commands.Cog, name='Manipulate Timeslots'): | |||||||
| 			await ctx.send(f'```Timeslot {conf[str(ctx.guild.id)]["timeslots"][timeslot]} with the key `{timeslot}` has been deleted for the guild `{ctx.guild.name}`.```') | 			await ctx.send(f'```Timeslot {conf[str(ctx.guild.id)]["timeslots"][timeslot]} with the key `{timeslot}` has been deleted for the guild `{ctx.guild.name}`.```') | ||||||
| 			conf[str(ctx.guild.id)]['timeslots'].pop(timeslot, None) | 			conf[str(ctx.guild.id)]['timeslots'].pop(timeslot, None) | ||||||
| 			yaml_dump(conf, configFile) | 			yaml_dump(conf, configFile) | ||||||
| 			if not all([len(yaml_load(configFile)[x]['timeslots']) > 0 for x in yaml_load(configFile)]): | 			if not all([x['timeslots'] for x in yaml_load(configFile).values()]): | ||||||
| 				unloadCog(f'./{cogsDir}/slashcommands/secondary/manipulate_timeslots.py') | 				unloadCog(f'./{cogsDir}/slashcommands/secondary/manipulate_timeslots.py') | ||||||
|  | 				if self.client.get_cog('Game Management') is not None: | ||||||
|  | 					unloadCog(f'./{cogsDir}/slashcommands/secondary/game_management.py') | ||||||
|  | 				if self.client.get_cog('Game Setup') is not None: | ||||||
|  | 					unloadCog(f'./{cogsDir}/slashcommands/secondary/game_setup.py') | ||||||
| 				await self.client.slash.sync_all_commands() | 				await self.client.slash.sync_all_commands() | ||||||
| 		elif len(conf[str(ctx.guild.id)]['timeslots']) > 0: | 		elif len(conf[str(ctx.guild.id)]['timeslots']) > 0: | ||||||
| 			output = f'```Timeslot `{timeslot}` was not found in the guild `{ctx.guild.name}`. Please enter a valid key.\n\n Available timeslots are:\n(key): (timeslot name)' | 			output = f'```Timeslot `{timeslot}` was not found in the guild `{ctx.guild.name}`. Please enter a valid key.\n\n Available timeslots are:\n(key): (timeslot name)' | ||||||
|   | |||||||
| @@ -1 +1,23 @@ | |||||||
| {} | '864651943820525609': | ||||||
|  |   channels: | ||||||
|  |     help: 866645822472454206 | ||||||
|  |     mod: 865348933022515220 | ||||||
|  |     signup: 866110421592965171 | ||||||
|  |   configured: false | ||||||
|  |   membership: [] | ||||||
|  |   name: Test | ||||||
|  |   notifications: | ||||||
|  |     help: true | ||||||
|  |     signup: true | ||||||
|  |   owner: 493694762210033664 | ||||||
|  |   prefix: '-' | ||||||
|  |   roles: | ||||||
|  |     admin: | ||||||
|  |     - 866642278529368095 | ||||||
|  |     bot: 866639184121954305 | ||||||
|  |     committee: 866642278529368095 | ||||||
|  |     newcomer: 866645308091138060 | ||||||
|  |     returning_player: 866645365524660224 | ||||||
|  |     student: 866645394699714570 | ||||||
|  |   timeslots: | ||||||
|  |     sunaft: Sunday Afternoon 1 pm | ||||||
|   | |||||||
| @@ -1 +1,2 @@ | |||||||
| {} | '864651943820525609': | ||||||
|  |   sunaft: [] | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								app/data/gm.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								app/data/gm.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | '864651943820525609': {} | ||||||
							
								
								
									
										1
									
								
								app/data/lookup.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								app/data/lookup.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | '864651943820525609': {} | ||||||
| @@ -76,7 +76,7 @@ class Debug(commands.Cog, name='Debug Commands'): | |||||||
| 				bot_token=os.getenv('TEST_3_TOKEN'), | 				bot_token=os.getenv('TEST_3_TOKEN'), | ||||||
| 				guild_ids=[ ctx.guild.id ] | 				guild_ids=[ ctx.guild.id ] | ||||||
| 			) | 			) | ||||||
| 			await ctx.reply(f'```All slash commands have been deleted for the guold {ctx.guild.name}.```') | 			await ctx.reply(f'```All slash commands have been deleted for the guild `{ctx.guild.name}``.```') | ||||||
| 		elif command == '--global' or command == '-g': | 		elif command == '--global' or command == '-g': | ||||||
| 			await utils.manage_commands.remove_all_commands( | 			await utils.manage_commands.remove_all_commands( | ||||||
| 				bot_id=self.client.user.id, | 				bot_id=self.client.user.id, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user