Module_state done: global datas management
newnemubot replaces old one
This commit is contained in:
parent
684cecd137
commit
25b2634ea3
12 changed files with 454 additions and 415 deletions
97
modules/birthday.py
Normal file
97
modules/birthday.py
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
# coding=utf-8
|
||||
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from datetime import date
|
||||
|
||||
from module_state import ModuleState
|
||||
|
||||
nemubotversion = 3.0
|
||||
|
||||
def load():
|
||||
global DATAS
|
||||
DATAS.setIndex("name", "birthday")
|
||||
|
||||
|
||||
def help_tiny ():
|
||||
"""Line inserted in the response to the command !help"""
|
||||
return "People birthdays and ages"
|
||||
|
||||
|
||||
def help_full ():
|
||||
return "!anniv /who/: gives the remaining time before the anniversary of /who/\n!age /who/: gives the age of /who/\nIf /who/ is not given, gives the remaining time before your anniversary.\n\n To set yout birthday, say it to nemubot :)"
|
||||
|
||||
|
||||
def findName(msg):
|
||||
if len(msg.cmd) < 2 or msg.cmd[1].lower() == "moi" or msg.cmd[1].lower() == "me":
|
||||
name = msg.sender.lower()
|
||||
else:
|
||||
name = msg.cmd[1].lower()
|
||||
|
||||
matches = []
|
||||
|
||||
if name in DATAS.index:
|
||||
matches.append(name)
|
||||
else:
|
||||
for k in DATAS.index.keys ():
|
||||
if k.find (name) == 0:
|
||||
matches.append (k)
|
||||
return (matches, name)
|
||||
|
||||
|
||||
def parseanswer(msg):
|
||||
if msg.cmd[0] == "anniv":
|
||||
(matches, name) = findName(msg)
|
||||
if len(matches) == 1:
|
||||
name = matches[0]
|
||||
tyd = DATAS.index[name].getDate("born")
|
||||
tyd = datetime(date.today().year, tyd.month, tyd.day)
|
||||
|
||||
if tyd.day == datetime.today().day and tyd.month == datetime.today().month:
|
||||
msg.send_chn (msg.countdown_format (DATAS.index[name].getDate("born"), "", "C'est aujourd'hui l'anniversaire de %s ! Il a%s. Joyeux anniversaire :)" % (name, "%s")))
|
||||
else:
|
||||
if tyd < datetime.today():
|
||||
tyd = datetime(date.today().year + 1, tyd.month, tyd.day)
|
||||
|
||||
msg.send_chn (msg.countdown_format (tyd, "Il reste %s avant l'anniversaire de %s !" % ("%s", name), ""))
|
||||
else:
|
||||
msg.send_chn ("%s: désolé, je ne connais pas la date d'anniversaire de %s. Quand est-il né ?"%(msg.sender, name))
|
||||
return True
|
||||
elif msg.cmd[0] == "age":
|
||||
(matches, name) = findName(msg)
|
||||
if len(matches) == 1:
|
||||
name = matches[0]
|
||||
d = DATAS.index[name].getDate("born")
|
||||
|
||||
msg.send_chn (msg.countdown_format (d, "", "%s a %s." % (n, "%s")))
|
||||
else:
|
||||
msg.send_chn ("%s: désolé, je ne connais pas l'âge de %s. Quand est-il né ?"%(msg.sender, name))
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def parseask(msg):
|
||||
msgl = msg.content.lower ()
|
||||
if re.match("^.*(date de naissance|birthday|geburtstag|née? |nee? le|born on).*$", msgl) is not None:
|
||||
try:
|
||||
extDate = msg.extractDate ()
|
||||
if extDate is None:
|
||||
msg.send_chn ("%s: ta date de naissance ne paraît pas valide..." % (msg.sender))
|
||||
else:
|
||||
if msg.sender.lower() in DATAS.index:
|
||||
DATAS.index[msg.sender.lower()] = extDate
|
||||
else:
|
||||
ms = ModuleState("birthday")
|
||||
ms.setAttribute("name", msg.sender.lower())
|
||||
ms.setAttribute("born", extDate)
|
||||
DATAS.addChild(ms)
|
||||
msg.send_chn ("%s: ok, c'est noté, ta date de naissance est le %s" % (msg.sender, extDate.strftime("%A %d %B %Y à %H:%M")))
|
||||
save()
|
||||
except:
|
||||
msg.send_chn ("%s: ta date de naissance ne paraît pas valide..." % (msg.sender))
|
||||
return True
|
||||
return False
|
||||
|
||||
def parselisten (msg):
|
||||
return False
|
||||
2
modules/birthday.xml
Normal file
2
modules/birthday.xml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" ?>
|
||||
<nemubotmodule name="birthday" />
|
||||
454
modules/qd.py
Normal file
454
modules/qd.py
Normal file
|
|
@ -0,0 +1,454 @@
|
|||
# coding=utf-8
|
||||
|
||||
import re
|
||||
import time
|
||||
import random
|
||||
import sys
|
||||
import threading
|
||||
from datetime import timedelta
|
||||
from datetime import datetime
|
||||
from datetime import date
|
||||
|
||||
from module_state import ModuleState
|
||||
|
||||
nemubotversion = 3.0
|
||||
|
||||
channels = "#nemutest #42sh #ykar #epitagueule"
|
||||
LASTSEEN = dict ()
|
||||
temps = dict ()
|
||||
|
||||
class Wrapper:
|
||||
def __init__(self):
|
||||
self.cache = dict()
|
||||
|
||||
def items(self):
|
||||
global DATAS
|
||||
ret = list()
|
||||
for k in DATAS.index.keys():
|
||||
ret.append((k, self[k]))
|
||||
return ret
|
||||
|
||||
def __contains__(self, i):
|
||||
global DATAS
|
||||
return i in DATAS.index
|
||||
|
||||
def __getitem__(self, i):
|
||||
global DATAS
|
||||
if i in self.cache:
|
||||
return self.cache[i]
|
||||
else:
|
||||
sc = Score()
|
||||
sc.parse(DATAS.index[i])
|
||||
self.cache[i] = sc
|
||||
return sc
|
||||
|
||||
def __setitem__(self, i, j):
|
||||
global DATAS
|
||||
ms = ModuleState("player")
|
||||
ms.setAttribute("name", i)
|
||||
j.save(ms)
|
||||
DATAS.addChild(ms)
|
||||
DATAS.setIndex("name", "player")
|
||||
|
||||
def __delitem__(self, i):
|
||||
global DATAS
|
||||
del DATAS.index[i]
|
||||
|
||||
def save(self, i):
|
||||
if i in self.cache:
|
||||
self.cache[i].save(DATAS.index[i])
|
||||
del self.cache[i]
|
||||
|
||||
|
||||
SCORES = Wrapper()
|
||||
|
||||
class Score:
|
||||
def __init__(self):
|
||||
#FourtyTwo
|
||||
self.ftt = 0
|
||||
#TwentyThree
|
||||
self.twt = 0
|
||||
self.pi = 0
|
||||
self.notfound = 0
|
||||
self.tententen = 0
|
||||
self.leet = 0
|
||||
self.great = 0
|
||||
self.bad = 0
|
||||
self.triche = 0
|
||||
self.last = None
|
||||
self.changed = False
|
||||
|
||||
def parse(self, item):
|
||||
self.ftt = item.getInt("fourtytwo")
|
||||
self.twt = item.getInt("twentythree")
|
||||
self.pi = item.getInt("pi")
|
||||
self.notfound = item.getInt("notfound")
|
||||
self.tententen = item.getInt("tententen")
|
||||
self.leet = item.getInt("leet")
|
||||
self.great = item.getInt("great")
|
||||
self.bad = item.getInt("bad")
|
||||
self.triche = item.getInt("triche")
|
||||
|
||||
def save(self, state):
|
||||
state.setAttribute("fourtytwo", self.ftt)
|
||||
state.setAttribute("twentythree", self.twt)
|
||||
state.setAttribute("pi", self.pi)
|
||||
state.setAttribute("notfound", self.notfound)
|
||||
state.setAttribute("tententen", self.tententen)
|
||||
state.setAttribute("leet", self.leet)
|
||||
state.setAttribute("great", self.great)
|
||||
state.setAttribute("bad", self.bad)
|
||||
state.setAttribute("triche", self.triche)
|
||||
|
||||
def merge(self, other):
|
||||
self.ftt += other.ftt
|
||||
self.twt += other.twt
|
||||
self.pi += other.pi
|
||||
self.notfound += other.notfound
|
||||
self.tententen += other.tententen
|
||||
self.leet += other.leet
|
||||
self.great += other.great
|
||||
self.bad += other.bad
|
||||
self.triche += other.triche
|
||||
|
||||
def newWinner(self):
|
||||
self.ftt = 0
|
||||
self.twt = 0
|
||||
self.pi = 1
|
||||
self.notfound = 1
|
||||
self.tententen = 0
|
||||
self.leet = 1
|
||||
self.great = -1
|
||||
self.bad = -4
|
||||
self.triche = 0
|
||||
|
||||
def isWinner(self):
|
||||
return self.great >= 42
|
||||
|
||||
def playFtt(self):
|
||||
if self.canPlay():
|
||||
self.ftt += 1
|
||||
def playTwt(self):
|
||||
if self.canPlay():
|
||||
self.twt += 1
|
||||
def playSuite(self):
|
||||
self.canPlay()
|
||||
self.twt += 1
|
||||
self.great += 1
|
||||
def playPi(self):
|
||||
if self.canPlay():
|
||||
self.pi += 1
|
||||
def playNotfound(self):
|
||||
if self.canPlay():
|
||||
self.notfound += 1
|
||||
def playTen(self):
|
||||
if self.canPlay():
|
||||
self.tententen += 1
|
||||
def playLeet(self):
|
||||
if self.canPlay():
|
||||
self.leet += 1
|
||||
def playGreat(self):
|
||||
if self.canPlay():
|
||||
self.great += 1
|
||||
def playBad(self):
|
||||
if self.canPlay():
|
||||
self.bad += 1
|
||||
self.great += 1
|
||||
def playTriche(self):
|
||||
self.triche += 1
|
||||
def oupsTriche(self):
|
||||
self.triche -= 1
|
||||
def bonusQuestion(self):
|
||||
return
|
||||
|
||||
def toTuple(self):
|
||||
return (self.ftt, self.twt, self.pi, self.notfound, self.tententen, self.leet, self.great, self.bad, self.triche)
|
||||
|
||||
def canPlay(self):
|
||||
ret = self.last == None or self.last.minute != datetime.now().minute or self.last.hour != datetime.now().hour or self.last.day != datetime.now().day
|
||||
self.changed = self.changed or ret
|
||||
return ret
|
||||
|
||||
def hasChanged(self):
|
||||
if self.changed:
|
||||
self.changed = False
|
||||
self.last = datetime.now()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def score(self):
|
||||
return (self.ftt * 2 + self.great * 5 + self.leet * 13.37 + (self.pi + 1) * 3.1415 * (self.notfound + 1) + self.tententen * 10 + self.twt - (self.bad + 1) * 10 * (self.triche * 5 + 1) + 7)
|
||||
|
||||
def details(self):
|
||||
return "42: %d, 23: %d, leet: %d, pi: %d, 404: %d, 10: %d, great: %d, bad: %d, triche: %d = %d."%(self.ftt, self.twt, self.leet, self.pi, self.notfound, self.tententen, self.great, self.bad, self.triche, self.score())
|
||||
|
||||
|
||||
def load():
|
||||
global DATAS
|
||||
DATAS.setIndex("name", "player")
|
||||
|
||||
|
||||
def help_tiny ():
|
||||
"""Line inserted in the response to the command !help"""
|
||||
return "42 game!"
|
||||
|
||||
def help_full ():
|
||||
return "!42: display scores\n!42 help: display the performed calculate\n!42 manche: display information about current round\n!42 /who/: show the /who/'s scores"
|
||||
|
||||
|
||||
def rev (tupl):
|
||||
(k, v) = tupl
|
||||
return (v.score(), k)
|
||||
|
||||
def parseanswer (msg):
|
||||
if msg.cmd[0] == "42" or msg.cmd[0] == "score" or msg.cmd[0] == "scores":
|
||||
global SCORES
|
||||
if len(msg.cmd) > 2 and msg.is_owner and ((msg.cmd[1] == "merge" and len(msg.cmd) > 3) or msg.cmd[1] == "oupstriche"):
|
||||
if msg.cmd[2] in SCORES and (len(msg.cmd) <= 3 or msg.cmd[3] in SCORES):
|
||||
if msg.cmd[1] == "merge":
|
||||
SCORES[msg.cmd[2]].merge (SCORES[msg.cmd[3]])
|
||||
del SCORES[msg.cmd[3]]
|
||||
msg.send_chn ("%s a été correctement fusionné avec %s."%(msg.cmd[3], msg.cmd[2]))
|
||||
elif msg.cmd[1] == "oupstriche":
|
||||
SCORES[msg.cmd[2]].oupsTriche()
|
||||
else:
|
||||
if msg.cmd[2] not in SCORES:
|
||||
msg.send_chn ("%s n'est pas un joueur connu."%msg.cmd[2])
|
||||
elif msg.cmd[3] not in SCORES:
|
||||
msg.send_chn ("%s n'est pas un joueur connu."%msg.cmd[3])
|
||||
elif len(msg.cmd) > 1 and (msg.cmd[1] == "help" or msg.cmd[1] == "aide"):
|
||||
msg.send_chn ("Formule : \"42\" * 2 + great * 5 + leet * 13.37 + (pi + 1) * 3.1415 * (not_found + 1) + tententen * 10 + \"23\" - (bad + 1) * 10 * (triche * 5 + 1) + 7")
|
||||
elif len(msg.cmd) > 1 and (msg.cmd[1] == "manche" or msg.cmd[1] == "round"):
|
||||
manche = DATAS.getNode("manche")
|
||||
msg.send_chn ("Nous sommes dans la %de manche, gagnée par %s avec %d points et commencée par %s le %s." % (manche.getInt("number"), manche["winner"], manche.getInt("winner_score"), manche["who"], manche.getDate("date")))
|
||||
#elif msg.channel == "#nemutest":
|
||||
else:
|
||||
phrase = ""
|
||||
|
||||
if len(msg.cmd) > 1:
|
||||
if msg.cmd[1] in SCORES:
|
||||
phrase += " " + msg.cmd[1] + ": " + SCORES[msg.cmd[1]].details()
|
||||
else:
|
||||
phrase = " %s n'a encore jamais joué,"%(msg.cmd[1])
|
||||
else:
|
||||
for nom, scr in sorted(SCORES.items(), key=rev, reverse=True):
|
||||
score = scr.score()
|
||||
if score != 0:
|
||||
if phrase == "":
|
||||
phrase = " *%s.%s: %d*,"%(nom[0:1], nom[1:len(nom)], score)
|
||||
else:
|
||||
phrase += " %s.%s: %d,"%(nom[0:1], nom[1:len(nom)], score)
|
||||
|
||||
msg.send_chn ("Scores :%s" % (phrase[0:len(phrase)-1]))
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def win(msg):
|
||||
global SCORES
|
||||
who = msg.sender
|
||||
|
||||
manche = DATAS.getNode("manche")
|
||||
|
||||
maxi_scor = 0
|
||||
maxi_name = None
|
||||
|
||||
for player in DATAS.index.keys():
|
||||
scr = SCORES[player].score()
|
||||
if scr > maxi_scor:
|
||||
maxi_scor = scr
|
||||
maxi_name = player
|
||||
|
||||
#Reset !
|
||||
SCORES = dict()
|
||||
# SCORES[maxi_name] = (-10, 0, -4, 0, 0, -2, 0)
|
||||
# SCORES[maxi_name] = (0, 0, 0, 0, 0, 0, 0)
|
||||
SCORES[who] = Score()
|
||||
SCORES[who].newWinner()
|
||||
|
||||
if who != maxi_name:
|
||||
msg.send_chn ("Félicitations %s, tu remportes cette manche terminée par %s, avec un score de %d !"%(maxi_name, who, maxi_scor))
|
||||
else:
|
||||
msg.send_chn ("Félicitations %s, tu remportes cette manche avec %d points !"%(maxi_name, maxi_scor))
|
||||
|
||||
manche.setAttribute("number", manche.getInt("number") + 1)
|
||||
manche.setAttribute("winner", maxi_name)
|
||||
manche.setAttribute("winner_score", maxi_scor)
|
||||
manche.setAttribute("who", who)
|
||||
manche.setAttribute("date", datetime.now())
|
||||
|
||||
print ("Nouvelle manche !")
|
||||
save()
|
||||
|
||||
|
||||
def parseask (msg):
|
||||
if len(DELAYED) > 0:
|
||||
if msg.sender in DELAYED:
|
||||
DELAYED[msg.sender].msg = msg.content[9:]
|
||||
DELAYED[msg.sender].delayEvnt.set()
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def getUser(name):
|
||||
global SCORES
|
||||
if name not in SCORES:
|
||||
SCORES[name] = Score()
|
||||
return SCORES[name]
|
||||
|
||||
|
||||
def parselisten (msg):
|
||||
if len(DELAYED) > 0 and msg.sender in DELAYED and DELAYED[msg.sender].good(msg.content):
|
||||
msg.send_chn("%s: n'oublie pas le nemubot: devant ta réponse pour qu'elle soit prise en compte !" % msg.sender)
|
||||
|
||||
bfrseen = None
|
||||
if msg.realname in LASTSEEN:
|
||||
bfrseen = LASTSEEN[msg.realname]
|
||||
LASTSEEN[msg.realname] = datetime.now()
|
||||
|
||||
if msg.channel == "#nemutest" and msg.sender not in DELAYED:
|
||||
# if msg.channel != "#nemutest" and msg.sender not in DELAYED:
|
||||
|
||||
if re.match("^(42|quarante[- ]?deux).{,2}$", msg.content.strip().lower()):
|
||||
if msg.time.minute == 10 and msg.time.second == 10 and msg.time.hour == 10:
|
||||
getUser(msg.sender).playTen()
|
||||
getUser(msg.sender).playGreat()
|
||||
elif msg.time.minute == 42:
|
||||
if msg.time.second == 0:
|
||||
getUser(msg.sender).playGreat()
|
||||
getUser(msg.sender).playFtt()
|
||||
else:
|
||||
getUser(msg.sender).playBad()
|
||||
|
||||
if re.match("^(23|vingt[ -]?trois).{,2}$", msg.content.strip().lower()):
|
||||
if msg.time.minute == 23:
|
||||
if msg.time.second == 0:
|
||||
getUser(msg.sender).playGreat()
|
||||
getUser(msg.sender).playTwt()
|
||||
else:
|
||||
getUser(msg.sender).playBad()
|
||||
|
||||
if re.match("^(10){3}.{,2}$", msg.content.strip().lower()):
|
||||
if msg.time.minute == 10 and msg.time.hour == 10:
|
||||
if msg.time.second == 10:
|
||||
getUser(msg.sender).playGreat()
|
||||
getUser(msg.sender).playTen()
|
||||
else:
|
||||
getUser(msg.sender).playBad()
|
||||
|
||||
if re.match("^0?12345.{,2}$", msg.content.strip().lower()):
|
||||
if msg.time.hour == 1 and msg.time.minute == 23 and (msg.time.second == 45 or (msg.time.second == 46 and msg.time.microsecond < 330000)):
|
||||
getUser(msg.sender).playSuite()
|
||||
else:
|
||||
getUser(msg.sender).playBad()
|
||||
|
||||
if re.match("^[1l][e3]{2}[t7] ?t?ime.{,2}$", msg.content.strip().lower()):
|
||||
if msg.time.hour == 13 and msg.time.minute == 37:
|
||||
if msg.time.second == 0:
|
||||
getUser(msg.sender).playGreat()
|
||||
getUser(msg.sender).playLeet()
|
||||
else:
|
||||
getUser(msg.sender).playBad()
|
||||
|
||||
if re.match("^(pi|3.14) ?time.{,2}$", msg.content.strip().lower()):
|
||||
if msg.time.hour == 3 and msg.time.minute == 14:
|
||||
if msg.time.second == 15 or msg.time.second == 16:
|
||||
getUser(msg.sender).playGreat()
|
||||
getUser(msg.sender).playPi()
|
||||
else:
|
||||
getUser(msg.sender).playBad()
|
||||
|
||||
if re.match("^(404( ?time)?|time ?not ?found).{,2}$", msg.content.strip().lower()):
|
||||
if msg.time.hour == 4 and msg.time.minute == 4:
|
||||
if msg.time.second == 0 or msg.time.second == 4:
|
||||
getUser(msg.sender).playGreat()
|
||||
getUser(msg.sender).playNotfound()
|
||||
else:
|
||||
getUser(msg.sender).playBad()
|
||||
|
||||
if getUser(msg.sender).isWinner():
|
||||
print ("Nous avons un vainqueur ! Nouvelle manche :p")
|
||||
win(msg)
|
||||
return True
|
||||
elif getUser(msg.sender).hasChanged():
|
||||
gu = GameUpdater(msg, bfrseen)
|
||||
gu.start()
|
||||
return True
|
||||
return False
|
||||
|
||||
DELAYED = dict()
|
||||
|
||||
class DelayedTuple:
|
||||
def __init__(self, regexp, great):
|
||||
self.delayEvnt = threading.Event()
|
||||
self.msg = None
|
||||
self.regexp = regexp
|
||||
self.great = great
|
||||
|
||||
def triche(self, res):
|
||||
if res is not None:
|
||||
return re.match(".*" + self.regexp + ".*", res.lower() + " ") is None
|
||||
else:
|
||||
return True
|
||||
|
||||
def perfect(self, res):
|
||||
if res is not None:
|
||||
return re.match(".*" + self.great + ".*", res.lower() + " ") is not None
|
||||
else:
|
||||
return False
|
||||
|
||||
def wait(self, timeout):
|
||||
self.delayEvnt.wait(timeout)
|
||||
|
||||
LASTQUESTION = 99999
|
||||
|
||||
class GameUpdater(threading.Thread):
|
||||
def __init__(self, msg, bfrseen):
|
||||
self.msg = msg
|
||||
self.bfrseen = bfrseen
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
def run(self):
|
||||
global DELAYED, LASTQUESTION
|
||||
|
||||
if self.bfrseen is not None:
|
||||
seen = datetime.now() - self.bfrseen
|
||||
rnd = random.randint(0, int(seen.seconds/90))
|
||||
else:
|
||||
rnd = 1
|
||||
|
||||
if rnd != 0:
|
||||
QUESTIONS = CONF.getNodes("question")
|
||||
|
||||
if self.msg.channel == "#nemutest":
|
||||
quest = 9
|
||||
else:
|
||||
if LASTQUESTION >= len(QUESTIONS):
|
||||
random.shuffle(QUESTIONS)
|
||||
LASTQUESTION = 0
|
||||
quest = LASTQUESTION
|
||||
LASTQUESTION += 1
|
||||
|
||||
question = QUESTIONS[quest]["question"]
|
||||
regexp = QUESTIONS[quest]["regexp"]
|
||||
great = QUESTIONS[quest]["great"]
|
||||
self.msg.send_chn("%s: %s" % (self.msg.sender, question))
|
||||
|
||||
DELAYED[self.msg.sender] = DelayedTuple(regexp, great)
|
||||
|
||||
DELAYED[self.msg.sender].wait(20)
|
||||
|
||||
if DELAYED[self.msg.sender].triche(DELAYED[self.msg.sender].msg):
|
||||
getUser(self.msg.sender).playTriche()
|
||||
self.msg.send_chn("%s: Tricheur !" % self.msg.sender)
|
||||
elif DELAYED[self.msg.sender].perfect(DELAYED[self.msg.sender].msg):
|
||||
if random.randint(0, 10) == 1:
|
||||
getUser(self.msg.sender).bonusQuestion()
|
||||
self.msg.send_chn("%s: Correct !" % self.msg.sender)
|
||||
else:
|
||||
self.msg.send_chn("%s: J'accepte" % self.msg.sender)
|
||||
del DELAYED[self.msg.sender]
|
||||
SCORES.save(self.msg.sender)
|
||||
save()
|
||||
Loading…
Add table
Add a link
Reference in a new issue