Ejemplo n.º 1
0
class helper(ConsolePlugin):
	VERSION = "0.0.1"
	playerlist = []
	helperlist = []
	PHASE = 0
	CONFIG = None

	def onPluginLoad(self, config):
		
		self.ms = MasterServer ()
		self.CONFIG = config
		ini = ConfigParser.ConfigParser()
		ini.read(config)
		
		for (name, value) in ini.items('helpers'):
			self.helperlist.append({'name': name, 'level' : value})

		pass
		
	def reload_config(self):
		
        	self.helperlist = []
       		self.ipban = []
                ini = ConfigParser.ConfigParser()
                ini.read(self.CONFIG)

		for (name, value) in ini.items('helpers'):
			self.helperlist.append({'name': name, 'level' : value})

	def onStartServer(self, *args, **kwargs):
				
		self.playerlist = []

	def getPlayerByClientNum(self, cli):

		for client in self.playerlist:
			if (client['clinum'] == cli):
				return client

	def getPlayerByName(self, name):

		for client in self.playerlist:
			if (client['name'].lower() == name.lower()):
				return client

	def onConnect(self, *args, **kwargs):
		
		id = args[0]
		
		for client in self.playerlist:
			if (client['clinum'] == id):
				return
		
		self.playerlist.append ({'clinum' : id,\
					 'acctid' : 0,\
					 'name' : 'X',\
					 'active' : False,\
					 'helper' : False,\
					 'level' : 0})
	
	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client ['active'] = False

	def onSetName(self, *args, **kwargs):
		
		cli = args[0]
		playername = args[1]
		client = self.getPlayerByClientNum(cli)
		client ['name'] = playername
					
	def onAccountId(self, *args, **kwargs):

		cli = args[0]
		id = args[1]
		stats = self.ms.getStatistics (id).get ('all_stats').get (int(id))
		level = int(stats['level'])
		sf = int(stats['sf'])
					
		client = self.getPlayerByClientNum(cli)
		client['sf'] = sf
		client['level'] = level
		client['active'] = True
		client['helper'] = False

		if client['level'] <= 10:
			self.helperNotify(client, **kwargs)

		for each in self.helperlist:
			if client['name'].lower() == each['name']:
				client['helper'] = True

	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		self.PHASE = phase
		
		if (phase == 7):
			self.banlist = []	
			for each in self.playerlist:
				each['team'] = 0
				each['commander'] = False
					
		if (phase == 6):
			#fetch helper list and reload at the start of each game
			updatethread = threading.Thread(target=self.update, args=(), kwargs=kwargs)
			updatethread.start()	

	def update(self, **kwargs):
		
		response = urllib2.urlopen('http://188.40.92.72/helper.ini')
		helperlist = response.read()
			
		f = open(self.CONFIG, 'w')
		f.write(helperlist)
		f.close
		f.flush()
		os.fsync(f.fileno())
		self.reload_config()

	def helperNotify(self, client, **kwargs):
		
		activehelpers = []
		
		for player in self.playerlist:
			if player['helper'] and player['active']:
				activehelpers.append(player['name'])

		activestring = ', '.join(activehelpers)

		kwargs['Broadcast'].broadcast(\
		"SendMessage %s ^rATTENTION: ^cAs a new player it so good to get help from more experienced players. The following players on this server have \
		indicated their willingness to help newer players: ^y%s. ^cYou can contact them by using chat (^wCTRL+ENTER^c) and whispering them (^y/w playername^c with your message)."
			 % (client['clinum'], activestring))
			 
	def onListClients(self, *args, **kwargs):
		clinum = args[0]
		name = args[2]
		ip = args[1]
		
		
		client = self.getPlayerByName(name)
		if not client:
		#if a player is missing from the list this will put them as an active player
			acct = self.ms.getAccount(name)
			acctid = acct[name]
			self.onConnect(clinum, 0000, ip, 0000, **kwargs)
			self.onSetName(clinum, name, **kwargs)
			self.onAccountId(clinum, acctid, **kwargs)
Ejemplo n.º 2
0
class pug(ConsolePlugin):
	VERSION = "0.0.1"
	ms = None
	PHASE = 0
	STARTSTAMP = 0
	STARTED = False
	PICKING = False
	playerlist = []
	startinfo = {'h_captain' : None, 'h_ready' : False, 'h_first' : False, 'b_captain' : None, 'b_ready' : False, 'b_first' : False}
	TIME = 0
	
	def onPluginLoad(self, config):
		self.ms = MasterServer ()

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		'''
		for (name, value) in ini.items('var'):
			if (name == "clan1"):
				self.CLAN1 = value
			if (name == "clan2"):
				self.CLAN2 = value
		'''
		pass


	def onStartServer(self, *args, **kwargs):
		
		self.PHASE = 0
		self.playerlist = []
		self.startinfo = {'h_captain' : None, 'h_ready' : False, 'h_first' : False, 'b_captain' : None, 'b_ready' : False, 'b_first' : False}

	def getPlayerByClientNum(self, cli):

		for client in self.playerlist:
			if (client['clinum'] == cli):
				return client


	def getPlayerByName(self, name):

		for client in self.playerlist:
			if (client['name'].lower() == name.lower()):
				return client


	def onConnect(self, *args, **kwargs):
		
		id = args[0]
		ip = args[2]
		
		for client in self.playerlist:
			if (client['clinum'] == id):
				return
		
		self.playerlist.append ({'clinum' : id,\
					 'acctid' : 0,\
					 'level' : 0,\
					 'ip' : ip,\
					 'sf' : 0,\
					 'name' : 'X',\
					 'active' : False,\
					 'team' : 0,\
					 'ping' : 0,\
					 'clan' : 'X'})

		kwargs['Broadcast'].broadcast("SendMessage %s ^cTo toggle your PUG availability send the chat message ^rpug noplay" % (id))
		
	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client ['active'] = False
	
		if client['clinum'] == self.startinfo['h_captain']:
			self.startinfo['h_captain'] = None
			self.startinfo['h_ready'] = False
			kwargs['Broadcast'].broadcast("set State_Interrupted_EffectPath \"trigger UpdateDetail 1\"")
		if client['clinum'] == self.startinfo['b_captain']:
			self.startinfo['b_captain'] = None
			self.startinfo['b_ready'] = False
			kwargs['Broadcast'].broadcast("set Gadget_Hail_ModelPath \"trigger UpdateError 1\"")
			
	def onSetName(self, *args, **kwargs):

		cli = args[0]
		playername = args[1]
		client = self.getPlayerByClientNum(cli)
		client ['name'] = playername					
		client ['play'] = True

	def onAccountId(self, *args, **kwargs):

		cli = args[0]
		id = args[1]
		stats = self.ms.getStatistics (id).get ('all_stats').get (int(id))
		
		level = int(stats['level'])
		sf = int(stats['sf'])
		exp = int(stats['exp'])
		time = int(stats['secs'])
		time = time/60
		sf = int(exp/time)
		clan = stats['clan_tag']
		client = self.getPlayerByClientNum(cli)
		
		client ['acctid'] = int(id)
		client ['level'] = level
		client ['sf'] = sf
		client ['active'] = True
		client ['clan'] = clan
		client ['newteam'] = 0
		
		
	def onTeamChange (self, *args, **kwargs):

		team = int(args[1])
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client['team'] = team

	def onGameStart (self, *args, **kwargs):
		
		self.STARTSTAMP = args[1]

	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		self.PHASE = phase

		if phase == 5:
			self.STARTSTAMP = args[1]
			self.STARTED = True
		if phase == 6:
			self.PICKING = False
			self.STARTED = False
			self.startinfo = {'h_captain' : None, 'h_ready' : False, 'h_first' : False, 'b_captain' : None, 'b_ready' : False, 'b_first' : False}
			kwargs['Broadcast'].broadcast("set State_SuccessfulBlock_Description -1;\
							set State_Interrupted_EffectPath \"trigger UpdateDetail 1\";\
							set Gadget_Hail_ModelPath \"trigger UpdateError 1\";\
							set State_ImpPoisoned_Name \"trigger UpdateSpeed 1\";\
							set Gadget_Hail_Description \"trigger UpdatePercent -1\";\
							set State_ImpPoisoned_ExpiredEffectPath \"trigger UpdateExtraction 1\";\
							set maxteams 3;\
							set Pet_Shaman_Prerequisite 1;\
							set sv_setupTimeCommander 600000000;\
							Set sv_maxteamdifference 30;")
			kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"echo SCRIPT Client #GetScriptParam(clientid)# #GetScriptParam(what)# with value #GetScriptParam(value)#; echo\" scriptinput")
		if phase == 7:
			for each in self.playerlist:
				each['newteam'] = 0
	
	def onMessage(self, *args, **kwargs):
		
		name = args[1]
		message = args[2]
		
		client = self.getPlayerByName(name)
		
		noplay = re.match("pug noplay", message, flags=re.IGNORECASE)
		
		if noplay:
			self.togglePlay(client, **kwargs)
	
	def togglePlay(self, client, playing=None, **kwargs):
		color = '^g'
		if self.PICKING:
				kwargs['Broadcast'].broadcast("SendMessage %s ^rYou cannot toggle your status once picking has begun." % (client['clinum']))
				return
		if not playing:
			if client['play']:
				client['play'] = False
				color = '^r'
			else:
				client['play'] = True
		else:
			client['play'] = playing
			if not client['play']:
				color = '^r' 
		kwargs['Broadcast'].broadcast("SendMessage %s ^cYour Playing Status: %s%s" % (client['clinum'], color, client['play']))
	
	
	def onScriptEvent(self, *args, **kwargs):		
		
		caller = args[0]
		client = self.getPlayerByClientNum(caller)
		event = args[1]
		value = args[2]
		info = self.startinfo
		
		#Captain select
		if event == 'Captain':
			if caller == info['b_captain'] or caller == info['h_captain']:
				return
			if value == 'beasts':
				info['b_captain'] = caller
				kwargs['Broadcast'].broadcast("set Gadget_Hail_ModelPath \"trigger UpdateError 0\"; SendMessage -1 ^r%s^w is Captain of the Beasts!" % (client['name']))
				if not info['h_captain']:
					info['h_first'] = True
				else:
					self.beginpicking(**kwargs)
			if value == 'humans':
				info['h_captain'] = caller
				kwargs['Broadcast'].broadcast("set State_Interrupted_EffectPath \"trigger UpdateDetail 0\";  SendMessage -1 ^r%s^w is Captain of the Humans!" % (client['name']))
				if not info['b_captain']:
					info['b_first'] = True
				else:
		
					self.beginpicking(**kwargs)
			print info
			
		#Toggle player availability
		if event == 'Toggle':
			playing = False
			if value == 'true':
				playing = True

			self.togglePlay(client, playing, **kwargs)
			
		#Player select
		if event == 'Select':
			player = self.getPlayerByName(value)
			
			if caller == info['h_captain']:
				if not player['play']:
					kwargs['Broadcast'].broadcast("SendMessage %s ^rThat player has requested to not play in this match." % (client['clinum']))
					return
				player['newteam'] = 1
				client['newteam'] = 1
				kwargs['Broadcast'].broadcast("SendMessage -1 ^r%s^w has selected ^y%s ^wfor the Humans!" % (client['name'], player['name']))
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 1" % (player['clinum']))
				kwargs['Broadcast'].broadcast("set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\"" % (info['b_captain'], info['b_captain']))
				
			if caller == info['b_captain']:
				if not player['play']:
					kwargs['Broadcast'].broadcast("SendMessage %s ^rThat player has requested to not play in this match." % (client['name']))
					return
				player['newteam'] = 2
				client['newteam'] = 2
				kwargs['Broadcast'].broadcast("SendMessage -1 ^r%s^w has selected ^y%s ^wfor the Beasts!" % (client['name'], player['name']))
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 2" % (player['clinum']))
				kwargs['Broadcast'].broadcast("set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\"" % (info['h_captain'],info['h_captain'] ))
		#Ready
		if event == 'Ready':
			#TODO:only make the button do something if the minimum number of players are reached
			if self.STARTED:
				return
			if caller == info['h_captain']:
				info['h_ready'] = True
				kwargs['Broadcast'].broadcast("SendMessage -1 ^r%s^w has indicated that Humans are ready!" % (client['name']))
			if caller == info['b_captain']:
				info['b_ready'] = True
				kwargs['Broadcast'].broadcast("SendMessage -1 ^r%s^w has indicated that Beasts are ready!" % (client['name']))
			#Start the game if both captains say they are ready
			if info['h_ready'] and info['b_ready']:
				kwargs['Broadcast'].broadcast("set State_ImpPoisoned_Name \"trigger UpdateSpeed 0\"")
				self.populate(**kwargs)
				
	def beginpicking(self, **kwargs):
		self.PICKING = True
		#start by making the teams unjoinable: doesn't seem to work
		kwargs['Broadcast'].broadcast("set sv_maxteamdifference 1; set State_ImpPoisoned_ExpiredEffectPath \"trigger UpdateExtraction 0\";")
		#move everyone to spectator, but move captains to the appropriate team
		for each in self.playerlist:
			if each['active']:
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 0" % (each['clinum']))
			if each['clinum'] == self.startinfo['h_captain']:
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 1" % (each['clinum']))
			if each['clinum'] == self.startinfo['b_captain']:
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 2" % (each['clinum']))
		#Set variables to get the first captain to start picking
		if self.startinfo['h_first']:
			kwargs['Broadcast'].broadcast("set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\"" % (self.startinfo['h_captain'], self.startinfo['h_captain']))
		else:
			kwargs['Broadcast'].broadcast("set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\"" % (self.startinfo['b_captain'], self.startinfo['b_captain']))

	def populate(self, **kwargs):
	
		for each in self.playerlist:
			if each['active']:
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# %s" % (each['clinum'], each['newteam']))
		#Send to the next phase
		kwargs['Broadcast'].broadcast("NextPhase; set sv_setupTimeCommander 60000; PrevPhase")
		
	def onListClients(self, *args, **kwargs):
		clinum = args[0]
		name = args[2]
		ip = args[1]
		
		try:
			client = self.getPlayerByName(name)
		except:
		#if a player is missing from the list this will put them as an active player
			acct = self.ms.getAccount(name)
			acctid = acct[name]
			self.onConnect(clinum, 0000, ip, 0000, **kwargs)
			self.onSetName(clinum, name, **kwargs)
			self.onAccountId(clinum, acctid, **kwargs)
Ejemplo n.º 3
0
class sendstats(ConsolePlugin):
	base = None
	sent = None
	playerlist = []
	login = None
	lpass = None
	broadcast = 0
	serverid = 0
	loaded = False
	sending = False
	def onPluginLoad(self, config):
		self.ms = MasterServer ()
		ini = ConfigParser.ConfigParser()
		ini.read(config)

		for (name, value) in ini.items('paths'):
			if (name == "base"):
				self.base = value
			if (name == "sent"):
				self.sent = value
				
	def getPlayerByName(self, name):

		client = None

		for client in self.playerlist:
			if (client['name'].lower() == name.lower()):
				return client

	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		
		
		if not self.loaded:
			kwargs['Broadcast'].broadcast("echo SERVERVAR: svr_login is #svr_login#")
			kwargs['Broadcast'].broadcast("echo SERVERVAR: svr_pass is #svr_pass#")			
			kwargs['Broadcast'].broadcast("echo SERVERVAR: svr_broadcast is #svr_broadcast#")
			self.loaded = True
		#Everytime we start a game, start a new thread to send all the stats to eaxs' script, and replays to stony
		if (phase == 6):
						 
			uploadthread = thread.start_new_thread(self.uploadstats, ())
			#eventthread  = thread.start_new_thread(self.uploadevent, ())
			
		
	def uploadstats(self):
		print 'starting uploadstats'
		self.ss = StatsServers ()
		home  = os.environ['HOME']
		path = 	os.path.join(home, self.base)
		sentdir = os.path.join(home, self.sent)
		
		for infile in glob.glob( os.path.join(home, self.base,'*.stats') ):
			print "Sending stat file: " + infile
			statstring_raw = open(infile, 'r')
			datastat = statstring_raw.readlines()
			statstring = datastat[1]
			replayname = os.path.splitext(os.path.basename(infile))[0]
			try:
				replaysize = os.path.getsize(os.path.join(home, self.base, replayname+'.s2r'))
			except:
				replaysize = 100000

			statstring_replay = statstring + ("&file_name=%s.s2r&file_size=%s" % (replayname,replaysize))

			try:
				self.ss.s2gstats(statstring_replay)
	
			except Exception as e:
				print e.message
				print 'upload failed. no stats sent'				
				continue

			try:
				shutil.copy(infile,sentdir)
				os.remove(os.path.join(home, self.base, infile))
			except:
				continue

		#if not self.sending:
			#self.uploadreplay()
		
	def uploadevent(self):

		self.ss = StatsServers ()
		home  = os.environ['HOME']
		path = 	os.path.join(home, self.base)
		sentdir = os.path.join(home, self.sent)
		
		for infile in glob.glob( os.path.join(home, self.base,'*.event') ):
			match = os.path.splitext(os.path.basename(infile))[0]
			s2pfile = infile
			statstring = open(infile, 'r').read()
			decoded = urllib.quote(statstring)
			stats = ("event%s=%s" % (match,decoded))

			try:
				self.ss.s2pstats(stats)
	
			except:
				print 'upload failed. no stats sent'				
				return

			try:
				shutil.copy(infile,sentdir)
				os.remove(os.path.join(home, self.base, infile))
			except:
				continue
			
	def getServerVar(self, *args, **kwargs):
	
		var = args[0]
		
		if var == 'svr_login':
			self.login = args[1]

		if var == 'svr_pass':
			self.lpass = args[1]
			
		if var == 'svr_broadcast':
			self.broadcast = int(args[1])
		
		self.ms = MasterServer ()

		if self.broadcast > 0:
			server = self.ms.getServer(self.login, self.lpass, self.broadcast)
			self.serverid = server['svr_id']
			print self.serverid
			
	def uploadreplay(self):
		print 'starting uploadreplay'
		self.sending = True
		self.ss = StatsServers ()
		home  = os.environ['HOME']
		sentdir = os.path.join(home, self.sent)
		time.sleep(1)
		for infile in glob.glob( os.path.join(home, self.base,'*.s2r') ):
			print "Sending replay file: " + infile
			with open(infile, 'rb') as f:
				data = f.read()
				encoded = base64.b64decode(data)

			replay = {'id':infile, 'login':self.login, 'pass':self.lpass, 'content':encoded}
			replayjson = json.dumps(replay)
			
			try:
				self.ss.replays(replayjson)
				
			except:
				print 'upload failed. replay not sent'				
				continue

			print 'Sent replay'
			
			try:
				shutil.copy(infile,sentdir)
				os.remove(os.path.join(home, self.base, infile))
			except:
				continue
				
		self.sending = False
				
	def getPlayerByClientNum(self, cli):

		for client in self.playerlist:
			if (client['clinum'] == cli):
				return client

	def onConnect(self, *args, **kwargs):
		
		id = args[0]
		ip = args[2]

		self.playerlist.append ({'clinum' : id, 'acctid' : 0,'name' : 'X', 'ip' : ip})

	def onSetName(self, *args, **kwargs):
				
		cli = args[0]
		playername = args[1]

		client = self.getPlayerByClientNum(cli)
		client ['name'] = playername

	def onAccountId(self, *args, **kwargs):
		self.ss = StatsServers ()
		cli = args[0]
		id = args[1]
		client = self.getPlayerByClientNum(cli)
		client ['acctid'] = int(id)
		name = client ['name']
		ip = client['ip']
		server = self.serverid
		
		playerinfo = ("sync_user=1&username=%s&acc=%s&ip=%s&svr=%s" % (name, id, ip, server))
		
		#Send info to PS2	
		self.ss.salvagestats(playerinfo)
		
	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		
		acct = client['acctid']
		name = client['name']
		server = self.serverid
		
		playerinfo = ("sync_user=2&username=%s&acc=%s&svr=%s" % (name, id, server))
		#Send info to PS2	
		self.ss.salvagestats(playerinfo)
		
	def onListClients(self, *args, **kwargs):
		clinum = args[0]
		name = args[2]
		ip = args[1]
		
		client = self.getPlayerByName(name)
		if not client:
		#if a player is missing from the list this will put them as an active player
			acct = self.ms.getAccount(name)
			acctid = acct[name]
			self.onConnect(clinum, 0000, ip, 0000, **kwargs)
			self.onSetName(clinum, name, **kwargs)
			self.onAccountId(clinum, acctid, **kwargs)		
Ejemplo n.º 4
0
class admin(ConsolePlugin):
	VERSION = "1.6.4"
	playerlist = []
	adminlist = []
	banlist = []
	fullbanlist = []
	ipban = []
	itemlist = []
	PHASE = 0
	CONFIG = None
	UPDATE = True
	NEEDRELOAD = False
	LASTMESSAGE = {'client' : None, 'firsttime' : 0, 'lasttime' : 0, 'repeat' : 0}
	DLL = '2f4827b8'
	norunes = 0
	
	def onPluginLoad(self, config):
		
		self.ms = MasterServer ()
		self.CONFIG = config
		ini = ConfigParser.ConfigParser()
		banini = ConfigParser.ConfigParser ()
		banconfig = os.path.dirname(config) + "/ban.ini"
		banini.read (banconfig)
		ini.read(config)
		
		
		for (name, value) in ini.items('admin'):
			self.adminlist.append({'name': name, 'level' : value})
		for (name, value) in banini.items('ipban'):
			self.ipban.append(name)	
		
		
		pass
		
	def reload_config(self):
		
        	self.adminlist = []
       		self.ipban = []
                ini = ConfigParser.ConfigParser()
                ini.read(self.CONFIG)

		banini = ConfigParser.ConfigParser ()
		banconfig = os.path.dirname(self.CONFIG) + "/ban.ini"
		banini.read (banconfig)

                for (name, value) in ini.items('admin'):
                	self.adminlist.append({'name': name, 'level' : value})

                for (name, value) in banini.items('ban'):
                	self.fullbanlist.append({'name': name, 'level' : value})
                for (name, value) in banini.items('ipban'):
                	self.ipban.append(name)

	def reload_plugins(self):
	
		config = os.path.realpath(os.path.dirname (os.path.realpath (__file__)) + "/../s2wrapper.ini")
		
		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for name in ini.options('plugins'):
			if name == 'admin':
				PluginsManager.reload(name)
				continue
			if ini.getboolean('plugins', name):
				PluginsManager.reload(name)
			
	def onStartServer(self, *args, **kwargs):
		kwargs['Broadcast'].broadcast("Set norunes 0")
		kwargs['Broadcast'].broadcast("exec patch.cfg")
		self.playerlist = []
		self.banlist = []	

	def RegisterScripts(self, **kwargs):
		#any extra scripts that need to go in can be done here
		kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"echo SCRIPT Client #GetScriptParam(clientid)# #GetScriptParam(what)# with value #GetScriptParam(value)#; echo\" scriptinput")
		#these are for identifying bought and sold items
		kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"set _client #GetScriptParam(clientid)#; set _item #GetScriptParam(itemname)#; echo ITEM: Client #_client# SOLD #_item#; echo\" sellitem")
		if self.norunes == 1:
		
			kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"set _client #GetScriptParam(clientid)#; set _buyindex #GetIndexFromClientNum(|#_client|#)#;\
		 		set _none \"\"; set _item #GetScriptParam(itemname)#;\
		 		if #StringEquals(|#_item|#,|#_none|#)# TakeItem #_buyindex# #GetScriptParam(slot)#;\
		 		if #StringEquals(|#_item|#,|#_none|#)# SendMessage #GetScriptParam(clientid)# ^yYou cannot equip persistent items on this server;\
		 		echo ITEM: Client #_client# BOUGHT #_item#; echo\" buyitem")
		else:
			kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"set _client #GetScriptParam(clientid)#; set _item #GetScriptParam(itemname)#;\
				echo ITEM: Client #_client# BOUGHT #_item#; echo\" buyitem")
				
		kwargs['Broadcast'].broadcast("set con_showerr false; set con_showwarn false;")
		kwargs['Broadcast'].broadcast("Set Entity_NpcController_Name \"S2WRAPPER\"")
		#kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"set kid #GetScriptParam(clientid)#; set kcheck _karmaflag#kid#; if [kcheck > 0] clientexecscript clientdo #kid# cmd \\\"set voice_disabled true\\\"; echo\" spawn")
	def getPlayerByClientNum(self, cli):

		for client in self.playerlist:
			if (client['clinum'] == cli):
				return client
				
	def getPlayerByAcctId(self, acctid):
		for client in self.playerlist:
			if (client['acctid'] == acctid):
				return client

	def getPlayerByName(self, name):

		for client in self.playerlist:
			if (client['name'].lower() == name.lower()):
				return client

	def onConnect(self, *args, **kwargs):
		
		id = args[0]
		ip = args[2]
		
		for each in self.ipban:
			if each == ip:
				reason = "You are banned from this server."
				kwargs['Broadcast'].broadcast(\
 		"clientexecscript %s clientdo cmd \"SetSave host_onload true; SetSave host_created 1; WriteConfigScript ~/startup.cfg\"" % (id))
 				kwargs['Broadcast'].broadcast(\
 		"clientexecscript %s clientdo cmd \"quit\"" % (id))
				kwargs['Broadcast'].broadcast("kick %s \"%s\"" % (id, reason))
				return

		reason = "An administrator has removed you from this server. You may rejoin the server after the current game ends."
		
		for each in self.banlist:
			if each == ip:
				kwargs['Broadcast'].broadcast(\
					"Kick %s \"%s\"" % (id, reason))

		for client in self.playerlist:
			if (client['clinum'] == id):
				client['ip'] = ip
				return
		
		self.playerlist.append ({'clinum' : id,\
					 'acctid' : 0,\
					 'name' : 'X',\
					 'ip' : ip,\
					 'team' : 0,\
					 'sf' : 0,\
					 'active' : False,\
					 'level' : 0,\
					 'admin' : False,\
					 'value' : 0,\
					 'karma' : 0,\
					 'commander' : False,\
					 'req' : 0,\
					 'flood' : None,\
					 'f_req' : 0,\
					 'l_req' : 0,\
					 'msgsum' : None})
	
	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client ['active'] = False

	def onSetName(self, *args, **kwargs):
		
		cli = args[0]
		playername = args[1]
		if playername == "":
			reason = "You dont seem to have a name, thats odd."
			kwargs['Broadcast'].broadcast("kick %s \"%s\"" % (cli, reason))

		client = self.getPlayerByClientNum(cli)
		client ['name'] = playername

	def getAccountInfo(self, *args, **kwargs):
		client = self.getPlayerByClientNum(args[0])
		stats = self.ms.getStatistics (client['acctid']).get ('all_stats').get (client['acctid'])
		level = int(stats['level'])
		sf = int(stats['sf'])
		karma = int(stats['karma'])
					
		client['sf'] = sf
		client['level'] = level
		client['karma'] = karma
		client['active'] = True
		#kwargs['Broadcast'].broadcast(\
 		#"clientexecscript %s clientdo cmd \"set _vr #StringLength(|#GetCheckSum(cgame.dll)|#)#; if [_vr > 0] \\\"SendScriptInput what DLL value #getchecksum(cgame.dll)#\\\"; Else \\\"SendScriptInput what DLL value NONE\\\"\"" % (client['clinum']))
 		
 		if karma < 0:
 			kwargs['Broadcast'].broadcast(\
 			"set _karmaflag%s 1" % (client['clinum']))
 			
		#If client has disconnected, give them their gold back
		self.giveGold(False, client, **kwargs)
		

	def onAccountId(self, *args, **kwargs):
		cli = args[0]
		id = args[1]
		client = self.getPlayerByClientNum(cli)
		client['acctid'] = int(id)

		statthread = threading.Thread(target=self.getAccountInfo, args=(cli,None), kwargs=kwargs)
		statthread.start()
			
		if self.isBanned(client, **kwargs):
			kwargs['Broadcast'].broadcast(\
					"clientexecscript %s clientdo cmd \"SetSave cl_packetSendFPS 1\"" % (cli))
			
		if self.isAdmin(client, **kwargs):
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^cYou are registered as an administrator. Use ^radmin <command>^c to execute commands through chat.^c You can get help by sending ^radmin help ^cto chat." % (cli))
			client['admin'] = True
			
		if self.isSuperuser(client, **kwargs):
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^cYou are registered as superuser on this server. You can send console commands with chat message: ^rsudo <command>." % (cli))
	
						
	def isAdmin(self, client, **kwargs):
		admin = False
		
		for each in self.adminlist:
			if client['name'].lower() == each['name']:
				admin = True
		
		return admin

	def isSuperuser(self, client, **kwargs):
		superuser = False

		for each in self.adminlist:
			if client['name'].lower() == each['name']:
				if each['level'] == 'super':
					superuser = True
		
		return superuser

	def isBanned(self, client, **kwargs):
		banned = False

		for each in self.fullbanlist:
			if client['name'].lower() == each['name']:
				if each['level'] == 'banned':
					banned = True
		
		return banned

	def onMessage(self, *args, **kwargs):
		
		name = args[1]
		message = args[2]
		
		client = self.getPlayerByName(name)
		clinum = client['clinum']
		admin = self.isAdmin(client, **kwargs)
		superuser = self.isSuperuser(client, **kwargs)

		# ---
		# MORE THEN FLOOD REPEATS(3)=4 A SEC(1) = kick
		FLOOD_REPEATS = 2
		FLOOD_A_SEC = 0.5	

		if not client['flood']:
			client['flood'] = { 'time' : 0, 'count' : 0 }


		flood = client['flood']
		print "flood: %s - %f - %f = %f" % (flood['count'], time.time (), flood['time'], (time.time ()-flood['time']))

                # Sickened2: spam-check based on message length and checksum
                msglen = len(list(message))
                if msglen > 100:
                        # this should be a lookup table for checksums of typical spam messages
                        spam1chksum = "ec10ca635bb6b956959830f4e652369d"
                        m = hashlib.md5()
                        m.update(message[:100])
                        chksum = m.hexdigest()
                        if chksum == spam1chksum:
                                reason = "Attention! Spamming results in automatic kicking."
                                kwargs['Broadcast'].broadcast("Kick %s \"%s\"" % (clinum, reason))
                        elif not client['msgsum']:
                                client['msgsum'] = chksum
                                #print "Checksum"
                                #print client['msgsum']
                        elif client['msgsum'] == chksum:
                                reason = "Attention! Spamming results in automatic kicking."
                                kwargs['Broadcast'].broadcast("Kick %s \"%s\"" % (clinum, reason))
                        else:
                                client['msgsum'] = chksum

		# Sickened2: the following method is not as effective because
		# 1) for large messages (e.g. > 250 bytes) part of the message is returned. For the same message length the
		#    size could vary. So we can't use the message length reliably
		# 2) if 2 chat packets are sent to the server and the 1st one arrives with delay but in the correct order,
		#    the difference between the time of arrival between the two packets is shorter than the difference
		#    between the departure time of the two packets
                ## Sickened2: additional spam check; user is not capable of manually typing more than 
                ##            MAX_TYPING_SPEED characters per second (avg)
                #MAX_TYPING_SPEED = 212; # chars/sec
                #msglen = len(list(message))
                #print "msglen = %d" % msglen
                #timediff = time.time () - flood['time']
                #print "timediff = %f" % timediff
                ##print("len(list(message)) / timediff ={0}".format(len(list(message)) / timediff))
                #if msglen / timediff > MAX_TYPING_SPEED:
                #        reason = "Sigh. Spamming results in automatic kicking."
                #        kwargs['Broadcast'].broadcast("Kick %s \"%s\"" % (clinum, reason))

		if (time.time () - flood['time']) < FLOOD_A_SEC:

			flood['count'] += 1

			if flood['count'] > FLOOD_REPEATS:
				reason = "Spamming results in automatic kicking."
				kwargs['Broadcast'].broadcast("Kick %s \"%s\"" % (clinum, reason))

		else:
			flood['count'] = 0

		flood['time'] = time.time ()

		#ignore everything else if it isn't from admin
		if not admin:
			return

		if superuser:
			self.superCommand(message, **kwargs)
		
		#Matches for normal admins
		restart = re.match("admin restart", message, flags=re.IGNORECASE)
		shuffle = re.match("admin shuffle", message, flags=re.IGNORECASE)
		kick = re.match("admin kick (\S+)", message, flags=re.IGNORECASE)
		ban = re.match("admin ban (\S+)", message, flags=re.IGNORECASE)
		timeout = re.match("admin timeout (\S+)", message, flags=re.IGNORECASE)
		slap = re.match("admin slap (\S+)", message, flags=re.IGNORECASE)
		micoff = re.match("admin micoff (\S+)", message, flags=re.IGNORECASE)
		micon = re.match("admin micon (\S+)", message, flags=re.IGNORECASE)
		changeworld = re.match("admin changeworld (\S+)", message, flags=re.IGNORECASE)
		help = re.match("admin help", message, flags=re.IGNORECASE)
		balance = re.match("admin balance", message, flags=re.IGNORECASE)
		getbalance = re.match("admin get balance", message, flags=re.IGNORECASE)
		reportbal = re.match("admin report balance", message, flags=re.IGNORECASE)
		swap = re.match("admin swap (\S+)", message, flags=re.IGNORECASE)
		setteam = re.match("admin setteam (\S+) (\S+)", message, flags=re.IGNORECASE)

		if restart:
			#restarts server if something catastrophically bad has happened
			kwargs['Broadcast'].broadcast("restart")

		if shuffle:
			#artificial shuffle vote
			if self.PHASE != 5:
				kwargs['Broadcast'].broadcast(\
					"SendMessage %s Cannot shuffle until the game has started!"\
					 % (client['clinum']))
				return
			
			kwargs['Broadcast'].broadcast("SendMessage -1 %s has shuffled the game." % (name))
			self.listClients(**kwargs)	
			shufflethread = threading.Thread(target=self.onShuffle, args=(clinum,None), kwargs=kwargs)
			shufflethread.start()

		if kick:
			#kicks a player from the server
			reason = "An administrator has removed you from the server, probably for being annoying"
			kickclient = self.getPlayerByName(kick.group(1))
			kwargs['Broadcast'].broadcast(\
				"Kick %s \"%s\""\
				 % (kickclient['clinum'], reason))

		if timeout:
			reason = "An administrator has banned you from the server. You are banned till this game is over."
			kickclient = self.getPlayerByName(timeout.group(1))
			kwargs['Broadcast'].broadcast(\
				"Kick %s \"%s\"" \
				 % (kickclient['clinum'], reason))

			self.banlist.append(kickclient['ip'])

			
		if ban:
			#kicks a player from the server and temporarily bans that player's IP till the game is over
			reason = "An administrator has banned you from the server."
			kickclient = self.getPlayerByName(ban.group(1))
			kwargs['Broadcast'].broadcast(\
				"Kick %s \"%s\"" \
				 % (kickclient['clinum'], reason))

	                banini = ConfigParser.ConfigParser ()
	                banconfig = os.path.dirname(self.CONFIG) + "/ban.ini"
	                banini.read (banconfig)
			banini.set ('ipban', kickclient['ip'], kickclient['name'])
			banini.write (open(banconfig, 'wb'))
			self.ipban.append(kickclient['ip'])

		if slap:
			#slap will move a player x+100, y+200 to get them off of a structure
			if self.PHASE != 5:
				return
				
			slapclient = self.getPlayerByName(slap.group(1))
			kwargs['Broadcast'].broadcast(\
				"set _slapindex #GetIndexFromClientNum(%s)#;\
				 set _sx #GetPosX(|#_slapindex|#)#; set _sy #GetPosY(|#_slapindex|#)#; set _sz #GetPosZ(|#_slapindex|#)#;\
				 SetPosition #_slapindex# [_sx + 200] [_sy + 200] #_sz#;\
				 SendMessage %s ^cAn adminstrator has moved you for jumping on buildings. YOU WILL BE BANNED if this action persists"\
				 % (slapclient['clinum'], slapclient['clinum']))
		
		if micoff:
			#Turns off players mic with clientdo	
			offclient = self.getPlayerByName(micoff.group(1))
			kwargs['Broadcast'].broadcast("ClientExecScript %s clientdo cmd \"set voice_disabled true\"" % (offclient['clinum']))

		if micon:
			#Turns on players mic with clientdo	
			onclient = self.getPlayerByName(micon.group(1))
			kwargs['Broadcast'].broadcast("ClientExecScript %s clientdo cmd \"set voice_disabled false\"" % (onclient['clinum']))
			
		if changeworld:
			#change the map
			kwargs['Broadcast'].broadcast(\
				"changeworld %s"\
				 % (changeworld.group(1)))
				 
		if balance:
			if self.PHASE != 5:
				kwargs['Broadcast'].broadcast(\
					"SendMessage %s Cannot balance if the game has not started!"\
					 % (client['clinum']))
				return

			kwargs['Broadcast'].broadcast("SendMessage -1 %s has balanced the game." % (name))
			self.listClients(**kwargs)
			balancethread = threading.Thread(target=self.doBalance, args=(clinum,True,False), kwargs=kwargs)
			balancethread.start()
			

		if getbalance:
			self.listClients(**kwargs)
			balancethread = threading.Thread(target=self.doBalance, args=(clinum,False,False), kwargs=kwargs)
			balancethread.start()


		if reportbal:
			self.listClients(**kwargs)
			balancethread = threading.Thread(target=self.doBalance, args=(clinum,False,True), kwargs=kwargs)
			balancethread.start()

		if swap:
			#swap a player to a different team
			swapplayer = self.getPlayerByName(swap.group(1))
			newteam = 0
			team = swapplayer['team']
			if team == 1:
				newteam = 2
			if team == 2:
				newteam = 1
			if newteam == 0:
				return
			kwargs['Broadcast'].broadcast(\
				"SetTeam #GetIndexFromClientNum(%s)# %s"\
				 % (swapplayer['clinum'], newteam))
				 
		if setteam:
			#swap a player to x team
			setplayer = self.getPlayerByName(setteam.group(2))
			newteam = setteam.group(1)
			kwargs['Broadcast'].broadcast(\
				"SetTeam #GetIndexFromClientNum(%s)# %s"\
				 % (setplayer['clinum'], newteam))
				 
		self.logCommand(client['name'],message)

		if help:
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s All commands on the server are done through server chat. All commands are logged to prevent you from abusing them.The following are commands and a short description of what they do."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin restart ^whard reset of the server. ONLY use in weird cases."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin shuffle ^wwill shuffle the game and set to previous phase."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin kick playername ^wwill remove a player from the server."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin timeout playername ^wwill remove a player for one game."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin ban playername ^wwill remove a player from the server and ban that IP address permenantly."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin micoff playername ^wwill turn the players mic off. Use on mic spammers."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin micon playername ^wwill turn the players mic on."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin changeworld mapname ^wwill change the map to the desired map."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin swap playername ^wwill move a specific player to another team."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin balance ^wwill move two players to achieve balance."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin get balance ^wwill report avg. and median SF values for the teams as well as a stack value."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin report balance ^wwill send a message to ALL players that has the avg. and median SF values."\
				 % (client['clinum']))	
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin setteam x playername ^wwill set players team to x."\
				 % (client['clinum']))

	def superCommand(self, message, **kwargs):
		supercommand = re.match("sudo (.*)", str(message), flags=re.IGNORECASE)
		if supercommand:
			kwargs['Broadcast'].broadcast("%s" % (supercommand.group(1)))

	def doBalance(self, admin, doBalance=False, doReport=False, **kwargs):
		clinum = admin
		
		for each in self.playerlist:
			each['team'] = 0
			
		time.sleep(1)
		teamone = []
		teamtwo = []

		#populate current team lists:
		for each in self.playerlist:
			if not each['active']:
				continue
			if each['team'] == 1:
				teamone.append(each)
			if each['team'] == 2:
				teamtwo.append(each)
		
		teamonestats = self.getTeamInfo(teamone)
		teamtwostats = self.getTeamInfo(teamtwo)
		stack = round(self.evaluateBalance(teamone, teamtwo),1)
		startstack = abs(self.evaluateBalance(teamone, teamtwo))
		
		if doReport:
			kwargs['Broadcast'].broadcast(\
			"SendMessage -1 ^y Team One (%s players) Avg. SF is ^r%s^y median is ^r%s^y, Team Two (%s players) Avg. SF is ^r%s^y median is ^r%s.^y Stack value: ^r%s" \
		 	% (teamonestats['size'], round(teamonestats['avg'],1), round(teamonestats['median'],1), teamtwostats['size'], round(teamtwostats['avg'], 1), round(teamtwostats['median'],1), abs(stack)))	
		 	return
		 	
		kwargs['Broadcast'].broadcast(\
		"SendMessage %s ^y Team One (%s players) Avg. SF is ^r%s^y median is ^r%s^y, Team Two (%s players) Avg. SF is ^r%s^y median is ^r%s. ^yStack value: ^r%s" \
		 % (clinum, teamonestats['size'], round(teamonestats['avg'],1), round(teamonestats['median'],1), teamtwostats['size'], round(teamtwostats['avg'],1), round(teamtwostats['median'], 1), abs(stack)))	
		#Find the players to swap
		lowest = -1
		pick1 = None
		pick2 = None
		
		for player1 in teamone:
			if player1['commander']:
				continue
			for player2 in teamtwo:
				if player2['commander']:
					continue
				#sort of inefficient to send the teamlist each time				
				ltarget = abs(self.evaluateBalance(teamone, teamtwo, player1, player2, True))
				
				if (lowest < 0):
					lowest = ltarget
					pick1 = player1
					pick2 = player2
					continue
			
				if (lowest < ltarget):
					continue
			
				lowest = ltarget
				pick1 = player1
				pick2 = player2

		#If the stack isn't improved, abort it
		if (lowest >= startstack):
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^yUnproductive balance. No swapping scenario would improve the balance over its current state." % (admin))
			return
		
		kwargs['Broadcast'].broadcast(\
		"SendMessage %s ^y Balance will swap ^r%s ^yand ^r%s" \
		 % (clinum, pick1['name'], pick2['name']))
		
		if not doBalance:
			index1 = map(itemgetter('clinum'), teamone).index(pick1['clinum'])
			index2 = map(itemgetter('clinum'), teamtwo).index(pick2['clinum'])
		
			teamone[index1]['team'] = 2
			teamtwo[index2]['team'] = 1

			teamonestats = self.getTeamInfo(teamone)
			teamtwostats = self.getTeamInfo(teamtwo)
			stack = round(self.evaluateBalance(teamone, teamtwo),1)
			#kwargs['Broadcast'].broadcast(\
		#"SendMessage %s ^cProposed change: ^y Team One (%s players) Avg. SF: ^r%s^y median SF: ^r%s^y, Team Two (%s players) Avg. SF: ^r%s^y median SF: ^r%s. ^yStack value: ^r%s" \
		#% (clinum, teamonestats['size'], round(teamonestats['avg'],1), round(teamonestats['median'],1), teamtwostats['size'], round(teamtwostats['avg'],1), round(teamtwostats['median'], 1), abs(stack)))
		 	return
			
		if doBalance:
			#Do the switch
			kwargs['Broadcast'].broadcast(\
				"set _index #GetIndexFromClientNum(%s)#;\
			 	SetTeam #_index# 2;\
			 	set _index #GetIndexFromClientNum(%s)#;\
			 	SetTeam #_index# 1"\
			 	% (pick1['clinum'], pick2['clinum']))
		
			#Give them gold if needed
			self.giveGold(True, pick1, **kwargs)
			self.giveGold(True, pick2, **kwargs)

			teamonestats = self.getTeamInfo(teamone)
			teamtwostats = self.getTeamInfo(teamtwo)
			kwargs['Broadcast'].broadcast(\
			"SendMessage -1 ^yAfter balance: Team One Avg. SF was ^r%s^y median was ^r%s^y, Team Two Avg. SF was ^r%s^y median was ^r%s"\
			 % (teamonestats['avg'], teamonestats['median'], teamtwostats['avg'], teamtwostats['median']))
	 				 
	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		self.PHASE = phase
		kwargs['Broadcast'].broadcast("echo SERVERVAR: norunes is #norunes#")
		
		if (phase == 7):
			self.banlist = []	
			for each in self.playerlist:
				each['team'] = 0
				each['commander'] = False
				each['value'] = 0
			
					
		if (phase == 6):
			
			if self.UPDATE:
			#fetch admin list and reload at the start of each game
				updatethread = threading.Thread(target=self.update, args=(), kwargs=kwargs)
				updatethread.start()	
			#check if server is empty after 2 minutes		
				pluginthread = threading.Thread(target=self.pluginreload, args=(), kwargs=kwargs)
				pluginthread.start()

			self.RegisterScripts(**kwargs)
			self.ItemList()

		if (phase == 4):
			kwargs['Broadcast'].broadcast("listclients")

	def update(self, **kwargs):
		response = urllib2.urlopen('http://188.40.92.72/admin.ini')
		adminlist = response.read()
		
		f = open(self.CONFIG, 'w')
		f.write(adminlist)
		f.close
		f.flush()
		os.fsync(f.fileno())
		self.reload_config()
		
			
		if self.NEEDRELOAD:
			self.pluginreload(**kwargs)
			return

		#Update the wrapper
		try:
			gitpath = os.path.realpath(os.path.dirname (os.path.realpath (__file__)) + "/../.git")
			command = ["git","--git-dir",gitpath,"pull"]
			output = subprocess.Popen(command, stdout=subprocess.PIPE).communicate()
			result = output[0].split("\n")[0]
			print 'result is %s' % result
			#TODO: make sure these work on all servers?
			notneeded = re.match("Already up-to-date.", result)
			needed = re.match("Updating .*", result)
		except:
			print 'error getting git update'
			return
		
		if notneeded:
			print 'update not needed'
			self.NEEDRELOAD = False
			return

		if needed:
			print 'update needed'
			self.NEEDRELOAD = True
			self.pluginreload(**kwargs)
			return

	def pluginreload(self, **kwargs):
		print 'pluginreload called'
		#Wait a couple minutes to allow clients to connect
		time.sleep(120)
		#Figure out how many clients are present
		kwargs['Broadcast'].broadcast("serverstatus")
	
	def onServerStatusResponse(self, *args, **kwargs):

		if self.NEEDRELOAD:
			gamemap = args[0]
			active = int(args[2])
			
			if active == 0:
				self.reload_plugins()
				kwargs['Broadcast'].broadcast("NextPhase; PrevPhase")
				self.NEEDRELOAD = False

	def logCommand(self, client, message, **kwargs):
		localtime = time.localtime(time.time())
		date = ("%s-%s-%s, %s:%s:%s" % (localtime[1], localtime[2], localtime[0], localtime[3], localtime[4], localtime[5]))
		f = open('admin.log', 'a')		
		f.write("Timestamp: \"%s\", Admin: %s, Command: %s\n" % (date, client, message))
		f.close

	def onTeamChange (self, *args, **kwargs):
		
		team = int(args[1])
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client['team'] = team

		self.requestTracker(cli, **kwargs)

	def onShuffle (self, *args, **kwargs):
		
		for each in self.playerlist:
			each['team'] = 0
			each['value'] = 0

		clinum = args[0]
		time.sleep(2)
		shufflelist = []

		#Put all the active players in a list
		for each in self.playerlist:
			if not each['active']:
				continue
			if each['team'] > 0:
				shufflelist.append(each)
	
		#sort shufflelists based on SF
		shufflelist = sorted(shufflelist, key=itemgetter('sf', 'level', 'clinum'), reverse=True)
		
		#randomly choose if we begin with human or beast
		r = random.randint(1,2)
		
		#Assign new teams, just like the K2 way, but Ino won't always be on humans
		for each in shufflelist:
		#TODO: is there a cleaner, more pythonic way to do this?	
			each['team'] = r
			if r == 1:
				r += 1
			elif r == 2:
				r -=1
			
		#Now actually do the shuffling
		for each in shufflelist:
			kwargs['Broadcast'].broadcast(\
				"SetTeam #GetIndexFromClientNum(%s)# %s"\
				 % (each['clinum'], each['team']))
		#Finish it off by going forward a phase
		kwargs['Broadcast'].broadcast(\
			"nextphase")
		
		
		kwargs['Broadcast'].broadcast(\
			"SendMessage %s You have shuffled the game." % (clinum))
		#Run balancer to get it nice and even
		#self.onBalance(clinum, **kwargs)
		kwargs['Broadcast'].broadcast("Startgame")
		
		
	def getTeamInfo(self, teamlist, **kwargs):
		
		teamsf = []
		combteamsf = float(0)		
		#figure out current averages and set some commonly used variables:
		for each in teamlist:
			combteamsf += each['sf']
			teamsf.append(each['sf'])
	
		sizeteam = len(teamlist)
		avgteam = combteamsf/sizeteam
		med = median(teamsf)
		
		teaminfo = {'size' : sizeteam, 'avg' : avgteam, 'total' : combteamsf, 'median' : med}
		
		return teaminfo

	def evaluateBalance(self, team1, team2, pick1=None, pick2=None, swap=False, **kwargs):
		#This function will swap out the picked players in a temporary list if swap is true and report the stack percent
		#If swap is false, it will just report the balance		
		#First, make new lists that we can modify:
		teamone = list(team1)
		teamtwo = list(team2)
		
		if swap:
			#Remove those players from the lists...		
			for each in teamone:
				if each['clinum'] == pick1['clinum']:
					teamone.remove(each) 
			for each in teamtwo:
				if each['clinum'] == pick2['clinum']:
					teamtwo.remove(each) 
		
			#Add to the lists		
			teamone.append(pick2)
			teamtwo.append(pick1)

		#Get the new team stats...
		teamonestats = self.getTeamInfo(teamone)
		teamtwostats = self.getTeamInfo(teamtwo)
		
		#Evaluate team balance
		teamoneshare = teamonestats['total']/(teamonestats['total'] + teamtwostats['total'])
		diffmedone = teamonestats['median']/(teamonestats['median'] + teamtwostats['median'])
		stack = teamoneshare + diffmedone
		#positive if team one is stacked, negative if team two is stacked
		return (stack - 1) * 100

	def onCommResign(self, *args, **kwargs):
	
		name = args[0]	
		client = self.getPlayerByName(name)
		client['commander'] = False
		
	
	def onUnitChange(self, *args, **kwargs):
	
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		self.requestTracker(cli, **kwargs)
		
		if args[1] != "Player_Commander":
			return

		client['commander'] = True
	
		

	def listClients(self, *args, **kwargs):

		kwargs['Broadcast'].broadcast("listclients")

	def onListClients(self, *args, **kwargs):
		clinum = int(args[0])
		name = args[2]
		ip = args[1]
		

		client = self.getPlayerByName(name)
		if not client:
		#if a player is missing from the list this will put them as an active player and get stats
		#usually used when reloading plugin during a game
			acct = self.ms.getAccount(name)
			acctid = acct[name]
			self.onConnect(clinum, 0000, ip, 0000, **kwargs)
			self.onSetName(clinum, name, **kwargs)
			self.onAccountId(clinum, acctid, **kwargs)
			client = self.getPlayerByName(name)
			
		client['active'] = True
		kwargs['Broadcast'].broadcast(\
		"echo CLIENT %s is on TEAM #GetTeam(|#GetIndexFromClientNum(%s)|#)#"\
		 % (client['clinum'], client['clinum']))
		
		
	def onRefreshTeams(self, *args, **kwargs):
		clinum = args[0]
		team = int(args[1])
		client = self.getPlayerByClientNum(clinum)
		client['team'] = team

	def ItemList(self, *args, **kwargs):
		
		self.itemlist = {
			'Advanced Sights' : 700,
			'Ammo Pack' : 500,
			'Ammo Satchel' : 200,
			'Chainmail' : 300,
			'Gust of Wind' : 450,
			'Magic Amplifier' : 700,
			'Brain of Maliken' : 750,
			'Heart of Maliken' : 950,
			'Lungs of Maliken' : 1000,
			'Mana Crystal' : 500,
			'Mana Stone' : 200,
			'Platemail' : 650,
			'Power Absorption' : 350,
			'Shield of Wisdom' : 650,
			'Stone Hide' : 650,
			'Tough Skin' : 300,
			'Trinket of Restoration' : 575
		}


	def onItemTransaction(self, *args, **kwargs):
		#adjust 'value' in playerlist to reflect what the player has bought or sold
		cli = args[0]
		trans = args[1]
		newitem = args[2]
		client = self.getPlayerByClientNum(cli)
		self.requestTracker(cli, **kwargs)
		
		try:
			value = self.itemlist[newitem]
		except:
			return
		
		if (trans == 'BOUGHT'):
			client['value'] += value
		elif (trans == 'SOLD'):
			client['value'] -= value
		
		

	def giveGold(self, balance, client, **kwargs):

		if client['value'] == 0:

			return
		
		gold = round(client['value']/2, 0)

		if balance:
			gold = client['value']

		kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^cYou have been compensated %s gold for your lost items.; GiveGold %s %s"\
			 % (client['clinum'], gold, client['clinum'], gold))
		
		client['value'] = 0

	def getMatchID(self, *args, **kwargs):
		matchid = args[0]
		kwargs['Broadcast'].broadcast("Set Entity_NpcController_Description %s" % (matchid))

	def onScriptEvent(self, *args, **kwargs):		
		
		caller = args[0]
		client = self.getPlayerByClientNum(caller)
		event = args[1]
		value = args[2]
		self.requestTracker(caller, **kwargs)
			
		if event == 'DLL':
			if value == 'NONE':
				return
			
			if value != self.DLL:
				
				banthread = threading.Thread(target=self.banclient, args=(caller, None), kwargs=kwargs)
				banthread.start()
			
				
	def banclient(self, *args, **kwargs):
		clinum = args[0]
		kwargs['Broadcast'].broadcast(\
				 "ClientExecScript %s clientdo cmd \"UICall game_options \\\"HTTPGetFile(\'http://masterserver.savage2.s2games.com/create.php?phrase=1\', \'~/null\');\\\"\"" % (clinum))

		time.sleep(1)

		kwargs['Broadcast'].broadcast(\
				 "ClientExecScript %s clientdo cmd \"quit\"" % (clinum))
		
	def getServerVar(self, *args, **kwargs):
		var = args[0]
		if var == 'norunes':
			self.norunes = args[1]
		
	def requestTracker (self, cli, **kwargs):
		tm = time.time()
		client = self.getPlayerByClientNum(cli)
		#If player requests item purchase, team join, unit select more than 12 times in 1 second, boot them
		
		if (tm - client['f_req']) > 1:
			client['req'] = 0
			client['f_req'] = tm
			return
			
		client['req'] += 1
		
		if client['req'] > 10:
			reason = "Spamming server requests results in automatic kicking."
			kwargs['Broadcast'].broadcast("Kick %s \"%s\"" % (client['clinum'], reason))
Ejemplo n.º 5
0
class admin(ConsolePlugin):
    VERSION = "1.3.6"
    playerlist = []
    adminlist = []
    banlist = []
    ipban = []
    itemlist = []
    PHASE = 0
    CONFIG = None
    UPDATE = True
    NEEDRELOAD = False
    LASTMESSAGE = {'client': None, 'firsttime': 0, 'lasttime': 0, 'repeat': 0}

    def onPluginLoad(self, config):

        self.ms = MasterServer()
        self.CONFIG = config
        ini = ConfigParser.ConfigParser()
        ini.read(config)

        for (name, value) in ini.items('admin'):
            self.adminlist.append({'name': name, 'level': value})
        for (name, value) in ini.items('ipban'):
            self.ipban.append(name)

        pass

    def reload_config(self):

        self.adminlist = []
        self.ipban = []
        ini = ConfigParser.ConfigParser()
        ini.read(self.CONFIG)

        for (name, value) in ini.items('admin'):
            self.adminlist.append({'name': name, 'level': value})
        for (name, value) in ini.items('ipban'):
            self.ipban.append(name)

    def reload_plugins(self):

        config = os.path.realpath(
            os.path.dirname(os.path.realpath(__file__)) + "/../s2wrapper.ini")
        print config
        ini = ConfigParser.ConfigParser()
        ini.read(config)
        for name in ini.options('plugins'):
            if name == 'admin':
                PluginsManager.reload(name)
                continue
            if ini.getboolean('plugins', name):
                PluginsManager.reload(name)

    def onStartServer(self, *args, **kwargs):

        self.playerlist = []
        self.banlist = []

    def RegisterScripts(self, **kwargs):
        #any extra scripts that need to go in can be done here
        #these are for identifying bought and sold items
        kwargs['Broadcast'].broadcast(
            "RegisterGlobalScript -1 \"set _client #GetScriptParam(clientid)#; set _item #GetScriptParam(itemname)#; echo ITEM: Client #_client# SOLD #_item#; echo\" sellitem"
        )
        kwargs['Broadcast'].broadcast(
            "RegisterGlobalScript -1 \"set _client #GetScriptParam(clientid)#; set _item #GetScriptParam(itemname)#; echo ITEM: Client #_client# BOUGHT #_item#; echo\" buyitem"
        )

    def getPlayerByClientNum(self, cli):

        for client in self.playerlist:
            if (client['clinum'] == cli):
                return client

    def getPlayerByName(self, name):

        for client in self.playerlist:
            if (client['name'].lower() == name.lower()):
                return client

    def onConnect(self, *args, **kwargs):

        id = args[0]
        ip = args[2]

        for each in self.ipban:
            if each == ip:
                reason = "You are banned from this server."
                kwargs['Broadcast'].broadcast("kick %s \"%s\"" % (id, reason))
                return

        reason = "An administrator has removed you from this server. You may rejoin the server after the current game ends."

        for each in self.banlist:
            if each == ip:
                kwargs['Broadcast'].broadcast(\
                 "Kick %s \"%s\"" % (id, reason))

        for client in self.playerlist:
            if (client['clinum'] == id):
                return

        self.playerlist.append ({'clinum' : id,\
            'acctid' : 0,\
            'name' : 'X',\
            'ip' : ip,\
            'team' : 0,\
            'sf' : 0,\
            'active' : False,\
            'level' : 0,\
            'admin' : False,\
            'value' : 0,\
            'commander' : False})

    def onDisconnect(self, *args, **kwargs):

        cli = args[0]
        client = self.getPlayerByClientNum(cli)
        client['active'] = False

    def onSetName(self, *args, **kwargs):

        cli = args[0]
        playername = args[1]
        client = self.getPlayerByClientNum(cli)
        client['name'] = playername

    def getAccountInfo(self, *args, **kwargs):
        client = self.getPlayerByClientNum(args[0])
        stats = self.ms.getStatistics(client['acctid']).get('all_stats').get(
            client['acctid'])
        level = int(stats['level'])
        sf = int(stats['sf'])

        client['sf'] = sf
        client['level'] = level
        client['active'] = True

        #If client has disconnected, give them their gold back
        self.giveGold(False, client, **kwargs)

    def onAccountId(self, *args, **kwargs):
        cli = args[0]
        id = args[1]
        client = self.getPlayerByClientNum(cli)
        client['acctid'] = int(id)

        statthread = threading.Thread(target=self.getAccountInfo,
                                      args=(cli, None),
                                      kwargs=kwargs)
        statthread.start()

        if self.isAdmin(client, **kwargs):
            kwargs['Broadcast'].broadcast(\
            "SendMessage %s ^cYou are registered as an administrator. Send the chat message: ^rhelp ^cto see what commands you can perform."\
             % (cli))
            client['admin'] = True

        if self.isSuperuser(client, **kwargs):
            kwargs['Broadcast'].broadcast(\
            "SendMessage %s ^cYou are registered as superuser on this server. You can send console commands with chat message: ^rsudo <command>."\
             % (cli))

    def isAdmin(self, client, **kwargs):
        admin = False

        for each in self.adminlist:
            if client['name'].lower() == each['name']:
                admin = True

        return admin

    def isSuperuser(self, client, **kwargs):
        superuser = False

        for each in self.adminlist:
            if client['name'].lower() == each['name']:
                if each['level'] == 'super':
                    superuser = True

        return superuser

    def onMessage(self, *args, **kwargs):

        name = args[1]
        message = args[2]

        client = self.getPlayerByName(name)
        clinum = client['clinum']
        admin = self.isAdmin(client, **kwargs)
        superuser = self.isSuperuser(client, **kwargs)

        #ADDED: more than 5 message in 1 second = kick
        tm = time.time()
        last = self.LASTMESSAGE['lasttime']
        first = self.LASTMESSAGE['firsttime']

        if (self.LASTMESSAGE['client'] == name):
            self.LASTMESSAGE['lasttime'] = tm
            #commanders are immune
            if not client['commander']:
                self.LASTMESSAGE['repeat'] += 1
                print 'repeat'

        else:
            self.LASTMESSAGE['client'] = name
            self.LASTMESSAGE['firsttime'] = tm
            self.LASTMESSAGE['repeat'] = 0

        if self.LASTMESSAGE['repeat'] > 4:
            if ((last - first) < 1):
                reason = "Spamming chat results in automatic kicking."
                kwargs['Broadcast'].broadcast(\
                 "Kick %s \"%s\"" % (clinum, reason))
                self.LASTMESSAGE['client'] = None
                self.LASTMESSAGE['repeat'] = 0
                self.LASTMESSAGE['firsttime'] = 0
                self.LASTMESSAGE['lasttime'] = 0
            else:
                self.LASTMESSAGE['repeat'] = 0
                self.LASTMESSAGE['client'] = None
                self.LASTMESSAGE['firsttime'] = 0
                self.LASTMESSAGE['lasttime'] = 0

        request = re.match("request admin", message, flags=re.IGNORECASE)
        if request:
            for each in self.playerlist:
                if each['active'] and each['admin']:
                    kwargs['Broadcast'].broadcast(
                        "SendMessage %s Admin present: ^y%s" %
                        (client['clinum'], each['name']))

        #ignore everything else if it isn't from admin
        if not admin:
            return

        #Pass to superCommand if the player is a superuser
        if superuser:
            self.superCommand(message, **kwargs)

        #Matches for normal admins
        restart = re.match("admin restart", message, flags=re.IGNORECASE)
        shuffle = re.match("admin shuffle", message, flags=re.IGNORECASE)
        kick = re.match("admin kick (\S+)", message, flags=re.IGNORECASE)
        ban = re.match("admin ban (\S+)", message, flags=re.IGNORECASE)
        slap = re.match("admin slap (\S+)", message, flags=re.IGNORECASE)
        changeworld = re.match("admin changeworld (\S+)",
                               message,
                               flags=re.IGNORECASE)
        help = re.match("help", message, flags=re.IGNORECASE)
        balance = re.match("admin balance", message, flags=re.IGNORECASE)
        getbalance = re.match("admin get balance",
                              message,
                              flags=re.IGNORECASE)
        reportbal = re.match("admin report balance",
                             message,
                             flags=re.IGNORECASE)

        if restart:
            #restarts server if something catastrophically bad has happened
            kwargs['Broadcast'].broadcast("restart")

        if shuffle:
            #artificial shuffle vote
            if self.PHASE != 5:
                kwargs['Broadcast'].broadcast(\
                 "SendMessage %s Cannot shuffle until the game has started!"\
                  % (client['clinum']))
                return

            kwargs['Broadcast'].broadcast(
                "SendMessage -1 %s has shuffled the game." % (name))
            self.listClients(**kwargs)
            shufflethread = threading.Thread(target=self.onShuffle,
                                             args=(clinum, None),
                                             kwargs=kwargs)
            shufflethread.start()

        if kick:
            #kicks a player from the server
            reason = "An administrator has removed you from the server, probably for being annoying"
            kickclient = self.getPlayerByName(kick.group(1))
            kwargs['Broadcast'].broadcast(\
             "Kick %s \"%s\""\
              % (kickclient['clinum'], reason))

        if ban:
            #kicks a player from the server and temporarily bans that player's IP till the game is over
            reason = "An administrator has banned you from the server. You are banned till this game is over."
            kickclient = self.getPlayerByName(ban.group(1))
            kwargs['Broadcast'].broadcast(\
             "Kick %s \"%s\"" \
              % (kickclient['clinum'], reason))
            self.banlist.append(kickclient['ip'])

        if slap:
            #slap will move a player x+100, y+200 to get them off of a structure

            slapclient = self.getPlayerByName(slap.group(1))
            kwargs['Broadcast'].broadcast(\
             "set _slapindex #GetIndexFromClientNum(%s)#;\
				 set _sx #GetPosX(|#_slapindex|#)#; set _sy #GetPosY(|#_slapindex|#)#; set _sz #GetPosZ(|#_slapindex|#)#;\
				 SetPosition #_slapindex# [_sx + 200] [_sy + 200] #_sz#;\
				 SendMessage %s ^cAn adminstrator has moved you for jumping on buildings. YOU WILL BE BANNED if this action persists"         \
              % (slapclient['clinum'], slapclient['clinum']))

        if changeworld:
            #change the map
            kwargs['Broadcast'].broadcast(\
             "changeworld %s"\
              % (changeworld.group(1)))

        if balance:
            if self.PHASE != 5:
                kwargs['Broadcast'].broadcast(\
                 "SendMessage %s Cannot balance if the game has not started!"\
                  % (client['clinum']))
                return

            kwargs['Broadcast'].broadcast(
                "SendMessage -1 %s has balanced the game." % (name))
            self.listClients(**kwargs)
            balancethread = threading.Thread(target=self.onBalance,
                                             args=(clinum, None),
                                             kwargs=kwargs)
            balancethread.start()

        if getbalance:
            self.listClients(**kwargs)
            balancethread = threading.Thread(target=self.getBalance,
                                             args=(clinum, None),
                                             kwargs=kwargs)
            balancethread.start()

        if reportbal:
            self.listClients(**kwargs)
            balancethread = threading.Thread(target=self.reportBalance,
                                             args=(),
                                             kwargs=kwargs)
            balancethread.start()

        self.logCommand(client['name'], message)

        if help:
            kwargs['Broadcast'].broadcast(\
             "SendMessage %s All commands on the server are done through server chat. All commands are logged to prevent you from abusing them.The following are commands and a short description of what they do."\
              % (client['clinum']))
            kwargs['Broadcast'].broadcast(\
             "SendMessage %s ^radmin restart ^whard reset of the server. ONLY use in weird cases."\
              % (client['clinum']))
            kwargs['Broadcast'].broadcast(\
             "SendMessage %s ^radmin shuffle ^wwill shuffle the game and set to previous phase."\
              % (client['clinum']))
            kwargs['Broadcast'].broadcast(\
             "SendMessage %s ^radmi kick playername ^wwill remove a player from the server."\
              % (client['clinum']))
            kwargs['Broadcast'].broadcast(\
             "SendMessage %s ^radmin ban playername ^wwill remove a player from the server and ban that IP address till the end of the game."\
              % (client['clinum']))
            kwargs['Broadcast'].broadcast(\
             "SendMessage %s ^radmin slap playername ^wwill move the player. Use to get them off of structures if they are exploiting."\
              % (client['clinum']))
            kwargs['Broadcast'].broadcast(\
             "SendMessage %s ^radmin changeworld mapname ^wwill change the map to the desired map."\
              % (client['clinum']))
            kwargs['Broadcast'].broadcast(\
             "SendMessage %s ^radmin balance ^wwill move two players to achieve balance."\
              % (client['clinum']))
            kwargs['Broadcast'].broadcast(\
             "SendMessage %s ^radmin get balance ^wwill report avg. and median SF values for the teams as well as a stack value."\
              % (client['clinum']))
            kwargs['Broadcast'].broadcast(\
             "SendMessage %s ^radmin report balance ^wwill send a message to ALL players that has the avg. and median SF values."\
              % (client['clinum']))

    def getBalance(self, *args, **kwargs):
        clinum = args[0]

        for each in self.playerlist:
            each['team'] = 0

        time.sleep(2)
        teamone = []
        teamtwo = []

        #populate current team lists:
        for each in self.playerlist:
            if not each['active']:
                continue
            if each['team'] == 1:
                teamone.append(each)
            if each['team'] == 2:
                teamtwo.append(each)

        teamonestats = self.getTeamInfo(teamone)
        teamtwostats = self.getTeamInfo(teamtwo)
        stack = round(self.evaluateBalance(teamone, teamtwo), 1)
        kwargs['Broadcast'].broadcast(\
        "SendMessage %s ^y Team One (%s players) Avg. SF is ^r%s^y median is ^r%s^y, Team Two (%s players) Avg. SF is ^r%s^y median is ^r%s. ^yStack value: ^r%s" \
         % (clinum, teamonestats['size'], round(teamonestats['avg'],1), round(teamonestats['median'],1), teamtwostats['size'], round(teamtwostats['avg'],1), round(teamtwostats['median'], 1), abs(stack)))

    def reportBalance(self, **kwargs):

        for each in self.playerlist:
            each['team'] = 0

        time.sleep(2)
        teamone = []
        teamtwo = []
        #populate current team lists:
        for each in self.playerlist:
            if not each['active']:
                continue
            if each['team'] == 1:
                teamone.append(each)
            if each['team'] == 2:
                teamtwo.append(each)

        teamonestats = self.getTeamInfo(teamone)
        teamtwostats = self.getTeamInfo(teamtwo)
        stack = round(self.evaluateBalance(teamone, teamtwo), 1)
        kwargs['Broadcast'].broadcast(\
        "SendMessage -1 ^y Team One (%s players) Avg. SF is ^r%s^y median is ^r%s^y, Team Two (%s players) Avg. SF is ^r%s^y median is ^r%s.^y Stack value: ^r%s" \
         % (teamonestats['size'], round(teamonestats['avg'],1), round(teamonestats['median'],1), teamtwostats['size'], round(teamtwostats['avg'], 1), round(teamtwostats['median'],1), abs(stack)))

    def superCommand(self, message, **kwargs):
        #This allows superuser to issue any console command
        supercommand = re.match("sudo (.*)", message, flags=re.IGNORECASE)

        if supercommand:
            kwargs['Broadcast'].broadcast("%s" % (supercommand.group(1)))

    def onPhaseChange(self, *args, **kwargs):
        phase = int(args[0])
        self.PHASE = phase

        if (phase == 7):
            self.banlist = []
            for each in self.playerlist:
                each['team'] = 0
                each['commander'] = False
                each['value'] = 0

        if (phase == 6):
            if self.UPDATE:
                #fetch admin list and reload at the start of each game
                updatethread = threading.Thread(target=self.update,
                                                args=(),
                                                kwargs=kwargs)
                updatethread.start()
                #check if server is empty after 2 minutes
                pluginthread = threading.Thread(target=self.pluginreload,
                                                args=(),
                                                kwargs=kwargs)
                pluginthread.start()

            self.RegisterScripts(**kwargs)
            self.ItemList()

        if (phase == 4):
            kwargs['Broadcast'].broadcast("listclients")

    def update(self, **kwargs):

        response = urllib2.urlopen('http://188.40.92.72/admin.ini')
        adminlist = response.read()

        f = open(self.CONFIG, 'w')
        f.write(adminlist)
        f.close
        f.flush()
        os.fsync(f.fileno())
        self.reload_config()

        if self.NEEDRELOAD:
            self.pluginreload(**kwargs)
            return

        #Update the wrapper
        try:
            gitpath = os.path.realpath(
                os.path.dirname(os.path.realpath(__file__)) + "/../.git")
            command = ["git", "--git-dir", gitpath, "pull"]
            output = subprocess.Popen(command,
                                      stdout=subprocess.PIPE).communicate()
            result = output[0].split("\n")[0]
            print 'result is %s' % result
            #TODO: make sure these work on all servers?
            notneeded = re.match("Already up-to-date.", result)
            needed = re.match("Updating .*", result)
        except:
            print 'error getting git update'
            return

        if notneeded:
            print 'update not needed'
            self.NEEDRELOAD = False
            return

        if needed:
            print 'update needed'
            self.NEEDRELOAD = True
            self.pluginreload(**kwargs)
            return

    def pluginreload(self, **kwargs):
        print 'pluginreload called'
        #Wait a couple minutes to allow clients to connect
        time.sleep(120)
        #Figure out how many clients are present
        kwargs['Broadcast'].broadcast("serverstatus")

    def onServerStatusResponse(self, *args, **kwargs):

        if self.NEEDRELOAD:
            gamemap = args[0]
            active = int(args[2])

            if active == 0:
                self.reload_plugins()
                kwargs['Broadcast'].broadcast("NextPhase; PrevPhase")
                self.NEEDRELOAD = False

    def logCommand(self, client, message, **kwargs):
        localtime = time.localtime(time.time())
        date = ("%s-%s-%s, %s:%s:%s" %
                (localtime[1], localtime[2], localtime[0], localtime[3],
                 localtime[4], localtime[5]))
        f = open('admin.log', 'a')
        f.write("Timestamp: \"%s\", Admin: %s, Command: %s\n" %
                (date, client, message))
        f.close

    def onTeamChange(self, *args, **kwargs):

        team = int(args[1])
        cli = args[0]
        client = self.getPlayerByClientNum(cli)
        client['team'] = team

    def onShuffle(self, *args, **kwargs):

        for each in self.playerlist:
            each['team'] = 0
            each['value'] = 0

        clinum = args[0]
        time.sleep(2)
        shufflelist = []

        #Put all the active players in a list
        for each in self.playerlist:
            if not each['active']:
                continue
            if each['team'] > 0:
                shufflelist.append(each)

        #sort shufflelists based on SF
        shufflelist = sorted(shufflelist,
                             key=itemgetter('sf', 'level', 'clinum'),
                             reverse=True)

        #randomly choose if we begin with human or beast
        r = random.randint(1, 2)

        #Assign new teams, just like the K2 way, but Ino won't always be on humans
        for each in shufflelist:
            #TODO: is there a cleaner, more pythonic way to do this?
            each['team'] = r
            if r == 1:
                r += 1
            elif r == 2:
                r -= 1

        #Now actually do the shuffling
        for each in shufflelist:
            kwargs['Broadcast'].broadcast(\
             "SetTeam #GetIndexFromClientNum(%s)# %s"\
              % (each['clinum'], each['team']))
        #Finish it off by going forward a phase
        kwargs['Broadcast'].broadcast(\
         "nextphase")


        kwargs['Broadcast'].broadcast(\
         "SendMessage %s You have shuffled the game." % (clinum))
        #Run balancer to get it nice and even
        self.onBalance(clinum, **kwargs)

    def onBalance(self, *args, **kwargs):

        for each in self.playerlist:
            each['team'] = 0

        time.sleep(2)
        teamone = []
        teamtwo = []

        #populate current team lists:
        for each in self.playerlist:
            if not each['active']:
                continue
            if each['team'] == 1:
                teamone.append(each)
            if each['team'] == 2:
                teamtwo.append(each)

        #Get Information about the teams

        teamonestats = self.getTeamInfo(teamone)
        teamtwostats = self.getTeamInfo(teamtwo)
        startstack = self.evaluateBalance(teamone, teamtwo)

        #Send message to admin that called the shuffle/balance
        kwargs['Broadcast'].broadcast(\
         "SendMessage %s ^yPrior to balance: Team One Avg. SF was ^r%s^y median was ^r%s^y, Team Two Avg. SF was ^r%s^y median was ^r%s" \
          % (args[0], teamonestats['avg'], teamonestats['median'], teamtwostats['avg'], teamtwostats['median']))

        #Find the players to swap
        lowest = -1
        pick1 = None
        pick2 = None

        for player1 in teamone:
            if player1['commander']:
                continue
            for player2 in teamtwo:
                if player2['commander']:
                    continue
                #sort of inefficient to send the teamlist each time
                ltarget = self.evaluateBalance(teamone, teamtwo, player1,
                                               player2, True)

                if (lowest < 0):
                    lowest = ltarget
                    pick1 = player1
                    pick2 = player2
                    continue

                if (lowest < ltarget):
                    continue

                lowest = ltarget
                pick1 = player1
                pick2 = player2

        #If the stack isn't improved, abort it
        if (lowest >= startstack):
            print 'unproductive balance. terminate'
            kwargs['Broadcast'].broadcast(\
             "echo unproductive balance")
            return
        #Do the switch
        kwargs['Broadcast'].broadcast(\
         "set _index #GetIndexFromClientNum(%s)#;\
			 SetTeam #_index# 2;\
			 set _index #GetIndexFromClientNum(%s)#;\
			 SetTeam #_index# 1"      \
          % (pick1['clinum'], pick2['clinum']))

        #Give them gold if needed
        self.giveGold(True, pick1, **kwargs)
        self.giveGold(True, pick2, **kwargs)

        teamonestats = self.getTeamInfo(teamone)
        teamtwostats = self.getTeamInfo(teamtwo)

        #kwargs['Broadcast'].broadcast(\
        #	"SendMessage %s ^yAfter balance: Team One Avg. SF was ^r%s^y median was ^r%s^y, Team Two Avg. SF was ^r%s^y median was ^r%s"\
        #	 % (clinum, teamonestats['avg'], teamonestats['median'], teamtwostats['avg'], teamtwostats['median']))

    def getTeamInfo(self, teamlist, **kwargs):

        teamsf = []
        combteamsf = float(0)
        #figure out current averages and set some commonly used variables:
        for each in teamlist:
            combteamsf += each['sf']
            teamsf.append(each['sf'])

        sizeteam = len(teamlist)
        avgteam = combteamsf / sizeteam
        med = median(teamsf)

        teaminfo = {
            'size': sizeteam,
            'avg': avgteam,
            'total': combteamsf,
            'median': med
        }

        return teaminfo

    def evaluateBalance(self,
                        team1,
                        team2,
                        pick1=None,
                        pick2=None,
                        swap=False,
                        **kwargs):
        #This function will swap out the picked players in a temporary list if swap is true and report the stack percent
        #If swap is false, it will just report the balance
        #First, make new lists that we can modify:
        teamone = list(team1)
        teamtwo = list(team2)

        if swap:
            #Remove those players from the lists...
            for each in teamone:
                if each['clinum'] == pick1['clinum']:
                    teamone.remove(each)
            for each in teamtwo:
                if each['clinum'] == pick2['clinum']:
                    teamtwo.remove(each)

            #Add to the lists
            teamone.append(pick2)
            teamtwo.append(pick1)

        #Get the new team stats...
        teamonestats = self.getTeamInfo(teamone)
        teamtwostats = self.getTeamInfo(teamtwo)

        #Evaluate team balance
        teamoneshare = teamonestats['total'] / (teamonestats['total'] +
                                                teamtwostats['total'])
        diffmedone = teamonestats['median'] / (teamonestats['median'] +
                                               teamtwostats['median'])
        stack = teamoneshare + diffmedone
        #positive if team one is stacked, negative if team two is stacked
        return (stack - 1) * 100

    def onCommResign(self, *args, **kwargs):

        name = args[0]
        client = self.getPlayerByName(name)
        client['commander'] = False

    def onUnitChange(self, *args, **kwargs):
        if args[1] != "Player_Commander":
            return

        cli = args[0]
        client = self.getPlayerByClientNum(cli)
        client['commander'] = True

    def listClients(self, *args, **kwargs):

        kwargs['Broadcast'].broadcast("listclients")

    def onListClients(self, *args, **kwargs):
        clinum = args[0]
        name = args[2]
        ip = args[1]

        client = self.getPlayerByName(name)
        if not client:
            #if a player is missing from the list this will put them as an active player and get stats
            #TODO: listclients clinum is always double diget (00, 01, etc.) so this might be a problem
            acct = self.ms.getAccount(name)
            acctid = acct[name]
            self.onConnect(clinum, 0000, ip, 0000, **kwargs)
            self.onSetName(clinum, name, **kwargs)
            self.onAccountId(clinum, acctid, **kwargs)
            client = self.getPlayerByName(name)

        client['active'] = True
        kwargs['Broadcast'].broadcast(\
        "echo CLIENT %s is on TEAM #GetTeam(|#GetIndexFromClientNum(%s)|#)#"\
         % (client['clinum'], client['clinum']))

    def onRefreshTeams(self, *args, **kwargs):
        clinum = args[0]
        team = int(args[1])
        client = self.getPlayerByClientNum(clinum)
        client['team'] = team

    def ItemList(self, *args, **kwargs):

        self.itemlist = {
            'Advanced Sights': 700,
            'Ammo Pack': 500,
            'Ammo Satchel': 200,
            'Chainmail': 300,
            'Gust of Wind': 450,
            'Magic Amplifier': 700,
            'Brain of Maliken': 750,
            'Heart of Maliken': 950,
            'Lungs of Maliken': 800,
            'Mana Crystal': 500,
            'Mana Stone': 200,
            'Platemail': 650,
            'Power Absorption': 350,
            'Shield of Wisdom': 650,
            'Stone Hide': 650,
            'Tough Skin': 300,
            'Trinket of Restoration': 575
        }

    def onItemTransaction(self, *args, **kwargs):
        #adjust 'value' in playerlist to reflect what the player has bought or sold
        cli = args[0]
        trans = args[1]
        newitem = args[2]
        client = self.getPlayerByClientNum(cli)

        try:
            value = self.itemlist[newitem]
        except:
            return

        if (trans == 'BOUGHT'):
            client['value'] += value
        elif (trans == 'SOLD'):
            client['value'] -= value

    def giveGold(self, balance, client, **kwargs):

        if client['value'] == 0:

            return

        gold = round(client['value'] / 2, 0)

        if balance:
            gold = client['value']

        kwargs['Broadcast'].broadcast(\
         "SendMessage %s ^cYou have been compensated %s gold for your lost items.; GiveGold %s %s"\
          % (client['clinum'], gold, client['clinum'], gold))

        client['value'] = 0
Ejemplo n.º 6
0
class sendstats(ConsolePlugin):
    base = None
    sent = None
    playerlist = []
    login = None
    lpass = None
    broadcast = 0
    serverid = 0
    loaded = False

    def onPluginLoad(self, config):

        ini = ConfigParser.ConfigParser()
        ini.read(config)

        for (name, value) in ini.items('paths'):
            if (name == "base"):
                self.base = value
            if (name == "sent"):
                self.sent = value

    def getPlayerByName(self, name):

        client = None

        for client in self.playerlist:
            if (client['name'].lower() == name.lower()):
                return client

    def onPhaseChange(self, *args, **kwargs):
        phase = int(args[0])

        #Everytime we start a game, start a new thread to send all the stats to eaxs' script, and replays to stony
        if (phase == 6):

            uploadthread = thread.start_new_thread(self.uploadstats, ())
            eventthread = thread.start_new_thread(self.uploadevent, ())
            replaythread = thread.start_new_thread(self.uploadreplay, ())

        if not self.loaded:
            kwargs['Broadcast'].broadcast(
                "echo SERVERVAR: svr_login is #svr_login#")
            kwargs['Broadcast'].broadcast(
                "echo SERVERVAR: svr_pass is #svr_pass#")
            kwargs['Broadcast'].broadcast(
                "echo SERVERVAR: svr_broadcast is #svr_broadcast#")
            self.loaded = True

    def uploadstats(self):
        print 'starting uploadstats'
        self.ss = StatsServers()
        home = os.environ['HOME']
        path = os.path.join(home, self.base)
        sentdir = os.path.join(home, self.sent)

        for infile in glob.glob(os.path.join(home, self.base, '*.stats')):
            print "Sending stat file: " + infile
            s2pfile = infile
            statstring = open(infile, 'r').read()
            decoded = urllib.quote(statstring)
            stats = ("stats=%s" % (decoded))

            try:
                self.ss.s2gstats(statstring)
                self.ss.salvagestats(stats)
                self.ss.s2pstats(statstring)

            except:
                print 'upload failed. no stats sent'
                return

            try:
                shutil.copy(infile, sentdir)
                os.remove(os.path.join(home, self.base, infile))
            except:
                continue

    def uploadevent(self):

        self.ss = StatsServers()
        home = os.environ['HOME']
        path = os.path.join(home, self.base)
        sentdir = os.path.join(home, self.sent)

        for infile in glob.glob(os.path.join(home, self.base, '*.event')):
            match = os.path.splitext(os.path.basename(infile))[0]
            s2pfile = infile
            statstring = open(infile, 'r').read()
            decoded = urllib.quote(statstring)
            stats = ("event%s=%s" % (match, decoded))

            try:
                self.ss.s2pstats(stats)

            except:
                print 'upload failed. no stats sent'
                return

            try:
                shutil.copy(infile, sentdir)
                os.remove(os.path.join(home, self.base, infile))
            except:
                continue

    def getServerVar(self, *args, **kwargs):

        var = args[0]

        if var == 'svr_login':
            self.login = args[1]

        if var == 'svr_pass':
            self.lpass = args[1]

        if var == 'svr_broadcast':
            self.broadcast = int(args[1])

        self.ms = MasterServer()

        if self.broadcast > 0:
            server = self.ms.getServer(self.login, self.lpass, self.broadcast)
            self.serverid = server['svr_id']
            print self.serverid

    def uploadreplay(self):
        print 'starting uploadreplay'
        self.ss = StatsServers()
        home = os.environ['HOME']
        path = os.path.join(home, self.base)
        sentdir = os.path.join(home, self.sent)
        remotehost = '188.40.92.72'
        remotefile = 'incoming'
        port = 22522
        for infile in glob.glob(os.path.join(home, self.base, '*.s2r')):
            print "Sending replay file: " + infile

            try:
                #self.ss.sendreplay(infile)
                os.system('scp -P "%s" "%s" scponly@"%s:%s"' %
                          (port, infile, remotehost, remotefile))

            except:
                print 'upload failed. replay not sent'
                continue

            print 'Sent replay'

            try:
                shutil.copy(infile, sentdir)
                os.remove(os.path.join(home, self.base, infile))
            except:
                continue

    def getPlayerByClientNum(self, cli):

        for client in self.playerlist:
            if (client['clinum'] == cli):
                return client

    def onConnect(self, *args, **kwargs):

        id = args[0]
        ip = args[2]

        self.playerlist.append({
            'clinum': id,
            'acctid': 0,
            'name': 'X',
            'ip': ip
        })

    def onSetName(self, *args, **kwargs):

        cli = args[0]
        playername = args[1]

        client = self.getPlayerByClientNum(cli)
        client['name'] = playername

    def onAccountId(self, *args, **kwargs):
        self.ss = StatsServers()
        cli = args[0]
        id = args[1]
        client = self.getPlayerByClientNum(cli)
        client['acctid'] = int(id)
        name = client['name']
        ip = client['ip']
        server = self.serverid

        playerinfo = ("sync_user=1&username=%s&acc=%s&ip=%s&svr=%s" %
                      (name, id, ip, server))

        #Send info to PS2
        self.ss.salvagestats(playerinfo)

    def onDisconnect(self, *args, **kwargs):

        cli = args[0]
        client = self.getPlayerByClientNum(cli)

        acct = client['acctid']
        name = client['name']
        server = self.serverid

        playerinfo = ("sync_user=2&username=%s&acc=%s&svr=%s" %
                      (name, id, server))
        #Send info to PS2
        self.ss.salvagestats(playerinfo)

    def onListClients(self, *args, **kwargs):
        clinum = args[0]
        name = args[2]
        ip = args[1]

        client = self.getPlayerByName(name)
        if not client:
            #if a player is missing from the list this will put them as an active player
            acct = self.ms.getAccount(name)
            acctid = acct[name]
            self.onConnect(clinum, 0000, ip, 0000, **kwargs)
            self.onSetName(clinum, name, **kwargs)
            self.onAccountId(clinum, acctid, **kwargs)
Ejemplo n.º 7
0
class extras(ConsolePlugin):
	VERSION = "1.2.2"
	ms = None
	CHAT_INTERVAL = 10
	CHAT_STAMP = 0
	playerlist = []
	itemlist = []
	followlist = []
	FOLLOWERS = 4
	MAPSIZE = 0
	MAPSIZESET = False
	buildingprotect = False

	def onPluginLoad(self, config):
		self.ms = MasterServer ()
		
		ini = ConfigParser.ConfigParser()
		ini.read(config)
		
		pass
	
	def RegisterScripts(self, **kwargs):
		

		#Setup everything for following
		self.followlist = []
		followers = 1
		framestring = ""
		
		while followers <= self.FOLLOWERS:
			followstring = ("\
					RegisterGlobalScript -1 \"set _follower{0} #GetIndexFromClientNum(|#_f{0}|#)#;\
					set _followed{0} #GetIndexFromClientNum(|#_fd{0}|#)#;\
					set _fx{0} #GetPosX(|#_followed{0}|#)#;\
					set _fy{0} #GetPosY(|#_followed{0}|#)#;\
					set _x{0} #GetPosX(|#_follower{0}|#)#;\
					set _y{0} #GetPosY(|#_follower{0}|#)#;\
					set _z{0} #GetPosZ(|#_follower{0}|#)#;\
					set _zs{0} #_x{0}#, #_y{0}#;\
					set _zt{0} #GetTerrainHeight(|#_zs{0}|#)#;\
					if [_z{0} < _zt{0}] set _z{0} [_zt{0} + 50];\
					set _followX{0} 200;\
					set _followY{0} 200;\
					SetPosition #_follower{0}# [_fx{0} + _followX{0}] [_fy{0} + _followY{0}] [_z{0}]\" follow{0}").format(followers)
			                    
			framestring += (";if [_f{0} >= 0] ExecScript follow{0}").format(followers)
			kwargs['Broadcast'].broadcast("%s" % (followstring))
			f = "_f{0}".format(followers)
			fd = "_fd{0}".format(followers)
			kwargs['Broadcast'].broadcast("set %s -1; set %s -1" % (f, fd))
			self.followlist.append({'follower' : -1, 'followed' : -1, 'f' : f, 'fd' : fd})
			followers += 1
			
		kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"set _ii 0%s\" frame" % (framestring))

		

	def getPlayerByClientNum(self, cli):

		client = None

		for client in self.playerlist:
			if (client['clinum'] == cli):
				return client

	def getPlayerByName(self, name):

		client = None

		for client in self.playerlist:
			if (client['name'].lower() == name.lower()):
				return client

	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		
		if phase == 5:

			self.RegisterScripts(**kwargs)
		
		if phase == 6:
			
			self.RegisterScripts(**kwargs)

			#remove stuck for players
			for each in self.playerlist:
				each['stuck'] = False
			#set buildig protect scripts

			#TODO: make sure the place it moves them is a valid position
			if self.buildingprotect:
				kwargs['Broadcast'].broadcast("\
				RegisterGlobalScript -1 \"RegisterEntityScript #GetScriptParam(index)# death \\\"Set _dead\
					#GetScriptParam(index)#; ExecScript Death\\\";\
				set _index #GetScriptParam(index)#; set _mz 350;\
				set _type #GetScriptParam(type)#; echo #_type#; if #StringEquals(|#_type|#,Building_HumanHellShrine)#\
				set _mz 2000; if #StringEquals(|#_type|#,Building_ArrowTower)# set _mz 2000;\
				if #StringEquals(|#_type|#,Building_CannonTower)# set _mz 2000;\
				if #StringEquals(|#_type|#,Building_ChlorophilicSpire)# set _mz 2000;\
				if #StringEquals(|#_type|#,Building_EntangleSpire)# set _mz 2000;\
				if #StringEquals(|#_type|#,Building_ShieldTower)# set _mz 2000;\
				if #StringEquals(|#_type|#,Building_StrataSpire)# set _mz 2000;\
				set _x #GetPosX(|#_index|#)#;\
				set _y #GetPosY(|#_index|#)#;\
				set _z #GetPosZ(|#_index|#)#;\
				SpawnEntityatEntity #_index# Trigger_Proximity model /core/null/null.mdf name DeathTrigger#_index# triggeronplayer 1 triggerradius\
					 250 triggerenter\
					 \\\"set _domove 1; set _xindex #GetScriptParam(index)#;\
					 set _xtype #GetType(|#_xindex|#)#;\
					 if #StringEquals(|#_xtype|#,Player_Behemoth)# set _domove 0;\
					 if #StringEquals(|#_xtype|#,Player_Malphas)# set _domove 0;\
					 if #StringEquals(|#_xtype|#,Player_Devourer)# set _domove 0;\
					 set _xx #GetPosX(|#_xindex|#)#;\
					 set _xy #GetPosY(|#_xindex|#)#;\
					 set _xz #GetPosZ(|#_xindex|#)#;\
					 if [_domove == 1] SetPosition #_xindex# [_xx + 300] [_xy - 300] #_xz#\\\";\
				 SetPosition #GetIndexFromName(DeathTrigger|#_index|#)# #_x# #_y# [_z + _mz];\
				 echo\" buildingplaced")

				kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"RemoveEntity #GetIndexFromName(DeathTrigger|#_dead|#)#; echo\" Death");
			#get the map size
			#removing this for now as it is not used. Old55 2/10/12
			#mapthread = threading.Thread(target=self.getMapSize, args=(), kwargs=kwargs)
			#mapthread.start()
				
		if phase == 7:
			for each in self.playerlist:
				each['team'] = 0
			self.MAPSIZESET = False

	def onConnect(self, *args, **kwargs):
		
		id = args[0]
		
		for client in self.playerlist:
			if (client['clinum'] == id):
				return

		self.playerlist.append ({
		 'clinum' : id,\
		 'acctid' : 0,\
		 'level' : 0,\
		 'sf' : 0,\
		 'lf' : 0,\
		 'name' : 'X',\
		 'team' : 0,\
		 'stuck' : False,\
		 'index' : 0,\
		 'exp' : 2,\
		 'value' : 150,\
		 'prevent' : 0,\
		 'active' : False,\
		 'gamelevel' : 1})

	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client ['active'] = False
		
		for each in self.followlist:
			if each ['follower'] == client['clinum'] or each['followed'] == client['clinum']:
				each['follower'] = -1
				each['followed'] = -1
				self.follow(**kwargs)
				
	def onSetName(self, *args, **kwargs):

				
		cli = args[0]
		playername = args[1]
		
		client = self.getPlayerByClientNum(cli)
		client ['name'] = playername
		mapmessage = "^cSpectators on this server can follow individual players. Send the message: ^rfollow playername. ^cTo stop following: ^rstop follow.\
			      ^cIf you get stuck on the map you can send the message: ^rstuck^c to nudge you out of your spot. This can be used once a game."
		kwargs['Broadcast'].broadcast("SendMessage %s %s" % (client['clinum'], mapmessage))
		
	def onAccountId(self, *args, **kwargs):

		cli = args[0]
		id = args[1]
		stats = self.ms.getStatistics (id).get ('all_stats').get (int(id))
		
		level = int(stats['level'])
		sf = int(stats['sf'])
		lf = int(stats['lf'])
		exp = int(stats['exp'])
		time = int(stats['secs'])
		
		client = self.getPlayerByClientNum(cli)

		client ['acctid'] = int(id)
		client ['level'] = level
		client ['sf'] = sf
		client ['lf'] = lf
		client ['exp'] = exp
		client ['active'] = True


	def onTeamChange (self, *args, **kwargs):
		
		team = int(args[1])
		cli = args[0]
		
		client = self.getPlayerByClientNum(cli)
		client['team'] = team

		for each in self.followlist:
			if each ['follower'] == client['clinum'] or each['followed'] == client['clinum']:
				each['follower'] = -1
				each['followed'] = -1
				self.follow(**kwargs)
				
	def onMessage(self, *args, **kwargs):
		
		name = args[1]
		message = args[2]
		
		client = self.getPlayerByName(name)
		
		#Various chat matches
		followed = re.match("follow (\S+)", message, flags=re.IGNORECASE)
		stopfollow = re.match("stop follow", message, flags=re.IGNORECASE)
		stuck = re.match("stuck", message, flags=re.IGNORECASE)

		if followed:
			action = 'start'
			followed_player = self.getPlayerByName(followed.group(1))
			if followed_player == None:
				kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^cCould not find a player by that name." % (client['clinum']))
				return
			
			if (followed_player ['team'] > 0) and (client ['team'] == 0):
				self.followaction(action, client, followed_player, **kwargs)

		if stopfollow:
			action = 'stop'
			self.followaction(action, client, followed_player=None, **kwargs)
			
		if stuck:
			if client['stuck']:
				return
			kwargs['Broadcast'].broadcast(\
				"set _stuckindex #GetIndexFromClientNum(%s)#;\
				 set _X [rand*100]; echo #_X#;\
				 set _Y [rand*100]; echo #_Y#;\
				 set _stuckx #GetPosX(|#_stuckindex|#)#;\
				 set _stucky #GetPosY(|#_stuckindex|#)#;\
				 set _stuckz #GetPosZ(|#_stuckindex|#)#;\
				 SetPosition #_stuckindex# [_stuckx + _X] [_stucky + _Y] [_stuckz + 40]" % (client['clinum']))

			client['stuck'] = True
	
	def onScriptEvent(self, *args, **kwargs):		
		
		caller = args[0]
		client = self.getPlayerByClientNum(caller)
		event = args[1]
		value = args[2]
				
		if event == 'Follow':
		#Determine if it is follow or stop
			if value == 'stop':
				action = value
				self.followaction(action, client, followed_player=None, **kwargs)
				return
			else:
				action = 'start'
				followed_player = self.getPlayerByName(value)
				if (followed_player ['team'] > 0) and (client ['team'] == 0):
					self.followaction(action, client, followed_player, **kwargs)
					return

		#if event == 'SetMapPosition':
			
		#	if client['team'] != 0:
		#		return
			
		#	maxcoord = ((self.MAPSIZE - 1) * 64 * 64)
		#	print maxcoord
		#	location = re.match("(0\.\d+)_(0.\d+)", value)
		#	print location.group(1), location.group(2)
		#	coordx = float(location.group(1))*maxcoord
		#	coordy = float(location.group(2))*maxcoord
		#	print coordx, coordy
		#	kwargs['Broadcast'].broadcast(\
		#		 "SetPosition #GetIndexFromClientNum(%s)# %s %s #GetPosZ(|#GetIndexFromClientNum(%s)|#)#" % (client['clinum'], coordx, coordy, client['clinum']))
				 
	def followaction(self, action, client, followed_player, **kwargs):
		
		if action == 'start':
		
			for each in self.followlist:
				#first check if they are already a follower
				if each ['follower'] == client['clinum']:
					each ['followed'] = followed_player['clinum']
					self.follow(**kwargs)
					return
				
			for each in self.followlist:
				#if not already follower, grab the first available spot
				if each['follower'] == -1:
					each ['follower'] = client['clinum']
					each ['followed'] = followed_player['clinum']
					self.follow(**kwargs)
					return
			#If all the spots are filled, report it
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^cThe follow list is full!" % (client['clinum']))
			return
						
		if action == 'stop':
			for each in self.followlist:
				if each['follower'] == client['clinum']:
					each['follower'] = -1
					each['followed'] = -1
		
		self.follow(**kwargs)
		
	def follow(self, **kwargs):
		for each in self.followlist:
			kwargs['Broadcast'].broadcast(\
			"set %s %s; set %s %s" % (each['f'], each['follower'], each['fd'], each['followed']))

	def getMapSize(self,**kwargs):
		
		checkdimension = 131071
		self.MAPSIZE = 10
		while not self.MAPSIZESET:
			time.sleep(0.5)
			self.MAPSIZESET = True
			checkdimension = checkdimension/2
			kwargs['Broadcast'].broadcast("echo #GetTerrainHeight(%s,0)#" % (checkdimension))
			print 'Map Size =', self.MAPSIZE
			time.sleep(1)

	def mapDimensions(self, *args, **kwargs):
		if self.MAPSIZE > 0:
			print 'made it to MAP DIMENSONS'
			self.MAPSIZE -= 1
			self.MAPSIZESET = False
			
	def onListClients(self, *args, **kwargs):
		clinum = args[0]
		name = args[2]
		ip = args[1]
		
		
		client = self.getPlayerByName(name)
		if not client:
		#if a player is missing from the list this will put them as an active player
			acct = self.ms.getAccount(name)
			acctid = acct[name]
			self.onConnect(clinum, 0000, ip, 0000, **kwargs)
			self.onSetName(clinum, name, **kwargs)
			self.onAccountId(clinum, acctid, **kwargs)
Ejemplo n.º 8
0
class admin(ConsolePlugin):
	VERSION = "1.3.6"
	playerlist = []
	adminlist = []
	banlist = []
	ipban = []
	itemlist = []
	PHASE = 0
	CONFIG = None
	UPDATE = True
	NEEDRELOAD = False
	LASTMESSAGE = {'client' : None, 'firsttime' : 0, 'lasttime' : 0, 'repeat' : 0}


	def onPluginLoad(self, config):
		
		self.ms = MasterServer ()
		self.CONFIG = config
		ini = ConfigParser.ConfigParser()
		ini.read(config)
		
		for (name, value) in ini.items('admin'):
			self.adminlist.append({'name': name, 'level' : value})
		for (name, value) in ini.items('ipban'):
			self.ipban.append(name)	
		
		
		pass
		
	def reload_config(self):
		
        	self.adminlist = []
       		self.ipban = []
                ini = ConfigParser.ConfigParser()
                ini.read(self.CONFIG)

                for (name, value) in ini.items('admin'):
                	self.adminlist.append({'name': name, 'level' : value})
                for (name, value) in ini.items('ipban'):
                	self.ipban.append(name)	

	def reload_plugins(self):
	
		config = os.path.realpath(os.path.dirname (os.path.realpath (__file__)) + "/../s2wrapper.ini")
		print config
		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for name in ini.options('plugins'):
			if name == 'admin':
				PluginsManager.reload(name)
				continue
			if ini.getboolean('plugins', name):
				PluginsManager.reload(name)
			
	def onStartServer(self, *args, **kwargs):
				
		self.playerlist = []
		self.banlist = []	

	def RegisterScripts(self, **kwargs):
		#any extra scripts that need to go in can be done here
		#these are for identifying bought and sold items
		kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"set _client #GetScriptParam(clientid)#; set _item #GetScriptParam(itemname)#; echo ITEM: Client #_client# SOLD #_item#; echo\" sellitem")
		kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"set _client #GetScriptParam(clientid)#; set _item #GetScriptParam(itemname)#; echo ITEM: Client #_client# BOUGHT #_item#; echo\" buyitem")

	def getPlayerByClientNum(self, cli):

		for client in self.playerlist:
			if (client['clinum'] == cli):
				return client

	def getPlayerByName(self, name):

		for client in self.playerlist:
			if (client['name'].lower() == name.lower()):
				return client

	def onConnect(self, *args, **kwargs):
		
		id = args[0]
		ip = args[2]
		
		for each in self.ipban:
			if each == ip:
				reason = "You are banned from this server."
				kwargs['Broadcast'].broadcast("kick %s \"%s\"" % (id, reason))
				return

		reason = "An administrator has removed you from this server. You may rejoin the server after the current game ends."
		
		for each in self.banlist:
			if each == ip:
				kwargs['Broadcast'].broadcast(\
					"Kick %s \"%s\"" % (id, reason))

		for client in self.playerlist:
			if (client['clinum'] == id):
				return
		
		self.playerlist.append ({'clinum' : id,\
					 'acctid' : 0,\
					 'name' : 'X',\
					 'ip' : ip,\
					 'team' : 0,\
					 'sf' : 0,\
					 'active' : False,\
					 'level' : 0,\
					 'admin' : False,\
					 'value' : 0,\
					 'commander' : False})
	
	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client ['active'] = False

	def onSetName(self, *args, **kwargs):
		
		cli = args[0]
		playername = args[1]
		client = self.getPlayerByClientNum(cli)
		client ['name'] = playername

	def getAccountInfo(self, *args, **kwargs):
		client = self.getPlayerByClientNum(args[0])
		stats = self.ms.getStatistics (client['acctid']).get ('all_stats').get (client['acctid'])
		level = int(stats['level'])
		sf = int(stats['sf'])
					
		client['sf'] = sf
		client['level'] = level
		client['active'] = True
		
		#If client has disconnected, give them their gold back
		self.giveGold(False, client, **kwargs)
		

	def onAccountId(self, *args, **kwargs):
		cli = args[0]
		id = args[1]
		client = self.getPlayerByClientNum(cli)
		client['acctid'] = int(id)

		statthread = threading.Thread(target=self.getAccountInfo, args=(cli,None), kwargs=kwargs)
		statthread.start()	

		if self.isAdmin(client, **kwargs):
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^cYou are registered as an administrator. Send the chat message: ^rhelp ^cto see what commands you can perform."\
			 % (cli))
			client['admin'] = True

		if self.isSuperuser(client, **kwargs):
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^cYou are registered as superuser on this server. You can send console commands with chat message: ^rsudo <command>."\
			 % (cli))
		
 
		
	def isAdmin(self, client, **kwargs):
		admin = False
		
		for each in self.adminlist:
			if client['name'].lower() == each['name']:
				admin = True
		
		return admin

	def isSuperuser(self, client, **kwargs):
		superuser = False

		for each in self.adminlist:
			if client['name'].lower() == each['name']:
				if each['level'] == 'super':
					superuser = True
		
		return superuser

	def onMessage(self, *args, **kwargs):
		
		name = args[1]
		message = args[2]
		
		client = self.getPlayerByName(name)
		clinum = client['clinum']
		admin = self.isAdmin(client, **kwargs)
		superuser = self.isSuperuser(client, **kwargs)

		#ADDED: more than 5 message in 1 second = kick
		tm = time.time()
		last = self.LASTMESSAGE['lasttime']
		first = self.LASTMESSAGE['firsttime']
		
		
		if (self.LASTMESSAGE['client'] == name):
			self.LASTMESSAGE['lasttime'] = tm
			#commanders are immune
			if not client['commander']:
				self.LASTMESSAGE['repeat'] += 1
				print 'repeat'
			
		else:
			self.LASTMESSAGE['client'] = name
			self.LASTMESSAGE['firsttime'] = tm
			self.LASTMESSAGE['repeat'] = 0	
			
		if self.LASTMESSAGE['repeat'] > 4:
			if ((last - first) < 1):
				reason = "Spamming chat results in automatic kicking."
				kwargs['Broadcast'].broadcast(\
					"Kick %s \"%s\"" % (clinum, reason))
				self.LASTMESSAGE['client'] = None
				self.LASTMESSAGE['repeat'] = 0
				self.LASTMESSAGE['firsttime'] = 0
				self.LASTMESSAGE['lasttime'] = 0
			else:
				self.LASTMESSAGE['repeat'] = 0
				self.LASTMESSAGE['client'] = None
				self.LASTMESSAGE['firsttime'] = 0
				self.LASTMESSAGE['lasttime'] = 0
		
		request = re.match("request admin", message, flags=re.IGNORECASE)
		if request:
			for each in self.playerlist:
				if each['active'] and each['admin']:
					kwargs['Broadcast'].broadcast("SendMessage %s Admin present: ^y%s" % (client['clinum'], each['name']))

		#ignore everything else if it isn't from admin
		if not admin:
			return

		#Pass to superCommand if the player is a superuser
		if superuser:
			self.superCommand(message, **kwargs)
		
		#Matches for normal admins
		restart = re.match("admin restart", message, flags=re.IGNORECASE)
		shuffle = re.match("admin shuffle", message, flags=re.IGNORECASE)
		kick = re.match("admin kick (\S+)", message, flags=re.IGNORECASE)
		ban = re.match("admin ban (\S+)", message, flags=re.IGNORECASE)
		slap = re.match("admin slap (\S+)", message, flags=re.IGNORECASE)
		changeworld = re.match("admin changeworld (\S+)", message, flags=re.IGNORECASE)
		help = re.match("help", message, flags=re.IGNORECASE)
		balance = re.match("admin balance", message, flags=re.IGNORECASE)
		getbalance = re.match("admin get balance", message, flags=re.IGNORECASE)
		reportbal = re.match("admin report balance", message, flags=re.IGNORECASE)

		if restart:
			#restarts server if something catastrophically bad has happened
			kwargs['Broadcast'].broadcast("restart")

		if shuffle:
			#artificial shuffle vote
			if self.PHASE != 5:
				kwargs['Broadcast'].broadcast(\
					"SendMessage %s Cannot shuffle until the game has started!"\
					 % (client['clinum']))
				return
			
			kwargs['Broadcast'].broadcast("SendMessage -1 %s has shuffled the game." % (name))
			self.listClients(**kwargs)	
			shufflethread = threading.Thread(target=self.onShuffle, args=(clinum,None), kwargs=kwargs)
			shufflethread.start()

		if kick:
			#kicks a player from the server
			reason = "An administrator has removed you from the server, probably for being annoying"
			kickclient = self.getPlayerByName(kick.group(1))
			kwargs['Broadcast'].broadcast(\
				"Kick %s \"%s\""\
				 % (kickclient['clinum'], reason))
			
		if ban:
			#kicks a player from the server and temporarily bans that player's IP till the game is over
			reason = "An administrator has banned you from the server. You are banned till this game is over."
			kickclient = self.getPlayerByName(ban.group(1))
			kwargs['Broadcast'].broadcast(\
				"Kick %s \"%s\"" \
				 % (kickclient['clinum'], reason))
			self.banlist.append(kickclient['ip'])

		if slap:
			#slap will move a player x+100, y+200 to get them off of a structure
			
			slapclient = self.getPlayerByName(slap.group(1))
			kwargs['Broadcast'].broadcast(\
				"set _slapindex #GetIndexFromClientNum(%s)#;\
				 set _sx #GetPosX(|#_slapindex|#)#; set _sy #GetPosY(|#_slapindex|#)#; set _sz #GetPosZ(|#_slapindex|#)#;\
				 SetPosition #_slapindex# [_sx + 200] [_sy + 200] #_sz#;\
				 SendMessage %s ^cAn adminstrator has moved you for jumping on buildings. YOU WILL BE BANNED if this action persists"\
				 % (slapclient['clinum'], slapclient['clinum']))
			

		if changeworld:
			#change the map
			kwargs['Broadcast'].broadcast(\
				"changeworld %s"\
				 % (changeworld.group(1)))

		
		if balance:
			if self.PHASE != 5:
				kwargs['Broadcast'].broadcast(\
					"SendMessage %s Cannot balance if the game has not started!"\
					 % (client['clinum']))
				return

			kwargs['Broadcast'].broadcast("SendMessage -1 %s has balanced the game." % (name))
			self.listClients(**kwargs)
			balancethread = threading.Thread(target=self.onBalance, args=(clinum, None), kwargs=kwargs)
			balancethread.start()
			

		if getbalance:
			self.listClients(**kwargs)
			balancethread = threading.Thread(target=self.getBalance, args=(clinum, None), kwargs=kwargs)
			balancethread.start()


		if reportbal:
			self.listClients(**kwargs)
			balancethread = threading.Thread(target=self.reportBalance, args=(), kwargs=kwargs)
			balancethread.start()

		self.logCommand(client['name'],message)

		if help:
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s All commands on the server are done through server chat. All commands are logged to prevent you from abusing them.The following are commands and a short description of what they do."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin restart ^whard reset of the server. ONLY use in weird cases."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin shuffle ^wwill shuffle the game and set to previous phase."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmi kick playername ^wwill remove a player from the server."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin ban playername ^wwill remove a player from the server and ban that IP address till the end of the game."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin slap playername ^wwill move the player. Use to get them off of structures if they are exploiting."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin changeworld mapname ^wwill change the map to the desired map."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin balance ^wwill move two players to achieve balance."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin get balance ^wwill report avg. and median SF values for the teams as well as a stack value."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin report balance ^wwill send a message to ALL players that has the avg. and median SF values."\
				 % (client['clinum']))

	def getBalance(self, *args, **kwargs):
		clinum = args[0]
		
		for each in self.playerlist:
			each['team'] = 0
			
		time.sleep(2)
		teamone = []
		teamtwo = []

		#populate current team lists:
		for each in self.playerlist:
			if not each['active']:
				continue
			if each['team'] == 1:
				teamone.append(each)
			if each['team'] == 2:
				teamtwo.append(each)
		
		teamonestats = self.getTeamInfo(teamone)
		teamtwostats = self.getTeamInfo(teamtwo)
		stack = round(self.evaluateBalance(teamone, teamtwo),1)
		kwargs['Broadcast'].broadcast(\
		"SendMessage %s ^y Team One (%s players) Avg. SF is ^r%s^y median is ^r%s^y, Team Two (%s players) Avg. SF is ^r%s^y median is ^r%s. ^yStack value: ^r%s" \
		 % (clinum, teamonestats['size'], round(teamonestats['avg'],1), round(teamonestats['median'],1), teamtwostats['size'], round(teamtwostats['avg'],1), round(teamtwostats['median'], 1), abs(stack)))

	def reportBalance(self, **kwargs):
		
		for each in self.playerlist:
			each['team'] = 0
			
		time.sleep(2)
		teamone = []
		teamtwo = []
		#populate current team lists:
		for each in self.playerlist:
			if not each['active']:
				continue
			if each['team'] == 1:
				teamone.append(each)
			if each['team'] == 2:
				teamtwo.append(each)

		teamonestats = self.getTeamInfo(teamone)
		teamtwostats = self.getTeamInfo(teamtwo)
		stack = round(self.evaluateBalance(teamone, teamtwo), 1)
		kwargs['Broadcast'].broadcast(\
		"SendMessage -1 ^y Team One (%s players) Avg. SF is ^r%s^y median is ^r%s^y, Team Two (%s players) Avg. SF is ^r%s^y median is ^r%s.^y Stack value: ^r%s" \
		 % (teamonestats['size'], round(teamonestats['avg'],1), round(teamonestats['median'],1), teamtwostats['size'], round(teamtwostats['avg'], 1), round(teamtwostats['median'],1), abs(stack)))

	def superCommand(self, message, **kwargs):
		#This allows superuser to issue any console command
		supercommand = re.match("sudo (.*)", message, flags=re.IGNORECASE)
		
		if supercommand:
			kwargs['Broadcast'].broadcast("%s" % (supercommand.group(1)))
		
				 
	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		self.PHASE = phase
		
		if (phase == 7):
			self.banlist = []	
			for each in self.playerlist:
				each['team'] = 0
				each['commander'] = False
				each['value'] = 0
					
		if (phase == 6):
			if self.UPDATE:
			#fetch admin list and reload at the start of each game
				updatethread = threading.Thread(target=self.update, args=(), kwargs=kwargs)
				updatethread.start()	
			#check if server is empty after 2 minutes		
				pluginthread = threading.Thread(target=self.pluginreload, args=(), kwargs=kwargs)
				pluginthread.start()

			self.RegisterScripts(**kwargs)
			self.ItemList()

		if (phase == 4):
			kwargs['Broadcast'].broadcast("listclients")

	def update(self, **kwargs):
		
		
		response = urllib2.urlopen('http://188.40.92.72/admin.ini')
		adminlist = response.read()
		
		f = open(self.CONFIG, 'w')
		f.write(adminlist)
		f.close
		f.flush()
		os.fsync(f.fileno())
		self.reload_config()
		
			
		if self.NEEDRELOAD:
			self.pluginreload(**kwargs)
			return

		#Update the wrapper
		try:
			gitpath = os.path.realpath(os.path.dirname (os.path.realpath (__file__)) + "/../.git")
			command = ["git","--git-dir",gitpath,"pull"]
			output = subprocess.Popen(command, stdout=subprocess.PIPE).communicate()
			result = output[0].split("\n")[0]
			print 'result is %s' % result
			#TODO: make sure these work on all servers?
			notneeded = re.match("Already up-to-date.", result)
			needed = re.match("Updating .*", result)
		except:
			print 'error getting git update'
			return
		
		if notneeded:
			print 'update not needed'
			self.NEEDRELOAD = False
			return

		if needed:
			print 'update needed'
			self.NEEDRELOAD = True
			self.pluginreload(**kwargs)
			return

	def pluginreload(self, **kwargs):
		print 'pluginreload called'
		#Wait a couple minutes to allow clients to connect
		time.sleep(120)
		#Figure out how many clients are present
		kwargs['Broadcast'].broadcast("serverstatus")
	
	def onServerStatusResponse(self, *args, **kwargs):

		if self.NEEDRELOAD:
			gamemap = args[0]
			active = int(args[2])
			
			if active == 0:
				self.reload_plugins()
				kwargs['Broadcast'].broadcast("NextPhase; PrevPhase")
				self.NEEDRELOAD = False

	def logCommand(self, client, message, **kwargs):
		localtime = time.localtime(time.time())
		date = ("%s-%s-%s, %s:%s:%s" % (localtime[1], localtime[2], localtime[0], localtime[3], localtime[4], localtime[5]))
		f = open('admin.log', 'a')		
		f.write("Timestamp: \"%s\", Admin: %s, Command: %s\n" % (date, client, message))
		f.close

	def onTeamChange (self, *args, **kwargs):
		
		team = int(args[1])
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client['team'] = team

	def onShuffle (self, *args, **kwargs):
		
		for each in self.playerlist:
			each['team'] = 0
			each['value'] = 0

		clinum = args[0]
		time.sleep(2)
		shufflelist = []

		#Put all the active players in a list
		for each in self.playerlist:
			if not each['active']:
				continue
			if each['team'] > 0:
				shufflelist.append(each)
	
		#sort shufflelists based on SF
		shufflelist = sorted(shufflelist, key=itemgetter('sf', 'level', 'clinum'), reverse=True)
		
		#randomly choose if we begin with human or beast
		r = random.randint(1,2)
		
		#Assign new teams, just like the K2 way, but Ino won't always be on humans
		for each in shufflelist:
		#TODO: is there a cleaner, more pythonic way to do this?	
			each['team'] = r
			if r == 1:
				r += 1
			elif r == 2:
				r -=1
			
		#Now actually do the shuffling
		for each in shufflelist:
			kwargs['Broadcast'].broadcast(\
				"SetTeam #GetIndexFromClientNum(%s)# %s"\
				 % (each['clinum'], each['team']))
		#Finish it off by going forward a phase
		kwargs['Broadcast'].broadcast(\
			"nextphase")
		
		
		kwargs['Broadcast'].broadcast(\
			"SendMessage %s You have shuffled the game." % (clinum))
		#Run balancer to get it nice and even
		self.onBalance(clinum, **kwargs)
		
		
	def onBalance(self, *args, **kwargs):

		for each in self.playerlist:
			each['team'] = 0
			
		time.sleep(2)
		teamone = []
		teamtwo = []

		#populate current team lists:
		for each in self.playerlist:
			if not each['active']:
				continue
			if each['team'] == 1:
				teamone.append(each)
			if each['team'] == 2:
				teamtwo.append(each)

		#Get Information about the teams
		
		teamonestats = self.getTeamInfo(teamone)
		teamtwostats = self.getTeamInfo(teamtwo)
		startstack = self.evaluateBalance(teamone, teamtwo)
		
		#Send message to admin that called the shuffle/balance
		kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^yPrior to balance: Team One Avg. SF was ^r%s^y median was ^r%s^y, Team Two Avg. SF was ^r%s^y median was ^r%s" \
			 % (args[0], teamonestats['avg'], teamonestats['median'], teamtwostats['avg'], teamtwostats['median']))

				
		#Find the players to swap
		lowest = -1
		pick1 = None
		pick2 = None
		
		for player1 in teamone:
			if player1['commander']:
				continue
			for player2 in teamtwo:
				if player2['commander']:
					continue
				#sort of inefficient to send the teamlist each time				
				ltarget = self.evaluateBalance(teamone, teamtwo, player1, player2, True)
				
				if (lowest < 0):
					lowest = ltarget
					pick1 = player1
					pick2 = player2
					continue
			
				if (lowest < ltarget):
					continue
			
				lowest = ltarget
				pick1 = player1
				pick2 = player2

		#If the stack isn't improved, abort it
		if (lowest >= startstack):
			print 'unproductive balance. terminate'
			kwargs['Broadcast'].broadcast(\
				"echo unproductive balance")
			return
		#Do the switch
		kwargs['Broadcast'].broadcast(\
			"set _index #GetIndexFromClientNum(%s)#;\
			 SetTeam #_index# 2;\
			 set _index #GetIndexFromClientNum(%s)#;\
			 SetTeam #_index# 1"\
			 % (pick1['clinum'], pick2['clinum']))
		
		#Give them gold if needed
		self.giveGold(True, pick1, **kwargs)
		self.giveGold(True, pick2, **kwargs)

		teamonestats = self.getTeamInfo(teamone)
		teamtwostats = self.getTeamInfo(teamtwo)

		#kwargs['Broadcast'].broadcast(\
		#	"SendMessage %s ^yAfter balance: Team One Avg. SF was ^r%s^y median was ^r%s^y, Team Two Avg. SF was ^r%s^y median was ^r%s"\
		#	 % (clinum, teamonestats['avg'], teamonestats['median'], teamtwostats['avg'], teamtwostats['median']))


	def getTeamInfo(self, teamlist, **kwargs):
		
		teamsf = []
		combteamsf = float(0)		
		#figure out current averages and set some commonly used variables:
		for each in teamlist:
			combteamsf += each['sf']
			teamsf.append(each['sf'])
	
		sizeteam = len(teamlist)
		avgteam = combteamsf/sizeteam
		med = median(teamsf)
		
		teaminfo = {'size' : sizeteam, 'avg' : avgteam, 'total' : combteamsf, 'median' : med}
		
		return teaminfo

	def evaluateBalance(self, team1, team2, pick1=None, pick2=None, swap=False, **kwargs):
		#This function will swap out the picked players in a temporary list if swap is true and report the stack percent
		#If swap is false, it will just report the balance		
		#First, make new lists that we can modify:
		teamone = list(team1)
		teamtwo = list(team2)
		
		if swap:
			#Remove those players from the lists...		
			for each in teamone:
				if each['clinum'] == pick1['clinum']:
					teamone.remove(each) 
			for each in teamtwo:
				if each['clinum'] == pick2['clinum']:
					teamtwo.remove(each) 
		
			#Add to the lists		
			teamone.append(pick2)
			teamtwo.append(pick1)

		#Get the new team stats...
		teamonestats = self.getTeamInfo(teamone)
		teamtwostats = self.getTeamInfo(teamtwo)
		
		#Evaluate team balance
		teamoneshare = teamonestats['total']/(teamonestats['total'] + teamtwostats['total'])
		diffmedone = teamonestats['median']/(teamonestats['median'] + teamtwostats['median'])
		stack = teamoneshare + diffmedone
		#positive if team one is stacked, negative if team two is stacked
		return (stack - 1) * 100

	def onCommResign(self, *args, **kwargs):
	
		name = args[0]	
		client = self.getPlayerByName(name)
		client['commander'] = False
		
	
	def onUnitChange(self, *args, **kwargs):
		if args[1] != "Player_Commander":
			return

		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client['commander'] = True

	def listClients(self, *args, **kwargs):

		kwargs['Broadcast'].broadcast("listclients")

	def onListClients(self, *args, **kwargs):
		clinum = args[0]
		name = args[2]
		ip = args[1]
		

		client = self.getPlayerByName(name)
		if not client:
		#if a player is missing from the list this will put them as an active player and get stats
		#TODO: listclients clinum is always double diget (00, 01, etc.) so this might be a problem
			acct = self.ms.getAccount(name)
			acctid = acct[name]
			self.onConnect(clinum, 0000, ip, 0000, **kwargs)
			self.onSetName(clinum, name, **kwargs)
			self.onAccountId(clinum, acctid, **kwargs)
			client = self.getPlayerByName(name)
			
		client['active'] = True
		kwargs['Broadcast'].broadcast(\
		"echo CLIENT %s is on TEAM #GetTeam(|#GetIndexFromClientNum(%s)|#)#"\
		 % (client['clinum'], client['clinum']))
		
		
	def onRefreshTeams(self, *args, **kwargs):
		clinum = args[0]
		team = int(args[1])
		client = self.getPlayerByClientNum(clinum)
		client['team'] = team

	def ItemList(self, *args, **kwargs):
		
		self.itemlist = {
			'Advanced Sights' : 700,
			'Ammo Pack' : 500,
			'Ammo Satchel' : 200,
			'Chainmail' : 300,
			'Gust of Wind' : 450,
			'Magic Amplifier' : 700,
			'Brain of Maliken' : 750,
			'Heart of Maliken' : 950,
			'Lungs of Maliken' : 800,
			'Mana Crystal' : 500,
			'Mana Stone' : 200,
			'Platemail' : 650,
			'Power Absorption' : 350,
			'Shield of Wisdom' : 650,
			'Stone Hide' : 650,
			'Tough Skin' : 300,
			'Trinket of Restoration' : 575
		}


	def onItemTransaction(self, *args, **kwargs):
		#adjust 'value' in playerlist to reflect what the player has bought or sold
		cli = args[0]
		trans = args[1]
		newitem = args[2]
		client = self.getPlayerByClientNum(cli)

		try:
			value = self.itemlist[newitem]
		except:
			return
		
		if (trans == 'BOUGHT'):
			client['value'] += value
		elif (trans == 'SOLD'):
			client['value'] -= value
		

	def giveGold(self, balance, client, **kwargs):

		if client['value'] == 0:

			return
		
		gold = round(client['value']/2, 0)

		if balance:
			gold = client['value']

		kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^cYou have been compensated %s gold for your lost items.; GiveGold %s %s"\
			 % (client['clinum'], gold, client['clinum'], gold))
		
		client['value'] = 0
Ejemplo n.º 9
0
class pug(ConsolePlugin):
	VERSION = "1.0.1"
	ms = None
	PHASE = 0
	STARTSTAMP = 0
	STARTED = False
	PICKING = False
	HUMANPICK = False
	playerlist = []
	startinfo = {'h_captain' : None, 'h_ready' : False, 'h_first' : False, 'b_captain' : None, 'b_ready' : False, 'b_first' : False}
	teamlist = [];
	TIME = 0
	
	def onPluginLoad(self, config):
		self.ms = MasterServer ()

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		'''
		for (name, value) in ini.items('var'):
			if (name == "clan1"):
				self.CLAN1 = value
			if (name == "clan2"):
				self.CLAN2 = value
		'''
		pass


	def onStartServer(self, *args, **kwargs):
		
		self.PHASE = 0
		self.playerlist = []
		self.startinfo = {'h_captain' : None, 'h_ready' : False, 'h_first' : False, 'b_captain' : None, 'b_ready' : False, 'b_first' : False}

	def getPlayerByClientNum(self, cli):

		for client in self.playerlist:
			if (client['clinum'] == cli):
				return client


	def getPlayerByName(self, name):

		for client in self.playerlist:
			if (client['name'].lower() == name.lower()):
				return client


	def onConnect(self, *args, **kwargs):
		
		id = args[0]
		ip = args[2]
		
		for client in self.playerlist:
			if (client['clinum'] == id):
				return
		
		self.playerlist.append ({'clinum' : id,\
					 'acctid' : 0,\
					 'level' : 0,\
					 'ip' : ip,\
					 'sf' : 0,\
					 'name' : 'X',\
					 'active' : False,\
					 'team' : 0,\
					 'ping' : 0,\
					 'clan' : 'X'})

		#kwargs['Broadcast'].broadcast("SendMessage %s ^cTo toggle your PUG availability send the chat message ^rpug noplay" % (id))
		
	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client ['active'] = False
	
		if client['clinum'] == self.startinfo['h_captain']:
			self.startinfo['h_captain'] = None
			self.startinfo['h_ready'] = False
			kwargs['Broadcast'].broadcast("set State_Interrupted_EffectPath \"trigger UpdateDetail 1\"; set Pet_HumanWorker_Inventory9 \"\";")
			if self.PICKING:
				resetall(**kwargs)
		if client['clinum'] == self.startinfo['b_captain']:
			self.startinfo['b_captain'] = None
			self.startinfo['b_ready'] = False
			kwargs['Broadcast'].broadcast("set Gadget_Hail_ModelPath \"trigger UpdateError 1\"; set Pet_BeastWorker_Inventory9 \"\";")
			if self.PICKING:
				resetall(**kwargs)
				
	def onSetName(self, *args, **kwargs):

		cli = args[0]
		playername = args[1]
		client = self.getPlayerByClientNum(cli)
		client ['name'] = playername					
		client ['play'] = True
		kwargs['Broadcast'].broadcast("ClientExecScript %s clientdo cmd  \"showwidget pug_button\"" % (cli))

	def onAccountId(self, *args, **kwargs):

		cli = args[0]
		id = args[1]
		stats = self.ms.getStatistics (id).get ('all_stats').get (int(id))
		
		level = int(stats['level'])
		sf = int(stats['sf'])
		exp = int(stats['exp'])
		time = int(stats['secs'])
		time = time/60
		#sf = int(exp/time)
		clan = stats['clan_tag']
		client = self.getPlayerByClientNum(cli)
		
		client ['acctid'] = int(id)
		client ['level'] = level
		client ['sf'] = sf
		client ['active'] = True
		client ['clan'] = clan
		client ['newteam'] = 0
		
		kwargs['Broadcast'].broadcast("ClientExecScript %s clientdo cmd  \"showwidget pug_button\"" % (cli))

		if self.PICKING:
			kwargs['Broadcast'].broadcast("ClientExecScript %s clientdo cmd  \"hidewidget team_button0; hidewidget team_button1\"" % (cli))

	def onTeamChange (self, *args, **kwargs):

		team = int(args[1])
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client['team'] = team
		
		if self.PICKING:
			
			for each in self.teamlist:
				if (each['player'] == cli) and (team != each['team']):
					#don't let them switch
					kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# %s" % (each['player'],each['team']))
					return
						
				#kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 0" % (each['player']))
			
	def onGameStart (self, *args, **kwargs):
		
		self.STARTSTAMP = args[1]

	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		self.PHASE = phase

		if phase == 5:
			self.STARTSTAMP = args[1]
			self.STARTED = True
			self.PICKING = False
			
		if phase == 6:
			self.PICKING = False
			self.teamlist = []
			self.startinfo = {'h_captain' : None, 'h_ready' : False, 'h_first' : False, 'b_captain' : None, 'b_ready' : False, 'b_first' : False}
			kwargs['Broadcast'].broadcast("set State_SuccessfulBlock_Description -1;\
							set State_Interrupted_EffectPath \"trigger UpdateDetail 1\";\
							set Gadget_Hail_ModelPath \"trigger UpdateError 1\";\
							set State_ImpPoisoned_Name \"trigger UpdateSpeed 1\";\
							set Gadget_Hail_Description \"trigger UpdatePercent -1\";\
							set State_ImpPoisoned_ExpiredEffectPath \"trigger UpdateExtraction 1\";\
							set maxteams 3;\
							set sv_maxteamdifference 10;\
							set Pet_Shaman_Prerequisite 1;\
							set Pet_HumanWorker_Inventory9 \"\";\
							set Pet_BeastWorker_Inventory9 \"\";")
			kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"echo SCRIPT Client #GetScriptParam(clientid)# #GetScriptParam(what)# with value #GetScriptParam(value)#; echo\" scriptinput")
			kwargs['Broadcast'].broadcast("ClientExecScript -1 clientdo cmd  \"showwidget team_button0; showwidget team_button1\"")

		if phase == 7:
			for each in self.playerlist:
				each['newteam'] = 0
			self.PICKING = False
			self.STARTED = False
			resetall(**kwargs)
	
	def togglePlay(self, client, playing=None, **kwargs):
		color = '^g'
		if self.PICKING:
				kwargs['Broadcast'].broadcast("SendMessage %s ^rYou cannot toggle your status once picking has begun." % (client['clinum']))
				return
		if not playing:
			if client['play']:
				client['play'] = False
				color = '^r'
			else:
				client['play'] = True
		else:
			client['play'] = playing
			if not client['play']:
				color = '^r' 
		#kwargs['Broadcast'].broadcast("SendMessage %s ^cYour Playing Status: %s%s" % (client['clinum'], color, client['play']))
	
	
	def onScriptEvent(self, *args, **kwargs):		
		
		caller = args[0]
		client = self.getPlayerByClientNum(caller)
		event = args[1]
		value = args[2]
		#info = self.startinfo
		
		#Captain initiated
		if event == 'Captain':
			#If they are already captain, do nothing
			if caller == self.startinfo['b_captain'] or caller == self.startinfo['h_captain']:
				return
			#Beasts, set captain
			if value == 'beasts':
				self.startinfo['b_captain'] = caller
				kwargs['Broadcast'].broadcast("set Gadget_Hail_ModelPath \"trigger UpdateError 0\"; set Pet_BeastWorker_Inventory9 \"%s\"" % (client['name']))
				if not self.startinfo['h_captain']:
					self.startinfo['h_first'] = True
			#Humans, set captain
			if value == 'humans':
				self.startinfo['h_captain'] = caller
				kwargs['Broadcast'].broadcast("set State_Interrupted_EffectPath \"trigger UpdateDetail 0\"; set Pet_HumanWorker_Inventory9  \"%s\"" % (client['name']))
				if not self.startinfo['b_captain']:
					self.startinfo['b_first'] = True
			#Check if picking is initiated, if so determine who gets the next picking
			if self.PICKING:
				self.setpicking(**kwargs)
				return			
			#Start picking process through the normal mechanism
			if self.startinfo['h_captain'] and self.startinfo['b_captain']:
				self.beginpicking(**kwargs)

		#Toggle player availability
		if event == 'Toggle':
			playing = False
			if value == 'true':
				playing = True

			self.togglePlay(client, playing, **kwargs)
			
		#Player select
		if event == 'Select':
			player = self.getPlayerByName(value)
			#switch everything to ingame_picking function if the game is already started
			
			if self.PHASE == 5:
				#pickthread = threading.Thread(target=self.ingame_picking, args=(caller, client, player, None), kwargs=kwargs)
				#pickthread.start()
				#self.ingame_picking(caller, client, player, **kwargs)
				print 'Will go to ingame picking'
			if caller == self.startinfo['h_captain']:
				#check players status
				if not player['play']:
					kwargs['Broadcast'].broadcast("SendMessage %s ^rThat player has requested to not play in this match." % (client['clinum']))
					return
			
				player['newteam'] = 1
				client['newteam'] = 1
				self.teamlist.append({"player" : player["clinum"], "team" : 1});
				kwargs['Broadcast'].broadcast("SendMessage -1 ^r%s^w has selected ^y%s ^wfor the Humans!" % (client['name'], player['name']))
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 1" % (player['clinum']))
				kwargs['Broadcast'].broadcast("set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\"" % (self.startinfo['b_captain'], self.startinfo['b_captain']))
				self.HUMANPICK = False
				
			if caller == self.startinfo['b_captain']:
				if not player['play']:
					kwargs['Broadcast'].broadcast("SendMessage %s ^rThat player has requested to not play in this match." % (client['clinum']))
					return
				player['newteam'] = 2
				client['newteam'] = 2
				self.teamlist.append({"player" : player["clinum"], "team" : 2});
				kwargs['Broadcast'].broadcast("SendMessage -1 ^r%s^w has selected ^y%s ^wfor the Beasts!" % (client['name'], player['name']))
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 2" % (player['clinum']))
				kwargs['Broadcast'].broadcast("set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\"" % (self.startinfo['h_captain'],self.startinfo['h_captain'] ))
				self.HUMANPICK = True
				
			if self.PICKING:
				self.setpicking(**kwargs)
		#Ready
		if event == 'Ready':

			if self.STARTED:
				return
			if caller == self.startinfo['h_captain']:
				if self.startinfo['h_ready']:
					return
				self.startinfo['h_ready'] = True
				kwargs['Broadcast'].broadcast("SendMessage -1 ^r%s^w has indicated that Humans are ready!" % (client['name']))
			if caller == self.startinfo['b_captain']:
				if self.startinfo['b_ready']:
					return
				self.startinfo['b_ready'] = True
				kwargs['Broadcast'].broadcast("SendMessage -1 ^r%s^w has indicated that Beasts are ready!" % (client['name']))
			#Start the game if both captains say they are ready
			if self.startinfo['h_ready'] and self.startinfo['b_ready']:
				kwargs['Broadcast'].broadcast("set State_ImpPoisoned_Name \"trigger UpdateSpeed 0\"")
				self.populate(**kwargs)
		
		if event == 'Resign':
		#if pick has begun and a captain resigns, just reset the whole damn thing
			if self.PICKING:
				self.resetall(**kwargs);
				
			if client['clinum'] == self.startinfo['h_captain']:
				
				self.startinfo['h_captain'] = None
				self.startinfo['h_ready'] = False
				kwargs['Broadcast'].broadcast("set State_Interrupted_EffectPath \"trigger UpdateDetail 1\"; set Pet_HumanWorker_Inventory9 \"\";")
				
			if client['clinum'] == self.startinfo['b_captain']:
				
				self.startinfo['b_captain'] = None
				self.startinfo['b_ready'] = False
				kwargs['Broadcast'].broadcast("set Gadget_Hail_ModelPath \"trigger UpdateError 1\"; set Pet_BeastWorker_Inventory9 \"\";")
				
			#self.setpicking(**kwargs)
	
	def resetall(self, **kwargs):
		self.PICKING = False
		self.teamlist = []
		self.startinfo = {'h_captain' : None, 'h_ready' : False, 'h_first' : False, 'b_captain' : None, 'b_ready' : False, 'b_first' : False}
		kwargs['Broadcast'].broadcast("set State_SuccessfulBlock_Description -1;\
							set State_Interrupted_EffectPath \"trigger UpdateDetail 1\";\
							set Gadget_Hail_ModelPath \"trigger UpdateError 1\";\
							set State_ImpPoisoned_Name \"trigger UpdateSpeed 1\";\
							set Gadget_Hail_Description \"trigger UpdatePercent -1\";\
							set State_ImpPoisoned_ExpiredEffectPath \"trigger UpdateExtraction 1\";\
							set maxteams 3;\
							set sv_maxteamdifference 10;\
							set Pet_Shaman_Prerequisite 1;\
							set Pet_HumanWorker_Inventory9 \"\";\
							set Pet_BeastWorker_Inventory9 \"\";")
			
		kwargs['Broadcast'].broadcast("ClientExecScript -1 clientdo cmd  \"showwidget team_button0; showwidget team_button1\"")
		
		for each in self.playerlist:
			if each['active']:
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 0; SendMessage -1 ^yTeams are reset after captain resignation." % (each['clinum']))
		
	def RegisterStart(self, **kwargs):
		self.PICKING = True
								
	def beginpicking(self, **kwargs):
		#move everyone to spec
		for each in self.playerlist:
			if each['active']:
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 0" % (each['clinum']))
				
		
		self.teamlist = [];
		#start by making the teams unjoinable
		kwargs['Broadcast'].broadcast("set sv_setupTimeCommander 600000000; set sv_maxteamdifference 1; set State_ImpPoisoned_ExpiredEffectPath \"trigger UpdateExtraction 0\";")
		kwargs['Broadcast'].broadcast("ClientExecScript -1 clientdo cmd  \"hidewidget team_button0; hidewidget team_button1\"")

		#move captains to the appropriate team and have them switch back to lobby
		for each in self.playerlist:
			if each['clinum'] == self.startinfo['h_captain']:
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 1" % (each['clinum']))
			if each['clinum'] == self.startinfo['b_captain']:
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 2" % (each['clinum']))
		kwargs['Broadcast'].broadcast("ClientExecScript %s clientdo cmd  \"Action ToggleLobby\"" % (self.startinfo['h_captain']))
		kwargs['Broadcast'].broadcast("ClientExecScript %s clientdo cmd  \"Action ToggleLobby\"" % (self.startinfo['b_captain']))
		self.teamlist.append({"player" : self.startinfo['h_captain'], "team" : 1});
		self.teamlist.append({"player" : self.startinfo['b_captain'], "team" : 2});
		#Set variables to get the first captain to start picking
		if self.startinfo['h_first']:
			self.HUMANPICK = True
			self.setpicking(**kwargs)
		else:
			self.HUMANPICK = False
			self.setpicking(**kwargs)
			
		kwargs['Broadcast'].broadcast("echo STARTTOURNEY")
		
	def populate(self, **kwargs):
	
		for each in self.playerlist:
			if each['active']:
				kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# %s" % (each['clinum'], each['newteam']))
		#Send to the next phase
		kwargs['Broadcast'].broadcast("NextPhase; set sv_setupTimeCommander 60000; PrevPhase")
		
	def onListClients(self, *args, **kwargs):
		clinum = args[0]
		name = args[2]
		ip = args[1]
		
		try:
			client = self.getPlayerByName(name)
		except:
		#if a player is missing from the list this will put them as an active player
			acct = self.ms.getAccount(name)
			acctid = acct[name]
			self.onConnect(clinum, 0000, ip, 0000, **kwargs)
			self.onSetName(clinum, name, **kwargs)
			self.onAccountId(clinum, acctid, **kwargs)

	def onServerStatus(self, *args, **kwargs):
		if self.STARTED != 1:
			return
		pickthread = threading.Thread(target=self.ingame_picking, args=(), kwargs=kwargs)
		pickthread.start()

	def ingame_picking(self, *args, **kwargs):
		
		self.listClients(self, **kwargs)
		teamone = []
		teamtwo = []		
		time.sleep(1)
		
		#populate current team lists:
		for each in self.playerlist:
			if not each['active']:
				continue
			if each['team'] == 1:
				teamone.append(each)
			if each['team'] == 2:
				teamtwo.append(each)
				
		#figure out who gets the pick
		team1 = len(teamone)
		team2 = len(teamtwo)
		
		if team1 > team2:
			self.HUMANPICK = False
			self.setpicking(**kwargs)
		if team2 > team1:
			self.HUMANPICK = True
			self.setpicking(**kwargs)
		
		if team1 == team2:
			return
		

			
	def listClients(self, *args, **kwargs):

		kwargs['Broadcast'].broadcast("listclients")

	def onListClients(self, *args, **kwargs):
		clinum = args[0]
		name = args[2]
		ip = args[1]
		

		client = self.getPlayerByName(name)
		if not client:
		#if a player is missing from the list this will put them as an active player and get stats
		#TODO: listclients clinum is always double diget (00, 01, etc.) so this might be a problem
			acct = self.ms.getAccount(name)
			acctid = acct[name]
			self.onConnect(clinum, 0000, ip, 0000, **kwargs)
			self.onSetName(clinum, name, **kwargs)
			self.onAccountId(clinum, acctid, **kwargs)
			client = self.getPlayerByName(name)
			
		client['active'] = True
		kwargs['Broadcast'].broadcast(\
		"echo CLIENT %s is on TEAM #GetTeam(|#GetIndexFromClientNum(%s)|#)#"\
		 % (client['clinum'], client['clinum']))
		 
	def onRefreshTeams(self, *args, **kwargs):
		clinum = args[0]
		team = int(args[1])
		client = self.getPlayerByClientNum(clinum)
		client['team'] = team


	def setpicking(self, **kwargs):

		if self.HUMANPICK:
			kwargs['Broadcast'].broadcast("set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\"" % (self.startinfo['h_captain'],self.startinfo['h_captain'] ))
		else:
			kwargs['Broadcast'].broadcast("set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\"" % (self.startinfo['b_captain'], self.startinfo['b_captain']))
Ejemplo n.º 10
0
class helper(ConsolePlugin):
    VERSION = "0.0.1"
    playerlist = []
    helperlist = []
    PHASE = 0
    CONFIG = None

    def onPluginLoad(self, config):

        self.ms = MasterServer()
        self.CONFIG = config
        ini = ConfigParser.ConfigParser()
        ini.read(config)

        for (name, value) in ini.items('helpers'):
            self.helperlist.append({'name': name, 'level': value})

        pass

    def reload_config(self):

        self.helperlist = []
        self.ipban = []
        ini = ConfigParser.ConfigParser()
        ini.read(self.CONFIG)

        for (name, value) in ini.items('helpers'):
            self.helperlist.append({'name': name, 'level': value})

    def onStartServer(self, *args, **kwargs):

        self.playerlist = []

    def getPlayerByClientNum(self, cli):

        for client in self.playerlist:
            if (client['clinum'] == cli):
                return client

    def getPlayerByName(self, name):

        for client in self.playerlist:
            if (client['name'].lower() == name.lower()):
                return client

    def onConnect(self, *args, **kwargs):

        id = args[0]

        for client in self.playerlist:
            if (client['clinum'] == id):
                return

        self.playerlist.append ({'clinum' : id,\
            'acctid' : 0,\
            'name' : 'X',\
            'active' : False,\
            'helper' : False,\
            'level' : 0})

    def onDisconnect(self, *args, **kwargs):

        cli = args[0]
        client = self.getPlayerByClientNum(cli)
        client['active'] = False

    def onSetName(self, *args, **kwargs):

        cli = args[0]
        playername = args[1]
        client = self.getPlayerByClientNum(cli)
        client['name'] = playername

    def onAccountId(self, *args, **kwargs):

        cli = args[0]
        id = args[1]
        stats = self.ms.getStatistics(id).get('all_stats').get(int(id))
        level = int(stats['level'])
        sf = int(stats['sf'])

        client = self.getPlayerByClientNum(cli)
        client['sf'] = sf
        client['level'] = level
        client['active'] = True
        client['helper'] = False

        if client['level'] <= 10:
            self.helperNotify(client, **kwargs)

        for each in self.helperlist:
            if client['name'].lower() == each['name']:
                client['helper'] = True

    def onPhaseChange(self, *args, **kwargs):
        phase = int(args[0])
        self.PHASE = phase

        if (phase == 7):
            self.banlist = []
            for each in self.playerlist:
                each['team'] = 0
                each['commander'] = False

        if (phase == 6):
            #fetch helper list and reload at the start of each game
            updatethread = threading.Thread(target=self.update,
                                            args=(),
                                            kwargs=kwargs)
            updatethread.start()

    def update(self, **kwargs):

        response = urllib2.urlopen('http://188.40.92.72/helper.ini')
        helperlist = response.read()

        f = open(self.CONFIG, 'w')
        f.write(helperlist)
        f.close
        f.flush()
        os.fsync(f.fileno())
        self.reload_config()

    def helperNotify(self, client, **kwargs):

        activehelpers = []

        for player in self.playerlist:
            if player['helper'] and player['active']:
                activehelpers.append(player['name'])

        activestring = ', '.join(activehelpers)

        kwargs['Broadcast'].broadcast(\
        "SendMessage %s ^rATTENTION: ^cAs a new player it so good to get help from more experienced players. The following players on this server have \
		indicated their willingness to help newer players: ^y%s. ^cYou can contact them by using chat (^wCTRL+ENTER^c) and whispering them (^y/w playername^c with your message)."
          % (client['clinum'], activestring))

    def onListClients(self, *args, **kwargs):
        clinum = args[0]
        name = args[2]
        ip = args[1]

        client = self.getPlayerByName(name)
        if not client:
            #if a player is missing from the list this will put them as an active player
            acct = self.ms.getAccount(name)
            acctid = acct[name]
            self.onConnect(clinum, 0000, ip, 0000, **kwargs)
            self.onSetName(clinum, name, **kwargs)
            self.onAccountId(clinum, acctid, **kwargs)
Ejemplo n.º 11
0
class extras(ConsolePlugin):
    VERSION = "1.2.2"
    ms = None
    CHAT_INTERVAL = 10
    CHAT_STAMP = 0
    playerlist = []
    itemlist = []
    followlist = []
    FOLLOWERS = 4
    MAPSIZE = 0
    MAPSIZESET = False
    buildingprotect = False

    def onPluginLoad(self, config):
        self.ms = MasterServer()

        ini = ConfigParser.ConfigParser()
        ini.read(config)

        pass

    def RegisterScripts(self, **kwargs):

        #Setup everything for following
        self.followlist = []
        followers = 1
        framestring = ""

        while followers <= self.FOLLOWERS:
            followstring = ("\
					RegisterGlobalScript -1 \"set _follower{0} #GetIndexFromClientNum(|#_f{0}|#)#;\
					set _followed{0} #GetIndexFromClientNum(|#_fd{0}|#)#;\
					set _fx{0} #GetPosX(|#_followed{0}|#)#;\
					set _fy{0} #GetPosY(|#_followed{0}|#)#;\
					set _x{0} #GetPosX(|#_follower{0}|#)#;\
					set _y{0} #GetPosY(|#_follower{0}|#)#;\
					set _z{0} #GetPosZ(|#_follower{0}|#)#;\
					set _zs{0} #_x{0}#, #_y{0}#;\
					set _zt{0} #GetTerrainHeight(|#_zs{0}|#)#;\
					if [_z{0} < _zt{0}] set _z{0} [_zt{0} + 50];\
					set _followX{0} 200;\
					set _followY{0} 200;\
					SetPosition #_follower{0}# [_fx{0} + _followX{0}] [_fy{0} + _followY{0}] [_z{0}]\" follow{0}"
                            ).format(followers)

            framestring += (
                ";if [_f{0} >= 0] ExecScript follow{0}").format(followers)
            kwargs['Broadcast'].broadcast("%s" % (followstring))
            f = "_f{0}".format(followers)
            fd = "_fd{0}".format(followers)
            kwargs['Broadcast'].broadcast("set %s -1; set %s -1" % (f, fd))
            self.followlist.append({
                'follower': -1,
                'followed': -1,
                'f': f,
                'fd': fd
            })
            followers += 1

        kwargs['Broadcast'].broadcast(
            "RegisterGlobalScript -1 \"set _ii 0%s\" frame" % (framestring))

    def getPlayerByClientNum(self, cli):

        client = None

        for client in self.playerlist:
            if (client['clinum'] == cli):
                return client

    def getPlayerByName(self, name):

        client = None

        for client in self.playerlist:
            if (client['name'].lower() == name.lower()):
                return client

    def onPhaseChange(self, *args, **kwargs):
        phase = int(args[0])

        if phase == 5:

            self.RegisterScripts(**kwargs)

        if phase == 6:

            self.RegisterScripts(**kwargs)

            #remove stuck for players
            for each in self.playerlist:
                each['stuck'] = False
            #set buildig protect scripts

            #TODO: make sure the place it moves them is a valid position
            if self.buildingprotect:
                kwargs['Broadcast'].broadcast("\
				RegisterGlobalScript -1 \"RegisterEntityScript #GetScriptParam(index)# death \\\"Set _dead\
					#GetScriptParam(index)#; ExecScript Death\\\";\
				set _index #GetScriptParam(index)#; set _mz 350;\
				set _type #GetScriptParam(type)#; echo #_type#; if #StringEquals(|#_type|#,Building_HumanHellShrine)#\
				set _mz 2000; if #StringEquals(|#_type|#,Building_ArrowTower)# set _mz 2000;\
				if #StringEquals(|#_type|#,Building_CannonTower)# set _mz 2000;\
				if #StringEquals(|#_type|#,Building_ChlorophilicSpire)# set _mz 2000;\
				if #StringEquals(|#_type|#,Building_EntangleSpire)# set _mz 2000;\
				if #StringEquals(|#_type|#,Building_ShieldTower)# set _mz 2000;\
				if #StringEquals(|#_type|#,Building_StrataSpire)# set _mz 2000;\
				set _x #GetPosX(|#_index|#)#;\
				set _y #GetPosY(|#_index|#)#;\
				set _z #GetPosZ(|#_index|#)#;\
				SpawnEntityatEntity #_index# Trigger_Proximity model /core/null/null.mdf name DeathTrigger#_index# triggeronplayer 1 triggerradius\
					 250 triggerenter\
					 \\\"set _domove 1; set _xindex #GetScriptParam(index)#;\
					 set _xtype #GetType(|#_xindex|#)#;\
					 if #StringEquals(|#_xtype|#,Player_Behemoth)# set _domove 0;\
					 if #StringEquals(|#_xtype|#,Player_Malphas)# set _domove 0;\
					 if #StringEquals(|#_xtype|#,Player_Devourer)# set _domove 0;\
					 set _xx #GetPosX(|#_xindex|#)#;\
					 set _xy #GetPosY(|#_xindex|#)#;\
					 set _xz #GetPosZ(|#_xindex|#)#;\
					 if [_domove == 1] SetPosition #_xindex# [_xx + 300] [_xy - 300] #_xz#\\\";\
				 SetPosition #GetIndexFromName(DeathTrigger|#_index|#)# #_x# #_y# [_z + _mz];\
				 echo\" buildingplaced")

                kwargs['Broadcast'].broadcast(
                    "RegisterGlobalScript -1 \"RemoveEntity #GetIndexFromName(DeathTrigger|#_dead|#)#; echo\" Death"
                )
            #get the map size
            #removing this for now as it is not used. Old55 2/10/12
            #mapthread = threading.Thread(target=self.getMapSize, args=(), kwargs=kwargs)
            #mapthread.start()

        if phase == 7:
            for each in self.playerlist:
                each['team'] = 0
            self.MAPSIZESET = False

    def onConnect(self, *args, **kwargs):

        id = args[0]

        for client in self.playerlist:
            if (client['clinum'] == id):
                return

        self.playerlist.append ({
         'clinum' : id,\
         'acctid' : 0,\
         'level' : 0,\
         'sf' : 0,\
         'lf' : 0,\
         'name' : 'X',\
         'team' : 0,\
         'stuck' : False,\
         'index' : 0,\
         'exp' : 2,\
         'value' : 150,\
         'prevent' : 0,\
         'active' : False,\
         'gamelevel' : 1})

    def onDisconnect(self, *args, **kwargs):

        cli = args[0]
        client = self.getPlayerByClientNum(cli)
        client['active'] = False

        for each in self.followlist:
            if each['follower'] == client['clinum'] or each[
                    'followed'] == client['clinum']:
                each['follower'] = -1
                each['followed'] = -1
                self.follow(**kwargs)

    def onSetName(self, *args, **kwargs):

        cli = args[0]
        playername = args[1]

        client = self.getPlayerByClientNum(cli)
        client['name'] = playername
        mapmessage = "^cSpectators on this server can follow individual players. Send the message: ^rfollow playername. ^cTo stop following: ^rstop follow.\
			      ^cIf you get stuck on the map you can send the message: ^rstuck^c to nudge you out of your spot. This can be used once a game."

        kwargs['Broadcast'].broadcast("SendMessage %s %s" %
                                      (client['clinum'], mapmessage))

    def onAccountId(self, *args, **kwargs):

        cli = args[0]
        id = args[1]
        stats = self.ms.getStatistics(id).get('all_stats').get(int(id))

        level = int(stats['level'])
        sf = int(stats['sf'])
        lf = int(stats['lf'])
        exp = int(stats['exp'])
        time = int(stats['secs'])

        client = self.getPlayerByClientNum(cli)

        client['acctid'] = int(id)
        client['level'] = level
        client['sf'] = sf
        client['lf'] = lf
        client['exp'] = exp
        client['active'] = True

    def onTeamChange(self, *args, **kwargs):

        team = int(args[1])
        cli = args[0]

        client = self.getPlayerByClientNum(cli)
        client['team'] = team

        for each in self.followlist:
            if each['follower'] == client['clinum'] or each[
                    'followed'] == client['clinum']:
                each['follower'] = -1
                each['followed'] = -1
                self.follow(**kwargs)

    def onMessage(self, *args, **kwargs):

        name = args[1]
        message = args[2]

        client = self.getPlayerByName(name)

        #Various chat matches
        followed = re.match("follow (\S+)", message, flags=re.IGNORECASE)
        stopfollow = re.match("stop follow", message, flags=re.IGNORECASE)
        stuck = re.match("stuck", message, flags=re.IGNORECASE)

        if followed:
            action = 'start'
            followed_player = self.getPlayerByName(followed.group(1))
            if followed_player == None:
                kwargs['Broadcast'].broadcast(\
                "SendMessage %s ^cCould not find a player by that name." % (client['clinum']))
                return

            if (followed_player['team'] > 0) and (client['team'] == 0):
                self.followaction(action, client, followed_player, **kwargs)

        if stopfollow:
            action = 'stop'
            self.followaction(action, client, followed_player=None, **kwargs)

        if stuck:
            if client['stuck']:
                return
            kwargs['Broadcast'].broadcast(\
             "set _stuckindex #GetIndexFromClientNum(%s)#;\
				 set _X [rand*100]; echo #_X#;\
				 set _Y [rand*100]; echo #_Y#;\
				 set _stuckx #GetPosX(|#_stuckindex|#)#;\
				 set _stucky #GetPosY(|#_stuckindex|#)#;\
				 set _stuckz #GetPosZ(|#_stuckindex|#)#;\
				 SetPosition #_stuckindex# [_stuckx + _X] [_stucky + _Y] [_stuckz + 40]"                                                                                      % (client['clinum']))

            client['stuck'] = True

    def onScriptEvent(self, *args, **kwargs):

        caller = args[0]
        client = self.getPlayerByClientNum(caller)
        event = args[1]
        value = args[2]

        if event == 'Follow':
            #Determine if it is follow or stop
            if value == 'stop':
                action = value
                self.followaction(action,
                                  client,
                                  followed_player=None,
                                  **kwargs)
                return
            else:
                action = 'start'
                followed_player = self.getPlayerByName(value)
                if (followed_player['team'] > 0) and (client['team'] == 0):
                    self.followaction(action, client, followed_player,
                                      **kwargs)
                    return

        #if event == 'SetMapPosition':

        #	if client['team'] != 0:
        #		return

        #	maxcoord = ((self.MAPSIZE - 1) * 64 * 64)
        #	print maxcoord
        #	location = re.match("(0\.\d+)_(0.\d+)", value)
        #	print location.group(1), location.group(2)
        #	coordx = float(location.group(1))*maxcoord
        #	coordy = float(location.group(2))*maxcoord
        #	print coordx, coordy
        #	kwargs['Broadcast'].broadcast(\
        #		 "SetPosition #GetIndexFromClientNum(%s)# %s %s #GetPosZ(|#GetIndexFromClientNum(%s)|#)#" % (client['clinum'], coordx, coordy, client['clinum']))

    def followaction(self, action, client, followed_player, **kwargs):

        if action == 'start':

            for each in self.followlist:
                #first check if they are already a follower
                if each['follower'] == client['clinum']:
                    each['followed'] = followed_player['clinum']
                    self.follow(**kwargs)
                    return

            for each in self.followlist:
                #if not already follower, grab the first available spot
                if each['follower'] == -1:
                    each['follower'] = client['clinum']
                    each['followed'] = followed_player['clinum']
                    self.follow(**kwargs)
                    return
            #If all the spots are filled, report it
            kwargs['Broadcast'].broadcast(\
            "SendMessage %s ^cThe follow list is full!" % (client['clinum']))
            return

        if action == 'stop':
            for each in self.followlist:
                if each['follower'] == client['clinum']:
                    each['follower'] = -1
                    each['followed'] = -1

        self.follow(**kwargs)

    def follow(self, **kwargs):
        for each in self.followlist:
            kwargs['Broadcast'].broadcast(\
            "set %s %s; set %s %s" % (each['f'], each['follower'], each['fd'], each['followed']))

    def getMapSize(self, **kwargs):

        checkdimension = 131071
        self.MAPSIZE = 10
        while not self.MAPSIZESET:
            time.sleep(0.5)
            self.MAPSIZESET = True
            checkdimension = checkdimension / 2
            kwargs['Broadcast'].broadcast("echo #GetTerrainHeight(%s,0)#" %
                                          (checkdimension))
            print 'Map Size =', self.MAPSIZE
            time.sleep(1)

    def mapDimensions(self, *args, **kwargs):
        if self.MAPSIZE > 0:
            print 'made it to MAP DIMENSONS'
            self.MAPSIZE -= 1
            self.MAPSIZESET = False

    def onListClients(self, *args, **kwargs):
        clinum = args[0]
        name = args[2]
        ip = args[1]

        client = self.getPlayerByName(name)
        if not client:
            #if a player is missing from the list this will put them as an active player
            acct = self.ms.getAccount(name)
            acctid = acct[name]
            self.onConnect(clinum, 0000, ip, 0000, **kwargs)
            self.onSetName(clinum, name, **kwargs)
            self.onAccountId(clinum, acctid, **kwargs)
Ejemplo n.º 12
0
class admin(ConsolePlugin):
	VERSION = "1.6.3"
	playerlist = []
	adminlist = []
	banlist = []
	fullbanlist = []
	ipban = []
	itemlist = []
	PHASE = 0
	CONFIG = None
	UPDATE = True
	NEEDRELOAD = False
	LASTMESSAGE = {'client' : None, 'firsttime' : 0, 'lasttime' : 0, 'repeat' : 0}
	DLL = '2f4827b8'
	norunes = 0
	
	def onPluginLoad(self, config):
		
		self.ms = MasterServer ()
		self.CONFIG = config
		ini = ConfigParser.ConfigParser()
		banini = ConfigParser.ConfigParser ()
		banconfig = os.path.dirname(config) + "/ban.ini"
		banini.read (banconfig)
		ini.read(config)
		
		
		for (name, value) in ini.items('admin'):
			self.adminlist.append({'name': name, 'level' : value})
		for (name, value) in banini.items('ipban'):
			self.ipban.append(name)	
		
		
		pass
		
	def reload_config(self):
		
        	self.adminlist = []
       		self.ipban = []
                ini = ConfigParser.ConfigParser()
                ini.read(self.CONFIG)

		banini = ConfigParser.ConfigParser ()
		banconfig = os.path.dirname(self.CONFIG) + "/ban.ini"
		banini.read (banconfig)

                for (name, value) in ini.items('admin'):
                	self.adminlist.append({'name': name, 'level' : value})

                for (name, value) in banini.items('ban'):
                	self.fullbanlist.append({'name': name, 'level' : value})
                for (name, value) in banini.items('ipban'):
                	self.ipban.append(name)

	def reload_plugins(self):
	
		config = os.path.realpath(os.path.dirname (os.path.realpath (__file__)) + "/../s2wrapper.ini")
		
		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for name in ini.options('plugins'):
			if name == 'admin':
				PluginsManager.reload(name)
				continue
			if ini.getboolean('plugins', name):
				PluginsManager.reload(name)
			
	def onStartServer(self, *args, **kwargs):
		kwargs['Broadcast'].broadcast("Set norunes 0")
		kwargs['Broadcast'].broadcast("exec patch.cfg")
		self.playerlist = []
		self.banlist = []	

	def RegisterScripts(self, **kwargs):
		#any extra scripts that need to go in can be done here
		kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"echo SCRIPT Client #GetScriptParam(clientid)# #GetScriptParam(what)# with value #GetScriptParam(value)#; echo\" scriptinput")
		#these are for identifying bought and sold items
		kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"set _client #GetScriptParam(clientid)#; set _item #GetScriptParam(itemname)#; echo ITEM: Client #_client# SOLD #_item#; echo\" sellitem")
		if self.norunes == 1:
		
			kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"set _client #GetScriptParam(clientid)#; set _buyindex #GetIndexFromClientNum(|#_client|#)#;\
		 		set _none \"\"; set _item #GetScriptParam(itemname)#;\
		 		if #StringEquals(|#_item|#,|#_none|#)# TakeItem #_buyindex# #GetScriptParam(slot)#;\
		 		if #StringEquals(|#_item|#,|#_none|#)# SendMessage #GetScriptParam(clientid)# ^yYou cannot equip persistent items on this server;\
		 		echo ITEM: Client #_client# BOUGHT #_item#; echo\" buyitem")
		else:
			kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"set _client #GetScriptParam(clientid)#; set _item #GetScriptParam(itemname)#;\
				echo ITEM: Client #_client# BOUGHT #_item#; echo\" buyitem")
				
		kwargs['Broadcast'].broadcast("set con_showerr false; set con_showwarn false;")
		kwargs['Broadcast'].broadcast("Set Entity_NpcController_Name \"S2WRAPPER\"")
		#kwargs['Broadcast'].broadcast("RegisterGlobalScript -1 \"set kid #GetScriptParam(clientid)#; set kcheck _karmaflag#kid#; if [kcheck > 0] clientexecscript clientdo #kid# cmd \\\"set voice_disabled true\\\"; echo\" spawn")
	def getPlayerByClientNum(self, cli):

		for client in self.playerlist:
			if (client['clinum'] == cli):
				return client

	def getPlayerByName(self, name):

		for client in self.playerlist:
			if (client['name'].lower() == name.lower()):
				return client

	def onConnect(self, *args, **kwargs):
		
		id = args[0]
		ip = args[2]
		
		for each in self.ipban:
			if each == ip:
				reason = "You are banned from this server."
				kwargs['Broadcast'].broadcast(\
 		"clientexecscript %s clientdo cmd \"SetSave host_onload true; SetSave host_created 1; WriteConfigScript ~/startup.cfg\"" % (id))
 				kwargs['Broadcast'].broadcast(\
 		"clientexecscript %s clientdo cmd \"quit\"" % (id))
				kwargs['Broadcast'].broadcast("kick %s \"%s\"" % (id, reason))
				return

		reason = "An administrator has removed you from this server. You may rejoin the server after the current game ends."
		
		for each in self.banlist:
			if each == ip:
				kwargs['Broadcast'].broadcast(\
					"Kick %s \"%s\"" % (id, reason))

		for client in self.playerlist:
			if (client['clinum'] == id):
				client['ip'] = ip
				return
		
		self.playerlist.append ({'clinum' : id,\
					 'acctid' : 0,\
					 'name' : 'X',\
					 'ip' : ip,\
					 'team' : 0,\
					 'sf' : 0,\
					 'active' : False,\
					 'level' : 0,\
					 'admin' : False,\
					 'value' : 0,\
					 'karma' : 0,\
					 'commander' : False,\
					 'req' : 0,\
					 'flood' : None,\
					 'f_req' : 0,\
					 'l_req' : 0,\
					 'msgsum' : None})
	
	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client ['active'] = False

	def onSetName(self, *args, **kwargs):
		
		cli = args[0]
		playername = args[1]
		if playername == "":
			reason = "You dont seem to have a name, thats odd."
			kwargs['Broadcast'].broadcast("kick %s \"%s\"" % (cli, reason))

		client = self.getPlayerByClientNum(cli)
		client ['name'] = playername

	def getAccountInfo(self, *args, **kwargs):
		client = self.getPlayerByClientNum(args[0])
		stats = self.ms.getStatistics (client['acctid']).get ('all_stats').get (client['acctid'])
		level = int(stats['level'])
		sf = int(stats['sf'])
		karma = int(stats['karma'])
					
		client['sf'] = sf
		client['level'] = level
		client['karma'] = karma
		client['active'] = True
		#kwargs['Broadcast'].broadcast(\
 		#"clientexecscript %s clientdo cmd \"set _vr #StringLength(|#GetCheckSum(cgame.dll)|#)#; if [_vr > 0] \\\"SendScriptInput what DLL value #getchecksum(cgame.dll)#\\\"; Else \\\"SendScriptInput what DLL value NONE\\\"\"" % (client['clinum']))
 		
 		if karma < 0:
 			kwargs['Broadcast'].broadcast(\
 			"set _karmaflag%s 1" % (client['clinum']))
 			
		#If client has disconnected, give them their gold back
		self.giveGold(False, client, **kwargs)
		

	def onAccountId(self, *args, **kwargs):
		cli = args[0]
		id = args[1]
		client = self.getPlayerByClientNum(cli)
		client['acctid'] = int(id)

		statthread = threading.Thread(target=self.getAccountInfo, args=(cli,None), kwargs=kwargs)
		statthread.start()
			
		if self.isBanned(client, **kwargs):
			kwargs['Broadcast'].broadcast(\
					"clientexecscript %s clientdo cmd \"SetSave cl_packetSendFPS 1\"" % (cli))
			
		if self.isAdmin(client, **kwargs):
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^cYou are registered as an administrator. Use ^radmin <command>^c to execute commands through chat.^c You can get help by sending ^radmin help ^cto chat." % (cli))
			client['admin'] = True
			
		if self.isSuperuser(client, **kwargs):
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^cYou are registered as superuser on this server. You can send console commands with chat message: ^rsudo <command>." % (cli))
	
						
	def isAdmin(self, client, **kwargs):
		admin = False
		
		for each in self.adminlist:
			if client['name'].lower() == each['name']:
				admin = True
		
		return admin

	def isSuperuser(self, client, **kwargs):
		superuser = False

		for each in self.adminlist:
			if client['name'].lower() == each['name']:
				if each['level'] == 'super':
					superuser = True
		
		return superuser

	def isBanned(self, client, **kwargs):
		banned = False

		for each in self.fullbanlist:
			if client['name'].lower() == each['name']:
				if each['level'] == 'banned':
					banned = True
		
		return banned

	def onMessage(self, *args, **kwargs):
		
		name = args[1]
		message = args[2]
		
		client = self.getPlayerByName(name)
		clinum = client['clinum']
		admin = self.isAdmin(client, **kwargs)
		superuser = self.isSuperuser(client, **kwargs)

		# ---
		# MORE THEN FLOOD REPEATS(3)=4 A SEC(1) = kick
		FLOOD_REPEATS = 2
		FLOOD_A_SEC = 0.5	

		if not client['flood']:
			client['flood'] = { 'time' : 0, 'count' : 0 }


		flood = client['flood']
		print "flood: %s - %f - %f = %f" % (flood['count'], time.time (), flood['time'], (time.time ()-flood['time']))

                # Sickened2: spam-check based on message length and checksum
                msglen = len(list(message))
                if msglen > 100:
                        # this should be a lookup table for checksums of typical spam messages
                        spam1chksum = "ec10ca635bb6b956959830f4e652369d"
                        m = hashlib.md5()
                        m.update(message[:100])
                        chksum = m.hexdigest()
                        if chksum == spam1chksum:
                                reason = "Attention! Spamming results in automatic kicking."
                                kwargs['Broadcast'].broadcast("Kick %s \"%s\"" % (clinum, reason))
                        elif not client['msgsum']:
                                client['msgsum'] = chksum
                                #print "Checksum"
                                #print client['msgsum']
                        elif client['msgsum'] == chksum:
                                reason = "Attention! Spamming results in automatic kicking."
                                kwargs['Broadcast'].broadcast("Kick %s \"%s\"" % (clinum, reason))
                        else:
                                client['msgsum'] = chksum

		# Sickened2: the following method is not as effective because
		# 1) for large messages (e.g. > 250 bytes) part of the message is returned. For the same message length the
		#    size could vary. So we can't use the message length reliably
		# 2) if 2 chat packets are sent to the server and the 1st one arrives with delay but in the correct order,
		#    the difference between the time of arrival between the two packets is shorter than the difference
		#    between the departure time of the two packets
                ## Sickened2: additional spam check; user is not capable of manually typing more than 
                ##            MAX_TYPING_SPEED characters per second (avg)
                #MAX_TYPING_SPEED = 212; # chars/sec
                #msglen = len(list(message))
                #print "msglen = %d" % msglen
                #timediff = time.time () - flood['time']
                #print "timediff = %f" % timediff
                ##print("len(list(message)) / timediff ={0}".format(len(list(message)) / timediff))
                #if msglen / timediff > MAX_TYPING_SPEED:
                #        reason = "Sigh. Spamming results in automatic kicking."
                #        kwargs['Broadcast'].broadcast("Kick %s \"%s\"" % (clinum, reason))

		if (time.time () - flood['time']) < FLOOD_A_SEC:

			flood['count'] += 1

			if flood['count'] > FLOOD_REPEATS:
				reason = "Spamming results in automatic kicking."
				kwargs['Broadcast'].broadcast("Kick %s \"%s\"" % (clinum, reason))

		else:
			flood['count'] = 0

		flood['time'] = time.time ()
		
		request = re.match("request admin", message, flags=re.IGNORECASE)
		if request:
			for each in self.playerlist:
				if each['active'] and each['admin']:
					kwargs['Broadcast'].broadcast("SendMessage %s Admin present: ^y%s" % (client['clinum'], each['name']))

		#ignore everything else if it isn't from admin
		if not admin:
			return

		if superuser:
			self.superCommand(message, **kwargs)
		
		#Matches for normal admins
		restart = re.match("admin restart", message, flags=re.IGNORECASE)
		shuffle = re.match("admin shuffle", message, flags=re.IGNORECASE)
		kick = re.match("admin kick (\S+)", message, flags=re.IGNORECASE)
		ban = re.match("admin ban (\S+)", message, flags=re.IGNORECASE)
		timeout = re.match("admin timeout (\S+)", message, flags=re.IGNORECASE)
		slap = re.match("admin slap (\S+)", message, flags=re.IGNORECASE)
		micoff = re.match("admin micoff (\S+)", message, flags=re.IGNORECASE)
		micon = re.match("admin micon (\S+)", message, flags=re.IGNORECASE)
		changeworld = re.match("admin changeworld (\S+)", message, flags=re.IGNORECASE)
		help = re.match("admin help", message, flags=re.IGNORECASE)
		balance = re.match("admin balance", message, flags=re.IGNORECASE)
		getbalance = re.match("admin get balance", message, flags=re.IGNORECASE)
		reportbal = re.match("admin report balance", message, flags=re.IGNORECASE)
		swap = re.match("admin swap (\S+)", message, flags=re.IGNORECASE)
		setteam = re.match("admin setteam (\S+) (\S+)", message, flags=re.IGNORECASE)

		if restart:
			#restarts server if something catastrophically bad has happened
			kwargs['Broadcast'].broadcast("restart")

		if shuffle:
			#artificial shuffle vote
			if self.PHASE != 5:
				kwargs['Broadcast'].broadcast(\
					"SendMessage %s Cannot shuffle until the game has started!"\
					 % (client['clinum']))
				return
			
			kwargs['Broadcast'].broadcast("SendMessage -1 %s has shuffled the game." % (name))
			self.listClients(**kwargs)	
			shufflethread = threading.Thread(target=self.onShuffle, args=(clinum,None), kwargs=kwargs)
			shufflethread.start()

		if kick:
			#kicks a player from the server
			reason = "An administrator has removed you from the server, probably for being annoying"
			kickclient = self.getPlayerByName(kick.group(1))
			kwargs['Broadcast'].broadcast(\
				"Kick %s \"%s\""\
				 % (kickclient['clinum'], reason))

		if timeout:
			reason = "An administrator has banned you from the server. You are banned till this game is over."
			kickclient = self.getPlayerByName(timeout.group(1))
			kwargs['Broadcast'].broadcast(\
				"Kick %s \"%s\"" \
				 % (kickclient['clinum'], reason))

			self.banlist.append(kickclient['ip'])

			
		if ban:
			#kicks a player from the server and temporarily bans that player's IP till the game is over
			reason = "An administrator has banned you from the server."
			kickclient = self.getPlayerByName(ban.group(1))
			kwargs['Broadcast'].broadcast(\
				"Kick %s \"%s\"" \
				 % (kickclient['clinum'], reason))

	                banini = ConfigParser.ConfigParser ()
	                banconfig = os.path.dirname(self.CONFIG) + "/ban.ini"
	                banini.read (banconfig)
			banini.set ('ipban', kickclient['ip'], kickclient['name'])
			banini.write (open(banconfig, 'wb'))
			self.ipban.append(kickclient['ip'])

		if slap:
			#slap will move a player x+100, y+200 to get them off of a structure
			if self.PHASE != 5:
				return
				
			slapclient = self.getPlayerByName(slap.group(1))
			kwargs['Broadcast'].broadcast(\
				"set _slapindex #GetIndexFromClientNum(%s)#;\
				 set _sx #GetPosX(|#_slapindex|#)#; set _sy #GetPosY(|#_slapindex|#)#; set _sz #GetPosZ(|#_slapindex|#)#;\
				 SetPosition #_slapindex# [_sx + 200] [_sy + 200] #_sz#;\
				 SendMessage %s ^cAn adminstrator has moved you for jumping on buildings. YOU WILL BE BANNED if this action persists"\
				 % (slapclient['clinum'], slapclient['clinum']))
		
		if micoff:
			#Turns off players mic with clientdo	
			offclient = self.getPlayerByName(micoff.group(1))
			kwargs['Broadcast'].broadcast("ClientExecScript %s clientdo cmd \"set voice_disabled true\"" % (offclient['clinum']))

		if micon:
			#Turns on players mic with clientdo	
			onclient = self.getPlayerByName(micon.group(1))
			kwargs['Broadcast'].broadcast("ClientExecScript %s clientdo cmd \"set voice_disabled false\"" % (onclient['clinum']))
			
		if changeworld:
			#change the map
			kwargs['Broadcast'].broadcast(\
				"changeworld %s"\
				 % (changeworld.group(1)))
				 
		if balance:
			if self.PHASE != 5:
				kwargs['Broadcast'].broadcast(\
					"SendMessage %s Cannot balance if the game has not started!"\
					 % (client['clinum']))
				return

			kwargs['Broadcast'].broadcast("SendMessage -1 %s has balanced the game." % (name))
			self.listClients(**kwargs)
			balancethread = threading.Thread(target=self.doBalance, args=(clinum,True,False), kwargs=kwargs)
			balancethread.start()
			

		if getbalance:
			self.listClients(**kwargs)
			balancethread = threading.Thread(target=self.doBalance, args=(clinum,False,False), kwargs=kwargs)
			balancethread.start()


		if reportbal:
			self.listClients(**kwargs)
			balancethread = threading.Thread(target=self.doBalance, args=(clinum,False,True), kwargs=kwargs)
			balancethread.start()

		if swap:
			#swap a player to a different team
			swapplayer = self.getPlayerByName(swap.group(1))
			newteam = 0
			team = swapplayer['team']
			if team == 1:
				newteam = 2
			if team == 2:
				newteam = 1
			if newteam == 0:
				return
			kwargs['Broadcast'].broadcast(\
				"SetTeam #GetIndexFromClientNum(%s)# %s"\
				 % (swapplayer['clinum'], newteam))
				 
		if setteam:
			#swap a player to x team
			setplayer = self.getPlayerByName(setteam.group(2))
			newteam = setteam.group(1)
			kwargs['Broadcast'].broadcast(\
				"SetTeam #GetIndexFromClientNum(%s)# %s"\
				 % (setplayer['clinum'], newteam))
				 
		self.logCommand(client['name'],message)

		if help:
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s All commands on the server are done through server chat. All commands are logged to prevent you from abusing them.The following are commands and a short description of what they do."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin restart ^whard reset of the server. ONLY use in weird cases."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin shuffle ^wwill shuffle the game and set to previous phase."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin kick playername ^wwill remove a player from the server."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin timeout playername ^wwill remove a player for one game."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin ban playername ^wwill remove a player from the server and ban that IP address permenantly."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin micoff playername ^wwill turn the players mic off. Use on mic spammers."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin micon playername ^wwill turn the players mic on."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin changeworld mapname ^wwill change the map to the desired map."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin swap playername ^wwill move a specific player to another team."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin balance ^wwill move two players to achieve balance."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin get balance ^wwill report avg. and median SF values for the teams as well as a stack value."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin report balance ^wwill send a message to ALL players that has the avg. and median SF values."\
				 % (client['clinum']))	
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^radmin setteam x playername ^wwill set players team to x."\
				 % (client['clinum']))		

	def superCommand(self, message, **kwargs):
		supercommand = re.match("sudo (.*)", str(message), flags=re.IGNORECASE)
		if supercommand:
			kwargs['Broadcast'].broadcast("%s" % (supercommand.group(1)))

	def doBalance(self, admin, doBalance=False, doReport=False, **kwargs):
		clinum = admin
		
		for each in self.playerlist:
			each['team'] = 0
			
		time.sleep(1)
		teamone = []
		teamtwo = []

		#populate current team lists:
		for each in self.playerlist:
			if not each['active']:
				continue
			if each['team'] == 1:
				teamone.append(each)
			if each['team'] == 2:
				teamtwo.append(each)
		
		teamonestats = self.getTeamInfo(teamone)
		teamtwostats = self.getTeamInfo(teamtwo)
		stack = round(self.evaluateBalance(teamone, teamtwo),1)
		startstack = abs(self.evaluateBalance(teamone, teamtwo))
		
		if doReport:
			kwargs['Broadcast'].broadcast(\
			"SendMessage -1 ^y Team One (%s players) Avg. SF is ^r%s^y median is ^r%s^y, Team Two (%s players) Avg. SF is ^r%s^y median is ^r%s.^y Stack value: ^r%s" \
		 	% (teamonestats['size'], round(teamonestats['avg'],1), round(teamonestats['median'],1), teamtwostats['size'], round(teamtwostats['avg'], 1), round(teamtwostats['median'],1), abs(stack)))	
		 	return
		 	
		kwargs['Broadcast'].broadcast(\
		"SendMessage %s ^y Team One (%s players) Avg. SF is ^r%s^y median is ^r%s^y, Team Two (%s players) Avg. SF is ^r%s^y median is ^r%s. ^yStack value: ^r%s" \
		 % (clinum, teamonestats['size'], round(teamonestats['avg'],1), round(teamonestats['median'],1), teamtwostats['size'], round(teamtwostats['avg'],1), round(teamtwostats['median'], 1), abs(stack)))	
		#Find the players to swap
		lowest = -1
		pick1 = None
		pick2 = None
		
		for player1 in teamone:
			if player1['commander']:
				continue
			for player2 in teamtwo:
				if player2['commander']:
					continue
				#sort of inefficient to send the teamlist each time				
				ltarget = abs(self.evaluateBalance(teamone, teamtwo, player1, player2, True))
				
				if (lowest < 0):
					lowest = ltarget
					pick1 = player1
					pick2 = player2
					continue
			
				if (lowest < ltarget):
					continue
			
				lowest = ltarget
				pick1 = player1
				pick2 = player2

		#If the stack isn't improved, abort it
		if (lowest >= startstack):
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^yUnproductive balance. No swapping scenario would improve the balance over its current state." % (admin))
			return
		
		kwargs['Broadcast'].broadcast(\
		"SendMessage %s ^y Balance will swap ^r%s ^yand ^r%s" \
		 % (clinum, pick1['name'], pick2['name']))
		
		if not doBalance:
			index1 = map(itemgetter('clinum'), teamone).index(pick1['clinum'])
			index2 = map(itemgetter('clinum'), teamtwo).index(pick2['clinum'])
		
			teamone[index1]['team'] = 2
			teamtwo[index2]['team'] = 1

			teamonestats = self.getTeamInfo(teamone)
			teamtwostats = self.getTeamInfo(teamtwo)
			stack = round(self.evaluateBalance(teamone, teamtwo),1)
			#kwargs['Broadcast'].broadcast(\
		#"SendMessage %s ^cProposed change: ^y Team One (%s players) Avg. SF: ^r%s^y median SF: ^r%s^y, Team Two (%s players) Avg. SF: ^r%s^y median SF: ^r%s. ^yStack value: ^r%s" \
		#% (clinum, teamonestats['size'], round(teamonestats['avg'],1), round(teamonestats['median'],1), teamtwostats['size'], round(teamtwostats['avg'],1), round(teamtwostats['median'], 1), abs(stack)))
		 	return
			
		if doBalance:
			#Do the switch
			kwargs['Broadcast'].broadcast(\
				"set _index #GetIndexFromClientNum(%s)#;\
			 	SetTeam #_index# 2;\
			 	set _index #GetIndexFromClientNum(%s)#;\
			 	SetTeam #_index# 1"\
			 	% (pick1['clinum'], pick2['clinum']))
		
			#Give them gold if needed
			self.giveGold(True, pick1, **kwargs)
			self.giveGold(True, pick2, **kwargs)

			teamonestats = self.getTeamInfo(teamone)
			teamtwostats = self.getTeamInfo(teamtwo)
			kwargs['Broadcast'].broadcast(\
			"SendMessage -1 ^yAfter balance: Team One Avg. SF was ^r%s^y median was ^r%s^y, Team Two Avg. SF was ^r%s^y median was ^r%s"\
			 % (teamonestats['avg'], teamonestats['median'], teamtwostats['avg'], teamtwostats['median']))
	 				 
	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		self.PHASE = phase
		kwargs['Broadcast'].broadcast("echo SERVERVAR: norunes is #norunes#")
		
		if (phase == 7):
			self.banlist = []	
			for each in self.playerlist:
				each['team'] = 0
				each['commander'] = False
				each['value'] = 0
			
					
		if (phase == 6):
			
			if self.UPDATE:
			#fetch admin list and reload at the start of each game
				updatethread = threading.Thread(target=self.update, args=(), kwargs=kwargs)
				updatethread.start()	
			#check if server is empty after 2 minutes		
				pluginthread = threading.Thread(target=self.pluginreload, args=(), kwargs=kwargs)
				pluginthread.start()

			self.RegisterScripts(**kwargs)
			self.ItemList()

		if (phase == 4):
			kwargs['Broadcast'].broadcast("listclients")

	def update(self, **kwargs):
		response = urllib2.urlopen('http://188.40.92.72/admin.ini')
		adminlist = response.read()
		
		f = open(self.CONFIG, 'w')
		f.write(adminlist)
		f.close
		f.flush()
		os.fsync(f.fileno())
		self.reload_config()
		
			
		if self.NEEDRELOAD:
			self.pluginreload(**kwargs)
			return

		#Update the wrapper
		try:
			gitpath = os.path.realpath(os.path.dirname (os.path.realpath (__file__)) + "/../.git")
			command = ["git","--git-dir",gitpath,"pull"]
			output = subprocess.Popen(command, stdout=subprocess.PIPE).communicate()
			result = output[0].split("\n")[0]
			print 'result is %s' % result
			#TODO: make sure these work on all servers?
			notneeded = re.match("Already up-to-date.", result)
			needed = re.match("Updating .*", result)
		except:
			print 'error getting git update'
			return
		
		if notneeded:
			print 'update not needed'
			self.NEEDRELOAD = False
			return

		if needed:
			print 'update needed'
			self.NEEDRELOAD = True
			self.pluginreload(**kwargs)
			return

	def pluginreload(self, **kwargs):
		print 'pluginreload called'
		#Wait a couple minutes to allow clients to connect
		time.sleep(120)
		#Figure out how many clients are present
		kwargs['Broadcast'].broadcast("serverstatus")
	
	def onServerStatusResponse(self, *args, **kwargs):

		if self.NEEDRELOAD:
			gamemap = args[0]
			active = int(args[2])
			
			if active == 0:
				self.reload_plugins()
				kwargs['Broadcast'].broadcast("NextPhase; PrevPhase")
				self.NEEDRELOAD = False

	def logCommand(self, client, message, **kwargs):
		localtime = time.localtime(time.time())
		date = ("%s-%s-%s, %s:%s:%s" % (localtime[1], localtime[2], localtime[0], localtime[3], localtime[4], localtime[5]))
		f = open('admin.log', 'a')		
		f.write("Timestamp: \"%s\", Admin: %s, Command: %s\n" % (date, client, message))
		f.close

	def onTeamChange (self, *args, **kwargs):
		
		team = int(args[1])
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client['team'] = team

		self.requestTracker(cli, **kwargs)

	def onShuffle (self, *args, **kwargs):
		
		for each in self.playerlist:
			each['team'] = 0
			each['value'] = 0

		clinum = args[0]
		time.sleep(2)
		shufflelist = []

		#Put all the active players in a list
		for each in self.playerlist:
			if not each['active']:
				continue
			if each['team'] > 0:
				shufflelist.append(each)
	
		#sort shufflelists based on SF
		shufflelist = sorted(shufflelist, key=itemgetter('sf', 'level', 'clinum'), reverse=True)
		
		#randomly choose if we begin with human or beast
		r = random.randint(1,2)
		
		#Assign new teams, just like the K2 way, but Ino won't always be on humans
		for each in shufflelist:
		#TODO: is there a cleaner, more pythonic way to do this?	
			each['team'] = r
			if r == 1:
				r += 1
			elif r == 2:
				r -=1
			
		#Now actually do the shuffling
		for each in shufflelist:
			kwargs['Broadcast'].broadcast(\
				"SetTeam #GetIndexFromClientNum(%s)# %s"\
				 % (each['clinum'], each['team']))
		#Finish it off by going forward a phase
		kwargs['Broadcast'].broadcast(\
			"nextphase")
		
		
		kwargs['Broadcast'].broadcast(\
			"SendMessage %s You have shuffled the game." % (clinum))
		#Run balancer to get it nice and even
		#self.onBalance(clinum, **kwargs)
		kwargs['Broadcast'].broadcast("Startgame")
		
		
	def getTeamInfo(self, teamlist, **kwargs):
		
		teamsf = []
		combteamsf = float(0)		
		#figure out current averages and set some commonly used variables:
		for each in teamlist:
			combteamsf += each['sf']
			teamsf.append(each['sf'])
	
		sizeteam = len(teamlist)
		avgteam = combteamsf/sizeteam
		med = median(teamsf)
		
		teaminfo = {'size' : sizeteam, 'avg' : avgteam, 'total' : combteamsf, 'median' : med}
		
		return teaminfo

	def evaluateBalance(self, team1, team2, pick1=None, pick2=None, swap=False, **kwargs):
		#This function will swap out the picked players in a temporary list if swap is true and report the stack percent
		#If swap is false, it will just report the balance		
		#First, make new lists that we can modify:
		teamone = list(team1)
		teamtwo = list(team2)
		
		if swap:
			#Remove those players from the lists...		
			for each in teamone:
				if each['clinum'] == pick1['clinum']:
					teamone.remove(each) 
			for each in teamtwo:
				if each['clinum'] == pick2['clinum']:
					teamtwo.remove(each) 
		
			#Add to the lists		
			teamone.append(pick2)
			teamtwo.append(pick1)

		#Get the new team stats...
		teamonestats = self.getTeamInfo(teamone)
		teamtwostats = self.getTeamInfo(teamtwo)
		
		#Evaluate team balance
		teamoneshare = teamonestats['total']/(teamonestats['total'] + teamtwostats['total'])
		diffmedone = teamonestats['median']/(teamonestats['median'] + teamtwostats['median'])
		stack = teamoneshare + diffmedone
		#positive if team one is stacked, negative if team two is stacked
		return (stack - 1) * 100

	def onCommResign(self, *args, **kwargs):
	
		name = args[0]	
		client = self.getPlayerByName(name)
		client['commander'] = False
		
	
	def onUnitChange(self, *args, **kwargs):
	
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		self.requestTracker(cli, **kwargs)
		
		if args[1] != "Player_Commander":
			return

		client['commander'] = True
	
		

	def listClients(self, *args, **kwargs):

		kwargs['Broadcast'].broadcast("listclients")

	def onListClients(self, *args, **kwargs):
		clinum = int(args[0])
		name = args[2]
		ip = args[1]
		

		client = self.getPlayerByName(name)
		if not client:
		#if a player is missing from the list this will put them as an active player and get stats
		#usually used when reloading plugin during a game
			acct = self.ms.getAccount(name)
			acctid = acct[name]
			self.onConnect(clinum, 0000, ip, 0000, **kwargs)
			self.onSetName(clinum, name, **kwargs)
			self.onAccountId(clinum, acctid, **kwargs)
			client = self.getPlayerByName(name)
			
		client['active'] = True
		kwargs['Broadcast'].broadcast(\
		"echo CLIENT %s is on TEAM #GetTeam(|#GetIndexFromClientNum(%s)|#)#"\
		 % (client['clinum'], client['clinum']))
		
		
	def onRefreshTeams(self, *args, **kwargs):
		clinum = args[0]
		team = int(args[1])
		client = self.getPlayerByClientNum(clinum)
		client['team'] = team

	def ItemList(self, *args, **kwargs):
		
		self.itemlist = {
			'Advanced Sights' : 700,
			'Ammo Pack' : 500,
			'Ammo Satchel' : 200,
			'Chainmail' : 300,
			'Gust of Wind' : 450,
			'Magic Amplifier' : 700,
			'Brain of Maliken' : 750,
			'Heart of Maliken' : 950,
			'Lungs of Maliken' : 1000,
			'Mana Crystal' : 500,
			'Mana Stone' : 200,
			'Platemail' : 650,
			'Power Absorption' : 350,
			'Shield of Wisdom' : 650,
			'Stone Hide' : 650,
			'Tough Skin' : 300,
			'Trinket of Restoration' : 575
		}


	def onItemTransaction(self, *args, **kwargs):
		#adjust 'value' in playerlist to reflect what the player has bought or sold
		cli = args[0]
		trans = args[1]
		newitem = args[2]
		client = self.getPlayerByClientNum(cli)
		self.requestTracker(cli, **kwargs)
		
		try:
			value = self.itemlist[newitem]
		except:
			return
		
		if (trans == 'BOUGHT'):
			client['value'] += value
		elif (trans == 'SOLD'):
			client['value'] -= value
		
		

	def giveGold(self, balance, client, **kwargs):

		if client['value'] == 0:

			return
		
		gold = round(client['value']/2, 0)

		if balance:
			gold = client['value']

		kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^cYou have been compensated %s gold for your lost items.; GiveGold %s %s"\
			 % (client['clinum'], gold, client['clinum'], gold))
		
		client['value'] = 0

	def getMatchID(self, *args, **kwargs):
		matchid = args[0]
		kwargs['Broadcast'].broadcast("Set Entity_NpcController_Description %s" % (matchid))

	def onScriptEvent(self, *args, **kwargs):		
		
		caller = args[0]
		client = self.getPlayerByClientNum(caller)
		event = args[1]
		value = args[2]
		self.requestTracker(caller, **kwargs)
			
		if event == 'DLL':
			if value == 'NONE':
				return
			
			if value != self.DLL:
				
				banthread = threading.Thread(target=self.banclient, args=(caller, None), kwargs=kwargs)
				banthread.start()
			
				
	def banclient(self, *args, **kwargs):
		clinum = args[0]
		kwargs['Broadcast'].broadcast(\
				 "ClientExecScript %s clientdo cmd \"UICall game_options \\\"HTTPGetFile(\'http://masterserver.savage2.s2games.com/create.php?phrase=1\', \'~/null\');\\\"\"" % (clinum))

		time.sleep(1)

		kwargs['Broadcast'].broadcast(\
				 "ClientExecScript %s clientdo cmd \"quit\"" % (clinum))
		
	def getServerVar(self, *args, **kwargs):
		var = args[0]
		if var == 'norunes':
			self.norunes = args[1]
		
	def requestTracker (self, cli, **kwargs):
		tm = time.time()
		client = self.getPlayerByClientNum(cli)
		#If player requests item purchase, team join, unit select more than 12 times in 1 second, boot them
		
		if (tm - client['f_req']) > 1:
			client['req'] = 0
			client['f_req'] = tm
			return
			
		client['req'] += 1
		
		if client['req'] > 10:
			reason = "Spamming server requests results in automatic kicking."
			kwargs['Broadcast'].broadcast("Kick %s \"%s\"" % (client['clinum'], reason))
Ejemplo n.º 13
0
class pug(ConsolePlugin):
    VERSION = "1.0.1"
    ms = None
    PHASE = 0
    STARTSTAMP = 0
    STARTED = False
    PICKING = False
    HUMANPICK = False
    playerlist = []
    startinfo = {
        'h_captain': None,
        'h_ready': False,
        'h_first': False,
        'b_captain': None,
        'b_ready': False,
        'b_first': False
    }
    teamlist = []
    TIME = 0

    def onPluginLoad(self, config):
        self.ms = MasterServer()

        ini = ConfigParser.ConfigParser()
        ini.read(config)
        '''
		for (name, value) in ini.items('var'):
			if (name == "clan1"):
				self.CLAN1 = value
			if (name == "clan2"):
				self.CLAN2 = value
		'''
        pass

    def onStartServer(self, *args, **kwargs):

        self.PHASE = 0
        self.playerlist = []
        self.startinfo = {
            'h_captain': None,
            'h_ready': False,
            'h_first': False,
            'b_captain': None,
            'b_ready': False,
            'b_first': False
        }

    def getPlayerByClientNum(self, cli):

        for client in self.playerlist:
            if (client['clinum'] == cli):
                return client

    def getPlayerByName(self, name):

        for client in self.playerlist:
            if (client['name'].lower() == name.lower()):
                return client

    def onConnect(self, *args, **kwargs):

        id = args[0]
        ip = args[2]

        for client in self.playerlist:
            if (client['clinum'] == id):
                return

        self.playerlist.append ({'clinum' : id,\
            'acctid' : 0,\
            'level' : 0,\
            'ip' : ip,\
            'sf' : 0,\
            'name' : 'X',\
            'active' : False,\
            'team' : 0,\
            'ping' : 0,\
            'clan' : 'X'})

        #kwargs['Broadcast'].broadcast("SendMessage %s ^cTo toggle your PUG availability send the chat message ^rpug noplay" % (id))

    def onDisconnect(self, *args, **kwargs):

        cli = args[0]
        client = self.getPlayerByClientNum(cli)
        client['active'] = False

        if client['clinum'] == self.startinfo['h_captain']:
            self.startinfo['h_captain'] = None
            self.startinfo['h_ready'] = False
            kwargs['Broadcast'].broadcast(
                "set State_Interrupted_EffectPath \"trigger UpdateDetail 1\"; set Pet_HumanWorker_Inventory9 \"\";"
            )
            if self.PICKING:
                resetall(**kwargs)
        if client['clinum'] == self.startinfo['b_captain']:
            self.startinfo['b_captain'] = None
            self.startinfo['b_ready'] = False
            kwargs['Broadcast'].broadcast(
                "set Gadget_Hail_ModelPath \"trigger UpdateError 1\"; set Pet_BeastWorker_Inventory9 \"\";"
            )
            if self.PICKING:
                resetall(**kwargs)

    def onSetName(self, *args, **kwargs):

        cli = args[0]
        playername = args[1]
        client = self.getPlayerByClientNum(cli)
        client['name'] = playername
        client['play'] = True
        kwargs['Broadcast'].broadcast(
            "ClientExecScript %s clientdo cmd  \"showwidget pug_button\"" %
            (cli))

    def onAccountId(self, *args, **kwargs):

        cli = args[0]
        id = args[1]
        stats = self.ms.getStatistics(id).get('all_stats').get(int(id))

        level = int(stats['level'])
        sf = int(stats['sf'])
        exp = int(stats['exp'])
        time = int(stats['secs'])
        time = time / 60
        #sf = int(exp/time)
        clan = stats['clan_tag']
        client = self.getPlayerByClientNum(cli)

        client['acctid'] = int(id)
        client['level'] = level
        client['sf'] = sf
        client['active'] = True
        client['clan'] = clan
        client['newteam'] = 0

        kwargs['Broadcast'].broadcast(
            "ClientExecScript %s clientdo cmd  \"showwidget pug_button\"" %
            (cli))

        if self.PICKING:
            kwargs['Broadcast'].broadcast(
                "ClientExecScript %s clientdo cmd  \"hidewidget team_button0; hidewidget team_button1\""
                % (cli))

    def onTeamChange(self, *args, **kwargs):

        team = int(args[1])
        cli = args[0]
        client = self.getPlayerByClientNum(cli)
        client['team'] = team

        if self.PICKING:

            for each in self.teamlist:
                if (each['player'] == cli) and (team != each['team']):
                    #don't let them switch
                    kwargs['Broadcast'].broadcast(
                        "set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# %s"
                        % (each['player'], each['team']))
                    return

                #kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 0" % (each['player']))

    def onGameStart(self, *args, **kwargs):

        self.STARTSTAMP = args[1]

    def onPhaseChange(self, *args, **kwargs):
        phase = int(args[0])
        self.PHASE = phase

        if phase == 5:
            self.STARTSTAMP = args[1]
            self.STARTED = True
            self.PICKING = False

        if phase == 6:
            self.PICKING = False
            self.teamlist = []
            self.startinfo = {
                'h_captain': None,
                'h_ready': False,
                'h_first': False,
                'b_captain': None,
                'b_ready': False,
                'b_first': False
            }
            kwargs['Broadcast'].broadcast(
                "set State_SuccessfulBlock_Description -1;\
							set State_Interrupted_EffectPath \"trigger UpdateDetail 1\";\
							set Gadget_Hail_ModelPath \"trigger UpdateError 1\";\
							set State_ImpPoisoned_Name \"trigger UpdateSpeed 1\";\
							set Gadget_Hail_Description \"trigger UpdatePercent -1\";\
							set State_ImpPoisoned_ExpiredEffectPath \"trigger UpdateExtraction 1\";\
							set maxteams 3;\
							set sv_maxteamdifference 10;\
							set Pet_Shaman_Prerequisite 1;\
							set Pet_HumanWorker_Inventory9 \"\";\
							set Pet_BeastWorker_Inventory9 \"\";")
            kwargs['Broadcast'].broadcast(
                "RegisterGlobalScript -1 \"echo SCRIPT Client #GetScriptParam(clientid)# #GetScriptParam(what)# with value #GetScriptParam(value)#; echo\" scriptinput"
            )
            kwargs['Broadcast'].broadcast(
                "ClientExecScript -1 clientdo cmd  \"showwidget team_button0; showwidget team_button1\""
            )

        if phase == 7:
            for each in self.playerlist:
                each['newteam'] = 0
            self.PICKING = False
            self.STARTED = False
            resetall(**kwargs)

    def togglePlay(self, client, playing=None, **kwargs):
        color = '^g'
        if self.PICKING:
            kwargs['Broadcast'].broadcast(
                "SendMessage %s ^rYou cannot toggle your status once picking has begun."
                % (client['clinum']))
            return
        if not playing:
            if client['play']:
                client['play'] = False
                color = '^r'
            else:
                client['play'] = True
        else:
            client['play'] = playing
            if not client['play']:
                color = '^r'
        #kwargs['Broadcast'].broadcast("SendMessage %s ^cYour Playing Status: %s%s" % (client['clinum'], color, client['play']))

    def onScriptEvent(self, *args, **kwargs):

        caller = args[0]
        client = self.getPlayerByClientNum(caller)
        event = args[1]
        value = args[2]
        #info = self.startinfo

        #Captain initiated
        if event == 'Captain':
            #If they are already captain, do nothing
            if caller == self.startinfo[
                    'b_captain'] or caller == self.startinfo['h_captain']:
                return
            #Beasts, set captain
            if value == 'beasts':
                self.startinfo['b_captain'] = caller
                kwargs['Broadcast'].broadcast(
                    "set Gadget_Hail_ModelPath \"trigger UpdateError 0\"; set Pet_BeastWorker_Inventory9 \"%s\""
                    % (client['name']))
                if not self.startinfo['h_captain']:
                    self.startinfo['h_first'] = True
            #Humans, set captain
            if value == 'humans':
                self.startinfo['h_captain'] = caller
                kwargs['Broadcast'].broadcast(
                    "set State_Interrupted_EffectPath \"trigger UpdateDetail 0\"; set Pet_HumanWorker_Inventory9  \"%s\""
                    % (client['name']))
                if not self.startinfo['b_captain']:
                    self.startinfo['b_first'] = True
            #Check if picking is initiated, if so determine who gets the next picking
            if self.PICKING:
                self.setpicking(**kwargs)
                return
            #Start picking process through the normal mechanism
            if self.startinfo['h_captain'] and self.startinfo['b_captain']:
                self.beginpicking(**kwargs)

        #Toggle player availability
        if event == 'Toggle':
            playing = False
            if value == 'true':
                playing = True

            self.togglePlay(client, playing, **kwargs)

        #Player select
        if event == 'Select':
            player = self.getPlayerByName(value)
            #switch everything to ingame_picking function if the game is already started

            if self.PHASE == 5:
                #pickthread = threading.Thread(target=self.ingame_picking, args=(caller, client, player, None), kwargs=kwargs)
                #pickthread.start()
                #self.ingame_picking(caller, client, player, **kwargs)
                print 'Will go to ingame picking'
            if caller == self.startinfo['h_captain']:
                #check players status
                if not player['play']:
                    kwargs['Broadcast'].broadcast(
                        "SendMessage %s ^rThat player has requested to not play in this match."
                        % (client['clinum']))
                    return

                player['newteam'] = 1
                client['newteam'] = 1
                self.teamlist.append({
                    "player": player["clinum"],
                    "team": 1
                })
                kwargs['Broadcast'].broadcast(
                    "SendMessage -1 ^r%s^w has selected ^y%s ^wfor the Humans!"
                    % (client['name'], player['name']))
                kwargs['Broadcast'].broadcast(
                    "set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 1"
                    % (player['clinum']))
                kwargs['Broadcast'].broadcast(
                    "set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\""
                    %
                    (self.startinfo['b_captain'], self.startinfo['b_captain']))
                self.HUMANPICK = False

            if caller == self.startinfo['b_captain']:
                if not player['play']:
                    kwargs['Broadcast'].broadcast(
                        "SendMessage %s ^rThat player has requested to not play in this match."
                        % (client['clinum']))
                    return
                player['newteam'] = 2
                client['newteam'] = 2
                self.teamlist.append({
                    "player": player["clinum"],
                    "team": 2
                })
                kwargs['Broadcast'].broadcast(
                    "SendMessage -1 ^r%s^w has selected ^y%s ^wfor the Beasts!"
                    % (client['name'], player['name']))
                kwargs['Broadcast'].broadcast(
                    "set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 2"
                    % (player['clinum']))
                kwargs['Broadcast'].broadcast(
                    "set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\""
                    %
                    (self.startinfo['h_captain'], self.startinfo['h_captain']))
                self.HUMANPICK = True

            if self.PICKING:
                self.setpicking(**kwargs)
        #Ready
        if event == 'Ready':

            if self.STARTED:
                return
            if caller == self.startinfo['h_captain']:
                if self.startinfo['h_ready']:
                    return
                self.startinfo['h_ready'] = True
                kwargs['Broadcast'].broadcast(
                    "SendMessage -1 ^r%s^w has indicated that Humans are ready!"
                    % (client['name']))
            if caller == self.startinfo['b_captain']:
                if self.startinfo['b_ready']:
                    return
                self.startinfo['b_ready'] = True
                kwargs['Broadcast'].broadcast(
                    "SendMessage -1 ^r%s^w has indicated that Beasts are ready!"
                    % (client['name']))
            #Start the game if both captains say they are ready
            if self.startinfo['h_ready'] and self.startinfo['b_ready']:
                kwargs['Broadcast'].broadcast(
                    "set State_ImpPoisoned_Name \"trigger UpdateSpeed 0\"")
                self.populate(**kwargs)

        if event == 'Resign':
            #if pick has begun and a captain resigns, just reset the whole damn thing
            if self.PICKING:
                self.resetall(**kwargs)

            if client['clinum'] == self.startinfo['h_captain']:

                self.startinfo['h_captain'] = None
                self.startinfo['h_ready'] = False
                kwargs['Broadcast'].broadcast(
                    "set State_Interrupted_EffectPath \"trigger UpdateDetail 1\"; set Pet_HumanWorker_Inventory9 \"\";"
                )

            if client['clinum'] == self.startinfo['b_captain']:

                self.startinfo['b_captain'] = None
                self.startinfo['b_ready'] = False
                kwargs['Broadcast'].broadcast(
                    "set Gadget_Hail_ModelPath \"trigger UpdateError 1\"; set Pet_BeastWorker_Inventory9 \"\";"
                )

            #self.setpicking(**kwargs)

    def resetall(self, **kwargs):
        self.PICKING = False
        self.teamlist = []
        self.startinfo = {
            'h_captain': None,
            'h_ready': False,
            'h_first': False,
            'b_captain': None,
            'b_ready': False,
            'b_first': False
        }
        kwargs['Broadcast'].broadcast(
            "set State_SuccessfulBlock_Description -1;\
							set State_Interrupted_EffectPath \"trigger UpdateDetail 1\";\
							set Gadget_Hail_ModelPath \"trigger UpdateError 1\";\
							set State_ImpPoisoned_Name \"trigger UpdateSpeed 1\";\
							set Gadget_Hail_Description \"trigger UpdatePercent -1\";\
							set State_ImpPoisoned_ExpiredEffectPath \"trigger UpdateExtraction 1\";\
							set maxteams 3;\
							set sv_maxteamdifference 10;\
							set Pet_Shaman_Prerequisite 1;\
							set Pet_HumanWorker_Inventory9 \"\";\
							set Pet_BeastWorker_Inventory9 \"\";")

        kwargs['Broadcast'].broadcast(
            "ClientExecScript -1 clientdo cmd  \"showwidget team_button0; showwidget team_button1\""
        )

        for each in self.playerlist:
            if each['active']:
                kwargs['Broadcast'].broadcast(
                    "set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 0; SendMessage -1 ^yTeams are reset after captain resignation."
                    % (each['clinum']))

    def RegisterStart(self, **kwargs):
        self.PICKING = True

    def beginpicking(self, **kwargs):
        #move everyone to spec
        for each in self.playerlist:
            if each['active']:
                kwargs['Broadcast'].broadcast(
                    "set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 0"
                    % (each['clinum']))

        self.teamlist = []
        #start by making the teams unjoinable
        kwargs['Broadcast'].broadcast(
            "set sv_setupTimeCommander 600000000; set sv_maxteamdifference 1; set State_ImpPoisoned_ExpiredEffectPath \"trigger UpdateExtraction 0\";"
        )
        kwargs['Broadcast'].broadcast(
            "ClientExecScript -1 clientdo cmd  \"hidewidget team_button0; hidewidget team_button1\""
        )

        #move captains to the appropriate team and have them switch back to lobby
        for each in self.playerlist:
            if each['clinum'] == self.startinfo['h_captain']:
                kwargs['Broadcast'].broadcast(
                    "set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 1"
                    % (each['clinum']))
            if each['clinum'] == self.startinfo['b_captain']:
                kwargs['Broadcast'].broadcast(
                    "set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# 2"
                    % (each['clinum']))
        kwargs['Broadcast'].broadcast(
            "ClientExecScript %s clientdo cmd  \"Action ToggleLobby\"" %
            (self.startinfo['h_captain']))
        kwargs['Broadcast'].broadcast(
            "ClientExecScript %s clientdo cmd  \"Action ToggleLobby\"" %
            (self.startinfo['b_captain']))
        self.teamlist.append({
            "player": self.startinfo['h_captain'],
            "team": 1
        })
        self.teamlist.append({
            "player": self.startinfo['b_captain'],
            "team": 2
        })
        #Set variables to get the first captain to start picking
        if self.startinfo['h_first']:
            self.HUMANPICK = True
            self.setpicking(**kwargs)
        else:
            self.HUMANPICK = False
            self.setpicking(**kwargs)

        kwargs['Broadcast'].broadcast("echo STARTTOURNEY")

    def populate(self, **kwargs):

        for each in self.playerlist:
            if each['active']:
                kwargs['Broadcast'].broadcast(
                    "set _index #GetIndexFromClientNum(%s)#; SetTeam #_index# %s"
                    % (each['clinum'], each['newteam']))
        #Send to the next phase
        kwargs['Broadcast'].broadcast(
            "NextPhase; set sv_setupTimeCommander 60000; PrevPhase")

    def onListClients(self, *args, **kwargs):
        clinum = args[0]
        name = args[2]
        ip = args[1]

        try:
            client = self.getPlayerByName(name)
        except:
            #if a player is missing from the list this will put them as an active player
            acct = self.ms.getAccount(name)
            acctid = acct[name]
            self.onConnect(clinum, 0000, ip, 0000, **kwargs)
            self.onSetName(clinum, name, **kwargs)
            self.onAccountId(clinum, acctid, **kwargs)

    def onServerStatus(self, *args, **kwargs):
        if self.STARTED != 1:
            return
        pickthread = threading.Thread(target=self.ingame_picking,
                                      args=(),
                                      kwargs=kwargs)
        pickthread.start()

    def ingame_picking(self, *args, **kwargs):

        self.listClients(self, **kwargs)
        teamone = []
        teamtwo = []
        time.sleep(1)

        #populate current team lists:
        for each in self.playerlist:
            if not each['active']:
                continue
            if each['team'] == 1:
                teamone.append(each)
            if each['team'] == 2:
                teamtwo.append(each)

        #figure out who gets the pick
        team1 = len(teamone)
        team2 = len(teamtwo)

        if team1 > team2:
            self.HUMANPICK = False
            self.setpicking(**kwargs)
        if team2 > team1:
            self.HUMANPICK = True
            self.setpicking(**kwargs)

        if team1 == team2:
            return

    def listClients(self, *args, **kwargs):

        kwargs['Broadcast'].broadcast("listclients")

    def onListClients(self, *args, **kwargs):
        clinum = args[0]
        name = args[2]
        ip = args[1]

        client = self.getPlayerByName(name)
        if not client:
            #if a player is missing from the list this will put them as an active player and get stats
            #TODO: listclients clinum is always double diget (00, 01, etc.) so this might be a problem
            acct = self.ms.getAccount(name)
            acctid = acct[name]
            self.onConnect(clinum, 0000, ip, 0000, **kwargs)
            self.onSetName(clinum, name, **kwargs)
            self.onAccountId(clinum, acctid, **kwargs)
            client = self.getPlayerByName(name)

        client['active'] = True
        kwargs['Broadcast'].broadcast(\
        "echo CLIENT %s is on TEAM #GetTeam(|#GetIndexFromClientNum(%s)|#)#"\
         % (client['clinum'], client['clinum']))

    def onRefreshTeams(self, *args, **kwargs):
        clinum = args[0]
        team = int(args[1])
        client = self.getPlayerByClientNum(clinum)
        client['team'] = team

    def setpicking(self, **kwargs):

        if self.HUMANPICK:
            kwargs['Broadcast'].broadcast(
                "set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\""
                % (self.startinfo['h_captain'], self.startinfo['h_captain']))
        else:
            kwargs['Broadcast'].broadcast(
                "set State_SuccessfulBlock_Description %s; set Gadget_Hail_Description \"trigger UpdatePercent %s\""
                % (self.startinfo['b_captain'], self.startinfo['b_captain']))
Ejemplo n.º 14
0
class sandbox(ConsolePlugin):
	VERSION = "0.2.5"
	playerlist = []
	leaderlist = []
	modlist = []
	PHASE = 0
	
	def onPluginLoad(self, config):
		self.ms = MasterServer ()
		self.CONFIG = config
		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for (name, value) in ini.items('modders'):
			self.leaderlist.append({'name': name, 'level' : value})
		pass
	
	def reload_config(self):
		
		self.leaderlist = []
		ini = ConfigParser.ConfigParser()
		ini.read(self.CONFIG)

		for (name, value) in ini.items('modders'):
			self.leaderlist.append({'name': name, 'level' : value})

	def reload_plugins(self):
	
		config = os.path.realpath(os.path.dirname (os.path.realpath (__file__)) + "/../s2wrapper.ini")
		
		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for name in ini.options('plugins'):
			if name == 'sandbox':
				PluginsManager.reload(name)
				continue
			if ini.getboolean('plugins', name):
				PluginsManager.reload(name)
		
	def onStartServer(self, *args, **kwargs):
				
		self.playerlist = []
		self.modlist = []

	def getPlayerByClientNum(self, cli):

		for client in self.playerlist:
			if (client['clinum'] == cli):
				return client

	def getPlayerByName(self, name):

		for client in self.playerlist:
			if (client['name'].lower() == name.lower()):
				return client

	def onConnect(self, *args, **kwargs):
		
		id = args[0]

		for client in self.playerlist:
			if (client['clinum'] == id):
				return
		
		self.playerlist.append ({'clinum' : id,\
					 'acctid' : 0,\
					 'name' : 'X',\
					 'active' : False,\
					 'level' : 0,\
					 'leader' : False,})
	
	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client ['active'] = False

	def onSetName(self, *args, **kwargs):
		
		cli = args[0]
		playername = args[1]
		client = self.getPlayerByClientNum(cli)
		client ['name'] = playername
		
		kwargs['Broadcast'].broadcast("SendMessage %s ^yThis server is running the Sandbox plugin by GGGGGGGG. Version : %s. Mods currently active: ^r%" % (cli, self.VERSION, self.modlist))
					
	def onAccountId(self, *args, **kwargs):
		cli = args[0]
		id = args[1]
		stats = self.ms.getStatistics (id).get ('all_stats').get (int(id))
		level = int(stats['level'])
					
		client = self.getPlayerByClientNum(cli)
		client['level'] = level
		client['active'] = True	
		if self.isLeader(client, **kwargs):
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^cYou are registered as a modder. You can now use the sandbox. Send the chat message: ^rsb help ^cto see what commands you can perform."\
			 % (cli))
			client['leader'] = True
		
	def isLeader(self, client, **kwargs):
		leader = False
		
		for each in self.leaderlist:
			if client['name'].lower() == each['name']:
				leader = True
		
		return leader

	def onMessage(self, *args, **kwargs):
		
		name = args[1]
		message = args[2]
		
		client = self.getPlayerByName(name)
		leader = self.isLeader(client, **kwargs)
			
			
		if not leader:
			return
		
		startgame = re.match("sb startgame", message, flags=re.IGNORECASE)
		giveteamgold = re.match("sb giveteamgold (\S+) (\S+)", message, flags=re.IGNORECASE)
		giveplayergold = re.match("sb givegold (\S+) (\S+)", message, flags=re.IGNORECASE)
		giveplayersoul = re.match("sb givesoul (\S+) (\S+)", message, flags=re.IGNORECASE)
		giveplayerexperience = re.match("sb giveexp (\S+) (\S+)", message, flags=re.IGNORECASE)
		giveplayerammo = re.match("sb giveammo (\S+)", message, flags=re.IGNORECASE)
		resetattributes = re.match("sb resetattributes (\S+)", message, flags=re.IGNORECASE)
		resetexp = re.match("sb resetexp (\S+)", message, flags=re.IGNORECASE)
		refillhealth = re.match("sb refillhealth (\S+)", message, flags=re.IGNORECASE)
		refillmana = re.match("sb refillmana (\S+)", message, flags=re.IGNORECASE)
		refillstamina = re.match("sb refillstamina (\S+)", message, flags=re.IGNORECASE)
		kick = re.match("sb kick (\S+)", message, flags=re.IGNORECASE)
		slap = re.match("sb slap (\S+)", message, flags=re.IGNORECASE)
		changeworld = re.match("sb changeworld (\S+)", message, flags=re.IGNORECASE)
		help = re.match("sb help", message, flags=re.IGNORECASE)
		playerhelp = re.match("sb player help", message, flags=re.IGNORECASE)
		teamchange = re.match("sb allowteamchange", message, flags=re.IGNORECASE)
		teamdifference = re.match("sb teamdiff", message, flags=re.IGNORECASE)
		changepassword = re.match("sb password (\S+)", message, flags=re.IGNORECASE)
		setteam = re.match("sb setteam (\S+) (\S+)", message, flags=re.IGNORECASE)
		sbsudo = re.match("sb sudo (.*)", message, flags=re.IGNORECASE)
		
		modhelp = re.match("sb mod help", message, flags=re.IGNORECASE)
		movespeed = re.match("sb mod speed (\S+)", message, flags=re.IGNORECASE)
		gravity = re.match("sb mod gravity (\S+)", message, flags=re.IGNORECASE)
		buildspeed = re.match("sb mod buildspeed (\S+)", message, flags=re.IGNORECASE)
		jump = re.match("sb mod jump (\S+)", message, flags=re.IGNORECASE)
		
		modenable = re.match("mm enable (\S+)", message, flags=re.IGNORECASE)
		modactive = re.match("mm get active", message, flags=re.IGNORECASE)
		modindirectory = re.match("mm get list", message, flags=re.IGNORECASE)
		modreset = re.match("mm reset", message, flags=re.IGNORECASE)
		mmhelp = re.match("mm help", message, flags=re.IGNORECASE)
		mmcreate = re.match("mm create (\S+)", message, flags=re.IGNORECASE)
		mmdelete = re.match("mm delete (\S+)", message, flags=re.IGNORECASE)
		mmmodify = re.match("mm modify (\S+) (\S+) (.*)", message, flags=re.IGNORECASE)
		mmview = re.match("mm view (\S+)", message, flags=re.IGNORECASE)
		mmwrite = re.match("mm write (\S+) (.*)")
		
		if startgame:
			kwargs['Broadcast'].broadcast("startgame")

		if sbsudo:
			kwargs['Broadcast'].broadcast("%s" % (sbsudo.group(1)))
			
		if giveteamgold:
			kwargs['Broadcast'].broadcast("giveteamgold %s %s" % (giveteamgold.group(1), giveteamgold.group(2)))
			
		if giveplayergold:
			playergold = self.getPlayerByName(giveplayergold.group(1))
			kwargs['Broadcast'].broadcast("givegold %s %s" % (playergold['clinum'], giveplayergold.group(2)))
			
		if giveplayerammo:
			playerammo = self.getPlayerByName(giveplayerammo.group(1))
			kwargs['Broadcast'].broadcast("giveammo %s" % (playerammo['clinum']))

		if giveplayersoul:
			playersoul = self.getPlayerByName(giveplayersoul.group(1))
			kwargs['Broadcast'].broadcast("givesoul %s %s" % (playersoul['clinum'], giveplayersoul.group(2)))
			
		if giveplayerexperience:
			playerexperience = self.getPlayerByName(giveplayerexperience.group(1))
			kwargs['Broadcast'].broadcast("giveexp %s %s" % (playerexperience['clinum'], giveplayerexperience.group(2)))
		
		if kick:
			#kicks a player from the server
			reason = "An administrator has removed you from the server, probably for being annoying"
			kickclient = self.getPlayerByName(kick.group(1))
			kwargs['Broadcast'].broadcast("Kick %s \"%s\""% (kickclient['clinum'], reason))

		if slap:
			#slap will move a player x+100, y+200 to get them off of a structure
			
			slapclient = self.getPlayerByName(slap.group(1))
			kwargs['Broadcast'].broadcast(\
				"set _slapindex #GetIndexFromClientNum(%s)#;\
				 set _sx #GetPosX(|#_slapindex|#)#; set _sy #GetPosY(|#_slapindex|#)#; set _sz #GetPosZ(|#_slapindex|#)#;\
				 SetPosition #_slapindex# [_sx + 200] [_sy + 200] #_sz#;\
				 SendMessage %s ^cAn adminstrator has moved you for jumping on buildings. YOU WILL BE BANNED if this action persists"\
				 % (slapclient['clinum'], slapclient['clinum']))
			

		if changeworld:
			kwargs['Broadcast'].broadcast("changeworld %s" % (changeworld.group(1)))

		if movespeed:
			kwargs['Broadcast'].broadcast("set p_speed %s" % (movespeed.group(1)))
		
		if jump:
			kwargs['Broadcast'].broadcast("set p_jump %s" % (jump.group(1)))
			
		if gravity:
			kwargs['Broadcast'].broadcast("set p_gravity %s" % (gravity.group(1)))
			
		if buildspeed:
			kwargs['Broadcast'].broadcast(\
				"set Player_Conjurer_BuildingRepairRate %s;\
				 set Player_Engineer_BuildingRepairRate %s;"\
				 % (buildspeed.group(1), buildspeed.group(1)))
			
		if teamchange:
			kwargs['Broadcast'].broadcast("set g_allowteamchange true")

		if teamdifference:
			kwargs['Broadcast'].broadcast("set sv_maxTeamDifference 20")
			
		if changepassword:
			kwargs['Broadcast'].broadcast("set svr_connectpass %s" % (changepassword.group(1)))
			
		if setteam:
			#swap a player to a different team
			setplayer = self.getPlayerByName(setteam.group(2))
			newteam = setteam.group(1)
			kwargs['Broadcast'].broadcast(\
				"SetTeam #GetIndexFromClientNum(%s)# %s"\
				 % (setplayer['clinum'], newteam))
			
		if resetattributes:
			resetattributesplayer = self.getPlayerByName(resetattributes.group(1))
			kwargs['Broadcast'].broadcast("ResetAttributes #GetIndexFromClientNum(%s)#" % (resetattributesplayer['clinum']))
			
		if resetexp:
			resetexpplayer = self.getPlayerByName(resetexp.group(1))
			kwargs['Broadcast'].broadcast("ResetExp %s" % (resetexpplayer['clinum']))
			
		if refillhealth:
			refillhealthplayer = self.getPlayerByName(refillhealth.group(1))
			kwargs['Broadcast'].broadcast("RefillHealth #GetIndexFromClientNum(%s)#" % (refillhealthplayer['clinum']))
			
		if refillmana:
			refillmanaplayer = self.getPlayerByName(refillmana.group(1))
			kwargs['Broadcast'].broadcast("RefillMana #GetIndexFromClientNum(%s)#" % (refillmanaplayer['clinum']))
			
		if refillstamina:
			refillstaminaplayer = self.getPlayerByName(refillstamina.group(1))
			kwargs['Broadcast'].broadcast("RefillStamina #GetIndexFromClientNum(%s)#" % (refillstaminaplayer['clinum']))
						
		if help:
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s All commands on the server are done through server chat."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb mod help ^w for more info about the sb mod commands."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				 "SendMessage %s ^rsb player help ^w for more info about command's that affect players."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb startgame ^w will start the game"\
				% (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb giveteamgold team amount^w. will give gold to a team."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb changeworld mapname ^wwill change the map to the desired map."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb sudo args ^wdo whatever commands you want."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb allowteamchange ^wwill allow switching team."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb teamdiff ^wwill allow everyone to join in the same team."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb changepassword ^wwill change the server's password."\
				% (client['clinum']))
			
		if modhelp:
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb buildspeed amount ^wwill change the build speed."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb mod gravity amount ^wwill change the gravity."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb mod jump amount ^wwill change the jump height."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb mod speed amount ^wwill change the movement speed of the server."\
				 % (client['clinum']))
			
		if playerhelp:
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb setteam playername ^wwill move a specific player to another team."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb givegold player amount ^wwill give gold to a player."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb givesoul player amount ^wwill give souls to a player."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb giveexp player amount ^wwill give experience to a player."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				 "SendMessage %s ^rsb resetexp player ^wwill reset exp of a player."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
					"SendMessage %s ^rsb resetattributes ^wwill reset all attributes of a player."\
					% (client['clinum']))
			kwargs['Broadcast'].broadcast(\
					"SendMessage %s ^rsb refillhealth ^wwill refill a player health."\
					% (client['clinum']))
			kwargs['Broadcast'].broadcast(\
					"SendMessage %s ^rsb refillmana ^wwill refill a player mana."\
					% (client['clinum']))
			kwargs['Broadcast'].broadcast(\
					"SendMessage %s ^rsb refillstamina ^wwill refill a player stamina."\
					% (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb giveammo player ^wwill give ammo to a player."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb kick ^wwill remove a player from the server."\
				 % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rsb slap playername ^wwill move the player. Use to get them off of structures if they are exploiting."\
				 % (client['clinum']))
			
			
		if mmhelp:
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rmm enable modname ^wwill enable a mod."\
				 % (client['clinum'])) #modenable
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rmm get active ^wwill show all active mods."\
				 % (client['clinum'])) #modactive
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rmm get list ^wwill show all the possible mods."\
				 % (client['clinum'])) #modindirectory
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rmm reset ^wwill reset everything to its default settings."\
				 % (client['clinum'])) #modreset
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rmm create name ^wwill create a new mod with the specified name."\
				 % (client['clinum'])) #mmcreate
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rmm delete name^wwill delete a mod with the specified name."\
				 % (client['clinum'])) #mmdelete
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rmm modify name linenumber arg^wwill edit a mod by replacing a line with its arg."\
				 % (client['clinum'])) #mmmodify
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rmm view name ^wwill view what a mod contain with the specified name."\
				 % (client['clinum'])) #mmview			
			kwargs['Broadcast'].broadcast(\
				"SendMessage %s ^rmm write name arg ^wwill write a line in a mod file."\
				 % (client['clinum'])) #mmwrite				
				
		if modenable: #Enable a specific mod
			modName = "./mods/" + modenable.group(1)
			if os.path.isfile(modName): #Check if it exists
				with open(modName, 'r') as modfile:
					for line in modfile:
						kwargs['Broadcast'].broadcast("%s" % (line))
				self.modlist.append(modenable.group(1))
				kwargs['Broadcast'].broadcast("SendMessage -1 %s has been enabled." % (modenable.group(1)))
			else:
				kwargs['Broadcast'].broadcast("SendMessage -1 %s does not exist." % (modenable.group(1)))
					
		if modactive: #Shows the active mods currently on the server
			kwargs['Broadcast'].broadcast("SendMessage %s mods currently active on this server:" % (client['clinum']))
			if len(self.modlist) == 0:
				kwargs['Broadcast'].broadcast("SendMessage %s None" % (client['clinum']))
			else:
				for element in self.modlist:
					kwargs['Broadcast'].broadcast("SendMessage %s %s" % (client['clinum'], element))
		
		if modreset: #Reset all the mods to its original state
			self.modlist = []
			with open("./mods/original", 'r') as original:
				for line in original:
					kwargs['Broadcast'].broadcast("%s" % (line))	
			kwargs['Broadcast'].broadcast("SendMessage -1 All mods have been reseted.")
			
		if modindirectory: #Used to check what mods are in the directory
			modindir = os.listdir("./mods/")
			for each in modindir:
				kwargs['Broadcast'].broadcast("SendMessage %s %s" % (client['clinum'], each))		
			
		if mmcreate: #Used to create a mod
			modName = mmcreate.group(1)
			with open(modName, 'w') as newmodfile:
				newmodfile.write("//%s", newmodfile)
				kwargs['Broadcast'].broadcast("SendMessage %s %s has been created succesfully" % (client['clinum'], newmodfile))
				
		if mmview: #Used to view a mod
			with open("./mods/" + mmview.group(1), 'r') as modFile:
				for line in modFile:
					numberLine = 0
					kwargs['Broadcast'].broadcast("SendMessage %s %s %s" % (client['clinum'], numberLine, line))
					numberLine += 1
			
		if mmdelete: #Used to delete a mod
			os.remove("./mods/" + mmdelete.group(1))
			kwargs['Broadcast'].broadcast("SendMessage %s %s has been deleted with success" % (client['clinum'], mmdelete.group(1)))
			
		if mmwrite: #Used to write a line in a mod
			with open("./mods/" + mmwrite.group(1), 'a+') as modFile:
				modFile.write(mmwrite.group(2))
				kwargs['Broadcast'].broadcast("SendMessage %s %s has been added to %s successfully" % (client['clinum'], mmwrite.group(2), mmwrite.group(1)))
				
		if mmmodify: #modify a specific line
			with open("./mods/" + mmmodify.group(1), 'r') as modFile:
				data = modFile.readlines()
				data[mmmodify.group(2)] = mmmodifiy.group(3)
			with open("./mods" + mmmodify.group(1), 'w') as modFile:
				modFile.writelines(data)
				
				
					
						
	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		self.PHASE = phase

		if (phase == 7):
			self.banlist = []
			self.modlist = []
			with open("./mods/original", 'r') as original:
				for line in original:
					kwargs['Broadcast'].broadcast("%s" % (line))	
			for each in self.playerlist:
				each['team'] = 0
				each['commander'] = False
				
		if (phase == 6):
		#fetch leader list and reload at the start of each game
			try:
				response = urllib2.urlopen('http://cedeqien.com/modders.ini')
				leaderlist = response.read()
				leaderfile = os.path.join(os.path.dirname(self.CONFIG),'modders.ini')
				with open(leaderfile, 'w') as f:
					f.write(leaderlist)
				#reload the config file		
				self.onPluginLoad(leaderfile)
			except:
				return
				
	def onListClients(self, *args, **kwargs):
		clinum = int(args[0])
		name = args[2]
		ip = args[1]
		

		client = self.getPlayerByName(name)
		if not client:
		#if a player is missing from the list this will put them as an active player and get stats
		#usually used when reloading plugin during a game
			acct = self.ms.getAccount(name)
			acctid = acct[name]
			self.onConnect(clinum, 0000, ip, 0000, **kwargs)
			self.onSetName(clinum, name, **kwargs)
			self.onAccountId(clinum, acctid, **kwargs)
			client = self.getPlayerByName(name)
			
		client['active'] = True
		kwargs['Broadcast'].broadcast(\
		"echo CLIENT %s is on TEAM #GetTeam(|#GetIndexFromClientNum(%s)|#)#"\
		 % (client['clinum'], client['clinum']))