commands instead of on_message

This commit is contained in:
Bibin Muttappillil 2020-04-12 23:01:47 +02:00
parent eaf1686c5d
commit 7495336269
4 changed files with 79 additions and 69 deletions

View File

@ -13,7 +13,8 @@ if TOKEN is None:
print("Missing discord token!") print("Missing discord token!")
exit(1) exit(1)
bot = commands.Bot(command_prefix=commands.when_mentioned_or('$werewolf ')) PREFIX = '$w '
bot = commands.Bot(command_prefix=commands.when_mentioned_or(PREFIX))
@bot.event @bot.event
@ -22,34 +23,70 @@ async def on_ready():
print('We have logged in as {0.user}'.format(bot)) print('We have logged in as {0.user}'.format(bot))
@bot.event # game commands
async def on_message(message):
if message.author == bot.user: game_instances = {}
return
await bot.process_commands(message)
@bot.group(help="werewolf game", description="Prefix for the One Night Ultimate Werewolf commands.") @bot.group(help="werewolf game", description="Prefix for the One Night Ultimate Werewolf commands.")
async def game(ctx): async def game(ctx):
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
await bot.say('Invalid sub command passed...') await ctx.send('Invalid sub command passed...')
@game.command(help="start werewolf game", description="Start One Night Ultimate Werewolf game.") @game.command(help="start werewolf game", description="Start One Night Ultimate Werewolf game.")
async def setup(ctx):
if ctx.channel in game_instances:
await ctx.send("Game already setup in this channel")
else:
game_instances[ctx.channel] = Werewolf_Game(bot, ctx.channel)
def game_running(command):
@functools.wraps(command)
async def wrapper(ctx):
if ctx.channel not in game_instances:
await ctx.send(f"No game setup yet. Use {PREFIX}game setup")
elif game_instances[ctx.channel].running:
await ctx.send("Sorry! A game is already running")
else:
await command(ctx)
return wrapper
@game.command(help="start a round", description="Play one round of One Night Ultimate Werewolf")
@game_running
async def start(ctx): async def start(ctx):
if werewolf_game.running: await game_instances[ctx.channel].game()
await ctx.message.channel.send("Sorry! A game is already running")
return
werewolf_game.running = True
werewolf_game.set_channel(ctx.message.channel)
await werewolf_game.game() @game.command(help="set players", description="Set the players for the next round.")
@game_running
async def players(ctx):
await game_instances[ctx.channel].set_players(ctx.message)
@game.command(help="set roles", description="Set the roles for the next round.")
@game_running
async def roles(ctx):
try:
await game_instances[ctx.channel].set_roles(ctx.message.content.split()[3:])
except ValueError as error:
await ctx.send(error)
# ONLY FOR TESTING
@game.command()
@game_running
async def vote(ctx):
await game_instances[ctx.channel].vote()
# smaller commands
@bot.command(help="greets you", description="This just says hello back to the message author.") @bot.command(help="greets you", description="This just says hello back to the message author.")
async def hello(ctx): async def hello(ctx):
await ctx.message.channel.send(f"Hello {ctx.message.author.name} :wave:") await ctx.send(f"Hello {ctx.message.author.name} :wave:")
@bot.command(help="test bot responsiveness", description="This is a debug function to see if the bot listens to a command.") @bot.command(help="test bot responsiveness", description="This is a debug function to see if the bot listens to a command.")
@ -58,11 +95,14 @@ async def ping(ctx):
await ctx.send("pong") await ctx.send("pong")
# developer commands
def developer(command): def developer(command):
@functools.wraps(command) @functools.wraps(command)
async def wrapper(ctx): async def wrapper(ctx):
DEV_ID = 461892912821698562 DEV_ID = 461892912821698562
if ctx.message.author.id == DEV_ID: if ctx.author.id == DEV_ID:
await command(ctx) await command(ctx)
else: else:
await ctx.send("This command is not for you!") await ctx.send("This command is not for you!")
@ -81,6 +121,4 @@ async def debug(ctx):
print("DEBUG") print("DEBUG")
print(ctx.message.author.id) print(ctx.message.author.id)
werewolf_game = Werewolf_Game(bot)
bot.run(TOKEN) bot.run(TOKEN)

View File

@ -6,65 +6,40 @@ from werewolf_players import Player, No_player
class Game: class Game:
def __init__(self, bot): def __init__(self, bot, channel):
self.running = False self.running = False
self.bot = bot self.bot = bot
self.player_list = []
self.role_list = Role.role_set
def set_channel(self, channel):
self.channel = channel self.channel = channel
self.player_list = []
self.role_list = []
async def send(self, message): async def send(self, message):
await self.channel.send(message) await self.channel.send(message)
async def receive(self, command): async def set_players(self, msg):
def check(msg): self.player_list = [await Player.make(mem, self) for mem in msg.mentions]
return msg.channel == self.channel and msg.content.startswith(command)
return await self.bot.wait_for('message', check=check)
def setup(self):
self.werewolf_list = []
self.mason_list = []
async def set_players(self):
await self.send("Who is playing?")
msg = await self.receive('$players')
# use info from last round otherwise
if not msg.content.startswith('$players last'):
self.player_list = [await Player.make(mem, self) for mem in msg.mentions]
# check conditions
if not 0 <= len(self.player_list) <= 10:
raise ValueError("Invalid number of players: " + str(len(self.player_list)))
# send confirmation # send confirmation
await self.send("Players: " + ", ".join(p.name() for p in self.player_list)) await self.send("Players: " + ", ".join(p.name() for p in self.player_list))
async def set_roles(self): async def set_roles(self, suggestions):
await self.send("With which roles do you want to play?") self.role_list = [Role.match(r, self) for r in suggestions] # raises ValueError
msg = await self.receive('$roles')
# use info from last round otherwise
if not msg.content.startswith('$roles last'):
tmp_role = [Role.match(r, self) for r in msg.content.split()[1:]]
# invalid input
if None in tmp_role:
raise ValueError("Invalid list of roles: " + str(tmp_role))
self.role_list = tmp_role
# check condition
if not len(self.role_list) == (len(self.player_list) + 3):
raise ValueError("Invalid number of roles: " + str(len(self.role_list)) + " with " + str(len(self.player_list)) + " players")
# send confirmation # send confirmation
await self.send("Roles: " + ", ".join(r.name() for r in self.role_list)) await self.send("Roles: " + ", ".join(r.name() for r in self.role_list))
def check(self):
if not 0 <= len(self.player_list) <= 10:
raise ValueError(f"Invalid number of players: {len(self.player_list)}")
if not len(self.role_list) == (len(self.player_list) + 3):
raise ValueError(f"Invalid number of roles: {len(self.role_list)} with {len(self.player_list)} players")
def setup(self):
self.werewolf_list = []
self.mason_list = []
self.running = True
def distribute_roles(self): def distribute_roles(self):
shuffle(self.role_list) shuffle(self.role_list)
for i in range(len(self.player_list)): for i in range(len(self.player_list)):
@ -93,7 +68,7 @@ class Game:
async def vote(self, options): async def vote(self, options):
# vote # vote
await self.receive('$vote') # replace with dm: await self.receive('$vote')
await self.send("Vote in DM") await self.send("Vote in DM")
await asyncio.gather(*[p.cast_vote(options) for p in self.player_list]) await asyncio.gather(*[p.cast_vote(options) for p in self.player_list])
@ -185,9 +160,8 @@ class Game:
try: try:
self.check()
self.setup() self.setup()
await self.set_players()
await self.set_roles()
self.distribute_roles() self.distribute_roles()
await self.start_night() await self.start_night()
await self.send_role() await self.send_role()
@ -208,4 +182,4 @@ class Game:
await self.send("Error: I got bored waiting for your input") await self.send("Error: I got bored waiting for your input")
finally: finally:
self.end() self.end()
await self.send("Game ended") await self.send("Round ended")

View File

@ -21,7 +21,7 @@ class Player:
def name(self): def name(self):
return self.member.name return self.member.name
def __repr__(self): def __str__(self):
return self.name() return self.name()
def other(self): def other(self):
@ -54,6 +54,3 @@ class No_player(Player):
def name(self): def name(self):
return "no one" return "no one"
def __str__(self):
return self.name()

View File

@ -27,6 +27,7 @@ class Role:
for role_class in Role.role_set: for role_class in Role.role_set:
if message.casefold() == role_class.name(): if message.casefold() == role_class.name():
return role_class(game) return role_class(game)
raise ValueError(f"Invalid role: {message}")
@classmethod @classmethod
def name(cls): def name(cls):