diff options
Diffstat (limited to 'commands.py')
-rw-r--r-- | commands.py | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/commands.py b/commands.py new file mode 100644 index 0000000..e463b98 --- /dev/null +++ b/commands.py @@ -0,0 +1,107 @@ +import asyncio +from typing import Any, List +import random +from time import sleep + +import config + +from discord.ext import commands + + +async def await_n(it) -> List[Any]: + lst = [asyncio.create_task(task) for task in it] + if not lst: + return [] + done, _ = await asyncio.wait(lst) + return [task.result() for task in done] + + +async def answer(ctx: commands.Context, msg: str): + await ctx.send(f'{ctx.author.mention} {msg}') + + +@commands.command(help='display this help message', aliases=('hepl', 'h', '?')) +async def help(ctx: commands.Context): + command_doc = '\n'.join( + f' * {config.COMMAND_PREFIX.strip()} {c.name:15} - {c.help}' + for c in ctx.bot.commands) + await answer(ctx, f'''``` +{config.HELP_TEXT}\nThese are all available commands:\n{command_doc}```''') + + +@commands.command(help='create a new lobby', aliases=('create', 'inti', 'craete', 'cretae', 'c', 'i', '+')) +async def init(ctx: commands.Context): + ctx.bot.meta_channel = ctx.bot.get_meta_channel(ctx) or await ctx.bot.create_category(ctx) + ctx.bot.lobby_channel = ctx.bot.get_lobby_channel(ctx, ctx.bot.meta_channel) or await ctx.bot.create_lobby(ctx) + + +@commands.command(help=f'destruct all {config.NAME} channels', aliases=('kill', 'desctruction', 'genocide', '-')) +async def destroy(ctx: commands.Context): + futures = [] + meta_channel = ctx.bot.get_meta_channel(ctx) + for channel in (ctx.bot.get_lobby_channel(ctx, meta_channel), meta_channel): + if channel: + futures.append(channel.delete()) + await await_n(futures) + ctx.bot.lobby_channel = None + ctx.bot.meta_channel = None + ctx.bot.pair_channels = [] + + +@commands.command(help='start shuffling', aliases=('start', 'run', 'strat', 'rnu')) +async def shuffle(ctx: commands.Context): + channels = await ctx.bot.get_channels(ctx) + if not channels: + return + meta_channel, lobby_channel = channels + members = lobby_channel.members[:] + slots = len(members) >> 1 + ctx.bot.pair_channels = await ctx.bot.create_pair_channels(ctx, meta_channel, slots) + slots = [] + for i, _ in enumerate(ctx.bot.pair_channels): + slots.append(i) + slots.append(i) + random.shuffle(slots) + futures = [] + for slot in slots: + member = members.pop() + if member is None: break + futures.append(member.move_to(ctx.bot.pair_channels[slot])) + if members: + futures.append(members.pop().move_to(random.choice(ctx.bot.pair_channels))) + await await_n(futures) + + +@commands.command(help='move everyone back to lobby', aliases=('quit', 'exit', 'abort', 'back', 'return')) +async def stop(ctx: commands.Context): + channels = await ctx.bot.get_channels(ctx) + if not channels: + return + meta_channel, lobby_channel = channels + pair_channels = ctx.bot.get_pair_channels(ctx, meta_channel) + futures = [] + for channel in pair_channels: + for member in channel.members: + futures.append(member.move_to(lobby_channel)) + await await_n(futures) + await ctx.bot.destroy_pair_channels(ctx, meta_channel) + + +@commands.command(help='repeat "shuffle" and "stop" <n> (default: 3) times and <t> (default: 120) seconds') +async def loop(ctx: commands.Context, *args): + if len(args) >= 1 and args[0].isdigit(): + n = int(args[0]) + else: + n = 3 + if len(args) >= 2 and args[1].isdigit(): + t = int(ctx.args[1]) + else: + t = 120 + await answer(ctx, f'repeat shuffling {n} times and each {t} seconds') + for _ in range(n): + await shuffle(ctx) + sleep(t) + await stop(ctx) + + +bot_commands = [cmd for cmd in locals().values() if isinstance(cmd, commands.Command)] |