241 lines
11 KiB
Python
241 lines
11 KiB
Python
|
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
|
||
|
|
||
|
##### Game Management Commands
|
||
|
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
|
||
|
if not (set(ctx.author.roles) & set([ctx.guild.get_role(x) for x in conf[guildStr]['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[guildStr] if gms[guildStr][x]]):
|
||
|
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}`.')
|
||
|
t = lookup[rStr]['time']
|
||
|
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
|
||
|
hm = lookup[rStr]['header_message']
|
||
|
tc = discord.utils.find(lambda x: x.id == lookup[rStr]['text_message'],ctx.guild.channels)
|
||
|
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')
|
||
|
for line in text:
|
||
|
if 'Current Players: ' in line:
|
||
|
line = f'Current Players: {str(data[guildStr][t][rStr]["current_players"])}'
|
||
|
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
|
||
|
game = categories[guildStr][str(ctx.channel.category.id)]
|
||
|
rStr = str(game.id)
|
||
|
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
|
||
|
if not (set(ctx.author.roles) & set([ctx.guild.get_role(x) for x in conf[guildStr]['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[guildStr] if gms[guildStr][x]]):
|
||
|
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
|
||
|
await player.remove_roles(game, reason=f'`/player remove` command issued by {ctx.author.display_name}`.')
|
||
|
t = lookup[rStr]['time']
|
||
|
if type(data[guildStr][t][rStr]['current_players']) <= 1: data[guildStr][t][rStr]['current_players'] = None
|
||
|
else: data[guildStr][t][rStr]['current_players'] -= 1
|
||
|
hm = lookup[rStr]['header_message']
|
||
|
tc = discord.utils.find(lambda x: x.id == lookup[rStr]['text_message'],ctx.guild.channels)
|
||
|
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')
|
||
|
for line in text:
|
||
|
if 'Current Players: ' in line:
|
||
|
line = f'Current Players: {str(data[guildStr][t][rStr]["current_players"]) if data[guildStr][t][rStr]["current_players"] is not None else str(0)}'
|
||
|
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]:
|
||
|
await ctx.send(f'```Error: This command can only be issued in a text channel associated with a game.```', hidden=True)
|
||
|
return
|
||
|
game = categories[guildStr][str(ctx.channel.category.id)]
|
||
|
rStr = str(game.id)
|
||
|
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
|
||
|
await player.remove_roles(game, reason=f'`/player leave` command issued by {ctx.author.display_name}`.')
|
||
|
t = lookup[rStr]['time']
|
||
|
if type(data[guildStr][t][rStr]['current_players']) <= 1: data[guildStr][t][rStr]['current_players'] = None
|
||
|
else: data[guildStr][t][rStr]['current_players'] -= 1
|
||
|
hm = lookup[rStr]['header_message']
|
||
|
tc = discord.utils.find(lambda x: x.id == lookup[rStr]['text_message'],ctx.guild.channels)
|
||
|
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')
|
||
|
for line in text:
|
||
|
if 'Current Players: ' in line:
|
||
|
line = f'Current Players: {str(data[guildStr][t][rStr]["current_players"]) if data[guildStr][t][rStr]["current_players"] is not None else str(0)}'
|
||
|
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 left the game.```\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 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))
|