perefouras/fouras.py
2023-05-25 07:56:06 +00:00

156 lines
6.2 KiB
Python

import discord
from discord.ext import tasks
import os
import asyncio
from datetime import datetime, timedelta, timezone
import random
from dotenv import load_dotenv
import re
intents = discord.Intents.default()
intents.members = True
intents.presences = True
intents.guilds = True
intents.messages = True
intents.message_content = True
client = discord.Client(intents=intents)
load_dotenv()
token = os.getenv('DISCORD_TOKEN', "NO_TOKEN")
client.riddles = []
client.answers = []
client.ongoing_riddles = {}
def load_riddles():
with open('riddles.txt', 'r', encoding='utf-8') as r_file:
client.riddles = r_file.read().split('\n\n')
with open('answers.txt', 'r', encoding='utf-8') as a_file:
client.answers = [line.strip() for line in a_file.readlines()]
print('Loaded {0} riddles'.format(len(client.riddles)))
def new_riddle(channel, index):
current_riddle = dict(index=index, nbClues=-1, riddle=client.riddles[index].strip(), answer=client.answers[index])
client.ongoing_riddles[channel] = current_riddle
return format_message(current_riddle)
def finish_riddle(channel):
del client.ongoing_riddles[channel]
def clue_string(answer, nbClues):
finalString = "_"
for i in range(len(answer) - 1):
finalString += " _"
random.seed(hash(answer))
nbRevealed = 0
for i in range(nbClues):
id = random.randint(0, len(answer) - 1)
while finalString[id * 2] != '_':
id = random.randint(0, len(answer) - 1)
nbRevealed += 1
finalString = finalString[:id * 2] + answer[id] + finalString[id * 2 + 1:]
if nbRevealed == len(answer):
return finalString
return finalString
def format_message(current_riddle):
nbClues = current_riddle['nbClues']
answer = current_riddle['answer']
formatted_riddle = "> " + current_riddle['riddle'].replace("\n", "\n> ")
formatted_riddle = formatted_riddle.replace("\r", "")
clue = ""
if nbClues > -1:
if nbClues >= len(answer):
clue = clue + "\nNon trouvée, la solution était : `{0}`".format(answer)
else:
clue = clue + "\nIndice : `{0}`".format(clue_string(answer, nbClues))
if 'solver' in current_riddle:
clue = clue + "\n{0} a trouvé la solution, qui était : `{1}`".format(current_riddle['solver'].mention, answer)
if clue:
return "Énigme {0}:\n{1}\n{2}".format(current_riddle['index'] + 1, formatted_riddle, clue)
else:
return "Énigme {0}:\n{1}".format(current_riddle['index'] + 1, formatted_riddle)
@client.event
async def on_ready():
load_riddles()
print('Logged in as {0.user}'.format(client))
@client.event
async def on_message(message):
# don't answer to self
if message.author == client.user and message.channel in client.ongoing_riddles:
current_riddle = client.ongoing_riddles[message.channel]
if not ('message' in current_riddle):
current_riddle['message'] = message
return
if isinstance(message.channel, discord.DMChannel) or isinstance(message.channel, discord.TextChannel) or isinstance(message.channel, discord.Thread):
message_content = message.content.lower()
# command fouras
fouras_match = re.match(r"^fouras\s+(\d+)$", message_content)
if fouras_match:
index = int(fouras_match.group(1)) - 1
if index >= 0 and index < len(client.riddles):
await message.channel.send(new_riddle(message.channel, index))
else:
await message.channel.send("Numéro d'énigme invalide, merci de saisir un numéro entre 1 et {0}".format(len(client.riddles)))
return
if message_content == 'fouras':
if random.random() <= 0.03:
await message.channel.send("Non")
return
if len(client.riddles) > 0:
index = random.randint(0, len(client.riddles) - 1)
await message.channel.send(new_riddle(message.channel, index))
return
# command reload
if message_content == 'reload_riddles':
load_riddles()
await message.channel.send('Loaded {0} riddles'.format(len(client.riddles)))
return
# if current channel has ongoing riddle
if message.channel in client.ongoing_riddles:
current_riddle = client.ongoing_riddles[message.channel]
if 'message' in current_riddle:
answer = current_riddle["answer"]
if answer.lower() in message_content:
current_riddle["solver"] = message.author
await message.channel.send(f"Bravo {message.author.mention} ! La réponse était bien `{answer}`.")
await current_riddle['message'].edit(content=format_message(current_riddle))
finish_riddle(message.channel)
return
if message_content == 'repete' or message_content == 'répète' or message_content == 'repeat':
current_riddle.pop('message')
await message.channel.send(format_message(current_riddle))
return
# Commande /clue : révèle une lettre au hasard de la réponse attendue
if message_content == 'indice' or message_content == 'aide' or message_content == 'connard de fouras':
nbClues = current_riddle["nbClues"] + 1
current_riddle["nbClues"] = nbClues
if nbClues >= len(answer):
reply = "Perdu ! La réponse était : `{0}`".format(answer)
await message.channel.send(reply)
# else:
# reply = "Indice : `{0}`".format(clue_string(answer, nbClues))
await current_riddle['message'].edit(content=format_message(current_riddle))
if nbClues >= len(answer):
finish_riddle(message.channel)
return
# Initialise le client
client.run(token)