2021-07-21 11:49:29 +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
from bot import configFile , yaml_load , yaml_dump , lookupFile , dataFile , gmFile , categoriesFile
2021-07-23 00:44:21 +01:00
##### Player Add, Remove, and Leave Commands
2021-07-21 11:49:29 +01:00
class PlayerCommands ( commands . Cog , name = ' Player Commands ' ) :
def __init__ ( self , client ) :
self . client = client
conf = yaml_load ( configFile )
lookup = yaml_load ( lookupFile )
data = yaml_load ( dataFile )
gms = yaml_load ( gmFile )
categories = yaml_load ( categoriesFile )
guild_ids = [ int ( x ) for x in list ( lookup ) ]
@cog_ext.cog_subcommand (
base = ' player ' ,
name = ' add ' ,
description = ' Add a player to a game. ' ,
base_description = ' Commands to manage players in a game. ' ,
base_default_permission = True ,
guild_ids = guild_ids ,
options = [
create_option (
name = ' player ' ,
description = ' The player you want to add to the game. ' ,
option_type = 6 ,
required = True
) ,
create_option (
name = ' game ' ,
description = ' The role of the game you want to add the player to. ' ,
option_type = 8 ,
required = True
)
]
)
async def _player_add (
self ,
ctx : SlashContext ,
player : discord . User ,
game : discord . Role
) :
await ctx . channel . trigger_typing ( )
conf = yaml_load ( configFile )
lookup = yaml_load ( lookupFile )
data = yaml_load ( dataFile )
gms = yaml_load ( gmFile )
guildStr = str ( ctx . guild . id )
rStr = str ( game . id )
if rStr not in lookup [ guildStr ] :
await ctx . send ( f ' ```Error: This is not a valid game role. Please mention a role that is associated with a game.``` ' , hidden = True )
return
2021-07-21 23:05:13 +01:00
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 ) :
if not set ( ctx . author . roles ) & set ( [ ctx . guild . get_role ( int ( x ) ) for x in gms [ str ( ctx . guild . id ) ] if gms [ str ( ctx . guild . id ) ] [ x ] ] ) :
2021-07-21 11:49:29 +01:00
await ctx . send ( f ' ```Error: You are not authorised to issue this command. The command may only be issued by an administrator or by a GM.``` ' , hidden = True )
return
if ctx . author . id != lookup [ guildStr ] [ rStr ] [ ' gm ' ] :
await ctx . send ( f ' ```Error: You are not authorised to issue this command. A player may only be added to a game by the GM or by an administrator.``` ' , hidden = True )
return
if game in player . roles :
await ctx . send ( f ' ```Error: Player ` { player . display_name } ` is already in the game { lookup [ guildStr ] [ rStr ] [ " game_title " ] } .``` ' , hidden = True )
return
await player . add_roles ( game , reason = f ' `/player add` command issued by { ctx . author . display_name } `. ' )
2021-07-21 23:05:13 +01:00
t = lookup [ guildStr ] [ rStr ] [ ' time ' ]
2021-07-21 11:49:29 +01:00
if type ( data [ guildStr ] [ t ] [ rStr ] [ ' current_players ' ] ) is not int : data [ guildStr ] [ t ] [ rStr ] [ ' current_players ' ] = 1
else : data [ guildStr ] [ t ] [ rStr ] [ ' current_players ' ] + = 1
2021-07-21 23:05:13 +01:00
hm = data [ guildStr ] [ t ] [ rStr ] [ ' header_message ' ]
tc = discord . utils . find ( lambda x : x . id == lookup [ guildStr ] [ rStr ] [ ' text_channel ' ] , ctx . guild . channels )
2021-07-21 11:49:29 +01:00
if tc is not None :
p = await tc . pins ( )
if p :
header = discord . utils . find ( lambda x : x . id == hm , p )
if header is not None :
text = header . content . split ( ' \n ' )
2021-07-23 00:44:21 +01:00
for line , item in enumerate ( text ) :
if ' Current Players: ' in item :
text [ line ] = f ' Current Players: { str ( data [ guildStr ] [ t ] [ rStr ] [ " current_players " ] ) } '
2021-07-21 11:49:29 +01:00
break
await header . edit ( content = ' \n ' . join ( text ) )
else :
tPos = len ( ctx . guild . channels )
cat = discord . utils . find ( lambda x : x . id == lookup [ guildStr ] [ rStr ] [ ' category ' ] , ctx . guild . categories )
if cat is not None :
for t in cat . text_channels :
if t . position < = tPos :
tc = t
tPos = t . position
await tc . send ( f ' ```Player { player . display_name } has been added to the game by ` { ctx . author . display_name } `.``` \n { player . mention } | { game . mention } ' )
if ' mod ' in conf [ guildStr ] [ ' channels ' ] and ' committee ' in conf [ guildStr ] [ ' roles ' ] :
c = discord . utils . find ( lambda x : x . id == conf [ guildStr ] [ ' channels ' ] [ ' mod ' ] , ctx . guild . channels )
r = discord . utils . find ( lambda x : x . id == conf [ guildStr ] [ ' roles ' ] [ ' committee ' ] , ctx . guild . roles )
await c . send ( f ' ```Player ` { player . display_name } ` has been added to the game ` { lookup [ guildStr ] [ rStr ] [ " game_title " ] } ` by ` { ctx . author . display_name } ` via the `/player add` command.``` ' )
yaml_dump ( data , dataFile )
await ctx . send ( content = f ' ```Player ` { player . display_name } ` has been added to the game ` { lookup [ guildStr ] [ rStr ] [ " game_title " ] } `.``` ' , hidden = True )
@cog_ext.cog_subcommand (
base = ' player ' ,
name = ' remove ' ,
description = ' Remove a player from a game. ' ,
# base_description='Commands to manage players in a game.',
base_default_permission = True ,
guild_ids = guild_ids ,
options = [
create_option (
name = ' player ' ,
description = ' The player you want to remove from the game. ' ,
option_type = 6 ,
required = True
)
]
)
async def _player_remove (
self ,
ctx : SlashContext ,
player : discord . User
) :
await ctx . channel . trigger_typing ( )
conf = yaml_load ( configFile )
lookup = yaml_load ( lookupFile )
data = yaml_load ( dataFile )
gms = yaml_load ( gmFile )
categories = yaml_load ( categoriesFile )
guildStr = str ( ctx . guild . id )
if str ( ctx . channel . category . id ) not in categories [ guildStr ] :
await ctx . send ( f ' ```Error: This command can only be issued in a text channel associated with a game.``` ' , hidden = True )
return
2021-07-21 23:05:13 +01:00
game = discord . utils . find ( lambda x : x . id == categories [ guildStr ] [ str ( ctx . channel . category . id ) ] , ctx . guild . roles )
2021-07-21 11:49:29 +01:00
rStr = str ( game . id )
2021-07-21 23:05:13 +01:00
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 ) :
if not set ( ctx . author . roles ) & set ( [ ctx . guild . get_role ( int ( x ) ) for x in gms [ str ( ctx . guild . id ) ] if gms [ str ( ctx . guild . id ) ] [ x ] ] ) :
2021-07-21 11:49:29 +01:00
await ctx . send ( f ' ```Error: You are not authorised to issue this command. The command may only be issued by an administrator or by a GM.``` ' , hidden = True )
return
if ctx . author . id != lookup [ guildStr ] [ rStr ] [ ' gm ' ] :
await ctx . send ( f ' ```Error: You are not authorised to issue this command. A player may only be added to a game by the GM or by an administrator.``` ' , hidden = True )
return
2021-07-23 00:44:21 +01:00
if game not in player . roles :
await ctx . send ( f ' ```Error: Player ` { player . display_name } ` is not in the game { lookup [ guildStr ] [ rStr ] [ " game_title " ] } .``` ' , hidden = True )
return
2021-07-21 11:49:29 +01:00
await player . remove_roles ( game , reason = f ' `/player remove` command issued by { ctx . author . display_name } `. ' )
2021-07-21 23:05:13 +01:00
t = lookup [ guildStr ] [ rStr ] [ ' time ' ]
if data [ guildStr ] [ t ] [ rStr ] [ ' current_players ' ] < = 1 : data [ guildStr ] [ t ] [ rStr ] [ ' current_players ' ] = None
2021-07-21 11:49:29 +01:00
else : data [ guildStr ] [ t ] [ rStr ] [ ' current_players ' ] - = 1
2021-07-21 23:05:13 +01:00
hm = data [ guildStr ] [ t ] [ rStr ] [ ' header_message ' ]
tc = discord . utils . find ( lambda x : x . id == lookup [ guildStr ] [ rStr ] [ ' text_channel ' ] , ctx . guild . channels )
2021-07-21 11:49:29 +01:00
if tc is not None :
p = await tc . pins ( )
if p :
header = discord . utils . find ( lambda x : x . id == hm , p )
if header is not None :
text = header . content . split ( ' \n ' )
2021-07-23 00:44:21 +01:00
for line , item in enumerate ( text ) :
if ' Current Players: ' in item :
text [ line ] = f ' Current Players: { str ( data [ guildStr ] [ t ] [ rStr ] [ " current_players " ] ) if data [ guildStr ] [ t ] [ rStr ] [ " current_players " ] is not None else str ( 0 ) } '
2021-07-21 11:49:29 +01:00
break
await header . edit ( content = ' \n ' . join ( text ) )
else :
tPos = len ( ctx . guild . channels )
cat = ctx . channel . category
for t in cat . text_channels :
if t . position < = tPos :
tc = t
tPos = t . position
await tc . send ( f ' ```Player { player . display_name } has been removed from the game by ` { ctx . author . display_name } `.``` \n { game . mention } ' )
if ' mod ' in conf [ guildStr ] [ ' channels ' ] and ' committee ' in conf [ guildStr ] [ ' roles ' ] :
c = discord . utils . find ( lambda x : x . id == conf [ guildStr ] [ ' channels ' ] [ ' mod ' ] , ctx . guild . channels )
r = discord . utils . find ( lambda x : x . id == conf [ guildStr ] [ ' roles ' ] [ ' committee ' ] , ctx . guild . roles )
await c . send ( f ' ```Player ` { player . display_name } ` has been removed from the game ` { lookup [ guildStr ] [ rStr ] [ " game_title " ] } ` by ` { ctx . author . display_name } ` via the `/player remove` command.``` ' )
yaml_dump ( data , dataFile )
await ctx . send ( content = f ' ```Player ` { player . display_name } ` has been removed from the game ` { lookup [ guildStr ] [ rStr ] [ " game_title " ] } `.``` ' , hidden = True )
@cog_ext.cog_subcommand (
base = ' player ' ,
name = ' leave ' ,
description = ' Leave a game. ' ,
# base_description='Commands to manage players in a game.',
base_default_permission = True ,
guild_ids = guild_ids
)
async def _player_leave (
self ,
ctx : SlashContext
) :
await ctx . channel . trigger_typing ( )
conf = yaml_load ( configFile )
lookup = yaml_load ( lookupFile )
data = yaml_load ( dataFile )
gms = yaml_load ( gmFile )
categories = yaml_load ( categoriesFile )
guildStr = str ( ctx . guild . id )
player = ctx . author
if str ( ctx . channel . category . id ) not in categories [ guildStr ] :
2021-07-23 00:44:21 +01:00
await ctx . send ( f ' ```Error: This command can only be issued in a text channel associated with the game you are trying to leave.``` ' , hidden = True )
2021-07-21 11:49:29 +01:00
return
2021-07-23 00:44:21 +01:00
game = discord . utils . find ( lambda x : x . id == categories [ guildStr ] [ str ( ctx . channel . category . id ) ] , ctx . guild . roles )
2021-07-21 11:49:29 +01:00
rStr = str ( game . id )
if game not in player . roles :
2021-07-23 00:44:21 +01:00
await ctx . send ( f ' ```Error: You are not in the game { lookup [ guildStr ] [ rStr ] [ " game_title " ] } .``` ' , hidden = True )
2021-07-21 11:49:29 +01:00
return
await player . remove_roles ( game , reason = f ' `/player leave` command issued by { ctx . author . display_name } `. ' )
2021-07-21 23:05:13 +01:00
t = lookup [ guildStr ] [ rStr ] [ ' time ' ]
if data [ guildStr ] [ t ] [ rStr ] [ ' current_players ' ] < = 1 : data [ guildStr ] [ t ] [ rStr ] [ ' current_players ' ] = None
2021-07-21 11:49:29 +01:00
else : data [ guildStr ] [ t ] [ rStr ] [ ' current_players ' ] - = 1
2021-07-21 23:05:13 +01:00
hm = data [ guildStr ] [ t ] [ rStr ] [ ' header_message ' ]
tc = discord . utils . find ( lambda x : x . id == lookup [ guildStr ] [ rStr ] [ ' text_channel ' ] , ctx . guild . channels )
2021-07-21 11:49:29 +01:00
if tc is not None :
p = await tc . pins ( )
if p :
header = discord . utils . find ( lambda x : x . id == hm , p )
if header is not None :
text = header . content . split ( ' \n ' )
2021-07-23 00:44:21 +01:00
for line , item in enumerate ( text ) :
if ' Current Players: ' in item :
text [ line ] = f ' Current Players: { str ( data [ guildStr ] [ t ] [ rStr ] [ " current_players " ] ) if data [ guildStr ] [ t ] [ rStr ] [ " current_players " ] is not None else str ( 0 ) } '
2021-07-21 11:49:29 +01:00
break
await header . edit ( content = ' \n ' . join ( text ) )
else :
tPos = len ( ctx . guild . channels )
cat = ctx . channel . category
for t in cat . text_channels :
if t . position < = tPos :
tc = t
tPos = t . position
2021-07-23 00:44:21 +01:00
await tc . send ( f ' ```Player ` { player . display_name } ` has left the game.``` \n { game . mention } ' )
2021-07-21 11:49:29 +01:00
if ' mod ' in conf [ guildStr ] [ ' channels ' ] and ' committee ' in conf [ guildStr ] [ ' roles ' ] :
c = discord . utils . find ( lambda x : x . id == conf [ guildStr ] [ ' channels ' ] [ ' mod ' ] , ctx . guild . channels )
r = discord . utils . find ( lambda x : x . id == conf [ guildStr ] [ ' roles ' ] [ ' committee ' ] , ctx . guild . roles )
await c . send ( f ' ```Player ` { player . display_name } ` has left the game ` { lookup [ guildStr ] [ rStr ] [ " game_title " ] } ` via the `/player leave` command.``` ' )
yaml_dump ( data , dataFile )
await ctx . send ( content = f ' ```You have left the game ` { lookup [ guildStr ] [ rStr ] [ " game_title " ] } `.``` ' , hidden = True )
def setup ( client ) :
client . add_cog ( PlayerCommands ( client ) )