This commit is contained in:
Louis Chauvet 2020-04-05 12:08:43 +02:00
commit 59f58df037
Signed by: fomys
GPG Key ID: 1ECA046A9615ABA0
18 changed files with 500 additions and 146 deletions

28
main.py
View File

@ -395,17 +395,33 @@ class ClientById:
channel = self.client.get_channel(id_) channel = self.client.get_channel(id_)
return channel.send(*args, **kwargs) return channel.send(*args, **kwargs)
async def get_role(self, id_=None, name=None): async def get_role(self, id_=None, name=None, guild=None, case_sensitive=True):
guilds = self.client.guilds
if guild is not None:
guilds = [guild]
if id_ is not None: if id_ is not None:
for guild in self.client.guilds: for guild in guilds:
role = discord.utils.get(guild.roles, id=id_) role = discord.utils.get(guild.roles, id=id_)
if role: if role:
return role return role
if name is not None: if name is not None:
for guild in self.client.guilds: if case_sensitive:
role = discord.utils.get(guild.roles, name=name) for guild in guilds:
if role: role = discord.utils.get(guild.roles, name=name)
return role if role:
return role
else:
name = name.lower()
role = None
for guild in guilds:
for role_ in guild.roles:
if role_.name.lower() == name:
role = role_
break
if role is not None:
break
return role
return None return None

View File

@ -0,0 +1,56 @@
import datetime
import discord
import utils.emojis
from modules.base import BaseClassPython
class MainClass(BaseClassPython):
name = "Avalon"
help = {
"description": "Maître du jeu Avalon.",
"commands": {
"`{prefix}{command} join`": "",
"`{prefix}{command} quit`": "",
"`{prefix}{command} players list`": "",
"`{prefix}{command} players kick (<user_id>/<@mention>)`": "",
"`{prefix}{command} roles setup`": "",
"`{prefix}{command} roles list`": "",
}
}
help_active = True
command_text = "perdu"
color = 0xff6ba6
def __init__(self, client):
super().__init__(client)
self.config.init({"spectate_channel": 0,
"illustrations":{"merlin":"",
"perceval":"",
"gentil":"",
"assassin":"",
"mordred":"",
"morgane":"",
"oberon":"",
"mechant":""},
"couleurs":{"merlin":"",
"perceval":0,
"gentil":0,
"assassin":0,
"mordred":0,
"morgane":0,
"oberon":0,
"mechant":0,
"test":15},
"test":{"merlin":"",
"perceval":0,
"gentil":0,
"assassin":0,
"mordred":0,
"morgane":0,
"oberon":0,
"mechant":0,
"test":15}
})

0
modules/avalon/roles.py Normal file
View File

View File

@ -37,14 +37,17 @@ class BaseClass:
self.config.init({"authorized_roles": self.authorized_roles, "authorized_users": self.authorized_users}) self.config.init({"authorized_roles": self.authorized_roles, "authorized_users": self.authorized_users})
async def send_help(self, channel): async def send_help(self, channel):
if not self.help_active:
return
embed = discord.Embed( embed = discord.Embed(
title="[{nom}] - Aide".format(nom=self.name), title="[{nom}] - Aide".format(nom=self.name),
description=self.help["description"].format(prefix=self.client.config['prefix']), description="*" + self.help["description"].format(prefix=self.client.config['prefix']) + "*",
color=self.color color=self.color
) )
for command, description in self.help["commands"].items(): for command, description in self.help["commands"].items():
embed.add_field(name=command.format(prefix=self.client.config['prefix'], command=self.command_text), embed.add_field(name=command.format(prefix=self.client.config['prefix'], command=self.command_text),
value=description.format(prefix=self.client.config['prefix'], command=self.command_text), value="-> " + description.format(prefix=self.client.config['prefix'], command=self.command_text),
inline=False) inline=False)
await channel.send(embed=embed) await channel.send(embed=embed)
@ -165,6 +168,9 @@ class BaseClass:
Function which is executed for all command_text doesn't match with a `com_{subcommand}` function""" Function which is executed for all command_text doesn't match with a `com_{subcommand}` function"""
pass pass
async def com_help(self, message, args, kwargs):
await self.send_help(message.channel)
async def unauthorized(self, message): async def unauthorized(self, message):
await message.channel.send("Vous n'êtes pas autorisé à effectuer cette commande") await message.channel.send("Vous n'êtes pas autorisé à effectuer cette commande")

19
modules/clean/__init__.py Normal file
View File

@ -0,0 +1,19 @@
from modules.base import BaseClassPython
class MainClass(BaseClassPython):
name = "clean"
authorized_roles=[522918472548745217]
help = {
"description": "Supprime des messages",
"commands": {
"`{prefix}{command}`": "Supprime tous les messages du bot dans le salon"
}
}
command_text = "clean"
async def command(self, message, args, kwargs):
def is_me(m):
return m.author == self.client.user
deleted = await message.channel.purge(limit=10000000, check=is_me)
await message.channel.send('Deleted {} message(s)'.format(len(deleted)))

View File

@ -0,0 +1,11 @@
{
"version":"0.1.0",
"type": "python",
"dependencies": {
},
"bot_version": {
"min": "0.1.0",
"max": "0.1.0"
}
}

View File

@ -1,106 +1,106 @@
import asyncio import asyncio
import random import random
import traceback import traceback
import discord import discord
from discord import Message from discord import Message
from modules.base import BaseClassPython from modules.base import BaseClassPython
class MainClass(BaseClassPython): class MainClass(BaseClassPython):
name = "errors" name = "errors"
help_active = True help_active = True
authorized_users = [431043517217898496] authorized_users = [431043517217898496]
authorized_roles = [] authorized_roles = []
color = 0xdb1348 color = 0xdb1348
help = { help = {
"description": "Montre toutes les erreurs du bot dans discord.", "description": "Montre toutes les erreurs du bot dans discord.",
"commands": { "commands": {
"`{prefix}{command}`": "Renvoie une erreur de test.", "`{prefix}{command}`": "Renvoie une erreur de test.",
} }
} }
command_text = "unicorn" command_text = "unicorn"
def __init__(self, client): def __init__(self, client):
super().__init__(client) super().__init__(client)
self.config.init({"dev_chan": [], "memes": [""], "icon": ""}) self.config.init({"dev_chan": [], "memes": [""], "icon": ""})
self.errorsList = None self.errorsList = None
async def on_load(self): async def on_load(self):
if self.objects.save_exists('errorsList'): if self.objects.save_exists('errorsList'):
self.errorsList = self.objects.load_object('errorsList') self.errorsList = self.objects.load_object('errorsList')
else: else:
self.errorsList = [] self.errorsList = []
async def on_ready(self): async def on_ready(self):
for i in range(len(self.errorsList)): for i in range(len(self.errorsList)):
try: try:
msg_id = self.errorsList.pop(0) msg_id = self.errorsList.pop(0)
channel = self.client.get_channel(msg_id["channel_id"]) channel = self.client.get_channel(msg_id["channel_id"])
to_delete = await channel.fetch_message(msg_id["msg_id"]) to_delete = await channel.fetch_message(msg_id["msg_id"])
await to_delete.delete() await to_delete.delete()
except: except:
raise raise
await self.objects.save_object('errorsList', self.errorsList) self.objects.save_object('errorsList', self.errorsList)
async def command(self, message, args, kwargs): async def command(self, message, args, kwargs):
raise Exception("KERNEL PANIC!!!") raise Exception("KERNEL PANIC!!!")
async def on_error(self, event, *args, **kwargs): async def on_error(self, event, *args, **kwargs):
"""Send error message""" """Send error message"""
# Search first channel instance found in arg, then search in kwargs # Search first channel instance found in arg, then search in kwargs
channel = None channel = None
for arg in args: for arg in args:
if type(arg) == Message: if type(arg) == Message:
channel = arg.channel channel = arg.channel
break break
if type(arg) == discord.TextChannel: if type(arg) == discord.TextChannel:
channel = arg channel = arg
break break
if channel is None: if channel is None:
for _, v in kwargs.items(): for _, v in kwargs.items():
if type(v) == discord.Message: if type(v) == discord.Message:
channel = v.channel channel = v.channel
break break
if type(v) == discord.TextChannel: if type(v) == discord.TextChannel:
channel = v channel = v
break # Create embed break # Create embed
embed = discord.Embed( embed = discord.Embed(
title="[Erreur] Aïe :/", title="[Erreur] Aïe :/",
description="```python\n{0}```".format(traceback.format_exc()), description="```python\n{0}```".format(traceback.format_exc()),
color=self.color) color=self.color)
embed.set_image(url=random.choice(self.config.memes)) embed.set_image(url=random.choice(self.config.memes))
message_list = None message_list = None
# Send message to dev channels # Send message to dev channels
for chanid in self.config.dev_chan: for chanid in self.config.dev_chan:
try: try:
await self.client.get_channel(chanid).send( await self.client.get_channel(chanid).send(
embed=embed.set_footer(text="Ce message ne s'autodétruira pas.", icon_url=self.config.icon)) embed=embed.set_footer(text="Ce message ne s'autodétruira pas.", icon_url=self.config.icon))
except BaseException as e: except BaseException as e:
raise e raise e
# Send message to current channel if exists # Send message to current channel if exists
if channel is not None: if channel is not None:
message = await channel.send(embed=embed.set_footer(text="Ce message va s'autodétruire dans une minute", message = await channel.send(embed=embed.set_footer(text="Ce message va s'autodétruire dans une minute",
icon_url=self.config.icon)) icon_url=self.config.icon))
msg_id = {"channel_id": message.channel.id, "msg_id": message.id} msg_id = {"channel_id": message.channel.id, "msg_id": message.id}
self.errorsList.append(msg_id) self.errorsList.append(msg_id)
# Save message in errorsList now to keep them if a reboot happend during next 60 seconds # Save message in errorsList now to keep them if a reboot happend during next 60 seconds
self.objects.save_object('errorsList', self.errorsList) self.objects.save_object('errorsList', self.errorsList)
# Wait 60 seconds and delete message # Wait 60 seconds and delete message
await asyncio.sleep(60) await asyncio.sleep(60)
try: try:
channel = self.client.get_channel(msg_id["channel_id"]) channel = self.client.get_channel(msg_id["channel_id"])
delete_message = await channel.fetch_message(msg_id["msg_id"]) delete_message = await channel.fetch_message(msg_id["msg_id"])
await delete_message.delete() await delete_message.delete()
except: except:
raise raise
finally: finally:
try: try:
self.errorsList.remove(msg_id) self.errorsList.remove(msg_id)
except ValueError: except ValueError:
pass pass
# Save now to avoid deleting unkown message # Save now to avoid deleting unkown message
self.objects.save_object('errorsList', self.errorsList) self.objects.save_object('errorsList', self.errorsList)

View File

@ -0,0 +1,34 @@
import discord
import sys
from modules.base import BaseClassPython
class MainClass(BaseClassPython):
name = "NewMember"
color = 0xff071f
help_active = False
help = {
"description": "Module d'accueil",
"commands": {
}
}
def __init__(self, client):
super().__init__(client)
self.config.init({"new_role":430845952388104212,
"guild":297780867286433792,
"motd":"Bienvenue sur le serveur de la communauté d'E-penser. Nous vous prions de lire le règlement afin d'accéder au serveur complet."})
async def on_ready(self):
guild = self.client.get_guild(self.config.guild)
for i, member in enumerate(guild.members):
if len(member.roles) == 1:
await member.add_roles(await self.client.id.get_role(id_=self.config.new_role,
guild=guild))
if i%50==0:
print(i, member)
async def on_member_join(self, member):
await member.add_roles(await self.client.id.get_role(id_=self.config.new_role,
guild=self.client.get_guild(self.config.guild)))
await member.send(self.config.motd)

View File

@ -0,0 +1,11 @@
{
"version":"0.1.0",
"type": "python",
"dependencies": {
},
"bot_version": {
"min": "0.1.0",
"max": "0.1.0"
}
}

41
modules/purge/__init__.py Normal file
View File

@ -0,0 +1,41 @@
import discord
import sys
from modules.base import BaseClassPython
class MainClass(BaseClassPython):
name = "Purge"
color = 0xff0004
help_active = True
authorized_roles=[522918472548745217]
help = {
"description": "Suppression de messages en block.",
"commands": {
"`{prefix}{command} <message_id>`": "Supprime tous les messages du salon jusqu'au message spécifié",
}
}
command_text = "purge"
async def command(self, message, args, kwargs):
message_id = None
try:
message_id = int(args[0])
except ValueError:
pass
if len(args) and message_id is not None:
messages_list=[]
done=False
async for current in message.channel.history(limit=None):
if int(current.id) == message_id:
done = True
break
elif message.id != current.id:
messages_list.append(current)
if done:
chunks = [messages_list[x:x+99] for x in range(0, len(messages_list), 99)]
for chunk in chunks:
await message.channel.delete_messages(chunk)
await message.channel.send(f"**{len(messages_list)}** messages supprimés.")
else:
await message.channel.send("Le message spécifié n'a pas été trouvé.")
else:
await message.channel.send("Arguments invalides.")

View File

@ -0,0 +1,11 @@
{
"version":"0.1.0",
"type": "python",
"dependencies": {
},
"bot_version": {
"min": "0.1.0",
"max": "0.1.0"
}
}

View File

@ -0,0 +1,37 @@
import discord
import sys
from modules.base import BaseClassPython
class MainClass(BaseClassPython):
name = "ReadRules"
color = 0xff071f
help_active = False
help = {
"description": "Module d'accueil",
"commands": {
}
}
def __init__(self, client):
super().__init__(client)
self.config.init({"accepted_role":430846685380345876,
"new_role":430845952388104212,
"listen_chan":430995739636793345,
"log_chan":429977240202248192,
"passwords":["cacahuète","cacahuete","cacahuètes","cacahuetes"],
"succes_pm":"Félicitations, vous êtes désormais un **e-penseur** accompli. Bienvenue sur le serveur E-penser.",
"succes":" est désormais un **e-penseur** accompli."})
async def on_message(self, message):
if message.channel.id == self.config.listen_chan:
if message.content.lower() in self.config.passwords:
new_role = await self.client.id.get_role(id_=self.config.new_role, guild=message.channel.guild)
if new_role in message.author.roles:
await message.author.remove_roles(new_role)
await message.author.add_roles(await self.client.id.get_role(id_=self.config.accepted_role,
guild=message.channel.guild))
await message.author.send(self.config.succes_pm)
await message.channel.guild.get_channel(self.config.log_chan).send(message.author.mention + self.config.succes)
else:
await message.author.send(f"Le mot de passe que vous avez entré est incorrect : `{message.content}`.\nNous vous prions de lire le règlement afin d'accéder au serveur complet.")

View File

@ -0,0 +1,11 @@
{
"version":"0.1.0",
"type": "python",
"dependencies": {
},
"bot_version": {
"min": "0.1.0",
"max": "0.1.0"
}
}

View File

@ -0,0 +1,22 @@
import discord
import sys
from modules.base import BaseClassPython
class MainClass(BaseClassPython):
name = "Restart"
color = 0xff071f
help_active = True
authorized_roles = [431043517217898496]
help = {
"description": "Module gérant les redémarrages de Nikola Tesla",
"commands": {
"`{prefix}{command}`": "Redémarre le bot.",
}
}
command_text = "restart"
async def command(self, message, args, kwargs):
await message.channel.send(f"{message.author.mention}, Le bot va redémarrer.")
await self.client.logout()
sys.exit(0)

View File

@ -0,0 +1,11 @@
{
"version":"0.1.0",
"type": "python",
"dependencies": {
},
"bot_version": {
"min": "0.1.0",
"max": "0.1.0"
}
}

View File

@ -8,34 +8,103 @@ class MainClass(BaseClassPython):
color = 0xffb593 color = 0xffb593
help_active = True help_active = True
help = { help = {
"description": "Modulé gérant l'attribution des roles", "description": "Module gérant l'attribution des roles",
"commands": { "commands": {
"`{prefix}{command} list`": "Liste les roles", "`{prefix}{command} list`": "Liste les roles",
"`{prefix}{command} <role>`": "S'attribuer le role <role>" "`{prefix}{command} add <role> [role] ...`": "S'attribuer le(s) rôle(s) <role> ([role]...)",
"`{prefix}{command} remove <role> [role] ...`": "Se désattribuer le(s) rôle(s) <role> ([role]...)",
"`{prefix}{command} toggle <role> [role] ...`": "S'attribuer (ou désattribuer) le(s) rôle(s) <role> ([role]...)",
"`{prefix}{command} <role> [role] ...`": "Alias de `{prefix}{command} toggle`",
} }
} }
command_text = "roles" command_text = "roles"
def __init__(self, client): def __init__(self, client):
super().__init__(client) super().__init__(client)
self.config.init({"roles": {}}) self.config.init({"guild":297780867286433792,
"roles": {"435559220860157952":"Rôle mentionné lors des jeux."}})
async def com_list(self, message, args, kwargs): async def com_list(self, message, args, kwargs):
response = discord.Embed(title="Roles disponibles", color=self.color) response = discord.Embed(title="Roles disponibles", color=self.color)
for id_ in self.config.roles.keys(): for id_ in self.config.roles.keys():
role = await self.client.id.get_role(int(id_)) print(id_,type(id_))
response.add_field(name=role.name, value=self.config.roles[id_], inline=True) role = message.guild.get_role(int(id_))
if role is not None:
response.add_field(name=role.name, value=f" -> `{self.config.roles[id_]}`", inline=True)
await message.channel.send(embed=response) await message.channel.send(embed=response)
async def com_add(self, message, args, kwargs): async def com_add(self, message, args, kwargs):
guild = self.client.get_guild(self.config.guild)
member = guild.get_member(message.author.id)
if len(args) <= 1: if len(args) <= 1:
await message.channel.send("Il manque des arguments à la commande") await message.channel.send("Il manque des arguments à la commande")
for role in args[0:]: for role_ in args[1:]:
drole = await self.client.id.get_role(name="Invité") role = await self.client.id.get_role(name=role_, guild=guild, case_sensitive=False)
if drole is None or str(drole.id) not in self.config.roles.keys(): if role is None or str(role.id) not in self.config.roles.keys():
await message.channel.send(f"Le role {role} n'est pas disponible.") await message.channel.send(f"Le role {role_} n'est pas disponible.")
else: else:
try: await self.tryaddrole(message, member, role)
await message.author.add_roles(drole)
except discord.errors.Forbidden: async def com_remove(self, message, args, kwargs):
await message.channel.send(f"Je n'ai pas la permission d'attribuer le role {role}.") guild = self.client.get_guild(self.config.guild)
member = guild.get_member(message.author.id)
if len(args) <= 1:
await message.channel.send("Il manque des arguments à la commande")
for role_ in args[1:]:
role = await self.client.id.get_role(name=role_, guild=guild, case_sensitive=False)
if role is None or str(role.id) not in self.config.roles.keys():
await message.channel.send(f"Le role {role_} n'est pas disponible.")
else:
await self.tryremoverole(message, member, role)
async def com_toggle(self, message, args, kwargs):
guild = self.client.get_guild(self.config.guild)
member = guild.get_member(message.author.id)
if len(args) <= 1:
await message.channel.send("Il manque des arguments à la commande")
for role_ in args[1:]:
role = await self.client.id.get_role(name=role_, guild=guild, case_sensitive=False)
if role is None or str(role.id) not in self.config.roles.keys():
await message.channel.send(f"Le role {role_} n'est pas disponible.")
else:
await self.trytogglerole(message, member, role)
async def command(self, message, args, kwargs):
guild = self.client.get_guild(self.config.guild)
member = guild.get_member(message.author.id)
if len(args) < 1:
await message.channel.send("Il manque des arguments à la commande")
for role_ in args:
role = await self.client.id.get_role(name=role_, guild=guild, case_sensitive=False)
if role is None or str(role.id) not in self.config.roles.keys():
await message.channel.send(f"Le role {role_} n'est pas disponible.")
else:
await self.trytogglerole(message, member, role)
async def trytogglerole(self, message, member, role):
if role in member.roles:
await self.tryremoverole(message, member, role)
else:
await self.tryaddrole(message, member, role)
async def tryaddrole(self, message, member, role):
if role in member.roles:
await message.channel.send(f"Vous avez déjà le rôle {role}.")
return
try:
await member.add_roles(role, reason="Auto-attribution")
except discord.errors.Forbidden:
await message.channel.send(f"Je n'ai pas la permission de vous attribuer le rôle {role}.")
else:
await message.channel.send(f"Vous avez reçu le rôle {role}.")
async def tryremoverole(self, message, member, role):
if not role in member.roles:
await message.channel.send(f"Vous n'avez pas le rôle {role}.")
return
try:
await member.remove_roles(role, reason="Auto-désattribution")
except discord.errors.Forbidden:
await message.channel.send(f"Je n'ai pas la permission de vous retirer le rôle {role}.")
else:
await message.channel.send(f"Vous avez perdu le rôle {role}.")

View File

@ -5,30 +5,29 @@ data_type = "__data_type"
content = "__content" content = "__content"
class Encoder(json.JSONEncoder): class Encoder():
def __init__(self): def __init__(self, *args, **kwargs):
super().__init__() self.custom = {Encoder:(lambda x:x, lambda x:x)}
self.custom = {} self.JSONEncoder.custom = self.custom
def register(self, type_, encode, decode):
def register(self, type_, encode, decode, decode_args={}): self.custom.update({type_: (encode, decode)})
self.custom.update({type_: (encode, decode, decode_args)})
def default(self, obj):
if isinstance(obj, tuple(self.custom.keys())):
return {data_type: f'{type(obj)}', content: self.custom[type(obj)][0](obj)}
if isinstance(obj, (datetime.datetime)):
return {data_type: 'datetime.datetime', 'iso': obj.isoformat()}
if isinstance(obj, (datetime.timedelta)):
return {data_type: 'datetime.timedelta', 'totalseconds': obj.total_seconds()}
return json.JSONEncoder.default(self, obj)
def hook(self, dct): def hook(self, dct):
if data_type in dct: if data_type in dct:
for ty in self.custom.keys(): for ty in self.custom.keys():
if str(ty) == dct[data_type]: if str(ty) == dct[data_type]:
return self.custom[ty][1](dct[content], **self.custom[ty][2]) return self.custom[ty][1](dct[content])
if dct[data_type] == "datetime.datetime": if dct[data_type] == "datetime.datetime":
return datetime.datetime.fromisoformat(dct['iso']) return datetime.datetime.fromisoformat(dct['iso'])
elif dct[data_type] == "datetime.timedelta": elif dct[data_type] == "datetime.timedelta":
return datetime.timedelta(seconds=dct['totalseconds']) return datetime.timedelta(seconds=dct['totalseconds'])
return dct return dct
class JSONEncoder(json.JSONEncoder) :
def default(self, obj):
if isinstance(obj, tuple(self.custom.keys())):
return {data_type: f'{type(obj)}', content: self.custom[type(obj)][0](obj)}
if isinstance(obj, (datetime.datetime)):
return {data_type: 'datetime.datetime', 'iso': obj.isoformat()}
if isinstance(obj, (datetime.timedelta)):
return {data_type: 'datetime.timedelta', 'totalseconds': obj.total_seconds()}
return json.JSONEncoder.default(self, obj)

View File

@ -8,12 +8,12 @@ class Objects:
def __init__(self, path: str): def __init__(self, path: str):
self.path = os.path.abspath(path) self.path = os.path.abspath(path)
os.makedirs(os.path.join(self.path, "objects"), exist_ok=True) os.makedirs(os.path.join(self.path, "objects"), exist_ok=True)
self.encoder = jsonencoder.Encoder self.encoder = jsonencoder.Encoder()
def save_object(self, object_name, object_instance): def save_object(self, object_name, object_instance):
"""Save object into json file""" """Save object into json file"""
with open(os.path.join(self.path, "objects", object_name + ".json"), "w") as file: with open(os.path.join(self.path, "objects", object_name + ".json"), "w") as file:
json.dump(object_instance, file, cls=self.encoder) json.dump(object_instance, file, cls=self.encoder.JSONEncoder)
def load_object(self, object_name): def load_object(self, object_name):
"""Load object from json file""" """Load object from json file"""