# coding: utf8 import simplematrixbotlib as botlib import random import re import copy import configparser import signal import sys import pickle import threading import asyncio import nio from datetime import datetime,timedelta import requests import html2text import json # Var bot = None PREFIX = '!' USERNAME = "" # Listes et dictionnaires admins = [] # Admins du bot modos = {} # Moderateurs des salons modules = {} # Modules activés par salon prive = {} # Les espaces de message privés du bot avec les utilisateurs liste_mod = [] # Modules disponibles citations = {} #addquote bieres = {} # Boissons a offrir salons = {} # liste de salons recommandés welcome = {} # Messages d'accueil des salons clock = {} # horloges pbta # Connexion du bot config = configparser.ConfigParser() config.read('asmodee.ini') USERNAME = "" # Bot's username PASSWORD = "" # Bot's password SERVER = "" # Matrix server URL mods = ["roll", "quote", "biere", "stats", "liste", "horloge", "carte", "card", "cristal", "welcome", "salut", "jdr", "gens", "va", "salon", "kick", "mails", "titre", "invidious"] if ('AUTH' in config): USERNAME = config['AUTH']['username'] # Bot's username PASSWORD = config['AUTH']['password'] # Bot's password SERVER = config['AUTH']['server'] # Matrix server URL admins = config['AUTH']['admin'].split(",") # Admins du bot @admin1:host.tld,@admin2:host.tld,... else: print("Probleme de lecture de configuration asmodee.ini") # Create an instance of the MatrixBotAPI creds = botlib.Creds(SERVER, USERNAME, PASSWORD) bot = botlib.Bot(creds) # Chargement des données persistantes def horloge_read(): global clock try: with open("horloge", "rb") as fichier: loader = pickle.Unpickler(fichier) clock = loader.load() except: clock = {} def citations_read(): global citations try: with open("citations", "rb") as fichier: loader = pickle.Unpickler(fichier) citations = loader.load() except: citations = {} def bieres_read(): global bieres try: with open("bieres", "rb") as fichier: loader = pickle.Unpickler(fichier) bieres = loader.load() except: bieres = {} def salons_read(): global salons try: with open("salons", "rb") as fichier: loader = pickle.Unpickler(fichier) salons = loader.load() except: salons = {} def welcome_read(): global welcome try: with open("welcome", "rb") as fichier: loader = pickle.Unpickler(fichier) welcome = loader.load() except: welcome = {} def modos_read(): global modos try: with open("moderateurs", "rb") as fichier: loader = pickle.Unpickler(fichier) modos = loader.load() except: modos = {} def modules_read(): global modules try: with open("modules", "rb") as fichier: loader = pickle.Unpickler(fichier) modules = loader.load() except: modules = {} def prive_read(): global prive try: with open("prive", "rb") as fichier: loader = pickle.Unpickler(fichier) prive = loader.load() except: prive = {} def save_obj(room=None, event=None): with open("moderateurs", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(modos) with open("modules", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(modules) with open("prive", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(prive) if ('horloge' in liste_mod): with open("horloge", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(clock) if ('quote' in liste_mod): #with open("quotes", "wb") as fichier: # saver = pickle.Pickler(fichier) # saver.dump(quotes) with open("citations", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(citations) if ('biere' in liste_mod): with open("bieres", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(bieres) if ('salon' in liste_mod): with open("salons", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(salons) if ('welcome' in liste_mod): with open("welcome", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(welcome) def signal_handler(signal, frame): # Sauvegarder les données persistantes avant sortie save_obj(None,None) sys.exit(0) class Parser: #Pour parser la ligne de commande def __init__(self, str, nick, room): self._str = str.strip() self._nick = nick self._old = "" self._mtch = "" self._room = room self._arg = {} self._option = [False,False,False,0,0,0,0,0,False,0,0,False] @property def str(self): return self._str @str.setter def str(self, str): self._str = str @property def nick(self): return self._nick @nick.setter def nick(self, nick): self._nick = nick @property def old(self): return self._old @old.setter def old(self, old): self._old = old @property def mtch(self): return self._mtch @mtch.setter def mtch(self, mtch): self._mtch = mtch @property def room(self): return self._room @room.setter def room(self, room): self._room = room @property def arg(self): return self._arg @arg.setter def arg(self, arg): self._arg = arg @property def option(self): return self._option @option.setter def option(self, option): self._option = option def space(self): if (re.match("^\s", self._str) or re.match("^$", self._str)): return True else: return False def restaure(self): self._str += self._mtch self._old def eat(self,mtch,opt): pattern=r"^(\s*)(" + mtch + r")(.*)" if (re.match(pattern,self._str)): if (opt == 1): self._mtch = re.sub(pattern,r"\2",self._str) self._old += re.sub(pattern,r"\1\2",self._str) self._str = re.sub(pattern,r"\3",self._str) return True return False def roll(result,type,explosif,nb,f,noadd,ars,relance,mitige): # Lancement d'un dé # verif type et contenu params? roll = 0 new = 0 moins = 0 if (ars): roll = 1 if (type > 1): tmp = 1 while (ars and tmp == 1): roll *= 2 tmp = random.randrange(1,type+1) roll = ((roll//2)*tmp) else: tmp = random.randrange(1,type+1) roll += int(tmp) #print("roll " + str(roll)) while (explosif and tmp == type): tmp = random.randrange(1,type+1) roll += int(tmp) if (relance != 0 and relance != 1 and relance <= roll): new = 1 if (mitige != 0 and mitige >= roll): moins = 1 result += (' ' if nb>0 else '') + str(roll) if (f != 0 and roll < f): roll = 0 elif (f != 0 and roll >= f and noadd): tmp = int(roll//type) roll = tmp + ((roll - tmp*type) >= 1 if f else 0) roll -= moins #print("fin roll " + str(result) + " " + str(roll) + " " + str(new)) return (result,roll,new) def rolls(result,jet,type,nb,explosif,noadd,wild,f,g,ars,relance,mitige,z): # Lancement d'un groupe de dés y = 0 total = 0 allresult = [] if (nb > 100): nb = 100 tmp=(type and nb) if (tmp): jet += str(nb)+"d"+str(type) #print(jet) for i in range(nb): new = 0 # Star Wars if (z == True and i == 0): result, res1, new = roll(result,type,True,nb,f,noadd,ars,relance,mitige) allresult.append(res1) if (res1 == 1): y = 1 # Autre else: result, res1, new = roll(result,type,explosif,nb,f,noadd,ars,relance,mitige) allresult.append(res1) # Tant qu'il faut relancer while (new == 1): result, res1, new = roll(result,type,explosif,nb,f,noadd,ars,relance,mitige) allresult.append(res1) # Wild die de Savage Worlds if (wild != 0): jet += "w" + str(wild) result, res1, new = roll(result,wild,wild!=1,nb if nb else 0,f,noadd,ars,relance,mitige) allresult.append(res1) result += 'w' #print(allresult) allresult.sort(reverse=True) # 1 au de joker de Star Wars if (y == 1): del allresult[-1] del allresult[0] for i in range((len(allresult)) if (g == 0 and ((f != 0 and noadd) or not noadd)) else (0 if (noadd and f == 0) else g)): if (g == 0 or len(allresult) >= g): total += allresult[i] if allresult[i] else 0 if (noadd and f == 0): total += max(allresult) #print("total : " + str(total)) jet += (("g" + str(g)) if g != 0 else "#g") if g != parser.option[5] else (("g" + str(g)) if g != 0 else "") jet += (("f" + str(f)) if f != 0 else "#f") if f != parser.option[4] else (("f" + str(f)) if f != 0 else "") jet += (("r" + str(relance)) if relance != 0 else "#r") if relance != parser.option[9] else (("r" + str(relance)) if relance != 0 else "") jet += (("m" + str(mitige)) if mitige != 0 else "#m") if mitige != parser.option[9] else (("m" + str(mitige)) if mitige != 0 else "") if (tmp): jet += ("e" if explosif == True else "#e") if explosif != parser.option[0] else "" jet += ("n" if noadd == True else "#n") if noadd != parser.option[1] else "" jet += ("a" if ars == True else "#a") if ars != parser.option[8] else "" #print("fin rolls : " + str(result) + "|" + str(total) + "|" + str(jet)) return (result,total,jet) async def entryPoint(room, message): # Analyse des commandes ":", point d'entrée pour les jets de dés global modules try: rmod = modules[room.room_id, 'roll'] except: modules[room.room_id, 'roll'] = False if (modules[room.room_id, 'roll']): global parser text = getMessage(message) user = getUser(message) nick = getNick(room,message) parser = Parser(text,nick,room) if (parser.eat(":roll",1)): parser.option = [False,False,False,0,0,0,0,0,False,0,0,False] await rollXPoint() elif (parser.eat(":dom",1)): parser.option = [True,False,True,0,0,0,4,4,False,0,0,False] await rollXPoint() elif (parser.eat(":sw",1)): parser.option = [True,True,True,0,0,0,4,4,False,0,0,False] await rollXPoint() elif (parser.eat(":ars",1)): parser.option = [False,True,True,0,0,0,0,0,True,0,0,False] await rollXPoint() elif (parser.eat(":des",1)): parser.option = [False,True,True,0,10,0,0,0,False,0,0,False] await rollXPoint() elif (parser.eat(":wod",1)): parser.option = [False,True,True,0,8,0,0,0,False,10,0,False] await rollXPoint() elif (parser.eat(":adv",1)): parser.option = [False,True,False,0,5,0,0,0,False,0,0,False] await rollXPoint() elif (parser.eat(":owod",1)): parser.option = [False,True,True,0,6,0,0,0,False,10,1,False] await rollXPoint() elif (parser.eat(":star",1)): parser.option = [False,False,True,0,0,0,0,0,False,0,0,True] await rollXPoint() elif (parser.eat(":fate",1)): text = text[5:] + " 4d3-8" parser = Parser(text,nick,room) parser.option = [False,False,False,0,0,0,0,0,False,0,0,False] await rollXPoint() else: parser.arg["error"] = True if (not parser.arg.get("error",None) and not parser.eat("$",0)): parser.arg["noerror"] = True await msg(room,"Je n'ai pas compris " + text,user) def rollOptionPoint(): # Parse des options global parser while (True): if (parser.eat("[Ee]",1)): parser.option[0] = True elif (parser.eat("#[Ee]",1)): parser.option[0] = False elif (parser.eat("[Nn]",1)): parser.option[1] = True elif (parser.eat("#[Nn]",1)): parser.option[1] = False elif (parser.eat("[Vv]",1)): parser.option[2] = True elif (parser.eat("#[Vv]",1)): parser.option[2] = False elif (parser.eat("[Ww]",1)): if (parser.space()): parser.option[3] = 6 elif (parser.eat(r"\d+",1)): parser.option[3] = int(parser.mtch) else: parser.option[3] = 6 elif (parser.eat("#[Ww]",1)): parser.option[3] = 0 elif (parser.eat("[Ff]",1)): if (parser.space()): parser.option[4] = 6 elif (parser.eat(r"\d+",1)): parser.option[4] = int(parser.mtch) else: parser.option[4] = 6 elif (parser.eat("#[Ff]",1)): parser.option[4] = 0 elif (parser.eat("[Gg]",1)): if (parser.space()): parser.option[5] = 6 elif (parser.eat(r"\d+",1)): parser.option[5] = int(parser.mtch) else: parser.option[5] = 6 elif (parser.eat("#[Gg]",1)): parser.option[5] = 0 elif (parser.eat("[Ss]",1)): if (parser.space()): parser.option[6] = 4 elif (parser.eat(r"\d+",1)): parser.option[6] = int(parser.mtch) else: parser.option[6] = 4 if (parser.eat("[/]",1)): if (parser.space()): parser.option[7] = 4 elif (parser.eat(r"\d+",1)): parser.option[7] = int(parser.mtch) else: parser.option[7] = 4 else: parser.option[7] = 4 elif (parser.eat("#[Ss]",1)): parser.option[6] = 0 parser.option[7] = 0 elif (parser.eat("[Aa]",1)): parser.option[8] = True elif (parser.eat("#[Aa]",1)): parser.option[8] = False elif (parser.eat("[Rr]",1)): if (parser.space()): parser.option[9] = 10 elif (parser.eat(r"\d+",1)): parser.option[9] = int(parser.mtch) else: parser.option[9] = 10 elif (parser.eat("#[Rr]",1)): parser.option[9] = 0 elif (parser.eat("[Mm]",1)): if (parser.space()): parser.option[10] = 1 elif (parser.eat(r"\d+",1)): parser.option[10] = int(parser.mtch) else: parser.option[10] = 1 elif (parser.eat("#[Mm]",1)): parser.option[10] = 0 elif (parser.eat("[Zz]",1)): parser.option[11] = True elif (parser.eat("#[Zz]",1)): parser.option[11] = False else: break def dupli(orig): # Duplication d'un parser salon = orig.room orig.room = None nouv = copy.deepcopy(orig) nouv.option = [orig.option[0],orig.option[1],orig.option[2],orig.option[3],orig.option[4],orig.option[5],orig.option[6],orig.option[7],orig.option[8],orig.option[9],orig.option[10],orig.option[11]] orig.room = salon nouv.room = salon return nouv async def rollXPoint(): # Parser le nombre de lancers de dés identiques global parser await rollPlusMoinsPoint() if (parser.eat("[xX]",1)): if (parser.eat(r"\d+",1)): tmp = dupli(parser) str = parser.arg["jet"] xtime = int(parser.mtch)-1 xtime = xtime if (xtime < 11) else 10 for _ in range(xtime): parser = dupli(parser) parser.str = str #print (parser.str) await rollPlusMoinsPoint() parser = tmp else: parser.arg["error"] = True async def rollPlusMoinsPoint(): # Gérer les bloc du jet séparés par les + et -, afficher le résultat global parser parser.arg["roll_sig"] = True parser.arg["error"] = None result = "" res1 = "" res2 = "" jet = "" rollOptionPoint() #print(parser.option) exp,noa,ver,will,f,g,s,d,ars,r,m,z = parser.option rollEntityPoint() #print("de " + str(parser.arg.get("roll_nb",None)) + "|" + str(parser.arg.get("roll_typ",None))) if (not parser.arg["error"]): if (not parser.arg.get("roll_sig",True)): jet += "-" result += "-" if (parser.arg.get("roll_typ",None) or parser.arg.get("roll_wil",None)): result += "(" exp2,noa2,ver2,will2,f2,g2,s2,d2,ars2,r2,m2,z2 = parser.option parser.option = [exp,noa,ver,will,f,g,s,d,ars,r,m,z] result, res1, jet = rolls(result,jet,parser.arg.get("roll_typ",None),parser.arg.get("roll_nb",None),exp2,noa2,will2,f2,g2,ars2,r2,m2,z2) result += " = " + str(res1) + ")" else: jet += str(parser.arg.get("roll_nb",None)) result += str(parser.arg.get("roll_nb",None)) res1 = parser.arg["roll_nb"] #print("prem " + result + " " +str(res1)) if (not parser.arg.get("roll_sig",True)): res1 = -res1 while (parser.eat("[+-]",1)): parser.arg["roll_sig"] = True if (parser.mtch == "-"): parser.arg["roll_sig"] = not parser.arg.get("roll_sig",True) rollEntityPoint() if (not parser.arg.get("error",None)): jet += " +" if parser.arg.get("roll_sig",True) else " -" result += " + " if parser.arg.get("roll_sig",True) else " - " if (parser.arg.get("roll_typ",None) or parser.arg.get("roll_wil",None)): result += "(" exp2,noa2,ver2,will2,f2,g2,s2,d2,ars2,r2,m2,z2 = parser.option parser.option = [exp,noa,ver,will,f,g,s,d,ars,r,m,z] result, res2, jet = rolls(result,jet,parser.arg.get("roll_typ",None),parser.arg.get("roll_nb",None),exp2,noa2,will2,f2,g2,ars2,r2,m2,z2) result += " = " + str(res2) + ")" else: jet += str(parser.arg.get("roll_nb",None)) result += str(parser.arg.get("roll_nb",None)) res2 = parser.arg.get("roll_nb",None) res1 += res2 if parser.arg.get("roll_sig",None) else -res2 #print("deux " + result + " " +str(res1)) if (res1): if (ver): result = jet + " = (" + result + ") = " + str(res1) else: result = jet + " = " + str(res1) if (d <= 0): d=1 tmp = (res1 - s) // d + 1 result += ("/" + ("0" if (tmp < 0) else str(tmp))) if (s != 0) else "" parser.arg["jet"] = jet await msg(parser.room,parser.nick + " rolls " + ("e" if exp else "") + ("n" if noa else "") + ("v" if ver else "") + ("a" if ars else "") + ("s"+str(s)+"/"+str(d) if (s != 0) else "") + (" " if (exp or noa or ver or s != 0) else "") + result, "dice") elif (not parser.arg.get("noerror",False)): await msg(parser.room,"match = " + parser.mtch + "\nstr = " + parser.str, "dice") await msg(parser.room,"Rien compris. Essayez '!help' pour obtenir de l'aide.", "dice") def rollEntityPoint(): # Parser les séparateurs de bloc + et - global parser if (parser.eat("[-+]", 1)): if (parser.mtch == "-"): parser.arg["roll_sig"] = not parser.arg.get("roll_sig",True) rollOptionPoint() rollNbPoint() def rollNbPoint(): # Parser le nombre de dés global parser parser.arg["roll_nb"] = None if (parser.eat(r"\d+",1)): parser.arg["roll_nb"] = int(parser.mtch) #print("nb " + str(parser.arg.get("roll_nb",1))) rollDPoint() def rollDPoint(): # Parser le mot clé identifiant un dé global parser if (parser.eat("[dD]",1)): if (not parser.arg.get("roll_nb",False)): parser.arg["roll_nb"] = 1 parser.arg["roll_bon"] = 0 rollTypePoint() elif (parser.arg.get("roll_nb",False)): parser.arg["roll_typ"] = None else: parser.arg["error"] = True def rollTypePoint(): # Parser le nombre de faces du dé global parser if (parser.space()): parser.arg["roll_typ"] = 6 elif (parser.eat(r"\d+",1)): parser.arg["roll_typ"] = int(parser.mtch) if (parser.mtch == "1"): parser.option[0] = False else: parser.arg["roll_typ"] = 6 rollOptionPoint() if (not parser.arg.get("roll_nb",False)): parser.arg["error"] = True def getMessage(message): try: return(str(message).split(":",2)[2].strip()) except: return(str(message)) def getUser(message): match = re.search(r"^(@\w+:[^ :]+)", str(message)) return str(match.group()) def getNick(room, message): # Obtenir le DisplayName à partir du mxid. sender = getUser(message) nick = None try: nick = room.user_name(sender).split(' ')[0] except: nick = room.user_name(sender) return(nick) async def msg(room,mess,sender,content=False): try: try: lmod = modos.get(room.room_id) if (sender not in admins and lmod != None and sender not in lmod): mess = mess.replace('@room', 'tout le monde') except: try: mess = mess.replace('@room', 'tout le monde') except: print(mess) print("id : " + str(room.room_id) + " message : " + str(mess)) if (content): await bot.api.send_markdown_message(room.room_id, mess) else: await bot.api.send_text_message(room.room_id, mess) except: print("Impossible d'envoyer le message") async def modo(room,message): # Definition d'un moderateur global modos sender = getUser(message) texte = getMessage(message) print("texte : " + texte + " sender : " + sender) lmod = [] try: lmod = modos[room.room_id] except: lmod = [] if (sender in admins or sender in lmod or sender == bot.client.user_id): args = texte.split() args.pop(0) if (len(args) > 1 and args[0] == "add"): args.pop(0) candidat = " ".join(args) if (not candidat in lmod): lmod.append(candidat) modos[room.room_id] = lmod await msg(room,candidat + " devient moderateur.",sender) else: await msg(room,candidat + " est déjà moderateur.",sender) elif (len(args) > 1 and args[0] == "del"): args.pop(0) candidat = " ".join(args) if (candidat in lmod): place = lmod.index(candidat) del lmod[place] modos[room.room_id] = lmod await msg(room,candidat + " n'est plus moderateur.",sender) else: await msg(room,candidat + " n'est pas moderateur.",sender) else: await msg(room,"\n".join(lmod),sender) else: await msg(room,"Vous n'êtes pas autorisés à définir les modérateurs.",sender) async def module(room,message): # Definition des modules d'un salon lmod = [] sender = getUser(message) texte = getMessage(message) try: lmod = modos[room.room_id] except: lmod = [] if (sender in admins or sender in lmod or sender == bot.client.user_id): global modules args = texte.split() args.pop(0) if (len(args) == 2 and args[0] == "add"): args.pop(0) rmod = args[0] if (rmod in liste_mod): modules[room.room_id, rmod] = True await msg(room,"Module : " + rmod + " activé.",sender) else: await msg(room,"Module : " + rmod + " inconnu.",sender) elif (len(args) == 2 and args[0] == "del"): args.pop(0) rmod = args[0] if (rmod in liste_mod): modules[room.room_id, rmod] = False await msg(room,"Module : " + rmod + " désactivé.",sender) else: await msg(room,"Module : " + rmod + " inconnu.",sender) else: # Lister les modules actifs du salon rmod = "" for cle,valeur in modules.items(): if (cle[0] == room.room_id and valeur == True): rmod = rmod + cle[1] + ", " if (len(rmod) > 1): rmod = rmod[:-2] await msg(room,"Modules actuels : " + rmod,sender) # Lister les modules disponibles dmod = "" for val in liste_mod: dmod = dmod + val + ", " if (len(dmod) > 1): dmod = dmod[:-2] await msg(room,"Modules disponibles : " + dmod,sender) else: await msg(room,"Vous n'êtes pas autorisés à définir les modules du salon.",sender) async def liste(room, message): # Afficher un élement aléatoire d'une liste fournie global modules try: rmod = modules[room.room_id, 'liste'] except: modules[room.room_id, 'liste'] = False if (modules[room.room_id, 'liste']): res = [] nick = getNick(room,message) args = getMessage(message).split() args.pop(0) try: nb = int(args[len(args)-1]) args.pop(len(args)-1) except: nb = 1 args = ' '.join(args) list = args.split('/') if (nb <= len(list)): for i in range(nb): id = random.randrange(0,len(list)) res.append(list.pop(id)) await msg(room,nick + " obtient :\n" + '\n'.join(res),nick) else: await msg(room,"Utilisation : !liste [nombre d elements]",nick) async def aff_hor(room, hor, valeur): # affichage des horloges if (int(valeur) == 0): await msg(room,hor + " : " + chr(128320) + "\n", "horloge") elif (int(valeur) == 1): await msg(room,hor + " : " + chr(128338) + "\n", "horloge") elif (int(valeur) == 2): await msg(room,hor + " : " + chr(128341) + "\n", "horloge") elif (int(valeur) == 3): await msg(room,hor + " : " + chr(128344) + "\n", "horloge") elif (int(valeur) == 4): await msg(room,hor + " : " + chr(128345) + "\n", "horloge") elif (int(valeur) == 5): await msg(room,hor + " : " + chr(128346) + "\n", "horloge") elif (int(valeur) == 6): await msg(room,hor + " : " + chr(128347) + "\n", "horloge") else: await msg(room,hor + " : " + str(valeur) + " \n", "horloge") async def horloge(room, message): # Gestion des horloges PBTA global modules try: rmod = modules[room.room_id, 'horloge'] except: modules[room.room_id, 'horloge'] = False if (modules[room.room_id, 'horloge']): global clock nick = getNick(room,message) args = getMessage(message).split() args.pop(0) if (len(args) == 0): # Liste des horloges du salon for cle,valeur in clock.items(): if (cle[0] == room.room_id): await aff_hor(room, cle[1], valeur) elif (len(args) >= 2 and args[len(args)-1].isnumeric()): # Place le niveau de l'horloge entre 0 et 6 nv = int(args[len(args)-1]) clock[room.room_id, ' '.join(args[0:-1])] = nv elif (len(args) >= 2 and (args[len(args)-1][:1] == "+" or args[len(args)-1][:1] == "-")): nv = 0 hor = ' '.join(args[0:-1]) if ((room.room_id, hor) in clock): nv = clock[room.room_id, hor] val = 0 if (args[len(args)-1][1:].isnumeric()): val = int(args[len(args)-1][1:]) if (args[len(args)-1][:1] == "+"): nv = nv + val if (nv > 6): nv = 6 else: nv = nv - val if (nv < 0): nv = 0 clock[room.room_id, hor] = nv await aff_hor(room, hor, nv) elif (len(args) >= 2 and args[0] == "del"): # Supprime une horloge args.pop(0) del clock[room.room_id, ' '.join(args)] else: await msg(room,"Utilisation : \n- !horloge : Affiche les horloges. \n- !horloge : Place ou crée l'horloge au niveau spécifié.\n- !horloge del : Supprime l'horloge.",getUser(message)) async def reponses(room, phrases, content=False): # Afficher une réponse aléatoire dans la liste i = random.randrange(0,len(phrases)) await msg(room,phrases[i],"reponses",content) async def verifPMRoom(room, message): # Pour obtenir ou créer un salon pour les messages privés avec l'utilisateur global prive nick = "" sender = "" sender = getUser(message) nick = getNick(room, message) client_id = bot.creds.username.split(':')[0].split('@')[1] client_host = bot.creds.username.split(':')[1] room_nick = client_id + "_" + nick + "_b" salon = None room_id = prive.get(sender) if (room_id): await bot.async_client.room_invite(room_id=room_id, user_id=sender) new_salon = nio.rooms.MatrixRoom(room_id, client_id) new_salon.name="Asmodee" new_salon.topic="Informations d'Asmodee" new_salon.is_direct=True return(new_salon) else: salon = await bot.async_client.room_create(alias=room_nick, name="Asmodee", topic="Informations d'Asmodee",is_direct=True,invite=[sender]) if isinstance(salon, nio.responses.RoomCreateError): print("Impossible de creer : " + room_nick + " pour " + sender) return(room) else: prive[sender]=salon.room_id return(salon) #TODO : room_delete_alias(access_token, room_alias) async def biere(room,message): # Gestion des boissons global modules try: rmod = modules[room.room_id, 'biere'] except: modules[room.room_id, 'biere'] = False power = 0 if (modules[room.room_id, 'biere']): sender = getUser(message) mess = getMessage(message) lmod = modos.get(room.room_id) if (sender in admins or sender in lmod): power = 1 global bieres args = mess.split() args.pop(0) breuvages = {} give = False elu = "" envoyeur = getNick(room, message) try: breuvages = bieres[room.room_id] except: breuvages = {} if (len(args) > 1 and args[0] == "give"): give = True args.pop(0) submit = " ".join(args).split(":") elu = submit[0] if (power == 0): elu = elu.replace('@room', 'tout le monde') try: args = submit[1].split() except: args = "" if (len(args) > 2 and args[0] == "add"): #ajoute une biere args.pop(0) submit = " ".join(args).split(":") if (len(submit) > 1): # Ajout de la citation nick = submit[0].strip() nick = nick.replace('@room', 'tous') submit.pop(0) citation = ":".join(submit) citation = citation.replace('@room', 'tout le monde') tps = datetime.now().microsecond breuvages[nick,tps] = citation bieres[room.room_id] = breuvages await msg(room,"Ajout du breuvage " + nick + ":" + citation,sender) else: # message d'aide await msg(room,"!biere add :",sender) elif (len(args) > 0 and args[0] == "list"): # liste les quotes args.pop(0) salon = await verifPMRoom(room,message) print(salon) if (len(args) == 0): # Liste les breuvages du salon reponse = "Voici les reponses du salon " + room.room_id + "\n" alias = None if room.name: alias = room.name elif room.canonical_alias: alias = room.canonical_alias elif room.names: alias = room.names[0] else: alias = "" reponse = reponse + "(alias : " + alias + ")\n" for cle,valeur in breuvages.items(): reponse = reponse + cle[0] + " / " + str(cle[1]) + " : " + valeur + "\n" if (len(reponse) > 500): await msg(salon,reponse,sender) reponse = "" await msg(salon,reponse,sender) elif (args[0] == "all"): # tous les breuvages de tous les salons reponse = "Les breuvages de tous les salons : " + "\n" await msg(salon,reponse,sender) for rid,fame in bieres.items(): reponse = "Voici les reponses du salon " + rid + "\n" for cle,valeur in fame.items(): reponse = reponse + cle[0] + " / " + str(cle[1]) + " : " + valeur + "\n" if (len(reponse) > 500): await msg(salon,reponse,sender) reponse = "" await msg(salon,reponse,sender) else: # les breuvages du pseudo spécifié nick = " ".join(args) reponse = "Voici les reponses du breuvage " + nick + "\n" for cle,valeur in breuvages.items(): if (cle[0] == nick): reponse = reponse + cle[0] + " / " + str(cle[1]) + " : " + valeur + "\n" await msg(salon,reponse,sender) elif (len(args) > 1 and args[0] == "del"): salon = await verifPMRoom(room,message) lmod = modos[room.room_id] if (sender in admins): id = args[1] reponse = "Voici le breuvage supprimé : \n" for rid,fame in bieres.items(): for cle,valeur in fame.items(): if (str(cle[1]) == id): del fame[cle[0],cle[1]] reponse = reponse + rid + " / " + cle[0] + " / " + str(cle[1]) + " : " + valeur + "\n" break await msg(salon,reponse,sender) elif (sender in lmod): id = args[1] reponse = "Voici le breuvage supprimé : \n" rid = room.room_id fame = bieres[rid] for cle,valeur in fame.items(): if (str(cle[1]) == id): del fame[cle[0],cle[1]] reponse = reponse + rid + " / " + cle[0] + " / " + str(cle[1]) + " : " + valeur + "\n" break await msg(salon,reponse,sender) else: await msg(salon,"Vous n'êtes pas autorisés à supprimer des breuvages.",sender) elif (len(args) > 0): # cite une reponse d'un breuvage precis nick = " ".join(args) phrases = [] for cle,valeur in breuvages.items(): if (cle[0] == nick): if (give): phrases.append(valeur + " pour " + elu + " de la part de " + envoyeur) else: phrases.append(valeur + " pour " + envoyeur) if (len(phrases) > 0 ): await reponses(room,phrases) else: await msg(room,"Je n'ai pas de " + nick + " en stock!",sender) else: # cite une réponse d'un breuvage aleatoire phrases = [] for cle,valeur in breuvages.items(): if (give): phrases.append(valeur + " pour " + elu + " de la part de " + envoyeur) else: phrases.append(valeur + " pour " + envoyeur) if (len(phrases) > 0 ): await reponses(room,phrases) else: await msg(room,"Je n'ai pas de breuvages pour ce salon",sender) async def boissons(room,message): # Gestion des alias de boissons global modules try: rmod = modules[room.room_id, 'biere'] except: modules[room.room_id, 'biere'] = False if (modules[room.room_id, 'biere']): sender = getUser(message) mess = getMessage(message) boisson = "" elu = "" args = mess.split() try: boisson = args[0][1:] except: boisson = "" args.pop(0) if (len(args) > 0): elu = " ".join(args) if (len(elu) > 0 and len(boisson) > 0): mess = "!biere give " + elu + ":" + boisson elif (len(elu) > 0): mess = "!biere give " + elu elif (len(boisson) > 0): mess = "!biere " + boisson else: mess = "!biere" message = sender + " : " + mess await biere(room,message) async def salon(room,message): # Gestion des listes de salons recommandes global modules try: rmod = modules[room.room_id, 'salon'] except: modules[room.room_id, 'salon'] = False if (modules[room.room_id, 'salon']): sender = getUser(message) mess = getMessage(message) global salons args = mess.split() args.pop(0) famous = {} try: famous = salons[room.room_id] except: famous = {} if (len(args) > 3 and args[0] == "add"): #ajoute un salon recommande ref = "" desc = "" args.pop(0) if (args[0] == "desc"): args.pop(0) ref = "desc" desc = " ".join(args) else: ref = args[0] args.pop(0) desc = " ".join(args) famous[ref] = desc salons[room.room_id] = famous await msg(room,"Ajout du salon " + ref + " : " + desc,sender) elif (len(args) > 1 and args[0] == "del"): salon = await verifPMRoom(room,message) lmod = modos[room.room_id] if (sender in admins): id = args[1] reponse = "Voici le salon supprimé : \n" rid = room.room_id fame = salons[rid] for cle,valeur in fame.items(): if (str(cle) == id): del fame[cle] reponse = reponse + rid + " / " + cle + " : " + valeur + "\n" break await msg(room,reponse,sender) elif (sender in lmod): id = args[1] reponse = "Voici le salon supprimé : \n" rid = room.room_id fame = salons[rid] for cle,valeur in fame.items(): if (str(cle) == id): del fame[cle] reponse = reponse + rid + " / " + cle + " : " + valeur + "\n" break await msg(room,reponse,sender) else: await msg(salon,"Vous n'êtes pas autorisés à supprimer des salons.",sender) elif (len(args) > 0): # cite un salon precis ref = args[0] trouve = 0 for cle,valeur in famous.items(): if (cle == ref): await msg(salon,cle + " : " + valeur,sender) trouve = 1 break if (trouve == 0): await msg(room,"Je n'ai pas de salons nomme " + ref,sender) else: # cite tous les salons reponse = "" trouve = 0 if ("desc" in famous): reponse = reponse + famous["desc"] + "\n" for cle,valeur in famous.items(): if (cle != "desc"): reponse = reponse + cle + " : " + valeur + "\n" trouve = 1 if (trouve == 0): await msg(room,"Je n'ai pas de salons recommandes pour ce salon",sender) else: await msg(room,reponse,sender) async def accueil(room,message): # Mettre un message d'accueil global modules try: rmod = modules[room.room_id, 'welcome'] except: modules[room.room_id, 'welcome'] = False if (modules[room.room_id, 'welcome']): sender = getUser(message) mess = getMessage(message) lmod = modos[room.room_id] if (sender in admins or sender in lmod): global welcome args = mess.split() args.pop(0) reponse = " ".join(args) if (len(args) > 0): welcome[room.room_id] = reponse await msg(room,"Le message d'accueil est désormais : " + reponse,sender) else: await msg(salon,"Vous n'êtes pas autorisés à modifier le message d'accueil.",sender) async def bienvenue(room,message): # Affichage d'un message d'accueil aux nouveaux venus global modules try: rmod = modules[room.room_id, 'welcome'] except: modules[room.room_id, 'welcome'] = False if (modules[room.room_id, 'welcome']): sender = message.sender nick = room.user_name(message.state_key) if room.user_name(message.state_key) else message.state_key membership = message.membership prev_member = message.prev_membership if room.name: alias = room.name elif room.canonical_alias: alias = room.canonical_alias elif room.names: alias = room.names[0] else: alias = "" reponse = "" try: reponse = welcome[room.room_id] except: reponse = "" if (membership == "join" and prev_member != "join"): await msg(room,"Bienvenue sur " + alias + ", " + nick + ". " + reponse,sender) elif (membership == "leave" and prev_member != "leave"): await msg(room,"Au revoir " + nick + "!",sender) else: print("current: " + membership + " prev: " + prev_member) async def titre(room, message): # cherche le titre d'une page global modules try: rmod = modules[room.room_id, 'titre'] except: modules[room.room_id, 'titre'] = False if (modules[room.room_id, 'titre']): args = getMessage(message).split() sender = getUser(message) args.pop(0) try: invidious = modules[room.room_id, 'invidious'] except: invidious = False try: url=args[0] print(url) if (re.search(r"^.*://",url) is None): url = "http://" + url r = requests.get(url) res = re.search(r"(.*)",r.text) if (res is not None): await msg(room,html2text.html2text(str(re.sub("", "", res.group()))),sender) else: await msg(room,"Titre non trouvé",sender) if (re.search(r"http[s]?://(www\.)?youtube\.",url) is not None and invidious is False): res = re.sub(r"^.*\?v=(\w+).*$", r"\1", url, 0, re.MULTILINE) await msg(room,str("https://invidious.fdn.fr/watch?v=" + res),sender) except: await msg(room,"URL invalide",sender) async def addquote(room,message): # enregistrer les citations mode reponses matrix global modules try: rmod = modules[room.room_id, 'quote'] except: modules[room.room_id, 'quote'] = False if (modules[room.room_id, 'quote']): global citations content = getMessage(message) sender = getUser(message) if len(content) > 42: # Récupération de l'auteur auteur = "Un nain connu" match = re.search(r"<(@\w+:\w+.\w+)>", content) if match: auteur = match.group(1) nick = room.user_name(auteur) # Enlève la commande de la citation try: content = content.replace("\n!addquote", " ") content = content.replace("\n!", "\n") content = content.replace("

!addquote

\n", "") content = content.replace("

!", "

") content = content.replace("<"+auteur+">",nick+" <"+auteur+">") except: print("erreur content " + content) # Id tps = datetime.now().microsecond # récupérations des citations du salon famous = {} try: famous = citations[room.room_id] except: famous = {} # enregistrement de la citation famous[auteur,tps] = content citations[room.room_id] = famous await bot.api.send_markdown_message(room_id=room.room_id,message="Ajout de la citation de " + nick + ":\n" + content) async def showquote(room, message): # afficher les citations mode reponse matrix global modules try: rmod = modules[room.room_id, 'quote'] except: modules[room.room_id, 'quote'] = False if (modules[room.room_id, 'quote']): args = getMessage(message).split() sender = getUser(message) args.pop(0) famous = {} try: famous = citations[room.room_id] except: famous = {} if (len(args) == 1): # cite une quote d'une personne precise nick = args[0] phrases = [] for cle,valeur in famous.items(): if (cle[0] == nick): phrases.append(valeur) if (len(phrases) > 0 ): await reponses(room,phrases,True) else: await msg(room,"Je n'ai pas de citations pour " + nick,sender) else: # cite une quote aleatoire phrases = [] for cle,valeur in famous.items(): phrases.append(valeur) if (len(phrases) > 0 ): await reponses(room,phrases,True) else: await msg(room,"Je n'ai pas de citations pour ce salon",sender) async def help(room, message): # Aide en message privé await help_center(room,message,"help",True) async def aide(room, message): # Aide dans le salon await help_center(room,message,"aide",False) async def help_center(room,message,name,private): # Aide sur les commandes disponibles args = getMessage(message).split() args.pop(0) salon = room sender = getUser(message) if (private): salon = await verifPMRoom(room,message) if (len(args) > 0): if (re.search("roll", args[0])): await msg(salon,":roll (+-modifs ou des)\n\n- exemple :roll vr4g3 6d6 - \#g\#r3d6 +2 x3 : lance avec les details 6d6 en relancant les des avec un resultat de 4+ et en gardant les trois meilleurs, puis en retranchant 3d6 sans relancer les 4+ et en gardant tout, enfin ajouter 2. L'operation sera executee trois fois.\n\n- v : details (verbose) du jet\n- n : no add, chaque de est traite separement\n- e : explosif, si un de fait le maximum, on le relance et on additionne\n- z : Star Zars, le premier de est explosif. Mais s'il sort un 1, on retire ce 1 et la plus grande valeur des autres des\n- f : difficulte a atteindre par de avec option n\n- g : nombre de des conserves\n- r : relance si le de a obtenu au moins ce nombre\n- m : Enleve un succes si ce nombre ou moins est atteint\n- s : seuil a atteindre et niveaux de reussites\n- w : lance un wild die avec les autres.",sender, False) elif (re.search("sw", args[0])): await msg(salon,"- :sw : Lance les des en mode Savage Worlds\nVerbose/Noadd/Explosif/Seuil 4/Niveau de reussite 4/Wild Die d6.",sender, False) elif (re.search("dom", args[0])): await msg(salon,"- :dom : Lance les dommages en mode Savage Worlds\nVerbose/Explosif/seuil 4/Niveau de reussite 4.",sender, False) elif (re.search("owod", args[0])): await msg(salon,"- :owod : Lance les des en mode Ancien Monde des Tenebres\nVerbose/Noadd/Difficulte 6/Relance les 10/Les 1 enleve un succes.",sender, False) elif (re.search("wod", args[0])): await msg(salon,"- :wod : Lance les des en mode Nouveau Monde des Tenebres\nVerbose/Noadd/Difficulte 8/Relance les 10.",sender, False) elif (re.search("ars", args[0])): await msg(salon,"- :ars : Lance les des en mode Ars Magicka : de de tension\nVerbose/Noadd/Sur un 1, on relance et on double.",sender, False) elif (re.search("des", args[0])): await msg(salon,"- :des : Lance des des de desastre\nVerbose/Noadd/Difficulte 10.",sender, False) elif (re.search("star", args[0])): await msg(salon,"- :star : Lance des des en mode star wars. Le premier de est explosif. Mais s'il sort un 1, on retire ce 1 et la plus grande valeur des autres des.",sender, False) elif (re.search("carte", args[0])): await msg(salon,"- !carte : Tire une carte et la retire du paquet\n- !carte m : remelange le paquet.",sender, False) elif (re.search("card", args[0])): await msg(salon,"- !card : tire une carte sans la retirer du paquet.",sender, False) elif (re.search("liste", args[0])): await msg(salon,"- !liste [Nombre d'elements souhaites] : retourne ce nombre d'elements de la liste.",sender, False) elif (re.search("horloge", args[0])): await msg(salon,"- !horloge : Affiche les horloges\n- !horloge : Crée ou modifie une horloge en lui mettant un niveau (normalement de 0 à 6)\n- !horloge del : Supprime cette horloge.",sender, False) elif (re.search("last", args[0])): await msg(salon,"- !last : Date de son dernier post\n- !last : Date du dernier post de la personne\n- !last inactifs <[+-]nombre de jours> : liste de personnes (en privé) ayant posté depuis + ou - le nombre de jours spécifiés et ayant au maximum le nombre de messages spécifiés.\n",sender, False) elif (re.search("actif", args[0])): await msg(salon,"- !actif : Nombre de ses messages et taille moyenne de ceux ci\n- !actif : Nombre des messages de cette personne et taille moyenne de ceux ci\n",sender, False) elif (re.search("quote", args[0])): await msg(salon,"- !quote : Affiche une citation du salon au hasard\n- !quote : Affiche une citation d'une personne du salon au hasard\n- !quote add : : Enregistre une citation\n- !quote list [Personne] : Affiche les citation du salon ou d'une personne du salon en message privé\n- !quote list all : Affiche toutes les citations de tous les salons en message privé\n- !quote del : Supprime la citation avec l'id spécifié",sender, False) elif (re.search("biere", args[0])): await msg(salon,"- !biere : Fournit une boisson du salon au hasard\n- !biere : Fournit une boisson spécifique du salon\n- !biere give [:Nom du Breuvage] : Offre une boisson (spécifique en option) à la personne spécifiée\n- !biere add : : Enregistre une phrase pour ce breuvage\n- !biere list [Nom de Breuvage] : Affiche les phrases des breuvages du salon ou celles d'un breuvage spécifique du salon en message privé\n- !biere list all : Affiche toutes les citations de tous breuvages de tous les salons en message privé\n- !biere del : Supprime la phrase avec l'id spécifié",sender, False) elif (re.search("accueil", args[0])): await msg(salon,"- !accueil : Modifie le message d'accueil avec message. Il sera affiché à tout nouvel arrivant précédé de la mention 'Bienvenue sur le salon XXX, YYY.'",sender, False) elif (re.search("kick", args[0])): await msg(salon,"- !kick <@mxid> [@mxid] ... : kick les users listés",sender, False) elif (re.search("titre", args[0])): await msg(salon,"- !titre : retourne le titre de la page",sender, False) elif (re.search("mails", args[0]) or re.search("mail", args[0])): await msg(salon,"- !mail add : s'abonner aux messages du salon par mail.\n -!mail del : se désabonner aux messages du salon par mail.",sender, False) elif (re.search("modo", args[0])): await msg(salon,"- !modo : Affiche la liste des modérateurs (ils peuvent gérer le message d'accueil, supprimer des citations ou des boissons, ajouter/retirer des modules, ajouter/retirer des modérateurs)\n- !modo add : Ajoute une personne comme modérateur du salon\n- !modo del : Retire une personne des modérateurs.",sender, False) elif (re.search("module", args[0])): await msg(salon,"- !module : Affiche la liste des modules actifs sur le salon ainsi que celle des modules disponibles\n- !module add : Active un module sur le salon\n- !module del : Désactive un module sur le salon.",sender, False) elif (re.search("cristal", args[0])): await msg(salon,"- !cristal : Réponds à une question posée commençant par Est-ce, Combien, Pourquoi, Quand, Comment, Où et se terminant par un point d'interrogation.",sender, False) else: await msg(salon,"A venir",sender, False) else: rid = room.room_id message = "Commandes disponibles:" for cle,valeur in modules.items(): if (cle[0] == rid and cle[1] == "card" and valeur): message += "\n- !card" if (cle[0] == rid and cle[1] == "carte" and valeur): message += "\n- !carte" if (cle[0] == rid and cle[1] == "liste" and valeur): message += "\n- !liste [Nombre d'elements souhaites]" if (cle[0] == rid and cle[1] == "horloge" and valeur): message += "\n- !horloge : gestion des horloges PBTA" if (cle[0] == rid and cle[1] == "stats" and valeur): message += "\n- !last : Date de dernier post\n- !actif : Nombre de message et taille moyenne de ceux ci" if (cle[0] == rid and cle[1] == "quote" and valeur): message += "\n- !quote : citations du salon" if (cle[0] == rid and cle[1] == "biere" and valeur): message += "\n- !biere : breuvages du salon" if (cle[0] == rid and cle[1] == "cristal" and valeur): message += "\n- !cristal : Posez une question à la boule de cristal" if (cle[0] == rid and cle[1] == "welcome" and valeur): message += "\n- !accueil : Modifie le message d'accueil" if (cle[0] == rid and cle[1] == "kick" and valeur): message += "\n- !kick <@mxid> [@mxid] ... : kick les users listés" if (cle[0] == rid and cle[1] == "titre" and valeur): message += "\n- !titre : retourne le titre de la page en paramètre si celle ci possède une balise titre" if (cle[0] == rid and cle[1] == "mails" and valeur): message += "\n- !mail : s'abonner aux messages du salon par mail." if (cle[0] == rid and cle[1] == "roll" and valeur): message += "\n- :roll \n- :sw \n- :dom \n- :wod \n- :owod \n- :ars \n- :des \n- :star " message += "\n- !modo : Gère les modérateurs du salon\n- !module : Gère les modules actifs sur le salon\n\n- Pour plus de details, tapez !" + name + " \n\nRetrouvez Asmodee sur https://git.ombreport.info/nemesis/asmodee_matrix" await msg(salon,message,sender, False) @bot.listener.on_message_event async def callHelp(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("help"): await help(room, message) @bot.listener.on_message_event async def callAide(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("aide"): await aide(room, message) @bot.listener.on_message_event async def callShowquote(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("quote"): await showquote(room, message) @bot.listener.on_message_event async def callAddquote(room, message): match = botlib.MessageMatch(room, message, bot) if match.is_not_from_this_bot() and match.contains("!addquote"): await addquote(room, message) @bot.listener.on_message_event async def callTitre(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("titre"): await titre(room, message) @bot.listener.on_custom_event(nio.RoomMemberEvent) async def callBienvenue(room, message): match = botlib.MessageMatch(room, message, bot) if match.is_not_from_this_bot(): await bienvenue(room, message) @bot.listener.on_message_event async def callAccueil(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("accueil"): await accueil(room, message) @bot.listener.on_message_event async def callSalon(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("salon"): await salon(room, message) @bot.listener.on_message_event async def callBoisson(room, message): match = botlib.MessageMatch(room, message, bot, "%") if match.is_not_from_this_bot() and match.prefix(): await boissons(room, message) @bot.listener.on_message_event async def callBiere(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("biere"): await biere(room, message) @bot.listener.on_message_event async def callHor(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("horloge"): await horloge(room, message) @bot.listener.on_message_event async def callListe(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("liste"): await liste(room, message) @bot.listener.on_message_event async def callRoll(room, message): match = botlib.MessageMatch(room, message, bot, ":") if match.is_not_from_this_bot() and match.prefix(): await entryPoint(room, message) @bot.listener.on_message_event async def callModule(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("module"): await module(room, message) @bot.listener.on_message_event async def callModo(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("modo"): await modo(room, message) @bot.listener.on_message_event async def echo(room, message): match = botlib.MessageMatch(room, message, bot, PREFIX) if match.is_not_from_this_bot() and match.prefix() and match.command("echo"): print(message) await bot.api.send_text_message( room.room_id, " ".join(arg for arg in match.args()) ) def main(): config = configparser.ConfigParser() config.read('asmodee.ini') USERNAME = "" # Bot's username PASSWORD = "" # Bot's password SERVER = "" # Matrix server URL mods = ["roll", "quote", "biere", "stats", "liste", "horloge", "carte", "card", "cristal", "welcome", "salut", "jdr", "gens", "va", "salon", "kick", "mails", "titre", "invididious"] global admins if ('AUTH' in config): USERNAME = config['AUTH']['username'] # Bot's username PASSWORD = config['AUTH']['password'] # Bot's password SERVER = config['AUTH']['server'] # Matrix server URL admins = config['AUTH']['admin'].split(",") # Admins du bot @admin1:host.tld,@admin2:host.tld,... else: print("Probleme de lecture de configuration asmodee.ini") global liste_mod if ('MOD' in config): try: liste_mod = config['MOD']['liste'].split(',') # Liste des modules except: liste_mod = mods else: liste_mod = mods if (threading.current_thread().__class__.__name__ == '_MainThread'): print("main thread") signal.signal(signal.SIGINT, signal_handler) modules_read() modos_read() prive_read() if ('horloge' in liste_mod): horloge_read() if ('quote' in liste_mod): #quotes_read() citations_read() if ('biere' in liste_mod): bieres_read() if ('salon' in liste_mod): salons_read() if ('welcome' in liste_mod): welcome_read() if __name__ == "__main__": main() bot.run()