Debugged membership sign-ups and pitch menu.
Ready for more rigorous testing.
This commit is contained in:
		@@ -1,36 +0,0 @@
 | 
			
		||||
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	# Slash Command features
 | 
			
		||||
import logging
 | 
			
		||||
# logger and handler
 | 
			
		||||
from bot import configFile, yaml_load, yaml_dump
 | 
			
		||||
 | 
			
		||||
#### Error Handler Event Listener for Slash Command Errors
 | 
			
		||||
class on_slash_command_error(commands.Cog, name='On Command Error'):
 | 
			
		||||
	def __init__(self, client):
 | 
			
		||||
		self.client = client
 | 
			
		||||
 | 
			
		||||
	@commands.Cog.listener()
 | 
			
		||||
	async def on_slash_command_error(self, ctx:SlashContext, error):
 | 
			
		||||
		if isinstance(error, Exception):
 | 
			
		||||
			await ctx.send(
 | 
			
		||||
				content='```Invalid Command: {error}```',
 | 
			
		||||
				tts=True,
 | 
			
		||||
				hidden=True,
 | 
			
		||||
				delete_after=10,				
 | 
			
		||||
			)
 | 
			
		||||
			# if isinstance(error, commands.CommandNotFound):
 | 
			
		||||
			# 	print(f'Error: User {ctx.author.name}#{ctx.author.discriminator} / {ctx.author.display_name} entered an invalid command <{ctx.message.clean_content}> in the guild {ctx.guild.name}.')
 | 
			
		||||
			# 	await ctx.reply(f'```Error: This is not a valid command.```')
 | 
			
		||||
			# elif isinstance(error, commands.CheckFailure):
 | 
			
		||||
			# 	print(f'Error: User {ctx.author.name}#{ctx.author.discriminator} / {ctx.author.display_name} is not authorised to issue the command <{ctx.command.name}> in the guild {ctx.guild.name}.')
 | 
			
		||||
			# 	await ctx.reply(f'```Error: You are not authorised to issue this command.```')
 | 
			
		||||
			# else:
 | 
			
		||||
			# 	print(f'User {ctx.author.name}#{ctx.author.discriminator} / {ctx.author.display_name} received error: "{error}" when attempting to issue command <{ctx.command.name}> in the guild {ctx.guild.name}.')
 | 
			
		||||
			# 	await ctx.reply(f'```Error: {error}```')
 | 
			
		||||
 | 
			
		||||
def setup(client):
 | 
			
		||||
	client.add_cog(on_slash_command_error(client))
 | 
			
		||||
							
								
								
									
										163
									
								
								app/cogs/events/secondary/pitch_listener.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								app/cogs/events/secondary/pitch_listener.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
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, ComponentContext			# 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, ButtonStyle
 | 
			
		||||
from discord_slash.client import SlashCommand
 | 
			
		||||
from discord_slash.utils.manage_components import create_select, create_select_option, create_actionrow, wait_for_component, create_button, create_actionrow
 | 
			
		||||
 | 
			
		||||
from bot import configFile, yaml_load, yaml_dump, cogsDir, unloadCog, dataFile, lookupFile, gmFile, categoriesFile, pitchesFile, configFile, dataFile, lookupFile, unloadCog
 | 
			
		||||
 | 
			
		||||
#### Pitch Command
 | 
			
		||||
 | 
			
		||||
class PitchListener(commands.Cog, name='Pitch Listener'):
 | 
			
		||||
	def __init__(self, client):
 | 
			
		||||
		self.client = client
 | 
			
		||||
 | 
			
		||||
	@commands.Cog.listener(name='on_component')
 | 
			
		||||
	async def _pitch_listener(self, ctx:ComponentContext):
 | 
			
		||||
		conf = yaml_load(configFile)
 | 
			
		||||
		data = yaml_load(dataFile)
 | 
			
		||||
		lookup = yaml_load(lookupFile)
 | 
			
		||||
		pitches = yaml_load(pitchesFile)
 | 
			
		||||
		guildStr = str(ctx.guild.id)
 | 
			
		||||
		if not pitches.get(guildStr, {}): return	# If no pitches for current guild, ignore.
 | 
			
		||||
		[timeslot] = [*pitches[guildStr]]
 | 
			
		||||
		if ctx.origin_message.id not in pitches[guildStr][timeslot]['messages'] + [pitches[guildStr][timeslot]['control']]: return	# If the context id is not in the pitch menu, ignore
 | 
			
		||||
		newcomer = returning_player = None
 | 
			
		||||
		if 'newcomer' in conf[guildStr]['roles']: newcomer = discord.utils.find(lambda x: x.id == conf[guildStr]['roles']['newcomer'], ctx.guild.roles)
 | 
			
		||||
		if 'returning_player' in conf[guildStr]['roles']: returning_player = discord.utils.find(lambda x: x.id == conf[guildStr]['roles']['returning_player'], ctx.guild.roles)
 | 
			
		||||
		control = await ctx.channel.fetch_message(pitches[guildStr][timeslot]['control'])
 | 
			
		||||
		header_message = await ctx.channel.fetch_message(pitches[guildStr][timeslot]['header_message'])
 | 
			
		||||
		if ctx.origin_message.id == control.id:
 | 
			
		||||
			if not (set(ctx.author.roles) & set([ctx.guild.get_role(x) for x in conf[str(ctx.guild.id)]['roles']['admin']]) or ctx.author == ctx.guild.owner):
 | 
			
		||||
				await ctx.send(f'```Error: You are not authorised to do this. The control panel may only be issued by an administrator.```',hidden=True)
 | 
			
		||||
			else:
 | 
			
		||||
				if ctx.custom_id == 'allow_returning':
 | 
			
		||||
					await ctx.channel.set_permissions(reason=f'/pitch control switch triggered by {ctx.author.display_name}', target=returning_player, read_messages=True)
 | 
			
		||||
					await ctx.send(f'```Returning Players have now been allowed access to the pitch menu.```',  hidden=True)
 | 
			
		||||
				if ctx.custom_id == 'allow_newcomers':
 | 
			
		||||
					await ctx.channel.set_permissions(reason=f'/pitch control switch triggered by {ctx.author.display_name}', target=newcomer, read_messages=True)
 | 
			
		||||
					await ctx.send(f'```Newcomers have now been allowed access to the pitch menu.```',  hidden=True)
 | 
			
		||||
				if ctx.custom_id == 'allow_all':
 | 
			
		||||
					await ctx.channel.set_permissions(reason=f'/pitch control switch triggered by {ctx.author.display_name}', target=ctx.guild.default_role, read_messages= True, send_messages=False)
 | 
			
		||||
					await ctx.send(f'```All members have now been allowed access to the pitch menu.```', hidden=True)
 | 
			
		||||
				if ctx.custom_id == 'close_pitches':
 | 
			
		||||
					await ctx.send(f'```Please wait: closing pitches.```', hidden=True)
 | 
			
		||||
					await header_message.delete()
 | 
			
		||||
					for message in pitches[guildStr][timeslot]['messages']:
 | 
			
		||||
						m = await ctx.channel.fetch_message(message)
 | 
			
		||||
						await m.delete()
 | 
			
		||||
					await control.delete()
 | 
			
		||||
					await ctx.channel.edit(reason=f'/pitch command issued by {ctx.author.display_name}', overwrites={})
 | 
			
		||||
					await ctx.channel.send('```Pitch menu cleared. Pitches have now concluded.```')
 | 
			
		||||
					del pitches[guildStr][timeslot]
 | 
			
		||||
					if not pitches[guildStr]: del pitches[guildStr]
 | 
			
		||||
					yaml_dump(pitches,pitchesFile)
 | 
			
		||||
					if not pitches and self.client.get_cog('Pitch Listener') is not None:
 | 
			
		||||
						unloadCog(f'./{cogsDir}/events/secondary/pitch_listener.py')
 | 
			
		||||
						#### Deactivate global pitch listener
 | 
			
		||||
		else:
 | 
			
		||||
			index = int(ctx.custom_id.split('_',1)[1])
 | 
			
		||||
			if ctx.custom_id.startswith('join_'):
 | 
			
		||||
				if set([x.id for x in ctx.author.roles]) & set(pitches[guildStr][timeslot]['roles'].values()):
 | 
			
		||||
					for r in list(set([x.id for x in ctx.author.roles]) & set(pitches[guildStr][timeslot]['roles'].values())):
 | 
			
		||||
						role = ctx.guild.get_role(r)
 | 
			
		||||
						if role.id != pitches[guildStr][timeslot]['roles'][index]:
 | 
			
		||||
							await ctx.author.remove_roles(role,reason=f'/pitch interaction by {ctx.author.display_name}')
 | 
			
		||||
							i = pitches[guildStr][timeslot]['indices'][role.id]
 | 
			
		||||
							element = pitches[guildStr][timeslot]['entries'][i]
 | 
			
		||||
							gm = await self.client.fetch_user(element['gm'])
 | 
			
		||||
							data[guildStr][timeslot][str(role.id)]['current_players'] -= 1
 | 
			
		||||
							element['current_players'] -= 1
 | 
			
		||||
							o = f'_ _\n***{element["game_title"]}*** (GM: {gm.mention})\n```\n'
 | 
			
		||||
							if element['system'] is not None: o = ''.join([o,f'System: {element["system"]}\n'])
 | 
			
		||||
							if element['min_players'] is not None: o = ''.join([o,f'Minimum Players: {str(element["min_players"])}	'])
 | 
			
		||||
							if element['max_players'] is not None: o = ''.join([o,f'Maximum Players: {str(element["max_players"])}\n'])
 | 
			
		||||
							if element['platform'] is not None: o = ''.join([o,f'Platform: {element["platform"]}\n'])
 | 
			
		||||
							o = ''.join([o,f'```'])
 | 
			
		||||
							spaces_remaining = element["max_players"] - element["current_players"]
 | 
			
		||||
							o = ''.join([o,f'~~Spaces Remaining: {str(0)}~~'])if spaces_remaining <= 0 else ''.join([o,f'Spaces Remaining: {str(spaces_remaining)}'])
 | 
			
		||||
							m = await ctx.channel.fetch_message(pitches[guildStr][timeslot]['messages'][i])
 | 
			
		||||
							await m.edit(content=o)
 | 
			
		||||
							tc = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['text_channel'],ctx.guild.text_channels)
 | 
			
		||||
							if tc is None:
 | 
			
		||||
								c = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['category'],ctx.guild.categories)
 | 
			
		||||
								if c is not None:
 | 
			
		||||
									tPos = len(ctx.guild.channels)
 | 
			
		||||
									for t in c.text_channels:
 | 
			
		||||
										if t.position <= tPos:
 | 
			
		||||
											tc = t
 | 
			
		||||
											tPos = t.position
 | 
			
		||||
							if tc is not None:
 | 
			
		||||
								await tc.send(f'```{ctx.author.display_name} has left the game.```')
 | 
			
		||||
				role = ctx.guild.get_role(pitches[guildStr][timeslot]['roles'][index])
 | 
			
		||||
				if role in ctx.author.roles:
 | 
			
		||||
					await ctx.send(f'```Error: You are already in the game `{lookup[guildStr][str(role.id)]["game_title"]}`.```', hidden=True)
 | 
			
		||||
				else:
 | 
			
		||||
					await ctx.author.add_roles(role,reason=f'/pitch interaction by {ctx.author.display_name}')
 | 
			
		||||
					element = pitches[guildStr][timeslot]['entries'][index]
 | 
			
		||||
					data[guildStr][timeslot][str(role.id)]['current_players'] += 1
 | 
			
		||||
					element['current_players'] += 1
 | 
			
		||||
					gm = await self.client.fetch_user(element['gm'])
 | 
			
		||||
					o = f'_ _\n***{element["game_title"]}*** (GM: {gm.mention})\n```\n'
 | 
			
		||||
					if element['system'] is not None: o = ''.join([o,f'System: {element["system"]}\n'])
 | 
			
		||||
					if element['min_players'] is not None: o = ''.join([o,f'Minimum Players: {str(element["min_players"])}	'])
 | 
			
		||||
					if element['max_players'] is not None: o = ''.join([o,f'Maximum Players: {str(element["max_players"])}\n'])
 | 
			
		||||
					if element['platform'] is not None: o = ''.join([o,f'Platform: {element["platform"]}\n'])
 | 
			
		||||
					o = ''.join([o,f'```'])
 | 
			
		||||
					spaces_remaining = element["max_players"] - element["current_players"]
 | 
			
		||||
					o = ''.join([o,f'~~Spaces Remaining: {str(0)}~~'])if spaces_remaining <= 0 else ''.join([o,f'Spaces Remaining: {str(spaces_remaining)}'])
 | 
			
		||||
					m = await ctx.channel.fetch_message(pitches[guildStr][timeslot]['messages'][index])
 | 
			
		||||
					await m.edit(content=o)
 | 
			
		||||
					await ctx.send(f'You have joined the game `{lookup[guildStr][str(role.id)]["game_title"]}`.',hidden=True)
 | 
			
		||||
					tc = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['text_channel'],ctx.guild.text_channels)
 | 
			
		||||
					if tc is None:
 | 
			
		||||
						c = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['category'],ctx.guild.categories)
 | 
			
		||||
						if c is not None:
 | 
			
		||||
							tPos = len(ctx.guild.channels)
 | 
			
		||||
							for t in c.text_channels:
 | 
			
		||||
								if t.position <= tPos:
 | 
			
		||||
									tc = t
 | 
			
		||||
									tPos = t.position
 | 
			
		||||
					if tc is not None:
 | 
			
		||||
						await tc.send(f'```{ctx.author.display_name} has joined the game.```')
 | 
			
		||||
			elif ctx.custom_id.startswith('leave_'):
 | 
			
		||||
				role = ctx.guild.get_role(pitches[guildStr][timeslot]['roles'][index])
 | 
			
		||||
				if role not in ctx.author.roles:
 | 
			
		||||
					await ctx.send(f'```Error: You are not in the game `{lookup[guildStr][str(role.id)]["game_title"]}`.```', hidden=True)
 | 
			
		||||
				else:
 | 
			
		||||
					await ctx.author.remove_roles(role,reason=f'/pitch interaction by {ctx.author.display_name}')
 | 
			
		||||
					data[guildStr][timeslot][str(role.id)]['current_players'] -= 1
 | 
			
		||||
					element = pitches[guildStr][timeslot]['entries'][index]
 | 
			
		||||
					gm = await self.client.fetch_user(element['gm'])
 | 
			
		||||
					o = f'_ _\n***{element["game_title"]}*** (GM: {gm.mention})\n```\n'
 | 
			
		||||
					if element['system'] is not None: o = ''.join([o,f'System: {element["system"]}\n'])
 | 
			
		||||
					if element['min_players'] is not None: o = ''.join([o,f'Minimum Players: {str(element["min_players"])}	'])
 | 
			
		||||
					if element['max_players'] is not None: o = ''.join([o,f'Maximum Players: {str(element["max_players"])}\n'])
 | 
			
		||||
					if element['platform'] is not None: o = ''.join([o,f'Platform: {element["platform"]}\n'])
 | 
			
		||||
					o = ''.join([o,f'```'])
 | 
			
		||||
					spaces_remaining = element["max_players"] - element["current_players"]
 | 
			
		||||
					o = ''.join([o,f'~~Spaces Remaining: {str(0)}~~'])if spaces_remaining <= 0 else ''.join([o,f'Spaces Remaining: {str(spaces_remaining)}'])
 | 
			
		||||
					me = await ctx.channel.fetch_message(pitches[guildStr][timeslot]['messages'][index])
 | 
			
		||||
					await me.edit(content=o)
 | 
			
		||||
					await ctx.send(f'You have left the game `{lookup[guildStr][str(role.id)]["game_title"]}`.',hidden=True)
 | 
			
		||||
					tc = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['text_channel'],ctx.guild.text_channels)
 | 
			
		||||
					if tc is None:
 | 
			
		||||
						c = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['category'],ctx.guild.categories)
 | 
			
		||||
						if c is not None:
 | 
			
		||||
							tPos = len(ctx.guild.channels)
 | 
			
		||||
							for t in c.text_channels:
 | 
			
		||||
								if t.position <= tPos:
 | 
			
		||||
									tc = t
 | 
			
		||||
									tPos = t.position
 | 
			
		||||
					if tc is not None:
 | 
			
		||||
						await tc.send(f'```{ctx.author.display_name} has left the game.```')
 | 
			
		||||
		yaml_dump(data, dataFile)
 | 
			
		||||
		yaml_dump(pitches, pitchesFile)
 | 
			
		||||
 | 
			
		||||
def setup(client):
 | 
			
		||||
	client.add_cog(PitchListener(client))
 | 
			
		||||
@@ -3,8 +3,9 @@ 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_components import create_select, create_select_option, create_actionrow, wait_for_component, create_button, create_actionrow, create_choice, create_option
 | 
			
		||||
from discord_slash import SlashCommand, SlashContext, cog_ext, utils, ComponentContext			# Slash Command Library
 | 
			
		||||
from discord_slash.utils.manage_components import create_select, create_select_option, create_actionrow, wait_for_component, create_button, create_actionrow
 | 
			
		||||
from discord_slash.utils.manage_commands import create_choice, create_option
 | 
			
		||||
from discord_slash.model import ButtonStyle
 | 
			
		||||
import logging
 | 
			
		||||
# logger and handler
 | 
			
		||||
@@ -16,16 +17,17 @@ class MemberVerification(commands.Cog, name='Member Verification Cog'):
 | 
			
		||||
	def __init__(self, client):
 | 
			
		||||
		self.client = client
 | 
			
		||||
 | 
			
		||||
	@commands.Cog.listener()
 | 
			
		||||
	async def on_message(self, message):
 | 
			
		||||
	@commands.Cog.listener(name='on_message')
 | 
			
		||||
	async def _submission_listener(self, message):
 | 
			
		||||
		conf = yaml_load(configFile)
 | 
			
		||||
		categories = yaml_load(categoriesFile)
 | 
			
		||||
		guildStr = str(message.guild.id)
 | 
			
		||||
		lookup = yaml_load(lookupFile)
 | 
			
		||||
		if conf[guildStr]['channels'].get('signup', None) is not None: return
 | 
			
		||||
		if conf[guildStr]['channels'].get('signup', None) is None: return
 | 
			
		||||
		if message.author.bot: return
 | 
			
		||||
		if message.channel.id != conf[guildStr]['channels']['signup']: return
 | 
			
		||||
		if not message.attachments:
 | 
			
		||||
			await message.author.send(f'```Error: The message you posted in the `{message.channel.name}` channel of the guild `{message.guild.name}` was invalid. Your post must contain a screensot of your proof of purchase for membership.```')
 | 
			
		||||
		if not (message.attachments):
 | 
			
		||||
			await message.channel.send(f'```Error: The message you posted in the `{message.channel.name}` channel of the guild `{message.guild.name}` was invalid. Your post must contain a screensot of your proof of purchase for membership.```')
 | 
			
		||||
			await message.delete()
 | 
			
		||||
			return
 | 
			
		||||
		membership = [discord.utils.get(message.guild.roles, id=x) for x in conf[guildStr]['membership']]
 | 
			
		||||
@@ -35,9 +37,9 @@ class MemberVerification(commands.Cog, name='Member Verification Cog'):
 | 
			
		||||
		admin_buttons.append(create_button(style=ButtonStyle.grey, label='Alert', emoji='⚠️', custom_id=f'alert_{message.id}'))
 | 
			
		||||
		admin_buttons.append(create_button(style=ButtonStyle.red, label='Deny', emoji='✖️', custom_id=f'deny_{message.id}'))
 | 
			
		||||
		admin_buttons.append(create_button(style=ButtonStyle.green, label='Done', emoji='▶️', custom_id=f'done_{message.id}'))
 | 
			
		||||
		o = f'```For Administrators: Please verify the membership request submitted.```\n'
 | 
			
		||||
		o = f'```For Administrators: Please verify the membership request submitted by `{message.author.display_name}`.```'
 | 
			
		||||
		admins = '|'.join([discord.utils.get(message.guild.roles, id=x).mention for x in conf[guildStr]['roles']['admin']])
 | 
			
		||||
		o = '\n'.join((o,admins))
 | 
			
		||||
		o = ''.join((admins,o))
 | 
			
		||||
		m = await message.reply(
 | 
			
		||||
			content= o,
 | 
			
		||||
			components=[
 | 
			
		||||
@@ -55,55 +57,70 @@ class MemberVerification(commands.Cog, name='Member Verification Cog'):
 | 
			
		||||
				)
 | 
			
		||||
			]
 | 
			
		||||
		)
 | 
			
		||||
		while True:
 | 
			
		||||
			interaction_ctx = await wait_for_component(self.client, messages=m)
 | 
			
		||||
			if not (set(interaction_ctx.author.roles) & set([interaction_ctx.guild.get_role(x) for x in conf[str(interaction_ctx.guild.id)]['roles']['admin']]) or interaction_ctx.author == interaction_ctx.guild.owner):
 | 
			
		||||
				await interaction_ctx.send(f'```Error: You are not authorised to assign memberships for guild `{interaction_ctx.guild.name}`. Only administrators may assign memberships using this interface.```', hidden=True)
 | 
			
		||||
			else:
 | 
			
		||||
				submission = await interaction_ctx.channel.fetch_message(int(interaction_ctx.custom_id.split('_',1)[1]))
 | 
			
		||||
				if interaction_ctx.custom_id.startswith('done_'):
 | 
			
		||||
					await interaction_ctx.send(f'```Membership verification complete.```', hidden=True)
 | 
			
		||||
					break
 | 
			
		||||
				elif interaction_ctx.custom_id.startswith('deny_'):
 | 
			
		||||
					await interaction_ctx.send(f'```Membership verification denied.```', hidden=True)
 | 
			
		||||
					embed = discord.Embed(
 | 
			
		||||
						title = submission.author.name,
 | 
			
		||||
						description = f'[Jup to Message]({submission.jump_url})',
 | 
			
		||||
						colour = discord.Colour.red(),
 | 
			
		||||
					)
 | 
			
		||||
					await submission.author.send(f'```Your membership for guild `{submission.guild.name}` could not be verified. Please make sure your name and the kind of membership that you have bought are visible in the screenshot you upload. Please contact a Committee member if you have any difficulties.```')
 | 
			
		||||
					if conf[guildStr]['channels'].get('mod', None) is not None:
 | 
			
		||||
						await submission.guild.get_channel(conf[guildStr]['channels']['mod']).send(f'```Verifying the membership of {submission.author.display_name} failed.```\n{admins}', embed=embed)
 | 
			
		||||
					break
 | 
			
		||||
				elif interaction_ctx.custom_id.startswith('alert_'):
 | 
			
		||||
					await interaction_ctx.send(f'```Membership verification alert raised.```', hidden=True)
 | 
			
		||||
					embed = discord.Embed(
 | 
			
		||||
						title = submission.author.name,
 | 
			
		||||
						description = f'[Jup to Message]({submission.jump_url})',
 | 
			
		||||
						colour = discord.Colour.orange()
 | 
			
		||||
					)
 | 
			
		||||
					await submission.author.send(f'```Your membership for guild `{submission.guild.name}` needs to be reviewed by a Committee member.```')
 | 
			
		||||
					if conf[guildStr]['channels'].get('mod', None) is not None:
 | 
			
		||||
						await submission.guild.get_channel(conf[guildStr]['channels']['mod']).send(f'```There is a problem verifying the membership of {submission.author.display_name}.\nCould someone verify this person\'s membership manually via the EUSA portal?.```\n{admins}', embed=embed)
 | 
			
		||||
				elif interaction_ctx.custom_id.startswith('student_'):
 | 
			
		||||
					await interaction_ctx.send(f'````Student` role granted.```', hidden=True)
 | 
			
		||||
					student_role = submission.guild.get_role(conf[guildStr]['roles']['student'])
 | 
			
		||||
					await submission.author.add_roles(student_role, reason=f'Membership Verification: Student role assigned by `{interaction_ctx.author.display_name}`.')
 | 
			
		||||
					await submission.author.send(f'```You have additionally been assigned the role `Student` in the guild `{submission.guild.name}`.```')
 | 
			
		||||
				elif interaction_ctx.custom_id.startswith('membership_'):
 | 
			
		||||
					[selected_membership] = interaction_ctx.selected_options
 | 
			
		||||
					selected_role = interaction_ctx.guild.get_role(int(selected_membership))
 | 
			
		||||
					if selected_role not in submission.author.roles:
 | 
			
		||||
						await interaction_ctx.send(f'```Membership `{selected_role.name}` added to member `{submission.author.display_name}`.```', hidden=True)
 | 
			
		||||
						await submission.author.add_roles(selected_role, reason=f'Membership Verification: Membership verified by `{interaction_ctx.author.display_name}`.')
 | 
			
		||||
						await submission.author.send(f'```Your membership for guild `{submission.guild.name}` has been verified and you have been assigned the role `{selected_role.name}`.```')
 | 
			
		||||
					else:
 | 
			
		||||
						await interaction_ctx.send(f'```Membership `{selected_role.name}` removed from member `{submission.author.display_name}`.```', hidden=True)
 | 
			
		||||
						await submission.author.remove_roles(selected_role, reason=f'Membership Verification: Membership removed by `{interaction_ctx.author.display_name}`.')
 | 
			
		||||
						await submission.author.send(f'```Your role `{selected_role.name}` has been removed in the guild `{submission.guild.name}`.```')
 | 
			
		||||
		if conf[guildStr]['notifications'].get('signup', False):
 | 
			
		||||
			embed = discord.Embed(
 | 
			
		||||
				title = f'Member Verification Request',
 | 
			
		||||
				description = f'User: {message.author.name}\n\n[Jup to Message]({m.jump_url})',
 | 
			
		||||
				colour = discord.Colour.blue(),
 | 
			
		||||
			)
 | 
			
		||||
		if conf[guildStr]['channels'].get('mod', None) is not None:
 | 
			
		||||
			await message.guild.get_channel(conf[guildStr]['channels']['mod']).send(f'```New membership verification request.```\n{admins}', embed=embed)	
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	@commands.Cog.listener(name='on_component')
 | 
			
		||||
	async def _verification_response(self, ctx:ComponentContext):
 | 
			
		||||
		conf = yaml_load(configFile)
 | 
			
		||||
		categories = yaml_load(categoriesFile)
 | 
			
		||||
		guildStr = str(ctx.guild.id)
 | 
			
		||||
		admins = '|'.join([discord.utils.get(ctx.guild.roles, id=x).mention for x in conf[guildStr]['roles']['admin']])
 | 
			
		||||
		lookup = yaml_load(lookupFile)
 | 
			
		||||
		if ctx.channel.id != conf[guildStr]['channels']['signup']: return
 | 
			
		||||
		if not (set(ctx.author.roles) & set([ctx.guild.get_role(x) for x in conf[str(ctx.guild.id)]['roles']['admin']]) or ctx.author == ctx.guild.owner):
 | 
			
		||||
			await ctx.send(f'```Error: You are not authorised to assign memberships for guild `{ctx.guild.name}`. Only administrators may assign memberships using this interface.```', hidden=True)
 | 
			
		||||
		else:
 | 
			
		||||
			submission = await ctx.channel.fetch_message(int(ctx.custom_id.split('_',1)[1]))
 | 
			
		||||
			if ctx.custom_id.startswith('done_'):
 | 
			
		||||
				await ctx.send(f'```Membership verification complete.```', hidden=True)
 | 
			
		||||
				await ctx.origin_message.delete()
 | 
			
		||||
			elif ctx.custom_id.startswith('deny_'):
 | 
			
		||||
				await ctx.send(f'```Membership verification denied.```', hidden=True)
 | 
			
		||||
				embed = discord.Embed(
 | 
			
		||||
					title = submission.author.name,
 | 
			
		||||
					description = f'[Jup to Message]({submission.jump_url})',
 | 
			
		||||
					colour = discord.Colour.red(),
 | 
			
		||||
				)
 | 
			
		||||
				await submission.channel.send(f'```Your membership for guild `{submission.guild.name}` could not be verified. Please make sure your name and the kind of membership that you have bought are visible in the screenshot you upload. Please contact a Committee member if you have any difficulties.```')
 | 
			
		||||
				if conf[guildStr]['channels'].get('mod', None) is not None:
 | 
			
		||||
					await submission.guild.get_channel(conf[guildStr]['channels']['mod']).send(f'```Verifying the membership of {submission.author.display_name} failed.```\n{admins}', embed=embed)
 | 
			
		||||
				await ctx.origin_message.delete()
 | 
			
		||||
			elif ctx.custom_id.startswith('alert_'):
 | 
			
		||||
				await ctx.send(f'```Membership verification alert raised.```', hidden=True)
 | 
			
		||||
				embed = discord.Embed(
 | 
			
		||||
					title = submission.author.name,
 | 
			
		||||
					description = f'[Jup to Message]({submission.jump_url})',
 | 
			
		||||
					colour = discord.Colour.orange()
 | 
			
		||||
				)
 | 
			
		||||
				await submission.channel.send(f'```Your membership for guild `{submission.guild.name}` needs to be reviewed by a Committee member.```')
 | 
			
		||||
				if conf[guildStr]['channels'].get('mod', None) is not None:
 | 
			
		||||
					await submission.guild.get_channel(conf[guildStr]['channels']['mod']).send(f'```There is a problem verifying the membership of {submission.author.display_name}.\nCould someone verify this person\'s membership manually via the EUSA portal?.```\n{admins}', embed=embed)
 | 
			
		||||
			elif ctx.custom_id.startswith('student_'):
 | 
			
		||||
				await ctx.send(f'````Student` role granted.```', hidden=True)
 | 
			
		||||
				student_role = submission.guild.get_role(conf[guildStr]['roles']['student'])
 | 
			
		||||
				await submission.author.add_roles(student_role, reason=f'Membership Verification: Student role assigned by `{ctx.author.display_name}`.')
 | 
			
		||||
				await submission.channel.send(f'```You have additionally been assigned the role `Student` in the guild `{submission.guild.name}`.```')
 | 
			
		||||
			elif ctx.custom_id.startswith('membership_'):
 | 
			
		||||
				[selected_membership] = ctx.selected_options
 | 
			
		||||
				selected_role = ctx.guild.get_role(int(selected_membership))
 | 
			
		||||
				if selected_role not in submission.author.roles:
 | 
			
		||||
					await ctx.send(f'```Membership `{selected_role.name}` added to member `{submission.author.display_name}`.```', hidden=True)
 | 
			
		||||
					await submission.author.add_roles(selected_role, reason=f'Membership Verification: Membership verified by `{ctx.author.display_name}`.')
 | 
			
		||||
					await submission.channel.send(f'```Your membership for guild `{submission.guild.name}` has been verified and you have been assigned the role `{selected_role.name}`.```')
 | 
			
		||||
				else:
 | 
			
		||||
					pass
 | 
			
		||||
		await m.delete()
 | 
			
		||||
					await ctx.send(f'```Membership `{selected_role.name}` removed from member `{submission.author.display_name}`.```', hidden=True)
 | 
			
		||||
					await submission.author.remove_roles(selected_role, reason=f'Membership Verification: Membership removed by `{ctx.author.display_name}`.')
 | 
			
		||||
					await submission.channel.send(f'```Your role `{selected_role.name}` has been removed in the guild `{submission.guild.name}`.```')
 | 
			
		||||
			else:
 | 
			
		||||
				pass
 | 
			
		||||
 | 
			
		||||
def setup(client):
 | 
			
		||||
	client.add_cog(MemberVerification(client))
 | 
			
		||||
@@ -15,15 +15,15 @@ class RestrictionListener(commands.Cog, name='Membership Restriction Listener'):
 | 
			
		||||
		self.client = client
 | 
			
		||||
	
 | 
			
		||||
	# Block non-verified user from posting messages.
 | 
			
		||||
	@commands.Cog.listener()
 | 
			
		||||
	async def on_message(self,message):
 | 
			
		||||
	@commands.Cog.listener(name='on_message')
 | 
			
		||||
	async def _restriction_listener(self,message):
 | 
			
		||||
		conf = yaml_load(configFile)
 | 
			
		||||
		categories = yaml_load(categoriesFile)
 | 
			
		||||
		guildStr = str(message.guild.id)
 | 
			
		||||
		lookup = yaml_load(lookupFile)
 | 
			
		||||
		if conf[guildStr].get('restrict',False): return
 | 
			
		||||
		if not conf[guildStr].get('restrict',False): return
 | 
			
		||||
		if message.author.bot: return
 | 
			
		||||
		if str(message.channel.category) not in categories[guildStr]: return
 | 
			
		||||
		if str(message.channel.category) in categories[guildStr]: return
 | 
			
		||||
		if (set(message.author.roles) & set([message.guild.get_role(x) for x in conf[guildStr]['roles']['admin']]) or message.author == message.guild.owner): return
 | 
			
		||||
		if set(message.author.roles) & set([message.guild.get_role(x) for x in conf[guildStr]['membership']]): return
 | 
			
		||||
		if message.channel.overwrites_for(message.author).manage_channels: return
 | 
			
		||||
@@ -33,18 +33,21 @@ class RestrictionListener(commands.Cog, name='Membership Restriction Listener'):
 | 
			
		||||
		await message.delete()
 | 
			
		||||
	
 | 
			
		||||
	# Reinstate on verification
 | 
			
		||||
	@commands.Cog.listener()
 | 
			
		||||
	async def on_member_update(self, before, after):
 | 
			
		||||
	@commands.Cog.listener(name='on_member_update')
 | 
			
		||||
	async def _reinstate_listener(self, before, after):
 | 
			
		||||
		if before.roles == after.roles: return
 | 
			
		||||
		if len(set(after.roles) - set(before.roles)) != 1: return
 | 
			
		||||
		[d] = list(set(after.roles) - set(before.roles))
 | 
			
		||||
		conf = yaml_load(configFile)
 | 
			
		||||
		categories = yaml_load(categoriesFile)
 | 
			
		||||
		guildStr = str(after.guild.id)
 | 
			
		||||
		if d.id not in conf[guildStr]['membership']: return
 | 
			
		||||
		lookup = yaml_load(lookupFile)
 | 
			
		||||
		if not set(after.author.roles) & set([after.guild.get_role(x) for x in conf[guildStr]['membership']]): return
 | 
			
		||||
		for game in list(set(after.author.roles) & set([after.guild.get_role(int(x)) for x in lookup[guildStr]])):
 | 
			
		||||
			c = discord.utils.get(lambda x: x.id == lookup[guildStr][str(game.id)]['category'])
 | 
			
		||||
		if not set(after.roles) & set([after.guild.get_role(x) for x in conf[guildStr]['membership']]): return
 | 
			
		||||
		for game in list(set(after.roles) & set([after.guild.get_role(int(x)) for x in lookup[guildStr]])):
 | 
			
		||||
			c = discord.utils.get(after.guild.categories, id=lookup[guildStr][str(game.id)]['category'])
 | 
			
		||||
			if c is not None:
 | 
			
		||||
				if c.overwrites_for(after).send_messages is False: await c.set_permissions(after, overwrite = False, reason= f'Membership Restriction: {after.display_name} has been verified and reinstated.')
 | 
			
		||||
				if c.overwrites_for(after).send_messages is False: await c.set_permissions(after, overwrite = None, reason= f'Membership Restriction: {after.display_name} has been verified and reinstated.')
 | 
			
		||||
 | 
			
		||||
def setup(client):
 | 
			
		||||
	client.add_cog(RestrictionListener(client))
 | 
			
		||||
@@ -9,7 +9,7 @@ from discord_slash.model import SlashCommandPermissionType, ButtonStyle
 | 
			
		||||
from discord_slash.client import SlashCommand
 | 
			
		||||
from discord_slash.utils.manage_components import create_select, create_select_option, create_actionrow, wait_for_component, create_button, create_actionrow
 | 
			
		||||
 | 
			
		||||
from bot import configFile, yaml_load, yaml_dump, cogsDir, unloadCog, dataFile, lookupFile, gmFile, categoriesFile
 | 
			
		||||
from bot import configFile, yaml_load, yaml_dump, cogsDir, unloadCog, dataFile, lookupFile, gmFile, categoriesFile, pitchesFile, loadCog
 | 
			
		||||
 | 
			
		||||
#### Pitch Command
 | 
			
		||||
 | 
			
		||||
@@ -42,8 +42,12 @@ class Pitch(commands.Cog, name='Pitch Command'):
 | 
			
		||||
		lookup = yaml_load(lookupFile)
 | 
			
		||||
		gms = yaml_load(gmFile)
 | 
			
		||||
		categories = yaml_load(categoriesFile)
 | 
			
		||||
		pitches = {}
 | 
			
		||||
		guildStr = str(ctx.guild.id)
 | 
			
		||||
		pitches = yaml_load(pitchesFile)
 | 
			
		||||
		if guildStr not in pitches: pitches[guildStr] = {}
 | 
			
		||||
		if pitches[guildStr]:
 | 
			
		||||
			await ctx.send(f'```Error: pitches are already running for the guild `{ctx.guild.name}`. Please close the existing pitches first before issuing this command.```')
 | 
			
		||||
			return
 | 
			
		||||
		if 'timeslots' not in conf[guildStr]: conf[guildStr]['timeslots'] = {}
 | 
			
		||||
		tsDict = {k: conf[guildStr]['timeslots'][k] for k in data[guildStr] if data[guildStr][k]}
 | 
			
		||||
		optionsList = [create_select_option(label=tsDict[x], value=x, description=x) for x in tsDict]
 | 
			
		||||
@@ -83,7 +87,6 @@ class Pitch(commands.Cog, name='Pitch Command'):
 | 
			
		||||
				ctx.guild.default_role: p
 | 
			
		||||
			}
 | 
			
		||||
		)
 | 
			
		||||
		if guildStr not in pitches: pitches[guildStr] = {}
 | 
			
		||||
		if timeslot not in pitches[guildStr]: pitches[guildStr][timeslot] = {}
 | 
			
		||||
		pitches[guildStr][timeslot]['indices'] = {}
 | 
			
		||||
		pitches[guildStr][timeslot]['entries'] = [x for x in data[guildStr][timeslot].values()]
 | 
			
		||||
@@ -91,6 +94,7 @@ class Pitch(commands.Cog, name='Pitch Command'):
 | 
			
		||||
		header_message = await ctx.channel.send(
 | 
			
		||||
			content=f'**Game listing for {conf[guildStr]["timeslots"][timeslot]}**\n_ _```The following are the games that are being pitched. Please select which game you would like to join by clicking on the `Join` button below.```'
 | 
			
		||||
		)
 | 
			
		||||
		pitches[guildStr][timeslot]['header_message'] = header_message.id
 | 
			
		||||
		pitches[guildStr][timeslot]['messages'] = []
 | 
			
		||||
		pitches[guildStr][timeslot]['roles'] = {}
 | 
			
		||||
		for index, element in enumerate(pitches[guildStr][timeslot]['entries']):
 | 
			
		||||
@@ -122,9 +126,9 @@ class Pitch(commands.Cog, name='Pitch Command'):
 | 
			
		||||
					)
 | 
			
		||||
				]
 | 
			
		||||
			)
 | 
			
		||||
			pitches[guildStr][timeslot]['messages'].append(m)
 | 
			
		||||
			pitches[guildStr][timeslot]['messages'].append(m.id)
 | 
			
		||||
			r = discord.utils.find(lambda x: x.id == element['role'],ctx.guild.roles)
 | 
			
		||||
			pitches[guildStr][timeslot]['roles'][index] = r
 | 
			
		||||
			pitches[guildStr][timeslot]['roles'][index] = r.id
 | 
			
		||||
			pitches[guildStr][timeslot]['indices'][r.id] = index
 | 
			
		||||
		newcomer = returning_player = None
 | 
			
		||||
		if 'newcomer' in conf[guildStr]['roles']: newcomer = discord.utils.find(lambda x: x.id == conf[guildStr]['roles']['newcomer'], ctx.guild.roles)
 | 
			
		||||
@@ -172,123 +176,11 @@ class Pitch(commands.Cog, name='Pitch Command'):
 | 
			
		||||
				)
 | 
			
		||||
			]
 | 
			
		||||
		)
 | 
			
		||||
		while True:
 | 
			
		||||
			button_ctx = await wait_for_component(
 | 
			
		||||
				self.client,
 | 
			
		||||
				messages=pitches[guildStr][timeslot]['messages'] + [control]
 | 
			
		||||
			)
 | 
			
		||||
			if button_ctx.origin_message.id == control.id:
 | 
			
		||||
				if not (set(ctx.author.roles) & set([ctx.guild.get_role(x) for x in conf[str(ctx.guild.id)]['roles']['admin']]) or ctx.author == ctx.guild.owner):
 | 
			
		||||
					await button_ctx.send(f'```Error: You are not authorised to do this. The control panel may only be issued by an administrator.```',hidden=True)
 | 
			
		||||
				else:
 | 
			
		||||
					if button_ctx.custom_id == 'allow_returning':
 | 
			
		||||
						await ctx.channel.set_permissions(reason=f'/pitch command issued by {ctx.author.display_name}', target=returning_player, read_messages=True)
 | 
			
		||||
						await button_ctx.send(f'```Returning Players have now been allowed access to the pitch menu.```',  hidden=True)
 | 
			
		||||
					if button_ctx.custom_id == 'allow_newcomers':
 | 
			
		||||
						await ctx.channel.set_permissions(reason=f'/pitch command issued by {ctx.author.display_name}', target=newcomer, read_messages=True)
 | 
			
		||||
						await button_ctx.send(f'```Newcomers have now been allowed access to the pitch menu.```',  hidden=True)
 | 
			
		||||
					if button_ctx.custom_id == 'allow_all':
 | 
			
		||||
						await ctx.channel.set_permissions(reason=f'/pitch command issued by {ctx.author.display_name}', target=ctx.guild.default_role, read_messages= True, send_messages=False)
 | 
			
		||||
						await button_ctx.send(f'```All members have now been allowed access to the pitch menu.```', hidden=True)
 | 
			
		||||
					if button_ctx.custom_id == 'close_pitches': break
 | 
			
		||||
			else:
 | 
			
		||||
				index = int(button_ctx.custom_id.split('_',1)[1])
 | 
			
		||||
				if button_ctx.custom_id.startswith('join_'):
 | 
			
		||||
					if set(button_ctx.author.roles) & set(pitches[guildStr][timeslot]['roles'].values()):
 | 
			
		||||
						print('Check 0')
 | 
			
		||||
						for role in list(set(button_ctx.author.roles) & set(pitches[guildStr][timeslot]['roles'].values())):
 | 
			
		||||
							if role != pitches[guildStr][timeslot]['roles'][index]:
 | 
			
		||||
								print('check 1')
 | 
			
		||||
								await button_ctx.author.remove_roles(role,reason=f'/pitch interaction by {button_ctx.author.display_name}')
 | 
			
		||||
								data[guildStr][timeslot][str(role.id)]['current_players'] -= 1
 | 
			
		||||
								i = pitches[guildStr][timeslot]['indices'][role.id]
 | 
			
		||||
								element = pitches[guildStr][timeslot]['entries'][i]
 | 
			
		||||
								gm = await self.client.fetch_user(element['gm'])
 | 
			
		||||
								o = f'_ _\n***{element["game_title"]}*** (GM: {gm.mention})\n```\n'
 | 
			
		||||
								if element['system'] is not None: o = ''.join([o,f'System: {element["system"]}\n'])
 | 
			
		||||
								if element['min_players'] is not None: o = ''.join([o,f'Minimum Players: {str(element["min_players"])}	'])
 | 
			
		||||
								if element['max_players'] is not None: o = ''.join([o,f'Maximum Players: {str(element["max_players"])}\n'])
 | 
			
		||||
								if element['platform'] is not None: o = ''.join([o,f'Platform: {element["platform"]}\n'])
 | 
			
		||||
								o = ''.join([o,f'```'])
 | 
			
		||||
								spaces_remaining = element["max_players"] - element["current_players"]
 | 
			
		||||
								o = ''.join([o,f'~~Spaces Remaining: {str(0)}~~'])if spaces_remaining <= 0 else ''.join([o,f'Spaces Remaining: {str(spaces_remaining)}'])
 | 
			
		||||
								await pitches[guildStr][timeslot]['messages'][i].edit(content=o)
 | 
			
		||||
								tc = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['text_channel'],ctx.guild.text_channels)
 | 
			
		||||
								if tc is None:
 | 
			
		||||
									c = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['category'],ctx.guild.categories)
 | 
			
		||||
									if c is not None:
 | 
			
		||||
										tPos = len(ctx.guild.channels)
 | 
			
		||||
										for t in c.text_channels:
 | 
			
		||||
											if t.position <= tPos:
 | 
			
		||||
												tc = t
 | 
			
		||||
												tPos = t.position
 | 
			
		||||
								if tc is not None:
 | 
			
		||||
									await tc.send(f'```{button_ctx.author.display_name} has left the game.```')
 | 
			
		||||
					role = pitches[guildStr][timeslot]['roles'][index]
 | 
			
		||||
					if role in button_ctx.author.roles:
 | 
			
		||||
						await button_ctx.send(f'```Error: You are already in the game `{lookup[guildStr][str(role.id)]["game_title"]}`.```', hidden=True)
 | 
			
		||||
					else:
 | 
			
		||||
						await button_ctx.author.add_roles(role,reason=f'/pitch interaction by {button_ctx.author.display_name}')
 | 
			
		||||
						data[guildStr][timeslot][str(role.id)]['current_players'] += 1
 | 
			
		||||
						element = pitches[guildStr][timeslot]['entries'][index]
 | 
			
		||||
						gm = await self.client.fetch_user(element['gm'])
 | 
			
		||||
						o = f'_ _\n***{element["game_title"]}*** (GM: {gm.mention})\n```\n'
 | 
			
		||||
						if element['system'] is not None: o = ''.join([o,f'System: {element["system"]}\n'])
 | 
			
		||||
						if element['min_players'] is not None: o = ''.join([o,f'Minimum Players: {str(element["min_players"])}	'])
 | 
			
		||||
						if element['max_players'] is not None: o = ''.join([o,f'Maximum Players: {str(element["max_players"])}\n'])
 | 
			
		||||
						if element['platform'] is not None: o = ''.join([o,f'Platform: {element["platform"]}\n'])
 | 
			
		||||
						o = ''.join([o,f'```'])
 | 
			
		||||
						spaces_remaining = element["max_players"] - element["current_players"]
 | 
			
		||||
						o = ''.join([o,f'~~Spaces Remaining: {str(0)}~~'])if spaces_remaining <= 0 else ''.join([o,f'Spaces Remaining: {str(spaces_remaining)}'])
 | 
			
		||||
						await pitches[guildStr][timeslot]['messages'][index].edit(content=o)
 | 
			
		||||
						await button_ctx.send(f'You have joined the game `{lookup[guildStr][str(role.id)]["game_title"]}`.',hidden=True)
 | 
			
		||||
						tc = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['text_channel'],ctx.guild.text_channels)
 | 
			
		||||
						if tc is None:
 | 
			
		||||
							c = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['category'],ctx.guild.categories)
 | 
			
		||||
							if c is not None:
 | 
			
		||||
								tPos = len(ctx.guild.channels)
 | 
			
		||||
								for t in c.text_channels:
 | 
			
		||||
									if t.position <= tPos:
 | 
			
		||||
										tc = t
 | 
			
		||||
										tPos = t.position
 | 
			
		||||
						if tc is not None:
 | 
			
		||||
							await tc.send(f'```{button_ctx.author.display_name} has joined the game.```')
 | 
			
		||||
				elif button_ctx.custom_id.startswith('leave_'):
 | 
			
		||||
					role = pitches[guildStr][timeslot]['roles'][index]
 | 
			
		||||
					if role not in button_ctx.author.roles:
 | 
			
		||||
						await button_ctx.send(f'```Error: You are not in the game `{lookup[guildStr][str(role.id)]["game_title"]}`.```', hidden=True)
 | 
			
		||||
					else:
 | 
			
		||||
						await button_ctx.author.remove_roles(role,reason=f'/pitch interaction by {button_ctx.author.display_name}')
 | 
			
		||||
						data[guildStr][timeslot][str(role.id)]['current_players'] -= 1
 | 
			
		||||
						element = pitches[guildStr][timeslot]['entries'][index]
 | 
			
		||||
						gm = await self.client.fetch_user(element['gm'])
 | 
			
		||||
						o = f'_ _\n***{element["game_title"]}*** (GM: {gm.mention})\n```\n'
 | 
			
		||||
						if element['system'] is not None: o = ''.join([o,f'System: {element["system"]}\n'])
 | 
			
		||||
						if element['min_players'] is not None: o = ''.join([o,f'Minimum Players: {str(element["min_players"])}	'])
 | 
			
		||||
						if element['max_players'] is not None: o = ''.join([o,f'Maximum Players: {str(element["max_players"])}\n'])
 | 
			
		||||
						if element['platform'] is not None: o = ''.join([o,f'Platform: {element["platform"]}\n'])
 | 
			
		||||
						o = ''.join([o,f'```'])
 | 
			
		||||
						spaces_remaining = element["max_players"] - element["current_players"]
 | 
			
		||||
						o = ''.join([o,f'~~Spaces Remaining: {str(0)}~~'])if spaces_remaining <= 0 else ''.join([o,f'Spaces Remaining: {str(spaces_remaining)}'])
 | 
			
		||||
						await pitches[guildStr][timeslot]['messages'][index].edit(content=o)
 | 
			
		||||
						await button_ctx.send(f'You have left the game `{lookup[guildStr][str(role.id)]["game_title"]}`.',hidden=True)
 | 
			
		||||
						tc = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['text_channel'],ctx.guild.text_channels)
 | 
			
		||||
						if tc is None:
 | 
			
		||||
							c = discord.utils.find(lambda x: x.id == lookup[guildStr][str(role.id)]['category'],ctx.guild.categories)
 | 
			
		||||
							if c is not None:
 | 
			
		||||
								tPos = len(ctx.guild.channels)
 | 
			
		||||
								for t in c.text_channels:
 | 
			
		||||
									if t.position <= tPos:
 | 
			
		||||
										tc = t
 | 
			
		||||
										tPos = t.position
 | 
			
		||||
						if tc is not None:
 | 
			
		||||
							await tc.send(f'```{button_ctx.author.display_name} has left the game.```')
 | 
			
		||||
			yaml_dump(data, dataFile)
 | 
			
		||||
		await header_message.delete()
 | 
			
		||||
		for message in pitches[guildStr][timeslot]['messages']: await message.delete()
 | 
			
		||||
		await control.delete()
 | 
			
		||||
		await ctx.channel.edit(reason=f'/pitch command issued by {ctx.author.display_name}', overwrites={})
 | 
			
		||||
		await button_ctx.channel.send('```Pitch menu cleared. Pitches have now concluded.```')
 | 
			
		||||
		pitches[guildStr][timeslot]['control'] = control.id
 | 
			
		||||
		yaml_dump(pitches,pitchesFile)
 | 
			
		||||
		if self.client.get_cog('Pitch Listener') is None:
 | 
			
		||||
				loadCog(f'./{cogsDir}/events/secondary/pitch_listener.py')
 | 
			
		||||
				#### Activate global pitch listener
 | 
			
		||||
 | 
			
		||||
def setup(client):
 | 
			
		||||
	client.add_cog(Pitch(client))
 | 
			
		||||
		Reference in New Issue
	
	Block a user