Errors and permissions
This commit is contained in:
parent
5694a61edb
commit
d206ea2cb9
105
werewolf/game.py
105
werewolf/game.py
@ -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
|
||||
success, role, category, channel, log_channel = await self._get_settings(ctx)
|
||||
|
||||
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
|
||||
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…
x
Reference in New Issue
Block a user