]> gitweb.pimeys.fr Git - bots/deconnaisseur.git/blob - deconnaisseur.py
On ne propose pas d'énigme si le chan est mort
[bots/deconnaisseur.git] / deconnaisseur.py
1 #!/usr/bin/python
2 # -*- coding:utf8 -*-
3
4 # Codé par 20-100 le 23/04/12
5
6 # Un bot IRC qui sort des déconnaissances
7
8 import irclib
9 import ircbot
10 import threading
11 import random
12 import time
13 import pickle
14 import re
15 from remplace_accents import remplace_accents
16
17 config_password="PatrickSébastien"
18 config_pseudo="deconnaisseur"
19 config_chanlist=["#bot","#flood"]
20 config_play_channels=["#flood"]
21 config_stay_channels=["#flood","#bot"]
22 config_overops=["[20-100]","[20-100]_","PEB"]
23 config_ops=["Nit","Eguel","Harry"]
24
25 config_source_file="deconnaissances.txt"
26 config_played_file_template="played.%s.txt" #il faut rajouter le nom du serveur
27 def get_config_played_file(serveur):
28 serveurs={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
29 return config_played_file_template%(serveurs[serveur])
30 ttrig=120 #time trigger (normalement 120, mais diminué pour les tests)
31 Ttrig=600 #between two enigms (600)
32 config_time_incompressible=15 #on peut pas retrigger en dessous de ce temps (60)
33 config_time_incompressible_clue=60 #on peut pas forcer la demande d'indice en dessous
34
35 config_score_file="scores.pickle"
36
37 config_tag_triggers=[u"t(|a)g",u"ta gueule",u"la ferme",u"ferme( |-)la",u"tais-toi",u"chut"]
38 config_tag_actions=[u"se tait",u"ferme sa gueule",u"se la ferme",u"la ferme"]
39 config_tag_answers=[u"J'me tais si j'veux !",
40 u"Je t'entends pas :°",
41 u"Héhé, try again",
42 u"Non, j'ai pas envie",
43 u"Peut-être quand toi tu la fermeras, et encore…"]
44
45 config_level2=[]
46 config_level3=["[20-100]","Petite-Peste","PEB","Constance","pika"]
47
48 config_debug_stdout = True
49 config_logfile_template="deconnaisseur.%s.log"
50 def get_config_logfile(serveur):
51 serveurs={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
52 return config_logfile_template%(serveurs[serveur])
53
54 config_quit_messages=[u"Se décrocher la mâchoire, pas cuit bras d'oiseau ou métalld précieuxld"]
55
56 config_leave_messages=[u"On continuera à jouer plus tard ;)"]
57
58 # Quand personne ne cause, on finit par se taire
59 # temps au bout duquel, si personne n'a parlé, on se tait
60 config_idle_time=20*60
61 # liste des bots, qui ne sont pas considérés comme de l'activité
62 config_idle_bots=["deconnaisseur","Basile","historien","Hung","Salesman","Shadobot","Wen","___"]
63
64 class UnicodeBotError(Exception):
65 pass
66 def bot_unicode(chain):
67 try:
68 unicode(chain,"utf8")
69 except UnicodeDecodeError:
70 raise UnicodeBotError
71
72 def log(serveur,channel,auteur=None,message=None):
73 f=open(get_config_logfile(serveur),"a")
74 if auteur==message==None:
75 # alors c'est que c'est pas un channel mais juste une ligne de log
76 chain="%s %s"%(time.strftime("%F %T"),channel)
77 else:
78 chain="%s [%s:%s] %s"%(time.strftime("%F %T"),channel,auteur,message)
79 f.write(chain+"\n")
80 if config_debug_stdout:
81 print chain
82 f.close()
83
84
85 def reussi(message,answer,answer_regexp,auteur):
86 if auteur in config_level3:
87 return answer in message
88 if auteur in config_level2:
89 return remplace_accents(answer) in message
90 else:
91 if re.match(remplace_accents(answer_regexp).lower(),remplace_accents(message).lower()):
92 return True
93
94 def is_something(chain,matches,avant=u".*(?:^| )",apres=u"(?:$|\.| |,|;).*",case_sensitive=False,debug=False):
95 if case_sensitive:
96 chain=unicode(chain,"utf8")
97 else:
98 chain=unicode(chain,"utf8").lower()
99 allmatches="("+"|".join(matches)+")"
100 reg=(avant+allmatches+apres).lower()
101 o=re.match(reg,chain)
102 return o
103
104 def is_tag(chain):
105 return is_something(chain,config_tag_triggers)
106
107 class RefuseError(Exception):
108 pass
109
110 class Deconnaisseur(ircbot.SingleServerIRCBot):
111 def __init__(self,serveur,debug=False):
112 temporary_pseudo=config_pseudo+str(random.randrange(10000,100000))
113 ircbot.SingleServerIRCBot.__init__(self, [(serveur, 6667)],
114 temporary_pseudo,"Un bot irc.[flagellez 20-100, il le mérite]", 10)
115 self.debug=debug
116 self.serveur=serveur
117 self.overops=config_overops
118 self.ops=self.overops+config_ops
119 self.chanlist=config_chanlist
120 self.stay_channels=config_stay_channels
121 self.play_channels=config_play_channels
122 self.play_status={i:[0] for i in self.play_channels}
123 self.last_activity={}
124 self.quiet_channels=[]
125
126 def give_me_my_pseudo(self,serv):
127 serv.privmsg("NickServ","RECOVER %s %s"%(config_pseudo,config_password))
128 serv.privmsg("NickServ","RELEASE %s %s"%(config_pseudo,config_password))
129 time.sleep(0.3)
130 serv.nick(config_pseudo)
131
132 def on_welcome(self, serv, ev):
133 self.serv=serv # ça serv ira :)
134 self.give_me_my_pseudo(serv)
135 serv.privmsg("NickServ","identify %s"%(config_password))
136 log(self.serveur,"Connected")
137 if self.debug:
138 self.chanlist=["#bot"]
139 self.play_channels=["#bot"]
140 for c in self.chanlist:
141 log(self.serveur,"JOIN %s"%(c))
142 serv.join(c)
143 self.update_activity(c,"") # la chaîne vide ne sera jamais un nom de bot et donc marchera toujours
144 for c in self.play_channels:
145 token=time.time()-3600
146 self.play_status[c]=[0,token]
147 serv.execute_delayed(random.randrange(ttrig),self.start_enigme,(serv,c,token))
148
149 def start_enigme(self,serv,channel,token=None):
150 # On reste silencieux si lechan n'est pas actif
151 if not self.is_active(channel):
152 serv.execute_delayed(ttrig*5,self.start_enigme,(serv,channel,token))
153 return
154 if self.play_status[channel][0]==0 and channel in self.play_channels:
155 ok="skip"
156 if token==self.play_status[channel][-1]:
157 ok="do_it"
158 if token==None:
159 if time.time() > self.play_status[channel][-1]+config_time_incompressible:
160 ok="do_it"
161 else:
162 ok="refuse"
163 if ok=="do_it":
164 enigme,indice,answer_reg,answer=self.get_enigme()
165 log(self.serveur,channel,u"$Énigme$".encode("utf8"),("%s; %s; %s; %s"%(enigme, indice, answer_reg, answer)).encode("utf8"))
166 serv.privmsg(channel,enigme.encode("utf8"))
167 token=time.time()
168 self.play_status[channel]=[1,enigme,indice,answer_reg,answer,token]
169 serv.execute_delayed(random.randrange(ttrig*3,ttrig*5),self.give_indice,(serv,channel,token))
170 elif ok=="refuse":
171 raise RefuseError
172 def give_indice(self,serv,channel,token):
173 if self.play_status[channel][0]==1:
174 if token==None:
175 # c'est donc que l'indice a été demandé
176 if self.play_status[channel][-1]+config_time_incompressible_clue<time.time():
177 token=self.play_status[channel][-1]
178 if self.play_status[channel][-1]==token:
179 indice=self.play_status[channel][2]
180 serv.privmsg(channel,"indice : %s"%(indice).encode("utf8"))
181 self.play_status[channel][0]=2
182 serv.execute_delayed(random.randrange(ttrig*1,ttrig*3),self.give_answer,(serv,channel,token))
183 def give_answer(self,serv,channel,token):
184 if self.play_status[channel][0]==2 and self.play_status[channel][-1]==token:
185 answer=self.play_status[channel][4]
186 serv.privmsg(channel,"C'était : %s"%(answer).encode("utf8"))
187 token=time.time()
188 self.play_status[channel]=[0,token]
189 serv.execute_delayed(random.randrange(Ttrig*5,Ttrig*10),self.start_enigme,(serv,channel,token))
190
191 def get_enigme(self):
192 # on récupère les déconnaissances
193 f=open(config_source_file)
194 t=f.read()
195 f.close()
196 l=re.findall("%\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)\n",t)
197 dec={int(i[0]):list(i[1:]) for i in l if len(i)==5}
198 # on va chercher combien de fois elles ont été jouées
199 played_file=get_config_played_file(self.serveur)
200 f=open(played_file)
201 t=f.read()
202 f.close()
203 l=re.findall("(.*):(.*)",t)
204 played={int(i[0]):int(i[1]) for i in l}
205 # on récupère le nombre d'occurrences le plus faible
206 mini=min(played.values())
207 # on choisit un id dans ceux qui ont ce nombre d'occurences
208 id_choisi=random.choice([k for k,v in played.items() if v==mini])
209 enigme,indice,answer_reg,answer=dec[id_choisi]
210 # on incrémente la choisie
211 played[id_choisi]+=1
212 # on enregistre le played_file
213 f=open(played_file,"w")
214 f.write("\n".join(["%-3s : %s"%(k,v) for k,v in played.items()]))
215 f.close()
216 return enigme.decode("utf8"),indice.decode("utf8"),answer_reg.decode("utf8"),answer.decode("utf8")
217
218 def pourmoi(self, serv, message):
219 pseudo=self.nick
220 size=len(pseudo)
221 if message[:size]==pseudo and len(message)>size and message[size]==":":
222 return (True,message[size+1:].strip(" "))
223 else:
224 return (False,message)
225
226 def on_privmsg(self, serv, ev):
227 message=ev.arguments()[0]
228 auteur = irclib.nm_to_n(ev.source())
229 try:
230 test=bot_unicode(message)
231 except UnicodeBotError:
232 serv.privmsg(auteur,
233 "Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…")
234 return
235 message=message.split()
236 cmd=message[0].lower()
237 notunderstood=False
238 if cmd=="help":
239 helpmsg_default="""Liste des commandes :
240 HELP Affiche ce message d'aide
241 SCORE Affiche ton score (SCORE TRANSFERT <pseudo> [<n>] pour transférer des points)
242 SCORES Affiche les scores"""
243 helpmsg_ops="""
244 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
245 LEAVE Faire quitter un channel
246 PLAY Passe un channel en mode "jouer"
247 NOPLAY Passe un channel en mode "ne pas jouer"
248 QUIET Se taire sur un channel
249 NOQUIET Opposé de QUIET"""
250 helpmsg_overops="""
251 SCORES {DEL|ADD|SUB} Tu veux un dessin ?
252 SAY Fais envoyer un message sur un chan ou à une personne
253 STAY Ignorera les prochains LEAVE pour un chan
254 NOSTAY Opposé de STAY
255 STATUS Montre l'état courant
256 DIE Mourir"""
257 helpmsg=helpmsg_default
258 if auteur in self.ops:
259 helpmsg+=helpmsg_ops
260 if auteur in self.overops:
261 helpmsg+=helpmsg_overops
262 for ligne in helpmsg.split("\n"):
263 serv.privmsg(auteur,ligne)
264 elif cmd=="join":
265 if auteur in self.ops:
266 if len(message)>1:
267 if message[1] in self.chanlist:
268 serv.privmsg(auteur,"Je suis déjà sur %s"%(message[1]))
269 else:
270 serv.join(message[1])
271 self.chanlist.append(message[1])
272 self.update_activity(message[1],"")
273 serv.privmsg(auteur,"Channels : "+" ".join(self.chanlist))
274 log(self.serveur,"priv",auteur," ".join(message))
275 else:
276 serv.privmsg(auteur,"Channels : "+" ".join(self.chanlist))
277 else:
278 notunderstood=True
279 elif cmd=="leave":
280 if auteur in self.ops and len(message)>1:
281 if message[1] in self.chanlist:
282 if not (message[1] in self.stay_channels) or auteur in self.overops:
283 self.quitter(message[1]," ".join(message[2:]))
284 self.chanlist.remove(message[1])
285 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
286 else:
287 serv.privmsg(auteur,"Non, je reste !")
288 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
289 else:
290 serv.privmsg(auteur,"Je ne suis pas sur %s"%(message[1]))
291 else:
292 notunderstood=True
293 elif cmd=="stay":
294 if auteur in self.overops:
295 if len(message)>1:
296 if message[1] in self.stay_channels:
297 serv.privmsg(auteur,"Je stay déjà sur %s."%(message[1]))
298 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
299 else:
300 self.stay_channels.append(message[1])
301 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
302 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
303 else:
304 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
305 else:
306 notunderstood=True
307 elif cmd=="nostay":
308 if auteur in self.overops:
309 if len(message)>1:
310 if message[1] in self.stay_channels:
311 self.stay_channels.remove(message[1])
312 serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
313 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
314 else:
315 serv.privmsg(auteur,"Je ne stay pas sur %s."%(message[1]))
316 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
317 else:
318 notunderstood=True
319 elif cmd=="play":
320 if auteur in self.ops:
321 if len(message)>1:
322 if message[1] in self.play_channels:
323 serv.privmsg(auteur,"Je play déjà sur %s."%(message[1]))
324 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
325 else:
326 self.play_channels.append(message[1])
327 self.play_status[message[1]]=[0,time.time()-3600]
328 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
329 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
330 else:
331 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
332 else:
333 notunderstood=True
334 elif cmd=="noplay":
335 if auteur in self.ops:
336 if len(message)>1:
337 if message[1] in self.play_channels:
338 self.play_channels.remove(message[1])
339 serv.privmsg(auteur,"Play channels : "+" ".join(self.play_channels))
340 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
341 else:
342 serv.privmsg(auteur,"Je ne play pas sur %s."%(message[1]))
343 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
344 else:
345 notunderstood=True
346 elif cmd=="quiet":
347 if auteur in self.ops:
348 if len(message)>1:
349 if message[1] in self.quiet_channels:
350 serv.privmsg(auteur,"Je me la ferme déjà sur %s"%(message[1]))
351 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
352 else:
353 self.quiet_channels.append(message[1])
354 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
355 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
356 else:
357 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
358 else:
359 notunderstood=True
360 elif cmd=="noquiet":
361 if auteur in self.ops:
362 if len(message)>1:
363 if message[1] in self.quiet_channels:
364 self.quiet_channels.remove(message[1])
365 serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
366 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
367 else:
368 serv.privmsg(auteur,"Je ne me la ferme pas sur %s."%(message[1]))
369 log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
370 else:
371 notunderstood=True
372 elif cmd in ["states","status"]:
373 if auteur in self.overops:
374 for k in self.play_status.keys():
375 serv.privmsg(auteur,(u"%s : %s"%(k,"; ".join([unicode(i) for i in self.play_status[k]]))).encode("utf8") )
376 elif cmd=="say":
377 if auteur in self.overops and len(message)>2:
378 serv.privmsg(message[1]," ".join(message[2:]))
379 log(self.serveur,"priv",auteur," ".join(message))
380 elif len(message)<=2:
381 serv.privmsg(auteur,"Syntaxe : SAY <channel> <message>")
382 else:
383 notunderstood=True
384 elif cmd=="die":
385 if auteur in self.overops:
386 log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
387 self.mourir()
388 elif cmd=="score":
389 if len(message)>1:
390 if len(message) in [3,4] and message[1].lower()=="transfert":
391 scores=self.get_scores()
392 de,to=auteur,message[2]
393 value=scores.get(de,0)
394 if len(message)==4:
395 try:
396 asked=int(message[3])
397 except ValueError:
398 serv.privmsg(auteur,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
399 return
400 else:
401 asked=value
402 if value==0:
403 serv.privmsg(auteur,"Vous n'avez pas de points")
404 return
405 elif asked<=0:
406 serv.privmsg(auteur,"Bien tenté…")
407 return
408 elif asked>value:
409 serv.privmsg(auteur,"Vous n'avez que %s points"%(value))
410 return
411 else:
412 self.add_score(de,-asked)
413 self.add_score(to,asked)
414 serv.privmsg(auteur,"Transfert de %s points de %s à %s"%(asked,de,to))
415 else:
416 serv.privmsg(auteur,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
417 else:
418 serv.privmsg(auteur,"Votre score : %s"%(self.get_scores().get(auteur,0)) )
419 elif cmd=="scores":
420 if len(message)==1:
421 scores=self.get_scores().items()
422 # trie par score
423 scores.sort(lambda x,y:cmp(x[1],y[1]))
424 scores.reverse()
425 serv.privmsg(auteur,"Scores by score : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
426 # trie par pseudo
427 scores.sort(lambda x,y:cmp(x[0].lower(),y[0].lower()))
428 serv.privmsg(auteur,"Scores by pseudo : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
429 elif auteur in self.overops:
430 souscmd=message[1].lower()
431 if souscmd=="del":
432 if len(message)==3:
433 todelete=message[2]
434 scores=self.get_scores()
435 if scores.has_key(todelete):
436 del scores[todelete]
437 self.save_scores(scores)
438 serv.privmsg(auteur,"Score de %s supprimé"%(todelete))
439 else:
440 serv.privmsg(auteur,"Ce score n'existe pas : %s"%(todelete))
441 else:
442 serv.privmsg(auteur,"Syntaxe : SCORES DEL <pseudo>")
443 elif souscmd in ["add","sub"]:
444 if len(message)==4:
445 toadd,val=message[2],message[3]
446 try:
447 val=int(val)
448 except ValueError:
449 serv.privmsg(auteur,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
450 return
451 if souscmd=="sub":
452 val=-val
453 self.add_score(toadd,val)
454 serv.privmsg(auteur,"Done")
455 else:
456 serv.privmsg(auteur,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
457 else:
458 serv.privmsg(auteur,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
459 else:
460 notunderstood=True
461 else:
462 notunderstood=True
463 if notunderstood:
464 serv.privmsg(auteur,"Je n'ai pas compris. Essaye HELP…")
465
466 def on_pubmsg(self, serv, ev):
467 auteur = irclib.nm_to_n(ev.source())
468 canal = ev.target()
469 message = ev.arguments()[0]
470 self.update_activity(canal,auteur)
471 try:
472 test=bot_unicode(message)
473 except UnicodeBotError:
474 if not canal in self.quiet_channels:
475 serv.privmsg(canal,
476 "%s: Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…"%(auteur))
477 return
478 tryother=False
479 pour_moi,message=self.pourmoi(serv,message)
480 if pour_moi and message.split()!=[]:
481 cmd=message.split()[0].lower()
482 try:
483 args=" ".join(message.split()[1:])
484 except:
485 args=""
486 if cmd in ["meurs","die","crève"]:
487 if auteur in self.overops:
488 self.mourir()
489 log(self.serveur,canal,auteur,message+"[successful]")
490 else:
491 serv.privmsg(canal,"%s: crève !"%(auteur))
492 log(self.serveur,canal,auteur,message+"[failed]")
493 if cmd in ["meur", "meurt","meurre","meurres"] and not canal in self.quiet_channels:
494 serv.privmsg(canal,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
495 if cmd in ["part","leave","dégage"]:
496 if auteur in self.ops and (not (canal in self.stay_channels)
497 or auteur in self.overops):
498 self.quitter(canal)
499 log(self.serveur,canal,auteur,message+"[successful]")
500 self.chanlist.remove(canal)
501 else:
502 serv.privmsg(canal,"%s: Non, je reste !"%(auteur))
503 log(self.serveur,canal,auteur,message+"[failed]")
504
505 if cmd in ["deviens","pseudo"]:
506 if auteur in self.ops:
507 become=args
508 serv.nick(become)
509 log(self.serveur,canal,auteur,message+"[successful]")
510 if cmd in ["coucou"] and not canal in self.quiet_channels:
511 serv.privmsg(canal,"%s: coucou"%(auteur))
512 if cmd in ["ping"] and not canal in self.quiet_channels:
513 serv.privmsg(canal,"%s: pong"%(auteur))
514 if cmd in ["déconnaissance","deconnaissance","énigme","enigme","encore"]:
515 if canal in self.play_channels:
516 if self.play_status.get(canal,[-1])[0]==0:
517 try:
518 self.start_enigme(serv,canal)
519 except RefuseError:
520 serv.privmsg(canal,"%s: Je peux souffler une minute ?"%(auteur))
521 else:
522 serv.privmsg(canal,("%s: Rappel : %s"%(auteur,self.play_status[canal][1])).encode("utf8") )
523 else:
524 serv.privmsg(canal,"%s: pas ici…"%(auteur))
525 if cmd in ["score","!score"]:
526 serv.privmsg(auteur,"Votre score : %s"%(self.get_scores().get(auteur,0)) )
527 if cmd in ["scores","!scores"]:
528 scores=self.get_scores().items()
529 # trie par score
530 scores.sort(lambda x,y:cmp(x[1],y[1]))
531 scores.reverse()
532 serv.privmsg(auteur,"Scores by score : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
533 # trie par pseudo
534 scores.sort(lambda x,y:cmp(x[0].lower(),y[0].lower()))
535 serv.privmsg(auteur,"Scores by pseudo : "+" ; ".join(["%s %s"%(i[0],i[1]) for i in scores]))
536 if cmd=="indice" and canal in self.play_channels:
537 self.give_indice(serv,canal,None)
538 if is_tag(message) and not canal in self.quiet_channels:
539 if auteur in self.ops:
540 action=random.choice(config_tag_actions)
541 serv.action(canal,action.encode("utf8"))
542 self.quiet_channels.append(canal)
543 else:
544 answer=random.choice(config_tag_answers)
545 for ligne in answer.split("\n"):
546 serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
547 if "Bâille, cru aile ou orld" in message:
548 self.mourir(u"Un de mes easters eggs (non en fait j'en ai qu'un) a été découvert par %s !"%auteur)
549 else:
550 tryother=True
551 else:
552 tryother=True
553 if tryother:
554 if self.play_status.get(canal,[-1])[0] in [1,2]:
555 answer_regexp=self.play_status[canal][3]
556 answer=self.play_status[canal][4]
557 if reussi(message.decode("utf8"),answer,answer_regexp,auteur):
558 serv.privmsg(canal,(u"%s: bravo ! (C'était %s)"%(auteur,answer)).encode("utf8"))
559 log(self.serveur,canal,auteur+"$win",message)
560 self.add_score(auteur,1)
561 token=time.time()
562 self.play_status[canal]=[0,token]
563 serv.execute_delayed(random.randrange(Ttrig*5,Ttrig*10),self.start_enigme,(serv,canal,token))
564
565 def on_kick(self,serv,ev):
566 auteur = irclib.nm_to_n(ev.source())
567 channel = ev.target()
568 victime = ev.arguments()[0]
569 raison = ev.arguments()[1]
570 if victime==self.nick:
571 log(self.serveur,"%s kické de %s par %s (raison : %s)" %(victime,channel,auteur,raison))
572 time.sleep(5)
573 serv.join(channel)
574 self.update_activity(message[1],"")
575 # on ne dit rien au rejoin
576 #l1,l2=config_kick_answers,config_kick_actions
577 #n1,n2=len(l1),len(l2)
578 #i=random.randrange(n1+n2)
579 #if i>=n1:
580 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
581 #else:
582 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
583
584 def quitter(self,chan,leave_message=None):
585 if leave_message==None:
586 leave_message=random.choice(config_leave_messages)
587 self.serv.part(chan,message=leave_message.encode("utf8"))
588
589 def mourir(self,quit_message=None):
590 if quit_message==None:
591 quit_message=random.choice(config_quit_messages)
592 self.die(msg=quit_message.encode("utf8"))
593
594 def get_scores(self):
595 f=open(config_score_file)
596 scores=pickle.load(f)
597 f.close()
598 return scores
599
600 def add_score(self,pseudo,value):
601 scores=self.get_scores()
602 if scores.has_key(pseudo):
603 scores[pseudo]+=value
604 else:
605 scores[pseudo]=value
606 self.save_scores(scores)
607
608 def save_scores(self,scores):
609 f=open(config_score_file,"w")
610 pickle.dump(scores,f)
611 f.close()
612
613 def _getnick(self):
614 return self.serv.get_nickname()
615 nick = property(_getnick)
616
617 def update_activity(self,canal,pseudo):
618 if not pseudo in config_idle_bots:
619 self.last_activity[canal]=time.time()
620 def is_active(self,canal):
621 return time.time()-self.last_activity[canal]<config_idle_time
622
623 if __name__=="__main__":
624 import sys
625 if len(sys.argv)==1:
626 print "Usage : deconnaisseur.py <serveur> [--debug]"
627 exit(1)
628 serveur=sys.argv[1]
629 if "debug" in sys.argv or "--debug" in sys.argv:
630 debug=True
631 else:
632 debug=False
633 serveurs={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
634 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
635 try:
636 serveur=serveurs[serveur]
637 except KeyError:
638 print "Server Unknown : %s"%(serveur)
639 exit(404)
640 deco=Deconnaisseur(serveur,debug)
641 deco.start()