4 # Codé par 20-100 le 23/04/12
6 # Un bot IRC qui sort des déconnaissances
15 from remplace_accents
import remplace_accents
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"]
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
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
35 config_score_file
="scores.pickle"
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 :°",
42 u
"Non, j'ai pas envie",
43 u
"Peut-être quand toi tu la fermeras, et encore…"]
46 config_level3
=["[20-100]","Petite-Peste","PEB"]
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
])
54 config_quit_messages
=[u
"Se décrocher la mâchoire, pas cuit bras d'oiseau ou métalld précieuxld"]
56 config_leave_messages
=[u
"On continuera à jouer plus tard ;)"]
58 class UnicodeBotError(Exception):
60 def bot_unicode(chain
):
63 except UnicodeDecodeError:
66 def log(serveur
,channel
,auteur
=None,message
=None):
67 f
=open(get_config_logfile(serveur
),"a")
68 if auteur
==message
==None:
69 # alors c'est que c'est pas un channel mais juste une ligne de log
70 chain
="%s %s"%(time
.strftime("%F %T"),channel
)
72 chain
="%s [%s:%s] %s"%(time
.strftime("%F %T"),channel
,auteur
,message
)
74 if config_debug_stdout
:
79 def reussi(message
,answer
,answer_regexp
,auteur
):
80 if auteur
in config_level3
:
81 return answer
in message
82 if auteur
in config_level2
:
83 return remplace_accents(answer
) in message
85 if re
.match(remplace_accents(answer_regexp
).lower(),remplace_accents(message
).lower()):
88 def is_something(chain
,matches
,avant
=u
".*(?:^| )",apres
=u
"(?:$|\.| |,|;).*",case_sensitive
=False,debug
=False):
90 chain
=unicode(chain
,"utf8")
92 chain
=unicode(chain
,"utf8").lower()
93 allmatches
="("+"|".join(matches
)+")"
94 reg
=(avant
+allmatches
+apres
).lower()
99 return is_something(chain
,config_tag_triggers
)
101 class RefuseError(Exception):
104 class Deconnaisseur(ircbot
.SingleServerIRCBot
):
105 def __init__(self
,serveur
,debug
=False):
106 temporary_pseudo
=config_pseudo
+str(random
.randrange(10000,100000))
107 ircbot
.SingleServerIRCBot
.__init
__(self
, [(serveur
, 6667)],
108 temporary_pseudo
,"Un bot irc.[flagellez 20-100, il le mérite]", 10)
111 self
.overops
=config_overops
112 self
.ops
=self
.overops
+config_ops
113 self
.chanlist
=config_chanlist
114 self
.stay_channels
=config_stay_channels
115 self
.play_channels
=config_play_channels
116 self
.play_status
={i
:[0] for i
in self
.play_channels
}
117 self
.quiet_channels
=[]
119 def give_me_my_pseudo(self
,serv
):
120 serv
.privmsg("NickServ","RECOVER %s %s"%(config_pseudo
,config_password
))
121 serv
.privmsg("NickServ","RELEASE %s %s"%(config_pseudo
,config_password
))
123 serv
.nick(config_pseudo
)
125 def on_welcome(self
, serv
, ev
):
126 self
.serv
=serv
# ça serv ira :)
127 self
.give_me_my_pseudo(serv
)
128 serv
.privmsg("NickServ","identify %s"%(config_password))
129 log(self
.serveur
,"Connected")
131 self
.chanlist
=["#bot"]
132 self
.play_channels
=["#bot"]
133 for c
in self
.chanlist
:
134 log(self
.serveur
,"JOIN %s"%(c))
136 for c
in self
.play_channels
:
137 token
=time
.time()-3600
138 self
.play_status
[c
]=[0,token
]
139 serv
.execute_delayed(random
.randrange(ttrig
),self
.start_enigme
,(serv
,c
,token
))
141 def start_enigme(self
,serv
,channel
,token
=None):
142 if self
.play_status
[channel
][0]==0 and channel
in self
.play_channels
:
144 if token
==self
.play_status
[channel
][-1]:
147 if time
.time() > self
.play_status
[channel
][-1]+config_time_incompressible
:
152 enigme
,indice
,answer_reg
,answer
=self
.get_enigme()
153 log(self
.serveur
,channel
,u
"$Énigme$".encode("utf8"),("%s; %s; %s; %s"%(enigme
, indice
, answer_reg
, answer
)).encode("utf8"))
154 serv
.privmsg(channel
,enigme
.encode("utf8"))
156 self
.play_status
[channel
]=[1,enigme
,indice
,answer_reg
,answer
,token
]
157 serv
.execute_delayed(random
.randrange(ttrig
*3,ttrig
*5),self
.give_indice
,(serv
,channel
,token
))
160 def give_indice(self
,serv
,channel
,token
):
161 if self
.play_status
[channel
][0]==1:
163 # c'est donc que l'indice a été demandé
164 if self
.play_status
[channel
][-1]+config_time_incompressible_clue
<time
.time():
165 token
=self
.play_status
[channel
][-1]
166 if self
.play_status
[channel
][-1]==token
:
167 indice
=self
.play_status
[channel
][2]
168 serv
.privmsg(channel
,"indice : %s"%(indice).encode("utf8"))
169 self
.play_status
[channel
][0]=2
170 serv
.execute_delayed(random
.randrange(ttrig
*1,ttrig
*3),self
.give_answer
,(serv
,channel
,token
))
171 def give_answer(self
,serv
,channel
,token
):
172 if self
.play_status
[channel
][0]==2 and self
.play_status
[channel
][-1]==token
:
173 answer
=self
.play_status
[channel
][4]
174 serv
.privmsg(channel
,"C'était : %s"%(answer).encode("utf8"))
176 self
.play_status
[channel
]=[0,token
]
177 serv
.execute_delayed(random
.randrange(Ttrig
*5,Ttrig
*10),self
.start_enigme
,(serv
,channel
,token
))
179 def get_enigme(self
):
180 # on récupère les déconnaissances
181 f
=open(config_source_file
)
184 l
=re
.findall("%\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)\n",t
)
185 dec
={int(i
[0]):list(i
[1:]) for i
in l
if len(i
)==5}
186 # on va chercher combien de fois elles ont été jouées
187 played_file
=get_config_played_file(self
.serveur
)
191 l
=re
.findall("(.*):(.*)",t
)
192 played
={int(i
[0]):int(i
[1]) for i
in l
}
193 # on récupère le nombre d'occurrences le plus faible
194 mini
=min(played
.values())
195 # on choisit un id dans ceux qui ont ce nombre d'occurences
196 id_choisi
=random
.choice([k
for k
,v
in played
.items() if v
==mini
])
197 enigme
,indice
,answer_reg
,answer
=dec
[id_choisi
]
198 # on incrémente la choisie
200 # on enregistre le played_file
201 f
=open(played_file
,"w")
202 f
.write("\n".join(["%-3s : %s"%(k
,v
) for k
,v
in played
.items()]))
204 return enigme
.decode("utf8"),indice
.decode("utf8"),answer_reg
.decode("utf8"),answer
.decode("utf8")
206 def pourmoi(self
, serv
, message
):
209 if message
[:size
]==pseudo
and len(message
)>size
and message
[size
]==":":
210 return (True,message
[size
+1:].strip(" "))
212 return (False,message
)
214 def on_privmsg(self
, serv
, ev
):
215 message
=ev
.arguments()[0]
216 auteur
= irclib
.nm_to_n(ev
.source())
218 test
=bot_unicode(message
)
219 except UnicodeBotError
:
221 "Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…")
223 message
=message
.split()
224 cmd
=message
[0].lower()
227 helpmsg_default
="""Liste des commandes :
228 HELP Affiche ce message d'aide
229 SCORE Affiche ton score (SCORE TRANSFERT <pseudo> [<n>] pour transférer des points)
230 SCORES Affiche les scores"""
232 JOIN Faire rejoindre un channel (sans paramètres, donne la liste des chans actuels)
233 LEAVE Faire quitter un channel
234 PLAY Passe un channel en mode "jouer"
235 NOPLAY Passe un channel en mode "ne pas jouer"
236 QUIET Se taire sur un channel
237 NOQUIET Opposé de QUIET"""
239 SCORES {DEL|ADD|SUB} Tu veux un dessin ?
240 SAY Fais envoyer un message sur un chan ou à une personne
241 STAY Ignorera les prochains LEAVE pour un chan
242 NOSTAY Opposé de STAY
243 STATUS Montre l'état courant
245 helpmsg
=helpmsg_default
246 if auteur
in self
.ops
:
248 if auteur
in self
.overops
:
249 helpmsg
+=helpmsg_overops
250 for ligne
in helpmsg
.split("\n"):
251 serv
.privmsg(auteur
,ligne
)
253 if auteur
in self
.ops
:
255 if message
[1] in self
.chanlist
:
256 serv
.privmsg(auteur
,"Je suis déjà sur %s"%(message
[1]))
258 serv
.join(message
[1])
259 self
.chanlist
.append(message
[1])
260 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
261 log(self
.serveur
,"priv",auteur
," ".join(message
))
263 serv
.privmsg(auteur
,"Channels : "+" ".join(self
.chanlist
))
267 if auteur
in self
.ops
and len(message
)>1:
268 if message
[1] in self
.chanlist
:
269 if not (message
[1] in self
.stay_channels
) or auteur
in self
.overops
:
270 self
.quitter(message
[1]," ".join(message
[2:]))
271 self
.chanlist
.remove(message
[1])
272 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
274 serv
.privmsg(auteur
,"Non, je reste !")
275 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
277 serv
.privmsg(auteur
,"Je ne suis pas sur %s"%(message
[1]))
281 if auteur
in self
.overops
:
283 if message
[1] in self
.stay_channels
:
284 serv
.privmsg(auteur
,"Je stay déjà sur %s."%(message
[1]))
285 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
287 self
.stay_channels
.append(message
[1])
288 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
289 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
291 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
295 if auteur
in self
.overops
:
297 if message
[1] in self
.stay_channels
:
298 self
.stay_channels
.remove(message
[1])
299 serv
.privmsg(auteur
,"Stay channels : "+" ".join(self
.stay_channels
))
300 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
302 serv
.privmsg(auteur
,"Je ne stay pas sur %s."%(message
[1]))
303 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
307 if auteur
in self
.ops
:
309 if message
[1] in self
.play_channels
:
310 serv
.privmsg(auteur
,"Je play déjà sur %s."%(message
[1]))
311 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
313 self
.play_channels
.append(message
[1])
314 self
.play_status
[message
[1]]=[0,time
.time()-3600]
315 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
316 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
318 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
322 if auteur
in self
.ops
:
324 if message
[1] in self
.play_channels
:
325 self
.play_channels
.remove(message
[1])
326 serv
.privmsg(auteur
,"Play channels : "+" ".join(self
.play_channels
))
327 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
329 serv
.privmsg(auteur
,"Je ne play pas sur %s."%(message
[1]))
330 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
334 if auteur
in self
.ops
:
336 if message
[1] in self
.quiet_channels
:
337 serv
.privmsg(auteur
,"Je me la ferme déjà sur %s"%(message
[1]))
338 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
340 self
.quiet_channels
.append(message
[1])
341 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
342 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
344 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
348 if auteur
in self
.ops
:
350 if message
[1] in self
.quiet_channels
:
351 self
.quiet_channels
.remove(message
[1])
352 serv
.privmsg(auteur
,"Quiet channels : "+" ".join(self
.quiet_channels
))
353 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
355 serv
.privmsg(auteur
,"Je ne me la ferme pas sur %s."%(message
[1]))
356 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[failed]")
359 elif cmd
in ["states","status"]:
360 if auteur
in self
.overops
:
361 for k
in self
.play_status
.keys():
362 serv
.privmsg(auteur
,(u
"%s : %s"%(k
,"; ".join([unicode(i
) for i
in self
.play_status
[k
]]))).encode("utf8") )
364 if auteur
in self
.overops
and len(message
)>2:
365 serv
.privmsg(message
[1]," ".join(message
[2:]))
366 log(self
.serveur
,"priv",auteur
," ".join(message
))
367 elif len(message
)<=2:
368 serv
.privmsg(auteur
,"Syntaxe : SAY <channel> <message>")
372 if auteur
in self
.overops
:
373 log(self
.serveur
,"priv",auteur
," ".join(message
)+"[successful]")
377 if len(message
) in [3,4] and message
[1].lower()=="transfert":
378 scores
=self
.get_scores()
379 de
,to
=auteur
,message
[2]
380 value
=scores
.get(de
,0)
383 asked
=int(message
[3])
385 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
390 serv
.privmsg(auteur
,"Vous n'avez pas de points")
393 serv
.privmsg(auteur
,"Bien tenté…")
396 serv
.privmsg(auteur
,"Vous n'avez que %s points"%(value))
399 self
.add_score(de
,-asked
)
400 self
.add_score(to
,asked
)
401 serv
.privmsg(auteur
,"Transfert de %s points de %s à %s"%(asked
,de
,to
))
403 serv
.privmsg(auteur
,"Syntaxe : SCORE TRANSFERT <pseudo> [<n>]")
405 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
408 scores
=self
.get_scores().items()
410 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
412 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
414 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
415 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
416 elif auteur
in self
.overops
:
417 souscmd
=message
[1].lower()
421 scores
=self
.get_scores()
422 if scores
.has_key(todelete
):
424 self
.save_scores(scores
)
425 serv
.privmsg(auteur
,"Score de %s supprimé"%(todelete))
427 serv
.privmsg(auteur
,"Ce score n'existe pas : %s"%(todelete))
429 serv
.privmsg(auteur
,"Syntaxe : SCORES DEL <pseudo>")
430 elif souscmd
in ["add","sub"]:
432 toadd
,val
=message
[2],message
[3]
436 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
440 self
.add_score(toadd
,val
)
441 serv
.privmsg(auteur
,"Done")
443 serv
.privmsg(auteur
,"Syntaxe : SCORES {ADD|SUB} <pseudo> <n>")
445 serv
.privmsg(auteur
,"Syntaxe : SCORES {DEL|ADD|SUB} <pseudo> [<n>]")
451 serv
.privmsg(auteur
,"Je n'ai pas compris. Essaye HELP…")
453 def on_pubmsg(self
, serv
, ev
):
454 auteur
= irclib
.nm_to_n(ev
.source())
456 message
= ev
.arguments()[0]
458 test
=bot_unicode(message
)
459 except UnicodeBotError
:
460 if not canal
in self
.quiet_channels
:
462 "%s: Euh, tu fais de la merde avec ton encodage là, j'ai failli crasher…"%(auteur))
465 pour_moi
,message
=self
.pourmoi(serv
,message
)
466 if pour_moi
and message
.split()!=[]:
467 cmd
=message
.split()[0].lower()
469 args
=" ".join(message
.split()[1:])
472 if cmd
in ["meurs","die","crève"]:
473 if auteur
in self
.overops
:
475 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
477 serv
.privmsg(canal
,"%s: crève !"%(auteur))
478 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
479 if cmd
in ["meur", "meurt","meurre","meurres"] and not canal
in self
.quiet_channels
:
480 serv
.privmsg(canal
,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
481 if cmd
in ["part","leave","dégage"]:
482 if auteur
in self
.ops
and (not (canal
in self
.stay_channels
)
483 or auteur
in self
.overops
):
485 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
486 self
.chanlist
.remove(canal
)
488 serv
.privmsg(canal
,"%s: Non, je reste !"%(auteur))
489 log(self
.serveur
,canal
,auteur
,message
+"[failed]")
491 if cmd
in ["deviens","pseudo"]:
492 if auteur
in self
.ops
:
495 log(self
.serveur
,canal
,auteur
,message
+"[successful]")
496 if cmd
in ["coucou"] and not canal
in self
.quiet_channels
:
497 serv
.privmsg(canal
,"%s: coucou"%(auteur))
498 if cmd
in ["ping"] and not canal
in self
.quiet_channels
:
499 serv
.privmsg(canal
,"%s: pong"%(auteur))
500 if cmd
in ["déconnaissance","deconnaissance","énigme","enigme","encore"]:
501 if canal
in self
.play_channels
:
502 if self
.play_status
.get(canal
,[-1])[0]==0:
504 self
.start_enigme(serv
,canal
)
506 serv
.privmsg(canal
,"%s: Je peux souffler une minute ?"%(auteur))
508 serv
.privmsg(canal
,("%s: Rappel : %s"%(auteur
,self
.play_status
[canal
][1])).encode("utf8") )
510 serv
.privmsg(canal
,"%s: pas ici…"%(auteur))
511 if cmd
in ["score","!score"]:
512 serv
.privmsg(auteur
,"Votre score : %s"%(self
.get_scores().get(auteur
,0)) )
513 if cmd
in ["scores","!scores"]:
514 scores
=self
.get_scores().items()
516 scores
.sort(lambda x
,y
:cmp(x
[1],y
[1]))
518 serv
.privmsg(auteur
,"Scores by score : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
520 scores
.sort(lambda x
,y
:cmp(x
[0].lower(),y
[0].lower()))
521 serv
.privmsg(auteur
,"Scores by pseudo : "+" ; ".join(["%s %s"%(i
[0],i
[1]) for i
in scores
]))
522 if cmd
=="indice" and canal
in self
.play_channels
:
523 self
.give_indice(serv
,canal
,None)
524 if is_tag(message
) and not canal
in self
.quiet_channels
:
525 if auteur
in self
.ops
:
526 action
=random
.choice(config_tag_actions
)
527 serv
.action(canal
,action
.encode("utf8"))
528 self
.quiet_channels
.append(canal
)
530 answer
=random
.choice(config_tag_answers
)
531 for ligne
in answer
.split("\n"):
532 serv
.privmsg(canal
,"%s: %s"%(auteur
,ligne
.encode("utf8")))
538 if self
.play_status
.get(canal
,[-1])[0] in [1,2]:
539 answer_regexp
=self
.play_status
[canal
][3]
540 answer
=self
.play_status
[canal
][4]
541 if reussi(message
.decode("utf8"),answer
,answer_regexp
,auteur
):
542 serv
.privmsg(canal
,(u
"%s: bravo ! (C'était %s)"%(auteur
,answer
)).encode("utf8"))
543 log(self
.serveur
,canal
,auteur
+"$win",message
)
544 self
.add_score(auteur
,1)
546 self
.play_status
[canal
]=[0,token
]
547 serv
.execute_delayed(random
.randrange(Ttrig
*5,Ttrig
*10),self
.start_enigme
,(serv
,canal
,token
))
549 def on_kick(self
,serv
,ev
):
550 auteur
= irclib
.nm_to_n(ev
.source())
551 channel
= ev
.target()
552 victime
= ev
.arguments()[0]
553 raison
= ev
.arguments()[1]
554 if victime
==self
.nick
:
555 log(self
.serveur
,"%s kické par %s (raison : %s)" %(victime
,auteur
,raison
))
558 # on ne dit rien au rejoin
559 #l1,l2=config_kick_answers,config_kick_actions
560 #n1,n2=len(l1),len(l2)
561 #i=random.randrange(n1+n2)
563 # serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
565 # serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
567 def quitter(self
,chan
,leave_message
=None):
568 if leave_message
==None:
569 leave_message
=random
.choice(config_leave_messages
)
570 self
.serv
.part(chan
,message
=leave_message
.encode("utf8"))
573 quit_message
=random
.choice(config_quit_messages
)
574 self
.die(msg
=quit_message
.encode("utf8"))
576 def get_scores(self
):
577 f
=open(config_score_file
)
578 scores
=pickle
.load(f
)
582 def add_score(self
,pseudo
,value
):
583 scores
=self
.get_scores()
584 if scores
.has_key(pseudo
):
585 scores
[pseudo
]+=value
588 self
.save_scores(scores
)
590 def save_scores(self
,scores
):
591 f
=open(config_score_file
,"w")
592 pickle
.dump(scores
,f
)
596 return self
.serv
.get_nickname()
597 nick
= property(_getnick
)
599 if __name__
=="__main__":
602 print "Usage : deconnaisseur.py <serveur> [--debug]"
605 if "debug" in sys
.argv
or "--debug" in sys
.argv
:
609 serveurs
={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
610 "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
612 serveur
=serveurs
[serveur
]
614 print "Server Unknown : %s"%(serveur)
616 deco
=Deconnaisseur(serveur
,debug
)