177 lines
8.4 KiB
Python
177 lines
8.4 KiB
Python
|
import os
|
||
|
import pymongo
|
||
|
import discord
|
||
|
from discord.ext import commands
|
||
|
from bot import dbClient, p, state, gameTimes, gameTime, timeSlotList, dbFindTimeslot, dbLookupRole, in_game_channel
|
||
|
|
||
|
# Lookup GMs
|
||
|
def gmLookup(guild, member):
|
||
|
gamesList = []
|
||
|
db = dbClient[str(guild.id)]
|
||
|
try:
|
||
|
for c in db.list_collection_names():
|
||
|
ret = db[c].find({'gm':member.id})
|
||
|
for e in ret:
|
||
|
gamesList.append(guild.get_role(e['role']))
|
||
|
except:
|
||
|
for cat in guild.categories:
|
||
|
if cat.name.split(': ',maxsplit=1)[0] in timeSlotList():
|
||
|
for p in cat.overwrites:
|
||
|
if cat.overwrites[member].manage_channels:
|
||
|
for r in guild.roles:
|
||
|
if r.name == cat.name:
|
||
|
gamesList.append(r)
|
||
|
break
|
||
|
break
|
||
|
finally:
|
||
|
return gamesList
|
||
|
|
||
|
# Check if User is a GM
|
||
|
def user_is_GM(ctx):
|
||
|
if ctx.author.guild_permissions.administrator:
|
||
|
return True
|
||
|
if len(gmLookup(ctx.guild,ctx.author)) > 0:
|
||
|
return True
|
||
|
|
||
|
# Check if User is a Player
|
||
|
def user_is_Player(ctx):
|
||
|
gamesList = []
|
||
|
db = dbClient[str(ctx.guild.id)]
|
||
|
try:
|
||
|
for c in db.list_collection_names():
|
||
|
ret = db[c].find({})
|
||
|
for e in ret:
|
||
|
gamesList.append(ctx.guild.get_role(e['role']))
|
||
|
except:
|
||
|
for r in ctx.guild.roles:
|
||
|
if r.name.split(': ',maxsplit = 1)[0] in timeSlotList():
|
||
|
gamesList.append(r)
|
||
|
if set(gamesList) & set(ctx.author.roles):
|
||
|
return True
|
||
|
raise commands.CommandError('Error: You are not currently playing in any game.')
|
||
|
|
||
|
class GameManagement(commands.Cog, name='Game Management Commands'):
|
||
|
def __init__(self, client):
|
||
|
self.client = client
|
||
|
|
||
|
# GM Kick Command
|
||
|
@commands.command(name='kickplayer', aliases=['kick','removeplayer','dropplayer','drop', 'remove'],description='This removes a player from your game. Can only be invoked by the GM or a server admin. The syntax is `kickplayer {@Player}`. **This command must be called inside the text channel of the game you are kicking the player from.**. *The action gets logged with the Committee so we can keep track of who is in wose game.*')
|
||
|
@commands.check(user_is_GM)
|
||
|
@commands.check(in_game_channel)
|
||
|
async def kickPlayer(self, ctx, arg):
|
||
|
if not (arg.startswith('<@') and not (arg.startswith('<@&'))):
|
||
|
raise commands.CommandError('Invalid argument. The second parameter must @ the Player.')
|
||
|
if not ctx.author.permissions_in(ctx.channel.category).manage_channels:
|
||
|
raise commands.CommandError('You are not authorised to use this command here as you are not the GM.')
|
||
|
await ctx.message.delete()
|
||
|
await ctx.channel.trigger_typing()
|
||
|
permissions = ctx.channel.category.overwrites
|
||
|
for p in permissions:
|
||
|
if isinstance(p,discord.Role) and p.name == ctx.channel.category.name:
|
||
|
break
|
||
|
u = await ctx.guild.fetch_member(int(arg.replace('<@', '').replace('>', '').replace('!', '')))
|
||
|
await u.remove_roles(p)
|
||
|
isPlayer = False
|
||
|
for playerRoles in u.roles:
|
||
|
if playerRoles.name.split(': ',maxsplit=1)[0] in timeSlotList():
|
||
|
isPlayer = True
|
||
|
break
|
||
|
if not isPlayer:
|
||
|
for r in ctx.guild.roles:
|
||
|
if r.name == 'Players':
|
||
|
break
|
||
|
if r.name == 'Players':
|
||
|
await u.remove_roles(r)
|
||
|
for cr in ctx.guild.roles:
|
||
|
if cr.name == 'Committee':
|
||
|
break
|
||
|
await ctx.channel.send(f'{u.mention} has been kicked from the game. This has been logged with the {cr.mention}.')
|
||
|
for tc in ctx.guild.text_channels:
|
||
|
if tc.name.split('-',maxsplit=1)[1] == 'moderator-logs':
|
||
|
break
|
||
|
await tc.send(f'Hey {cr.mention}, {u.mention} has been kicked from the {p.mention} game by GM {ctx.author.mention}.')
|
||
|
|
||
|
@kickPlayer.error
|
||
|
async def clear_kick_error(self, ctx, error):
|
||
|
if isinstance(error, commands.CheckFailure):
|
||
|
await ctx.channel.send('You are not authorised to use this command as you are not a GM.')
|
||
|
raise error
|
||
|
|
||
|
# GM Add Command
|
||
|
@commands.command(name='addplayer', aliases=['add'],description='This command adds a player to your game. Can only be invoked by the GM for the game. The syntax is `addplayer {@Player} {@Game Role}`. As you cannot @-mention someone who cannot already see your channel, you are **not restricted** to use this command in a text channel belonging to your game. *The action gets logged with the Committee so we can keep track of who is in wose game.*')
|
||
|
@commands.check(user_is_GM)
|
||
|
async def addPlayer(self, ctx, arg1, arg2):
|
||
|
if not (arg1.startswith('<@') and not (arg1.startswith('<@&'))):
|
||
|
raise commands.CommandError('Invalid argument. The first parameter must @ the Player.')
|
||
|
if not arg2.startswith('<@&'):
|
||
|
raise commands.CommandError('Invalid argument. The second parameter must @ the game role.')
|
||
|
r = ctx.guild.get_role(int(arg2[3:-1]))
|
||
|
if r.name.split(': ',maxsplit=1)[0] not in timeSlotList():
|
||
|
raise commands.CommandError('Error: the role is not a valid game role.')
|
||
|
cat = dbLookupRole(ctx.guild,r)
|
||
|
if not ctx.author.permissions_in(cat).manage_channels:
|
||
|
raise commands.CommandError('You are not authorised to use this command as you are not the GM for the game.')
|
||
|
await ctx.message.delete()
|
||
|
await ctx.channel.trigger_typing()
|
||
|
u = await ctx.guild.fetch_member(int(arg1.replace('<@', '').replace('>', '').replace('!', '')))
|
||
|
for rl in ctx.guild.roles:
|
||
|
if rl.name == 'Players':
|
||
|
break
|
||
|
await u.add_roles(r,rl)
|
||
|
tPos = len(ctx.guild.channels)
|
||
|
tFirst = None
|
||
|
for t in cat.text_channels:
|
||
|
if t.position <= tPos:
|
||
|
tFirst = t
|
||
|
tPos = t.position
|
||
|
for cr in ctx.guild.roles:
|
||
|
if cr.name == 'Committee':
|
||
|
break
|
||
|
for tc in ctx.guild.text_channels:
|
||
|
if tc.name.split('-',maxsplit=1)[1] == 'moderator-logs':
|
||
|
break
|
||
|
await tFirst.send(f'{u.mention} has joined the game. Welcome! This has been logged with the {cr.mention}.')
|
||
|
await ctx.channel.send(f'{u.mention} has been added to the game {r.mention}.')
|
||
|
await tc.send(f'Hey {cr.mention}, {u.mention} was added to the {r.mention} game by {ctx.author.mention}.')
|
||
|
|
||
|
@addPlayer.error
|
||
|
async def clear_add_error(self, ctx, error):
|
||
|
if isinstance(error, commands.CheckFailure):
|
||
|
await ctx.channel.send('You are not authorised to use this command as you are not a GM.')
|
||
|
raise error
|
||
|
|
||
|
# Leave Game Command
|
||
|
@commands.command(name='leave',aliases=['leavegame','quit','quitgame','dropout'],description='This command is to leave the game you are in. **It must be invoked in the text channel of the game you are in.** *The action gets logged with the Committee so we can keep track of who is in wose game.*')
|
||
|
@commands.check(user_is_Player)
|
||
|
@commands.check(in_game_channel)
|
||
|
async def leaveGame(self, ctx):
|
||
|
await ctx.message.delete()
|
||
|
await ctx.channel.trigger_typing()
|
||
|
permissions = ctx.channel.category.overwrites
|
||
|
for p in permissions:
|
||
|
if isinstance(p,discord.Role) and p.name == ctx.channel.category.name:
|
||
|
break
|
||
|
await ctx.author.remove_roles(p)
|
||
|
isPlayer = False
|
||
|
for playerRoles in ctx.author.roles:
|
||
|
if playerRoles.name.split(': ',maxsplit=1)[0] in timeSlotList():
|
||
|
isPlayer = True
|
||
|
break
|
||
|
if not isPlayer:
|
||
|
for r in ctx.guild.roles:
|
||
|
if r.name == 'Players':
|
||
|
break
|
||
|
if r.name == 'Players':
|
||
|
await ctx.author.remove_roles(r)
|
||
|
for cr in ctx.guild.roles:
|
||
|
if cr.name == 'Committee':
|
||
|
break
|
||
|
await ctx.channel.send(f'{ctx.author.mention} has left the game. This has been logged with the {cr.mention}.')
|
||
|
for tc in ctx.guild.text_channels:
|
||
|
if tc.name.split('-',maxsplit=1)[1] == 'moderator-logs':
|
||
|
break
|
||
|
await tc.send(f'Hey {cr.mention}, {ctx.author.mention} has left the {p.mention} game by GM {ctx.author.mention}.')
|
||
|
|
||
|
# Cog Setup Function
|
||
|
def setup(client):
|
||
|
client.add_cog(GameManagement(client))
|