2020-04-25 14:42:06 +00:00
|
|
|
#!/bin/python
|
2020-04-25 23:50:06 +00:00
|
|
|
import random
|
2020-04-25 14:42:06 +00:00
|
|
|
|
|
|
|
import discord
|
2020-04-27 08:05:17 +00:00
|
|
|
import yaml
|
2020-04-27 09:43:16 +00:00
|
|
|
from discord.ext import commands
|
|
|
|
from discord.ext.commands import Context, group, Cog
|
2020-04-25 16:58:35 +00:00
|
|
|
from discord.utils import get
|
2020-04-25 14:42:06 +00:00
|
|
|
|
2020-04-27 14:35:29 +00:00
|
|
|
from src.cogs.tirage_logic import TiragePhase, Tirage
|
2020-04-27 08:05:17 +00:00
|
|
|
from src.constants import *
|
2020-04-27 14:35:29 +00:00
|
|
|
from src.errors import TfjmError
|
2020-04-27 09:43:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TirageCog(Cog, name="Tirages"):
|
|
|
|
def __init__(self, bot):
|
|
|
|
self.bot: commands.Bot = bot
|
|
|
|
|
|
|
|
# We retrieve the global variable.
|
|
|
|
# We don't want tirages to be ust an attribute
|
|
|
|
# as we want them to outlive the Cog, for instance
|
|
|
|
# if the cog is reloaded turing a tirage.
|
|
|
|
from src.tfjm_discord_bot import tirages
|
|
|
|
|
|
|
|
self.tirages = tirages
|
|
|
|
|
2020-04-27 10:28:30 +00:00
|
|
|
# ---------- Commandes hors du groupe draw ----------- #
|
|
|
|
|
|
|
|
@commands.command(
|
|
|
|
name="dice", aliases=["de", "dé", "roll"], usage="n",
|
|
|
|
)
|
|
|
|
async def dice(self, ctx: Context, n: int):
|
|
|
|
"""Lance un dé à `n` faces."""
|
|
|
|
channel = ctx.channel.id
|
|
|
|
if channel in self.tirages:
|
|
|
|
await self.tirages[channel].dice(ctx, n)
|
|
|
|
else:
|
|
|
|
if n < 1:
|
|
|
|
raise TfjmError(f"Je ne peux pas lancer un dé à {n} faces, désolé.")
|
|
|
|
|
|
|
|
dice = random.randint(1, n)
|
|
|
|
await ctx.send(
|
|
|
|
f"Le dé à {n} face{'s' * (n > 1)} s'est arrêté sur... **{dice}**"
|
|
|
|
)
|
|
|
|
|
|
|
|
@commands.command(
|
|
|
|
name="random-problem",
|
|
|
|
aliases=["rp", "problème-aléatoire", "probleme-aleatoire", "pa"],
|
|
|
|
)
|
|
|
|
async def random_problem(self, ctx: Context):
|
|
|
|
"""Choisit un problème parmi ceux de cette année."""
|
|
|
|
|
|
|
|
channel = ctx.channel.id
|
|
|
|
if channel in self.tirages:
|
|
|
|
await self.tirages[channel].choose_problem(ctx)
|
|
|
|
else:
|
|
|
|
problem = random.choice(PROBLEMS)
|
|
|
|
await ctx.send(f"Le problème tiré est... **{problem}**")
|
|
|
|
|
|
|
|
@commands.command(
|
|
|
|
name="oui", aliases=["accept", "yes", "o", "accepte", "ouiiiiiii"],
|
|
|
|
)
|
|
|
|
async def accept_cmd(self, ctx):
|
|
|
|
"""
|
|
|
|
Accepte le problème qui vient d'être tiré.
|
|
|
|
|
|
|
|
Sans effet si il n'y a pas de tirage en cours.
|
|
|
|
"""
|
|
|
|
|
|
|
|
channel = ctx.channel.id
|
|
|
|
if channel in self.tirages:
|
|
|
|
await self.tirages[channel].accept(ctx, True)
|
|
|
|
else:
|
|
|
|
await ctx.send(f"{ctx.author.mention} approuve avec vigeur !")
|
|
|
|
|
|
|
|
@commands.command(
|
|
|
|
name="non", aliases=["refuse", "no", "n", "nope", "jaaamais"],
|
|
|
|
)
|
|
|
|
async def refuse_cmd(self, ctx):
|
|
|
|
"""
|
|
|
|
Refuse le problème qui vient d'être tiré.
|
|
|
|
|
|
|
|
Sans effet si il n'y a pas de tirage en cours.
|
|
|
|
"""
|
|
|
|
|
|
|
|
channel = ctx.channel.id
|
|
|
|
if channel in self.tirages:
|
|
|
|
await self.tirages[channel].accept(ctx, False)
|
|
|
|
else:
|
2020-04-27 18:03:51 +00:00
|
|
|
await ctx.send(f"{ctx.author.mention} nie tout en bloc !")
|
2020-04-27 10:28:30 +00:00
|
|
|
|
|
|
|
# ---------- Commandes du groupe draw ----------- #
|
|
|
|
|
2020-04-27 09:43:16 +00:00
|
|
|
@group(
|
|
|
|
name="draw", aliases=["d", "tirage"],
|
|
|
|
)
|
|
|
|
async def draw_group(self, ctx: Context) -> None:
|
2020-04-27 20:07:20 +00:00
|
|
|
"""Groupe de commandes pour les tirages. Détails: `!help draw`"""
|
2020-04-27 09:43:16 +00:00
|
|
|
|
2020-04-27 16:44:39 +00:00
|
|
|
print("WTFF")
|
|
|
|
|
2020-04-27 09:43:16 +00:00
|
|
|
@draw_group.command(
|
|
|
|
name="start", usage="équipe1 équipe2 équipe3 (équipe4)",
|
|
|
|
)
|
2020-04-27 10:35:02 +00:00
|
|
|
@commands.has_role(Role.ORGA)
|
2020-04-27 16:44:39 +00:00
|
|
|
async def start(self, ctx: Context, *teams: discord.Role):
|
2020-04-27 09:43:16 +00:00
|
|
|
"""
|
2020-04-27 20:07:20 +00:00
|
|
|
(orga) Commence un tirage avec 3 ou 4 équipes.
|
2020-04-27 09:43:16 +00:00
|
|
|
|
2020-04-27 14:35:29 +00:00
|
|
|
Cette commande attend des trigrames d'équipes.
|
2020-04-27 09:43:16 +00:00
|
|
|
|
2020-04-27 14:35:29 +00:00
|
|
|
Exemple:
|
|
|
|
`!draw start AAA BBB CCC`
|
2020-04-27 09:43:16 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
channel: discord.TextChannel = ctx.channel
|
|
|
|
channel_id = channel.id
|
|
|
|
if channel_id in self.tirages:
|
2020-04-27 20:07:20 +00:00
|
|
|
raise TfjmError(
|
|
|
|
"Il y a déjà un tirage en cours sur cette channel, "
|
|
|
|
"il est possible d'en commencer un autre sur une autre channel."
|
|
|
|
)
|
2020-04-27 09:43:16 +00:00
|
|
|
|
|
|
|
if len(teams) not in (3, 4):
|
2020-04-27 20:07:20 +00:00
|
|
|
raise TfjmError(
|
|
|
|
"Il faut 3 ou 4 équipes pour un tirage. "
|
|
|
|
"Exemple: `!draw start @AAA @BBB @CCC`"
|
|
|
|
)
|
2020-04-27 09:43:16 +00:00
|
|
|
|
|
|
|
# Here all data should be valid
|
|
|
|
|
|
|
|
# Prevent everyone from writing except Capitaines, Orga, CNO, Benevole
|
|
|
|
if False:
|
|
|
|
read = discord.PermissionOverwrite(send_messages=False)
|
|
|
|
send = discord.PermissionOverwrite(send_messages=True)
|
|
|
|
r = lambda role_name: get(ctx.guild.roles, name=role_name)
|
|
|
|
overwrites = {
|
|
|
|
ctx.guild.default_role: read,
|
2020-04-27 10:35:02 +00:00
|
|
|
r(Role.CAPTAIN): send,
|
|
|
|
r(Role.BENEVOLE): send,
|
2020-04-27 09:43:16 +00:00
|
|
|
}
|
|
|
|
await channel.edit(overwrites=overwrites)
|
|
|
|
|
|
|
|
await ctx.send(
|
|
|
|
"Nous allons commencer le tirage du premier tour. "
|
|
|
|
"Seuls les capitaines de chaque équipe peuvent désormais écrire ici. "
|
|
|
|
"Merci de d'envoyer seulement ce que est nécessaire et suffisant au "
|
|
|
|
"bon déroulement du tournoi. Vous pouvez à tout moment poser toute question "
|
|
|
|
"si quelque chose n'est pas clair ou ne va pas. \n\n"
|
|
|
|
"Pour plus de détails sur le déroulement du tirgae au sort, le règlement "
|
|
|
|
"est accessible sur https://tfjm.org/reglement."
|
|
|
|
)
|
|
|
|
|
|
|
|
self.tirages[channel_id] = Tirage(ctx, channel_id, teams)
|
|
|
|
await self.tirages[channel_id].phase.start(ctx)
|
|
|
|
|
2020-04-27 20:07:20 +00:00
|
|
|
@draw_group.command(name="abort")
|
2020-04-27 10:35:02 +00:00
|
|
|
@commands.has_role(Role.ORGA)
|
2020-04-27 09:43:16 +00:00
|
|
|
async def abort_draw_cmd(self, ctx):
|
2020-04-27 10:28:30 +00:00
|
|
|
"""
|
2020-04-27 20:07:20 +00:00
|
|
|
(orga) Annule le tirage en cours.
|
2020-04-27 10:28:30 +00:00
|
|
|
|
|
|
|
Le tirage ne pourra pas être continué. Si besoin,
|
|
|
|
n'hésitez pas à appeller un @dev : il peut réparer
|
|
|
|
plus de choses qu'on imagine (mais moins qu'on voudrait).
|
|
|
|
"""
|
2020-04-27 09:43:16 +00:00
|
|
|
channel_id = ctx.channel.id
|
|
|
|
if channel_id in self.tirages:
|
|
|
|
await self.tirages[channel_id].end(ctx)
|
|
|
|
await ctx.send("Le tirage est annulé.")
|
|
|
|
|
|
|
|
@draw_group.command(name="skip", aliases=["s"])
|
2020-04-27 10:35:02 +00:00
|
|
|
@commands.has_role(Role.DEV)
|
2020-04-27 16:44:39 +00:00
|
|
|
async def draw_skip(self, ctx, *teams: discord.Role):
|
2020-04-27 20:07:20 +00:00
|
|
|
"""(dev) Passe certaines phases du tirage."""
|
2020-04-27 09:43:16 +00:00
|
|
|
channel = ctx.channel.id
|
|
|
|
self.tirages[channel] = tirage = Tirage(ctx, channel, teams)
|
|
|
|
|
|
|
|
tirage.phase = TiragePhase(tirage, round=1)
|
|
|
|
for i, team in enumerate(tirage.teams):
|
|
|
|
team.tirage_order = [i + 1, i + 1]
|
|
|
|
team.passage_order = [i + 1, i + 1]
|
|
|
|
team.accepted_problems = [PROBLEMS[i], PROBLEMS[-i - 1]]
|
|
|
|
tirage.teams[0].rejected = [{PROBLEMS[3]}, set(PROBLEMS[4:8])]
|
|
|
|
tirage.teams[1].rejected = [{PROBLEMS[7]}, set()]
|
|
|
|
|
|
|
|
await ctx.send(f"Skipping to {tirage.phase.__class__.__name__}.")
|
|
|
|
await tirage.phase.start(ctx)
|
|
|
|
await tirage.update_phase(ctx)
|
|
|
|
|
|
|
|
@draw_group.command(name="show")
|
2020-04-27 14:37:27 +00:00
|
|
|
async def show_cmd(self, ctx: Context, tirage_id: str = "all"):
|
2020-04-27 10:28:30 +00:00
|
|
|
"""
|
2020-04-27 14:35:29 +00:00
|
|
|
Affiche le résumé d'un tirage.
|
2020-04-27 10:28:30 +00:00
|
|
|
|
2020-04-27 14:35:29 +00:00
|
|
|
Exemples:
|
|
|
|
`!draw show all` - Liste les ID possible
|
|
|
|
`!draw show 42` - Affiche le tirage n°42
|
2020-04-27 10:28:30 +00:00
|
|
|
"""
|
|
|
|
|
2020-04-27 09:43:16 +00:00
|
|
|
if not TIRAGES_FILE.exists():
|
|
|
|
await ctx.send("Il n'y a pas encore eu de tirages.")
|
|
|
|
return
|
|
|
|
|
|
|
|
with open(TIRAGES_FILE) as f:
|
|
|
|
tirages = list(yaml.load_all(f))
|
|
|
|
|
2020-04-27 10:28:30 +00:00
|
|
|
if tirage_id.lower() == "all":
|
2020-04-27 16:44:39 +00:00
|
|
|
await ctx.send(
|
|
|
|
"Voici in liste de tous les tirages qui ont été faits et "
|
|
|
|
"quelles équipes y on participé."
|
|
|
|
"Vous pouvez en consulter un en particulier avec `!draw show ID`."
|
|
|
|
)
|
2020-04-27 09:43:16 +00:00
|
|
|
msg = "\n".join(
|
2020-04-27 16:44:39 +00:00
|
|
|
f"`{i}`: {', '.join(team.name for team in tirage.teams)}"
|
2020-04-27 09:43:16 +00:00
|
|
|
for i, tirage in enumerate(tirages)
|
|
|
|
)
|
|
|
|
await ctx.send(msg)
|
|
|
|
else:
|
|
|
|
try:
|
2020-04-27 10:28:30 +00:00
|
|
|
n = int(tirage_id)
|
2020-04-27 09:43:16 +00:00
|
|
|
if n < 0:
|
|
|
|
raise ValueError
|
|
|
|
tirage = tirages[n]
|
|
|
|
except (ValueError, IndexError):
|
|
|
|
await ctx.send(
|
2020-04-27 10:28:30 +00:00
|
|
|
f"`{tirage_id}` n'est pas un identifiant valide. "
|
2020-04-27 16:44:39 +00:00
|
|
|
f"Les identifiants valides sont visibles avec `!draw show all`"
|
2020-04-27 09:43:16 +00:00
|
|
|
)
|
|
|
|
else:
|
|
|
|
await tirage.show(ctx)
|
|
|
|
|
|
|
|
|
|
|
|
def setup(bot):
|
|
|
|
bot.add_cog(TirageCog(bot))
|