2021-07-23 00:44:21 +01:00
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 , 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
2021-07-24 17:58:23 +01:00
from bot import configFile , yaml_load , yaml_dump , cogsDir , unloadCog , dataFile , lookupFile , gmFile , categoriesFile , pitchesFile , loadCog
2021-07-23 00:44:21 +01:00
#### Pitch Command
class Pitch ( commands . Cog , name = ' Pitch Command ' ) :
def __init__ ( self , client ) :
self . client = client
conf = yaml_load ( configFile )
permissions = { }
guild_ids = list ( set . intersection ( set ( [ int ( guildKey ) for guildKey in yaml_load ( configFile ) if yaml_load ( configFile ) [ guildKey ] [ ' timeslots ' ] ] ) , set ( [ int ( guildKey ) for guildKey in yaml_load ( configFile ) if ' bot ' in yaml_load ( configFile ) [ guildKey ] [ ' roles ' ] and 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_slash (
name = ' pitch ' ,
2021-07-27 11:51:02 +01:00
description = ' Initialises the menu for game pitches. ' ,
2021-07-23 00:44:21 +01:00
default_permission = False ,
permissions = permissions ,
guild_ids = guild_ids ,
)
async def _pitch ( self , ctx : SlashContext ) :
await ctx . channel . trigger_typing ( )
conf = yaml_load ( configFile )
data = yaml_load ( dataFile )
lookup = yaml_load ( lookupFile )
gms = yaml_load ( gmFile )
categories = yaml_load ( categoriesFile )
guildStr = str ( ctx . guild . id )
2021-07-24 17:58:23 +01:00
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
2021-07-23 00:44:21 +01:00
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 ]
try :
m = await ctx . send (
content = ' ```Select which time slot for which you would like to run pitches for.``` ' ,
delete_after = 5 ,
components = [
create_actionrow (
create_select (
placeholder = ' Time Slot ' ,
options = optionsList ,
min_values = 1 ,
max_values = 1
)
)
]
)
while True :
select_ctx = await wait_for_component ( self . client , messages = m , timeout = 5 )
if select_ctx . author != ctx . author :
await select_ctx . send ( f ' ```Invalid response: you are not the person who issued the command.``` ' , hidden = True )
else :
break
await m . delete ( )
[ timeslot ] = select_ctx . selected_options
except asyncio . TimeoutError :
await ctx . send ( f ' ```Error: Command timed out.``` ' , hidden = True )
return
await ctx . channel . trigger_typing ( )
p = discord . PermissionOverwrite ( )
p . read_messages = False
p . send_messages = False
await ctx . channel . edit (
reason = f ' /pitch command issued by { ctx . author . display_name } ' ,
overwrites = {
ctx . guild . default_role : p
}
)
if timeslot not in pitches [ guildStr ] : pitches [ guildStr ] [ timeslot ] = { }
2021-07-24 13:15:01 +01:00
pitches [ guildStr ] [ timeslot ] [ ' indices ' ] = { }
2021-07-23 00:44:21 +01:00
pitches [ guildStr ] [ timeslot ] [ ' entries ' ] = [ x for x in data [ guildStr ] [ timeslot ] . values ( ) ]
pitches [ guildStr ] [ timeslot ] [ ' entries ' ] . sort ( key = lambda x : x [ ' game_title ' ] )
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.``` '
)
2021-07-24 17:58:23 +01:00
pitches [ guildStr ] [ timeslot ] [ ' header_message ' ] = header_message . id
2021-07-23 00:44:21 +01:00
pitches [ guildStr ] [ timeslot ] [ ' messages ' ] = [ ]
pitches [ guildStr ] [ timeslot ] [ ' roles ' ] = { }
for index , element in enumerate ( pitches [ guildStr ] [ timeslot ] [ ' entries ' ] ) :
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 . send (
content = o ,
components = [
create_actionrow (
create_button (
style = ButtonStyle . green ,
label = ' Join ' ,
emoji = ' 🉑 ' ,
custom_id = f ' join_ { index } '
) ,
create_button (
style = ButtonStyle . red ,
label = ' Leave ' ,
emoji = ' 🈳 ' ,
custom_id = f ' leave_ { index } '
)
)
]
)
2021-07-24 17:58:23 +01:00
pitches [ guildStr ] [ timeslot ] [ ' messages ' ] . append ( m . id )
2021-07-24 13:15:01 +01:00
r = discord . utils . find ( lambda x : x . id == element [ ' role ' ] , ctx . guild . roles )
2021-07-24 17:58:23 +01:00
pitches [ guildStr ] [ timeslot ] [ ' roles ' ] [ index ] = r . id
2021-07-24 13:15:01 +01:00
pitches [ guildStr ] [ timeslot ] [ ' indices ' ] [ r . id ] = index
2021-07-23 00:44:21 +01:00
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 )
buttons = [ ]
if returning_player is not None :
buttons . append (
create_button (
style = ButtonStyle . grey ,
label = ' Allow Returning Players ' ,
emoji = ' 🔁 ' ,
custom_id = ' allow_returning '
)
)
if newcomer is not None :
buttons . append (
create_button (
style = ButtonStyle . grey ,
label = ' Allow Newcomers ' ,
emoji = ' 🆕 ' ,
custom_id = ' allow_newcomers '
)
)
buttons . append (
create_button (
style = ButtonStyle . green ,
label = ' Allow All ' ,
emoji = ' 🚪 ' ,
custom_id = ' allow_all '
)
)
buttons . append (
create_button (
style = ButtonStyle . red ,
label = ' Close Pitches ' ,
emoji = ' 🔒 ' ,
custom_id = ' close_pitches '
)
)
control = await ctx . channel . send (
content = ' _ _ \n ```Control Panel: \n For Admin Use Only``` ' ,
components = [
create_actionrow (
* buttons
)
]
)
2021-07-24 17:58:23 +01:00
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
2021-07-23 00:44:21 +01:00
def setup ( client ) :
client . add_cog ( Pitch ( client ) )