from typing import Dict, Callable, List, Union import discord import logging logger = logging.getLogger(__name__) class Game: """ Game state for one guild """ def __init__(self, config_dict: Dict, save_function: Callable): self.config = config_dict self.save_function = save_function @staticmethod def new_dict(): return { "game_started": False, } def is_started(self): return self.config["game_started"] def get_players(self) -> List[int]: return self.config["players"] def get_player_info(self, player: Union[int, discord.Member]): if isinstance(player, discord.Member): player = player.id return self.config["player_info"][str(player)] def get_dm_role(self) -> int: return self.config["dm_role"] def get_game_category(self) -> int: return self.config["category"] async def start(self, guild: discord.Guild, dm_role: discord.Role, player_role: discord.Role): if self.is_started(): raise ValueError("Game already started") logger.info(f"[{guild.name}] Starting game") self.config["dm_role"] = dm_role.id self.config["player_role"] = player_role.id self.config["players"] = [member.id for member in player_role.members] self.config["player_info"] = {str(player): {} for player in self.config["players"]} permissions = { guild.default_role: discord.PermissionOverwrite(send_messages = False), dm_role: discord.PermissionOverwrite(send_messages = True), player_role: discord.PermissionOverwrite(send_messages = True), } game_category = await guild.create_category("In-game", overwrites = permissions) self.config["category"] = game_category.id logger.debug(f"[{guild.name}] Created game category") permissions = { guild.default_role: discord.PermissionOverwrite(read_messages = False), dm_role: discord.PermissionOverwrite(read_messages = True), } self.config["admin_chan"] = (await game_category.create_text_channel("admin", overwrites = permissions)).id logger.debug(f"[{guild.name}] Created admin channel") permissions = { guild.default_role: discord.PermissionOverwrite(send_messages = False), dm_role: discord.PermissionOverwrite(send_messages = True), } self.config["announce_chan"] = (await game_category.create_text_channel("announce", overwrites = permissions)).id self.config["votes_chan"] = (await game_category.create_text_channel("votes", overwrites = permissions)).id logger.debug(f"[{guild.name}] Created announcements and votes channels") self.config["discussion_chan"] = (await game_category.create_text_channel("discussion")).id # Permissions are inherited from the category logger.debug(f"[{guild.name}] Created discussion channel") for player in self.get_players(): player_member: discord.Member = guild.get_member(player) channel_permissions = { guild.default_role: discord.PermissionOverwrite(read_messages = False), player_member: discord.PermissionOverwrite(read_messages = True), dm_role: discord.PermissionOverwrite(read_messages = True), } player_channel = await game_category.create_text_channel(player_member.name, overwrites = channel_permissions) self.get_player_info(player)["channel"] = player_channel.id logger.debug(f"[{guild.name}] Created player channels") self.config["game_started"] = True self.save_function() async def delete(self, guild: discord.Guild): category = guild.get_channel(self.get_game_category()) for channel in category.channels: await channel.delete() await category.delete() self.config.clear() self.config.update(self.new_dict()) self.save_function()