added config command to disable rhymes
This commit is contained in:
parent
b38d596bca
commit
4e966eb821
@ -9,7 +9,7 @@ https://git.epicsparrow.com/Anselme/SparrowBot/src/branch/master/app/fourasmodul
|
|||||||
`/fouras` pour demander une énigme
|
`/fouras` pour demander une énigme
|
||||||
`/indice` pour demander un indice sur l'énigme courante
|
`/indice` pour demander un indice sur l'énigme courante
|
||||||
|
|
||||||
`/fouras_requete` pour demander une énigme précise
|
`/requete` pour demander une énigme précise
|
||||||
`/repete` pour que le père fouras répète l'énigme (pratique si vous avez la flemme de scroller quand il y a eu plein de messages)
|
`/repete` pour que le père fouras répète l'énigme (pratique si vous avez la flemme de scroller quand il y a eu plein de messages)
|
||||||
|
|
||||||
# Pour les admins
|
# Pour les admins
|
||||||
@ -18,6 +18,8 @@ https://git.epicsparrow.com/Anselme/SparrowBot/src/branch/master/app/fourasmodul
|
|||||||
Un administrateur du serveur doit cliquer sur ce lien :
|
Un administrateur du serveur doit cliquer sur ce lien :
|
||||||
https://discord.com/api/oauth2/authorize?client_id=1110208055171367014&permissions=274877975552&scope=bot
|
https://discord.com/api/oauth2/authorize?client_id=1110208055171367014&permissions=274877975552&scope=bot
|
||||||
|
|
||||||
|
## Comment configurer ou désactiver les "poil au"
|
||||||
|
`/config [ratio]` ratio est multiplié au cooldown aléatoire des "poil au", un ratio négatif désactive complètement la feature
|
||||||
|
|
||||||
# Pour les développeurs
|
# Pour les développeurs
|
||||||
|
|
||||||
|
|||||||
143
database.py
143
database.py
@ -1,11 +1,43 @@
|
|||||||
# database.py
|
# database.py
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from datetime import datetime
|
import random
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, Tuple
|
from typing import Any, Dict, Tuple
|
||||||
|
|
||||||
DB_FILE = "data/database.db"
|
DB_FILE = "data/database.db"
|
||||||
|
|
||||||
|
# guild-state queries
|
||||||
|
CREATE_GUILD_STATE_QUERY = """
|
||||||
|
INSERT INTO guild_state (guild_id, cooldown_until, cooldown_ratio, self_control, last_updated)
|
||||||
|
VALUES (?, datetime('now'), 1.0, 1.0, datetime('now'))
|
||||||
|
"""
|
||||||
|
|
||||||
|
GET_GUILD_STATE_QUERY = """
|
||||||
|
SELECT cooldown_until, cooldown_ratio, self_control, last_updated
|
||||||
|
FROM guild_state
|
||||||
|
WHERE guild_id = ?
|
||||||
|
"""
|
||||||
|
|
||||||
|
CONFIGURE_COOLDOWN_RATIO_QUERY = """
|
||||||
|
UPDATE guild_state
|
||||||
|
SET cooldown_ratio = ?
|
||||||
|
WHERE guild_id = ?
|
||||||
|
"""
|
||||||
|
|
||||||
|
DAMAGE_SELF_CONTROL_QUERY = """
|
||||||
|
UPDATE guild_state
|
||||||
|
SET self_control = self_control * 0.9
|
||||||
|
WHERE guild_id = ?
|
||||||
|
"""
|
||||||
|
|
||||||
|
RESET_COOLDOWN_QUERY = """
|
||||||
|
UPDATE guild_state
|
||||||
|
SET cooldown_until = ?,
|
||||||
|
self_control = self_control + 1.0,
|
||||||
|
last_updated = datetime('now')
|
||||||
|
WHERE guild_id = ?
|
||||||
|
"""
|
||||||
|
|
||||||
def ensure_db() -> None:
|
def ensure_db() -> None:
|
||||||
"""Initialize SQLite database and create tables if needed."""
|
"""Initialize SQLite database and create tables if needed."""
|
||||||
@ -16,7 +48,6 @@ def ensure_db() -> None:
|
|||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS guild_state (
|
CREATE TABLE IF NOT EXISTS guild_state (
|
||||||
guild_id TEXT PRIMARY KEY,
|
guild_id TEXT PRIMARY KEY,
|
||||||
guild_name TEXT NOT NULL DEFAULT '',
|
|
||||||
cooldown_until TEXT NOT NULL DEFAULT '1970-01-01T00:00:00',
|
cooldown_until TEXT NOT NULL DEFAULT '1970-01-01T00:00:00',
|
||||||
cooldown_ratio REAL NOT NULL DEFAULT 1.0,
|
cooldown_ratio REAL NOT NULL DEFAULT 1.0,
|
||||||
self_control REAL NOT NULL DEFAULT 1.0,
|
self_control REAL NOT NULL DEFAULT 1.0,
|
||||||
@ -45,96 +76,61 @@ def get_connection() -> sqlite3.Connection:
|
|||||||
|
|
||||||
|
|
||||||
def get_guild_state(guild_id: str) -> Dict[str, Any]:
|
def get_guild_state(guild_id: str) -> Dict[str, Any]:
|
||||||
"""Retrieve guild state from database."""
|
|
||||||
with get_connection() as conn:
|
with get_connection() as conn:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute(
|
cursor.execute(GET_GUILD_STATE_QUERY,(guild_id,))
|
||||||
"""
|
|
||||||
SELECT guild_id, guild_name, cooldown_until, cooldown_ratio, self_control, last_updated
|
|
||||||
FROM guild_state WHERE guild_id = ?
|
|
||||||
""",
|
|
||||||
(guild_id,),
|
|
||||||
)
|
|
||||||
row = cursor.fetchone()
|
row = cursor.fetchone()
|
||||||
|
|
||||||
|
if not row:
|
||||||
|
cursor.execute(CREATE_GUILD_STATE_QUERY, (guild_id,))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
cursor.execute(GET_GUILD_STATE_QUERY,(guild_id,))
|
||||||
|
row = cursor.fetchone()
|
||||||
|
|
||||||
if row:
|
if row:
|
||||||
return {
|
return {
|
||||||
"guild_id": row["guild_id"],
|
|
||||||
"guild_name": row["guild_name"],
|
|
||||||
"cooldown_until": row["cooldown_until"],
|
"cooldown_until": row["cooldown_until"],
|
||||||
"cooldown_ratio": row["cooldown_ratio"],
|
"cooldown_ratio": row["cooldown_ratio"],
|
||||||
"self_control": row["self_control"],
|
"self_control": row["self_control"],
|
||||||
"last_updated": row["last_updated"],
|
"last_updated": row["last_updated"],
|
||||||
}
|
}
|
||||||
else:
|
return {}
|
||||||
return {
|
|
||||||
"guild_id": guild_id,
|
|
||||||
"guild_name": "",
|
|
||||||
"cooldown_until": "1970-01-01T00:00:00",
|
|
||||||
"cooldown_ratio": 1.0,
|
|
||||||
"self_control": 1.0,
|
|
||||||
"last_updated": datetime.now().isoformat(),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def update_guild_state(
|
def rhyme_configure_cooldown_ratio(guild_id: str, cooldown_ratio: float) -> bool:
|
||||||
guild_id: str, guild_name: str, cooldown_until: str, cooldown_ratio: float, self_control: float
|
with get_connection() as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute(CONFIGURE_COOLDOWN_RATIO_QUERY, (cooldown_ratio, guild_id,))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def rhyme_damage_self_control(guild_id: str) -> None:
|
||||||
|
with get_connection() as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute(DAMAGE_SELF_CONTROL_QUERY, (guild_id,))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def rhyme_reset_cooldown(
|
||||||
|
guild_id: str,
|
||||||
|
ratio: float
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Update guild state in database."""
|
|
||||||
with get_connection() as conn:
|
with get_connection() as conn:
|
||||||
|
# Calculate new cooldown duration
|
||||||
|
wait_time = random.randint(900, 10800) if bool(random.getrandbits(1)) else random.randint(0, 900)
|
||||||
|
wait_time = 0 if ratio < 0 else int(wait_time * ratio)
|
||||||
|
cooldown_until = datetime.now().replace(second=0, microsecond=0) + timedelta(seconds=wait_time)
|
||||||
|
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute(
|
cursor.execute(RESET_COOLDOWN_QUERY, (cooldown_until.isoformat(), guild_id,))
|
||||||
"""
|
|
||||||
INSERT OR REPLACE INTO guild_state (guild_id, guild_name, cooldown_until, cooldown_ratio, self_control, last_updated)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
|
||||||
""",
|
|
||||||
(
|
|
||||||
guild_id,
|
|
||||||
guild_name,
|
|
||||||
cooldown_until,
|
|
||||||
cooldown_ratio,
|
|
||||||
self_control,
|
|
||||||
datetime.now().isoformat(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
def delete_guild_state(guild_id: str) -> bool:
|
|
||||||
"""Delete guild state from database."""
|
|
||||||
with get_connection() as conn:
|
|
||||||
cursor = conn.cursor()
|
|
||||||
cursor.execute("DELETE FROM guild_state WHERE guild_id = ?", (guild_id,))
|
|
||||||
conn.commit()
|
|
||||||
return cursor.rowcount > 0
|
|
||||||
|
|
||||||
|
|
||||||
def get_all_guild_states() -> Dict[str, Dict[str, Any]]:
|
|
||||||
"""Retrieve all guild states (for debug purposes)."""
|
|
||||||
with get_connection() as conn:
|
|
||||||
cursor = conn.cursor()
|
|
||||||
cursor.execute(
|
|
||||||
"SELECT guild_id, guild_name, cooldown_until, cooldown_ratio, self_control, last_updated FROM guild_state"
|
|
||||||
)
|
|
||||||
return {
|
|
||||||
row["guild_id"]: {
|
|
||||||
"guild_name": row["guild_name"],
|
|
||||||
"cooldown_until": row["cooldown_until"],
|
|
||||||
"cooldown_ratio": row["cooldown_ratio"],
|
|
||||||
"self_control": row["self_control"],
|
|
||||||
"last_updated": row["last_updated"],
|
|
||||||
}
|
|
||||||
for row in cursor.fetchall()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def get_active_riddle(channel_id: str):
|
def get_active_riddle(channel_id: str):
|
||||||
"""Récupérer une énigme active pour un canal spécifique."""
|
|
||||||
with get_connection() as conn:
|
with get_connection() as conn:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute(
|
cursor.execute("SELECT * FROM active_riddles WHERE channel_id = ?", (str(channel_id),))
|
||||||
"SELECT * FROM active_riddles WHERE channel_id = ?", (str(channel_id),)
|
|
||||||
)
|
|
||||||
row = cursor.fetchone()
|
row = cursor.fetchone()
|
||||||
|
|
||||||
if row:
|
if row:
|
||||||
@ -157,7 +153,6 @@ def save_active_riddle(
|
|||||||
message_id: int,
|
message_id: int,
|
||||||
solver_id: str = None,
|
solver_id: str = None,
|
||||||
):
|
):
|
||||||
"""Sauvegarder ou mettre à jour une énigme active."""
|
|
||||||
with get_connection() as conn:
|
with get_connection() as conn:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
# Si solver_id existe, on considère que c'est résolu et on garde l'entrée pour historique
|
# Si solver_id existe, on considère que c'est résolu et on garde l'entrée pour historique
|
||||||
@ -169,7 +164,7 @@ def save_active_riddle(
|
|||||||
(channel_id, riddle_index, nb_clues, message_id, solver_id, updated_at)
|
(channel_id, riddle_index, nb_clues, message_id, solver_id, updated_at)
|
||||||
VALUES (?, ?, ?, ?, ?, datetime('now'))
|
VALUES (?, ?, ?, ?, ?, datetime('now'))
|
||||||
""",
|
""",
|
||||||
(str(channel_id), riddle_index, nb_clues, message_id, solver_id),
|
(str(channel_id), riddle_index, nb_clues, message_id, solver_id)
|
||||||
)
|
)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
@ -178,9 +173,7 @@ def remove_active_riddle(channel_id: str) -> bool:
|
|||||||
"""Supprimer une énigme active du suivi."""
|
"""Supprimer une énigme active du suivi."""
|
||||||
with get_connection() as conn:
|
with get_connection() as conn:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute(
|
cursor.execute("DELETE FROM active_riddles WHERE channel_id = ?", (str(channel_id),))
|
||||||
"DELETE FROM active_riddles WHERE channel_id = ?", (str(channel_id),)
|
|
||||||
)
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
return cursor.rowcount > 0
|
return cursor.rowcount > 0
|
||||||
|
|
||||||
|
|||||||
107
fouras.py
107
fouras.py
@ -3,7 +3,7 @@ import json
|
|||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord import Interaction, app_commands
|
from discord import Interaction, app_commands
|
||||||
@ -30,6 +30,14 @@ Code Source : https://git.epicsparrow.com/Anselme/perefouras
|
|||||||
Ajouter ce bot à votre serveur : {url}
|
Ajouter ce bot à votre serveur : {url}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
BUG_REPORT = """
|
||||||
|
BUG REPORT from {user} (`{user_id}`) in channel {channel} (`{channel_id}`) :
|
||||||
|
> {message}
|
||||||
|
|
||||||
|
History :
|
||||||
|
```json\n{history}```
|
||||||
|
"""
|
||||||
|
|
||||||
SUCCESS = """
|
SUCCESS = """
|
||||||
Bravo {user} ! La réponse était bien `{answer}`.
|
Bravo {user} ! La réponse était bien `{answer}`.
|
||||||
"""
|
"""
|
||||||
@ -146,42 +154,6 @@ async def handle_debug_commands(message, client: discord.Client) -> bool:
|
|||||||
"""Handle debug commands (debug, save, load, broadcast). Returns True if handled."""
|
"""Handle debug commands (debug, save, load, broadcast). Returns True if handled."""
|
||||||
message_content = message.content.lower()
|
message_content = message.content.lower()
|
||||||
|
|
||||||
if message_content == "debug fouras":
|
|
||||||
if message.author.id == MAINTAINER_ID:
|
|
||||||
# Récupération depuis la DB au lieu d'une variable globale
|
|
||||||
db_riddles = database.get_all_active_riddles()
|
|
||||||
|
|
||||||
dump = {}
|
|
||||||
for riddle_data in db_riddles:
|
|
||||||
try:
|
|
||||||
channel = await client.fetch_channel(int(riddle_data["channel_id"]))
|
|
||||||
channel_name = await get_channel_name(channel, client)
|
|
||||||
|
|
||||||
# Reconstruction partielle pour l'affichage
|
|
||||||
riddle_info = {
|
|
||||||
"riddle_index": riddle_data["riddle_index"],
|
|
||||||
"nb_clues": riddle_data["nb_clues"],
|
|
||||||
"message_id": riddle_data["message_id"],
|
|
||||||
"solver_id": riddle_data["solver_id"],
|
|
||||||
"created_at": riddle_data["created_at"],
|
|
||||||
"updated_at": riddle_data["updated_at"],
|
|
||||||
}
|
|
||||||
|
|
||||||
# On ajoute le texte de l'énigme si disponible
|
|
||||||
if 0 <= riddle_data["riddle_index"] < len(riddles):
|
|
||||||
riddle_info["text"] = (
|
|
||||||
riddles[riddle_data["riddle_index"]][:50] + "..."
|
|
||||||
)
|
|
||||||
|
|
||||||
dump[channel_name] = riddle_info
|
|
||||||
except Exception as e:
|
|
||||||
dump[f"Channel_{riddle_data['channel_id']}"] = {"error": str(e)}
|
|
||||||
|
|
||||||
await message.author.send(
|
|
||||||
"```json\n{0}```".format(json.dumps(dump, ensure_ascii=False, indent=4))
|
|
||||||
)
|
|
||||||
return True
|
|
||||||
|
|
||||||
broadcast_match = re.match(r"^broadcast\s+(\d+) (.*)", message.content)
|
broadcast_match = re.match(r"^broadcast\s+(\d+) (.*)", message.content)
|
||||||
if broadcast_match and message.author.id == MAINTAINER_ID:
|
if broadcast_match and message.author.id == MAINTAINER_ID:
|
||||||
index = int(broadcast_match.group(1))
|
index = int(broadcast_match.group(1))
|
||||||
@ -293,7 +265,7 @@ async def handle_bug_report(message, client: discord.Client) -> bool:
|
|||||||
channel_id=message.channel.id,
|
channel_id=message.channel.id,
|
||||||
message=message.content,
|
message=message.content,
|
||||||
history=messages_json,
|
history=messages_json,
|
||||||
state=state_json,
|
# state=state_json,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
await message.channel.send(
|
await message.channel.send(
|
||||||
@ -322,18 +294,6 @@ async def handle_message(message, client: discord.Client) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
async def new_riddle(interaction: Interaction, index: int) -> None:
|
async def new_riddle(interaction: Interaction, index: int) -> None:
|
||||||
class ConfirmRiddle(discord.ui.View):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__(timeout=60)
|
|
||||||
|
|
||||||
@discord.ui.button(label="Oui", style=discord.ButtonStyle.success)
|
|
||||||
async def yes(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
||||||
await interaction.response.send_message("Confirmé.", ephemeral=True)
|
|
||||||
|
|
||||||
@discord.ui.button(label="Non", style=discord.ButtonStyle.danger)
|
|
||||||
async def no(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
||||||
await interaction.response.send_message("Annulé.", ephemeral=True)
|
|
||||||
|
|
||||||
if random.random() <= 0.03:
|
if random.random() <= 0.03:
|
||||||
await interaction.response.send_message("Non")
|
await interaction.response.send_message("Non")
|
||||||
else:
|
else:
|
||||||
@ -375,11 +335,11 @@ def setup_commands(client: discord.Client, tree) -> None:
|
|||||||
|
|
||||||
|
|
||||||
@tree.command(
|
@tree.command(
|
||||||
name="fouras_requete",
|
name="requete",
|
||||||
description="Demander une énigme spécifique au Père Fouras"
|
description="Demander une énigme spécifique au Père Fouras"
|
||||||
)
|
)
|
||||||
@app_commands.describe(index="Numéro de l'énigme")
|
@app_commands.describe(index="Numéro de l'énigme")
|
||||||
async def fouras_requete(
|
async def requete(
|
||||||
interaction: discord.Interaction,
|
interaction: discord.Interaction,
|
||||||
index: int,
|
index: int,
|
||||||
):
|
):
|
||||||
@ -413,15 +373,15 @@ def setup_commands(client: discord.Client, tree) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@tree.command(
|
# @tree.command(
|
||||||
name="about",
|
# name="about",
|
||||||
description="Qui est le Père Fouras ?"
|
# description="Qui est le Père Fouras ?"
|
||||||
)
|
# )
|
||||||
async def about(
|
# async def about(
|
||||||
interaction: discord.Interaction,
|
# interaction: discord.Interaction,
|
||||||
):
|
# ):
|
||||||
author_user = await client.fetch_user(AUTHOR_ID)
|
# author_user = await client.fetch_user(AUTHOR_ID)
|
||||||
await interaction.response.send_message(ABOUT.format(user=author_user.mention, url=API_URL), ephemeral=True)
|
# await interaction.response.send_message(ABOUT.format(user=author_user.mention, url=API_URL), ephemeral=True)
|
||||||
|
|
||||||
|
|
||||||
@tree.command(
|
@tree.command(
|
||||||
@ -459,28 +419,3 @@ def setup_commands(client: discord.Client, tree) -> None:
|
|||||||
if(not await update_riddle_message(interaction.channel, current_riddle)):
|
if(not await update_riddle_message(interaction.channel, current_riddle)):
|
||||||
return
|
return
|
||||||
await interaction.response.send_message("Nouvel indice : `{0}`".format(clue_string(answer, nb_clues)))
|
await interaction.response.send_message("Nouvel indice : `{0}`".format(clue_string(answer, nb_clues)))
|
||||||
|
|
||||||
@tree.command(
|
|
||||||
name="testmodal"
|
|
||||||
)
|
|
||||||
async def testmodal(
|
|
||||||
interaction: Interaction
|
|
||||||
):
|
|
||||||
class Confirm(discord.ui.View):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__(timeout=60)
|
|
||||||
|
|
||||||
@discord.ui.button(label="Oui", style=discord.ButtonStyle.success)
|
|
||||||
async def yes(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
||||||
await interaction.response.send_message("✅ Confirmé.", ephemeral=True)
|
|
||||||
|
|
||||||
@discord.ui.button(label="Non", style=discord.ButtonStyle.danger)
|
|
||||||
async def no(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
||||||
await interaction.response.send_message("❌ Annulé.", ephemeral=True)
|
|
||||||
|
|
||||||
view = Confirm()
|
|
||||||
await interaction.response.send_message(
|
|
||||||
"Es-tu sûr ?",
|
|
||||||
view=view,
|
|
||||||
ephemeral=True
|
|
||||||
)
|
|
||||||
|
|||||||
3
main.py
3
main.py
@ -26,7 +26,7 @@ async def on_ready():
|
|||||||
"""Initialize bot state and sync commands."""
|
"""Initialize bot state and sync commands."""
|
||||||
# Import initialization functions
|
# Import initialization functions
|
||||||
from fouras import load_riddles, setup_commands
|
from fouras import load_riddles, setup_commands
|
||||||
from rhymes import ensure_log_file, load_rhymes
|
from rhymes import ensure_log_file, load_rhymes, setup_rhymes_commands
|
||||||
|
|
||||||
# Ensure directories exist
|
# Ensure directories exist
|
||||||
ensure_log_file()
|
ensure_log_file()
|
||||||
@ -36,6 +36,7 @@ async def on_ready():
|
|||||||
|
|
||||||
# register fouras commands
|
# register fouras commands
|
||||||
setup_commands(client, tree)
|
setup_commands(client, tree)
|
||||||
|
setup_rhymes_commands(client, tree)
|
||||||
|
|
||||||
# Load rhymes
|
# Load rhymes
|
||||||
success, msg = load_rhymes()
|
success, msg = load_rhymes()
|
||||||
|
|||||||
@ -932,7 +932,7 @@ Qui parlent souvent d'amour
|
|||||||
|
|
||||||
D'une grande dureté est le bois de son cœur
|
D'une grande dureté est le bois de son cœur
|
||||||
Son nom témoigne de sa couleur
|
Son nom témoigne de sa couleur
|
||||||
Taillé, sculpté elle est exotique
|
Taillée, sculptée elle est exotique
|
||||||
Elle fait l'objet d'un certain trafic
|
Elle fait l'objet d'un certain trafic
|
||||||
|
|
||||||
Elle plonge dans un bruit
|
Elle plonge dans un bruit
|
||||||
|
|||||||
150
rhymes.py
150
rhymes.py
@ -4,6 +4,8 @@ import random
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, Tuple
|
from typing import Any, Dict, Tuple
|
||||||
|
import discord
|
||||||
|
from discord import Interaction, app_commands
|
||||||
|
|
||||||
import database
|
import database
|
||||||
|
|
||||||
@ -74,71 +76,6 @@ async def get_guild_name(guildId, client) -> str:
|
|||||||
return "[Server={0}]".format(guild.name)
|
return "[Server={0}]".format(guild.name)
|
||||||
|
|
||||||
|
|
||||||
async def handle_debug_commands(message, client) -> bool:
|
|
||||||
"""Handle debug commands (debug, save, load). Returns True if handled."""
|
|
||||||
message_content = message.content.lower()
|
|
||||||
|
|
||||||
if message_content == "debug poilau":
|
|
||||||
if message.author.id == 151626081458192384:
|
|
||||||
all_states = database.get_all_guild_states()
|
|
||||||
dump = {}
|
|
||||||
for guild_id, state in all_states.items():
|
|
||||||
channel_name = await get_guild_name(guild_id, client)
|
|
||||||
cooldown_dt = datetime.fromisoformat(state["cooldown_until"])
|
|
||||||
time_remaining = max(0, (cooldown_dt - datetime.now()).total_seconds())
|
|
||||||
sleeping_time = "{:.2f} s".format(time_remaining)
|
|
||||||
dump[channel_name] = {
|
|
||||||
"cooldown_until": state["cooldown_until"],
|
|
||||||
"cooldown_ratio": state["cooldown_ratio"],
|
|
||||||
"cooldown_remaining": sleeping_time,
|
|
||||||
"self-control": state["self_control"],
|
|
||||||
"last_updated": state["last_updated"],
|
|
||||||
}
|
|
||||||
await message.author.send(
|
|
||||||
"```json\n{0}```".format(json.dumps(dump, ensure_ascii=False, indent=2))
|
|
||||||
)
|
|
||||||
return True
|
|
||||||
|
|
||||||
if message_content == "save poilau":
|
|
||||||
if message.author.id == 151626081458192384:
|
|
||||||
all_states = database.get_all_guild_states()
|
|
||||||
json_str = "```json\n{0}```".format(
|
|
||||||
json.dumps(all_states, ensure_ascii=False, indent=2)
|
|
||||||
)
|
|
||||||
await message.author.send("State persisted in SQLite database")
|
|
||||||
await message.author.send(json_str)
|
|
||||||
return True
|
|
||||||
|
|
||||||
if message_content == "load poilau":
|
|
||||||
if message.author.id == 151626081458192384:
|
|
||||||
success, msg = load_rhymes()
|
|
||||||
all_states = database.get_all_guild_states()
|
|
||||||
json_str = "```json\n{0}```".format(
|
|
||||||
json.dumps(all_states, ensure_ascii=False, indent=2)
|
|
||||||
)
|
|
||||||
await message.author.send(msg)
|
|
||||||
await message.author.send(json_str)
|
|
||||||
return True
|
|
||||||
|
|
||||||
if message_content == "tg fouras" and message.guild:
|
|
||||||
# Disable cooldown for this server (set to far future)
|
|
||||||
cooldown_date = datetime.now().replace(
|
|
||||||
hour=0, minute=0, second=0, microsecond=0
|
|
||||||
)
|
|
||||||
cooldown_date = cooldown_date.replace(day=cooldown_date.day + 10000)
|
|
||||||
database.update_guild_state(
|
|
||||||
str(message.guild.id),
|
|
||||||
guild_name=message.guild.name,
|
|
||||||
cooldown_until=cooldown_date.isoformat(),
|
|
||||||
cooldown_ratio=1.0,
|
|
||||||
self_control=2.0,
|
|
||||||
)
|
|
||||||
await message.channel.send("ok :'(")
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
async def handle_rhyme_logic(message, client) -> bool:
|
async def handle_rhyme_logic(message, client) -> bool:
|
||||||
"""Main rhyme detection logic. Returns True if rhyme was triggered."""
|
"""Main rhyme detection logic. Returns True if rhyme was triggered."""
|
||||||
message_content = message.content.lower()
|
message_content = message.content.lower()
|
||||||
@ -147,57 +84,28 @@ async def handle_rhyme_logic(message, client) -> bool:
|
|||||||
if message.author != client.user and message.guild and last_word:
|
if message.author != client.user and message.guild and last_word:
|
||||||
rhyme = find_rhyme(last_word)
|
rhyme = find_rhyme(last_word)
|
||||||
guild_id = str(message.guild.id)
|
guild_id = str(message.guild.id)
|
||||||
guild_name = message.guild.name
|
|
||||||
|
|
||||||
if rhyme:
|
if rhyme:
|
||||||
guild_state = database.get_guild_state(guild_id)
|
guild_state = database.get_guild_state(guild_id)
|
||||||
|
cooldown_ratio = guild_state["cooldown_ratio"]
|
||||||
|
|
||||||
# Update guild name if changed
|
if cooldown_ratio >= 0:
|
||||||
if guild_state["guild_name"] != guild_name:
|
# Check cooldown
|
||||||
database.update_guild_state(
|
cooldown_dt = datetime.fromisoformat(guild_state["cooldown_until"])
|
||||||
guild_id,
|
now_dt = datetime.now()
|
||||||
guild_name=guild_name,
|
|
||||||
cooldown_until=guild_state["cooldown_until"],
|
|
||||||
cooldown_ratio=guild_state["cooldown_ratio"],
|
|
||||||
self_control=guild_state["self_control"],
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check cooldown
|
if now_dt >= cooldown_dt:
|
||||||
cooldown_dt = datetime.fromisoformat(guild_state["cooldown_until"])
|
self_control = guild_state["self_control"]
|
||||||
now_dt = datetime.now()
|
|
||||||
|
|
||||||
if now_dt >= cooldown_dt:
|
# Probability check
|
||||||
self_control = guild_state["self_control"]
|
if random.random() < self_control:
|
||||||
|
database.rhyme_damage_self_control(guild_id)
|
||||||
|
return False
|
||||||
|
|
||||||
# Probability check
|
database.rhyme_reset_cooldown(guild_id, cooldown_ratio)
|
||||||
if random.random() < self_control:
|
|
||||||
new_self_control = self_control * 0.9
|
|
||||||
database.update_guild_state(
|
|
||||||
guild_id,
|
|
||||||
guild_name=guild_name,
|
|
||||||
cooldown_until=now_dt.isoformat(),
|
|
||||||
cooldown_ratio=1.0,
|
|
||||||
self_control=new_self_control,
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Calculate new cooldown duration
|
await message.channel.send(rhyme)
|
||||||
wait_time = random.randint(0, 900)
|
return True
|
||||||
if bool(random.getrandbits(1)):
|
|
||||||
wait_time = random.randint(900, 10800)
|
|
||||||
|
|
||||||
new_cooldown_dt = now_dt.replace(second=0, microsecond=0) + timedelta(seconds=wait_time)
|
|
||||||
|
|
||||||
database.update_guild_state(
|
|
||||||
guild_id,
|
|
||||||
guild_name=guild_name,
|
|
||||||
cooldown_until=new_cooldown_dt.isoformat(),
|
|
||||||
cooldown_ratio=1.0,
|
|
||||||
self_control=self_control + 1.0,
|
|
||||||
)
|
|
||||||
|
|
||||||
await message.channel.send(rhyme)
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -208,9 +116,27 @@ async def handle_message(message, client) -> bool:
|
|||||||
database.ensure_db()
|
database.ensure_db()
|
||||||
ensure_log_file()
|
ensure_log_file()
|
||||||
|
|
||||||
# Handle debug commands first
|
|
||||||
if await handle_debug_commands(message, client):
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Process rhyme logic
|
# Process rhyme logic
|
||||||
return await handle_rhyme_logic(message, client)
|
return await handle_rhyme_logic(message, client)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_rhymes_commands(client: discord.Client, tree: discord.app_commands.CommandTree) -> None:
|
||||||
|
@tree.command(
|
||||||
|
name="config",
|
||||||
|
description="Permet de configurer à quel point le Père Fouras est relou"
|
||||||
|
)
|
||||||
|
@app_commands.default_permissions(manage_guild=True)
|
||||||
|
@app_commands.checks.has_permissions(manage_guild=True)
|
||||||
|
@app_commands.describe(ratio="ratio de cooldown (0 = )")
|
||||||
|
async def config(
|
||||||
|
interaction: discord.Interaction,
|
||||||
|
ratio: float
|
||||||
|
):
|
||||||
|
guild_id: str = str(interaction.guild_id)
|
||||||
|
guild_state = database.get_guild_state(guild_id)
|
||||||
|
database.rhyme_configure_cooldown_ratio(guild_id, ratio)
|
||||||
|
msg = f"Le ratio de cooldown passe de {guild_state["cooldown_ratio"]:.2f} à {ratio:.2f} pour le serveur {interaction.guild.name}"
|
||||||
|
if ratio < 0:
|
||||||
|
await interaction.response.send_message(f"{msg}\nLes \"poil au\" sont désormais désactivés.", ephemeral=True)
|
||||||
|
else:
|
||||||
|
await interaction.response.send_message(f"{msg}\nLes \"poil au\" ont désormais un cooldown entre 0 et {int(180*ratio)} minutes.", ephemeral=True)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user