Errors and permissions

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

@ -26,12 +26,11 @@ class Game:
day_vote_count = 3
def __init__(self, guild: discord.Guild, role: discord.Role=None,
category: discord.CategoryChannel=None, village: discord.TextChannel=None,
log_channel: discord.TextChannel=None, game_code=None):
def __init__(self, guild: discord.Guild, role: discord.Role = None,
category: discord.CategoryChannel = None, village: discord.TextChannel = None,
log_channel: discord.TextChannel = None, game_code=None):
self.guild = guild
self.game_code = game_code
self.game_role = role
self.roles = [] # List[Role]
self.players = [] # List[Player]
@ -48,10 +47,14 @@ class Game:
self.day_count = 0
self.ongoing_vote = False
self.game_role = role # discord.Role
self.channel_category = category # discord.CategoryChannel
self.village_channel = village # discord.TextChannel
self.log_channel = log_channel
self.to_delete = set()
self.save_perms = {}
self.p_channels = {} # uses default_secret_channel
self.vote_groups = {} # ID : VoteGroup()
@ -97,14 +100,22 @@ class Game:
if self.game_role is None:
try:
self.game_role = await ctx.guild.create_role(name="Players",
self.game_role = await ctx.guild.create_role(name="WW Players",
hoist=True,
mentionable=True,
reason="(BOT) Werewolf game role")
self.to_delete.add(self.game_role)
except (discord.Forbidden, discord.HTTPException):
await ctx.send("Game role not configured and unable to generate one, cannot start")
self.roles = []
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()
@ -112,32 +123,54 @@ class Game:
overwrite = {
self.guild.default_role: discord.PermissionOverwrite(read_messages=True, send_messages=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)
}
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,
reason="(BOT) New game of werewolf")
else:
await self.channel_category.edit(name="🔴 Werewolf Game (ACTIVE)", reason="(BOT) New game of werewolf")
for target, ow in overwrite.items():
await self.channel_category.set_permissions(target=target,
overwrite=ow,
reason="(BOT) New game of werewolf")
else: # No need to modify categories
pass
# await self.channel_category.edit(name="🔴 Werewolf Game (ACTIVE)", reason="(BOT) New game of werewolf")
# for target, ow in overwrite.items():
# await self.channel_category.set_permissions(target=target,
# overwrite=ow,
# reason="(BOT) New game of werewolf")
if self.village_channel is None:
self.village_channel = await self.guild.create_text_channel("village-square",
overwrites=overwrite,
reason="(BOT) New game of werewolf",
category=self.channel_category)
try:
self.village_channel = await self.guild.create_text_channel("🔵Werewolf",
overwrites=overwrite,
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:
await self.village_channel.edit(name="Village Square",
category=self.channel_category,
reason="(BOT) New game of werewolf")
for target, ow in overwrite.items():
await self.village_channel.set_permissions(target=target,
overwrite=ow,
reason="(BOT) New game of werewolf")
self.save_perms[self.village_channel] = self.village_channel.overwrites()
try:
await self.village_channel.edit(name="🔵Werewolf",
category=self.channel_category,
reason="(BOT) New game of werewolf")
except discord.Forbidden as e:
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
# Assuming everything worked so far
print("Pre at_game_start")
@ -147,7 +180,9 @@ class Game:
print("Channel id: " + channel_id)
overwrite = {
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"]:
@ -433,7 +468,12 @@ class Game:
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, "
"total players is **{}**".format(member.mention, len(self.players)))
@ -744,7 +784,14 @@ class Game:
async def _end_game(self):
# Remove game_role access for potential archiving for now
reason = '(BOT) End of WW game'
await self.village_channel.set_permissions(self.game_role, overwrite=None, reason=reason)
await self.channel_category.set_permissions(self.game_role, overwrite=None, reason=reason)
await self.channel_category.edit(reason=reason, name="Werewolf Game (INACTIVE)")
for obj in self.to_delete:
print(obj)
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

@ -1,6 +1,6 @@
import discord
from discord.ext import commands
from redbot.core import Config
from redbot.core import Config, checks
from redbot.core import RedContext
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.utils.menus import menu, DEFAULT_CONTROLS
class Werewolf:
"""
Base to host werewolf on a guild
@ -44,6 +45,7 @@ class Werewolf:
else:
await ctx.send("No code generated")
@checks.guildowner()
@commands.group()
async def wwset(self, ctx: RedContext):
"""
@ -52,47 +54,80 @@ class Werewolf:
if ctx.invoked_subcommand is None:
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()
@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
This role should not be manually assigned
"""
await self.config.guild(ctx.guild).role_id.set(role.id)
await ctx.send("Game role has been set to **{}**".format(role.name))
if role is None:
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()
@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
"""
category = discord.utils.get(ctx.guild.categories, id=int(category_id))
if category is None:
await ctx.send("Category not found")
return
await self.config.guild(ctx.guild).category_id.set(category.id)
await ctx.send("Channel Category has been set to **{}**".format(category.name))
if category_id is None:
await self.config.guild(ctx.guild).category_id.set(None)
await ctx.send("Cleared Game Channel Category")
else:
category = discord.utils.get(ctx.guild.categories, id=int(category_id))
if category is None:
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()
@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
"""
await self.config.guild(ctx.guild).channel_id.set(channel.id)
await ctx.send("Game Channel has been set to **{}**".format(channel.mention))
if channel is None:
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()
@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
"""
await self.config.guild(ctx.guild).log_channel_id.set(channel.id)
await ctx.send("Log Channel has been set to **{}**".format(channel.mention))
if channel is None:
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()
async def ww(self, ctx: RedContext):
@ -165,7 +200,8 @@ class Werewolf:
if not game:
await ctx.send("No game running, cannot start")
await game.setup(ctx)
if not await game.setup(ctx):
pass # Do something?
@commands.guild_only()
@ww.command(name="stop")
@ -305,36 +341,11 @@ class Werewolf:
return None
if guild.id not in self.games or self.games[guild.id].game_over:
await ctx.send("Starting a new game...")
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, 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
success, role, category, channel, log_channel = await self._get_settings(ctx)
if not success:
await ctx.send("Cannot start a new game")
return None
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):
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