# coding: utf8 import random import re import copy import configparser import io import signal import sys import pickle import time from datetime import datetime from matrix_bot_api.matrix_bot_api import MatrixBotAPI from matrix_bot_api.mregex_handler import MRegexHandler from matrix_bot_api.mcommand_handler import MCommandHandler from matrix_client.client import MatrixClient from mall_handler import MAllHandler # Version initiale par Philippe Depriester et Clement Gauche cartes_base = ["As de carreau", "2 de carreau", "3 de carreau", "4 de carreau", "5 de carreau", "6 de carreau", \ "7 de carreau", "8 de carreau", "9 de carreau", "10 de carreau", "Valet de carreau", "Dame de carreau", \ "Roi de carreau", "As de coeur", "2 de coeur", "3 de coeur", "4 de coeur", "5 de coeur", "6 de coeur", \ "7 de coeur", "8 de coeur", "9 de coeur", "10 de coeur", "Valet de coeur", "Dame de coeur", "Roi de coeur", \ "As de pique", "2 de pique", "3 de pique", "4 de pique", "5 de pique", "6 de pique", "7 de pique", "8 de pique", \ "9 de pique", "10 de pique", "Valet de pique", "Dame de pique", "Roi de pique", "As de trefle", "2 de trefle", \ "3 de trefle", "4 de trefle", "5 de trefle", "6 de trefle", "7 de trefle", "8 de trefle", "9 de trefle", \ "10 de trefle", "Valet de trefle", "Dame de trefle", "Roi de trefle", "Joker rouge", "Joker noir"] cartes=list(cartes_base) bot = None clock = {} stats = {} quotes = {} bieres = {} admins = [] # Admins du bot def horloge_read(): global clock try: with open("horloge", "rb") as fichier: loader = pickle.Unpickler(fichier) clock = loader.load() except: clock = {} def stats_read(): global stats try: with open("stats", "rb") as fichier: loader = pickle.Unpickler(fichier) stats = loader.load() except: stats = {} def quotes_read(): global quotes try: with open("quotes", "rb") as fichier: loader = pickle.Unpickler(fichier) quotes = loader.load() except: quotes = {} def bieres_read(): global bieres try: with open("bieres", "rb") as fichier: loader = pickle.Unpickler(fichier) bieres = loader.load() except: bieres = {} def signal_handler(signal, frame): with open("horloge", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(clock) with open("stats", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(stats) with open("quotes", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(quotes) with open("bieres", "wb") as fichier: saver = pickle.Pickler(fichier) saver.dump(bieres) sys.exit(0) class Userstats: #Pour garder des stats sur les users def __init__(self,room,user,nick): self.room = room self.user = user self.nick = nick.strip() self.date = 0 self.mess = 0 self.char = 0 self.kapoue = 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 verifPMRoom(room, event): global bot nick = "" try: nick = event['sender'].split("@")[1].split(":")[0] except: nick = getNick(room, event) client_id = "" client_host = "" try: client_id = bot.client.user_id.split("@")[1].split(":")[0] except: client_id = "asmodee_d" try: client_host = bot.client.user_id.split("@")[1].split(":")[1] except: client_host = "ombreport.info_d" alias = "#" + client_id + "_" + nick + ":" + client_host salon = None #salons = bot.client.rooms #print("\nalias = " + alias) #for cle, salon in salons.items(): # if alias in salon.aliases: # print("trouvé : " + cle) # print(salon.aliases) # salon.send_text("gagné") # return salon # else: # print(salon.aliases) # print(salon.room_id) try: salon = bot.client.join_room(alias) except: #part = [bot.client.user_id,event['sender']] try: salon = bot.client.create_room() salon.set_room_topic("Informations d'Asmodée") salon.invite_user(event['sender']) salon.add_room_alias(alias) salon.update_aliases() except: print("Impossible de creer ou joindre " + alias) return None #salon.send_text("nouvelle conversation") # TODO vérifier la présence du sender dans la liste des membres de ce salon et réinviter si besoin try: salon.invite_user(event['sender']) except: print("il etait deja dedans, c'est sale") return salon def getNick(room, event): members = room.get_joined_members() nick = "" try: nick = [user.get_friendly_name() for user in members if user.user_id == event['sender']][0] except: try: nick = members[event['sender']]['displayname'] except: nick = event['sender'] return(nick) def card(room, event): room.send_text(cartes_base[random.randrange(0,len(cartes_base))]) def carte(room, event): global cartes args = event['content']['body'].split() if (len(args) > 1): cartes=list(cartes_base) room.send_text("Le paquet est melange") else: if (len(cartes) < 1): cartes=list(cartes_base) room.send_text("Le paquet est melange") i = random.randrange(0,len(cartes)) room.send_text(cartes[i]) cartes.pop(i) def help(room, event): help_center(room,event,"help",True) def aide(room, event): help_center(room,event,"aide",False) def help_center(room,event,name,private): args = event['content']['body'].split() args.pop(0) salon = room if (private): salon = verifPMRoom(room,event) if (len(args) > 0): if (re.search("roll", args[0])): salon.send_text(":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.") elif (re.search("sw", args[0])): salon.send_text("- :sw : Lance les des en mode Savage Worlds\nVerbose/Noadd/Explosif/Seuil 4/Niveau de reussite 4/Wild Die d6.") elif (re.search("dom", args[0])): salon.send_text("- :dom : Lance les dommages en mode Savage Worlds\nVerbose/Explosif/seuil 4/Niveau de reussite 4.") elif (re.search("owod", args[0])): salon.send_text("- :owod : Lance les des en mode Ancien Monde des Tenebres\nVerbose/Noadd/Difficulte 6/Relance les 10/Les 1 enleve un succes.") elif (re.search("wod", args[0])): salon.send_text("- :wod : Lance les des en mode Nouveau Monde des Tenebres\nVerbose/Noadd/Difficulte 8/Relance les 10.") elif (re.search("ars", args[0])): salon.send_text("- :ars : Lance les des en mode Ars Magicka : de de tension\nVerbose/Noadd/Sur un 1, on relance et on double.") elif (re.search("des", args[0])): salon.send_text("- :des : Lance des des de desastre\nVerbose/Noadd/Difficulte 10.") elif (re.search("star", args[0])): salon.send_text("- :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.") elif (re.search("carte", args[0])): salon.send_text("- !carte : Tire une carte et la retire du paquet\n- !carte m : remelange le paquet.") elif (re.search("card", args[0])): salon.send_text("- !card : tire une carte sans la retirer du paquet.") elif (re.search("liste", args[0])): salon.send_text("- !liste [Nombre d'elements souhaites] : retourne ce nombre d'elements de la liste.") elif (re.search("horloge", args[0])): salon.send_text("- !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.") elif (re.search("last", args[0])): salon.send_text("- !last : Date de son dernier post\n- !last : Date du dernier post de la personne\n") elif (re.search("actif", args[0])): salon.send_text("- !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") elif (re.search("quote", args[0])): salon.send_text("- !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é") elif (re.search("biere", args[0])): salon.send_text("- !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é") else: salon.send_text("A venir") else: salon.send_text("Commandes disponibles:\n- !card\n- !carte\n- !liste [Nombre d'elements souhaites]\n- !horloge : gestion des horloges PBTA\n- !last : Date de dernier post\n- !actif : Nombre de message et taille moyenne de ceux ci\n- !quote : citations du salon\n- !biere : breuvages du salon\n- :roll \n- :sw \n- :dom \n- :wod \n- :owod \n- :ars \n- :des \n- :star \n\n- Pour plus de details, tapez !" + name + " \n\nRetrouvez Asmodee sur https://git.ombreport.info/nemesis/asmodee_matrix") def roll(result,type,explosif,nb,f,noadd,ars,relance,mitige): # 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): y = 0 total = 0 allresult = [] if (nb > 10000): nb = 10000 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) def entryPoint(room, event): global parser text = event['content']['body'] nick = getNick(room,event) parser = Parser(text,nick,room) print(text) if (parser.eat(":roll",1)): parser.option = [False,False,False,0,0,0,0,0,False,0,0,False] rollXPoint() elif (parser.eat(":dom",1)): parser.option = [True,False,True,0,0,0,4,4,False,0,0,False] rollXPoint() elif (parser.eat(":sw",1)): parser.option = [True,True,True,0,0,0,4,4,False,0,0,False] rollXPoint() elif (parser.eat(":ars",1)): parser.option = [False,True,True,0,0,0,0,0,True,0,0,False] rollXPoint() elif (parser.eat(":des",1)): parser.option = [False,True,True,0,10,0,0,0,False,0,0,False] rollXPoint() elif (parser.eat(":wod",1)): parser.option = [False,True,True,0,8,0,0,0,False,10,0,False] rollXPoint() elif (parser.eat(":owod",1)): parser.option = [False,True,True,0,6,0,0,0,False,10,1,False] rollXPoint() elif (parser.eat(":star",1)): parser.option = [False,False,True,0,0,0,0,0,False,0,0,True] rollXPoint() else: parser.arg["error"] = True if (not parser.arg.get("error",None) and not parser.eat("$",0)): parser.arg["noerror"] = True room.send_text("Je n'ai pas compris " + text) def rollOptionPoint(): 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): 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 def rollXPoint(): global parser 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) rollPlusMoinsPoint() parser = tmp else: parser.arg["error"] = True def rollPlusMoinsPoint(): 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 parser.room.send_text(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) elif (not parser.arg.get("noerror",False)): parser.room.send_text("match = " + parser.mtch + "\nstr = " + parser.str) parser.room.send_text("Rien compris. Essayez '!help' pour obtenir de l'aide.") def rollEntityPoint(): global parser if (parser.eat("[-+]", 1)): if (parser.mtch == "-"): parser.arg["roll_sig"] = not parser.arg.get("roll_sig",True) rollOptionPoint() rollNbPoint() def rollNbPoint(): 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(): 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(): 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 reponses(room, phrases): i = random.randrange(0,len(phrases)) room.send_text(phrases[i]) def jdr(room, event): nick = getNick(room,event) phrases = [] phrases.append("Rock & Role baby!") phrases.append("De toute maniere " + nick + ", les gens ont perdu la foi dans le rolisme.") phrases.append("Bon, c'est quand la prochaine partie " + nick + "?") reponses(room, phrases) def gens(room, event): nick = getNick(room,event) phrases = [] phrases.append("L'enfer c'est les autres.") phrases.append("Bah " + nick + ", les gens c'est pratique pour jouer aux osselets. Bon faut juste trouver ou mettre la chair ensuite.") phrases.append("Franchement " + nick + ", les gens c'est comme les films X. Plus il y'en a, plus ca part en couilles...") reponses(room, phrases) def va(room, event): nick = getNick(room,event) phrases = [] phrases.append("Moi ca va si jamais quelqu'un se pose la question...") phrases.append("Quand l'appetit va, tout va " + nick +"!") phrases.append("Attention a " + nick + ", la suite est 'not safe for depression'") reponses(room, phrases) def maman(room, event): nick = getNick(room,event) phrases = [] phrases.append("On avait dit 'Pas les mamans'!") phrases.append("Oh, c'est pas la mere a boire " + nick + "}!") phrases.append("C'est pas l'homme qui prend la mere, c'est la mere qui prend l'homme...") reponses(room, phrases) def hi_callback(room, event): # Somebody said hi, let's say Hi back nick = getNick(room,event) phrases = [] phrases.append("Salutations " + nick + "!") phrases.append("Chalut " + nick + " :)") phrases.append("Hello " + nick +"!") phrases.append("Oh non, et voilà de nouveau " + nick + "...") reponses(room, phrases) def echo_callback(room, event): args = event['content']['body'].split() args.pop(0) # Echo what they said back room.send_text(' '.join(args)) def liste(room, event): res = [] nick = getNick(room,event) args = event['content']['body'].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)) room.send_text(nick + " obtient :\n" + '\n'.join(res)) else: room.send_text("Utilisation : !liste [nombre d elements]") def cristal(room, event): nick = getNick(room,event) args = event['content']['body'].split() args.pop(0) if (len(args) < 2 or args[len(args)-1][-1] != '?'): room.send_text("Utilisation : !cristal ") else: args[len(args)-1] = args[len(args)-1][0:-1] args = list(set(args).difference(set(["Dans", "Jusque", "le", "la", "les", "de", "des", "un", "une", "est", "sont", "serait", "seraient", "était", "étaient", "sera", "seront", "ont", "aurait", "auraient", "aura", "auront", "a", "à"]))) conj = args[0] args.pop(0) cle = max(args, key=len) if (conj == "Est-ce" or conj == "est-ce"): # traitement Oui/non phrases = [] phrases.append("Evidemment " + nick + ", qu'est ce que tu croyais?") phrases.append("Non " + nick + ", malheurement non.") phrases.append("Oui " + nick +", et quelque chose d'encore pire ensuite pour " + cle + "!") phrases.append("Je ne sais pas si je dois te le dire au risque de te faire de la peine, " + nick + "...") reponses(room, phrases) elif (conj == "Combien" or conj == "combien"): # traitement quantité phrases = [] phrases.append("Enormement " + nick + "!") phrases.append("Quasiment aucun " + nick + " :)") phrases.append("Peu comparé à l'immensité, mais au niveau de " + nick +", forcément...") phrases.append("J'en vois des dizaines, des centaines et par un prompt renfort ils furent 500 en arrivant au port!") reponses(room, phrases) elif (conj == "Pourquoi" or conj == "pourquoi"): # traitement raison phrases = [] phrases.append("Parce que la vie est injuste " + nick + "!") phrases.append("A cause del'orgueil, " + nick + ", la mère de tous les vices.") phrases.append("Pour la richesse, pour le pouvoir, pour le pouvoir qu'apporte la richesse.") phrases.append("A cause d'une démence aussi soudaine que passagère.") reponses(room, phrases) elif (conj == "Comment" or conj == "comment"): # traitement methode phrases = [] phrases.append("Discrètement, sournoisement, vicieusement " + nick + "!") phrases.append("Avec panache! :)") phrases.append("Avec un trombone et un élastique, comme McGuy" + nick +"!") phrases.append("Avec une aide des plus innattendues.") reponses(room, phrases) elif (conj == "Quand" or conj == "quand"): # traitement temps phrases = [] phrases.append("Plus vite que tu ne l'imagine, retourne toi " + nick + "!") phrases.append("Dans vraiment de temps, mais n'est pas mort ce qui à jamais dort...") phrases.append("Pile poil la durée que tu imaginais.") phrases.append("Dans plus lontemps que tu ne le pensais, mais tous les intervenants ont une bonne excuse. Leur collègue de droite a merdé.") reponses(room, phrases) elif (conj == "Où" or conj == "où"): # traitement lieu phrases = [] phrases.append("Dans la ville voisine") phrases.append("A l'extérieur") phrases.append("Au dernier endroit où on y penserait") phrases.append("Là où les ennuis se concentrent, comme d'habitude") reponses(room, phrases) else: # reponse generique phrases = [] phrases.append("Toujours en mouvement le futur est. Toujours sans lunettes flou je vois.") phrases.append("La boule de cristal est momentanément indisponible, veuillez réitérer votre divination ultérieurement.") phrases.append("Une ombre plane sur ton âme, ses crocs approchent.") phrases.append("Tu portes quelque chose de sombre, je refuse de me laisser souiller.") reponses(room, phrases) def horloge(room, event): global clock nick = getNick(room,event) args = event['content']['body'].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): if (int(valeur) == 0): room.send_text(cle[1] + " : " + chr(128320) + "\n") elif (int(valeur) == 1): room.send_text(cle[1] + " : " + chr(128338) + "\n") elif (int(valeur) == 2): room.send_text(cle[1] + " : " + chr(128341) + "\n") elif (int(valeur) == 3): room.send_text(cle[1] + " : " + chr(128344) + "\n") elif (int(valeur) == 4): room.send_text(cle[1] + " : " + chr(128345) + "\n") elif (int(valeur) == 5): room.send_text(cle[1] + " : " + chr(128346) + "\n") elif (int(valeur) == 6): room.send_text(cle[1] + " : " + chr(128347) + "\n") else: room.send_text(cle[1] + " : " + str(valeur) + " \n") 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[0] == "del"): # Supprime une horloge args.pop(0) del clock[room.room_id, ' '.join(args)] else: room.send_text("Utilisation : \n- !horloge : Affiche les horloges. \n- !horloge : Place ou crée l'horloge au niveau spécifié.\n- !horloge del : Supprime l'horloge.") def statistiques(room,event): global stats nick = getNick(room,event) user = event['sender'] usrstats1 = 0 usrstats2 = 0 if ('body' in event['content']): try: usrstats1 = stats[room.room_id,user] except: usrstats1 = Userstats(room.room_id,user,nick) try: usrstats2 = stats[room.room_id,nick] except: usrstats2 = Userstats(room.room_id,user,nick) # date de la phrase date = datetime.now() usrstats1.date = date usrstats2.date = date # recup nb phrases +1, 1 sinon if (usrstats1.mess >= usrstats2.mess): usrstats2.mess = usrstats1.mess + 1 usrstats1.mess = usrstats2.mess else: usrstats1.mess = usrstats2.mess + 1 usrstats2.mess = usrstats1.mess # recup nb lettres +lettres phrase, lettres phrases sinon if (usrstats1.char >= usrstats2.char): usrstats2.char = usrstats1.char + len(event['content']['body']) usrstats1.char = usrstats2.char else: usrstats1.char = usrstats2.char + len(event['content']['body']) usrstats2.char = usrstats1.char # si kapoue, recup nb kapoue +1, 1 sinon if (re.match(".*KAPOUE|.*[Kk]apoue", event['content']['body'])): if (usrstats1.kapoue >= usrstats2.kapoue): usrstats2.kapoue = usrstats1.kapoue + 1 usrstats1.kapoue = usrstats2.kapoue else: usrstats1.kapoue = usrstats2.kapoue + 1 usrstats2.kapoue = usrstats1.kapoue # insertion des objets stats[room.room_id,user] = usrstats1 stats[room.room_id,nick] = usrstats2 def last(room,event): global stats args = event['content']['body'].split() args.pop(0) pers = "" if (len(args) == 0): pers = getNick(room,event) else: pers=" ".join(args) try: usrstats = stats[room.room_id,pers] room.send_text("J'ai vu " + usrstats.nick + " poster pour la derniere fois le " + usrstats.date.strftime("%Y-%m-%d %H:%M:%S")) except: room.send_text(pers + " : Personne non reconnue") #for cle,valeur in stats.items(): # if (cle[0] == room.room_id): # room.send_text(cle[1] + "\n") def actif(room,event): global stats args = event['content']['body'].split() args.pop(0) pers = "" if (len(args) == 0): pers = getNick(room,event) else: pers=" ".join(args) try: usrstats = stats[room.room_id,pers] moy = "{:10.2f}".format(usrstats.char / usrstats.mess) room.send_text(usrstats.nick + " a poste " + str(usrstats.mess) + " messages avec une moyenne de " + moy + " caracteres par message") except: room.send_text(pers + " : Personne non reconnue\n") def nb_kap(room,event): global stats args = event['content']['body'].split() args.pop(0) pers = "" if (len(args) == 0): pers = getNick(room,event) else: pers=" ".join(args) try: usrstats = stats[room.room_id,pers] if (usrstats.kapoue < 10): room.send_text(usrstats.nick + " a crié " + str(usrstats.kapoue) + " KAPOUE!") elif (usrstats.kapoue < 50): room.send_text(usrstats.nick + " a crié " + str(usrstats.kapoue) + " KAPOUE! Pendez le!") elif (usrstats.kapoue < 150): room.send_text(usrstats.nick + " a crié " + str(usrstats.kapoue) + " KAPOUE! Brûlez le vif!") else: room.send_text(usrstats.nick + " a crié " + str(usrstats.kapoue) + " KAPOUE! Faites le manger par des fourmis! Pauvres bêtes...") except: room.send_text(pers + " : Personne non reconnue\n") def quote(room,event): global quotes args = event['content']['body'].split() args.pop(0) famous = {} try: famous = quotes[room.room_id] except: famous = {} if (len(args) > 3 and args[0] == "add"): #ajoute une quote args.pop(0) submit = " ".join(args).split(":") if (len(submit) > 1): # Ajout de la citation nick = submit[0].strip() submit.pop(0) citation = ":".join(submit) tps = datetime.now().microsecond famous[nick,tps] = citation quotes[room.room_id] = famous room.send_text("Ajout de la citation de " + nick + ":" + citation) else: # message d'aide room.send_text("!quote add :") elif (len(args) > 0 and args[0] == "list"): # liste les quotes args.pop(0) salon = verifPMRoom(room,event) if (len(args) == 0): # Liste les quotes 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 famous.items(): reponse = reponse + cle[0] + " / " + str(cle[1]) + " : " + valeur + "\n" if (len(reponse) > 500): salon.send_text(reponse) reponse = "" salon.send_text(reponse) elif (args[0] == "all"): # toutes les quotes de tous les salons reponse = "Les citations de tous les salons : " + "\n" salon.send_text(reponse) for rid,fame in quotes.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): salon.send_text(reponse) reponse = "" salon.send_text(reponse) else: # les quotes du pseudo spécifié nick = " ".join(args) reponse = "Voici les citations enregistrées de " + nick + "\n" for cle,valeur in famous.items(): if (cle[0] == nick): reponse = reponse + cle[0] + " / " + str(cle[1]) + " : " + valeur + "\n" salon.send_text(reponse) elif (len(args) > 1 and args[0] == "del"): salon = verifPMRoom(room,event) if (event['sender'] in admins): id = args[1] reponse = "Voici la citation supprimée : \n" for rid,fame in quotes.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 salon.send_text(reponse) else: salon.send_text("Vous n'êtes pas autorisés à supprimer des citations.") elif (len(args) > 0): # cite une quote d'une personne precise nick = " ".join(args) phrases = [] for cle,valeur in famous.items(): if (cle[0] == nick): phrases.append(cle[0] + " : " + valeur) if (len(phrases) > 0 ): reponses(room,phrases) else: room.send_text("Je n'ai pas de citations pour " + nick) else: # cite une quote aleatoire phrases = [] for cle,valeur in famous.items(): phrases.append(cle[0] + " : " + valeur) if (len(phrases) > 0 ): reponses(room,phrases) else: room.send_text("Je n'ai pas de citations pour ce salon") def biere(room,event): global bieres args = event['content']['body'].split() args.pop(0) brevages = {} give = False elu = "" envoyeur = getNick(room,event) 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] try: args = submit[1].split() except: args = "" if (len(args) > 3 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() submit.pop(0) citation = ":".join(submit) tps = datetime.now().microsecond breuvages[nick,tps] = citation bieres[room.room_id] = breuvages room.send_text("Ajout du breuvage " + nick + ":" + citation) else: # message d'aide room.send_text("!biere add :") 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): salon.send_text(reponse) reponse = "" salon.send_text(reponse) elif (args[0] == "all"): # tous les breuvages de tous les salons reponse = "Les breuvages de tous les salons : " + "\n" salon.send_text(reponse) for rid,fame in biere.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): salon.send_text(reponse) reponse = "" salon.send_text(reponse) 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" salon.send_text(reponse) elif (len(args) > 1 and args[0] == "del"): salon = verifPMRoom(room,event) if (event['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 salon.send_text(reponse) else: salon.send_text("Vous n'êtes pas autorisés à supprimer des breuvages.") 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 ): reponses(room,phrases) else: room.send_text("Je n'ai pas de " + nick + " en stock!") 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 ): reponses(room,phrases) else: room.send_text("Je n'ai pas de breuvages pour ce salon") def invitations(room_id, state): global bot try: global bot bot.client.join_room(room_id) time.sleep(2) del bot main() except: print("Impossible de rejoindre ce salon") def main(): config = configparser.ConfigParser() config.read('asmodee.ini') USERNAME = "" # Bot's username PASSWORD = "" # Bot's password SERVER = "" # Matrix server URL 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") #print("admins") #for admin in admins: # print(admin) # Create an instance of the MatrixBotAPI global bot bot = MatrixBotAPI(USERNAME, PASSWORD, SERVER) # Aide help_handler = MCommandHandler("help", help) bot.add_handler(help_handler) aide_handler = MCommandHandler("aide", aide) bot.add_handler(aide_handler) # Add a regex handler waiting for keywords and answers #hi_handler = MRegexHandler("[Ss]alut|[Cc]halut|'lut|[Cc]oucou|[Bb]onjour|[Hh]ello", hi_callback) #bot.add_handler(hi_handler) #jdr_handler = MRegexHandler("[Jj]dr|[Rr]pg", jdr) #bot.add_handler(jdr_handler) #gens_handler = MRegexHandler("[Gg]ens", gens) #bot.add_handler(gens_handler) #maman_handler = MRegexHandler("[Mm]aman|[Mm]ere", maman) #bot.add_handler(maman_handler) #va_handler = MRegexHandler("ca va|vas]", va) #bot.add_handler(va_handler) # Add a regex handler waiting for the dice commands and aliases entry_handler = MCommandHandler("", entryPoint, ':') bot.add_handler(entry_handler) # Cartes !card tire une carte d'un paquet plein !carte tire une carte qui disparait du paquet card_handler = MCommandHandler("card", card) bot.add_handler(card_handler) carte_handler = MCommandHandler("carte", carte) bot.add_handler(carte_handler) # Un élément d'une liste liste_handler = MCommandHandler("liste", liste) bot.add_handler(liste_handler) # Boule de cristal cristal_handler = MCommandHandler("cristal", cristal) bot.add_handler(cristal_handler) # horloges horloge_read() signal.signal(signal.SIGINT, signal_handler) horloge_handler = MCommandHandler("horloge", horloge) bot.add_handler(horloge_handler) # stats stats_read() stats_handler = MAllHandler(statistiques) bot.add_handler(stats_handler) last_handler = MCommandHandler("last", last) bot.add_handler(last_handler) actif_handler = MCommandHandler("actif", actif) bot.add_handler(actif_handler) nb_kap_handler = MCommandHandler("nb_kap", nb_kap) bot.add_handler(nb_kap_handler) # quotes quotes_read() quote_handler = MCommandHandler("quote", quote) bot.add_handler(quote_handler) # bieres bieres_read() biere_handler = MCommandHandler("biere", biere) bot.add_handler(biere_handler) #test_handler = MCommandHandler("test", verifPMRoom) #bot.add_handler(test_handler) # Invitations bot.client.add_invite_listener(invitations) # Start polling bot.start_polling() # Infinitely read stdin to stall main thread while the bot runs in other threads while True: input() if __name__ == "__main__": main()