Errors and permissions

pull/5/head
Bobloy 7 years ago
parent 5694a61edb
commit d206ea2cb9

@ -26,12 +26,11 @@ class Game:
day_vote_count = 3 day_vote_count = 3
def __init__(self, guild: discord.Guild, role: discord.Role=None, def __init__(self, guild: discord.Guild, role: discord.Role = None,
category: discord.CategoryChannel=None, village: discord.TextChannel=None, category: discord.CategoryChannel = None, village: discord.TextChannel = None,
log_channel: discord.TextChannel=None, game_code=None): log_channel: discord.TextChannel = None, game_code=None):
self.guild = guild self.guild = guild
self.game_code = game_code self.game_code = game_code
self.game_role = role
self.roles = [] # List[Role] self.roles = [] # List[Role]
self.players = [] # List[Player] self.players = [] # List[Player]
@ -48,10 +47,14 @@ class Game:
self.day_count = 0 self.day_count = 0
self.ongoing_vote = False self.ongoing_vote = False
self.game_role = role # discord.Role
self.channel_category = category # discord.CategoryChannel self.channel_category = category # discord.CategoryChannel
self.village_channel = village # discord.TextChannel self.village_channel = village # discord.TextChannel
self.log_channel = log_channel self.log_channel = log_channel
self.to_delete = set()
self.save_perms = {}
self.p_channels = {} # uses default_secret_channel self.p_channels = {} # uses default_secret_channel
self.vote_groups = {} # ID : VoteGroup() self.vote_groups = {} # ID : VoteGroup()
@ -97,14 +100,22 @@ class Game:
if self.game_role is None: if self.game_role is None:
try: try:
self.game_role = await ctx.guild.create_role(name="Players", self.game_role = await ctx.guild.create_role(name="WW Players",
hoist=True, hoist=True,
mentionable=True, mentionable=True,
reason="(BOT) Werewolf game role") reason="(BOT) Werewolf game role")
self.to_delete.add(self.game_role)
except (discord.Forbidden, discord.HTTPException): except (discord.Forbidden, discord.HTTPException):
await ctx.send("Game role not configured and unable to generate one, cannot start") await ctx.send("Game role not configured and unable to generate one, cannot start")
self.roles = [] self.roles = []
return False return False
try:
for player in self.players:
await player.member.add_roles(*[self.game_role])
except discord.Forbidden:
await ctx.send(
"Unable to add role **{}**\nBot is missing `manage_roles` permissions".format(self.game_role.name))
return False
await self.assign_roles() await self.assign_roles()
@ -112,32 +123,54 @@ class Game:
overwrite = { overwrite = {
self.guild.default_role: discord.PermissionOverwrite(read_messages=True, send_messages=False, self.guild.default_role: discord.PermissionOverwrite(read_messages=True, send_messages=False,
add_reactions=False), add_reactions=False),
self.guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True, add_reactions=True), self.guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True, add_reactions=True,
manage_messages=True, manage_channels=True,
manage_roles=True),
self.game_role: discord.PermissionOverwrite(read_messages=True, send_messages=True) self.game_role: discord.PermissionOverwrite(read_messages=True, send_messages=True)
} }
if self.channel_category is None: if self.channel_category is None:
self.channel_category = await self.guild.create_category("🔴 Werewolf Game (ACTIVE)", self.channel_category = await self.guild.create_category("Werewolf Game",
overwrites=overwrite, overwrites=overwrite,
reason="(BOT) New game of werewolf") reason="(BOT) New game of werewolf")
else: else: # No need to modify categories
await self.channel_category.edit(name="🔴 Werewolf Game (ACTIVE)", reason="(BOT) New game of werewolf") pass
for target, ow in overwrite.items(): # await self.channel_category.edit(name="🔴 Werewolf Game (ACTIVE)", reason="(BOT) New game of werewolf")
await self.channel_category.set_permissions(target=target, # for target, ow in overwrite.items():
overwrite=ow, # await self.channel_category.set_permissions(target=target,
reason="(BOT) New game of werewolf") # overwrite=ow,
# reason="(BOT) New game of werewolf")
if self.village_channel is None: if self.village_channel is None:
self.village_channel = await self.guild.create_text_channel("village-square", try:
overwrites=overwrite, self.village_channel = await self.guild.create_text_channel("🔵Werewolf",
reason="(BOT) New game of werewolf", overwrites=overwrite,
category=self.channel_category) reason="(BOT) New game of werewolf",
category=self.channel_category)
except discord.Forbidden:
await ctx.send("Unable to create Game Channel and none was provided\n"
"Grant Bot appropriate permissions or assign a game_channel")
return False
else: else:
await self.village_channel.edit(name="Village Square", self.save_perms[self.village_channel] = self.village_channel.overwrites()
category=self.channel_category, try:
reason="(BOT) New game of werewolf") await self.village_channel.edit(name="🔵Werewolf",
for target, ow in overwrite.items(): category=self.channel_category,
await self.village_channel.set_permissions(target=target, reason="(BOT) New game of werewolf")
overwrite=ow, except discord.Forbidden as e:
reason="(BOT) New game of werewolf") print("Unable to rename Game Channel")
print(e)
await ctx.send("Unable to rename Game Channel, ignoring")
try:
for target, ow in overwrite.items():
curr = self.village_channel.overwrites_for(target)
curr.update(**{perm: value for perm, value in ow})
await self.village_channel.set_permissions(target=target,
overwrite=curr,
reason="(BOT) New game of werewolf")
except discord.Forbidden:
await ctx.send("Unable to edit Game Channel permissions\n"
"Grant Bot appropriate permissions to manage permissions")
return
self.started = True self.started = True
# Assuming everything worked so far # Assuming everything worked so far
print("Pre at_game_start") print("Pre at_game_start")
@ -147,7 +180,9 @@ class Game:
print("Channel id: " + channel_id) print("Channel id: " + channel_id)
overwrite = { overwrite = {
self.guild.default_role: discord.PermissionOverwrite(read_messages=False), self.guild.default_role: discord.PermissionOverwrite(read_messages=False),
self.guild.me: discord.PermissionOverwrite(read_messages=True) self.guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True, add_reactions=True,
manage_messages=True, manage_channels=True,
manage_roles=True)
} }
for player in self.p_channels[channel_id]["players"]: for player in self.p_channels[channel_id]["players"]:
@ -433,7 +468,12 @@ class Game:
self.players.append(Player(member)) self.players.append(Player(member))
await member.add_roles(*[self.game_role]) if self.game_role is not None:
try:
await member.add_roles(*[self.game_role])
except discord.Forbidden:
await channel.send(
"Unable to add role **{}**\nBot is missing `manage_roles` permissions".format(self.game_role.name))
await channel.send("{} has been added to the game, " await channel.send("{} has been added to the game, "
"total players is **{}**".format(member.mention, len(self.players))) "total players is **{}**".format(member.mention, len(self.players)))
@ -744,7 +784,14 @@ class Game:
async def _end_game(self): async def _end_game(self):
# Remove game_role access for potential archiving for now # Remove game_role access for potential archiving for now
reason = '(BOT) End of WW game' reason = '(BOT) End of WW game'
await self.village_channel.set_permissions(self.game_role, overwrite=None, reason=reason) for obj in self.to_delete:
await self.channel_category.set_permissions(self.game_role, overwrite=None, reason=reason) print(obj)
await self.channel_category.edit(reason=reason, name="Werewolf Game (INACTIVE)") await obj.delete(reason=reason)
try:
await self.village_channel.edit(reason=reason, name="Werewolf")
await self.village_channel.set_permissions(self.game_role, overwrite=None, reason=reason)
except (discord.HTTPException, discord.NotFound, discord.errors.NotFound):
pass
# Optional dynamic channels/categories # Optional dynamic channels/categories

@ -1,6 +1,6 @@
import discord import discord
from discord.ext import commands from discord.ext import commands
from redbot.core import Config from redbot.core import Config, checks
from redbot.core import RedContext from redbot.core import RedContext
from redbot.core.bot import Red from redbot.core.bot import Red
@ -8,6 +8,7 @@ from werewolf.builder import GameBuilder, role_from_name, role_from_alignment, r
from werewolf.game import Game from werewolf.game import Game
from werewolf.utils.menus import menu, DEFAULT_CONTROLS from werewolf.utils.menus import menu, DEFAULT_CONTROLS
class Werewolf: class Werewolf:
""" """
Base to host werewolf on a guild Base to host werewolf on a guild
@ -44,6 +45,7 @@ class Werewolf:
else: else:
await ctx.send("No code generated") await ctx.send("No code generated")
@checks.guildowner()
@commands.group() @commands.group()
async def wwset(self, ctx: RedContext): async def wwset(self, ctx: RedContext):
""" """
@ -52,47 +54,80 @@ class Werewolf:
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
await ctx.send_help() await ctx.send_help()
@commands.guild_only()
@wwset.command(name="list")
async def wwset_list(self, ctx: RedContext):
"""
Lists current guild settings
"""
success, role, category, channel, log_channel = await self._get_settings(ctx)
if not success:
await ctx.send("Failed to get settings")
return None
embed = discord.Embed(title="Current Guild Settings")
embed.add_field(name="Role", value=str(role))
embed.add_field(name="Category", value=str(category))
embed.add_field(name="Channel", value=str(channel))
embed.add_field(name="Log Channel", value=str(log_channel))
await ctx.send(embed=embed)
@commands.guild_only() @commands.guild_only()
@wwset.command(name="role") @wwset.command(name="role")
async def wwset_role(self, ctx: RedContext, role: discord.Role): async def wwset_role(self, ctx: RedContext, role: discord.Role=None):
""" """
Assign the game role Assign the game role
This role should not be manually assigned This role should not be manually assigned
""" """
await self.config.guild(ctx.guild).role_id.set(role.id) if role is None:
await ctx.send("Game role has been set to **{}**".format(role.name)) await self.config.guild(ctx.guild).role_id.set(None)
await ctx.send("Cleared Game Role")
else:
await self.config.guild(ctx.guild).role_id.set(role.id)
await ctx.send("Game Role has been set to **{}**".format(role.name))
@commands.guild_only() @commands.guild_only()
@wwset.command(name="category") @wwset.command(name="category")
async def wwset_category(self, ctx: RedContext, category_id): async def wwset_category(self, ctx: RedContext, category_id=None):
""" """
Assign the channel category Assign the channel category
""" """
if category_id is None:
category = discord.utils.get(ctx.guild.categories, id=int(category_id)) await self.config.guild(ctx.guild).category_id.set(None)
if category is None: await ctx.send("Cleared Game Channel Category")
await ctx.send("Category not found") else:
return category = discord.utils.get(ctx.guild.categories, id=int(category_id))
await self.config.guild(ctx.guild).category_id.set(category.id) if category is None:
await ctx.send("Channel Category has been set to **{}**".format(category.name)) await ctx.send("Category not found")
return
await self.config.guild(ctx.guild).category_id.set(category.id)
await ctx.send("Game Channel Category has been set to **{}**".format(category.name))
@commands.guild_only() @commands.guild_only()
@wwset.command(name="channel") @wwset.command(name="channel")
async def wwset_channel(self, ctx: RedContext, channel: discord.TextChannel): async def wwset_channel(self, ctx: RedContext, channel: discord.TextChannel=None):
""" """
Assign the village channel Assign the village channel
""" """
await self.config.guild(ctx.guild).channel_id.set(channel.id) if channel is None:
await ctx.send("Game Channel has been set to **{}**".format(channel.mention)) await self.config.guild(ctx.guild).channel_id.set(None)
await ctx.send("Cleared Game Channel")
else:
await self.config.guild(ctx.guild).channel_id.set(channel.id)
await ctx.send("Game Channel has been set to **{}**".format(channel.mention))
@commands.guild_only() @commands.guild_only()
@wwset.command(name="logchannel") @wwset.command(name="logchannel")
async def wwset_log_channel(self, ctx: RedContext, channel: discord.TextChannel): async def wwset_log_channel(self, ctx: RedContext, channel: discord.TextChannel=None):
""" """
Assign the log channel Assign the log channel
""" """
await self.config.guild(ctx.guild).log_channel_id.set(channel.id) if channel is None:
await ctx.send("Log Channel has been set to **{}**".format(channel.mention)) await self.config.guild(ctx.guild).log_channel_id.set(None)
await ctx.send("Cleared Game Log Channel")
else:
await self.config.guild(ctx.guild).log_channel_id.set(channel.id)
await ctx.send("Game Log Channel has been set to **{}**".format(channel.mention))
@commands.group() @commands.group()
async def ww(self, ctx: RedContext): async def ww(self, ctx: RedContext):
@ -165,7 +200,8 @@ class Werewolf:
if not game: if not game:
await ctx.send("No game running, cannot start") await ctx.send("No game running, cannot start")
await game.setup(ctx) if not await game.setup(ctx):
pass # Do something?
@commands.guild_only() @commands.guild_only()
@ww.command(name="stop") @ww.command(name="stop")
@ -305,36 +341,11 @@ class Werewolf:
return None return None
if guild.id not in self.games or self.games[guild.id].game_over: if guild.id not in self.games or self.games[guild.id].game_over:
await ctx.send("Starting a new game...") await ctx.send("Starting a new game...")
role = None success, role, category, channel, log_channel = await self._get_settings(ctx)
category = None
channel = None if not success:
log_channel = None await ctx.send("Cannot start a new game")
return None
role_id = await self.config.guild(guild).role_id()
category_id = await self.config.guild(guild).category_id()
channel_id = await self.config.guild(guild).channel_id()
log_channel_id = await self.config.guild(guild).log_channel_id()
if role_id is not None:
role = discord.utils.get(guild.roles, id=role_id)
if role is None:
await ctx.send("Game Role is invalid, cannot start new game")
return None
if category_id is not None:
category = discord.utils.get(guild.categories, id=category_id)
if category is None:
await ctx.send("Game Category is invalid, cannot start new game")
return None
if channel_id is not None:
channel = discord.utils.get(guild.text_channels, id=channel_id)
if channel is None:
await ctx.send("Village Channel is invalid, cannot start new game")
return None
if log_channel_id is not None:
log_channel = discord.utils.get(guild.text_channels, id=log_channel_id)
if log_channel is None:
await ctx.send("Log Channel is invalid, cannot start new game")
return None
self.games[guild.id] = Game(guild, role, category, channel, log_channel, game_code) self.games[guild.id] = Game(guild, role, category, channel, log_channel, game_code)
@ -342,3 +353,38 @@ class Werewolf:
async def _game_start(self, game): async def _game_start(self, game):
await game.start() await game.start()
async def _get_settings(self, ctx):
guild = ctx.guild
role = None
category = None
channel = None
log_channel = None
role_id = await self.config.guild(guild).role_id()
category_id = await self.config.guild(guild).category_id()
channel_id = await self.config.guild(guild).channel_id()
log_channel_id = await self.config.guild(guild).log_channel_id()
if role_id is not None:
role = discord.utils.get(guild.roles, id=role_id)
if role is None:
await ctx.send("Game Role is invalid")
return False, None, None, None, None
if category_id is not None:
category = discord.utils.get(guild.categories, id=category_id)
if category is None:
await ctx.send("Game Category is invalid")
return False, None, None, None, None
if channel_id is not None:
channel = discord.utils.get(guild.text_channels, id=channel_id)
if channel is None:
await ctx.send("Village Channel is invalid")
return False, None, None, None, None
if log_channel_id is not None:
log_channel = discord.utils.get(guild.text_channels, id=log_channel_id)
if log_channel is None:
await ctx.send("Log Channel is invalid")
return False, None, None, None, None
return True, role, category, channel, log_channel
Loading…
Cancel
Save