forked from viveksantayana/geas-bot
Changed file structure.
Moved code to main bot and cog files.
This commit is contained in:
@ -1,177 +0,0 @@
|
||||
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))
|
@ -1,48 +0,0 @@
|
||||
import discord
|
||||
from discord.ext import commands, tasks
|
||||
from datetime import datetime
|
||||
|
||||
def helpChannels(client):
|
||||
l = []
|
||||
for guild in client.guilds:
|
||||
channel = discord.utils.find(lambda c: c.name == '⛑-help', guild.channels)
|
||||
l.append(channel)
|
||||
return l
|
||||
|
||||
def committeeRoles(client):
|
||||
l = []
|
||||
for guild in client.guilds:
|
||||
role = discord.utils.find(lambda r: r.name == 'Committee', guild.roles)
|
||||
l.append(role)
|
||||
return l
|
||||
|
||||
def checkCommitteeRoles(author,committee):
|
||||
if set(author.roles) & set(committee):
|
||||
return True
|
||||
|
||||
class HelpNotifier(commands.Cog, name='Help Notifier Commands'):
|
||||
def __init__(self,client):
|
||||
self.client = client
|
||||
|
||||
# Message in Help channel event listener.
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self,message):
|
||||
if message.author.bot:
|
||||
return
|
||||
if checkCommitteeRoles(message.author, committeeRoles(self.client)):
|
||||
return
|
||||
if message.channel not in helpChannels(self.client):
|
||||
return
|
||||
committeeChannel = discord.utils.find(lambda t: t.name == '🗞-moderator-logs',message.guild.channels)
|
||||
committeeRole = discord.utils.find(lambda c: c.name == 'Committee', message.guild.roles)
|
||||
embed = discord.Embed(
|
||||
title = message.content,
|
||||
description = f'[Jump to Message]({message.jump_url})',
|
||||
colour = discord.Colour.orange(),
|
||||
)
|
||||
embed.set_footer(text=datetime.now().strftime('%a %-d %b %y, %-I:%M %p'))
|
||||
embed.set_author(name=message.author.display_name, icon_url=message.author.avatar_url)
|
||||
await committeeChannel.send(f'Hey {committeeRole.mention}, {message.author.mention} has just posted the following message in the {message.channel.mention} channel', embed=embed)
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(HelpNotifier(client))
|
@ -1,112 +0,0 @@
|
||||
import discord
|
||||
from discord.ext import commands, tasks
|
||||
from datetime import datetime
|
||||
from bot import dbClient, p, state, gameTimes, gameTime, timeSlotList, dbFindTimeslot, dbLookupRole
|
||||
|
||||
def gameCategories(client):
|
||||
l = []
|
||||
try:
|
||||
for guild in client.guilds:
|
||||
dbName = str(guild.id)
|
||||
db = dbClient[dbName]
|
||||
for colName in db.list_collection_names():
|
||||
if colName != 'settings':
|
||||
ret = db[colName].find()
|
||||
for e in ret:
|
||||
l.append(guild.get_channel(e['category']))
|
||||
except:
|
||||
for guild in client.guilds:
|
||||
for cat in guild.categories:
|
||||
if cat.name.split(': ',maxsplit=1)[0] in timeSlotList():
|
||||
l.append(cat)
|
||||
return l
|
||||
|
||||
def gameRoles(client):
|
||||
l = []
|
||||
try:
|
||||
for guild in client.guilds:
|
||||
dbName = str(guild.id)
|
||||
db = dbClient[dbName]
|
||||
for colName in db.list_collection_names():
|
||||
if colName != 'settings':
|
||||
ret = db[colName].find()
|
||||
for e in ret:
|
||||
l.append(guild.get_role(e['role']))
|
||||
except:
|
||||
for guild in client.guilds:
|
||||
for role in guild.roles:
|
||||
if role.name.split(': ',maxsplit=1)[0] in timeSlotList():
|
||||
l.append(role)
|
||||
return l
|
||||
|
||||
def committeeRoles(client):
|
||||
l = []
|
||||
for guild in client.guilds:
|
||||
role = discord.utils.find(lambda r: r.name == 'Committee', guild.roles)
|
||||
l.append(role)
|
||||
return l
|
||||
|
||||
def memberRoles(client):
|
||||
l = []
|
||||
for guild in client.guilds:
|
||||
role = discord.utils.find(lambda r: r.name == 'Life Members', guild.roles)
|
||||
l.append(role)
|
||||
role = discord.utils.find(lambda r: r.name == 'Members: Full Year', guild.roles)
|
||||
l.append(role)
|
||||
role = discord.utils.find(lambda r: r.name == 'Members: Semester 2', guild.roles)
|
||||
l.append(role)
|
||||
role = discord.utils.find(lambda r: r.name == 'Members: Semester 1', guild.roles)
|
||||
l.append(role)
|
||||
role = discord.utils.find(lambda r: r.name == 'New Member', guild.roles)
|
||||
l.append(role)
|
||||
role = discord.utils.find(lambda r: r.name == 'Temporary Access', guild.roles)
|
||||
l.append(role)
|
||||
return l
|
||||
|
||||
def checkCommitteeRoles(author,committee):
|
||||
if set(author.roles) & set(committee):
|
||||
return True
|
||||
|
||||
def checkMemberRoles(author,memberRoles):
|
||||
if set(author.roles) & set(memberRoles):
|
||||
return True
|
||||
|
||||
class MembershipRestriction(commands.Cog, name='Membership Restriction Protocol'):
|
||||
def __init__(self,client):
|
||||
self.client = client
|
||||
|
||||
# Event Listener for Message from Non-Member in Game Channels
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self,message):
|
||||
if message.author.bot:
|
||||
return
|
||||
guestRole = discord.utils.find(lambda g: g.name == 'Guest', message.guild.roles)
|
||||
if guestRole.permissions.read_messages:
|
||||
return
|
||||
if message.channel.category not in gameCategories(self.client):
|
||||
return
|
||||
if checkCommitteeRoles(message.author, committeeRoles(self.client)) or message.guild.owner == message.author:
|
||||
return
|
||||
if checkMemberRoles(message.author, memberRoles(self.client)):
|
||||
return
|
||||
signupChannel = discord.utils.find(lambda c: c.name == '📋-membership-signups', message.guild.channels)
|
||||
if message.channel.overwrites_for(message.author).manage_channels:
|
||||
return
|
||||
await message.channel.send(f'{message.author.mention} does not have a verified membership of Geas. Please submit your membership confirmation for verification in the {signupChannel.mention} to ensure you have access to your game.')
|
||||
await message.channel.category.set_permissions(message.author, send_messages = False, connect = False)
|
||||
await message.delete()
|
||||
|
||||
# Event Listener for Reinstating Permissions when Membership is Assigned
|
||||
@commands.Cog.listener()
|
||||
async def on_member_update(self,before,after):
|
||||
if before.roles == after.roles:
|
||||
return
|
||||
if checkMemberRoles(after, memberRoles(self.client)):
|
||||
for g in after.roles:
|
||||
if g in gameRoles(self.client):
|
||||
cat = dbLookupRole(after.guild, g)
|
||||
if not cat.overwrites_for(after).send_messages and not cat.overwrites_for(after).manage_channels:
|
||||
await cat.set_permissions(after, overwrite = None)
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(MembershipRestriction(client))
|
@ -1,142 +0,0 @@
|
||||
import discord
|
||||
from discord.ext import commands, tasks
|
||||
from datetime import datetime
|
||||
|
||||
def membershipSignupChannels(client):
|
||||
l = []
|
||||
for guild in client.guilds:
|
||||
channel = discord.utils.find(lambda c: c.name == '📋-membership-signups', guild.channels)
|
||||
l.append(channel)
|
||||
return l
|
||||
|
||||
def committeeRoles(client):
|
||||
l = []
|
||||
for guild in client.guilds:
|
||||
role = discord.utils.find(lambda r: r.name == 'Committee', guild.roles)
|
||||
l.append(role)
|
||||
return l
|
||||
|
||||
def checkCommitteeRoles(author,committee):
|
||||
if set(author.roles) & set(committee):
|
||||
return True
|
||||
|
||||
class MembershipVerification(commands.Cog, name='Membership Verification Commands'):
|
||||
def __init__(self,client):
|
||||
self.client = client
|
||||
|
||||
# Message in Membership Signup event listener.
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self,message):
|
||||
if message.channel in membershipSignupChannels(self.client) and message.author.id != self.client.user.id:
|
||||
if message.attachments == []:
|
||||
await message.author.send(f'**Error**: The message you posted in the {message.channel.name} channel of {message.guild.name} was invalid. Your post must contain a screensot of your proof of purchase for membership from EUSA.')
|
||||
await message.delete()
|
||||
return
|
||||
await message.add_reaction('1️⃣')
|
||||
await message.add_reaction('2️⃣')
|
||||
await message.add_reaction('📅')
|
||||
await message.add_reaction('📚')
|
||||
await message.add_reaction('⚠️')
|
||||
await message.add_reaction('🚫')
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_raw_reaction_add(self,payload):
|
||||
if payload.user_id != self.client.user.id and self.client.get_channel(payload.channel_id) in membershipSignupChannels(self.client):
|
||||
guild = await self.client.fetch_guild(payload.guild_id)
|
||||
member = await guild.fetch_member(payload.user_id)
|
||||
channel = await self.client.fetch_channel(payload.channel_id)
|
||||
message = await channel.fetch_message(payload.message_id)
|
||||
studentsRole = discord.utils.find(lambda g: g.name == 'Students', guild.roles)
|
||||
semesterOneRole = discord.utils.find(lambda g: g.name == 'Members: Semester 1', guild.roles)
|
||||
semesterTwoRole = discord.utils.find(lambda g: g.name == 'Members: Semester 2', guild.roles)
|
||||
fullYearRole = discord.utils.find(lambda g: g.name == 'Members: Full Year', guild.roles)
|
||||
channels = await guild.fetch_channels()
|
||||
committeeChannel = discord.utils.find(lambda t: t.name == '🗞-moderator-logs', channels)
|
||||
committeeRole = discord.utils.find(lambda c: c.name == 'Committee', guild.roles)
|
||||
if not checkCommitteeRoles(member, committeeRoles(self.client)):
|
||||
await member.send(f'**Error**: Only Committee members are authorised to react to posts on the {channel.name} channel for {guild.name}.')
|
||||
await message.remove_reaction(payload.emoji.name, member)
|
||||
return
|
||||
if payload.emoji.name == '1️⃣':
|
||||
await message.author.add_roles(semesterOneRole)
|
||||
await message.add_reaction('✅')
|
||||
await message.author.send(f'Your membership for {guild.name} has been verified and you have been assigned the role **Members: Semester 1**.')
|
||||
return
|
||||
if payload.emoji.name == '2️⃣':
|
||||
await message.author.add_roles(semesterTwoRole)
|
||||
await message.add_reaction('✅')
|
||||
await message.author.send(f'Your membership for {guild.name} has been verified and you have been assigned the role **Members: Semester 2**.')
|
||||
return
|
||||
if payload.emoji.name == '📅':
|
||||
await message.author.add_roles(fullYearRole)
|
||||
await message.add_reaction('✅')
|
||||
await message.author.send(f'Your membership for {guild.name} has been verified and you have been assigned the role **Members: Full Year**.')
|
||||
return
|
||||
if payload.emoji.name == '📚':
|
||||
await message.author.add_roles(studentsRole)
|
||||
await message.author.send(f'You have additionally been assigned the role **Students**.')
|
||||
return
|
||||
if payload.emoji.name == '⚠️':
|
||||
embed = discord.Embed(
|
||||
title = message.author.name,
|
||||
description = f'[Jump to Message]({message.jump_url})',
|
||||
colour = discord.Colour.orange(),
|
||||
)
|
||||
await message.author.send(f'Your membership for {guild.name} needs to be reviewed by a Committee member.')
|
||||
await committeeChannel.send(f'Hey {committeeRole.mention}, there is a problem verifying the membership of {message.author.mention}.\nCould someone verify this person\'s membership manually via the EUSA portal and return to the message?', embed=embed)
|
||||
return
|
||||
if payload.emoji.name == '🚫':
|
||||
embed = discord.Embed(
|
||||
title = message.author.name,
|
||||
description = f'[Jump to Message]({message.jump_url})',
|
||||
colour = discord.Colour.red(),
|
||||
)
|
||||
await message.author.send(f'Your membership for {guild.name} could not be verified. Please make sure that your name and the kind of membership you have bought are visible in the screenshot you upload. Please contact a Committee member if you have any difficulties.')
|
||||
await committeeChannel.send(f'Hey {committeeRole.mention}, verifying the membership of {message.author.mention} failed.', embed=embed)
|
||||
return
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_raw_reaction_remove(self,payload):
|
||||
if payload.user_id != self.client.user.id and self.client.get_channel(payload.channel_id) in membershipSignupChannels(self.client):
|
||||
guild = await self.client.fetch_guild(payload.guild_id)
|
||||
member = await guild.fetch_member(payload.user_id)
|
||||
channel = await self.client.fetch_channel(payload.channel_id)
|
||||
message = await channel.fetch_message(payload.message_id)
|
||||
studentsRole = discord.utils.find(lambda g: g.name == 'Students', guild.roles)
|
||||
semesterOneRole = discord.utils.find(lambda g: g.name == 'Members: Semester 1', guild.roles)
|
||||
semesterTwoRole = discord.utils.find(lambda g: g.name == 'Members: Semester 2', guild.roles)
|
||||
fullYearRole = discord.utils.find(lambda g: g.name == 'Members: Full Year', guild.roles)
|
||||
channels = await guild.fetch_channels()
|
||||
committeeChannel = discord.utils.find(lambda t: t.name == '🗞-moderator-logs', channels)
|
||||
committeeRole = discord.utils.find(lambda c: c.name == 'Committee', guild.roles)
|
||||
if not checkCommitteeRoles(member, committeeRoles(self.client)):
|
||||
await message.remove_reaction(payload.emoji.name, member)
|
||||
return
|
||||
if payload.emoji.name == '1️⃣':
|
||||
await message.author.remove_roles(semesterOneRole)
|
||||
await message.remove_reaction('✅',self.client.user)
|
||||
await message.author.send(f'Your role **Members: Semester 1** for {guild.name} has been removed.')
|
||||
return
|
||||
if payload.emoji.name == '2️⃣':
|
||||
await message.author.remove_roles(semesterTwoRole)
|
||||
await message.remove_reaction('✅',self.client.user)
|
||||
await message.author.send(f'Your role **Members: Semester 2** for {guild.name} has been removed.')
|
||||
return
|
||||
if payload.emoji.name == '📅':
|
||||
await message.author.remove_roles(fullYearRole)
|
||||
await message.remove_reaction('✅',self.client.user)
|
||||
await message.author.send(f'Your role **Members: Full Year** for {guild.name} has been removed.')
|
||||
return
|
||||
if payload.emoji.name == '📚':
|
||||
await message.author.remove_roles(studentsRole)
|
||||
await message.author.send(f'Your role **Students** for {guild.name} has been removed.')
|
||||
return
|
||||
if payload.emoji.name == '⚠️':
|
||||
await message.author.send(f'Your membership for {guild.name} is being reviewed by a Committee member.')
|
||||
return
|
||||
if payload.emoji.name == '🚫':
|
||||
await message.author.send(f'Your membership for {guild.name} is being reviewed by a Committee member.')
|
||||
return
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(MembershipVerification(client))
|
@ -1,190 +0,0 @@
|
||||
import os
|
||||
import pymongo
|
||||
import discord
|
||||
from discord.ext import commands, tasks
|
||||
from bot import dbClient, p, state, gameTimes, gameTime, timeSlotList, dbFindTimeslot, dbLookupRole, syncGames
|
||||
|
||||
pitchState = {}
|
||||
|
||||
def pitchListening():
|
||||
l = []
|
||||
for guild in pitchState:
|
||||
for slot in pitchState[guild]:
|
||||
l.append(pitchState[guild][slot]['menuMessage'].id)
|
||||
return l
|
||||
|
||||
|
||||
emojiList = [
|
||||
'1️⃣',
|
||||
'2️⃣',
|
||||
'3️⃣',
|
||||
'4️⃣',
|
||||
'5️⃣',
|
||||
'6️⃣',
|
||||
'7️⃣',
|
||||
'8️⃣',
|
||||
'9️⃣',
|
||||
'🔟',
|
||||
'🇦',
|
||||
'🇧',
|
||||
'🇨',
|
||||
'🇩',
|
||||
'🇪',
|
||||
'🇫',
|
||||
'🇬',
|
||||
'🇭',
|
||||
'🇮',
|
||||
'🇯'
|
||||
]
|
||||
|
||||
class PitchMenu(commands.Cog, name='Pitch Menu Commands'):
|
||||
def __init__(self,client):
|
||||
self.client = client
|
||||
|
||||
# Pitch Run Command
|
||||
@commands.has_permissions(administrator=True)
|
||||
@commands.group(name='pitch', aliases=['pitches'], description='The command to run pitches. It has two subcommands. Syntax: `pitch {run|clear} {wed|sunaft|suneve|oneshot|other}`')
|
||||
async def pitch(self, ctx):
|
||||
if ctx.invoked_subcommand is None:
|
||||
await ctx.send(f'Invalid subcommand. Please use either `{p}pitch run` or `{p}pitch clear`')
|
||||
|
||||
@pitch.command(name='run', aliases=['start','generate','setup'], description='Subcommand to set up pitches. Syntax: `pitch run {wed|sunaft|suneve|oneshot|other}`')
|
||||
async def pitch_run(self, ctx, arg):
|
||||
if arg.lower() not in ['all', 'other', 'wed', 'sunaft', 'suneve', 'oneshot']:
|
||||
raise commands.CommandError('Invalid argument. {arg} is not a valid flag for the command.')
|
||||
syncGames(ctx.guild)
|
||||
await ctx.message.delete()
|
||||
await ctx.channel.trigger_typing()
|
||||
## Constructing Pitch State Dictionary
|
||||
dbName = str(ctx.guild.id)
|
||||
db = dbClient[dbName]
|
||||
colName = gameTime(arg.lower())
|
||||
if dbName not in pitchState:
|
||||
pitchState[dbName] = {}
|
||||
if colName not in pitchState[dbName]:
|
||||
pitchState[dbName][colName] = {}
|
||||
pitchState[dbName][colName]['entries'] = []
|
||||
# Try database queries
|
||||
try:
|
||||
cur = db[colName].find().sort('game')
|
||||
for entry in cur:
|
||||
gameDict = {}
|
||||
gameDict['game'] = entry['game']
|
||||
gameDict['gm'] = await ctx.guild.fetch_member(entry['gm'])
|
||||
gameDict['role'] = discord.utils.find(lambda m: m.id == entry['role'],ctx.guild.roles)
|
||||
gameDict['capacity'] = entry['capacity'] if entry['capacity'] != None else 5
|
||||
gameDict['signups'] = 0
|
||||
cat = discord.utils.find(lambda m: m.id == entry['category'], ctx.guild.categories)
|
||||
tFirst = None
|
||||
tPos = len(ctx.guild.channels)
|
||||
for t in cat.text_channels:
|
||||
if t.position <= tPos:
|
||||
tFirst = t
|
||||
tPos = t.position
|
||||
gameDict['textchannel'] = tFirst
|
||||
pitchState[dbName][colName]['entries'].append(dict(gameDict))
|
||||
# Infer from server if database fails
|
||||
except:
|
||||
for r in ctx.guild.roles:
|
||||
if r.name.startswith(colName):
|
||||
gameDict = {}
|
||||
gameDict['game'] = r.name.split(': ',maxsplit=1)[1]
|
||||
gameDict['role'] = r
|
||||
gameDict['capacity'] = 5
|
||||
gameDict['signups'] = 0
|
||||
cat = discord.utils.find(lambda m: m.name == r.name, ctx.guild.categories)
|
||||
for p in cat.overwrites:
|
||||
if isinstance(p,discord.Member) and cat.overwrites[p].manage_channels:
|
||||
gameDict['gm'] = p
|
||||
break
|
||||
tFirst = None
|
||||
tPos = len(ctx.guild.channels)
|
||||
for t in cat.text_channels:
|
||||
if t.position <= tPos:
|
||||
tFirst = t
|
||||
tPos = t.position
|
||||
gameDict['textchannel'] = t
|
||||
pitchState[dbName][colName]['entries'].append(dict(gameDict))
|
||||
pitchState[dbName][colName]['entries'].sort(key= lambda m: m['game'])
|
||||
# Begin Constructing the Menu
|
||||
pitchState[dbName][colName]['headerMessage'] = await ctx.channel.send(f'**Game listing for {colName}**\n_ _\nThe following are the games that are being pitched. Please select your game by clicking on the emoji reaction at the bottom of the menu.\n_ _')
|
||||
for e in pitchState[dbName][colName]['entries']:
|
||||
e['message'] = await ctx.channel.send(f'{emojiList[pitchState[dbName][colName]["entries"].index(e)]} **{e["game"]}** (GM {e["gm"].mention}). {e["capacity"] - e["signups"]} spaces remaining.')
|
||||
pitchState[dbName][colName]['menuMessage'] = await ctx.channel.send('_ _\n**Please select a game from the above list by clicking on the corresponding emoji reaction below.**')
|
||||
for option in pitchState[dbName][colName]['entries']:
|
||||
await pitchState[dbName][colName]['menuMessage'].add_reaction(emojiList[pitchState[dbName][colName]["entries"].index(option)])
|
||||
|
||||
@pitch.command(name='clear', aliases=['end','cancel','reset','delete'], description='Subcommand to clear pitches. {wed|sunaft|suneve|oneshot|other}')
|
||||
async def pitch_clear(self, ctx, arg):
|
||||
if arg.lower() not in ['all', 'other', 'wed', 'sunaft', 'suneve', 'oneshot']:
|
||||
raise commands.CommandError(f'Invalid argument. {arg} is not a valid flag for the command.')
|
||||
await ctx.message.delete()
|
||||
await ctx.channel.trigger_typing()
|
||||
dbName = str(ctx.guild.id)
|
||||
db = dbClient[dbName]
|
||||
colName = gameTime(arg.lower())
|
||||
for e in pitchState[dbName][colName]['entries']:
|
||||
await e['message'].delete()
|
||||
await pitchState[dbName][colName]['menuMessage'].delete()
|
||||
await pitchState[dbName][colName]['headerMessage'].delete()
|
||||
await ctx.send(f'Pitch menu for {colName} has been reset.')
|
||||
pitchState[dbName][colName].clear
|
||||
|
||||
# Emoji Reaction Event Listeners
|
||||
@commands.Cog.listener()
|
||||
async def on_raw_reaction_add(self, payload):
|
||||
if payload.user_id != self.client.user.id:
|
||||
if payload.message_id in pitchListening():
|
||||
guildID = str(payload.guild_id)
|
||||
guild = discord.utils.find(lambda g: g.id == payload.guild_id, self.client.guilds)
|
||||
channel = discord.utils.find(lambda c: c.id == payload.channel_id, guild.channels)
|
||||
author = await guild.fetch_member(payload.user_id)
|
||||
for slot in pitchState[guildID]:
|
||||
if pitchState[guildID][slot]['menuMessage'].id == payload.message_id:
|
||||
break
|
||||
message = await channel.fetch_message(pitchState[guildID][slot]['menuMessage'].id)
|
||||
for reaction in message.reactions:
|
||||
if reaction.emoji != payload.emoji.name:
|
||||
i = emojiList.index(reaction.emoji)
|
||||
if author in await reaction.users().flatten():
|
||||
await reaction.remove(author)
|
||||
i = emojiList.index(payload.emoji.name)
|
||||
e = pitchState[guildID][slot]['entries'][i]
|
||||
playerRole = discord.utils.find(lambda p: p.name == 'Players',guild.roles)
|
||||
await author.add_roles(playerRole,e['role'])
|
||||
e['signups'] += 1
|
||||
contentString = f'{emojiList[i]} **{e["game"]}** (GM {e["gm"].mention}). {e["capacity"] - e["signups"] if e["signups"] <= e["capacity"] else 0} {"space" if e["capacity"] - e["signups"] == 1 else "spaces"} remaining.'
|
||||
await e['message'].edit(content=f'~~{contentString}~~' if e['signups'] >= e['capacity'] else contentString)
|
||||
await e['textchannel'].send(f'{author.mention} has joined the game.')
|
||||
|
||||
# Emoji Un-React Event Listener
|
||||
@commands.Cog.listener()
|
||||
async def on_raw_reaction_remove(self, payload):
|
||||
if payload.user_id != self.client.user.id:
|
||||
if payload.message_id in pitchListening():
|
||||
guildID = str(payload.guild_id)
|
||||
guild = discord.utils.find(lambda g: g.id == payload.guild_id, self.client.guilds)
|
||||
channel = discord.utils.find(lambda c: c.id == payload.channel_id, guild.channels)
|
||||
author = await guild.fetch_member(payload.user_id)
|
||||
for slot in pitchState[guildID]:
|
||||
if pitchState[guildID][slot]['menuMessage'].id == payload.message_id:
|
||||
break
|
||||
message = await channel.fetch_message(pitchState[guildID][slot]['menuMessage'].id)
|
||||
i = emojiList.index(payload.emoji.name)
|
||||
e = pitchState[guildID][slot]['entries'][i]
|
||||
e['signups'] -= 1
|
||||
contentString = f'{emojiList[i]} **{e["game"]}** (GM {e["gm"].mention}). {e["capacity"] - e["signups"] if e["signups"] <= e["capacity"] else 0} {"space" if e["capacity"] - e["signups"] == 1 else "spaces"} remaining.'
|
||||
await e['message'].edit(content=f'~~{contentString}~~' if e['signups'] >= e['capacity'] else contentString)
|
||||
await e['textchannel'].send(f'{author.mention} has left the game.')
|
||||
await author.remove_roles(e['role'])
|
||||
isPlayer = False
|
||||
for role in author.roles:
|
||||
if role.name.split(': ',maxsplit=1)[0] in timeSlotList():
|
||||
isPlayer = True
|
||||
break
|
||||
if not isPlayer:
|
||||
playerRole = discord.utils.find(lambda p: p.name == 'Players',guild.roles)
|
||||
await author.remove_roles(playerRole)
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(PitchMenu(client))
|
26
app/cogs/botcommands/prefix.py
Normal file
26
app/cogs/botcommands/prefix.py
Normal file
@ -0,0 +1,26 @@
|
||||
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 bot import configFile, yaml_load, yaml_dump
|
||||
|
||||
### Cog for handling the non-Slash prefix for native Bot commands.
|
||||
|
||||
class Prefix(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.command(
|
||||
name = 'changeprefix',
|
||||
aliases = ['prefix'],
|
||||
description = 'This command changes the prefix string for the native, non-slash command functionality of the bot. Defaults to `-`. It does not affect the workings of /commands.',
|
||||
brief = 'Changes the bot prefix.'
|
||||
)
|
||||
async def _changePrefix(self, ctx, prefix:str = '-'):
|
||||
conf = yaml_load(configFile)
|
||||
conf[str(ctx.guild.id)]['prefix'] = prefix.lower()
|
||||
yaml_dump(conf, configFile)
|
||||
await ctx.send(f"`{self.client.user.name}`'s prefix for native bot commands has been changed to `{prefix}` for the guild `{ctx.guild.name}`.\n`Note: This will not affect /commands.`")
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(Prefix(client))
|
31
app/cogs/dev/dev.py
Normal file
31
app/cogs/dev/dev.py
Normal file
@ -0,0 +1,31 @@
|
||||
import os
|
||||
from dotenv import load_dotenv # Import OS variables from Dotenv file.
|
||||
load_dotenv() # Load Dotenv. Delete this for production
|
||||
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
|
||||
|
||||
from bot import loadCog, unloadCog
|
||||
|
||||
##### Dev Cog
|
||||
class Dev(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.command(
|
||||
name='debug',
|
||||
description='Toggles debug feature for the guild. Enter either `on` or `off`.',
|
||||
brief='Toggle debug features.'
|
||||
)
|
||||
async def _debug(self, ctx, toggle:str):
|
||||
if toggle.lower() == 'on':
|
||||
loadCog(f'./debug/debug.py')
|
||||
await ctx.reply(f'Debug commands enabled. Use them carefully.')
|
||||
elif toggle.lower() == 'off':
|
||||
unloadCog(f'./debug/debug.py')
|
||||
await ctx.reply(f'Debug commands disabled.')
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(Dev(client))
|
30
app/cogs/events/on_connect.py
Normal file
30
app/cogs/events/on_connect.py
Normal file
@ -0,0 +1,30 @@
|
||||
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
|
||||
|
||||
#### Actions for the Bot to take on connecting to Discord.
|
||||
class on_connect(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_connect(self): ## Actions for when bot logs in and enters ready state
|
||||
print('Bot has connected.')
|
||||
# logging.info('Bot has connected.')
|
||||
await self.client.change_presence(
|
||||
status = discord.Status.online,
|
||||
activity = discord.Activity(
|
||||
type = discord.ActivityType.listening,
|
||||
name = f'/commands'
|
||||
)
|
||||
)
|
||||
# for g in self.client.guilds:
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(on_connect(client))
|
33
app/cogs/events/on_guild_channel_delete.py
Normal file
33
app/cogs/events/on_guild_channel_delete.py
Normal file
@ -0,0 +1,33 @@
|
||||
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
|
||||
|
||||
##### Actions for the bot to take whenever a channel in a guild is deleted
|
||||
class on_guild_channel_delete(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
#### What to do if a mod channel gets deleted: try and pull default system channel, and if not then top-most channel
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_channel_delete(self, channel):
|
||||
conf = yaml_load(configFile)
|
||||
if conf[str(channel.guild.id)]['modchannel'] == channel.id:
|
||||
if channel.guild.system_channel is None:
|
||||
p = len(channel.guild.channels)
|
||||
c = None
|
||||
for t in channel.guild.text_channels:
|
||||
if t.position < p:
|
||||
p = t.position
|
||||
conf[str(channel.guild.id)]['modchannel'] = t.id
|
||||
else:
|
||||
conf[str(channel.guild.id)]['modchannel'] = channel.guild.system_channel.id
|
||||
yaml_dump(conf, configFile)
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(on_guild_channel_delete(client))
|
22
app/cogs/events/on_guild_join.py
Normal file
22
app/cogs/events/on_guild_join.py
Normal file
@ -0,0 +1,22 @@
|
||||
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, setConfig, yaml_load, yaml_dump
|
||||
|
||||
#### Actions for the bot to take when the Bot joins a guild.
|
||||
|
||||
class on_guild_join(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_join(self, guild):
|
||||
setConfig(guild)
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(on_guild_join(client))
|
22
app/cogs/events/on_guild_remove.py
Normal file
22
app/cogs/events/on_guild_remove.py
Normal file
@ -0,0 +1,22 @@
|
||||
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 clearConfig, configFile, yaml_load, yaml_dump
|
||||
|
||||
#### Actions for the bot to take when removed from a guild.
|
||||
|
||||
class on_guild_remove(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_remove(self, guild): ## Actions for when the bot is removed from a guild.
|
||||
clearConfig(str(guild.id))
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(on_guild_remove(client))
|
27
app/cogs/events/on_guild_role_create.py
Normal file
27
app/cogs/events/on_guild_role_create.py
Normal file
@ -0,0 +1,27 @@
|
||||
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
|
||||
|
||||
##### Actions for the bot to take whenever there is a new role created.
|
||||
|
||||
class on_guild_role_create(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_role_create(self, role):
|
||||
conf = yaml_load(configFile)
|
||||
#### Bot will only respond if the role is not a bot-managed role, and the role is an admin role
|
||||
if not (role.is_bot_managed() or role.is_integration()) and role.permissions.administrator:
|
||||
conf[str(role.guild.id)]['adminroles'].append(role.id)
|
||||
yaml_dump(conf, configFile)
|
||||
#### If the role is created with admin privileges, the bot adds the role to its configs.
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(on_guild_role_create(client))
|
27
app/cogs/events/on_guild_role_delete.py
Normal file
27
app/cogs/events/on_guild_role_delete.py
Normal file
@ -0,0 +1,27 @@
|
||||
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
|
||||
|
||||
##### Actions for the bot to take whenever there is a new role deleted.
|
||||
|
||||
class on_guild_role_delete(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_role_delete(self, role):
|
||||
conf = yaml_load(configFile)
|
||||
#### Bot will only respond if the role is not a bot-managed role, and the role is an admin role
|
||||
if role.id in conf[str(role.guild.id)]['adminroles']:
|
||||
conf[str(role.guild.id)]['adminroles'].remove(role.id)
|
||||
yaml_dump(conf, configFile)
|
||||
#### If the role is one of the Admin roles and is deleted, updates the bot's config to delete that role, preventing unnecessary roles from accumulating.
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(on_guild_role_delete(client))
|
34
app/cogs/events/on_guild_role_update.py
Normal file
34
app/cogs/events/on_guild_role_update.py
Normal file
@ -0,0 +1,34 @@
|
||||
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
|
||||
|
||||
##### Actions for the bot to take whenever there is a new role deleted.
|
||||
|
||||
class on_guild_role_update(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_role_update(self, before, after):
|
||||
conf = yaml_load(configFile)
|
||||
#### If the original role is in the config as an admin role, and it subsequently is run by a bot or is not an admin, remove it from config
|
||||
if before.id in conf[str(before.guild.id)]['adminroles']:
|
||||
if after.is_bot_managed() or after.is_integration() or not after.permissions.administrator:
|
||||
conf[str(after.guild.id)]['adminroles'].remove(after.id)
|
||||
yaml_dump(conf, configFile)
|
||||
|
||||
#### If the new role is an admin and is not already in the config, add it.
|
||||
if not (after.is_bot_managed() or after.is_integration()) and after.permissions.administrator:
|
||||
if after.id not in conf[str(after.guild.id)]['adminroles']:
|
||||
conf[str(after.guild.id)]['adminroles'].remove(after.id)
|
||||
yaml_dump(conf, configFile)
|
||||
#### If the role is one of the Admin roles and is deleted, updates the bot's config to delete that role, preventing unnecessary roles from accumulating.
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(on_guild_role_update(client))
|
25
app/cogs/events/on_guild_update.py
Normal file
25
app/cogs/events/on_guild_update.py
Normal file
@ -0,0 +1,25 @@
|
||||
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
|
||||
|
||||
##### Actions for the bot to take whenever the guild info or ownership are updated.
|
||||
class on_guild_update(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_guild_update(self, before, after):
|
||||
conf = yaml_load(configFile)
|
||||
conf[str(after.id)]['name'] = after.name
|
||||
conf[str(after.id)]['owner'] = after.owner_id
|
||||
# Updates guild name and channel
|
||||
yaml_dump(conf,configFile)
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(on_guild_update(client))
|
30
app/cogs/events/on_ready.py
Normal file
30
app/cogs/events/on_ready.py
Normal file
@ -0,0 +1,30 @@
|
||||
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 # Slash Command features
|
||||
import logging
|
||||
# logger and handler
|
||||
from bot import clearConfig, configFile, setConfig, yaml_dump, yaml_load
|
||||
|
||||
#### Actions for the Bot to take once it is ready to interact with commands.
|
||||
class on_ready(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_ready(self):
|
||||
|
||||
#### Create any missing config entries for guilds
|
||||
for guild in self.client.guilds:
|
||||
setConfig(guild)
|
||||
|
||||
#### Delete any extra config entries for guilds the bot is not in
|
||||
conf = yaml_load(configFile)
|
||||
for key in list(conf):
|
||||
clearConfig(key)
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(on_ready(client))
|
35
app/cogs/slashcommands/config.py
Normal file
35
app/cogs/slashcommands/config.py
Normal file
@ -0,0 +1,35 @@
|
||||
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 # Slash Command features
|
||||
|
||||
##### Configuration Cog
|
||||
class Configuration(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@cog_ext.cog_slash(
|
||||
# base='botrole',
|
||||
# subcommand_group='configure',
|
||||
name='configure',
|
||||
description='Parameter to define the role assigned to the dice bots.',
|
||||
# base_description='Command to configure the various guild parameters.',
|
||||
# subcommand_group_description='These are configuration commands to set up the various guild parameters.',
|
||||
guild_ids=guild_ids
|
||||
# options=[
|
||||
# create_option(
|
||||
# name='botrole',
|
||||
# description='The role that the dice bots are assigned in order to access the text channels.'
|
||||
# type=8,
|
||||
# required=True
|
||||
# )
|
||||
# ]
|
||||
)
|
||||
async def _configure(self, ctx:SlashContext, option):
|
||||
await ctx.send(f'The `botrole` for the guild `{ctx.guild.name}` has been set to `{option}`.')
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(Configuration(client))
|
Reference in New Issue
Block a user