Example #1
0
    async def toggle_key(
            self, message: Message, room1: str, room2: str, user: str
    ):
        connection = self.roleplay.get_connection(room1, room2)
        if not connection:
            await message.channel.send(
                f'No connection from {room1} to {room2}.'
            )
            return

        config = State.get_config(message.guild.id)
        keys = config['connections'][connection.name]['k']
        for member in message.mentions:
            if member.id not in keys:
                keys.append(member.id)
                await message.channel.send(
                    f'{member.mention} can now lock and unlock the connection '
                    f'from {room1} to {room2}.'
                )
            else:
                keys.remove(member.id)
                await message.channel.send(
                    f'{member.mention} can no longer lock and unlock the '
                    f'connection from {room1} to {room2}.'
                )
        State.save_config(message.guild.id, config)
        await self.bot.save_guild_config(message.guild, config)
        await message.delete()
Example #2
0
    async def start_game(self, message: Message, roleplay: str, players: str):
        config = State.get_config(message.guild.id)
        if config and 'rp' in config and config['rp']:
            await message.channel.send(
                f'Cannot start roleplay, {config["rp"]} is already in progress.'
            )
            return

        if roleplay not in self.bot.roleplays:
            await message.channel.send(
                f'Cannot start roleplay, unknown roleplay name {roleplay}'
            )
            return

        loading_message = await message.channel.send(f'Setting up new game...')
        config = {'rp': roleplay, 'connections': {}}
        await self.bot.save_guild_config(message.guild, config)
        await self.bot.refresh_from_config(message.guild, config, True)
        await message.author.add_roles(State.get_admin_role(message.guild.id))

        self.roleplay = self.bot.roleplays[roleplay]
        player_role = State.get_player_role(message.guild.id)
        for member in message.mentions:
            await member.add_roles(player_role)
        await self.move_force(message, self.roleplay.starting_room, None)

        await message.channel.send(f'The game begins.')
        await loading_message.delete()
        await message.delete()
Example #3
0
    async def hide(self, message: Message, location: str):
        config = State.get_config(message.guild.id)
        channel: TextChannel = message.channel
        connection = self.roleplay.get_connection(channel.name, location)
        if not connection:
            await channel.send(
                f'No connection from {channel.name} to {location}.',
                delete_after=60*60
            )
            return

        is_hidden = config['connections'][connection.name].get('h', False)
        if is_hidden:
            await channel.send(
                f'Connection from {channel.name} to {location} is already '
                'hidden.',
                delete_after=60*60
            )
        else:
            config['connections'][connection.name]['h'] = True
            State.save_config(message.guild.id, config)
            await self.bot.save_guild_config(message.guild, config)
            text = f'A connection between {channel.name} and {location} has ' \
                   f'been hidden.'
            await channel.send(text)
            await message.delete()
            await self.bot.get_chronicle(message.guild).log_announcement(
                channel, text
            )
Example #4
0
 async def view_remove(self, message: Message, room: str) -> None:
     config = State.get_config(message.guild.id)
     if 'views' not in config:
         config['views'] = {}
     if room in config['views'] \
             and message.channel.name in config['views'][room]:
         config['views'][room].remove(message.channel.name)
         await self.bot.save_guild_config(message.guild, config)
         await message.channel.send(f'Remote view to {room} removed.')
     else:
         await message.channel.send(
             f'No remote view to {room} set up in this channel.'
         )
Example #5
0
 async def view_add(self, message: Message, room: str) -> None:
     config = State.get_config(message.guild.id)
     if 'views' not in config:
         config['views'] = {}
     if room not in config['views']:
         config['views'][room] = []
     if message.channel.name not in config['views'][room]:
         config['views'][room].append(message.channel.name)
         await self.bot.save_guild_config(message.guild, config)
         await message.channel.send(f'Remote view to {room} added.')
     else:
         await message.channel.send(
             f'There is already a remote view to {room} in this channel.'
         )
Example #6
0
 async def view_list(self, message: Message) -> None:
     config = State.get_config(message.guild.id)
     all_views = []
     for user_id, views in config.get('views', {}).items():
         user: Member = message.guild.get_member(user_id)
         if user and views:
             all_views.append(
                 f'**{user.display_name}:** ' + ', '.join(views)
             )
     if all_views:
         await message.channel.send(
             'The following remote views are set up:\n'
             + '\n'.join(all_views)
         )
     else:
         await message.channel.send('No remote views are set up.')
Example #7
0
    async def _lock_or_unlock(
            self, message: Message, location: str, lock: bool = True
    ):
        config = State.get_config(message.guild.id)
        channel: TextChannel = message.channel
        connection = self.roleplay.get_connection(channel.name, location)
        if not connection:
            await channel.send(
                f'No connection from {channel.name} to {location}.',
                delete_after=60*60
            )
            return
        connection_config = config['connections'][connection.name]

        if not State.is_admin(message.author) \
                and message.author.id not in connection_config['k']:
            await channel.send(
                f'{message.author.mention} does not have the key to '
                f'{location}.',
                delete_after=60*60
            )
            return

        locked = connection_config['l']
        if locked and lock or not locked and not lock:
            await channel.send(
                f'Access to {location} is already '
                f'{"locked" if lock else "unlocked"}.',
                delete_after=60*60
            )
            return
        self._update_connection(
            config["connections"], channel.name, location, locked=lock
        )
        State.save_config(message.guild.id, config)
        await self.bot.save_guild_config(message.guild, config)
        await channel.send(
            f'{"Locked" if lock else "Unlocked"} access to {location}.'
        )
        await message.delete()
        name = 'the GM' \
            if State.is_admin(message.author) else message.author.display_name
        await self.bot.get_chronicle(message.guild).log_announcement(
            channel,
            f'Access from **{message.channel.name}** to **{location}** '
            f'{"" if lock else "un"}locked by **{name}**'
        )
Example #8
0
async def global_variables(request: Request):
    bot: RoleplayBot = request.app['bot']
    roleplays = []
    for guild in bot.guilds:
        if bot.get_roleplay_for_guild(guild.id):
            roleplays.append({'id': guild.id, 'name': guild.name})

    try:
        guild_id = int(request.match_info['guild_id'])
    except (KeyError, ValueError):
        guild_id = None
    roleplay = None
    if guild_id is not None:
        config = State.get_config(guild_id)
        roleplay_data = bot.get_roleplay_for_guild(guild_id)
        if roleplay_data:
            guild = bot.get_guild(guild_id)
            roleplay = {
                'id':
                guild_id,
                'name':
                guild.name,
                'description':
                roleplay_data.description,
                'characters': [{
                    'user_id': user_id,
                    'id': character_id,
                    **character,
                }
                               for user_id, user_characters in config.get(
                                   'characters', {}).items()
                               for character_id, character in
                               user_characters['characters'].items()],
                'commands': [
                    command for plugin in bot.get_all_plugins(guild)
                    for command in sorted(plugin.commands.values(),
                                          key=lambda c: c.name)
                    if command.enabled and not command.requires_admin
                    and not command.hidden
                ]
            }
    return {
        'base_url': bot_config['rpbot']['base_url'],
        'roleplay': roleplay,
        'roleplays': sorted(roleplays, key=itemgetter('name')),
    }
Example #9
0
 async def log(
     self,
     source_channel: Optional[str],
     message: str,
     extra_only: bool = False,
 ) -> None:
     config = State.get_config(self.guild.id)
     if not config:
         return
     views = config.get('views', {})
     dest_channels = set() if extra_only else {self.channel_name}
     if source_channel in views:
         dest_channels.update(views[source_channel])
     for channel in self.guild.text_channels:
         if channel.name in dest_channels:
             await channel.send(message[:MAX_MESSAGE_LENGTH])
             if message[MAX_MESSAGE_LENGTH:]:
                 await channel.send(message[MAX_MESSAGE_LENGTH:])
Example #10
0
async def character(request: Request):
    try:
        guild_id = int(request.match_info['guild_id'])
    except (KeyError, ValueError):
        guild_id = None
    char = None
    if guild_id is not None:
        user_id = request.match_info['user_id']
        character_id = request.match_info['character_id']
        config = State.get_config(guild_id)
        characters_data = config.get('characters', {})
        char = characters_data.get(user_id, {}).get('characters',
                                                    {}).get(character_id)
        if char:
            move_timers = State.get_var(guild_id, 'move_timers')
            move_countdown_time = None
            if move_timers:
                move_countdown_time = move_timers.get(int(user_id))
            char = {
                **char, "move_countdown_time":
                move_countdown_time.astimezone().isoformat()
                if move_countdown_time else ""
            }
    return {'character': char}
Example #11
0
 async def reload(self, message: Message) -> None:
     self.bot.reload()
     await self.bot.refresh_from_config(
         message.guild, State.get_config(message.guild.id)
     )
     await message.channel.send('Roleplay definition and plugins reloaded.')
Example #12
0
    async def move(self, message: Message, room: Optional[str]):
        connections = State.get_config(message.guild.id)['connections']
        channel: TextChannel = message.channel
        destinations = self._list_destinations(connections, channel.name)

        if not room:
            destination_list = '\n'.join(
                destination + (' *(locked)*' if locked else '')
                for destination, locked in destinations
            )
            await channel.send(
                (
                    'The following destinations are available from here:\n'
                    + destination_list
                ) if destination_list
                else 'No destinations are currently available.',
                delete_after=60*60
            )
            await message.delete()
            return

        for destination, locked in destinations:
            if destination == room:
                if locked:
                    await channel.send(
                        f'{room} is currently locked off.',
                        delete_after=60*60
                    )
                    await message.delete()
                    return
                break
        else:
            await channel.send(
                f'Cannot reach {room} from here.',
                delete_after=60*60
            )
            return

        move_timers = State.get_var(message.guild.id, 'move_timers')
        if not move_timers:
            move_timers = defaultdict(lambda: datetime.min)
        time_remaining = (
                move_timers[message.author.id] - datetime.now()
        ).total_seconds()
        if time_remaining > 0:
            minutes = time_remaining // 60
            await channel.send(
                'Must wait '
                + (
                    f'{int(minutes)} minutes' if minutes
                    else f'{int(time_remaining)} seconds'
                )
                + ' before moving again.',
                delete_after=60*60
            )
            return

        connection = self.roleplay.get_connection(channel.name, room)
        new_channel = await self._move_player(
            message.author, room, message.channel
        )
        move_timers[message.author.id] = datetime.now() + timedelta(
            minutes=connection.timer
        )
        State.set_var(message.guild.id, 'move_timers', move_timers)
        await channel.send(f'{message.author.mention} moves to {room}')
        await new_channel.send(
            f'{message.author.mention} moves in from {channel.name}'
        )
        await message.delete()
Example #13
0
 def get_roleplay_for_guild(self, guild_id: int):
     config = State.get_config(guild_id)
     return self.roleplays[config['rp']] \
         if config and 'rp' in config and config['rp'] else None
Example #14
0
 def _get_config(guild: Guild) -> Dict[str, Any]:
     config = State.get_config(guild.id)
     if not config or not config.get('rp'):
         raise CommandException(
             'No active roleplay, characters not available.')
     return config
Example #15
0
 async def _save_config(self, guild: Guild) -> None:
     await self.bot.save_guild_config(guild, State.get_config(guild.id))