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
|
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
|
|
||||||
log_channel = None
|
|
||||||
|
|
||||||
role_id = await self.config.guild(guild).role_id()
|
if not success:
|
||||||
category_id = await self.config.guild(guild).category_id()
|
await ctx.send("Cannot start a new game")
|
||||||
channel_id = await self.config.guild(guild).channel_id()
|
return None
|
||||||
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…
x
Reference in New Issue
Block a user