[Otfbot-svn] r482 - contrib

allo at BerliOS allo
Sa Nov 1 20:13:58 CET 2008


Author: allo
Date: 2008-11-01 20:13:57 +0100 (Sat, 01 Nov 2008)
New Revision: 482

Added:
   contrib/nobodyisperfectMod.yaml
Modified:
   contrib/nobodyisperfectMod.py
Log:
update from neTear (untested)


Modified: contrib/nobodyisperfectMod.py
===================================================================
--- contrib/nobodyisperfectMod.py	2008-10-29 19:51:50 UTC (rev 481)
+++ contrib/nobodyisperfectMod.py	2008-11-01 19:13:57 UTC (rev 482)
@@ -18,26 +18,18 @@
 #Thanks to "Wete" "p_kater" and "stetie" for the very good ideas and testing this game, and of course 
 #"allo" and "cato" (for the nice basement at least)
 #Let's make this game famous :)
-#Note: Still under construction
 #*/
-#actual Gameflow -> !startgame > join|add with "ich" > !startgame > Round1 > !restart >Roundbar |>!end/abort <>!vote end[e]/abort
-#Everything should work automatically except !restartgame, well after the gameadmin has been "removed", if he does not restart the game,
-#the game will pause as long as another player will do ![re]startgame(or !end/abort). The removed gameadmin might !join/add immediately without being the new gameadmin.
-#game modified and "prettyfied" by neTear 12/2007 01/2008 with Midnight Commander/Kate, just because python 'sucks'...
-#Addition: saving the scoretable when game "ends" - for better HoF statistics in future
-#Addition: Timeout Warnings to players without action during QUIZ and WAITING_FOR_ANSWERS "Schnarchnasenorden" - this one is configurable, too ;)
-#Addition: Class Favorits will give sorted list (by points) for output
-#Bugfix and Addition: Max. Nick Len. Players nickname longer than maxnicklen cannot (be) join(ed)/add(ed)
-#Todos: track .task errors, maybe the pointer gets lost when stopping timer?
+#game modified and "prettyfied" by neTear 2008
 # -*- coding: utf-8 -*- 
 import shutil, time, random, string, os
 import chatMod
 import twisted.internet.task as timehook
-import math #just used for voting, needed for "rounding", try another solution...
+import math #just used for voting, "rounding"
 import pickle
 import atexit
 import operator as favop
-HELPUSER="#CCHAR#join #CCHAR#part (mitspielen/aussteigen) #CCHAR#score #CCHAR#rules #CCHAR#+players"
+import sys
+HELPUSER="#CCHAR#join #CCHAR#part (mitspielen/aussteigen) #CCHAR#score #CCHAR#rules #CCHAR#players"
 HELPADMIN="#CCHAR#abortgame #CCHAR#restartgame #CCHAR#add/remove Mitspieler #CCHAR#gamespeed #CCHAR#autoremove #CCHAR#kill "
 HELPBUG="Genervte #BOLD#irssi#BOLD#-Anwender moegen ein \"/set mirc_blink_fix on\" machen, oder x-chat,chatzilla,mIRC oder Telnet... benutzen ;)"
 
@@ -50,60 +42,35 @@
 QUIZ=5
 GAME_WAITING=6
 
+path_data="data" #fix this
+path_archiv="archiv"
+favdata="NIPfav.data"
+hofdata="NIPhalloffame.data"
+nipbuffer="NIPbuffer.data"
+scoredata="NIPScore.data"
+
 class chatMod(chatMod.chatMod):
 	
 	def __init__(self, bot):
 		self.bot=bot
+		self.nipdatadir=path_data+"/nobodyisperfectMod/" #fixme 
+		self.check_data_dirs()
 		atexit.register(self.nipexithook)
-		self.kcs_=self.fp_handler()
 		self.fav=self.favorits()
 		self.NIPbuffer=self.NIPqb()
 		self.default_nip()
 		self.nip_init()
 		self.init_vars()
-		self.fav.load(self.nipdatadir+self.favfile)
+		self.fav.load(self.nipdatadir+favdata)
 		self.fav.sort() #sorting all entries
+#if (not os.path.isdir(os.path.dirname(self.nipdatadir+path_archiv))):
+#os.makedirs(os.path.dirname(self.nipdatadir+path_archiv))
+	def check_data_dirs(self):
+		if (not os.path.isdir(self.nipdatadir)):
+			os.makedirs(os.path.dirname(self.nipdatadir))
+		if (not os.path.isdir(os.path.dirname(self.nipdatadir+path_archiv+"/archiv"))):
+			os.makedirs(os.path.dirname(self.nipdatadir+path_archiv+"/archiv"))
 
-	class fp_handler():#
-		def __init__(self):
-			self.name = []
-			self.fp_time = [] #default/config
-			self.user = [] #list in list ....
-			#self.channel = [] #
-			self.fp_ts = []
-			
-		def cmd_index(self, cmd):
-			if cmd in self.name:
-				for i in range(len(self.name)):
-					if self.name[i]==cmd:
-						return i
-			else:
-				return False
-		def delUser(self, cmd, user=None):
-			if not type(cmd)==int:
-				i=self.cmd_index(cmd)
-			else:
-				i=int(cmd)
-			if user==None:
-				self.user[i]=[]
-			else:
-				if user in self.user[cmd]:
-					self.user[i].remove(user)
-				else:
-					if user in self.user[i]:
-						self.user[i].remove(user)
-		def addUser(self, cmd, user):
-			if type(cmd)==int: #different kind of overloading oO
-				if not user in self.user[cmd]:
-					self.user[int(cmd)].append(user)
-			else:
-				i=self.cmd_index(cmd)
-				if not user in self.user[i]:
-					self.user[i].append(user)
-		def release(self,cmd):#for special purposes
-			self.fp_ts[self.cmd_index(cmd)]=int(time.time())
-
-
 	class favorits():
 		def __init__(self):
 			self.player = {}
@@ -137,8 +104,8 @@
 					sfile=open(favfile, "w")
 					pickle.dump(self.player,sfile)
 					sfile.close()
-				except IOError:
-					print "Error writing to file "+favfile
+				except:
+					print str(sys.exc_info()[1])
 				finally:
 					sfile.close()
 		def load(self, favfile):
@@ -146,10 +113,11 @@
 					lfile=open(favfile, "r")
 					self.player=pickle.load(lfile)
 					lfile.close()
-				except IOError:
-					print "Error reading file "+favfile
+				except:
+					print str(sys.exc_info()[1])
 				finally:
 					pass
+				
 		def sort(self, player=None):
 				try:
 					if not player:
@@ -158,7 +126,7 @@
 					else:
 						self.player[player]=sorted(self.getlist(player), key=favop.itemgetter(1), reverse=True)
 				except:
-					print "Error while sorting Favorites"
+					print str(sys.exc_info()[1])
 					pass
 
 	class NIPqb():
@@ -177,13 +145,23 @@
 				self.answer[user]=options
 			elif cmd=="t":
 				self.tip[user]=options
+
+		def replace_user(self, oldname, newname):
+			oldvals=self.get(oldname)
+			#print oldvals
+			self.clean(oldname)
+			self.question[newname]=oldvals[0]
+			self.answer[newname]=oldvals[1]
+			self.tip[newname]=oldvals[2]
+			
 		def clean(self, user):
 			self.question[user]=""
 			self.answer[user]=""
 			self.tip[user]=""
-		def save(self, nipbufferfile): #pickle is broken with unicode (since 2000???)
+			
+		def save(self, bufferfile): #pickle is broken with unicode (since 2000???)
 			try:
-				sfile=open(nipbufferfile+".dat", "w")
+				sfile=open(bufferfile,  "w")
 				for player in self.question:
 					player=str(player)
 					if self.question.has_key(player) and self.answer.has_key(player):
@@ -193,12 +171,14 @@
 						sfile.write(player+"#"+str(self.question[player])+"#"+str(self.answer[player])+"#"+tip+"\n")
 				sfile.close()
 			except:
-				self.bot.logger.error("while saving NIPbuffer")
+				print (" Error while saving NIPbuffer "+bufferfile)
+				print str(sys.exc_info()[1])
 			finally:
 				sfile.close()
-		def load(self, nipbufferfile):
+				
+		def load(self, bufferfile):
 			try:
-				lfile=open(nipbufferfile+".dat", "r")
+				lfile=open(bufferfile, "r")
 				qbdata=lfile.read()
 				lfile.close()
 				for line in qbdata.split("\n"):
@@ -208,23 +188,24 @@
 						self.answer[ls[0]]=ls[2]
 						self.tip[ls[0]]=ls[3]
 			except:
+				print str(sys.exc_info()[1])
 				pass
 
 
 	def nipexithook(self):
-		self.NIPbuffer.save(self.nipdatadir+"NIPbuffer")
+		self.NIPbuffer.save(self.nipdatadir+nipbuffer)
 		if not self.phase==NO_GAME:
-			self.nip_hof_update(self.nipdatadir+self.hofdatafile)
+			self.nip_hof_update(self.nipdatadir+hofdata)
 		self.save_score(True)
-		self.fav.save(self.nipdatadir+self.favfile)
+		self.fav.save(self.nipdatadir+favdata)
 		pass
 	
 	
 	def nip_init(self):
 		self.gamechannel="" #this is not multichannel compatible! # now it is (more|less) ;)
 		self.data_update_needed=False
-		self.init_autocmd()
-		self.kcs_update(self.kcs_config)
+		#self.init_autocmd()
+		#self.kcs_update(self.kcs_config)
 		self.allscore={}
 		self.load_score()
 		self.nT_init() #init the looptimer with polltime (used for different timeout)
@@ -241,75 +222,54 @@
 		#todo make const and or config ^^^ (xml sucks for config?)
 		self.uservoted_end=[]
 		self.votedEnd=0
+		self.scoreEnd=0
 		self.newplayers=[] #used as buffer for joining during game round 
 		self.hof=[]
-		self.hof=self.nip_hof(self.nipdatadir+self.hofdatafile,"read") #
-		self.NIPbuffer.load(self.nipdatadir+"NIPbuffer")
+		self.hof=self.nip_hof(self.nipdatadir+hofdata,"read") #
+		self.NIPbuffer.load(self.nipdatadir+nipbuffer)
 		#################
 		
 	def default_nip(self):
-		#first using global vars, try to make them local when everything works
-		#the best would be to make a function for all outputs.... nip_sendmsg,- guess, this game as being opensource will become famous
 		self.NIPencoding=self.bot.getConfig("encoding","UTF-8")
-		self.cchar=self.bot.getConfig("cchar", "!", "NIP")
-		self.nipdatadir=self.bot.getConfig("datadir", "modules/nip-data/", "NIP") #Need to get os? Not for scrappy windows anymore
-		self.hofdatafile=self.bot.getConfig("HoFdata", "niphof.txt", "NIP")
-		self.favfile=str(self.bot.getConfig("FavoritData", "fav.data", "NIP")) #todo better parsing		
-		self.channels=self.bot.getConfig("channels", "#otf-quiz  #nobody-is-perfect", "NIP").split() #all channels where NIPmod will throw messages from and allow to start a game
+		self.cchar=self.bot.getConfig("commandChar", "", "main")
+		if self.cchar == "":
+			self.cchar="!"
+		#self.nipdatadir=self.bot.getConfig("datadir", "data/nobodyisperfectMod/", "NIP")
+		#self.hofdatafile=self.bot.getConfig("HoFdata", "niphof.txt", "NIP")
+		#self.channels=self.bot.getConfig("channels", "#otf-quiz  #nobody-is-perfect", "NIP").split() #all channels where NIPmod will throw messages from and allow to start a game
 		self.minplayers=int(self.bot.getConfig("minPlayer", "5", "NIP"))
 		self.maxplayers=int(self.bot.getConfig("maxPlayer", "12", "NIP"))
-		self.fp_time=int(self.bot.getConfig("FPTime", "5", "NIP")) #default time for floodprotection
+		#self.fp_time=int(self.bot.getConfig("FPTime", "5", "NIP")) #default time for floodprotection
 		
-		self.kcs_config=str(self.bot.getConfig("FPSpecialCommands", "favorits 0,place 0,savegame 52,halloffame 12,place 0,vote 0,scores 12,abortgame 0,add 0,remove 0", "NIP")) #overwrite default fp_time, note: no whitespace after ",".
+		#self.kcs_config=str(self.bot.getConfig("FPSpecialCommands", "favorits 0,place 0,savegame 52,halloffame 12,place 0,vote 0,scores 12,abortgame 0,add 0,remove 0", "NIP")) #overwrite default fp_time, note: no whitespace after ",".
 		
 		self.maxnicklen=int(self.bot.getConfig("maxNickLength", "14", "NIP"))
-		self.userWarnMax=(int(self.bot.getConfig("AutoremovepPlayerKickAfterRounds", "2", "NIP"))) #better name?
+		self.scoreLimit=int(self.bot.getConfig("ScoreLimit", "0", "NIP"))
+		self.userWarnMax=(int(self.bot.getConfig("AutoremovePlayerAfterRounds", "2", "NIP")))
 		self.init_timeouts(int(self.bot.getConfig("TimeOutBase", "60", "NIP"))) #see function
 		self.TGAMEADMIN=str(self.bot.getConfig("NameGameAdmin", "#BOLD#NIP-Admin#BOLD#", "NIP"))
 		self.TGAMEMASTER=str(self.bot.getConfig("NameGameMaster", "#BOLD#QUIZ-Meister#BOLD#", "NIP"))
 		self.TNIPQUESTION=str(self.bot.getConfig("NameNipQuestion", "#BOLD##DBLUE#NIP-Frage#NORM#" ,"NIP"))
 		self.TNIPWARNINGS=str(self.bot.getConfig("NameNipWarnings", "Verteilung der#BOLD# #DRED#Schnarchnasenorden#NORM#:" ,"NIP"))
-		self.NIPRULES=str(self.bot.getConfig("RULES","http://otf-chat.xenim.de/wiki/bot:nobody-is-perfect" ,"NIP"))
+		#self.NIPRULES=str(self.bot.getConfig("RULES","http://otf-chat.xenim.de/wiki/games:nobody-is-perfect" ,"NIP"))
+		self.NIPRULES=str(self.bot.getConfig("RULES","Ask my admin to set the link to rules in my config" ,"NIP"))
+		self.Nobody=self.bot.getBoolConfig("Nobody", "true", "NIP") #Player NobodyX for probably missing answers
 		self.mirc_stuff_init()
-	
-	def kcs_update(self, cmdlist=None): #used to assign longer fp protection (or disable each) from config- update val in .kcs_
-		if cmdlist!=None:
-			for scmd in cmdlist.split(","):
-				scmds=scmd.split(" ",24)
-				try:
-					cmd=scmds[0]
-					val=int(scmds[1])
-					#assert type(val)==IntType or int?
-					cmdi=self.kcs_.cmd_index(cmd)
-					if cmdi:
-						self.kcs_.fp_time[cmdi]=val
-				except:
-					self.bot.logger.error("Config Error with FPSpecialCommands ")
 
-	def init_autocmd(self):
-		#knowncommands
-		#you have to make every command used in game a "knowncommand" while using "auto_command or Floodprotection".... even those for replace_command
-		self.kcs=["vote","halloffame","hof","place","splitpoints","abortgame","resetgame","end","add", "remove", "startgame", "restartgame", "kill", "scores", "ranking", "gamespeed", "autoremove", "stats","favorits","groupies","continue", "players","rules","status","niphelp","join","part","help","testing","netear","p_kater"]
-		self.kcs.sort()
-		i=0
-		for cmd in self.kcs: #Todo: use_ this in autocommand
-			self.kcs_.name.append(cmd)
-			self.kcs_.fp_time.append(int(self.fp_time))
-			self.kcs_.user.append([''])
-			self.kcs_.fp_ts.append(0)
 
-
 	def init_timeouts(self, timeOutBase):
-		TimeBase=60
+		self.TimeBase=60
 		if type(timeOutBase)==int:
-			if timeOutBase>30 and timeOutBase<420:
-				TimeBase=timeOutBase
+			if timeOutBase>19 and timeOutBase<1000:
+				self.TimeBase=timeOutBase
+				self.bot.setConfig("TimeOutBase", str(self.TimeBase), "NIP")
 			else:
-				self.bot.logger.error("TimeOutBase Config must not be smaller 30 or greater 420")
-				TimeBase=60
+				self.bot.logger.error("TimeOutBase Config must not be smaller 20 or greater 420")
+				self.TimeBase=60
 		else:
 			self.bot.logger.error("TimeOutBase Config has to be an integer")
-			TimeBase=60
+			self.TimeBase=60
+		TimeBase=self.TimeBase
 		self.timeouts={}#used in nTimerset
 		self.timeouts['ANSWER_TIME']=2*TimeBase
 		self.timeouts['QUIZ_TIME']=TimeBase-10   #60 time waiting for quiz answers, nTimerset will add foo seconds for each player
@@ -318,14 +278,15 @@
 		self.timeouts['STARTPHASE']=TimeBase*8 #Timeout after first !startgame - will call end_of_game (not end_of_quiz)
 		#we now use them as default base values, - !gamespeed will half all times
 		self.timeouts['GAMEADMINNOTIFY']=TimeBase #sends a "highlight" to a sleeping "gameadmin"
-		self.timeouts['GAMEADMINKICK']=TimeBase #kick the lazy gameadmin after notify, [re]starter|aborter will be the new one automatically
+		self.timeouts['GAMEADMINKICK']=TimeBase #"kick" the lazy gameadmin after notify, [re]starter|aborter will be the new one automatically
+		self.timeouts['ENDAFTERPAUSE']=TimeBase*60 #Game ends if paused and not restarted (last resort loop)
 		for name in self.timeouts.keys():
 			self.bot.logger.info(str(name)+" "+str(self.timeouts.get(name,""))+" sec")
 
 
 	def mirc_stuff_init(self):
 		self.NIPPREFIX="|\x0316,14NIP\x033\x0F" #nip gameplay pre output this - may be set to =""
-		#some (m)IRCstuff... I LOVE eyecandy! (but it must not disturb)
+		#some (m)IRCstuff
 		self.colors={}
 		self.colors["#BOLD#"]="\x02" #tooglelike 
 		self.colors["#NORM#"]="\x0F" #resetallMIRColorslike
@@ -378,6 +339,7 @@
 		self.roundofgame=1 #counter, used in game as info, maybe good for new statistic
 		self.eoq_cnt=0 #see end_of_quiz ~used for debugging #obsolete when everything works
 		self.votedEnd=0 #important to reset here...
+		self.scoreEnd=0 #used to end game after player reached scorelimit
 		self.userWarnCnt={} #used for autoremoving player after foo times giving no "quiz-answer"
 
 
@@ -440,19 +402,15 @@
 					cmsg = cmsg.replace(pre, val)
 			if cmsg.count("#CCHAR#"):
 				cmsg = cmsg.replace("#CCHAR#",str(self.cchar))
-			#self.bot.logger.debug("nipmsg to:"+str(cchannel)+"|"+cmsg)
 			self.bot.sendmsg(cchannel, str(self.NIPPREFIX)+cmsg, self.NIPencoding)
 	
 	
-        def nTimerhook(self):
+	def nTimerhook(self):
 		self.gl_ts-=self.polltime
-		if self.gl_ts <= 0:
-			if self.nTimer.running:
-				self.nTimer.stop() #stops twisted.internet.task.LoopingCall...., lost pointer?
-				self.bot.logger.debug("Timer stopped gl_ts="+str(self.gl_ts))
-			else: #stopped before, should fix runtime-race condition when game ends
-				self.bot.logger.debug("Timer stopped before. No hookaction in Phase="+str(self.phase)+" action="+self.hookaction)
-				return 0
+		if self.gl_ts < 0:
+			self.gl_ts=0
+		if self.gl_ts <= 0 and self.nTimerFlag:
+			self.nTimerFlag=False 
 			if self.hookaction=="end_of_quiz":
 				self.bot.logger.debug("hookaction->"+str(self.hookaction)+" Phase:"+str(self.phase))
 				self.hookaction="None"
@@ -474,24 +432,25 @@
 				self.kick_gameadmin()
 				if self.phase==WAITING_FOR_PLAYERS:
 					self.end_of_game()
-
-
+			
+			elif self.hookaction=="end_of_game":
+				self.bot.logger.debug("hookaction->"+str(self.hookaction)+" Phase:"+str(self.phase))
+				self.hookaction="None"
+				self.end_of_game()
+			
 		if (self.phase==QUIZ or self.phase==WAITING_FOR_ANSWERS or self.phase==WAITING_FOR_QUESTION) and not self.playerwarned:
 			if self.gl_ts <= self.warn_ts:
 				self.warn_players()
 				self.playerwarned=1
 		#Good place for debugging stuff at this point, but vvvverbose
 		#tstatus=str(self.nTimer.running)
-		#print "NIPdebug: Timer running:"+tstatus+" gl_ts=" +str(self.gl_ts)+"  Gamephase="+str(self.phase)+" hookaction="+str(self.hookaction)+" [NIL]"
+		#self.bot.logger.debug("ts="+str(self.gl_ts)+" phase="+str(self.phase)+" "+str(self.hookaction))
 		
 	def nT_init(self):
 		self.nTimer=timehook.LoopingCall(self.nTimerhook) #this is the workaround for callLater
 		self.bot.logger.debug("nTimer initialised")	
 
 	def nTimerset(self, REQ_TIME, REQ_ACTION):
-		#try:
-		if self.nTimer.running:
-			self.nTimer.stop()
 		#dynamically longer timeouts for some conditions (ircd thwarts game when playing with more players )
 		if type(REQ_TIME)==str:
 			REQ_TIME=int(self.timeouts.get(REQ_TIME, 60))
@@ -503,42 +462,10 @@
 		self.gl_ts=(REQ_TIME+addtime)/self.gamespeed
 		self.warn_ts=self.gl_ts / 3 #used for warning players for timeout "Schnarnasenorden" oO
 		self.playerwarned=0 #bool to avoid multiple "Schnarchnasenorden"
+		self.bot.logger.debug("Setting Timer: polltime=" +str(self.polltime)+" REQ_ACTION:"+str(self.hookaction)+" REQTIME:"+str(self.gl_ts)+" warn_ts:"+str(self.warn_ts))
 		
-		self.nTimer.start(self.polltime)
-		self.bot.logger.debug("Starting Timer: polltime=" +str(self.polltime)+" REQ_ACTION:"+str(self.hookaction)+" REQTIME:"+str(self.gl_ts)+" warn_ts:"+str(self.warn_ts))
+		self.nTimerFlag=True
 
-
-	#Floodprotection
-	def cmd_is_fp(self, cmd, user): #FP for each cmd with different protect times
-		#releasing protection without a loopingCall
-		cmdi=self.kcs_.cmd_index(cmd)
-		if cmdi:
-			act_ts=int(time.time())
-			c_ts=self.kcs_.fp_ts[cmdi]
-			if c_ts < act_ts:
-				self.kcs_.delUser(cmdi)
-				self.kcs_.fp_ts[cmdi]=0
-			c_ts=self.kcs_.fp_ts[cmdi]
-			if c_ts!=0: #release and warn
-				if c_ts < act_ts: #release
-					self.kcs_.fp_ts[cmdi]=0
-					self.kcs_.delUser(cmdi, user)
-					return False
-				else: #return time left to wait or -1 if user has been informed once
-					c_ts-=act_ts
-					if not user in self.kcs_.user[cmdi]:
-						#self.kcs_.user.insert(cmdi, user)
-						self.kcs_.addUser(cmd, user)
-						return c_ts
-					else:
-						return -1 #user got notice once
-				
-			else: #protect the cmd
-				if c_ts==0: #.-1 
-					self.kcs_.fp_ts[cmdi]=self.kcs_.fp_time[cmdi]+act_ts
-					return False
-
-
 ##########################################################
 
 	def notify_gameadmin(self):
@@ -553,6 +480,7 @@
 				self.show_players()
 				self.nipmsg("PRE_XWeiter geht's mit #BOLD##CCHAR#restartgame ")
 				self.phase=GAME_WAITING
+				self.nTimerset('ENDAFTERPAUSE', "end_of_game")
 
 	def kick_gameadmin(self, refby=None):
 		self.bot.logger.debug("kick_gameadmin refby "+str(refby))
@@ -568,6 +496,7 @@
 			self.phase=GAME_WAITING #set only when not in "startphase"
 		else:
 			self.nipmsg("PRE_XWeiter geht's mit #BOLD##CCHAR#startgame ")
+		self.nTimerset('ENDAFTERPAUSE', "end_of_game")
 
 
 	def stop_timer(self):
@@ -579,6 +508,9 @@
 	def add_player(self, addnick):
 		if self.phase==NO_GAME:
 			return 0
+		if string.lower(addnick)[:6]=='nobody':
+			self.nipmsg("PRE_X"+addnick+": Illegaler Nickname :)")
+			return 0
 		if len(addnick) > self.maxnicklen:
 			self.nipmsg("PRE_X"+addnick+": Dein Nickname ist zu lang fuer das Spiel, maximal "+str(self.maxnicklen)+" Zeichen.")
 		else:
@@ -626,6 +558,7 @@
 						self.nipmsg("PRE_X"+delnick+" mangels Lebenszeichen automatisch aus dem Spiel entfernt.")
 					else:
 						self.nipmsg("PRE_X"+delnick+" spielt nicht mehr mit.")
+					self.set_warn_cnt(delnick, True)
 					
 				if delnick in self.uservoted_end:
 					self.uservoted_end.remove(delnick)
@@ -709,7 +642,20 @@
 		self.nipmsg("PRE_Q"+qw+"#BOLD#"+self.question)
 
 		self.nipmsg("PRE_C#UNDERLINE#Moegliche #BOLD#Antworten#BOLD# sind:#UNDERLINE#  ~"+str(self.gl_ts)+" Sek. Zeit!#DGREY#  (Aufforderung abwarten!)")
-		
+		#fit probably missing answers for more sexy gameplay
+		if self.Nobody: #flag from config or !nobody
+			nobodies=abs(len(self.players)+1-(len(self.answers.keys())))
+			if nobodies > 0:
+				for i in range(nobodies):
+					try:
+						fakeanswer=self.answers.values()[i]
+					except:
+						fakeanswer='Rembrandt'
+					if i==0:
+						fakeuser='Nobody'
+					else:
+						fakeuser='Nobody'+str(i)
+					self.answers[fakeuser]=fakeanswer
 		users=self.answers.keys()
 		random.shuffle(users)
 		for user in users:
@@ -730,10 +676,17 @@
 				self.allscore[player]=qty
 		else: #round "allscore" calculation
 			if str(player) in self.answeruser.values(): #we are evil at that point - no point for no given answer
+				iplayer=player
+				if string.lower(player)[:6]=='nobody':
+					player='Nobody'
 				if player in self.allscore.keys():
-					self.allscore[player]+=self.score[player]
+					self.allscore[player]+=self.score[iplayer]
 				else:
-					self.allscore[player]=self.score[player]
+					self.allscore[player]=self.score[iplayer]
+				if self.scoreLimit>0:
+					if self.allscore[player]>=self.scoreLimit:
+						self.scoreEnd=True
+						self.bot.logger.debug("SCORELIMIT reached by "+player+"!")
 		if not self.data_update_needed:
 				self.data_update_needed=True
 				self.bot.logger.debug("Setting data update is needed")
@@ -745,13 +698,16 @@
 		text=""
 		#build the output array here for 'from who'
 		for num in self.answeruser:
-			if self.answeruser[num]==self.gamemaster or self.answeruser[num]==self.gamemasterold:
+			player=self.answeruser[num]
+			if string.lower(player)[:6]=='nobody':
+				player='Nobody'
+			if player==self.gamemaster or player==self.gamemasterold:
 				snum=num #stored for later use 
-				firsttext+="("+self.answeruser[num]+" #NORM#**#BOLD#"+str(num)+"#BOLD#**)#NORM# "
+				firsttext+="("+player+" #NORM#**#BOLD#"+str(num)+"#BOLD#**)#NORM# "
 			else:
-				text+="#DGREY#("+self.answeruser[num]+" #NORM#"+str(num)+"#DGREY#)"
-		fromwho=firsttext+text	
-		return fromwho,snum
+				text+="#DGREY#("+player+" #NORM#"+str(num)+"#DGREY#)"
+		fromwho=firsttext+text
+		return fromwho, snum
 	
 	def quiz_scoring(self):
 		if len(self.score):
@@ -778,21 +734,37 @@
 				
 			#set in allscore
 			for user in self.score:
+				if string.lower(user)[:6]=='nobody':
+					player='Nobody'
 				self.add_allscore(user)
 
 
 	def check_for_answer(self):
+		#inc counter if no answer was given
 		for player in self.players:
 			if not player in self.answeruser.values():
-				if self.userWarnCnt.has_key(player):
-					self.userWarnCnt[player]+=1
-				else:
-					self.userWarnCnt[player]=1
+				#if self.userWarnCnt.has_key(player):
+				#	self.userWarnCnt[player]+=1
+				#else:
+				#	self.userWarnCnt[player]=1
+				self.set_warn_cnt(player)
 			else:
-				if self.userWarnCnt.has_key(player):
-					self.userWarnCnt[player]=0
+				self.set_warn_cnt(player, True)
+				
+				#if self.userWarnCnt.has_key(player):
+				#	self.userWarnCnt[player]=0
+		#print "check for answer->"+str(self.userWarnCnt)
 
-	
+	def set_warn_cnt(self, player, reset=None):
+		if reset==None:
+			if self.userWarnCnt.has_key(player):
+				self.userWarnCnt[player]+=1
+			else:
+				self.userWarnCnt[player]=1
+		else:
+			if self.userWarnCnt.has_key(player):
+				self.userWarnCnt[player]=0
+
 	def autoremoving(self, justplayer=None):
 		if not justplayer:
 			atext="" #
@@ -828,7 +800,7 @@
 		if self.gamemaster!="":
 			gmaster=self.gamemaster
 		if not self.answers.has_key(gmaster):
-			return "PRE_X"+self.TGAMEMASTER+gmaster+" hatte keine "+self.TNIPQUESTION
+			return "PRE_X"+self.TGAMEMASTER+" "+gmaster+" hatte keine "+self.TNIPQUESTION
 
 	def add_new_players(self):
 		if len(self.newplayers) > 0:
@@ -864,6 +836,8 @@
 				self.nipmsg(self.no_nip_question())
 		if self.votedEnd:
 			self.end_of_game()
+		elif self.scoreEnd:
+			self.end_of_game()
 		#last but not least co
 		else:
 			if self.autoremove:
@@ -878,90 +852,47 @@
 
 	def end_of_game(self):
 		self.stop_timer()
-		self.nipmsg("PRE_XSpiel beendet, #CCHAR#startgame startet ein Neues")
+		addtxt=""
+		if self.scoreEnd:
+			addtxt="(Scorelimit von "+str(self.scoreLimit)+" Punkten erreicht)"
+		self.nipmsg("PRE_XSpiel beendet!"+addtxt+" #BOLD##CCHAR#startgame#BOLD# startet ein Neues")
 		self.phase=NO_GAME
 		self.gameadmin=""
 		self.gamemaster=""
 		self.gameChannel=""
 		self.bot.logger.info("Gamechannel disangeged")
-		self.nip_hof_update(self.nipdatadir+self.hofdatafile)
+		self.nip_hof_update(self.nipdatadir+hofdata)
 		self.save_score()
-		self.fav.save(self.nipdatadir+self.favfile)
+		self.fav.save(self.nipdatadir+favdata)
 		self.players=[]
 		self.uservoted_end=[]
 
-
-	def auto_command(self, cmd, uuser, cchannel):
-		# not stress-tested so far, and maybe something for the bot itself
-		# extracts given usercmd to a given command, not case-sensitive, so user(player) may say !AborT and we'll realise
-		## Todo: for hundreds of commands i suggest to build another list/hash from first char of given command
-		## this is quick and dirty just to play around with python 
-		## Todo try to put the hit on the first unique cmd in kcd
-		if cmd=="":
-			return cmd
-		i=0
-		a=0
-		it=""
-		if cmd in self.kcs:
-			it=cmd
-			return it
-		else:
-			while ( a < len(self.kcs)):
-				kc=self.kcs[a]        #would be nice to have a sorted haash #kcs_ Todo
-				a+=1
-				if kc[:len(cmd)]==string.lower(cmd):
-					hit=kc
-					i+=1
-					if i >=2: #not unique
-						if cchannel==self.gamechannel: #avoid cmd conflicts oO
-							self.nipmsg("PRE_H"+uuser+": Meintest du:#BOLD#"+self.suggest_command(cmd)+"#BOLD#?")
-						break
-			if i == 1:
-				it=hit
-			else:
-				if i == 0:
-				#too long?
-					if cchannel==self.gamechannel:
-						suggest=self.suggest_command(cmd[:1])
-						if suggest:
-							self.nipmsg("PRE_H"+uuser+": Meintest du:#BOLD#"+suggest+"#BOLD#?")
-			return it
-
-		
-	def suggest_command(self, cmd):
-		suggest=""
-		for suggests in self.kcs: #todo use kcs_
-			if cmd==suggests[:len(cmd)]:
-				suggest=suggest+" \"#CCHAR#"+suggests+"\""
-		return suggest
-
-
-	def replace_command(self, cmd):    #maybe useful
-		if cmd=="end":
-			cmd="abortgame"
-		if cmd=="join":
-			cmd="add"
-		if cmd=="hof":
-			cmd="halloffame"  
-		if cmd=="part":
-			cmd="remove"
-		if cmd=="ranking":
-			cmd="halloffame"
-		if cmd=="groupies":
-			cmd="favorits"
-		if cmd=="continue":
-			cmd="restartgame"
-		if cmd=="p_kater":
-			cmd="rules"
-		if cmd=="help":
-			cmd="niphelp"
-		return cmd
+	def replace_command(self, command):    #maybe useful
+		if command=="end":
+			command="abortgame"
+		if command=="join":
+			command="add"
+		if command=="hof":
+			command="halloffame"  
+		if command=="part":
+			command="remove"
+		if command=="ranking":
+			command="halloffame"
+		if command=="groupies":
+			command="favorits"
+		if command=="continue":
+			command="restartgame"
+		if command=="rtfm":
+			command="rules"
+		if command=="fraglimit":
+			command="scorelimit"
+		return command
 	
 	def check_channel(self, cchannel, ccommand):
 		if ccommand=="status": #ccmd allowed in any channel
 			return 1
-		if cchannel not in self.channels:
-			return 0
+		#if cchannel not in self.channels:
+		#	return 0
 		if not self.gamechannel:
 			return 1
 		elif self.gamechannel==cchannel:
@@ -1015,346 +946,423 @@
 	
 	def nip_buffer(self, user, channel, command, options):
 		bmsg=""
+		if not command:
+			return 0
 		cmd=command[0]
 		if cmd=="h":
-			bmsg="!q[uestion] !a[nswer] !t[ip] NIP-Frage vorab einstellen, !n[ip] zeigt die Daten. Ueberschreiben ist moeglich."
+			bmsg="/msg "+self.bot.nickname+" !q[uestion] !a[nswer] !t[ip] -> NIP-Frage/Antwort/Tip vorab eingeben. !n[ip] zeigt die Daten. Ueberschreiben ist moeglich. Der Bot verwendet diese Frage dann automatisch, wenn du NIP-Fragesteller bist."
 		elif cmd=="q" or cmd=="a" or cmd=="t" or cmd=="n":
 			if options:
 				self.NIPbuffer.put(user, cmd, options)
 			rv=self.NIPbuffer.get(user)
 			bmsg="Frage: "+rv[0]+" Antwort: "+rv[1]+" Tip: "+rv[2]
 		if bmsg:
-			self.bot.sendmsg(user, "NIPbuffer: "+bmsg,self.NIPencoding)
+			#self.bot.sendmsg(user, "NIPbuffer: "+bmsg,self.NIPencoding)
+			self.bot.notice(user, "NIPbuffer: "+bmsg)
 		self.bot.logger.debug("NIPbuffer: "+user+" cmd="+cmd)
 
 
 	def command(self, user, channel, command, options):
-			user=user.split("!")[0]
-			if channel==self.bot.nickname and user!=self.gamemaster:
-				self.nip_buffer(user, channel, command, options) # we check for cmd 
-			if not self.check_channel(channel, command): #try this here (is confed gamechannel or a command for all channels)
-				return 0
-			command=self.auto_command(command, user, channel) #abbreviated commands
-			command=self.replace_command(command) #for synonyms
-			check_fp=self.cmd_is_fp(command, user) #floodprotection
-			if check_fp:
-				if check_fp >-1:
-					self.nipmsg("PRE_D"+user+":Warte "+str(check_fp)+" Sek. fuer !"+command, channel)
+		if channel==self.bot.nickname and user!=self.gamemaster:
+			self.nip_buffer(user.split("!")[0], channel, command, options) # nipbuffer in query
+			return True
+		#Floodprotection (channel)
+		command=self.replace_command(command)
+		try:
+			command=self.bot.cmdhandler.command_floodprotect(command, user, channel, True, False)
+			if not command:
+				return False
+		except:
+			pass # commandhandler/floodprotection not available
+		#################
+		user=user.split("!")[0]
+		
+		if not self.check_channel(channel, command): #try this here (is confed gamechannel or a command for all channels)
+			return False
+
+	#if channel!=self.bot.nickname: #no query
+		if command=="kill":
+			if self.gameadmin==user and self.phase!=WAITING_FOR_PLAYERS: 
+				self.nipmsg("PRE_XOoops! "+self.TGAMEADMIN+" "+self.gameadmin+" hat wohl keine Lust mehr...")
+				self.del_player(user)
+				self.gameadmin=""
+			else: 
+				if self.gameadmin==user:
+					self.nipmsg("PRE_X"+self.TGAMEADMIN+" "+self.gameadmin+" das geht erst nach #CCHAR#startgame oder #CCHAR#abortgame")
+		
+		elif command=="niphelp":
+			self.nipmsg("PRE_H"+HELPBUG)
+			if not self.phase==NO_GAME:
+				if options[:3].strip()=="all":
+					self.nipmsg("PRE_H"+HELPUSER)
+					self.nipmsg("PRE_H"+HELPADMIN)
+				else:
+					if self.gameadmin==user:
+						self.nipmsg("PRE_H"+self.TGAMEADMIN+" "+HELPADMIN)
+					else:
+						self.nipmsg("PRE_H"+HELPUSER)
 			else:
-				self.bot.logger.info("Allowed cmd "+command)
-				if channel!=self.bot.nickname: #no query
-					if command=="kill":
-						if self.gameadmin==user and self.phase!=WAITING_FOR_PLAYERS: 
-							self.nipmsg("PRE_XOoops!"+self.TGAMEADMIN+" "+self.gameadmin+" hat wohl keine Lust mehr...")
-							self.del_player(user)
-							self.gameadmin=""
-						else: 
-							if self.gameadmin==user:
-								self.nipmsg("PRE_X"+self.TGAMEADMIN+" "+self.gameadmin+" das geht erst nach #CCHAR#startgame oder #CCHAR#abortgame")
+				self.nipmsg("PRE_H#CCHAR#startgame. Waehrend des Spiels #CCHAR#niphelp <all> oder #CCHAR#rules", channel)
+		
+		elif command=="vote":
+			if not self.phase==NO_GAME:
+				if string.lower(options[:3].strip())=="end" or string.lower(options[:5].strip())=="abort":
+					self.vote_for_end(user)
+		
+		elif command=="autoremove":
+			if user==self.gameadmin:
+				if self.autoremove==0:
+					self.autoremove=1
+					self.nipmsg("PRE_X#BOLD#Autoremove#BOLD# ist nun #BOLD#aktiv#BOLD#, NIP-Fragesteller ohne Aktion werden automatisch aus dem piel entfernt")
+				else:
+					self.autoremove=0
+					self.nipmsg("PRE_X#BOLD#Autoremove#BOLD# ist nun #BOLD#inaktiv#BOLD#.")
+			else:
+				addword="inaktiv"
+				if self.autoremove==1:
+					addword="aktiv"
+				if not self.phase==NO_GAME:
+					self.nipmsg("PRE_X#BOLD#Autoremove#BOLD# ist #BOLD#"+addword+"#BOLD#. Wechsel nur durch den "+self.TGAMEADMIN+" moeglich!")
 
-					elif command=="niphelp":
-						self.nipmsg("PRE_H"+HELPBUG)
-						if not self.phase==NO_GAME:
-							if options[:3].strip()=="all":
- 								self.nipmsg("PRE_H"+HELPUSER)
-								self.nipmsg("PRE_H"+HELPADMIN)
-							else:
-								if self.gameadmin==user:
-									self.nipmsg("PRE_H"+self.TGAMEADMIN+" "+HELPADMIN)
-								else:
-									self.nipmsg("PRE_H"+HELPUSER)
-						else:
-							self.nipmsg("PRE_H#CCHAR#startgame. Waehrend des Spiels #CCHAR#niphelp <all> oder #CCHAR#rules", channel)
+		elif command=="splitpoints":
+			if user==self.gameadmin:
+				if self.splitpoints==0:
+					self.splitpoints=1
+					self.nipmsg("PRE_X#BOLD#Splitpoints#BOLD# ist nun #BOLD#aktiv#BOLD#, ich zeige die genaue Punkteverteilung")
+				else:
+					self.splitpoints=0
+					self.nipmsg("PRE_X#BOLD#Splitpoints#BOLD# ist nun #BOLD#inaktiv#BOLD#, ich zeige nur die Gesamtpunktzahl")
+			else:
+				addword="inaktiv"
+				if self.splitpoints==1:
+					addword="aktiv"
+				if not self.phase==NO_GAME:
+					self.nipmsg("PRE_X#BOLD#Splitpoints#BOLD# ist #BOLD#"+addword+"#BOLD#. Wechsel nur durch den "+self.TGAMEADMIN+" moeglich!")
+					
+		elif command=="nobody":
+			if user==self.gameadmin:
+				if self.Nobody==False:
+					self.Nobody=True
+					self.nipmsg("PRE_X#BOLD#Nobody#BOLD# spielt nun mit.")
+				else:
+					self.Nobody=False
+					self.nipmsg("PRE_X#BOLD#Nobody#BOLD# spielt nicht mehr mit.")
+				self.bot.setConfig("Nobody", str(self.Nobody), "NIP")
+			else:
+				if self.Nobody:
+					self.nipmsg("PRE_X#BOLD#Nobody#BOLD# spielt mit.")
+				else:
+					self.nipmsg("PRE_X#BOLD#Nobody#BOLD# spielt nicht mit.")
+		
+		elif command=="timebase":
+			if user==self.gameadmin:
+				try:
+					newVal=int(options)
+				except:
+					newVal=""
+				if type(newVal)==int:
+					if newVal>19 and newVal<1000:
+						self.bot.logger.debug("Setting Timebase to:"+str(newVal))
+						self.init_timeouts(int(newVal))
+					else:
+						self.nipmsg("PRE_XErlaubte TimeBase Werte 20-999 Sekunden. Standard=60")
+						return 0
+			text='Timebase='+str(self.TimeBase)+' seconds. Details:'
+			for key in self.timeouts.keys():
+				text=text+key+'='+str(self.timeouts.get(key,""))+' seconds; '
+			self.nipmsg("PRE_X"+text)
+		
+		elif command=="scorelimit":
+			if user==self.gameadmin:
+				try:
+					newVal=int(options)
+				except:
+					newVal=""
+				if type(newVal)==int:
+					if newVal >=0 and newVal < 1000:
+						self.bot.logger.debug("Setting Scorelimit to:"+str(newVal))
+						self.scoreLimit=(int(newVal))
+					else:
+						self.nipmsg("PRE_XErlaubte Scorelimit-Werte 0-999. Standard=0")
+						return 0
+			if self.scoreLimit>0:		
+				self.nipmsg("PRE_X"+"Spielende beim Erreichen von "+str(self.scoreLimit)+" Punkten")
+			else:
+				self.nipmsg("PRE_X"+"Es wurde kein Scorelimit eingestellt.")
 			
-					elif command=="vote":
-						if not self.phase==NO_GAME:
-							if string.lower(options[:3].strip())=="end" or string.lower(options[:5].strip())=="abort":
-								self.vote_for_end(user)
-				
-					elif command=="autoremove":
-						if user==self.gameadmin:
-							if self.autoremove==0:
-								self.autoremove=1
-								self.nipmsg("PRE_X#BOLD#Autoremove#BOLD# ist nun #BOLD#aktiv#BOLD#, NIP-Fragesteller ohne Aktion werden automatisch aus dem Spiel entfernt")
-							else:
-								self.autoremove=0
-								self.nipmsg("PRE_X#BOLD#Autoremove#BOLD# ist nun #BOLD#inaktiv#BOLD#.")
-						else:
-							addword="inaktiv"
-							if self.autoremove==1:
-								addword="aktiv"
-							if not self.phase==NO_GAME:
-								self.nipmsg("PRE_X#BOLD#Autoremove#BOLD# ist #BOLD#"+addword+"#BOLD#. Wechsel nur durch den "+self.TGAMEADMIN+" moeglich!")
+		elif command=="debugtimer": #obsolete
+			if string.lower(user)=='netear':
+				if self.nTimer.running:
+					self.nTimer.stop()
+					self.nipmsg("PRE_XTimer stopped")
+				else:
+					self.nipmsg("PRE_XTimer started")
+					self.nTimer.start(self.polltime)
+				text="[gl_ts=#BOLD#"+str(self.gl_ts)+"#BOLD#] "
+				text=text+"[polltime=#BOLD#"+str(self.polltime)+"#BOLD#] "
+				text=text+"[hookaction=#BOLD#"+str(self.hookaction)+"#BOLD#] "
+				text=text+"[Timer Running=#BOLD#"+str(self.nTimer.running)+"#BOLD#] "
+				self.nipmsg("PRE_XDebugging Info for twisted."+text)
+				result=self.game_status(channel)
+				if self.gamechannel!=channel and self.gamechannel!="":
+					self.nipmsg("PRE_GEs wird bereits gespielt! #BOLD#/join "+self.gamechannel, channel)
+				if self.gamechannel==channel or self.gamechannel=="":
+					self.nipmsg("PRE_G"+result, channel)
+		
+		elif command=="polltime":
+			if string.lower(user)=='netear':
+				try:
+					newVal=int(options)
+				except:
+					newVal=""
+				if type(newVal)==int:
+					if newVal>0 and newVal<30:
+						self.bot.logger.debug("Setting Polltime to:"+str(newVal))
+						self.polltime=newVal
+						if self.phase!=0:
+							self.nTimer.stop()
+							self.nTimer.start(self.polltime)
 
-					elif command=="splitpoints":
-						if user==self.gameadmin:
-							if self.splitpoints==0:
-								self.splitpoints=1
-								self.nipmsg("PRE_X#BOLD#Splitpoints#BOLD# ist nun #BOLD#aktiv#BOLD#, ich zeige die genaue Punkteverteilung")
-							else:
-								self.splitpoints=0
-								self.nipmsg("PRE_X#BOLD#Splitpoints#BOLD# ist nun #BOLD#inaktiv#BOLD#, ich zeige nur die Gesamtpunktzahl")
-						else:
-							addword="inaktiv"
-							if self.splitpoints==1:
-								addword="aktiv"
-							if not self.phase==NO_GAME:
-								self.nipmsg("PRE_X#BOLD#Splitpoints#BOLD# ist #BOLD#"+addword+"#BOLD#. Wechsel nur durch den "+self.TGAMEADMIN+" moeglich!")
+		elif command=="testing":
+			if user==self.gameadmin:
+				if self.minplayersold == 0:
+					self.minplayersold=self.minplayers
+					self.maxplayersold=self.maxplayers
+					self.minplayers=3 # default in config will be 5 
+					self.maxplayers=24 #default in config will be 12
+					self.nipmsg("PRE_XMinimum Spieler=#BOLD#"+str(self.minplayers)+"#BOLD# Maximum Spieler=#BOLD#"+str(self.maxplayers))
+				else:
+					self.minplayers=self.minplayersold
+					self.maxplayers=self.maxplayersold
+					self.minplayersold=0
+					self.maxplayersold=0
+					self.nipmsg("PRE_XMinimum Spieler=#BOLD#"+str(self.minplayers)+"#BOLD# Maximum Spieler=#BOLD#"+str(self.maxplayers))
+			else:
+				self.nipmsg("PRE_XYou have found a secret :)")
 
-					elif command=="gamespeed":
-						if user==self.gameadmin:
-							if self.gamespeed==1:
-								self.gamespeed=2
-								self.nipmsg("PRE_XSpielgeschwindigkeit ist nun #BOLD#schnell.")
-							else:
-								self.gamespeed=1
-								self.nipmsg("PRE_XSpielegeschwindigkeit ist nun #BOLD#normal.")
+		elif command=="add":
+			self.bot.logger.debug("Adding player in phase "+str(self.phase))
+			if self.phase==NO_GAME or self.phase==GAME_WAITING: #should work now
+			#if self.phase==GAME_WAITING:
+				if self.gameadmin: #we have one ;)
+					if user==self.gameadmin: #himself
+						if len(options) > 1:
+							player=options.strip() #Todo channeluserlist	
+							# need channeluserlist
+							self.add_player(player)
 						else:
-							actspeed="normal"
-							if self.gamespeed==2:
-								actspeed="schnell"
-							if not self.phase==NO_GAME:
-								self.nipmsg("PRE_XSpielgeschwindigkeit ist #BOLD#"+actspeed+"#BOLD#. Wechsel nur durch den "+self.TGAMEADMIN+" moeglich!")
+							self.add_player(user) #just add himself
+					else:
+						self.add_player(user) # just a player 
+				else:
+					self.add_player(user) # again maybe we have no admin
+			else:
+				if self.phase==WAITING_FOR_PLAYERS:
+					self.nipmsg("PRE_X"+user+": Einfach \"ich\" rufen!")
+				else: #only users join thereself
+					if not user in self.players and not user in self.newplayers and self.gameadmin!=user:
+						self.nipmsg("PRE_X"+user+" spielt ab der naechsten Runde mit")
+						self.newplayers.append(user)
+					elif user==self.gameadmin:
+						self.nipmsg("PRE_X"+user+": "+self.TGAMEADMIN+" kann nur zwischen den Runden einsteigen")
 
-					elif command=="testing":
-						if user==self.gameadmin:
-							if self.minplayersold == 0:
-								self.minplayersold=self.minplayers
-								self.maxplayersold=self.maxplayers
-								self.minplayers=3 # default in config will be 5 
-								self.maxplayers=24 #default in config will be 12
-								self.nipmsg("PRE_XMinimum Spieler=#BOLD#"+str(self.minplayers)+"#BOLD# Maximum Spieler=#BOLD#"+str(self.maxplayers))
-							else:
-								self.minplayers=self.minplayersold
-								self.maxplayers=self.maxplayersold
-								self.minplayersold=0
-								self.maxplayersold=0
-								self.nipmsg("PRE_XMinimum Spieler=#BOLD#"+str(self.minplayers)+"#BOLD# Maximum Spieler=#BOLD#"+str(self.maxplayers))
+		elif command=="remove":
+			#if self.phase==NO_GAME or self.phase==GAME_WAITING: #Todo removing alltime
+			if self.phase!=7: #try if compatible with flow (Todo)
+				if self.gameadmin: #we may have one ;)
+					if user==self.gameadmin: #himself
+						if len(options) > 1:
+						#player=string.lower(options[:24].strip()) #truncated and the trailing spaces eliminated 
+							player=options[:24].strip() #truncated and the trailing spaces eliminated 
+							self.del_player(player) #admin removes player
 						else:
-							self.nipmsg("PRE_XYou have found a secret :)")
-
-					elif command=="add":
-						self.bot.logger.debug("Adding player in phase "+str(self.phase))
-						if self.phase==NO_GAME or self.phase==GAME_WAITING: #should work now
-						#if self.phase==GAME_WAITING:
-							if self.gameadmin: #we have one ;)
-								if user==self.gameadmin: #himself
-									if len(options) > 1:
-										player=options.strip() #Todo channeluserlist	
-										# need channeluserlist
-										self.add_player(player)
-									else:
-										self.add_player(user) #just add himself
-								else:
-									self.add_player(user) # just a player 
-							else:
-								self.add_player(user) # again maybe we have no admin
+							self.del_player(user) #just remove himself 
+					else:
+						if len(options) == 0: #
+							self.del_player(user) # a player
 						else:
-							if self.phase==WAITING_FOR_PLAYERS:
-								self.nipmsg("PRE_X"+user+": Einfach \"ich\" rufen!")
-							else: #only users join thereself
-								if not user in self.players and not user in self.newplayers and self.gameadmin!=user:
-									self.nipmsg("PRE_X"+user+" spielt ab der naechsten Runde mit")
-									self.newplayers.append(user)
-								elif user==self.gameadmin:
-									self.nipmsg("PRE_X"+user+": "+self.TGAMEADMIN+" kann nur zwischen den Runden einsteigen")
+							self.nipmsg("PRE_X"+user+": Das darf nur der "+self.TGAMEADMIN+" "+str(self.gameadmin))
+				else:
+					self.del_player(user) # again even if there is no admin
+			else:
+				self.nipmsg("PRE_X"+user+": Aussteigen geht nur zwischen den Runden.") #obsolete
 
-					elif command=="remove":
-						#if self.phase==NO_GAME or self.phase==GAME_WAITING: #Todo removing alltime
-						if self.phase!=7: #try if compatible with flow (Todo)
-							if self.gameadmin: #we may have one ;)
-								if user==self.gameadmin: #himself
-									if len(options) > 1:
-									#player=string.lower(options[:24].strip()) #truncated and the trailing spaces eliminated 
-										player=options[:24].strip() #truncated and the trailing spaces eliminated 
-										self.del_player(player) #admin removes player
-									else:
-										self.del_player(user) #just remove himself 
-								else:
-									if len(options) == 0: #
-										self.del_player(user) # a player
-									else:
-										self.nipmsg("PRE_X"+user+": Das darf nur der "+self.TGAMEADMIN+" "+str(self.gameadmin))
-							else:
-								self.del_player(user) # again even if there is no admin
-						else:
-							self.nipmsg("PRE_X"+user+": Aussteigen geht nur zwischen den Runden.") #obsolete
+		elif command=="players":
+			#if self.phase==NO_GAME:
+			self.show_players()
 
-					elif command=="players":
-						#if self.phase==NO_GAME:
-						self.show_players()
-
-					elif command=="restartgame":
-						if self.gameadmin=="" and self.phase==GAME_WAITING:
-							self.new_gameadmin(user)
-				
-						if self.gameadmin==user and self.phase<2: #test
-							self.stop_timer() #needed here due to kick_gameadmin?
+		elif command=="restartgame":
+			if self.gameadmin=="" and self.phase==GAME_WAITING:
+				self.new_gameadmin(user)
+			if self.gameadmin==user and self.phase<2: #test
+				self.stop_timer() #needed here due to kick_gameadmin?
 	
-						if self.phase==GAME_WAITING and user==self.gameadmin:
-							if self.player_qty() >= self.minplayers:
+			if self.phase==GAME_WAITING and user==self.gameadmin:
+				if self.player_qty() >= self.minplayers:
 
-								tmpplayers=string.join(self.players," ") # trunc this? or predone?
-								if self.gamemaster:
-									tmpplayers=self.gamemaster+" "+tmpplayers
-								self.init_vars_for_restart()
-								self.nipmsg("PRE_GRunde (#BOLD#"+str(self.roundofgame)+"#BOLD#) mit: "+tmpplayers)
-								self.phase=WAITING_FOR_QUESTION
-								self.nTimerset('TIMEOUT', "end_of_quiz")
-								
-								if not self.check_nip_buffer(self.gamemaster):
-									self.nipmsg("PRE_Q"+str(self.gamemaster)+": Schick' mir die "+self.TNIPQUESTION+"."+"  ~"+str(self.gl_ts)+" Sek. Zeit!#DGREY# (/msg "+self.bot.nickname+" die Frage)") #guess gamemaster might work in all cases instead of user here ;)
-									self.bot.sendmsg(self.gamemaster,"Du kannst im "+self.gamechannel+" !resetgame machen, falls du dich vertippt hast. Und nun die NIP-Frage:",self.NIPencoding)
-							else:
-								self.nipmsg("PRE_GZu wenig Spieler. Mindestens "+str(self.minplayers)+" muessen mitspielen! #BOLD##CCHAR#join")
+					tmpplayers=string.join(self.players," ") # trunc this? or predone?
+					if self.gamemaster:
+						tmpplayers=self.gamemaster+" "+tmpplayers
+					self.init_vars_for_restart()
+					self.nipmsg("PRE_GRunde (#BOLD#"+str(self.roundofgame)+"#BOLD#) mit: "+tmpplayers)
+					self.phase=WAITING_FOR_QUESTION
+					self.nTimerset('TIMEOUT', "end_of_quiz")
 
-					elif command=="startgame":
-						##### if not self.gamechannel (see check_channel)means there is no game on network!
-						if self.phase==NO_GAME:
-							if len(user) < self.maxnicklen:
-								self.gamechannel=channel #needed for queries which result in a public answer # settint the . gamechannel also means there is a game running in this channel
-								self.bot.logger.info("Setting Gamechannel to "+channel)
-								self.init_vars()
-								self.allscore={}
-								self.save_score(True)
-								self.nipmsg("PRE_XSpielstand archiviert und geloescht!")
-								self.phase=WAITING_FOR_PLAYERS
-								
-								self.gameadmin=user
+					if not self.check_nip_buffer(self.gamemaster):
+						self.nipmsg("PRE_Q"+str(self.gamemaster)+": Schick' mir die "+self.TNIPQUESTION+"."+"  ~"+str(self.gl_ts)+" Sek. Zeit!#DGREY# (/msg "+self.bot.nickname+" die Frage)") #guess gamemaster might work in all cases instead of user here ;)
+						self.bot.sendmsg(self.gamemaster,"Du kannst im "+self.gamechannel+" !resetgame machen, falls du dich vertippt hast. Und nun die NIP-Frage:",self.NIPencoding)
+				else:
+					self.nipmsg("PRE_GZu wenig Spieler. Mindestens "+str(self.minplayers)+" muessen mitspielen! #BOLD##CCHAR#join")
 
-								self.nipmsg("PRE_X"+user+": Du bist nun der "+self.TGAMEADMIN+" - Los geht's mit #CCHAR#startgame.")
-								self.nipmsg("PRE_XWer moechte an einer Runde "+self.nameofgame+" teilnehmen? (\"\x02ich\x02\" rufen!)")
+		elif command=="startgame":
+			##### if not self.gamechannel (see check_channel)means there is no game on network!
+			if self.phase==NO_GAME:
+				if len(user) < self.maxnicklen:
+					self.gamechannel=channel #needed for queries which result in a public answer # settint the . gamechannel also means there is a game running in this channel
+					self.bot.logger.info("Setting Gamechannel to "+channel)
+					self.init_vars()
+					self.allscore={}
+					self.save_score(True)
+					self.nipmsg("PRE_XSpielstand archiviert und geloescht!")
+					self.phase=WAITING_FOR_PLAYERS
+					self.gameadmin=user
 
-								self.nTimerset('STARTPHASE',"kick_gameadmin") #in this phase we well do end_of_game after timeout
-							else:
-								self.nipmsg("PRE_X"+user+": Dein nickname ist zu lang. Maximal "+str(self.maxnicklen)+" Zeichen.")
-					
-						elif self.phase==WAITING_FOR_PLAYERS and user==self.gameadmin:
-							if self.player_qty() >= self.minplayers:
-								self.phase=WAITING_FOR_QUESTION
-								random.shuffle(self.players)
-								self.gamemaster=random.choice(self.players)
-								if self.gamemaster in self.players:
-									self.players.remove(self.gamemaster) # due to new flow at this point needed, too (because he knows the answer)
-								self.bot.logger.debug("Random choice setting gamemaster:"+self.gamemaster)
-								self.nTimerset('TIMEOUT', "end_of_quiz")
-								if not self.check_nip_buffer(self.gamemaster):
-									self.nipmsg("PRE_Q"+self.gamemaster+": Schick' mir die "+self.TNIPQUESTION+". ~"+str(self.gl_ts)+" Sek. Zeit! #DGREY# (/msg "+self.bot.nickname+" die Frage)")
-									self.bot.sendmsg(self.gamemaster, "Du kannst im "+self.gamechannel+" !resetgame machen, falls du dich vertippt hast. Und nun die NIP-Frage:",self.bot.getConfig("enncoding","UTF-8"))
-						
-							else:
-								self.nipmsg("PRE_X"+self.gameadmin+": Zuwenig Mitspieler! Mindestens "+str(self.minplayers)+" muessen mitspielen. #BOLD#\"ich\" rufen!")
-			
-						elif self.gameadmin=="": #Auto_new_gameadmin
-							self.new_gameadmin(user)
+					self.nipmsg("PRE_X"+user+": Du bist nun der "+self.TGAMEADMIN+" - Los geht's mit #CCHAR#startgame.")
+					self.nipmsg("PRE_XWer moechte an einer Runde "+self.nameofgame+" teilnehmen? (\"\x02ich\x02\" rufen!)")
+					self.nTimerset('STARTPHASE',"kick_gameadmin") #in this phase we do end_of_game after timeout
+					self.nTimer.start(self.polltime) # starting once here, and stop it when game ends due to lost reference to object
+				else:
+					self.nipmsg("PRE_X"+user+": Dein nickname ist zu lang. Maximal "+str(self.maxnicklen)+" Zeichen.")
 
-					elif command=="abortgame": #now "end of game"
-						if self.gameadmin=="" and self.phase!=NO_GAME:
-							self.new_gameadmin(user)
-	
-						if self.gameadmin==user and self.phase > 0:
-						#if len(self.uservoted_end)< 1:
-							if self.abortcnt < 1:
-								self.nipmsg("PRE_X"+self.gameadmin+": Um das Spiel tatsaechlich zu beenden, bitte noch einmal!")
-								self.abortcnt=1
-							else: # end the game
-								for player in self.players:
-									self.uservoted_end.append(player)
-								self.votedEnd=1
-								adminVote=True #
-								self.vote_for_end(user,adminVote)
-						else:
-							if not self.phase==NO_GAME:
-								self.nipmsg("PRE_XAbbruch nur durch den "+self.TGAMEADMIN+" "+self.gameadmin+" moeglich, versuche #CCHAR#vote", channel)
-			
-					elif command=="resetgame":
-						if self.phase==WAITING_FOR_QUIZMASTER_ANSWER or self.phase==WAITING_FOR_ANSWERS:
-							if self.gameadmin==user or self.gamemaster==user:
-								self.resetcnt+=1 #todo block more than x resets....
-								ppoints=self.resetcnt * 2
-								if self.resetcnt>1:
-									self.nipmsg("PRE_H"+user+": Auf ein Neues! #BOLD#Punktabzug: -"+str(ppoints))
-									self.bot.sendmsg(self.gamemaster,"Deine NIP-Frage:")
-									self.add_allscore(user,int(ppoints*-1))
-									self.reset_game()
-								else:
-									ppoints=1
-									self.nipmsg("PRE_H"+user+": Auf ein neues! #BOLD#Naechstemal Punktabzug!")
-									self.bot.sendmsg(self.gamemaster,"Deine NIP-Frage:")
-									#self.add_allscore(user, -1)
-									self.reset_game()
-							else:
-								self.nipmsg("PRE_H NOP")
-						else:
-							self.nipmsg("PRE_H NOP")
+			elif self.phase==WAITING_FOR_PLAYERS and user==self.gameadmin:
+				if self.player_qty() >= self.minplayers:
+					self.phase=WAITING_FOR_QUESTION
+					random.shuffle(self.players)
+					self.gamemaster=random.choice(self.players)
+					if self.gamemaster in self.players:
+						self.players.remove(self.gamemaster) # due to new flow at this point needed, too (because he knows the answer)
+					self.bot.logger.debug("Random choice setting gamemaster:"+self.gamemaster)
+					self.nTimerset('TIMEOUT', "end_of_quiz")
+					if not self.check_nip_buffer(self.gamemaster):
+						self.nipmsg("PRE_Q"+self.gamemaster+": Schick' mir die "+self.TNIPQUESTION+". ~"+str(self.gl_ts)+" Sek. Zeit! #DGREY# (/msg "+self.bot.nickname+" die Frage)")
+						self.bot.sendmsg(self.gamemaster, "Du kannst im "+self.gamechannel+" !resetgame machen, falls du dich vertippt hast. Und nun die NIP-Frage:",self.bot.getConfig("enncoding","UTF-8"))
 
-					elif command=="scores":
-						pointlen=0
-						if len(self.allscore):
-							pointlen=len(str(max(self.allscore.values())))
-						SCOREHEAD="#UNDERLINE#_-=Punkteverteilung=-"+self.create_ws(pointlen-1+self.maxnicklen-12)+"_#UNDERLINE##DGREY#"+" Runde:"+str(self.roundofgame)
-						self.nipmsg("PRE_S"+SCOREHEAD, channel)
-						if len(self.allscore):	
-							points=self.allscore.values()
-							points.sort()
-							points.reverse()
-							players=self.allscore.keys()
-							for point in points:
-								for player in players:
-									if self.allscore[player]==point:
-										pword="Punkte"
-										if point==1:
-											pword="Punkt"
-										splayer=player+self.create_ws(self.maxnicklen)
-										#spoints=str(point)+self.create_ws(12+len(str(point)))[:pointlen]
-										spoints=str(point)+self.create_ws(pointlen-len(str(point)))
-										self.nipmsg("PRE_S"+splayer[:self.maxnicklen]+"  "+spoints+ " "+pword, channel)
-										players.remove(player)
-										break; #
+				else:
+					self.nipmsg("PRE_X"+self.gameadmin+": Zuwenig Mitspieler! Mindestens "+str(self.minplayers)+" muessen mitspielen. #BOLD#\"ich\" rufen!")
 
-					elif command=="rules":
-					     self.nipmsg("PRE_H"+self.NIPRULES, channel)
+			elif self.gameadmin=="": #Auto_new_gameadmin
+				self.new_gameadmin(user)
 
-					elif command=="status":
-						result=self.game_status(channel)
-						if self.gamechannel!=channel and self.gamechannel!="":
-							self.nipmsg("PRE_GEs wird bereits gespielt! #BOLD#/join "+self.gamechannel, channel)
-						if self.gamechannel==channel or self.gamechannel=="":
-							self.nipmsg("PRE_G"+result, channel)
+		elif command=="abortgame" : #now "end of game"
+			if self.gameadmin=="" and self.phase!=NO_GAME:
+				self.new_gameadmin(user)
+			if self.gameadmin==user and self.phase > 0:
+			#if len(self.uservoted_end)< 1:
+				if self.abortcnt < 1:
+					self.nipmsg("PRE_X"+self.gameadmin+": Um das Spiel tatsaechlich zu beenden, bitte noch einmal!")
+					self.abortcnt=1
+				else: # end the game
+					for player in self.players:
+						self.uservoted_end.append(player)
+					self.votedEnd=1
+					adminVote=True #
+					self.vote_for_end(user,adminVote)
+			else:
+				if not self.phase==NO_GAME:
+					self.nipmsg("PRE_XAbbruch nur durch den "+self.TGAMEADMIN+" "+self.gameadmin+" moeglich, versuche #CCHAR#vote", channel)
 
-					elif command=="place":
-						self.show_user_in_halloffame(channel,user,options)
+		elif command=="resetgame":
+			if self.phase==WAITING_FOR_QUIZMASTER_ANSWER or self.phase==WAITING_FOR_ANSWERS:
+				if self.gameadmin==user or self.gamemaster==user:
+					self.resetcnt+=1 #todo block more than x resets....
+					ppoints=self.resetcnt * 2
+					if self.resetcnt>1:
+						self.nipmsg("PRE_H"+user+": Auf ein Neues! #BOLD#Punktabzug: -"+str(ppoints))
+						self.bot.sendmsg(self.gamemaster,"Deine NIP-Frage:")
+						self.add_allscore(user,int(ppoints*-1))
+						self.reset_game()
+					else:
+						ppoints=1
+						self.nipmsg("PRE_H"+user+": Auf ein neues! #BOLD#Naechstemal Punktabzug!")
+						self.bot.sendmsg(self.gamemaster,"Deine NIP-Frage:")
+						#self.add_allscore(user, -1)
+						self.reset_game()
+				else:
+					self.nipmsg("PRE_H NOP")
+			else:
+				self.nipmsg("PRE_H NOP")
 
-					elif command=="halloffame":
-						if self.hof==None:
-							self.bot.logger.error("HoF empty, file permissions? Maybe it is just new.")
-						else:
-							loption=options.split(" ")[0]
-							try:
-								loption=int(loption)
-							except:
-								if loption=="":
-									loption=0
-							if type (loption)==int:
-								self.show_halloffame(channel,user,int(loption))
-							else:
-								self.nipmsg("PRE_Z Versuche #BOLD##CCHAR#place#BOLD# oder gib die Seitenzahl an.",channel)
-					
-					elif command=="favorits":
-						if len(self.fav.player)>0:
-								loption=options.split(" ")[0]
-								if loption:
-									user=loption
-								favOut=user+"#BOLD# <-#BOLD#"
-								favlist=self.fav.getlist(user)
-								if favlist:
-									for player,val in self.fav.getlist(user):
-										favOut+="#DGREY#("+player+":#NORM#"+str(val*3)+"#DGREY#)" #
-									self.nipmsg("PRE_Z"+favOut,channel)
-								else:
-									self.nipmsg("PRE_ZNOP",channel)
+		elif command=="scores":
+			pointlen=0
+			if len(self.allscore):
+				pointlen=len(str(max(self.allscore.values())))
+			if self.scoreLimit==0:
+				addtxt="(Ohne Scorelimit)"
+			else:
+				addtxt="(Spielende beim Erreichen von "+str(self.scoreLimit)+" Punkten)"
+			SCOREHEAD="#UNDERLINE#_-=Punkteverteilung=-"+self.create_ws(pointlen-1+self.maxnicklen-12)+"_#UNDERLINE##DGREY#"+" Runde:"+str(self.roundofgame)+"  "+addtxt
+			self.nipmsg("PRE_S"+SCOREHEAD, channel)
+			if len(self.allscore):
+				points=self.allscore.values()
+				points.sort()
+				points.reverse()
+				players=self.allscore.keys()
+				for point in points:
+					for player in players:
+						if self.allscore[player]==point:
+							pword="Punkte"
+							if point==1:
+								pword="Punkt"
+							splayer=player+self.create_ws(self.maxnicklen)
+							#spoints=str(point)+self.create_ws(12+len(str(point)))[:pointlen]
+							spoints=str(point)+self.create_ws(pointlen-len(str(point)))
+							self.nipmsg("PRE_S"+splayer[:self.maxnicklen]+"  "+spoints+ " "+pword, channel)
+							players.remove(player)
+							break; #
 
+		elif command=="rules":
+		     self.nipmsg("PRE_H"+self.NIPRULES, channel)
 
+		elif command=="status":
+			result=self.game_status(channel)
+			if self.gamechannel!=channel and self.gamechannel!="":
+				self.nipmsg("PRE_GEs wird bereits gespielt! #BOLD#/join "+self.gamechannel, channel)
+			if self.gamechannel==channel or self.gamechannel=="":
+				self.nipmsg("PRE_G"+result,  channel)
+
+		elif command=="place":
+			self.show_user_in_halloffame(channel,user,options)
+
+		elif command=="halloffame":
+			if self.hof==None:
+				self.bot.logger.error("HoF empty, file permissions? Maybe it is just new.")
+			else:
+				loption=options.split(" ")[0]
+				try:
+					loption=int(loption)
+				except:
+					if loption=="":
+						loption=0
+				if type (loption)==int:
+					self.show_halloffame(channel,user,int(loption))
+				else:
+					self.nipmsg("PRE_Z Versuche #BOLD##CCHAR#place#BOLD# oder gib die Seitenzahl an.",channel)
+
+		elif command=="favorits":
+			if len(self.fav.player)>0:
+					loption=options.split(" ")[0]
+					if loption:
+						user=loption
+					favOut=user+"#BOLD# <-#BOLD#"
+					favlist=self.fav.getlist(user)
+					if favlist:
+						for player,val in self.fav.getlist(user):
+							favOut+="#DGREY#("+player+":#NORM#"+str(val*3)+"#DGREY#)" #
+						self.nipmsg("PRE_Z"+favOut,channel)
+					else:
+						self.nipmsg("PRE_ZNOP",channel)
+
+
 	def show_halloffame(self, channel, user, pagekey=None):
 		pointlen=len(str(self.hof[0][1])) # for building the length in formatted output
 		expand=""
@@ -1444,21 +1452,16 @@
 	def joined(self, channel):
 		#so check self.gamechannel on !start
 		#on join will throw this msg all confed channels
-		if self.check_channel(channel,None):
+		if self.check_channel(channel,  None):
 			self.nipmsg("PRE_HDave, moechtest du mit mir hier im "+channel+" spielen? #CCHAR#startgame",channel)
 
 
 	def userJoined(self, user, channel):
 		user=user.split("!")[0]
-		if not user in self.players and user!=self.gamemaster:
-			statusinfo=self.game_status(channel, user)
-			if self.gamechannel==channel:
-				self.bot.notice(user, "Hi,"+user+"! "+statusinfo)
-			else:
-				if self.gamechannel!="":
-					self.bot.notice(user, "Hi,"+user+"! /join "+self.gamechannel+" fuer eine Runde NIP!")
-				else:
-					self.bot.notice(user, "Hi,"+user+"! "+statusinfo)
+		#if not user in self.players and user!=self.gamemaster:
+		statusinfo=self.game_status(channel, user)
+		if self.gamechannel==channel:
+			self.bot.notice(user, "Hi,"+user+"! "+statusinfo)
 
 	def game_status(self, channel=None, player=None):
 		#set and return them to user just on request. notice on join, or command status (translation in mind)
@@ -1467,6 +1470,7 @@
 		stat=""
 		nt=""
 		ujoin=""
+		#print player,self.gameadmin,self.gamemaster
 		status=self.phase
 		if player in self.players:
 			uadd=" Du bist noch dabei."
@@ -1474,21 +1478,21 @@
 			uadd=" Du bist "+self.TGAMEMASTER
 		if self.gameadmin==player:
 			uadd=" Du bist "+self.TGAMEADMIN
-		if self.gameadmin==player and self.gameadmin==player:
+		if self.gameadmin==player and self.gamemaster==player:
 			uadd=" Du bist "+self.TGAMEADMIN+" und "+self.TGAMEMASTER
 		if self.gl_ts >= 1:
 			nt="#DGREY# Noch ~"+str(self.gl_ts)+" Sek."
 		else:
 			nt="#DGREY# ~~~" #no timeouts running
-		if len(uadd)==0:
+		if len(uadd)==0 and player not in self.players and player!=self.gamemaster:
 			ujoin="Zum Mitspielen #CCHAR#join."
-		if status==NO_GAME and not channel in self.channels:
-				c=""
-				for c in self.channels:
-					c=c+" "
-				stat="Es laeuft kein NIP.#CCHAR#startgame in "+str(c)+" moeglich"
-				ustat=stat
-		elif status==NO_GAME:
+		#if status==NO_GAME and not channel in self.channels:
+		#		c=""
+		#		for c in self.channels:
+		#			c=c+" "
+		#		stat="Es laeuft kein NIP.#CCHAR#startgame in "+str(c)+" moeglich"
+		#		ustat=stat
+		if status==NO_GAME:
 			stat="Es laeuft kein NIP. #BOLD##CCHAR#startgame#BOLD# startet ein Neues."
 			ustat=stat
 			stat=stat+nt
@@ -1514,8 +1518,10 @@
 		elif status==GAME_WAITING:
 			astat=""
 			if self.gameadmin=="":
-				astat=" #BOLD##CCHAR#restartgame sollte helfen.#BOLD#"
-			stat="NIP pausiert."+astat+" Mitspielen einfach mit #BOLD##CCHAR#join#BOLD#"
+				astat=" #BOLD##CCHAR#restartgame#BOLD# hilft!"
+			stat="NIP pausiert."+astat
+			if not player in self.players and player!=self.gamemaster:
+				stat=stat+" Mitspielen einfach mit #BOLD##CCHAR#join#BOLD#"
 			ustat=stat
 			stat=stat+nt
 		rv=""
@@ -1529,112 +1535,112 @@
 			rv=ustat
 		else:
 			rv=stat
-	
 		return rv
 	
-	
-	def msg(self, user, channel, msg):
+	def query(self, user, channel, msg):
+		#self.msg(user, channel, msg)
 		msg=msg.replace("%","")
 		user=user.split("!")[0]
-		if channel == self.bot.nickname:
-			if self.phase==WAITING_FOR_QUESTION and user==self.gamemaster:
-				self.question=msg
-				self.bot.sendmsg(user, "Und jetzt die richtige Antwort")
-				self.phase=WAITING_FOR_QUIZMASTER_ANSWER
-				self.nTimerset(self.gl_ts+24, "end_of_quiz") # we got the question, so the player is alive - give him again a little bit more time
+		if self.phase==WAITING_FOR_QUESTION and user==self.gamemaster:
+			self.question=msg
+			self.bot.sendmsg(user, "Und jetzt die richtige Antwort")
+			self.phase=WAITING_FOR_QUIZMASTER_ANSWER
+			self.nTimerset(self.gl_ts+24, "end_of_quiz") # we got the question, so the player is alive - give him again a little bit more time
+		elif self.phase==WAITING_FOR_QUIZMASTER_ANSWER and user==self.gamemaster:
+			self.answers[user]=msg
+			self.nTimerset('ANSWER_TIME', "end_of_answertime")
+			self.nipmsg("PRE_Q"+self.TNIPQUESTION+" ist: #BOLD#"+self.question)
+			self.nipmsg("PRE_ASchickt mir eure #BOLD#\"falschen\"#BOLD# Antworten! ~"+str(self.gl_ts)+" Sek. Zeit! #DGREY#  (/msg "+self.bot.nickname+" eure Antwort)")
+			self.phase=WAITING_FOR_ANSWERS
+			#remove gamemaster from game, because he knows the answer
+			if self.gamemaster in self.players: #sometimes he is not in before 
+			   self.players.remove(self.gamemaster)
+			
+			self.bot.sendmsg(self.gamemaster, "Zusatzinformation zur Frage einfach hinterschicken oder weglassen") #
+			self.bot.logger.debug("Sent an additional info (tip) request.")
 
-			elif self.phase==WAITING_FOR_QUIZMASTER_ANSWER and user==self.gamemaster:
+		elif (self.phase==WAITING_FOR_ANSWERS or self.phase==QUIZ) and user==self.gamemaster and not self.additional_info:
+			self.additional_info=msg
+
+		elif self.phase==WAITING_FOR_ANSWERS and not user in self.answers and user in self.players:
+			if msg[0]!=self.cchar: # we understand some commands in query now 
 				self.answers[user]=msg
-				self.nTimerset('ANSWER_TIME', "end_of_answertime")
-				self.nipmsg("PRE_Q"+self.TNIPQUESTION+" ist: #BOLD#"+self.question)
-				self.nipmsg("PRE_ASchickt mir eure #BOLD#\"falschen\"#BOLD# Antworten! ~"+str(self.gl_ts)+" Sek. Zeit! #DGREY#  (/msg "+self.bot.nickname+" eure Antwort)")
-				self.phase=WAITING_FOR_ANSWERS
+				if len(self.answers) == len(self.players)+1: #+gamemaster
+					self.end_of_answertime()
 
-				#remove gamemaster from game, because he knows the answer
-				if self.gamemaster in self.players: #sometimes he is not in before 
-				   self.players.remove(self.gamemaster)
-				
-				self.bot.sendmsg(self.gamemaster, "Zusatzinformation zur Frage einfach hinterschicken oder weglassen") #
-				self.bot.logger.debug("Sent an additional info (tip) request.")
-				
-
-			elif (self.phase==WAITING_FOR_ANSWERS or self.phase==QUIZ) and user==self.gamemaster and not self.additional_info:
-				self.additional_info=msg
-
-			elif self.phase==WAITING_FOR_ANSWERS and not user in self.answers and user in self.players:
-				if msg[0]!="!": # we understand some commands in query now oO
-					self.answers[user]=msg
-					if len(self.answers) == len(self.players)+1: #+gamemaster
-						self.end_of_answertime()
-		else:
-			#if string.lower(msg)[:3]=="ich" and self.phase==WAITING_FOR_PLAYERS:
-			if self.gamechannel==channel:
-				if self.phase==WAITING_FOR_PLAYERS and user!=self.bot.nickname: #add player with "ich" in first 42characters while startphase
-					if len(string.lower(msg).split("ich")[:42]) > 1: # parses *ich* just do that on WAITING_FOR_PLAYERS (startphase)
-						if len(string.lower(msg).split("nicht")[:24]) > 1: #yag
-							if not user in self.players:
-								self.nipmsg("PRE_H/kick "+user)
-							else:
-								self.nipmsg("PRE_H"+user+": Wer nicht will hat schon ;-)")
-								self.players.remove(user)
+	def msg(self, user, channel, msg):
+		msg=msg.replace("%","")
+		user=user.split("!")[0]
+		#self.bot.logger.debug("user="+user+"channel="+channel+" "+self.bot.nickname)
+		if self.gamechannel==channel:
+			if self.phase==WAITING_FOR_PLAYERS and user!=self.bot.nickname: #add player with "ich" in first 42characters while startphase
+				if len(string.lower(msg).split("ich")[:42]) > 1: # parses *ich* just do that on WAITING_FOR_PLAYERS (startphase)
+					if len(string.lower(msg).split("nicht")[:24]) > 1: #yag
+						if not user in self.players:
+							self.nipmsg("PRE_H/kick "+user)
 						else:
-							#if string.lower(msg)[:3]=="ich": 
-							if not (user in self.players or user==self.gamemaster):
-								if self.check_maxplayer():
-								#self.players.append(user[:12]) #max len of nick maybe dyn in future
-									self.add_player(user)
-									text=""
-									for item in self.players:
-										text=text+item+", "
-									text=text[:-2]+"."
-								self.show_players()
-				elif self.phase==QUIZ and user in self.players and not user in self.guessed and user!=self.gamemaster and user!=self.gamemasterold:
-					try:
-						gmaster=self.gamemaster
-						if gmaster=="":
-							gmaster=self.gamemasterold
-						if(self.answeruser[int(msg)]==gmaster):
-							if user in self.score:
-								#self.score[user]=self.score[user]+1
-								self.score[user]+=1 #shorter ;)
-								if self.splitpoints:
-									self.scores[user]=self.scores[user]+(" +1*") #
-							else:
-								self.score[user]=1
-								if self.splitpoints:
-									self.scores[user]="+1*"
+							self.nipmsg("PRE_H"+user+": Wer nicht will hat schon ;-)")
+							self.players.remove(user)
+					else:
+						#if string.lower(msg)[:3]=="ich": 
+						if not (user in self.players or user==self.gamemaster):
+							if self.check_maxplayer():
+							#self.players.append(user[:12]) #max len of nick maybe dyn in future
+								self.add_player(user)
+								text=""
+								for item in self.players:
+									text=text+item+", "
+								text=text[:-2]+"."
+							self.show_players()
+			elif self.phase==QUIZ and user in self.players and not user in self.guessed and user!=self.gamemaster and user!=self.gamemasterold:
+				#okay user is still there
+				self.set_warn_cnt(user, True)
+				try:
+					gmaster=self.gamemaster
+					if gmaster=="":
+						gmaster=self.gamemasterold
+					if(self.answeruser[int(msg)]==gmaster):
+						if user in self.score:
+							#self.score[user]=self.score[user]+1
+							self.score[user]+=1 #shorter ;)
+							if self.splitpoints:
+								self.scores[user]=self.scores[user]+(" +1*") #
+						else:
+							self.score[user]=1
+							if self.splitpoints:
+								self.scores[user]="+1*"
 
-						elif(self.answeruser[int(msg)]==user):
-							#to select the own answer gives 0 points
-							pass
+					elif(self.answeruser[int(msg)]==user):
+						#to select the own answer gives 0 points
+						pass
+					else:
+						if(self.answeruser[int(msg)] in self.score):
+							#self.score[self.answeruser[int(msg)]]=self.score[self.answeruser[int(msg)]]+3
+							self.score[self.answeruser[int(msg)]]+=3 #shorter oO
+							#Favorits
+							player=self.answeruser[int(msg)]#put that in .add oO
+							self.fav.add(player, user)
+							self.fav.sort(player)
+							
+							if self.splitpoints:
+								self.scores[self.answeruser[int(msg)]]=self.scores[self.answeruser[int(msg)]]+" 3<-"+user #
 						else:
-							if(self.answeruser[int(msg)] in self.score):
-								#self.score[self.answeruser[int(msg)]]=self.score[self.answeruser[int(msg)]]+3
-								self.score[self.answeruser[int(msg)]]+=3 #shorter oO
-								#Favorits
-								player=self.answeruser[int(msg)]#put that in .add oO
-								self.fav.add(player, user)
-								self.fav.sort(player)
-								
-								if self.splitpoints:
-									self.scores[self.answeruser[int(msg)]]=self.scores[self.answeruser[int(msg)]]+" 3<-"+user #
-							else:
-								self.score[self.answeruser[int(msg)]]=3
-								#Favorits
-								player=self.answeruser[int(msg)]
-								self.fav.add(player, user)
-								self.fav.sort(player)
-								
-								if self.splitpoints:
-									self.scores[self.answeruser[int(msg)]]=" 3<-"+user
-						self.guessed.append(user)
-					#except ValueError:
-					except: #trying to catch all
-						pass
-					if len(self.guessed) == len(self.players):
-						self.end_of_quiz()
-
-	def nip_hof(self,hofdataf,action):
+							self.score[self.answeruser[int(msg)]]=3
+							#Favorits
+							player=self.answeruser[int(msg)]
+							self.fav.add(player, user)
+							self.fav.sort(player)
+							
+							if self.splitpoints:
+								self.scores[self.answeruser[int(msg)]]=" 3<-"+user
+					self.guessed.append(user)
+				#except ValueError:
+				except: #trying to catch all
+					pass
+				if len(self.guessed) == len(self.players):
+					self.end_of_quiz()
+##########################
+	def nip_hof(self, hofdataf, action):
 		self.bot.logger.debug("HoF data "+action)
 		if action=="read":
 			try:
@@ -1648,7 +1654,7 @@
 					if len(line) > 1:
 						pair=line.split("=",1)
 						thof[pair[0]]=int(pair[1])
-						hof.append("") #is there a better way to "dim" a list?
+						hof.append("") 
 						cnt+=1
 				pairs = sorted((key,value) for (value,key) in thof.iteritems())
 				hcnt=len(pairs)-1 
@@ -1658,29 +1664,29 @@
 				self.bot.logger.debug("HoF filled")
 				return hof #better way to sort a list from dict?
 	
-			except IOError:
-				self.bot.logger.error("Could not open HoF Data "+hofdataf)
+			except:
+				self.bot.logger.error(str(sys.exc_info()[1]))
 				try:
 					self.bot.logger.debug("Creating "+hofdataf)
-					if (not os.path.isdir(os.path.dirname(hofdataf))):
-						os.makedirs(os.path.dirname(hofdataf))
+
 					hofFile = open(hofdataf, "w")
 					hofFile.close()
 					self.bot.logger.debug("File created "+hofdataf)
-				except IOError:
-					self.bot.logger.error("Could not create "+hofdataf+str(IOError))
+				except:
+					self.bot.logger.error(str(sys.exc_info()[1]))
 	
 		self.bot.logger.debug("HoF Data ready to use")
 		if action=="write":
 			self.bot.logger.debug("Writing HOF to file "+hofdataf)
 			#ts=time.strftime('%Y%m%d_%S%M%H')
 			ts=time.strftime('%Y%m%d_%H%M%S')
-			bfile=hofdataf+"."+ts
+			#bfile=hofdataf+"."+ts
+			bfile=self.nipdatadir+path_archiv+"/"+hofdata+"."+ts
 			self.bot.logger.info("Creating HoF backup "+bfile)
 			try:
 				shutil.copyfile(hofdataf, bfile)
 			except:
-				self.bot.logger.error("Couldn't create "+bfile+" "+str(IOError))	
+				self.bot.logger.error(str(sys.exc_info()[1]))
 			try:
 				hofFile=open(hofdataf, "w")
 				cnt=0
@@ -1691,8 +1697,8 @@
 						break
 						hofFile.close()
 				hofFile.close()
-			except IOerror:
-				self.bot.logger.debug("Could not open or write to "+hofdataf)
+			except:
+				self.bot.logger.error(str(sys.exc_info()[1]))
 
 	################################################################
 	
@@ -1740,28 +1746,28 @@
 		if len(self.allscore.values()) > 0: #no need to save empty scoretable
 			self.bot.logger.debug("Saving score table")
 			ts=time.strftime('%Y%m%d_%H%M%S')
-			scorefile=self.nipdatadir+"NIPScore."+ts
+			scorefile=self.nipdatadir+path_archiv+"/"+scoredata+"."+ts
 			try:
 				sf=open(scorefile, "w")
 				sf.write("GameStartTime="+str(self.starttime)+"\nGameStopTime="+str(time.strftime('%Y/%m/%d %H:%M:%S'))+"\nNo. of Rounds="+str(self.roundofgame)+"\n")
 				for key, value in self.allscore.items():
 					sf.write(str(key)+"="+str(value)+"\n")
 				sf.close()
-			except IOError:
-				self.bot.logger.error("IOError on "+scorefile)
+			except:
+				self.bot.logger.error(str(sys.exc_info()[1]))
 			finally:
 				sf.close()
 		else:
-			self.bot.logger.debug("Did not store empty scoretable")
+			self.bot.logger.debug("Didn't store an empty scoretable")
 		if self.data_update_needed or force:
-				scorefile=self.nipdatadir+"NIPactScoreTable"
+				scorefile=self.nipdatadir+scoredata
 				self.bot.logger.debug("Saving "+scorefile+" update_need:"+str(self.data_update_needed)+" Force:"+str(force))
 				try:
 					sf=open(scorefile, "w")
 					pickle.dump(self.allscore, sf)
 					sf.close()
-				except IOError:
-					self.bot.logger.error("IOError on "+scorefile)
+				except:
+					self.bot.logger.error(str(sys.exc_info()[1]))
 				finally:
 					sf.close()
 		else:
@@ -1769,10 +1775,50 @@
 
 
 	def load_score(self):
-		scorefile=self.nipdatadir+"NIPactScoreTable"
+		scorefile=self.nipdatadir+scoredata
 		try:
 			sf=open(scorefile, "r")
 			self.allscore=pickle.load(sf)
 			sf.close()
-		except IOError:
-			self.bot.logger.error("IOError on "+scorefile)
\ No newline at end of file
+		except:
+			self.bot.logger.error(str(sys.exc_info()[1]))
+
+	def userRenamed(self, oldname, newname):
+		#check this for sideeffects, should work ingame
+		if not self.phase==NO_GAME:
+			if string.lower(newname)[:6]=='nobody':
+				self.nipmsg("PRE_P"+ newname+": Dieser Nick ist nicht erlaubt.")
+				self.bot.notice(newname,"Nenne dich wieder \""+oldname+"\", sonst wirst du aus dem Spiel entfernt.")
+				return 0
+			self.bot.logger.debug(oldname+" renamed to "+newname)
+			c=0
+			if oldname==self.gamemaster:
+				self.gamemaster=newname
+				c=1
+			if oldname==self.gamemasterold:
+				self.gamemasterold=newname
+				c=1
+			if oldname==self.gameadmin:
+				self.gameadmin=newname
+				c=1
+			if oldname in self.players:
+				c=1
+				ncnt=0
+				for names in self.players:
+					if names==oldname:
+						self.players[ncnt]=newname
+					ncnt+=1
+			if oldname in self.newplayers:
+				c=1
+				ncnt=0
+				for names in self.newplayers:
+					if names==oldname:
+						self.newplayers[ncnt]=newname
+					ncnt+=1
+			if oldname in self.allscore.keys():
+				points=self.allscore.pop(oldname,0)
+				self.allscore[newname]=points
+			self.NIPbuffer.replace_user(oldname,newname)
+			if c:
+				self.nipmsg("PRE_P"+ oldname+" ist mir nun bekannt als "+newname)
+				self.bot.notice(newname,"Bitte beachte, dass \""+newname+"\" am Ende des Spiels in die \"Hall of Fame\" geschrieben wird!")
\ No newline at end of file

Added: contrib/nobodyisperfectMod.yaml
===================================================================
--- contrib/nobodyisperfectMod.yaml	2008-10-29 19:51:50 UTC (rev 481)
+++ contrib/nobodyisperfectMod.yaml	2008-11-01 19:13:57 UTC (rev 482)
@@ -0,0 +1,12 @@
+NIP.AutoremovePlayerAfterRounds: '2'
+NIP.NameGameAdmin: '#BOLD#NIP-Admin#BOLD#'
+NIP.NameGameMaster: '#BOLD#QUIZ-Meister#BOLD#'
+NIP.NameNipQuestion: '#BOLD##DBLUE#NIP-Frage#NORM#'
+NIP.NameNipWarnings: 'Verteilung der#BOLD# #DRED#Schnarchnasenorden#NORM#:'
+NIP.Nobody: 'False'
+NIP.RULES: 'http://otf-chat.xenim.de/wiki/games:nobody-is-perfect'
+NIP.ScoreLimit: '0'
+NIP.TimeOutBase: '60'
+NIP.maxNickLength: '14'
+NIP.maxPlayer: '12'
+NIP.minPlayer: '5'




Mehr Informationen über die Mailingliste Otfbot-dev