From eaf1686c5d8c0c0d94c421476bf80238301a059e Mon Sep 17 00:00:00 2001 From: bibin Date: Fri, 3 Apr 2020 16:09:39 +0200 Subject: [PATCH] on_message -> commands --- src/__pycache__/werewolf_game.cpython-37.pyc | Bin 9546 -> 9378 bytes .../werewolf_players.cpython-37.pyc | Bin 3113 -> 3151 bytes src/__pycache__/werewolf_roles.cpython-37.pyc | Bin 7043 -> 7026 bytes src/werewolf_bot.py | 83 +++++++++++------- src/werewolf_game.py | 33 +++---- src/werewolf_players.py | 15 ++-- src/werewolf_roles.py | 28 ++++-- 7 files changed, 93 insertions(+), 66 deletions(-) diff --git a/src/__pycache__/werewolf_game.cpython-37.pyc b/src/__pycache__/werewolf_game.cpython-37.pyc index e8e5524dbb113048256b87b0c2f373a9358df880..dd64ba7b90bde899458325189f4f61fd05dd2b02 100644 GIT binary patch delta 2918 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 delta 1238 zcmaJ=&rj4q6z;U$?QEAt6ax#92&*U?m8F2eL;{K$Q43l?m?z<&-%;4}0C>t~NW2 zQhOswZJV$q16^zt{-L(SY{?ToRSckCASWB=O5c8c{9rqcCo^@F+LE#zOY4 z#%BgaPj-Uzil^Cu(g1ouhY&NB)0n0cuiI`l@?CaWe9C@b`U@6HIV%mf>VzQ+cm{OP zqA+1$A`L(G{53z3nja>7D0L^Zbq8g&?zq|TdRcCjx$9TNzG0D~I5dj$Wu#^Jb@;2l z6zx@%NV@6xiM<+eK8)vD{o>M8kxn3jRHaHZ=-~rMa#KPoY-h}Q@FXsEgU1>fzXA3FNj}2=t00s;*E4ThTvle&16yu zd&3C;t{ACQ?Vuex)v4C_WvQOpw9cTIG+$Swu@KqmAf&U=_LbuU_Cx5YZHb@e{NVBB zH?OCe2i7ntto+>7Gv>jt?KpvPm=d4!Lt7S5_&CA@!W2T&+^ eIqoe$^RWr3(vB(V^hV^p3D`{9E1d35GWrjhzULPJ diff --git a/src/__pycache__/werewolf_roles.cpython-37.pyc b/src/__pycache__/werewolf_roles.cpython-37.pyc index 121e3a5e7ce5412c255a315b04595c1e2ec0abc7..58720c5315eacfb416e507c7b96b14b6859d293c 100644 GIT binary patch delta 626 zcmYjNJ4ho@6rDT1OtO=V`z9LWB!#$$yM7Q|P?IeFA|a?7al;1IQm~Ljh&%-gtqc}v z6ue*|_*+=4ccgQZFIodfugBQ!N5n!!s;E!lmB&b4kq;1>zh2p0n;~XHC9Z_>uyYWRRxUAg(Rzam}j) z-nMpkHd56Hxv43JF@`L|7ls~`!m*V_=WW_=^L)a5?0am2hz%wUf)EHj6i^cf_9Q;U zu3#7cwVj5?N%0vOs+ov7Zp9a3({$RQ{eD}hX}phLz&K|%S`YA|z0i`Qwta5p*We(P z!y97|N1bnWo~T3CbWc-xPjQ`;JwwEiPnq$Q{zS^2Blg6n%z4V6MA|M8``f1!@G;Tb p!9S{aUd59rj#TWf*hm#Hl^jfVOCh7ulwsK>BeGdqGDwW~y#im;FAAHj%VGrV?Z;rkC;=MsJ=Hs5+oO5&T`3_54=dDHCwiJ5&;s>je zfC4The!`jXoH+t0;;$n;m*vsx5Gpj_NAWmyV;!!ckLRBrCbVz`JFMVUghqUUsL2P3^rzbf1iTq*mYZ(Dos84Z(NhrUB|;8 z?luhy&BL9X4li*pcXeW!24C6Z`Iw^&! diff --git a/src/werewolf_bot.py b/src/werewolf_bot.py index c52ab07..c61c82e 100644 --- a/src/werewolf_bot.py +++ b/src/werewolf_bot.py @@ -1,8 +1,9 @@ import os -import discord -import asyncio from dotenv import load_dotenv - +import functools +import asyncio +import discord +from discord.ext import commands from werewolf_game import Game as Werewolf_Game @@ -12,54 +13,74 @@ if TOKEN is None: print("Missing discord token!") exit(1) -bot = discord.Client() +bot = commands.Bot(command_prefix=commands.when_mentioned_or('$werewolf ')) + @bot.event async def on_ready(): + await bot.change_presence(status=discord.Status.idle, activity=discord.Game('One Night Ultimate Werewolf')) print('We have logged in as {0.user}'.format(bot)) - -async def hello(message): - print("Hello") - await message.channel.send('Hello!:regional_indicator_a:') - - print(message.mentions) - @bot.event async def on_message(message): - - global running - if message.author == bot.user: return + await bot.process_commands(message) - if message.content.startswith('$hello'): - await hello(message) +@bot.group(help="werewolf game", description="Prefix for the One Night Ultimate Werewolf commands.") +async def game(ctx): + if ctx.invoked_subcommand is None: + await bot.say('Invalid sub command passed...') + + +@game.command(help="start werewolf game", description="Start One Night Ultimate Werewolf game.") +async def start(ctx): + if werewolf_game.running: + await ctx.message.channel.send("Sorry! A game is already running") return + werewolf_game.running = True + werewolf_game.set_channel(ctx.message.channel) - if message.content.startswith('$logout'): - await bot.logout() - return + await werewolf_game.game() - if message.content.startswith('$werewolf'): - - # start (only one instance running) - - if werewolf_game.running: - await message.channel.send("Sorry! A game is already running") - return - - werewolf_game.running = True - werewolf_game.set_channel(message.channel) +@bot.command(help="greets you", description="This just says hello back to the message author.") +async def hello(ctx): + await ctx.message.channel.send(f"Hello {ctx.message.author.name} :wave:") - await werewolf_game.game() +@bot.command(help="test bot responsiveness", description="This is a debug function to see if the bot listens to a command.") +async def ping(ctx): + print("pong") + await ctx.send("pong") + + +def developer(command): + @functools.wraps(command) + async def wrapper(ctx): + DEV_ID = 461892912821698562 + if ctx.message.author.id == DEV_ID: + await command(ctx) + else: + await ctx.send("This command is not for you!") + return wrapper + + +@bot.command(help="not for you", description="Shut down the bot.") +@developer +async def logout(ctx): + await bot.logout() + + +@bot.command(help="debug") +@developer +async def debug(ctx): + print("DEBUG") + print(ctx.message.author.id) - return werewolf_game = Werewolf_Game(bot) bot.run(TOKEN) diff --git a/src/werewolf_game.py b/src/werewolf_game.py index b01a931..e9e5d81 100644 --- a/src/werewolf_game.py +++ b/src/werewolf_game.py @@ -1,8 +1,9 @@ from random import shuffle import asyncio -from werewolf_roles import Role, Doppelganger, Werewolf, Minion, Mason, Seer, Robber, Troublemaker, Drunk, Insomniac, Villiager, Tanner, Hunter, No_role +from werewolf_roles import Role, Werewolf, Minion, Tanner, Hunter from werewolf_players import Player, No_player + class Game: def __init__(self, bot): @@ -11,26 +12,22 @@ class Game: self.player_list = [] self.role_list = Role.role_set - def set_channel(self, channel): self.channel = channel - async def send(self, message): await self.channel.send(message) - async def receive(self, command): def check(msg): return msg.channel == self.channel and msg.content.startswith(command) - return await self.bot.wait_for('message', check = check) + 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?") @@ -47,7 +44,6 @@ class Game: # send confirmation await self.send("Players: " + ", ".join(p.name() for p in self.player_list)) - async def set_roles(self): await self.send("With which roles do you want to play?") msg = await self.receive('$roles') @@ -69,7 +65,6 @@ class Game: # send confirmation await self.send("Roles: " + ", ".join(r.name() for r in self.role_list)) - def distribute_roles(self): shuffle(self.role_list) for i in range(len(self.player_list)): @@ -77,21 +72,20 @@ class Game: self.role_list[i].setPlayer(self.player_list[i]) self.middle_card = self.role_list[-3:] - self.active_role = sorted(self.role_list[:-3], key = lambda x: x.order) #necessary? - + self.active_role = sorted(self.role_list[:-3], key=lambda x: x.order) async def start_night(self): - await asyncio.gather( *[p.send("The night has begun") for p in self.player_list] ) + await asyncio.gather(*[p.send("The night has begun") for p in self.player_list]) async def send_role(self): - await asyncio.gather( *[p.send("Your role: " + p.night_role.name()) for p in self.player_list] ) + await asyncio.gather(*[p.send("Your role: " + p.night_role.name()) for p in self.player_list]) async def night_phases(self): - await asyncio.gather( *[r.phase1() for r in self.active_role] ) - await asyncio.gather( *[r.phase2() for r in self.active_role] ) - await asyncio.gather( *[r.phase3() for r in self.active_role] ) - await asyncio.gather( *[r.phase4() for r in self.active_role] ) - await asyncio.gather( *[r.phase5() for r in self.active_role] ) + await asyncio.gather(*[r.phase1() for r in self.active_role]) + await asyncio.gather(*[r.phase2() for r in self.active_role]) + await asyncio.gather(*[r.phase3() for r in self.active_role]) + await asyncio.gather(*[r.phase4() for r in self.active_role]) + await asyncio.gather(*[r.phase5() for r in self.active_role]) async def start_day(self): await self.send("The day has started") @@ -102,7 +96,7 @@ class Game: await self.receive('$vote') 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]) await self.send("Votes\n\n" + '\n'.join(str(p) + " :arrow_right: " + str(p.vote) for p in self.player_list)) @@ -187,7 +181,6 @@ class Game: def end(self): self.running = False - async def game(self): try: @@ -202,7 +195,7 @@ class Game: await self.night_phases() await self.start_day() - #discussion timer + # discussion timer options = self.player_list + [No_player(self)] await self.vote(options) diff --git a/src/werewolf_players.py b/src/werewolf_players.py index 9086772..2d88af0 100644 --- a/src/werewolf_players.py +++ b/src/werewolf_players.py @@ -1,3 +1,6 @@ +from werewolf_roles import No_role + + class Player: @staticmethod @@ -8,9 +11,8 @@ class Player: p.game = game return p - @staticmethod - def swap(player_A, player_B): - player_A.day_role, player_B.day_role = player_B.day_role, player_A.day_role + def swap(self, player_B): + self.day_role, player_B.day_role = player_B.day_role, self.day_role def setRole(self, role): self.night_role = role @@ -29,13 +31,13 @@ class Player: await self.dm.send(message) async def ask_choice(self, options): - await self.send('\n'.join( "(" + str(i) + ") " + str(options[i]) for i in range(len(options)) )) + await self.send('\n'.join("(" + str(i) + ") " + str(options[i]) for i in range(len(options)))) async def receive_choice(self, options): def check(choice): - return choice.channel == self.dm and choice.content.isdigit() and 0 <= int(choice.content) < len(options) + return choice.channel == self.dm and choice.content.isdigit() and 0 <= int(choice.content) < len(options) - return int((await self.game.bot.wait_for('message', timeout=30.0, check = check)).content) + return int((await self.game.bot.wait_for('message', timeout=30.0, check=check)).content) async def get_choice(self, options): await self.ask_choice(options) @@ -44,6 +46,7 @@ class Player: async def cast_vote(self, options): self.vote = options[await self.get_choice(options)] + class No_player(Player): def __init__(self): diff --git a/src/werewolf_roles.py b/src/werewolf_roles.py index 8d108cd..5185634 100644 --- a/src/werewolf_roles.py +++ b/src/werewolf_roles.py @@ -7,19 +7,19 @@ class Role: def setPlayer(self, player): self.player = player - async def phase1(self): # query stuff + doppelganger simulation + async def phase1(self): # query stuff + doppelganger simulation pass - async def phase2(self): # werewolf stuff + seer info + async def phase2(self): # werewolf stuff + seer info pass - async def phase3(self): # robber simulation & info + async def phase3(self): # robber simulation & info pass - async def phase4(self): # troublemaker simulation + async def phase4(self): # troublemaker simulation pass - async def phase5(self): # mostly sending info + drunk simulation + async def phase5(self): # mostly sending info + drunk simulation pass @staticmethod @@ -35,9 +35,11 @@ class Role: def __str__(self): return self.name() + class Doppelganger(Role): order = 1 + class Werewolf(Role): order = 2 @@ -107,9 +109,10 @@ class Robber(Role): self.choice = await self.player.get_choice(self.player.other()) async def phase3(self): - Player.swap(self.player, self.player.other()[self.choice]) + self.player.swap(self.player.other()[self.choice]) await self.player.send("You robbed: " + str(self.player.day_role)) + class Troublemaker(Role): order = 7 @@ -119,10 +122,11 @@ class Troublemaker(Role): self.B = await self.player.get_choice(self.player.other()) async def phase4(self): - Player.swap(self.player.other()[self.A], self.player.other()[self.B]) + self.player.other()[self.A].swap(self.player.other()[self.B]) # receive conformation await self.player.send("Received " + str(self.A) + " " + str(self.B)) + class Drunk(Role): order = 8 @@ -132,25 +136,31 @@ class Drunk(Role): async def phase5(self): self.player.day_role, self.game.middle_card[self.choice] = self.game.middle_card[self.choice], self.player.day_role - #receive conformation + # receive conformation await self.player.send("Received " + str(self.choice)) + class Insomniac(Role): order = 9 async def phase5(self): await self.player.send("You are now: " + str(self.player.day_role)) + class Villiager(Role): order = 10 + class Tanner(Role): order = 11 + class Hunter(Role): order = 12 + class No_role(Role): order = 1000 -Role.role_set = [Doppelganger, Werewolf, Minion, Mason, Seer, Robber, Troublemaker, Drunk, Insomniac, Villiager, Tanner, Hunter] \ No newline at end of file + +Role.role_set = [Doppelganger, Werewolf, Minion, Mason, Seer, Robber, Troublemaker, Drunk, Insomniac, Villiager, Tanner, Hunter]