Commit 56755ad0 authored by Ferdinand Schober's avatar Ferdinand Schober 💬
Browse files

bug fixes

parent 901df1f3
# Default ignored files
/workspace.xml
# Default ignored files
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (2)" project-jdk-type="Python SDK" />
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (2)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/werwolf.iml" filepath="$PROJECT_DIR$/.idea/werwolf.iml" />
</modules>
</component>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/werwolf.iml" filepath="$PROJECT_DIR$/.idea/werwolf.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.8 (2)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.8 (2)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>
\ No newline at end of file
#Werwölfe von Düsterwald
Ein Discord Server Bot für das Spiel "Werwölfe von Düsterwald"
#Werwölfe von Düsterwald
Ein Discord Server Bot für das Spiel "Werwölfe von Düsterwald"
from discord.ext.commands import Bot
from .cogs import utility_commands
from .cogs import werewolf_commands
from .config.server_config import server_config
def run():
client = Bot(command_prefix='$')
client.load_extension('game.cogs.utility_commands')
client.load_extension('game.cogs.werewolf_commands')
from discord.ext.commands import Bot
from .cogs import utility_commands
from .cogs import werewolf_commands
from .config.server_config import server_config
def run():
client = Bot(command_prefix='$')
client.load_extension('game.cogs.utility_commands')
client.load_extension('game.cogs.werewolf_commands')
client.run(server_config['bot_token'])
\ No newline at end of file
from ..roles.werewolf import Werewolf
from ..roles.villager import Villager
from ..roles.seer import Seer
from ..roles.witch import Witch
from ..roles.hunter import Hunter
from ..roles.amor import Amor
from ..roles.whore import Whore
from ..roles.girl import Girl
from ..game import Game
from ..day import Day
def is_alive(self, ctx):
return ctx.author in self.game[ctx.guild].alive
def is_role(Role):
def func(self, ctx):
return ctx.author in self.game[ctx.guild].role_of_type[Role].members
return func
def is_running(self, ctx):
from ..roles.werewolf import Werewolf
from ..roles.villager import Villager
from ..roles.seer import Seer
from ..roles.witch import Witch
from ..roles.hunter import Hunter
from ..roles.amor import Amor
from ..roles.whore import Whore
from ..roles.girl import Girl
from ..game import Game
from ..day import Day
def is_alive(self, ctx):
return ctx.author in self.game[ctx.guild].alive
def is_role(Role):
def func(self, ctx):
return ctx.author in self.game[ctx.guild].role_of_type[Role].members
return func
def is_running(self, ctx):
return not not self.game[ctx.guild]
\ No newline at end of file
import discord
from discord.ext import commands
from asyncio import create_task
from functools import wraps
class Util(commands.Cog):
def __init__(self, client):
self.client = client
@commands.Cog.listener()
async def on_ready(self):
await self.client.change_presence(status=discord.Status.online, activity=discord.Game('with 0s and 1s'))
@commands.Cog.listener()
async def on_member_join(self, member):
print(f'{member} has joined a server')
@commands.Cog.listener()
async def on_member_remove(self, member):
print(f'{member} has left a server')
@commands.command()
async def echo(self, ctx, *, args):
await ctx.send(args)
@commands.command()
async def ping(self, ctx):
await ctx.send('pong')
@commands.command()
async def clear(self, ctx, amount=2):
await ctx.channel.purge(limit=amount)
@commands.command()
async def spam(self, ctx, n=5):
for i in range(0, n):
create_task(ctx.send(f'{i}'))
def setup(client):
import discord
from discord.ext import commands
from asyncio import create_task
from functools import wraps
class Util(commands.Cog):
def __init__(self, client):
self.client = client
@commands.Cog.listener()
async def on_ready(self):
await self.client.change_presence(status=discord.Status.online, activity=discord.Game('with 0s and 1s'))
@commands.Cog.listener()
async def on_member_join(self, member):
print(f'{member} has joined a server')
@commands.Cog.listener()
async def on_member_remove(self, member):
print(f'{member} has left a server')
@commands.command()
async def echo(self, ctx, *, args):
await ctx.send(args)
@commands.command()
async def ping(self, ctx):
await ctx.send('pong')
@commands.command()
async def clear(self, ctx, amount=2):
await ctx.channel.purge(limit=amount)
@commands.command()
async def spam(self, ctx, n=5):
for i in range(0, n):
create_task(ctx.send(f'{i}'))
def setup(client):
client.add_cog(Util(client))
\ No newline at end of file
from discord.ext import commands
from discord import Permissions, PermissionOverwrite, Member, utils, Colour
from discord.ext.commands import CommandInvokeError, CommandError
from asyncio import create_task, Event, Lock, gather
from ..roles import Amor, Girl, Hunter, Seer, Villager, Werewolf, Whore, Witch, Role
from ..game import Game
from functools import wraps
def delete_command_message(command):
@wraps(command)
async def wrapper(self, ctx, *args, **kwargs):
await command(self, ctx, *args, **kwargs)
await ctx.message.delete()
return wrapper
def is_alive(ctx):
if ctx.author not in ctx.cog.game[ctx.guild].alive:
raise CommandError('You must be alive to invoke this command!')
return True
def is_not_alive(ctx):
if ctx.author in ctx.cog.game[ctx.guild].alive:
raise CommandError('You must be dead to invoke this command!')
return True
def args_alive(command):
@wraps(command)
async def wrapper(self, ctx, *args, **kwargs):
for arg in args:
if type(arg) == Member and arg not in ctx.cog.game[ctx.guild].alive:
raise CommandError(f'Member {arg.mention} lebt nicht mehr!')
for arg in kwargs.values():
if type(arg) == Member and arg not in ctx.cog.game[ctx.guild].alive:
raise CommandError(f'Member {arg.mention} lebt nicht mehr!')
await command(self, ctx, *args, **kwargs)
return wrapper
def is_role(Role):
def is_role(ctx):
if ctx.cog.game[ctx.guild].role_of_type.get(Role) == None:
raise CommandError(f'Die Rolle "{Role.get_name()}" ist nicht im Spiel!')
if ctx.author not in ctx.cog.game[ctx.guild].role_of_type[Role].members:
raise CommandError(f'Deine Rolle ist nicht {Role.get_name()}, {ctx.author.mention}!')
return True
return is_role
def is_running(ctx):
if not ctx.cog.running[ctx.guild]:
raise CommandInvokeError('Game ist not running')
return True
class WerwolfCommands(commands.Cog):
def __init__(self, client):
self.client = client
self.init_event = Event()
self.game = dict()
self.running = dict()
self.lock = Lock()
@commands.Cog.listener()
async def on_ready(self):
for guild in self.client.guilds:
self.game[guild] = None
self.running[guild] = False
self.init_event.set()
async def create_channels(self, guild, channel_names, role_alive, role_dead):
if not self.lock.locked():
async with self.lock:
overwrites = {
role_alive : PermissionOverwrite(read_messages=False, send_messages=False),
role_dead : PermissionOverwrite(read_messages=True, send_messages=False),
}
ww_category = await guild.create_category('werwolf')
await gather(*[ww_category.create_text_channel(name, overwrites=overwrites) for name in channel_names])
await ww_category.create_voice_channel('talk')
dead_talk = await ww_category.create_voice_channel('dead')
await dead_talk.set_permissions(role_alive, connect=False)
await utils.get(ww_category.text_channels, name='dorf').set_permissions(role_alive, read_messages=True, send_messages=True)
return ww_category
@commands.command()
async def clear_channels(self, ctx):
await self.uninstall(ctx.guild)
async def uninstall(self, guild):
if not self.lock.locked():
async with self.lock:
ww_category = utils.get(guild.categories, name='werwolf')
if not ww_category: return
await gather(*[channel.delete() for channel in ww_category.channels])
await ww_category.delete()
@commands.command()
async def start(self, ctx):
async with ctx.channel.typing():
await self.init_event.wait()
if self.running[ctx.guild]:
await ctx.send('Spiel läuft bereits!')
else:
async with ctx.channel.typing():
self.running[ctx.guild] = True
lobby = utils.get(ctx.guild.channels, name='lobby')
members = lobby.members
role_alive = utils.get(ctx.guild.roles, name='lebendig')
role_dead = utils.get(ctx.guild.roles, name='tot')
if not role_alive:
role_alive = await ctx.guild.create_role(name='lebendig', color=Colour.green(), hoist=True, mentionable=True)
if not role_dead:
role_dead = await ctx.guild.create_role(name='tot', color=Colour.red(), hoist=True, mentionable=True)
#roles = [Girl, Werewolf, Hunter, Witch, Whore, Seer]
roles = [Werewolf, Girl, Amor, Witch, Whore, Werewolf, Seer, Hunter, Villager, Werewolf]
category = await self.create_channels(ctx.guild, ['info', 'dorf'] + [role.get_channel_name() for role in set(roles[:len(members)]) ] + ['liebespaar'], role_alive, role_dead)
await gather(*[member.move_to(category.voice_channels[0]) for member in members])
self.game[ctx.guild] = Game(category, members, roles, role_alive, role_dead)
await self.game[ctx.guild].play(ctx)
self.running[ctx.guild] = False
await gather(*[member.move_to(lobby) for member in members])
@commands.Cog.listener()
async def on_command_error(self, ctx, error):
await ctx.send(str(error))
raise error
@commands.Cog.listener()
async def on_message(self, message):
game = self.game[message.guild]
if not game: return
ww_channel = game.role_of_type[Werewolf].channel
girl_channel = game.role_of_type.get(Girl).channel
if girl_channel and (message.channel == ww_channel):
await girl_channel.send(message.content)
@commands.command()
@commands.check(is_alive)
@commands.check(is_running)
@args_alive
async def accuse(self, ctx, *, player:Member):
await self.game[ctx.guild].day.accuse(ctx, player)
@commands.command()
@commands.check(is_alive)
@commands.check(is_running)
@delete_command_message
@args_alive
async def withdraw(self, ctx, *, player:Member):
await self.game[ctx.guild].day.withdraw(ctx, player)
@commands.command()
@commands.check(is_alive)
@commands.check(is_running)
async def confirm(self, ctx):
await self.game[ctx.guild].day.confirm(ctx)
@commands.command()
@commands.check(is_alive)
@commands.check(is_running)
@delete_command_message
@args_alive
async def vote(self, ctx, *, player:Member):
if ctx.channel == self.game[ctx.guild].day.channel:
await self.game[ctx.guild].day.vote(ctx, ctx.author, player)
elif ctx.author in self.game[ctx.guild].role_of_type[Werewolf].members:
await self.game[ctx.guild].role_of_member[ctx.author].vote(ctx, player)
@commands.command()
@commands.check(is_running)
@delete_command_message
async def captain(self, ctx):
await self.game[ctx.guild].day.print_captain(ctx)
@commands.command()
@commands.check(is_role(Witch))
@commands.check(is_alive)
@commands.check(is_running)
@delete_command_message
async def heal(self, ctx):
await self.game[ctx.guild].role_of_member[ctx.author].heal()
@commands.command()
@commands.check(is_role(Witch))
@commands.check(is_alive)
@commands.check(is_running)
@delete_command_message
@args_alive
async def poison(self, ctx, *, player:Member):
await self.game[ctx.guild].role_of_member[ctx.author].poison(player)
@commands.command()
@commands.check(is_role(Seer))
@commands.check(is_alive)
@commands.check(is_running)
@args_alive
async def see(self, ctx, *, player:Member):
await self.game[ctx.guild].role_of_member[ctx.author].see(player)
@commands.command()
@commands.check(is_role(Hunter))
@commands.check(is_not_alive)
@commands.check(is_running)
@args_alive
async def kill(self, ctx, *, player:Member):
await self.game[ctx.guild].role_of_member[ctx.author].kill(ctx, player)
@commands.command()
@commands.check(is_role(Amor))
@commands.check(is_alive)
@commands.check(is_running)
@args_alive
async def love(self, ctx, p1:Member, p2:Member):
await self.game[ctx.guild].role_of_member[ctx.author].love(p1, p2)
@commands.command()
@commands.check(is_role(Whore))
@commands.check(is_alive)
@commands.check(is_running)
@args_alive
async def sleep(self, ctx, *, player:Member):
await self.game[ctx.guild].role_of_member[ctx.author].sleep(player)
@commands.command()
@commands.check(is_role(Witch))
@commands.check(is_alive)
@commands.check(is_running)
@delete_command_message
async def no(self, ctx):
await self.game[ctx.guild].role_of_member[ctx.author].no()
@commands.command()
@commands.check(is_running)
@delete_command_message
async def alive(self, ctx):
await self.game[ctx.guild].print_living(ctx)
@commands.command()
@commands.check(is_running)
@delete_command_message
async def role(self, ctx):
await self.game[ctx.guild].role_of_member[ctx.member].get(Role)
def setup(client):
client.add_cog(WerwolfCommands(client))
from discord.ext import commands
from discord import Permissions, PermissionOverwrite, Member, utils, Colour
from discord.ext.commands import CommandInvokeError, CommandError
from asyncio import create_task, Event, Lock, gather
from ..roles import Amor, Girl, Hunter, Seer, Villager, Werewolf, Whore, Witch, Role
from ..game import Game
from functools import wraps
def delete_command_message(command):
@wraps(command)
async def wrapper(self, ctx, *args, **kwargs):
await command(self, ctx, *args, **kwargs)
await ctx.message.delete()
return wrapper
def is_alive(ctx):
if ctx.author not in ctx.cog.game[ctx.guild].alive:
raise CommandError('You must be alive to invoke this command!')
return True
def is_not_alive(ctx):
if ctx.author in ctx.cog.game[ctx.guild].alive:
raise CommandError('You must be dead to invoke this command!')
return True
def args_alive(command):
@wraps(command)
async def wrapper(self, ctx, *args, **kwargs):
for arg in args:
if type(arg) == Member and arg not in ctx.cog.game[ctx.guild].alive:
raise CommandError(f'Member {arg.mention} lebt nicht mehr!')
for arg in kwargs.values():
if type(arg) == Member and arg not in ctx.cog.game[ctx.guild].alive:
raise CommandError(f'Member {arg.mention} lebt nicht mehr!')
await command(self, ctx, *args, **kwargs)
return wrapper
def is_role(Role):
def is_role(ctx):
if ctx.cog.game[ctx.guild].role_of_type.get(Role) == None:
raise CommandError(f'Die Rolle "{Role.get_name()}" ist nicht im Spiel!')
if ctx.author not in ctx.cog.game[ctx.guild].role_of_type[Role].members:
raise CommandError(f'Deine Rolle ist nicht {Role.get_name()}, {ctx.author.mention}!')
return True
return is_role
def is_running(ctx):
if not ctx.cog.running[ctx.guild]:
raise CommandInvokeError('Game ist not running')
return True
class WerwolfCommands(commands.Cog):
def __init__(self, client):
self.client = client
self.init_event = Event()
self.game = dict()
self.running = dict()
self.lock = Lock()
@commands.Cog.listener()
async def on_ready(self):
for guild in self.client.guilds:
self.game[guild] = None
self.running[guild] = False
self.init_event.set()
async def create_channels(self, guild, channel_names, role_alive, role_dead):
if not self.lock.locked():
async with self.lock:
overwrites = {
role_alive : PermissionOverwrite(read_messages=False, send_messages=False),
role_dead : PermissionOverwrite(read_messages=True, send_messages=False),
}
ww_category = await guild.create_category('werwolf')
await gather(*[ww_category.create_text_channel(name, overwrites=overwrites) for name in channel_names])
await ww_category.create_voice_channel('talk')
dead_talk = await ww_category.create_voice_channel('dead')
await dead_talk.set_permissions(role_alive, connect=False)
await utils.get(ww_category.text_channels, name='dorf').set_permissions(role_alive, read_messages=True, send_messages=True)
return ww_category
@commands.command()
async def clear_channels(self, ctx):
await self.uninstall(ctx.guild)
async def uninstall(self, guild):
if not self.lock.locked():
async with self.lock:
ww_category = utils.get(guild.categories, name='werwolf')
if not ww_category: return
await gather(*[channel.delete() for channel in ww_category.channels])