# 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 # Var bot = None PREFIX = '!' USERNAME = "" # Listes et dictionnaires admins = [] # Admins du bot modos = {} # Moderateurs des salons modules = {} # Modules activés par salon 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 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) 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) return(room.user_name(sender)) async def msg(room,mess,sender,content=False): try: try: lmod = modos[room.room_id] if (sender not in admins 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)) 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(salon,"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 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[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(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,event['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 = verifPMRoom(room,event) # if (len(args) == 0): # Liste les breuvages du salon # reponse = "Voici les reponses du salon " + room.room_id + "\n" # if (len(room.aliases) > 0): # reponse = reponse + "(alias : " + room.aliases[0] + "\n" # for cle,valeur in breuvages.items(): # reponse = reponse + cle[0] + " / " + str(cle[1]) + " : " + valeur + "\n" # if (len(reponse) > 500): # msg(salon,reponse,event['sender']) # reponse = "" # msg(salon,reponse,event['sender']) # elif (args[0] == "all"): # # tous les breuvages de tous les salons # reponse = "Les breuvages de tous les salons : " + "\n" # msg(salon,reponse,event['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): # msg(salon,reponse,event['sender']) # reponse = "" # msg(salon,reponse,event['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" # msg(salon,reponse,event['sender']) elif (len(args) > 1 and args[0] == "del"): # salon = verifPMRoom(room,event) salon = room.room_id 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",event['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 = verifPMRoom(room,event) salon = room.room_id 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) @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() 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()