import os from dotenv import load_dotenv import functools import asyncio import discord from discord.ext import commands from werewolf_game import Game as Werewolf_Game load_dotenv() TOKEN = os.getenv('DISCORD_TOKEN') if TOKEN is None: print("Missing discord token!") exit(1) PREFIX = '$w ' bot = commands.Bot(command_prefix=commands.when_mentioned_or(PREFIX)) bot.remove_command('help') @bot.event async def on_ready(): await bot.change_presence(status=discord.Status.online, activity=discord.Game('One Night Ultimate Werewolf')) print('We have logged in as {0.user}'.format(bot)) @bot.command() async def help(ctx): embed = discord.Embed(title="How to play?", description="You will need to set up the game and its information in a channel and start the game there. Afterwards the player mainly interact with the bot in DM.", color=0x00ffff) embed.set_author(name="With this bot you can play One Night Ultimate Werewolf") # embed.set_thumbnail(url="https://images-na.ssl-images-amazon.com/images/I/717GrDtFKCL._AC_SL1000_.jpg") embed.add_field(name="$w game setup", value="Make this channel playable.", inline=False) embed.add_field(name="$w game players", value="Set mentioned users as players", inline=False) embed.add_field(name="$w game roles", value="Set the roles to play with", inline=False) embed.add_field(name="$w game start", value="Play one round", inline=False) embed.set_footer(text="Have fun!") await ctx.send(embed=embed) async def send_embed(ctx, desc, color): await ctx.send(embed=discord.Embed(description=desc, color=color)) async def send_friendly(ctx, desc): await send_embed(ctx, desc, 0x00ff00) async def send_wrong(ctx, desc): await send_embed(ctx, desc, 0xff8000) # game commands game_instances = {} @bot.group() async def game(ctx): if ctx.invoked_subcommand is None: await send_wrong(ctx, 'Invalid sub command passed...') @game.command() async def setup(ctx): if ctx.channel in game_instances: await send_wrong(ctx, "Game already setup in this channel") else: game_instances[ctx.channel] = Werewolf_Game(bot, ctx.channel) await send_friendly(ctx, "This channel can now play Werewolf") def channel_setup(command): @functools.wraps(command) async def wrapper(ctx, *args, **kwargs): if ctx.channel not in game_instances: await send_wrong(ctx, f"No game setup yet. Use {PREFIX}game setup") else: await command(ctx, *args, **kwargs) return wrapper def game_not_running(command): @functools.wraps(command) @channel_setup async def wrapper(ctx, *args, **kwargs): if game_instances[ctx.channel].running: await send_wrong(ctx, "Sorry! A game is already running") else: await command(ctx, *args, **kwargs) return wrapper def game_running(command): @functools.wraps(command) @channel_setup async def wrapper(ctx, *args, **kwargs): if not game_instances[ctx.channel].running: await send_wrong(ctx, "No game is running") else: await command(ctx, *args, **kwargs) return wrapper def error_handling(command): @functools.wraps(command) async def wrapper(ctx, *args, **kwargs): try: await command(ctx, *args, **kwargs) except ValueError as error: await send_wrong(ctx, str(error)) except asyncio.TimeoutError: await send_wrong(ctx, "Error: I got bored waiting for your input") return wrapper @game.command() @game_not_running @error_handling async def start(ctx): game_instances[ctx.channel].game = bot.loop.create_task(game_instances[ctx.channel].round()) await game_instances[ctx.channel].game @game.command() @game_running @channel_setup async def stop(ctx): game_instances[ctx.channel].game.cancel() await send_friendly(ctx, "Game canceled") @game.command() @game_not_running @error_handling async def players(ctx): await game_instances[ctx.channel].set_players(ctx.message) @game.command() @game_not_running @error_handling async def roles(ctx, *args): await game_instances[ctx.channel].set_roles(args) @game.command() @game_not_running @error_handling async def minutes(ctx, i): await game_instances[ctx.channel].set_time(i) @game.command() @game_running @error_handling async def time(ctx): await send_friendly(ctx, game_instances[ctx.channel].remaining_time_string()) # smaller commands @bot.command() async def hello(ctx): await send_friendly(ctx, f"Hello {ctx.message.author.name} :wave:") @bot.command() async def ping(ctx): print("pong") await send_friendly(ctx, "pong") # developer commands def developer(command): @functools.wraps(command) async def wrapper(ctx, *args, **kwargs): DEV_ID = 461892912821698562 if ctx.author.id == DEV_ID: await command(ctx, *args, **kwargs) else: await send_wrong(ctx, "This command is not for you!") return wrapper @bot.command() @developer async def logout(ctx): await bot.logout() @bot.command() @developer async def debug(ctx, *args): print("DEBUG") print(ctx.args) print(ctx.kwargs) bot.run(TOKEN)