Exemplo n.º 1
0
    def onPluginLoad(self, config):
        self.ms = MasterServer()

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

        pass
Exemplo n.º 2
0
	def onPluginLoad(self, config):
		self.ms = MasterServer ()

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		
		for (name, value) in ini.items('var'):
			if (name == "banmatch"):
				self.BANMATCH = int(value)
			if (name == "sflimit"):
				self.SFLIMIT = int(value)
			if (name == "levellimit"):
				self.LEVELLIMIT = int(value)
			if (name == "matchlimit"):
				self.MATCHLIMIT = int(value)

		for (name, value) in ini.items('ipban'):
			self.ipban.append(name)

		admins = os.path.join(os.path.dirname(config),'admin.ini')	
		ini.read(admins)

		for (name, value) in ini.items('admin'):
			self.adminlist.append({'name': name, 'level' : value})
		print self.adminlist
		pass
Exemplo n.º 3
0
	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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    def onPluginLoad(self, config):
        self.ms = MasterServer()

        ini = ConfigParser.ConfigParser()
        ini.read(config)
        for (name, value) in ini.items('balancer'):
            if (name == "threshold"):
                self.THRESHOLD = int(value)
            if (name == "jointhreshold"):
                self.JOINTHRESHOLD = int(value)

        pass
Exemplo n.º 6
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
Exemplo n.º 7
0
	def onPluginLoad(self, config):
		self.ms = MasterServer ()

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		#for (name, value) in config.items('balancer'):
		#	if (name == "level"):
		#		self._level = int(value)

		#	if (name == "sf"):
		#		self._sf = int(value)
		
		pass
Exemplo n.º 8
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
Exemplo n.º 9
0
	def onPluginLoad(self, config):
		self.config = self.CONFIG_DEFAULT.copy()
		self.ms = MasterServer()

		print(self.config)
		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for name in self.config.keys():
			try:
				self.config[name] = ini.get('limit', name)
			except:
				raise
		print(self.config)

		pass
Exemplo n.º 10
0
	def onPluginLoad(self, config):
		self.ms = MasterServer ()
		
		ini = ConfigParser.ConfigParser()
		ini.read(config)
		
		pass
Exemplo n.º 11
0
class limit(ConsolePlugin):

	CONFIG_DEFAULT = {
		'reason': "This server has restrictions on",
		'level_min': 10,
		'level_max': 100,
		'sf_min': 50,
		'sf_max': 500,
		'forcespec': False,
	}

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

		print(self.config)
		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for name in self.config.keys():
			try:
				self.config[name] = ini.get('limit', name)
			except:
				raise
		print(self.config)

		pass

	def onAccountId(self, *args, **kwargs):
		config = self.config
		reason = config['reason']

		clnum = int(args[0])
		id    = int(args[1])

		stats = self.ms.getStatistics("%d" % (id)).get('all_stats').get(id)
		lv = int(stats['level'])
		sf = int(stats['sf'])

		act = False

		if (lv < config['level_min']) or (lv > config['level_max']):
			act = True
			reason += ". Level %d - %d only" % (config['level_min'], config['level_max'])

		if (sf < config['sf_min']) or (sf > config['sf_max']):
			act = True
			reason += ". SF %d - %d only" % (config['sf_min'], config['sf_max'])

		if not act:
			return

		if not config['forcespec']:
			kwargs['Broadcast'].put("kick %d \"%s\"" % (clnum, reason))
		else:
			kwargs['Broadcast'].put("SendMessage %d \"%s\"" % (clnum, reason))
			kwargs['Broadcast'].put("SetTeam #GetIndexFromClientNum(%d)# 0" % (clnum))
		kwargs['Broadcast'].broadcast()

		return
Exemplo n.º 12
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
Exemplo n.º 13
0
	def onPluginLoad(self, config):
		self.ms = MasterServer ()

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for (name, value) in ini.items('admin'):
			self.adminlist.append(name)
		#Don't know how to get boolean values for things in a specific section of .ini
		for (name, value) in ini.items('var'):
			if (name == "changesvrname") and (value == "true"):
				self.SVRNAME = True
			if (name == "changesvrdesc") and (value == "true"):
				self.SVRDESC = True
			if (name == "svrname"):
				self.svrname = value
			if (name == "changesvrname"):
				self.svrdesc = value
			if (name == "double") and (value == "true"):
				self.DOUBLEELIM = True
Exemplo n.º 14
0
	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
Exemplo n.º 15
0
    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
Exemplo n.º 16
0
	def onPluginLoad(self, config):
		self.ms = MasterServer ()

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for (name, value) in ini.items('balancer'):
			if (name == "threshold"):
				self.THRESHOLD = int(value)
			if (name == "jointhreshold"):
				self.JOINTHRESHOLD = int(value)
		
		
		pass
Exemplo n.º 17
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
Exemplo n.º 18
0
    def onPluginLoad(self, config):
        self.ms = MasterServer()

        ini = ConfigParser.ConfigParser()
        ini.read(config)
        #for (name, value) in config.items('mapvote'):
        #	if (name == "level"):
        #		self._level = int(value)

        #	if (name == "sf"):
        #		self._sf = int(value)
        for (name, value) in ini.items('maps'):
            self.maplist.append({'name': name, 'status': value})

        for (name, value) in ini.items('var'):
            if (name == "votepercent"):
                self.VOTEPERCENT = value
            if (name == "minplayers"):
                self.MINPLAYERS = value

        print self.MINPLAYERS, self.VOTEPERCENT
        pass
Exemplo n.º 19
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
Exemplo n.º 20
0
	def onPluginLoad(self, config):
		self.ms = MasterServer ()

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for (name, value) in ini.items('maps'):
			self.maplist.append({'name' : name, 'status' : value})

		for (name, value) in ini.items('var'):
			if (name == "votepercent"):
				self.VOTEPERCENT = value
			if (name == "minplayers"):
				self.MINPLAYERS = value

		print self.MINPLAYERS, self.VOTEPERCENT
		pass
Exemplo n.º 21
0
    def onPluginLoad(self, config):
        print("In Plugin Load")
        self.ms = MasterServer()
        ini = ConfigParser.ConfigParser()
        ini.read(config)
        for (name, value) in ini.items('queue'):
            print("In ini Loop: " + str(name) + " / " + str(value))
            if (name == "ismodserver"):
                print("In: if (name == isModServer):")
                queue.isModServer = value
            if (name == "ismodservercurrentmod"):
                print("In: if (name == isModServerCurrentMod)")
                queue.isModServerCurrentMod = value

        print("Setting: " + "Set " + str(queue.isModServerGameVar) + " " +
              str(queue.isModServer))
        print("isModServerCurrentMod: " + queue.isModServerCurrentMod)
Exemplo n.º 22
0
 def handle(self, **kwargs):
     Log().info("@[{}]".format(self.__class__.__name__))
     scenario = kwargs["scenario"]
     if not is_open("localhost", 5000):
         # Master server is not running, will do start.
         Log().info("Master Server starting... ")
         master_server = MasterServer()
         master_server.set_scenario(scenario)
         master_server.start()
     else:
         Log().info("Master Server already started.")
     super(StartMaster, self).handle(**kwargs)
Exemplo n.º 23
0
	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
Exemplo n.º 24
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
Exemplo n.º 25
0
class beginners(ConsolePlugin):
	VERSION = "1.0.0"
	ms = None
	TIME = 0
	GAMESTARTED = 0
	STARTSTAMP = 0
	CHAT_INTERVAL = 10
	CHAT_STAMP = 0
	PHASE = 0
	MATCHES = 0
	playerlist = []
	adminlist = []
	ipban = []
	BANMATCH = 20
	SFLIMIT = 110
	LEVELLIMIT = 10
	MATCHLIMIT = 4
	
	def onPluginLoad(self, config):
		self.ms = MasterServer ()

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		
		for (name, value) in ini.items('var'):
			if (name == "banmatch"):
				self.BANMATCH = int(value)
			if (name == "sflimit"):
				self.SFLIMIT = int(value)
			if (name == "levellimit"):
				self.LEVELLIMIT = int(value)
			if (name == "matchlimit"):
				self.MATCHLIMIT = int(value)

		for (name, value) in ini.items('ipban'):
			self.ipban.append(name)

		admins = os.path.join(os.path.dirname(config),'admin.ini')	
		ini.read(admins)

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

	def onStartServer(self, *args, **kwargs):
		
		self.VERSION = "0.0.6"
		self.TIME = 0
		self.GAMESTARTED = 0
		self.STARTSTAMP = 0
		self.CHAT_INTERVAL = 10
		self.CHAT_STAMP = 0
		self.PHASE = 0
		self.MATCHES = 0
		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]
		ip = args[2]
		for client in self.playerlist:
			if (client['clinum'] == id):
				print 'already have entry with that clientnum!'
				return

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

		self.playerlist.append ({'clinum' : id, 'acctid' : 0, 'level' : 0, 'sf' : 0, 'name' : 'X', 'active' : 0, 'banned' : False, 'ip' : ip, 'banstamp' : 0, 'kills' : 0})

		
	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client ['active'] = 0
	

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

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

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

		doKick = False
		reason1 = "This is a beginners server. Please go play on a normal server."
		reason2 = "You (or someone at your IP address) have been temporarily prohibited from this server."
		reason3 = "Please go play on normal server."
		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'])
		wins = int(stats['wins'])
		losses = int(stats['losses'])
		dcs = int(stats['d_conns'])
		exp = int(stats['exp'])
		time = int(stats['secs'])
		if sf == 0 and time > 0:
			time = time/60
			sf = int(exp/time)
		total = wins + losses + dcs

		client = self.getPlayerByClientNum(cli)

		client ['acctid'] = int(id)
		client ['level'] = level
		client ['sf'] = sf
		client ['active'] = 1

		if client['banned']:
			reason = reason3
			doKick = True		

		for each in self.playerlist:
			if each['banned'] and (each['ip'] == client['ip']):
				reason = reason2
				doKick = True
				

		if (sf > self.SFLIMIT) and (total > self.MATCHLIMIT):
			reason = reason1
			doKick = True
			client ['banned'] = True
			client ['banstamp'] = self.MATCHES

		if (level > self.LEVELLIMIT):
			reason = reason1
			doKick = True

		for each in self.adminlist:
			if each['name'].lower() == client['name'].lower():
				doKick = False			
				client['banned'] = False
		if doKick:
			kwargs['Broadcast'].broadcast("kick %s \"%s\"" % (cli, reason))

		print client

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

	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		self.PHASE = phase
	
		if (phase == 7):
			self.onGameEnd()
		if (phase == 5):
			self.onGameStart(*args, **kwargs)
		
	
	def onGameEnd(self, *args, **kwargs):
						
		self.MATCHES += 1
		#all players are unbanned after 15 matches
		for each in self.playerlist:
			each['kills'] = 0
			each['active'] = 0
			duration = self.MATCHES - int(each['banstamp'])
			if duration > self.BANMATCH:
				each['banned'] = False

		self.GAMESTARTED = 0


	def onGameStart (self, *args, **kwargs):
		
		
		self.STARTSTAMP = args[1]
		self.GAMESTARTED = 1
		for each in self.playerlist:
			each['kills'] = 0
	
	def onServerStatus(self, *args, **kwargs):
		CURRENTSTAMP = int(args[1])
		self.TIME = int(CURRENTSTAMP) - int(self.STARTSTAMP)
			
		if self.PHASE == 5:
			if (self.TIME > (10 * 60 * 1000)):
				self.smurfCheck (**kwargs)			

	def onGetLevels(self, *args, **kwargs):
		clinum = args[0]
		level = int(args[1])
		client = self.getPlayerByClientNum(clinum)
		

	def onGetLevels(self, *args, **kwargs):
		clinum = args[0]
		level = int(args[1])
		client = self.getPlayerByClientNum(clinum)
		doKick = False
		reason = "This is either a smurf account or you are too good for this server. You should play on another server."
		if level > 6:
			doKick = True
			client ['banned'] = True
			client ['banstamp'] = self.MATCHES

		if doKick:
			kwargs['Broadcast'].broadcast("kick %s \"%s\"" % (cli, reason))	
		
	def onHasKilled(self, *args, **kwargs):
		
		killed = self.getPlayerByName(args[0])
		killer = self.getPlayerByName(args[1])
		
		killer['kills'] += 1
		print killer
		print killed

	def smurfCheck(self, **kwargs):
		
		totalkills = 0
		activeplayers = 0
		avgkills = 0
		reason = "Congratulations! You have done a great job and have graduated from this server."

		for each in self.playerlist:
			if each['active'] == 1:
				activeplayers += 1
				totalkills += int(each['kills'])

		avgkills = int(totalkills/activeplayers)
		kwargs['Broadcast'].broadcast("echo BEGINNERS: Average kills: %s" % (avgkills))
		for players in self.playerlist:
			if players['active'] == 1:
				over = 'No'
				if (players['kills'] > (avgkills * 3)) and (players['kills'] > 20):
					over = 'Yes'
					cli = players['clinum']
					#players['banned'] = True
					#players['banstamp'] = self.MATCHES
					#kwargs['Broadcast'].broadcast("kick %s \"%s\"" % (cli, reason))
					kwargs['Broadcast'].broadcast("echo BEGINNERS: Player: %s, Kills: %s, Over?: %s" % (players['name'], players['kills'], over))
				
				
	def onMessage(self, *args, **kwargs):
		
		name = args[1]
		message = args[2]
		
		client = self.getPlayerByName(name)
		
		if (args[0] == "SQUAD") and (message == 'report bans'):
			for bans in self.playerlist:
				if bans['banned']:
					kwargs['Broadcast'].broadcast("SendMessage %s Banned: %s, IP: %s" % (client['clinum'], bans['name'], bans['ip']))
Exemplo n.º 26
0
class mapvote(ConsolePlugin):
    VERSION = "0.0.1"
    ms = None
    PHASE = 0
    playerlist = []
    maplist = []
    votelist = {'votes': 0, 'playervotes': []}
    TOTALPLAYERS = 0
    VOTEPERCENT = 40
    MINPLAYERS = 0
    NEWMAP = None
    MAPVOTE = True

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

        ini = ConfigParser.ConfigParser()
        ini.read(config)
        #for (name, value) in config.items('mapvote'):
        #	if (name == "level"):
        #		self._level = int(value)

        #	if (name == "sf"):
        #		self._sf = int(value)
        for (name, value) in ini.items('maps'):
            self.maplist.append({'name': name, 'status': value})

        for (name, value) in ini.items('var'):
            if (name == "votepercent"):
                self.VOTEPERCENT = value
            if (name == "minplayers"):
                self.MINPLAYERS = value

        print self.MINPLAYERS, self.VOTEPERCENT
        pass

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

        print 'serverstarted'

    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]

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

    def onSetName(self, *args, **kwargs):
        mapnames = []
        for each in self.maplist:
            mapnames.append(each['name'])

        mapnames = ', '.join(mapnames)

        mapmessage = "^cThis server is currently equipped with the ability to vote for a map change. Before a game has started you can send the message to ^rALL ^cchat: ^ynextmap mapname"
        mapmessage2 = "^cThis will register your vote for that map."
        mapmessage3 = ("^cCurrent valid maps are: ^y%s" % (mapnames))
        cli = args[0]
        playername = args[1]
        client = self.getPlayerByClientNum(cli)
        client['name'] = playername
        kwargs['Broadcast'].broadcast("SendMessage %s %s" %
                                      (client['clinum'], mapmessage))
        kwargs['Broadcast'].broadcast("SendMessage %s %s" %
                                      (client['clinum'], mapmessage2))
        kwargs['Broadcast'].broadcast("SendMessage %s %s" %
                                      (client['clinum'], mapmessage3))

    def onAccountId(self, *args, **kwargs):
        self.TOTALPLAYERS += 1
        cli = args[0]
        id = args[1]
        stats = self.ms.getStatistics(id).get('all_stats').get(int(id))

        client = self.getPlayerByClientNum(cli)

        client['acctid'] = int(id)
        client['active'] = 1

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

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

        for each in self.playerlist:
            if cli == each['clinum']:
                each['active'] = 0

        #if a player has voted and disconnects, remove their vote
        for each in self.votelist['playervotes']:
            if each['player'] == client['name']:
                self.votelist['playervotes'].remove(each)
                self.votelist['votes'] -= 1

        self.TOTALPLAYERS -= 1

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

        if (phase == 7):
            self.onGameEnd(**kwargs)

        if (phase == 6):
            self.clearMapVotes(*args, **kwargs)

        if (phase == 5):
            self.clearMapVotes(*args, **kwargs)

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

        if (self.PICKING == 1):
            print 'team picking has begun, do not clear team player lists'
            kwargs['Broadcast'].broadcast(
                "echo team picking has begun, do not clear team player lists!")

            self.PICKING = 0
            return

    def voteCheck(self, *args, **kwargs):
        tie = False
        totalplayers = self.TOTALPLAYERS
        totalvotes = self.votelist['votes']
        minplayers = int(self.MINPLAYERS)
        threshold = int(self.VOTEPERCENT)
        votepercent = int(totalvotes / totalplayers) * 100
        #At least this many players must be present to even trigger a map selection
        if totalplayers < minplayers:
            print totalplayers
            print 'minplayer abort'
            return
        #This percentage of the total number of players must vote to trigger a map selection
        if votepercent < threshold:
            print votepercent
            print 'percent abort'
            return

        #determine which map has the most votes
        d = {}
        for votes in self.votelist['playervotes']:
            maps = votes['mapvote']
            d.setdefault(maps, 0)
            d[maps] += 1

        items = [(v, k) for k, v in d.items()]
        items.sort()
        items.reverse()
        size = len(items)
        if size > 1:
            if items[0][0] == items[1][0]:
                print 'we have a tie'
                tie = True
        if tie:
            kwargs['Broadcast'].broadcast(
                "Serverchat ^cThere is a tie between ^r%s ^cand ^r%s. ^cIf you would like to change your vote you may do so."
                % (items[0][1], items[1][1]))
            return

        #We have a map winner
        newmap = items[0][1]
        self.ChangeMap(newmap, **kwargs)

    def ChangeMap(self, newmap, **kwargs):

        status = 'official'

        for each in self.maplist:
            if each['name'] == newmap:
                status = each['status']
        if status == 'unofficial':
            kwargs['Broadcast'].broadcast(
                "set svr_sendStats false; set svr_official false ")

        kwargs['Broadcast'].broadcast("changeworld %s" % (newmap))
        self.clearMapVotes(*args, **kwargs)

    def onMessage(self, *args, **kwargs):
        voted = False
        votemap = None
        #ignore anything that isn't sent to ALL chat
        if args[0] != "ALL":
            return
        #if the game has started, or we are in end phase, ignore
        if self.PHASE == 5 or self.PHASE == 7:
            return

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

        client = self.getPlayerByName(name)

        mapvote = re.match("nextmap (\S+)", message, flags=re.IGNORECASE)
        formap = mapvote.group(1)

        if not mapvote:
            return

        if mapvote:

            voted = self.CheckVoted(client)

            for maps in self.maplist:
                if formap == maps['name']:

                    votemap = formap

            if votemap == None:
                #Map name is invalid, tell them they got it wrong
                kwargs['Broadcast'].broadcast(
                    "SendMessage %s ^cMap name not recognized." %
                    (client['clinum']))
                return

        #player has already voted, just change their map selection
        if voted:
            for each in self.votelist['playervotes']:
                if each['player'] == client['name']:
                    each['mapvote'] = votemap
                    kwargs['Broadcast'].broadcast(
                        "SendMessage %s ^cYou have switched your vote to ^r%s."
                        % (client['clinum'], votemap))
                    self.reportVotes(**kwargs)
                    self.voteCheck(**kwargs)
                    return
        #player has not yet voted, add to the total number of votes and add their selection to the list
        self.votelist['votes'] += 1
        self.votelist['playervotes'].append({
            'player': client['name'],
            'mapvote': votemap
        })
        kwargs['Broadcast'].broadcast(
            "SendMessage %s ^cYou have voted for ^r%s." %
            (client['clinum'], votemap))
        self.reportVotes(**kwargs)
        #check to see if all the voting critera have been met
        self.voteCheck(**kwargs)

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

        for each in self.votelist['playervotes']:
            if each['player'] == client['name']:
                return True

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

        self.votelist = {'votes': 0, 'playervotes': []}
        self.TOTALPLAYERS = 0

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

        d = {}
        for votes in self.votelist['playervotes']:
            maps = votes['mapvote']
            d.setdefault(maps, 0)
            d[maps] += 1

        items = [(v, k) for k, v in d.items()]
        items.sort()
        items.reverse()

        for each in items:
            kwargs['Broadcast'].broadcast("Serverchat ^cVotes for ^r%s: ^c%s" %
                                          (each[1], each[0]))

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

        kwargs['Broadcast'].broadcast(
            "set svr_sendStats true; set svr_official true")
Exemplo n.º 27
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']))
Exemplo n.º 28
0
class balancer(ConsolePlugin):
    VERSION = "1.0.8"
    ms = None
    TIME = 0
    THRESHOLD = 6
    JOINTHRESHOLD = 8
    DIFFERENCE = -1
    GAMESTARTED = 0
    STARTSTAMP = 0
    DENY = 0
    OPTION = 0
    PICKING = 0
    CHAT_INTERVAL = 10
    CHAT_STAMP = 0
    PHASE = 0
    TOTAL1 = 0
    TOTAL2 = 0
    STAMPS = 0
    reason = "Your Skill Factor is 0. Please play some matches on official beginner servers to get some stats before you join this server."
    playerlist = []
    itemlist = []
    balancereport = []
    teamOne = {'size': 0, 'avgBF': -1, 'combinedBF': 0, 'players': []}
    teamTwo = {'size': 0, 'avgBF': -1, 'combinedBF': 0, 'players': []}
    game = {'size': 0, 'avgBF': -1}
    switchlist = []
    followlist = []

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

        ini = ConfigParser.ConfigParser()
        ini.read(config)
        for (name, value) in ini.items('balancer'):
            if (name == "threshold"):
                self.THRESHOLD = int(value)
            if (name == "jointhreshold"):
                self.JOINTHRESHOLD = int(value)

        pass

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

        self.TIME = 0
        self.THRESHOLD = 6
        self.DIFFERENCE = -1
        self.GAMESTARTED = 0
        self.STARTSTAMP = 0
        self.DENY = 0
        self.OPTION = 0
        self.PICKING = 0
        self.CHAT_INTERVAL = 10
        self.CHAT_STAMP = 0
        self.PHASE = 0
        self.TOTAL1 = 0
        self.TOTAL2 = 0
        self.STAMPS = 0
        self.playerlist = []
        self.itemlist = []
        self.balancereport = []
        self.teamOne = {'size': 0, 'avgBF': -1, 'combinedBF': 0, 'players': []}
        self.teamTwo = {'size': 0, 'avgBF': -1, 'combinedBF': 0, 'players': []}
        self.game = {'size': 0, 'avgBF': -1}
        self.switchlist = []
        self.followlist = []

    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 onRefresh(self, *args, **kwargs):

        del self.teamOne['players'][:]
        del self.teamTwo['players'][:]
        self.teamOne['size'] = 0
        self.teamTwo['size'] = 0

        for client in self.playerlist:
            if (client['active'] == 1):
                kwargs['Broadcast'].broadcast(
                    "set _idx #GetIndexFromClientNum(%s)#; set _team #GetTeam(|#_idx|#)#; echo CLIENT %s is on TEAM #_team#"
                    % (client['clinum'], client['clinum']))

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

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

        if (team > 0):
            client = self.getPlayerByClientNum(clinum)
            teamlists = self.GetTeamLists(client, team)
            fromteam = teamlists['fromteam']

            self.addTeamMember(client, fromteam, team, **kwargs)

            return

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

        id = args[0]

        for client in self.playerlist:
            if (client['clinum'] == id):
                #added 10/12. If a player DCs and reconnects, they are auto-joined to their old team
                #but there is no team join message. This automatically adds them back to the balancer team list.
                print 'already have entry with that clientnum!'
                team = int(client['team'])

                if (team > 0):
                    teamlists = self.GetTeamLists(client, team)
                    toteam = teamlists['toteam']
                    fromteam = teamlists['fromteam']
                    self.addTeamMember(client, fromteam, team, **kwargs)
                    client['active'] = 1
                    return
                return
        self.playerlist.append({
            'clinum': id,
            'acctid': 0,
            'level': 0,
            'sf': 0,
            'bf': 0,
            'lf': 0,
            'name': 'X',
            'team': 0,
            'moved': 0,
            'index': 0,
            'exp': 2,
            'value': 150,
            'prevent': 0,
            'active': 0,
            'gamelevel': 1
        })

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

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

        client = self.getPlayerByClientNum(cli)

        client['name'] = playername

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

        doKick = False

        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'])
        if sf == 0 and exp > 500:
            time = time / 60
            sf = int(exp / time)
        client = self.getPlayerByClientNum(cli)

        client['acctid'] = int(id)
        client['level'] = level
        client['sf'] = sf
        client['lf'] = lf
        client['exp'] = exp
        client['active'] = 1
        if sf == 0:
            doKick = True

        if doKick:
            kwargs['Broadcast'].broadcast("kick %s \"%s\"" %
                                          (cli, self.reason))

        self.retrieveLevels(cli, **kwargs)

    def checkForSpectator(self, cli):
        player = self.getPlayerByClientNum(cli)

        if (player['team'] > 0):

            return cli
        else:
            return -1

    def getTeamMember(self, item, cli, fromteam):

        indice = -1

        for player in fromteam['players']:

            indice += 1

            if (player['clinum'] == cli):

                return indice

    def getPlayerIndex(self, cli):

        indice = -1
        for player in self.playlist:
            indice += 1

            if (player['clinum'] == cli):
                return indice

    def removeTeamMember(self, client, fromteam, team, **kwargs):
        print 'Removing player....'
        client['team'] = team
        cli = client['clinum']
        item = 'clinum'
        PLAYER_INDICE = self.getTeamMember(item, cli, fromteam)
        fromteam['combinedBF'] -= fromteam['players'][PLAYER_INDICE]['bf']
        del fromteam['players'][PLAYER_INDICE]

        self.getGameInfo(**kwargs)

    def addTeamMember(self, client, toteam, team, **kwargs):

        print 'Adding player....'
        cli = client['clinum']
        client['active'] = 1
        NAME = client['name']
        level = client['level']
        SF = client['sf']
        #BF = SF + level + (client ['gamelevel'] * 4)
        BF = SF + (client['gamelevel'] * 4)
        LF = client['lf'] + 10
        moved = client['moved']
        client['team'] = team
        client['bf'] = BF
        toteam['players'].append({
            'clinum': cli,
            'name': NAME,
            'sf': SF,
            'lf': LF,
            'level': level,
            'moved': moved,
            'bf': BF
        })

        self.getGameInfo(**kwargs)

    def GetTeamLists(self, client, team):

        currentteam = client['team']

        L = {'toteam': '0', 'fromteam': '0'}

        if (int(currentteam) == 1):
            L['fromteam'] = self.teamOne
            L['toteam'] = self.teamTwo
            return L
        if (int(currentteam) == 2):
            L['fromteam'] = self.teamTwo
            L['toteam'] = self.teamOne
            return L

        if (int(team) == 1):
            L['toteam'] = self.teamOne

        if (int(team) == 2):
            L['toteam'] = self.teamTwo

        return L
        #don't think I need this but I am leaving it in
        del L[0]

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

        spec = -1
        team = int(args[1])
        cli = args[0]
        self.retrieveLevels(cli, **kwargs)
        client = self.getPlayerByClientNum(cli)
        currentteam = client['team']
        prevented = int(client['prevent'])
        teamlists = self.GetTeamLists(client, team)
        toteam = teamlists['toteam']
        fromteam = teamlists['fromteam']

        if (self.DENY == 1):
            self.DIFFERENCE = abs(self.evaluateBalance())
            diff = self.DIFFERENCE

        #check to see if the player is on a team and going to spectator. spec = -1 unless the player is already on a team
        if (int(team) == 0):
            spec = self.checkForSpectator(cli)
        #need to have this to avoid having players added multiple times as I have seen happen
        if (spec == -1) and (int(currentteam) == int(team)):

            return
        #if the player is switching teams, add them to the new team and remove from the old
        if (spec == -1) and (int(currentteam) > 0):

            self.addTeamMember(client, toteam, team, **kwargs)
            self.removeTeamMember(client, fromteam, team, **kwargs)
        #if the player hasn't joined a team yet, go ahead and add them to the team
        elif (spec == -1):
            self.addTeamMember(client, toteam, team, **kwargs)
            self.getGameInfo(**kwargs)
            #Players are prevented from joining in the deny phase if they will cause greater than a 10% stack
            #this applies to both even and uneven games. The player is forced back to team 0.
            if (self.DENY == 1):
                self.DIFFERENCE = abs(self.evaluateBalance())
                if (self.DIFFERENCE > self.JOINTHRESHOLD) and (self.DIFFERENCE
                                                               > diff):
                    action = 'PREVENT'
                    self.retrieveIndex(client, action, **kwargs)
                    return
                #There may be an issue if the player is forced back to team 0 that they can't join a team
                #even if conditions are met. This just forcibly puts the player on the team they are are trying to join
                #provided the above critera is not true.
                if (prevented == 1):
                    action = 'ALLOW'
                    self.retrieveIndex(client, action, **kwargs)

        #if the player is going to spec, just remove them from the team
        if (spec > -1):
            self.removeTeamMember(client, fromteam, team, **kwargs)

        self.OPTION = 0

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

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

        team = client['team']

        if (int(team) > 0):

            teamlist = self.GetTeamLists(client, team)
            fromteam = teamlist['fromteam']
            self.removeTeamMember(client, fromteam, team, **kwargs)

        #self.sendGameInfo(**kwargs)
        client['active'] = 0

    def onCommResign(self, *args, **kwargs):
        name = args[0]

        client = self.getPlayerByName(name)
        team = client['team']
        cli = client['clinum']

        teamlist = self.GetTeamLists(client, team)
        fromteam = teamlist['fromteam']
        item = 'clinum'
        PLAYER_INDICE = self.getTeamMember(item, cli, fromteam)

        fromteam['players'][PLAYER_INDICE]['bf'] = client['sf'] + (
            client['gamelevel'] * 4)
        #fromteam['players'][PLAYER_INDICE]['bf'] = int(client['sf'] + client['level'] + (client['gamelevel']*4))
        fromteam['players'][PLAYER_INDICE]['moved'] = 0

        client['moved'] = 0

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

        cli = args[0]
        client = self.getPlayerByClientNum(cli)
        team = client['team']
        teamlist = self.GetTeamLists(client, team)
        fromteam = teamlist['fromteam']
        item = 'clinum'
        PLAYER_INDICE = self.getTeamMember(item, cli, fromteam)

        #fromteam['players'][PLAYER_INDICE]['bf'] = client ['lf']
        fromteam['players'][PLAYER_INDICE]['bf'] = fromteam['players'][
            PLAYER_INDICE]['lf']
        fromteam['players'][PLAYER_INDICE]['moved'] = 1
        #set moved to 1 to prevent the player from being auto-swapped as commander
        client['moved'] = 1

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

        if (phase == 7):
            self.onGameEnd(**kwargs)
        if (phase == 5):
            self.onGameStart(*args, **kwargs)
            self.PICKING = 0
        if (phase == 3):
            self.PICKING = 1
        if (phase == 6):
            self.onNewGame(*args, **kwargs)

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

        avg1 = int(self.TOTAL1 / self.STAMPS)
        avg2 = int(self.TOTAL2 / self.STAMPS)
        print avg1, avg2, self.STAMPS
        kwargs['Broadcast'].broadcast(
            "Serverchat ^cHow stacked was this game from start to finish? Humans had an average combined BF of ^r%s^c, Beasts had an average combined BF of ^r%s ^cfrom a total of ^y%s ^ctime points."
            % (avg1, avg2, self.STAMPS))
        #clear out the team dictionary info and globals when the map is reloaded
        del self.teamOne['players'][:]
        del self.teamTwo['players'][:]
        for player in self.playerlist:
            player['active'] = 0
            player['team'] = 0
            player['gamelevel'] = 1
            player['bf'] = int(player['sf'] + player['level'])
            player['value'] = 150
        self.teamOne['size'] = 0
        self.teamOne['avgBF'] = -1
        self.teamOne['combinedBF'] = 0
        self.teamTwo['size'] = 0
        self.teamTwo['avgBF'] = -1
        self.teamTwo['combinedBF'] = 0
        self.GAMESTARTED = 0
        self.STARTSTAMP = 0
        self.DENY = 0
        self.OPTION = 0
        self.DIFFERENCE = -1
        self.PICKING = 0
        self.balancereport = []
        #self.playerlist = []
        self.TOTAL1 = 0
        self.TOTAL2 = 0
        self.STAMPS = 0

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

        if (self.PICKING == 1):
            print 'team picking has begun, do not clear team player lists'
            kwargs['Broadcast'].broadcast(
                "echo team picking has begun, do not clear team player lists!")

            self.PICKING = 0
            return

        #clear out the team dictionary info and globals when the map is reloaded
        del self.teamOne['players'][:]
        del self.teamTwo['players'][:]
        for player in self.playerlist:
            player['active'] = 0
            player['team'] = 0
            player['gamelevel'] = 1
            player['bf'] = int(player['sf'] + player['level'])
            player['value'] = 150
        self.teamOne['size'] = 0
        self.teamOne['avgBF'] = -1
        self.teamOne['combinedBF'] = 0
        self.teamTwo['size'] = 0
        self.teamTwo['avgBF'] = -1
        self.teamTwo['combinedBF'] = 0
        self.GAMESTARTED = 0
        self.STARTSTAMP = 0
        self.DENY = 0
        self.OPTION = 0
        self.DIFFERENCE = -1

        self.RegisterScripts(**kwargs)

    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"
        )
        #this makes sure we get an update every thirty seconds.
        kwargs['Broadcast'].broadcast("set sv_statusNotifyTime 30000")

    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 retrieveIndex(self, mover, action, **kwargs):
        #Use this for any manipulations when you need to get the current player index from the server. This is used for MOVE, PREVENT, ALLOW
        cli = mover['clinum']
        client = self.getPlayerByClientNum(cli)
        kwargs['Broadcast'].broadcast(
            "set _value #GetIndexFromClientNum(%s)#; echo Sv: Client %s index is #_value#. ACTION: %s"
            % (cli, cli, action))

    def onRetrieveIndex(self, *args, **kwargs):
        #get stuff from parser
        clinum = args[0]
        index = args[1]
        action = args[2]
        if (action == 'MOVE'):
            self.move(clinum, index, **kwargs)
        if (action == 'PREVENT'):
            self.prevent(clinum, index, **kwargs)
        if (action == 'ALLOW'):
            self.allow(clinum, index, **kwargs)
        if (action == 'LEVEL'):
            self.level(clinum, index, **kwargs)

    def runBalancer(self, **kwargs):
        #determines if it is even or uneven balancer
        #3-23-11 - If there are fewer than 8 players, don't bother with balancer
        if (self.teamOne['size'] + self.teamTwo['size']) < 8:
            return

        diff = self.teamOne['size'] - self.teamTwo['size']
        print diff
        if (diff == 0):
            self.EvenTeamBalancer(**kwargs)
        #uneven balancer if there is a difference between 1-3. if it more than that, it would be best to restart, but that has not been implemented
        elif (abs(diff) > 0 and abs(diff) < 4):

            self.UnEvenTeamBalancer(**kwargs)

        else:
            return

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

        self.ItemList()
        self.STARTSTAMP = args[1]
        self.GAMESTARTED = 1
        kwargs['Broadcast'].broadcast("echo GAMESTARTED")

        self.sendGameInfo(**kwargs)

        kwargs['Broadcast'].broadcast(
            "ServerChat ^cIf necessary, the teams will be auto-balanced at 1, 3, and 6 minutes of game time."
        )
        kwargs['Broadcast'].broadcast(
            "ServerChat ^cAfter 6 minutes, joining will be limited to players that do not generate imbalance."
        )
        kwargs['Broadcast'].broadcast(
            "ServerChat ^cAt 5 minute increments starting at minute 10, the server will check for imbalance and notify players that they will be switched in one minute unless they reject the move."
        )
        kwargs['Broadcast'].broadcast(
            "ServerChat ^cSelected players may send the message 'reject' to ^bALL ^cchat to prevent the change."
        )

        self.RegisterScripts(**kwargs)
        self.startFollow(**kwargs)

    def onServerStatus(self, *args, **kwargs):
        CURRENTSTAMP = int(args[1])
        self.TIME = int(CURRENTSTAMP) - int(self.STARTSTAMP)
        #self.getTeamLevels(**kwargs)
        kwargs['Broadcast'].broadcast(
            "set _team1num #GetNumClients(1)#; set _team2num #GetNumClients(2)#; echo SERVER-SIDE client count, Team 1 #_team1num#, Team 2 #_team2num#"
        )

        if (self.GAMESTARTED == 1):
            self.TOTAL1 += self.teamOne['combinedBF']
            self.TOTAL2 += self.teamTwo['combinedBF']
            self.STAMPS += 1

    def evaluateBalance(self, BF1=0.0, BF2=0.0, moving=False, **kwargs):
        large = self.getLargeTeam()
        small = self.getSmallTeam()
        largebf = float(large['combinedBF'])
        smallbf = float(small['combinedBF'])
        totalbf = largebf + smallbf
        largeshare = (largebf - BF1 + BF2) / totalbf
        smallshare = (smallbf + BF1 - BF2) / totalbf
        largesize = float(large['size'])
        smallsize = float(small['size'])
        totalsize = largesize + smallsize
        if moving:
            largesize = float(large['size']) - 1.0
            smallsize = float(small['size']) + 1.0

        sizediff = largesize / totalsize
        largepercent = largeshare
        #largepercent = largeshare + sizediff
        return (largepercent - 0.5) * 100
        #return (largepercent - 1) * 100

    def getClosestPersonToTarget(self, team, **kwargs):

        lowest = -1
        pick = None

        for player1 in team['players']:

            if (player1['moved'] == 1):
                continue

            ltarget = abs(self.evaluateBalance(float(player1['bf']), 0.0,
                                               True))
            print ltarget
            if (lowest < 0):
                lowest = ltarget
                # wouldn't work if the first player was the one to pick, so had to do this here
                pick = player1
                continue

            if (lowest < ltarget):
                continue

            lowest = ltarget
            pick = player1

        print pick

        if (pick == None):
            kwargs['Broadcast'].broadcast(
                "echo BALANCER: UNEVEN balancer was not happy for some reason I can't figure out"
            )
            return

        kwargs['Broadcast'].broadcast(
            "echo BALANCER: UNEVEN balancer selections: Client %s with bf %s for a starting BF stacking of %s to %s"
            % (pick['clinum'], pick['bf'], self.DIFFERENCE, lowest))
        #if the selected option doesn't actually improve anything, terminate
        if (lowest > self.DIFFERENCE):
            kwargs['Broadcast'].broadcast(
                "echo BALANCER: unproductive UNEVEN balance")
            return

        if (self.OPTION == 0):
            #get the player index and move them
            action = 'MOVE'
            self.retrieveIndex(pick, action, **kwargs)
            return

        if (self.OPTION == 1):
            self.switchlist.append({
                'name': pick['name'],
                'clinum': pick['clinum'],
                'accept': 0
            })
            print self.switchlist
            self.giveOption(**kwargs)

    def getClosestTwoToTarget(self, team1, team2, **kwargs):

        lowest = -1
        pick1 = None
        pick2 = None

        for player1 in team1['players']:
            if (player1['moved'] == 1):
                continue
            for player2 in team2['players']:

                if (player2['moved'] == 1):
                    continue

                ltarget = abs(
                    self.evaluateBalance(float(player1['bf']),
                                         float(player2['bf'])))

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

                if (lowest < ltarget):
                    continue

                lowest = ltarget
                pick1 = player1
                pick2 = player2

        print pick1, pick2

        kwargs['Broadcast'].broadcast(
            "echo Balancer selections: Clients %s, %s with BF %s, %s." %
            (pick1['clinum'], pick2['clinum'], pick1['bf'], pick2['bf']))

        if (lowest >= self.DIFFERENCE):
            print 'unproductive balance. terminate'
            kwargs['Broadcast'].broadcast("echo unproductive EVEN balance")
            return

        if (self.OPTION == 0):
            action = 'MOVE'
            self.retrieveIndex(pick1, action, **kwargs)
            self.retrieveIndex(pick2, action, **kwargs)
            return

        if (self.OPTION == 1):
            self.switchlist.append({
                'name': pick1['name'],
                'clinum': pick1['clinum'],
                'accept': 0
            })
            self.switchlist.append({
                'name': pick2['name'],
                'clinum': pick2['clinum'],
                'accept': 0
            })
            print self.switchlist
            self.giveOption(**kwargs)

    def giveOption(self, **kwargs):

        index = -1
        playermessage = "^cYou have been selected to change teams to promote balance. You have one minute to REJECT this change by sending the message 'reject' to ^bALL ^cchat."
        for player in self.switchlist:
            index += 1
            kwargs['Broadcast'].broadcast("SendMessage %s %s" %
                                          (player['clinum'], playermessage))

        if (index == 0):
            kwargs['Broadcast'].broadcast(
                "Serverchat ^cTeams are currently unbalanced. ^r%s ^chas been selected to improve balance. They will automatically switch teams in one minute unless they reject the move by sending the message 'reject' to ^bALL ^cchat, or another player joins."
                % (self.switchlist[0]['name']))
        else:
            kwargs['Broadcast'].broadcast(
                "Serverchat ^cTeams are currently unbalanced. ^r%s ^cand ^r%s ^chave been selected to improve balance. They will automatically switch teams in one minute unless one of them rejects the move by sending the message 'reject' to ^bALL ^cchat, or another player joins."
                % (self.switchlist[0]['name'], self.switchlist[1]['name']))

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

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

        client = self.getPlayerByName(name)

        if (args[0] == "SQUAD") and (message == 'report balance'):
            self.getGameInfo()
            kwargs['Broadcast'].broadcast(
                "SendMessage %s Balance Report: ^yTeam 1 combined: ^g%s (%s players, %s BF average), ^yTeam 2 combined: ^g%s (%s players, %s BF average). ^yStack percentage: ^r%s. ^yCurrent Phase: ^c%s. ^yCurrent time stamp: ^c%s. ^yBalancer active = ^r%s"
                % (client['clinum'], self.teamOne['combinedBF'],
                   self.teamOne['size'], self.teamOne['avgBF'],
                   self.teamTwo['combinedBF'], self.teamTwo['size'],
                   self.teamTwo['avgBF'], round(self.evaluateBalance(), 1),
                   self.PHASE, self.TIME, self.GAMESTARTED))
            for moves in self.balancereport:
                kwargs['Broadcast'].broadcast(
                    "SendMessage %s BALANCER: Balanced move for: %s at time %s"
                    % (client['clinum'], moves['name'], moves['time']))

        if (args[0] == "SQUAD") and (message == 'report team one'):

            for player in self.teamOne['players']:
                kwargs['Broadcast'].broadcast(
                    "SendMessage %s Team One Report: Player: ^c%s ^rBF: ^y%s" %
                    (client['clinum'], player['name'], player['bf']))

        if (args[0] == "SQUAD") and (message == 'report team two'):

            for player in self.teamTwo['players']:
                kwargs['Broadcast'].broadcast(
                    "SendMessage %s Team Two Report: Player: ^c%s ^rBF: ^y%s" %
                    (client['clinum'], player['name'], player['bf']))

        if (args[0] == "SQUAD") and (message == 'report playerlist'):

            for active in self.playerlist:
                if (active['active'] == 1):
                    kwargs['Broadcast'].broadcast(
                        "SendMessage %s Active Player List: Player: ^c%s ^rSF: ^y%s"
                        % (client['clinum'], active['name'], active['sf']))
        if (args[0] == "SQUAD") and (message == 'report version'):

            kwargs['Broadcast'].broadcast(
                "SendMessage %s Balancer version: ^y%s" %
                (client['clinum'], self.VERSION))

        if args[0] != "ALL":
            return

        if re.match(".*tell\s+(?:me\s+)?(?:the\s+)?(?:SFs?|balance)(?:\W.*)?$",
                    message,
                    flags=re.IGNORECASE):
            tm = time.time()
            if (tm - self.CHAT_STAMP) < self.CHAT_INTERVAL:
                return
            self.CHAT_STAMP = tm
            return self.sendGameInfo(**kwargs)

        if (self.OPTION == 1) and (message == 'reject'):
            for player in self.switchlist:
                if (player['name'] == name):
                    kwargs['Broadcast'].broadcast(
                        "ServerChat ^r%s ^chas rejected a move to promote balance between the teams."
                        % (name))
                    del self.switchlist[:]

    def optionCheck(self, **kwargs):
        if (self.OPTION == 1):
            for player in self.switchlist:
                action = 'MOVE'
                self.retrieveIndex(player, action, **kwargs)
        del self.switchlist[:]

    def move(self, clinum, index, **kwargs):

        client = self.getPlayerByClientNum(clinum)

        client['moved'] = 1
        name = client['name']
        #only have to move players that are already on a team, and since they can only go to the other team we can use this
        if (int(client['team']) == 1):
            newteam = 2
        else:
            newteam = 1

        kwargs['Broadcast'].broadcast("SetTeam %s %s" % (index, newteam))
        kwargs['Broadcast'].broadcast(
            "Serverchat ^r%s ^chas switched teams to promote balance." %
            (name))
        kwargs['Broadcast'].broadcast("ResetAttributes %s" % (index))

        self.balancereport.append({'time': self.TIME, 'client': name})

        self.moveNotify(clinum, **kwargs)

    def prevent(self, clinum, index, **kwargs):
        client = self.getPlayerByClientNum(clinum)
        client['prevent'] = 1
        newteam = 0
        kwargs['Broadcast'].broadcast("SetTeam %s %s" % (index, newteam))

        self.preventNotify(clinum, **kwargs)

    def allow(self, clinum, index, **kwargs):
        client = self.getPlayerByClientNum(clinum)
        team = client['team']
        kwargs['Broadcast'].broadcast("SetTeam %s %s" % (index, team))
        client['prevent'] = 0

    def level(self, clinum, index, **kwargs):
        client = self.getPlayerByClientNum(clinum)
        team = client['team']
        kwargs['Broadcast'].broadcast(
            "set _plevel #GetLevel(%s)#; set team%s_level [team%s_level + _plevel]"
            % (index, team, team))

    def moveNotify(self, clinum, **kwargs):
        #this lets the player know the have been moved and compensates them for their purchased items. There is current no way to know
        #how much gold a player holds, though I think gold may actually transfer. Not 100% sure.
        client = self.getPlayerByClientNum(clinum)

        value = client['value']

        kwargs['Broadcast'].broadcast(
            "SendMessage %s ^cYou have automatically switched teams to promote balance."
            % (clinum))
        kwargs['Broadcast'].broadcast(
            "SendMessage %s ^cYou have been compensated ^g%s ^cgold for your non-consumable items and your attributes have been reset."
            % (clinum, value))
        kwargs['Broadcast'].broadcast("GiveGold %s %s" % (clinum, value))

        client['value'] = 0

    def preventNotify(self, clinum, **kwargs):
        kwargs['Broadcast'].broadcast(
            "SendMessage %s ^cYou cannot join that team as it will create imbalance. Please wait for another player to join or leave."
            % (clinum))

    def getSmallTeam(self):
        #writing these all out explicitly because I was having trouble with them
        if (self.teamOne['size'] < self.teamTwo['size']):
            return self.teamOne
        if (self.teamTwo['size'] < self.teamOne['size']):
            return self.teamTwo
        if (self.teamTwo['size'] == self.teamOne['size']):
            return self.teamTwo

    def getLargeTeam(self):
        #writing these all out explicitly because I was having trouble with them
        if (self.teamOne['size'] > self.teamTwo['size']):
            return self.teamOne
        if (self.teamTwo['size'] > self.teamOne['size']):
            return self.teamTwo
        if (self.teamTwo['size'] == self.teamOne['size']):
            return self.teamOne

    def getHighTeam(self):
        if (self.teamOne['avgBF'] > self.teamTwo['avgBF']):
            return self.teamOne
        return self.teamTwo

    def getLowTeam(self):
        if (self.teamOne['avgBF'] > self.teamTwo['avgBF']):
            return self.teamTwo
        return self.teamOne

    def getTeamOne(self):
        return self.teamOne

    def getTeamTwo(self):
        return self.teamTwo

    def getTeamAvg(self, team):
        #this updates the info for a team

        team['combinedBF'] = 0
        team['size'] = 0
        for clients in team['players']:
            team['combinedBF'] += clients['bf']
            team['size'] += 1
        if (team['size'] > 0):
            team['avgBF'] = (team['combinedBF'] / team['size'])
        else:
            team['avgBF'] = 0

    def getGameInfo(self, **kwargs):

        self.getTeamAvg(self.teamOne)
        self.getTeamAvg(self.teamTwo)
        self.game['size'] = (self.teamOne['size'] + self.teamTwo['size'])
        self.game['avgBF'] = ((self.teamOne['avgBF'] + self.teamTwo['avgBF']) /
                              2)

    def sendGameInfo(self, **kwargs):
        self.getGameInfo(**kwargs)

        if (self.GAMESTARTED == 1):
            self.DIFFERENCE = abs(self.evaluateBalance())

        if self.GAMESTARTED == 1:
            kwargs['Broadcast'].broadcast(
                "ServerChat ^cCurrent balance: ^yTeam 1 Avg. BF: ^g%s (%s players), ^yTeam 2 Avg. BF: ^g%s (%s players). Stack percentage: ^r%s"
                % (self.teamOne['avgBF'], self.teamOne['size'],
                   self.teamTwo['avgBF'], self.teamTwo['size'],
                   round(self.DIFFERENCE, 1)))

    def EvenTeamBalancer(self, **kwargs):
        self.getGameInfo(**kwargs)
        #added these to prevent any moves if there is an error in BF calculation that has sprung up on occasion
        for clients in self.teamOne['players']:
            if clients['bf'] > 1000:
                kwargs['Broadcast'].broadcast("echo refresh")
                return
        for clients in self.teamTwo['players']:
            if clients['bf'] > 1000:
                kwargs['Broadcast'].broadcast("echo refresh")
                return

        self.DIFFERENCE = abs(self.evaluateBalance())
        print(self.DIFFERENCE)

        if (self.DIFFERENCE > self.THRESHOLD):
            self.getClosestTwoToTarget(self.getLargeTeam(),
                                       self.getSmallTeam(), **kwargs)
        else:

            kwargs['Broadcast'].broadcast(
                "Serverchat ^cEven team balancer initiated but current balance percentage of ^y%s ^cdoes not meet the threshold of ^y%s"
                % (round(self.DIFFERENCE, 1), self.THRESHOLD))

    def UnEvenTeamBalancer(self, **kwargs):
        self.getGameInfo(**kwargs)
        #added these to prevent any moves if there is an error in BF calculation that has sprung up on occasion
        for clients in self.teamOne['players']:
            if clients['bf'] > 1000:
                kwargs['Broadcast'].broadcast("echo refresh")
                return
        for clients in self.teamTwo['players']:
            if clients['bf'] > 1000:
                kwargs['Broadcast'].broadcast("echo refresh")
                return

        overcheck = self.evaluateBalance()
        self.DIFFERENCE = abs(self.evaluateBalance())
        #In this scenario, the larger team has a much lower BF, so do a player swap instead of a single move.
        if (overcheck < 0) and (self.DIFFERENCE > self.THRESHOLD):
            self.getClosestTwoToTarget(self.getLargeTeam(),
                                       self.getSmallTeam(), **kwargs)
            kwargs['Broadcast'].broadcast(
                "echo BALANCER: ^cUneven team balancer with swap initiated")
            return
        #In this scenario, the larger team has greater BF, so do a single mvoe.
        if (overcheck > 0) and (self.DIFFERENCE > self.THRESHOLD):
            self.getClosestPersonToTarget(self.getLargeTeam(), **kwargs)
        else:
            print 'threshold not met'
            kwargs['Broadcast'].broadcast(
                "Serverchat ^cUneven team balancer initiated, but current balance percentage of ^y%s ^cdoes not meet the threshold of ^y%s"
                % (round(self.DIFFERENCE, 1), self.THRESHOLD))

    def onTeamCheck(self, *args, **kwargs):
        if (self.TIME % (60 * 1000)) == 0:
            self.sendGameInfo(**kwargs)

        if (self.teamOne['size'] == int(args[0])) and (self.teamTwo['size']
                                                       == int(args[1])):
            kwargs['Broadcast'].broadcast(
                "echo BALANCER: Team 1 count is correct")
            kwargs['Broadcast'].broadcast(
                "echo BALANCER: Team 2 count is correct")

            if (self.PHASE == 5):

                self.GAMESTARTED = 1

                if (self.TIME == (1 * 60 * 1000)):
                    self.runBalancer(**kwargs)
                elif (self.TIME == (3 * 60 * 1000)):
                    self.runBalancer(**kwargs)
                elif (self.TIME == (6 * 60 * 1000)):
                    self.runBalancer(**kwargs)
                if (self.TIME >= (6 * 60 * 1000)):
                    self.DENY = 1
                    self.optionCheck(**kwargs)
                    self.OPTION = 1

                    if (self.TIME % (5 * 60 * 1000)) == 0:
                        self.runBalancer(**kwargs)
            return
        else:
            #kwargs['Broadcast'].broadcast("Serverchat ^cBalancer is currently off until player counts can be verified.")
            kwargs['Broadcast'].broadcast("ListClients")
            kwargs['Broadcast'].broadcast("echo refresh")
            #this initiates turns balancer off and tries to refresh the teams to get the proper count
            self.GAMESTARTED = 0
            self.DENY = 0

    def retrieveLevels(self, cli, **kwargs):

        kwargs['Broadcast'].broadcast(
            "set _index #GetIndexFromClientNum(%s)#; set _plevel #GetLevel(|#_index|#)#;echo CLIENT %s is LEVEL #_plevel#; set _plevel 1"
            % (cli, cli))

    def getTeamLevels(self, **kwargs):

        if (self.GAMESTARTED == 1):

            for player1 in self.teamOne['players']:
                self.retrieveLevels(player1['clinum'], **kwargs)
            for player2 in self.teamTwo['players']:
                self.retrieveLevels(player2['clinum'], **kwargs)

    def onGetLevels(self, *args, **kwargs):
        clinum = args[0]
        level = int(args[1])
        client = self.getPlayerByClientNum(clinum)
        client['gamelevel'] = level
        client['bf'] = client['sf'] + client['level'] + (4 * level)
        if (client['team'] == 1):
            for player in self.teamOne['players']:
                if client['clinum'] == player['clinum']:
                    player['bf'] = client['bf']
        if (client['team'] == 2):
            for player in self.teamTwo['players']:
                if client['clinum'] == player['clinum']:
                    player['bf'] = client['bf']

    def onListClients(self, *args, **kwargs):
        clinum = args[0]
        name = args[2]
        print 'making client active'
        client = self.getPlayerByName(name)
        client['active'] = 1

    def onMapReset(self, *args, **kwargs):
        if (self.PHASE == 5):
            kwargs['Broadcast'].broadcast("prevphase")
            self.GAMESTARTED = 0
        else:
            return

    def startFollow(self, **kwargs):

        for followings in self.followlist:
            kwargs['Broadcast'].broadcast(
                "set _follower #GetIndexFromClientNum(%s)#; set _followed #GetIndexFromClientNum(%s)#; set _x #GetPosX(|#_followed|#)#; set _y #GetPosY(|#_followed|#)#; set _z #GetPosZ(|#_followed|#)#; SetPosition #_follower# [_x + 200] [_y + 200] [_z + 200]"
                % (followings['follower'], followings['followed']))
Exemplo n.º 29
0
class training(ConsolePlugin):

	ms = None
	playerlist = []
	unallowedlist = []

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

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		#for (name, value) in config.items('balancer'):
		#	if (name == "level"):
		#		self._level = int(value)

		#	if (name == "sf"):
		#		self._sf = int(value)
		
		pass

	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		print ('Current phase: %d' % (phase))
		if (phase == 5):
			self.onGameStart(*args, **kwargs)
			
	
	def onGameStart(self, *args, **kwargs):

		self.RegisterScripts(**kwargs)
		self.unallowedunits(**kwargs)

	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'].put("RegisterGlobalScript -1 \"echo changing team....;MakeOfficer #GetScriptParam(clientid)#;  ChangeUnit #GetScriptParam(index)# Player_Savage true false false false false false false; ForceSpawn #GetScriptParam(changedindex)#;echo\" changeteam")
		kwargs['Broadcast'].put("set sv_squadsize 1")
		kwargs['Broadcast'].put("set _team 0")
		kwargs['Broadcast'].put("RegisterGlobalScript -1 \"CreateVar int _player_#GetScriptParam(clientid)#_duel -1;Set _maxteams #GetMaxTeams()#;Set _curclients #GetNumClients()#;if [_maxteams <= _curclients + 1] SetMaxTeams [_maxteams + 1];Set _maxteams #GetMaxTeams()#;Set _team [_team + 1];echo #_team#;Set _player_joining 1;SetTeam #GetScriptParam(index)# #_team#;MakeOfficer #GetScriptParam(clientid)#;ChangeUnit #GetScriptParam(index)# Player_Savage true false false false false false false;ForceSpawn #GetScriptParam(changedindex)#;Set _playerteam #GetTeam(|#GetScriptParam(changedindex)|#)#;Set _loop 1;Set _max #GetMaxTeams()#;ExecScript ally1;Set _player_joining 0;GiveExperience #GetScriptParam(index)# 1073741824;ResetAttributes #GetScriptParam(index)#;Set _message \\\"This is a duel arena that allows players to join the same team. By joining the same team you can use VOIP to communicate and help newer players. This also allows players to have team duels!\\\";Set _image /ui/commander/attack_down.tga;Set _header Welcome to the duel arena!;ClientExecScript #GetScriptParam(clientid)# Welcome header #_header# content #_message# texture #_image#;ClientExecScript #GetScriptParam(clientid)# SetupMusic; echo\" playerjoin")
		kwargs['Broadcast'].put("RegisterGlobalScript -1 \"if [_loop != _playerteam] AddAlliedTeam #_playerteam# #_loop#';if [_loop != _playerteam] AddAlliedTeam #_loop# #_playerteam#;Set _loop [_loop + 1];if [_loop < _max] ExecScript ally2; echo\" ally1")
		kwargs['Broadcast'].put("RegisterGlobalScript -1 \"if [_loop != _playerteam] AddAlliedTeam #_playerteam# #_loop#';if [_loop != _playerteam] AddAlliedTeam #_loop# #_playerteam#;Set _loop [_loop + 1];if [_loop < _max] ExecScript ally1; echo\" ally2")
		kwargs['Broadcast'].broadcast()
	
	def onServerStatus(self, *args, **kwargs):
		
		kwargs['Broadcast'].put("SendMessage -1 \"^cThis server allows training of players. Send the message: ^ytrain <playername> ^cto ^bALL^c chat to begin training. This will allow you to use in-game VOIP to communicate. End training by sending the message: ^yend training\"")
		kwargs['Broadcast'].broadcast()

	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'] == name):
				return client

	def onConnect(self, *args, **kwargs):
		
		id = args[0]
		self.playerlist.append({
			'clinum' : id,
			'acctid' : 0,
			'level'  : 0,
			'sf' : 0,
			'lf' : 0,
			'name' : 'X',
			'team' : 0,
			'oldteam' : 0,
			'trainee' : -1,
			'unit' : 'Player_Savage'
		})

	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		index = self.getPlayerIndex(cli)
		#index = self.playerlist.index(clinum[cli])
		print index
		del self.playerlist[index]
		print self.playerlist

	def getPlayerIndex (self, cli):
		
		indice = -1
		for player in self.playerlist:
			indice += 1
							
			if (player['clinum'] == cli):
				return indice	

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

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

		client = self.getPlayerByClientNum(cli)

		client['name'] = playername
		
	def onUnitChange(self, *args, **kwargs):
		cli = args[0]
		unit = args[1]

		client = self.getPlayerByClientNum(cli)
		if unit in self.unallowedlist:
			kwargs['Broadcast'].broadcast("set _value #GetIndexFromClientNum(%s)#; ChangeUnit #_value# %s true false false false false false false; SendMessage %s ^cYou can't select that unit. Sorry!" % (cli, client['unit'], cli))
			return
		client['unit'] = unit

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

		self.unallowedlist = [
			'Player_Malphas',
			'Player_Maliken',
			'Player_Behemoth',
			'Player_Steambuchet',
			'Player_BatteringRam',
			'Player_Devourer',
			'Player_Tempest'
		]

	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 ['acctid'] = int(id)
		client ['level'] = level
		client ['sf'] = sf
		
	def onTeamChange (self, *args, **kwargs):
		team = int(args[1])
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client['team'] = team	
		print self.playerlist

	def onMessage(self, *args, **kwargs):
		# process only ALL chat messages
		if args[0] != "ALL":
			return

		name = args[1]
		(func, arg) = args[2].split(None, 1)
		# only single person training is supported right now
		arg = arg.split(None, 1)

		if   func == "train" and arg:
			self.trainingStart(name, arg, **kwargs)
		elif func == "end" and arg == "training":
			return self.trainingEnd(name, **kwargs)

	def trainingStart(self, name, trainee, **kwargs):
		trainer = self.getPlayerByName(name)

		if (int(trainer['trainee']) > -1):
			kwargs['Broadcast'].broadcast("SendMessage %s You are currently in a training session. End that session first." % (trainer['clinum']))
			return

		if (player['name'].lower() == trainee.lower()):
			toteam = player['team']
			trainer['oldteam'] = trainer['team']
			trainer['team'] = toteam
			trainer['trainee'] = player['clinum']

			kwargs['Broadcast'].broadcast("set _value #GetIndexFromClientNum(%s)#; set X #GetPosX(|#_value|#)#; set Y #GetPosY(|#_value|#)#; set Z #GetPosZ(|#_value|#)#; echo CLIENT %s POSITION #X# #Y# #Z#" % (trainer['clinum'], trainer['clinum']))
			client = self.getPlayerByClientNum(trainer['clinum'])
			kwargs['Broadcast'].broadcast("set _value #GetIndexFromClientNum(%s)#; SetTeam #_value# %s; SendMessage %s You are now in a training session with %s; ChangeUnit #GetIndexFromClientNum(%s)# %s; SetPosition #_value# #X# #Y# #Z#" % (client['clinum'], toteam, client['clinum'], trainee, client['clinum'], client['unit']))

	def trainingEnd(self, name, **kwargs):
		trainer = self.getPlayerByName(name)
		if (int(trainer['trainee']) == -1):
			return
		kwargs['Broadcast'].broadcast("set _value #GetIndexFromClientNum(%s)#; SetTeam #_value# %s; SendMessage %s ^cYou have ended your training session.; SendMessage %s ^r%s ^chas ended their training session with you." % (trainer['clinum'], trainer['oldteam'], trainer['clinum'], trainer['trainee'], trainer['name']))
		trainer['team'] = trainer['oldteam']
		trainer['trainee'] = -1
Exemplo n.º 30
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']))
Exemplo n.º 31
0
class tournament(ConsolePlugin):
	VERSION = "1.0.2"
	STARTED = 0
	MINIMUM =  2
	RECRUIT = False
	ORGANIZER = -1
	DUELROUND = 0
	TOURNEYROUND = 0
	MISSING = -1
	DOUBLEELIM = False
	CANCEL = False
	CURRENT = 1
	lastwinner = -1
	lastloser = -1
	playerlist = []
	tourneylist = {'totalplayers' : 0, 'players' : []}
	tourneystats = {'entries' : 0, 'avgSF' : 0, 'winner' : {}, 'runnerup' : {}}
	seededlist = []
	activeduel = []
	statueangle = []
	statuelist = []
	unitlist = []
	adminlist = []
	blockerlist = []
	OFFICIAL = False
	STATUE = 1
	SVRDESC = False
	svr_desc = "^yTourney - Last Winner: ^r"
	SVRNAME = False
	svr_name = "^yTourney - Last Winner: ^r"

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

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for (name, value) in ini.items('admin'):
			self.adminlist.append(name)
		#Don't know how to get boolean values for things in a specific section of .ini
		for (name, value) in ini.items('var'):
			if (name == "changesvrname") and (value == "true"):
				self.SVRNAME = True
			if (name == "changesvrdesc") and (value == "true"):
				self.SVRDESC = True
			if (name == "svrname"):
				self.svrname = value
			if (name == "changesvrname"):
				self.svrdesc = value
			if (name == "double") and (value == "true"):
				self.DOUBLEELIM = True

		
	def onStartServer(self, *args, **kwargs):
		print 'SERVER RESTARTED'
		self.statuelist = []
		self.STARTED = 0
		self.MINIMUM =  2
		self.RECRUIT = False
		self.ORGANIZER = -1
		self.DUELROUND = 0
		self.TOURNEYROUND = 0
		self.MISSING = -1
		self.playerlist = []
		self.tourneylist = {'totalplayers' : 0, 'players' : []}
		self.seededlist = []
		self.winnerlist = []
		self.loserlist = []
		self.activeduel = []
		self.unitlist = []
		self.counts = 4
		self.counter = 0
		f = open('winners.txt', 'r')
		self.statuelist = f.readlines()
		f.close()
			
		self.statueangle = ["0.0000 0.0000 161.7999",
				    "0.0000 0.0000 107.5998",
				    "0.0000 0.0000 53.1997",
				    "0.0000 0.0000 -22.6002",
				    "0.0000 0.0000 -63.0003",			    
				    "0.0000 0.0000 -109.2003"]

		self.blockerlist = [{'angles' : '0.0000 0.0000 -3.4000', 'name' : 'blocker1', 'position' : '7751.7021 8648.5215 -215.2963', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 38.6000', 'name' : 'blocker2', 'position' : '7112.2378 8417.8262 -148.7921', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 74.8001', 'name' : 'blocker3', 'position' : '6739.8462 8053.7290 -33.6641', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 105.200', 'name' : 'blocker4', 'position' : '6751.2056 7424.2529 20.8391', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 142.000', 'name' : 'blocker5', 'position' : '7105.5361 6935.4971 -244.8373', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 176.800', 'name' : 'blocker6', 'position' : '7682.2261 6741.1899 -246.9767', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 210.400', 'name' : 'blocker7', 'position' : '8237.4541 6833.5957 -14.6271', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 249.200', 'name' : 'blocker8', 'position' : '8587.6348 7221.5093 -58.0270 -215.2963', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 277.800', 'name' : 'blocker9', 'position' : '8664.1816 7800.2666 -182.6546', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 304.200', 'name' : 'blocker10', 'position' : '8420.5273 8446.7617 -6.7577', 'scale' : '33.4070'}]
		
		self.spawnStatues(**kwargs)
		self.doBlockers('on',**kwargs)

	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, 'sf' : 0, 'name' : 'X', 'index' : 0, 'active' : 0, 'register' : 0, 'loses' : 0})
	
	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client ['active'] = 0
		for each in self.activeduel:
			if each['clinum'] == cli:
				self.fightersPresent(**kwargs)

	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 ['acctid'] = int(id)
		client ['level'] = level
		client ['sf'] = sf
		client ['active'] = 1
		
		if (self.STARTED == 1) and (cli == self.MISSING):
			kwargs['Broadcast'].broadcast("set _MISSING -1")
			#self.nextDuelRound(**kwargs)
		kwargs['Broadcast'].broadcast("SendMessage %s ^cDuel Tournament made by ^yOld55 ^cand ^yPidgeoni" % (cli))
		
		if self.isAdmin(client, **kwargs):
			kwargs['Broadcast'].broadcast("SendMessage %s ^cYou are registered as an administrator for this tournament server. Send the chat message: ^rhelp ^cto see what commands you can perform." % (cli))
			
	def getPlayerIndex (self, cli):
		
		indice = -1
		for player in self.playlist:
			indice += 1
							
			if (player['clinum'] == cli):
				return indice
			
			

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

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

	def RegisterScripts(self, **kwargs):
		#any extra scripts that need to go in can be done here
		#default unit list
		self.unitlist = ['Player_Savage', \
				 'Player_ShapeShifter', \
				 'Player_Predator', \
				 'Player_Hunter', \
				 'Player_Marksman']
		
		kwargs['Broadcast'].broadcast("set _green #GetIndexFromName(green_spawn)#; \
						set _red #GetIndexFromName(red_spawn)#; \
						set _exit1 #GetIndexFromName(exit1)#; \
						set _exit2 #GetIndexFromName(exit2)#; \
						set _p1x #GetPosX(|#_green|#)#; \
						set _p1y #GetPosY(|#_green|#)#; \
						set _p1z #GetPosZ(|#_green|#)#; \
						set _p2x #GetPosX(|#_red|#)#; \
						set _p2y #GetPosY(|#_red|#)#; \
						set _p2z #GetPosZ(|#_red|#)#; \
						set _e1x #GetPosX(|#_exit1|#)#; \
						set _e1y #GetPosY(|#_exit1|#)#; \
						set e1z #GetPosZ(|#_exit1|#)#; \
						set _e2x #GetPosX(|#_exit2|#)#; \
						set _e2y #GetPosY(|#_exit2|#)#; \
						set _e2z #GetPosZ(|#_exit2|#)#; \
						set _MISSING -1")		
	
		
	def isAdmin(self, client, **kwargs):
		admin = False
		
		for each in self.adminlist:
			if client['name'].lower() == each:
				admin = True
		
		return admin

	def adminCommands (self, message, client, **kwargs):
		start = re.match("start", message, flags=re.IGNORECASE)
		official = re.match("toggle official", message, flags=re.IGNORECASE)
		redo = re.match("redo", message, flags=re.IGNORECASE)
		next = re.match("next", message, flags=re.IGNORECASE)
		elim = re.match("double", message, flags=re.IGNORECASE)
		fail = re.match("remove (\S+)", message, flags=re.IGNORECASE)
		kick = re.match("kick (\S+)", message, flags=re.IGNORECASE)
		help = re.match("help", message, flags=re.IGNORECASE)
		blocker = re.match("blocker (\S+)", message, flags=re.IGNORECASE)
		cancel = re.match("cancel", message, flags=re.IGNORECASE)
		#lets admin register people, even if not official tournament
		register = re.match("register (\S+)", message, flags=re.IGNORECASE)
		
		if start:
			self.start (client, **kwargs)

		if official:
			self.toggleOfficial (client, **kwargs)
		
		if redo:
			self.redoDuel (**kwargs)

		if next:
			self.endDuel (**kwargs)
			
		if register:
			client = self.getPlayerByName(register.group(1))
			self.register (client, **kwargs)
			
		if fail:
			killer = -1
			killed = -1

			client = self.getPlayerByName(fail.group(1))
			for each in self.activeduel:
				if each['clinum'] == client['clinum']:
					killed = each['clinum']
					each['loses'] = 3
					continue
				if each['clinum'] != client['clinum']:
				 	killer = each['clinum']
			
			if killer > -1 and killed > -1:
				self.onDeath(killer, killed, **kwargs)
				kwargs['Broadcast'].broadcast("SendMessage %s ^yAn administrator has removed you from the tournament" % (killed))

		if kick:
			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 blocker:
		
			self.doBlockers(blocker.group(1), **kwargs)

		if elim:
			if self.STARTED == 1:
				kwargs['Broadcast'].broadcast("SendMessage %s A tournament has already started" % (client['clinum']))
				return
			self.toggleDouble (client, **kwargs)

		if cancel:
			self.CANCEL = True
			self.endTourney(**kwargs)
			kwargs['Broadcast'].broadcast(\
						"Serverchat The tournament has been ended by an administrator")

		if help:
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s All commands on the server are done through server chat. The following are commands and a short description of what they do." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s As an admin you must ALWAYS register yourself by sending the message: ^rregister yourname" % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rtoggle official ^wsets the tournament between official and unofficial status.\
			 Admins MUST register people for official tournaments. Only admins can start tournaments in official mode." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rregister playername ^wwill register a player for the tournament. Must be used in official mode but also works in unofficial." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rblocker on/off ^wwill turn range blockers on/off around the arena." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rredo ^wwill force the players fighting in the arena to redo the last match. ONLY use after players have respawned as the next unit." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rremove playername ^wwill force a player to lose the match. Currently only works \
			when the player is on the server. If they have disconnected, it is best to just let them timeout." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rcancel ^wwill cancel the current tournament." % (client['clinum']))

	def onMessage(self, *args, **kwargs):
		
		name = args[1]
		message = args[2]
		
		client = self.getPlayerByName(name)
		admin = self.isAdmin(client, **kwargs)
		
		#pass to admincommands
		if admin:
			self.adminCommands(message, client, **kwargs)

		#only admins are allowed to start/add/redo/etc. if the tournament is official
		if self.OFFICIAL:
			return

		roundunit = re.match("Round (\S+) Unit (\S+)", message, flags=re.IGNORECASE)
		register = re.match("register", message, flags=re.IGNORECASE)
		


		if register:
			self.register (client, **kwargs)

		if roundunit:
			if client['clinum'] != self.ORGANIZER:
				return
			duelround = int(roundunit.group(1))
			unit = (roundunit.group(2))
			print duelround, unit
			self.unitlist[duelround-1] = ("Player_%s" % (unit))

	def doBlockers (self, toggle, **kwargs):

		if toggle == 'on':
			for each in self.blockerlist:
				kwargs['Broadcast'].broadcast(\
				"SpawnEntity Prop_Scenery model \"/world/props/tools/blocker_range.mdf\" position \"%s\" name \"%s\" angles \"%s\" scale \"%s\"" \
				% (each['position'], each['name'], each['angles'], each['scale']))

		if toggle == "off":
			for each in self.blockerlist:
				kwargs['Broadcast'].broadcast("RemoveEntity #GetIndexFromName(%s)#" % (each['name']))

		return

	def toggleOfficial (self, client, **kwargs):	
		
		if self.OFFICIAL:
			self.OFFICIAL = False
		else:
			self.OFFICIAL = True

		kwargs['Broadcast'].broadcast("SendMessage %s ^rOfficial Status: %s" % (client['clinum'], self.OFFICIAL))

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

		if self.DOUBLEELIM:
			self.OFFICIAL = False
		else:
			self.DOUBLEELIM = True

		kwargs['Broadcast'].broadcast("SendMessage %s ^rDouble Elimination Status: %s" % (client['clinum'], self.DOUBLEELIM))

	def redoDuel (self, **kwargs):	

		self.DUELROUND -= 1
		
		for each in self.activeduel:
			if (each['clinum'] == self.lastloser):
				each['loses'] -= 1
									
			if (each['clinum'] == self.lastwinner):
				each['wins'] -= 1
				kwargs['Broadcast'].broadcast("ExecScript GlobalSet var R%sS%s val %s" % (each['bracket'], each['column'], each['wins']))
				kwargs['Broadcast'].broadcast("ExecScript GlobalSync")
		
		kwargs['Broadcast'].broadcast("set _DUELER1 -1; set _DUELER2 -1")
		self.nextDuelRound(**kwargs)

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

		admin = self.isAdmin(client, **kwargs)
				
		if self.RECRUIT or self.STARTED == 1:
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rA tournament has already been started. You must wait till the current tournament ends to start a new one." % (client['clinum']))
			return

		activeplayers = 0
		for player in self.playerlist:
			if player['active'] == 1:
				activeplayers += 1

		if (activeplayers < self.MINIMUM):
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rA minimum of two active players is required to call a tournament" % (client['clinum']))		
			return
		
		self.RegisterScripts(**kwargs)	
		self.RECRUIT = True
		kwargs['Broadcast'].broadcast(\
		"ServerChat ^r%s ^chas started a tournament! To join the tournament, send the message 'register' to ALL, SQUAD, or TEAM chat.; \
		 ExecScript starttourney; \
		 ExecScript GlobalSet var TSB val %s; \
		 ExecScript GlobalShowDuel" \
		 % (client['name'], client['name']))

		self.ORGANIZER = client['clinum']
		kwargs['Broadcast'].broadcast("ClientExecScript %s ClientShowOptions" % (self.ORGANIZER))
	

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

		kwargs['Broadcast'].broadcast("TakeItem #GetIndexFromClientNum(%s)# 10" % (client ['clinum']))

		if self.RECRUIT and client['register'] == 0:
			self.tourneylist ['players'].append ({'clinum' : client['clinum'],
							      'acctid' : client['acctid'],
							      'name' : client['name'],
							      'sf' : client['sf'],
							      'level' : client['level'],
							      'totalwins' : 0,
							      'totalloses' : 0,
							      'seed' : 0,
							      'advance' : 2,
							      'bye' : 0,
							      'bracket' : 0})	
			client['register'] = 1
			self.tourneylist ['totalplayers'] += 1
			kwargs['Broadcast'].broadcast(\
			"Serverchat ^r%s ^chas registered for the tournament." % (client ['name']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^yYou have successfully registered for the tournament." % (client ['clinum']))
			
		else:

			return

	def RegisterStart(self, **kwargs):

		self.RECRUIT = False
		self.STARTED = 1
		self.seedPlayers(**kwargs)
	
	def getTourneyinfo(self, **kwargs):

		entries = self.seededlist['totalplayers']
		self.tourneystats['entries'] = entries
		totalsf = 0

		for each in self.seededlist['players']:
			totalsf += each['sf']

		self.tourneystats['avgSF'] = int(totalsf/entries)


	def seedPlayers(self, **kwargs):
		
		self.TOURNEYROUND = 1
		kwargs['Broadcast'].broadcast(\
		"ExecScript GlobalSet var TR val 1")
		kwargs['Broadcast'].broadcast(\
		"ClientExecScript %s ClientHideOptions" % (self.ORGANIZER))
		if (self.tourneylist ['totalplayers'] < 4):
			self.tourneylist = {'totalplayers' : 0, 'players' : []}
			self.seededlist = []
			self.STARTED = 0
			self.ORGANIZER = -1
			self.RECRUIT = False
			for each in self.playerlist:
				each['register'] = 0
		
			kwargs['Broadcast'].broadcast(\
			"ClientExecScript -1 ClientClear")
			kwargs['Broadcast'].broadcast(\
			"Serverchat The tournament must have 4 people to start. Aborting.")
			
			return

		self.seededlist = sorted(self.tourneylist ['players'], key=itemgetter('sf', 'level', 'clinum'), reverse=True)
		seed = 0

		#Gets information about tournament for scoring purposes
		#self.getTourneyinfo()

		for player in self.seededlist:
			seed += 1
			player['seed'] += seed

		totalplayers = self.tourneylist['totalplayers']
		start = 0
		end = totalplayers - 1

		#round 1 seeding/bracket placement
		if (self.tourneylist['totalplayers'] % (2)) == 0:
	
			total_brackets = (totalplayers / 2)
			bracket = 1

			while (start < total_brackets):
				self.seededlist[start]['bracket'] = bracket
				self.seededlist[end]['bracket'] = bracket
				kwargs['Broadcast'].broadcast(\
				"ExecScript GlobalSet var R%sNA val %s;\
				 ExecScript GlobalSet var R%sFA val %s;\
				 ExecScript GlobalSet var R%sNB val %s;\
				 ExecScript GlobalSet var R%sFB val %s;"\
				 % (bracket, self.seededlist[start]['name'],bracket,self.seededlist[start]['sf'],bracket,self.seededlist[end]['name'],bracket,self.seededlist[end]['sf']))	
				start += 1
				end -= 1
				bracket += 1

		if (self.tourneylist['totalplayers'] % (2)) != 0:
			totalplayers = totalplayers+1 
			total_brackets = (totalplayers / 2)
			bracket = 1
			self.seededlist[start]['bye'] = 1
			self.seededlist[start]['bracket'] = bracket
			self.seededlist[start]['advance'] = 1
			self.winnerlist.append(self.seededlist[start])
			print self.winnerlist

			kwargs['Broadcast'].broadcast(\
			"ExecScript GlobalSet var R%sSA val 3;\
			 ExecScript GlobalSet var R%sNA val %s;\
			 ExecScript GlobalSet var R%sFA val %s;\
			 ExecScript GlobalSet var R%sNB val BYE"\
			 % (bracket,bracket,self.seededlist[start]['name'],bracket,self.seededlist[start]['sf'],bracket))
			start += 1
			bracket += 1

			while (start < total_brackets):
				self.seededlist[start]['bracket'] = bracket
				self.seededlist[end]['bracket'] = bracket
				kwargs['Broadcast'].broadcast(\
				"ExecScript GlobalSet var R%sNA val %s;\
				 ExecScript GlobalSet var R%sFA val %s; \
				 ExecScript GlobalSet var R%sNB val %s; \
				 ExecScript GlobalSet var R%sFB val %s;"\
				 % (bracket,self.seededlist[start]['name'],bracket,self.seededlist[start]['sf'],bracket,self.seededlist[end]['name'],bracket,self.seededlist[end]['sf']))
				bracket += 1
				start += 1
				end -= 1

		
		self.checkRound(**kwargs)
		

	def checkRound(self, **kwargs):
		#figure out who has yet to fight
		print 'at checkRound'
		bl = []
		for brackets in self.seededlist:
			bl.append(brackets['bracket'])
		print bl

		for item in set(bl):
			if (bl.count(item) > 1):
				print item
				self.nextDuel(item, **kwargs)
				return
			
		self.nextRound(**kwargs)
		print 'round over'
		self.TOURNEYROUND += 1

	def nextDuel(self, bracket, **kwargs):
		print bracket
		kwargs['Broadcast'].broadcast(\
		"ExecScript GlobalSet var CR val %s;\
		 ExecScript GlobalSync"\
		 % (bracket))

		for each in self.seededlist:
			if each['bracket'] == bracket:
				#added to kill each of the duelers before the start so they get out of their current duels
				kwargs['Broadcast'].broadcast(\
				"set _index #GetIndexFromClientNum(%s)#;\
				 KillEntity #_index#"\
				 % (each['clinum']))
				self.activeduel.append(each)

		for each in self.activeduel:
			each['loses'] = 0
			each['wins'] = 0

		self.activeduel[0]['column'] = "A"
		self.activeduel[1]['column'] = "B"
		
		self.getNextDuel(**kwargs)

	def getNextDuel(self, *args, **kwargs):
		self.nextDuelRound(**kwargs)

	def nextDuelRound(self, **kwargs):
		
		if self.fightersPresent(**kwargs):
			kwargs['Broadcast'].broadcast("set _DUEL 0")
			self.getUnit(**kwargs)
			kwargs['Broadcast'].broadcast(\
			"set _index #GetIndexFromClientNum(%s)#;\
			 GiveItem #_index# 9 Spell_CommanderHeal;\
			 StartEffectOnObject #_index# \"shared/effects/green_aura.effect\";\
			 ResetAttributes #_index#;\
			 SetPosition #_index# #_p1x# #_p1y# #_p1z#;\
			 ChangeUnit #_index# #_UNIT# true false false false false false false;\
			 ClientExecScript %s holdmove"\
			 % (self.activeduel[0]['clinum'],self.activeduel[0]['clinum']))

			kwargs['Broadcast'].broadcast(\
			"set _index #GetIndexFromClientNum(%s)#;\
			 GiveItem #_index# 9 Spell_CommanderHeal;\
			 StartEffectOnObject #_index# \"shared/effects/red_aura.effect\"; \
			 ResetAttributes #_index#; \
			 SetPosition #_index# #_p2x# #_p2y# #_p2z#;\
			 ChangeUnit #_index# #_UNIT# true false false false false false false;\
			 ClientExecScript %s holdmove"\
			 % (self.activeduel[1]['clinum'],self.activeduel[1]['clinum']))

			kwargs['Broadcast'].broadcast(\
			"ExecScript setdueler dueler1 %s dueler2 %s"\
			 % (self.activeduel[0]['clinum'], self.activeduel[1]['clinum']))

			kwargs['Broadcast'].broadcast(\
			"Execscript duelcountdown")	
		else:
			
			print 'player missing'

	def waitForPlayer(self, *args, **kwargs):
		action = args[0]

		if (action == 'Timeout'):
			for each in self.activeduel:
				if each['clinum'] == self.MISSING:
					each['loses'] = 3
					missing = each['clinum']
					self.MISSING = -1
				else:
					remaining = each['clinum']
			self.onDeath(remaining, missing,**kwargs)
					
		if (action == 'Connected'):
			#if (self.DUELROUND > 0):
				#self.DUELROUND -= 1
			self.MISSING = -1
			kwargs['Broadcast'].broadcast("set _DUELER1 -1; set _DUELER2 -1")
			self.nextDuelRound(**kwargs)					
			
	def getUnit(self, **kwargs):
		
		unit = self.unitlist[self.DUELROUND]
		kwargs['Broadcast'].broadcast("set _UNIT %s" % (unit))

	def fightersPresent(self, **kwargs):
		
		if self.MISSING > -1:
			return False
		
		for each in self.activeduel:
			clinum = each['clinum']
			for players in self.playerlist:
				if (players['clinum'] == clinum) and (players['active'] == 0):
					self.MISSING = players['clinum']
					name = players['name']
					kwargs['Broadcast'].broadcast(\
					"ServerChat ^cThe next duel is between ^r%s ^cand ^r%s^c, but ^r%s ^chas disconnected. They have 1 minute to reconnect or they will lose the round.;\
					 set _MISSING %s;\
					 ExecScript missingfighter"\
					 % (self.activeduel[0]['name'],self.activeduel[1]['name'], name, self.MISSING))
					return False
		return True

	def onDeath(self, *args, **kwargs):
		print 'got Death'
		#this will be called from a specific filter
		killer = args[0]
		killed = args[1]
		wasduel = 0
		print args
		if self.STARTED != 1 or self.MISSING > -1:
			return
		
		for each in self.activeduel:
			if (each['clinum'] == killed):
				wasduel += 1
				clikilled = each
			if (each['clinum'] == killer):
				wasduel += 1
				clikill = each

		if wasduel == 2:
			self.DUELROUND += 1
			self.lastloser = clikilled['clinum']
			clikilled['loses'] += 1
			kwargs['Broadcast'].broadcast(\
			"set _idx #GetIndexFromClientNum(%s)#;\
			 TakeItem #_idx# 9;\
			 set _DUELER1 -1;\
			 set _DUELER2 -1"\
			 % (clikilled['clinum']))

			self.lastwinner = clikill['clinum']
			clikill['wins'] += 1
			kwargs['Broadcast'].broadcast(\
			"ExecScript GlobalSet var R%sS%s val %s;\
			 ExecScript GlobalSync"\
			 % (clikill['bracket'], clikill['column'], clikill['wins']))
					
			for each in self.activeduel:		
				if each['loses'] > 2:
					self.checkendDuel(**kwargs)
					kwargs['Broadcast'].broadcast("ExecScript GlobalSync")
					return
	
			kwargs['Broadcast'].broadcast("ExecScript nextduelround")
		
	def checkendDuel(self, **kwargs):
		kwargs['Broadcast'].broadcast(\
		"set _index #GetIndexFromClientNum(%s)#;\
		 StopEffectOnObject #_index# \"shared/effects/green_aura.effect\";\
		 SetPosition #_index# #_e1x# #_e1y# #_e1z#;\
		 ChangeUnit #_index# Player_Savage  true false false false false false false"\
		 % (self.activeduel[0]['clinum']))

		kwargs['Broadcast'].broadcast(\
		"set _index #GetIndexFromClientNum(%s)#;\
		 StopEffectOnObject #_index# \"shared/effects/red_aura.effect\";\
		 SetPosition #_index# #_e2x# #_e2y# #_e2z#;\
		 ChangeUnit #_index# Player_Savage  true false false false false false false"\
		 % (self.activeduel[1]['clinum']))

		if not self.OFFICIAL:
			self.endDuel(**kwargs)
			return

		if self.OFFICIAL:
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s This duel is over. Please send message 'next' to chat for the next duel, or 'redo' if there was an error."\
			 % (self.ORGANIZER))			
			
	def endDuel(self, **kwargs):
	
		for each in self.activeduel:
				if each['loses'] > 2:
					loser = each['name']
					clinum = each['clinum']
					each['totalloses'] += 1
					self.loserlist.append(each)
					self.tourneystats['runnerup'] = { 'name' : each['name'], 'acctid' : each['acctid'] }
					self.removePlayer(each['clinum'])
				if each['loses'] < 3:
					winner = each['name']
					self.tourneystats['winner'] = { 'name' : each['name'], 'acctid' : each['acctid'] }
					each['totalwins'] += 1
					if each['totalloses'] == 0:
						self.winnerlist.append(each)
					if each['totalloses'] == 1:
						self.loserlist.append(each)
		kwargs['Broadcast'].broadcast(\
		"ServerChat ^y%s ^chas defeated ^y%s ^cand moves on to the next round"\
		 % (winner, loser))

		self.activeduel = []
		self.DUELROUND = 0
		
		self.checkRound(**kwargs)

	def swapList(self, winners, losers, **kwargs):
		
		#gets if we are currently in winners or losers bracket, 1 = winner 2 = losers
		
		#special condition, all remaining players are in losers bracket
		if winners == 0:
			print 'condition: no winners'
			self.CURRENT = 2
			self.seededlist = list(self.loserlist)
			del self.loserlist[:]
			return

		#special condition, all are in winners bracket
		if losers == 0:
			print 'condition: no losers'
			self.CURRENT = 1
			self.seededlist = list(self.winnerlist)
			del self.winnerlist[:]
			return

		#special condition, split brackets
		if losers == 1 and winners == 1:
			print 'condition: split lists'
			self.seededlist = [self.winnerlist[0], self.loserlist[0]]
			del self.loserlist[:]
			del self.winnerlist[:]
			return		

		if self.CURRENT == 1:
			if losers > 1:
				print 'condition: start loser bracket'
				self.CURRENT = 2
				self.seededlist = list(self.loserlist)
				self.loserlist = []
				return
			elif losers < 2:
				self.CURRENT = 1
				self.seededlist = list(self.winnerlist)
				self.winnerlist = []
				return
		if self.CURRENT == 2:
			if winners > 1:
				print 'condition: start winner bracket'
				self.CURRENT = 1
				self.seededlist = list(self.winnerlist)
				self.winnerlist = []
				return
			elif winners < 2:
				self.CURRENT = 2
				self.seededlist = list(self.loserlist)
				self.loserlist = []
				return
		
		print self.seededlist
				
	def nextRound(self, **kwargs):
		kwargs['Broadcast'].broadcast("ExecScript GlobalClear; ClientExecScript -1 releasemove")
		
		print 'made it to nextRound'
		remaining = 0
		self.TOURNEYROUND += 1
		kwargs['Broadcast'].broadcast("ExecScript GlobalSet var TR val %s" % (self.TOURNEYROUND))
		
					
		if self.DOUBLEELIM:
			
			winners = self.getRemaining(self.winnerlist, **kwargs)
			losers = self.getRemaining(self.loserlist, **kwargs)
			remaining = winners + losers
			if remaining == 1:
				self.endTourney(**kwargs)
				return
			print winners, losers
			self.swapList(winners, losers)

		remaining = self.getRemaining(self.seededlist, **kwargs)
		kwargs['Broadcast'].broadcast("echo Remaining players: %s" % (remaining))
		if (remaining == 1):
			self.endTourney(**kwargs)		
			return

		if (remaining % (2)) != 0:
			self.getBye(**kwargs)
		
		self.seededlist = sorted(self.seededlist, key=itemgetter('advance', 'bracket'))

		#re-seed the list if we are switching to the loser bracket
		if self.CURRENT == 2:
			self.seededlist = sorted(self.seededlist, key=itemgetter('advance', 'seed', 'bracket'))

		#now to do the re-bracketing
		start = 0
		end = remaining - 1
		doround = True
		bracket = 0

		if (self.seededlist[start]['advance'] == 1):
			bracket = 1
			byer = self.seededlist[start]
			byer['bracket'] = bracket
			if byer['totalloses'] == 1:
				self.loserlist.append(self.seededlist[start])
			if byer['totalloses'] == 0:
				self.winnerlist.append(self.seededlist[start])
			kwargs['Broadcast'].broadcast(\
			"ExecScript GlobalSet var R%sSA val 3;\
			 ExecScript GlobalSet var R%sNA val %s;\
			 ExecScript GlobalSet var R%sFA val %s;\
			 ExecScript GlobalSet var R%sNB val BYE"\
			 % (bracket,bracket,self.seededlist[start]['name'],bracket,self.seededlist[start]['sf'],bracket))
			self.seededlist[start]['column'] = 'A'
			start += 1
		
		
		while doround:
			bracket += 1	
			self.seededlist[start]['bracket'] = bracket
			self.seededlist[end]['bracket'] = bracket
			kwargs['Broadcast'].broadcast(\
			"ExecScript GlobalSet var R%sNA val %s;\
			 ExecScript GlobalSet var R%sFA val %s;\
			 ExecScript GlobalSet var R%sNB val %s;\
			 ExecScript GlobalSet var R%sFB val %s;"\
			 % (bracket,self.seededlist[start]['name'],bracket,self.seededlist[start]['sf'],bracket,self.seededlist[end]['name'],bracket,self.seededlist[end]['sf']))
			self.seededlist[start]['column'] = "A"
			self.seededlist[end]['column'] = "B"
			if (end - start) == 1:
				doround = False
			start += 1
			end -= 1

		print self.seededlist
		self.checkRound(**kwargs)

	def getRemaining(self, getlist, **kwargs):
		remaining = 0

		for each in getlist:
			each['advance'] = 2
			remaining += 1

		return remaining

	def endTourney(self, **kwargs):

		if not self.CANCEL:
			winner = self.seededlist[0]
			name = winner['name']
			clinum = winner['clinum']
			wins = winner['totalwins']

			kwargs['Broadcast'].broadcast(\
			"ServerChat ^cThis tournament is over! The winner is %s with a total of %s wins."\
			 % (name, wins))

			kwargs['Broadcast'].broadcast(\
			"set _winnerind #GetIndexFromClientNum(%s);\
			 ClientExecScript %s ClientHideOptions"\
			 % (clinum, self.ORGANIZER))

			if self.SVRDESC:
				kwargs['Broadcast'].broadcast(\
				"set svr_desc \"%s\"%s" % (self.svr_desc, name))
			if self.SVRNAME:
				kwargs['Broadcast'].broadcast(\
				"set svr_name \"%s\"%s"\
				 % (self.svr_name, name))
			#Adds a statue
			kwargs['Broadcast'].broadcast(\
			"RemoveEntity #GetIndexFromName(player_%s)#;\
			 SpawnEntityAtEntity statue_%s Prop_Dynamic name player_%s maxhealth 999999999 model \"/world/props/arena/stone_legionnaire.mdf\" angles \"%s\" team 0 seed 0 scale 1.7627 propname %s"\
			 % (self.STATUE,self.STATUE,self.STATUE,self.statueangle[self.STATUE-1],name))
			self.STATUE += 1
			if self.STATUE > 6:
				self.STATUE = 1
			#add name to statue list
			self.statuelist.append(name)
			
			#Truncate statuelist to 6 winners
			size = len(self.statuelist)
			if size > 5:
				del self.statuelist[0]
			#writes file, winners.txt
			f = open('winners.txt', 'w')
			for each in self.statuelist:
				f.write("%s" % (each))
			f.close()
			
		self.tourneylist = {'totalplayers' : 0, 'players' : []}
		self.seededlist = []
		self.winnerlist = []
		self.loserlist = []
		self.activeduel = []
		self.CURRENT = 1
		self.STARTED = 0
		self.ORGANIZER = -1
		self.RECRUIT = False
		self.TOURNEYROUND = 0
		self.MISSING = -1
		self.CANCEL = False
		for each in self.playerlist:
			each['register'] = 0
		
		kwargs['Broadcast'].broadcast(\
		"ExecScript GlobalSet var TR val 0;\
		 ExecScript GlobalClear; ExecScript GlobalSync")

	def getBye(self, **kwargs):
		#give the bye to the highest seeded player that doesn't have a bye
		lowest = -1
		pick = None
		for each in self.seededlist:
			if each['bye'] == 1:
				continue
				
			ltarget = each['seed']
			if (lowest < 0):
				lowest = ltarget
				# wouldn't work if the first player was the one to pick, so had to do this here
				pick = each
				continue
			if (lowest < ltarget):
				continue
			lowest = ltarget
			pick = each

		print pick
		pick['bye'] = 1
		pick['advance'] = 1

	def removePlayer(self, clinum, **kwargs):
		#remove a player when they have been defeated, if double elimination they have been moved to self.loserlist with single loss.
		for each in self.seededlist:
			if each['clinum'] == clinum:
				self.seededlist.remove(each)
		#for double elimination, remove them all together if they have two loses
		for each in self.loserlist:
			if each['clinum'] == clinum:
				if each['totalloses'] > 1:
					self.loserlist.remove(each)

	def spawnStatues(self, **kwargs):
		for each in self.statuelist:
			kwargs['Broadcast'].broadcast(\
			"RemoveEntity #GetIndexFromName(player_%s)#;\
			 SpawnEntityAtEntity statue_%s Prop_Dynamic name player_%s maxhealth 999999999 model \"/world/props/arena/stone_legionnaire.mdf\" angles \"%s\" team 0 seed 0 scale 1.7627 propname %s"\
			 % (self.STATUE,self.STATUE,self.STATUE,self.statueangle[self.STATUE-1],each))

			self.STATUE += 1
			if self.STATUE > 6:
				self.STATUE = 1
					
Exemplo n.º 32
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
Exemplo n.º 33
0
 def __init__(self):
     master = MasterServer('Master2')
     master.run(['Slave21', 'Slave22'])
Exemplo n.º 34
0
class mapvote(ConsolePlugin):
	VERSION = "0.0.1"
	ms = None
	PHASE = 0
	playerlist = []
	maplist = []
	votelist = {'votes' : 0, 'playervotes' : []}
	TOTALPLAYERS = 0
	VOTEPERCENT = 40
	MINPLAYERS = 0
	NEWMAP = None
	MAPVOTE = True
	def onPluginLoad(self, config):
		self.ms = MasterServer ()

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		#for (name, value) in config.items('mapvote'):
		#	if (name == "level"):
		#		self._level = int(value)

		#	if (name == "sf"):
		#		self._sf = int(value)
		for (name, value) in ini.items('maps'):
			self.maplist.append({'name' : name, 'status' : value})

		for (name, value) in ini.items('var'):
			if (name == "votepercent"):
				self.VOTEPERCENT = value
			if (name == "minplayers"):
				self.MINPLAYERS = value

		print self.MINPLAYERS, self.VOTEPERCENT
		pass

	def onStartServer(self, *args, **kwargs):
		
		print 'serverstarted'


	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]
				
		self.playerlist.append ({'clinum' : id, 'acctid' : 0, 'name' : 'X', 'active' : 0})
		


	def onSetName(self, *args, **kwargs):
		mapnames = []
		for each in self.maplist:
			mapnames.append(each['name'])
			
		mapnames = ', '.join(mapnames)
		
		mapmessage = "^cThis server is currently equipped with the ability to vote for a map change. Before a game has started you can send the message to ^rALL ^cchat: ^ynextmap mapname"
		mapmessage2 = "^cThis will register your vote for that map."
		mapmessage3 = ("^cCurrent valid maps are: ^y%s" % (mapnames))	
		cli = args[0]
		playername = args[1]
		client = self.getPlayerByClientNum(cli)
		client ['name'] = playername
		kwargs['Broadcast'].broadcast("SendMessage %s %s" % (client['clinum'], mapmessage))
		kwargs['Broadcast'].broadcast("SendMessage %s %s" % (client['clinum'], mapmessage2))
		kwargs['Broadcast'].broadcast("SendMessage %s %s" % (client['clinum'], mapmessage3))

	def onAccountId(self, *args, **kwargs):
		self.TOTALPLAYERS += 1
		cli = args[0]
		id = args[1]
		stats = self.ms.getStatistics (id).get ('all_stats').get (int(id))
		
		client = self.getPlayerByClientNum(cli)

		client ['acctid'] = int(id)
		client ['active'] = 1
		
		

	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)

		for each in self.playerlist:
			if cli == each['clinum']:
				each['active'] = 0

		#if a player has voted and disconnects, remove their vote
		for each in self.votelist['playervotes']:
			if each['player'] == client['name']:
				self.votelist['playervotes'].remove(each)
				self.votelist['votes'] -= 1

		self.TOTALPLAYERS -= 1

		

	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		self.PHASE = phase
	
		if (phase == 7):
			self.onGameEnd(**kwargs)
		
		if (phase == 6):
			self.clearMapVotes(*args, **kwargs)

		if (phase == 5):
			self.clearMapVotes(*args, **kwargs)

	def onNewGame(self, *args, **kwargs):
		
		if (self.PICKING == 1):
			print 'team picking has begun, do not clear team player lists'
			kwargs['Broadcast'].broadcast("echo team picking has begun, do not clear team player lists!")
			
			self.PICKING = 0
			return

	def voteCheck(self, *args, **kwargs):
		tie = False
		totalplayers = self.TOTALPLAYERS 
		totalvotes = self.votelist['votes']
		minplayers = int(self.MINPLAYERS)
		threshold = int(self.VOTEPERCENT)
		votepercent = int(totalvotes/totalplayers) * 100
		#At least this many players must be present to even trigger a map selection
		if totalplayers < minplayers:
			print totalplayers
			print 'minplayer abort'
			return
		#This percentage of the total number of players must vote to trigger a map selection
		if votepercent < threshold:
			print votepercent
			print 'percent abort'
			return

		#determine which map has the most votes
		d = {}
		for votes in self.votelist['playervotes']:
			maps = votes['mapvote']
			d.setdefault(maps,0)
			d[maps] += 1

		items = [(v, k) for k, v in d.items()]
      		items.sort()
      		items.reverse()           
       		size = len(items)
		if size > 1:
			if items[0][0] == items[1][0]:
				print 'we have a tie'
				tie = True	
		if tie:
			kwargs['Broadcast'].broadcast("Serverchat ^cThere is a tie between ^r%s ^cand ^r%s. ^cIf you would like to change your vote you may do so." % (items[0][1], items[1][1]))
			return
		
		#We have a map winner
		newmap = items[0][1]			
		self.ChangeMap(newmap, **kwargs)

	def ChangeMap(self, newmap, **kwargs):

		status = 'official'

		for each in self.maplist:
			if each['name'] == newmap:
				status = each['status']
		if status == 'unofficial':
			kwargs['Broadcast'].broadcast("set svr_sendStats false; set svr_official false ")

		kwargs['Broadcast'].broadcast("changeworld %s" % (newmap))
		self.clearMapVotes(*args, **kwargs)

	def onMessage(self, *args, **kwargs):
		voted = False
		votemap = None
		#ignore anything that isn't sent to ALL chat
		if args[0] != "ALL":
			return
		#if the game has started, or we are in end phase, ignore
		if self.PHASE == 5 or self.PHASE == 7:
			return

		name = args[1]
		message = args[2]
		
		client = self.getPlayerByName(name)
			
		mapvote = re.match("nextmap (\S+)", message, flags=re.IGNORECASE)
		formap = mapvote.group(1)
		
		if not mapvote:
			return
		
		if mapvote:
			
			voted = self.CheckVoted(client)
			
			for maps in self.maplist:
				if formap == maps['name']:
					
					votemap = formap

			if votemap == None:
				#Map name is invalid, tell them they got it wrong
				kwargs['Broadcast'].broadcast("SendMessage %s ^cMap name not recognized." % (client['clinum']))
				return
		
		#player has already voted, just change their map selection
		if voted:
			for each in self.votelist['playervotes']:
				if each['player'] == client['name']:
					each['mapvote'] = votemap
					kwargs['Broadcast'].broadcast("SendMessage %s ^cYou have switched your vote to ^r%s." % (client['clinum'], votemap))
					self.reportVotes(**kwargs)
					self.voteCheck(**kwargs)
					return
		#player has not yet voted, add to the total number of votes and add their selection to the list
		self.votelist['votes'] += 1
		self.votelist['playervotes'].append({'player' : client['name'], 'mapvote' : votemap})
		kwargs['Broadcast'].broadcast("SendMessage %s ^cYou have voted for ^r%s." % (client['clinum'], votemap))
		self.reportVotes(**kwargs)
		#check to see if all the voting critera have been met
		self.voteCheck(**kwargs)

	def CheckVoted(self, client, **kwargs):
		
		for each in self.votelist['playervotes']:
			if each['player'] == client['name']:
				return True			
		
	
	def clearMapVotes(self, *args, **kwargs):

		self.votelist = {'votes' : 0, 'playervotes' : []}	
		self.TOTALPLAYERS = 0
	def reportVotes(self, *args, **kwargs):
			
		d = {}
		for votes in self.votelist['playervotes']:
			maps = votes['mapvote']
			d.setdefault(maps,0)
			d[maps] += 1

		items = [(v, k) for k, v in d.items()]
      		items.sort()
      		items.reverse()

		for each in items:
			kwargs['Broadcast'].broadcast("Serverchat ^cVotes for ^r%s: ^c%s" % (each[1], each[0]))	

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

		kwargs['Broadcast'].broadcast("set svr_sendStats true; set svr_official true")
Exemplo n.º 35
0
 def __init__(self):
     master = MasterServer('Master1')
     master.run(['Slave11', 'Slave12'])
Exemplo n.º 36
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))
Exemplo n.º 37
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)
Exemplo n.º 38
0
class tournament(ConsolePlugin):
	VERSION = "1.0.2"
	STARTED = 0
	MINIMUM =  2
	RECRUIT = False
	ORGANIZER = -1
	DUELROUND = 0
	TOURNEYROUND = 0
	MISSING = -1
	DOUBLEELIM = False
	CANCEL = False
	CURRENT = 1
	lastwinner = -1
	lastloser = -1
	playerlist = []
	tourneylist = {'totalplayers' : 0, 'players' : []}
	tourneystats = {'entries' : 0, 'avgSF' : 0, 'winner' : {}, 'runnerup' : {}}
	seededlist = []
	activeduel = []
	statueangle = []
	statuelist = []
	unitlist = []
	adminlist = []
	blockerlist = []
	OFFICIAL = False
	STATUE = 1
	SVRDESC = False
	svr_desc = "^yTourney - Last Winner: ^r"
	SVRNAME = False
	svr_name = "^yTourney - Last Winner: ^r"

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

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for (name, value) in ini.items('admin'):
			self.adminlist.append(name)
		#Don't know how to get boolean values for things in a specific section of .ini
		for (name, value) in ini.items('var'):
			if (name == "changesvrname") and (value == "true"):
				self.SVRNAME = True
			if (name == "changesvrdesc") and (value == "true"):
				self.SVRDESC = True
			if (name == "svrname"):
				self.svrname = value
			if (name == "changesvrname"):
				self.svrdesc = value
			if (name == "double") and (value == "true"):
				self.DOUBLEELIM = True

		
	def onStartServer(self, *args, **kwargs):
		print 'SERVER RESTARTED'
		self.statuelist = []
		self.STARTED = 0
		self.MINIMUM =  2
		self.RECRUIT = False
		self.ORGANIZER = -1
		self.DUELROUND = 0
		self.TOURNEYROUND = 0
		self.MISSING = -1
		self.playerlist = []
		self.tourneylist = {'totalplayers' : 0, 'players' : []}
		self.seededlist = []
		self.winnerlist = []
		self.loserlist = []
		self.activeduel = []
		self.unitlist = []
		self.counts = 4
		self.counter = 0
		f = open('winners.txt', 'r')
		self.statuelist = f.readlines()
		f.close()
			
		self.statueangle = ["0.0000 0.0000 161.7999",
				    "0.0000 0.0000 107.5998",
				    "0.0000 0.0000 53.1997",
				    "0.0000 0.0000 -22.6002",
				    "0.0000 0.0000 -63.0003",			    
				    "0.0000 0.0000 -109.2003"]

		self.blockerlist = [{'angles' : '0.0000 0.0000 -3.4000', 'name' : 'blocker1', 'position' : '7751.7021 8648.5215 -215.2963', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 38.6000', 'name' : 'blocker2', 'position' : '7112.2378 8417.8262 -148.7921', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 74.8001', 'name' : 'blocker3', 'position' : '6739.8462 8053.7290 -33.6641', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 105.200', 'name' : 'blocker4', 'position' : '6751.2056 7424.2529 20.8391', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 142.000', 'name' : 'blocker5', 'position' : '7105.5361 6935.4971 -244.8373', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 176.800', 'name' : 'blocker6', 'position' : '7682.2261 6741.1899 -246.9767', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 210.400', 'name' : 'blocker7', 'position' : '8237.4541 6833.5957 -14.6271', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 249.200', 'name' : 'blocker8', 'position' : '8587.6348 7221.5093 -58.0270 -215.2963', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 277.800', 'name' : 'blocker9', 'position' : '8664.1816 7800.2666 -182.6546', 'scale' : '33.4070'},
				    {'angles' : '0.0000 0.0000 304.200', 'name' : 'blocker10', 'position' : '8420.5273 8446.7617 -6.7577', 'scale' : '33.4070'}]
		
		self.spawnStatues(**kwargs)
		self.doBlockers('on',**kwargs)

	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, 'sf' : 0, 'name' : 'X', 'index' : 0, 'active' : 0, 'register' : 0, 'loses' : 0})
	
	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		client ['active'] = 0
		for each in self.activeduel:
			if each['clinum'] == cli:
				self.fightersPresent(**kwargs)

	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 ['acctid'] = int(id)
		client ['level'] = level
		client ['sf'] = sf
		client ['active'] = 1
		
		if (self.STARTED == 1) and (cli == self.MISSING):
			kwargs['Broadcast'].broadcast("set _MISSING -1")
			#self.nextDuelRound(**kwargs)
		kwargs['Broadcast'].broadcast("SendMessage %s ^cDuel Tournament made by ^yOld55 ^cand ^yPidgeoni" % (cli))
		
		if self.isAdmin(client, **kwargs):
			kwargs['Broadcast'].broadcast("SendMessage %s ^cYou are registered as an administrator for this tournament server. Send the chat message: ^rhelp ^cto see what commands you can perform." % (cli))
			
	def getPlayerIndex (self, cli):
		
		indice = -1
		for player in self.playlist:
			indice += 1
							
			if (player['clinum'] == cli):
				return indice
			
			

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

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

	def RegisterScripts(self, **kwargs):
		#any extra scripts that need to go in can be done here
		#default unit list
		self.unitlist = ['Player_Savage', \
				 'Player_ShapeShifter', \
				 'Player_Predator', \
				 'Player_Hunter', \
				 'Player_Marksman']
		
		kwargs['Broadcast'].broadcast("set _green #GetIndexFromName(green_spawn)#; \
						set _red #GetIndexFromName(red_spawn)#; \
						set _exit1 #GetIndexFromName(exit1)#; \
						set _exit2 #GetIndexFromName(exit2)#; \
						set _p1x #GetPosX(|#_green|#)#; \
						set _p1y #GetPosY(|#_green|#)#; \
						set _p1z #GetPosZ(|#_green|#)#; \
						set _p2x #GetPosX(|#_red|#)#; \
						set _p2y #GetPosY(|#_red|#)#; \
						set _p2z #GetPosZ(|#_red|#)#; \
						set _e1x #GetPosX(|#_exit1|#)#; \
						set _e1y #GetPosY(|#_exit1|#)#; \
						set e1z #GetPosZ(|#_exit1|#)#; \
						set _e2x #GetPosX(|#_exit2|#)#; \
						set _e2y #GetPosY(|#_exit2|#)#; \
						set _e2z #GetPosZ(|#_exit2|#)#; \
						set _MISSING -1")		
	
		
	def isAdmin(self, client, **kwargs):
		admin = False
		
		for each in self.adminlist:
			if client['name'].lower() == each:
				admin = True
		
		return admin

	def adminCommands (self, message, client, **kwargs):
		start = re.match("start", message, flags=re.IGNORECASE)
		official = re.match("toggle official", message, flags=re.IGNORECASE)
		redo = re.match("redo", message, flags=re.IGNORECASE)
		next = re.match("next", message, flags=re.IGNORECASE)
		elim = re.match("double", message, flags=re.IGNORECASE)
		fail = re.match("remove (\S+)", message, flags=re.IGNORECASE)
		kick = re.match("kick (\S+)", message, flags=re.IGNORECASE)
		help = re.match("help", message, flags=re.IGNORECASE)
		blocker = re.match("blocker (\S+)", message, flags=re.IGNORECASE)
		cancel = re.match("cancel", message, flags=re.IGNORECASE)
		#lets admin register people, even if not official tournament
		register = re.match("register (\S+)", message, flags=re.IGNORECASE)
		
		if start:
			self.start (client, **kwargs)

		if official:
			self.toggleOfficial (client, **kwargs)
		
		if redo:
			self.redoDuel (**kwargs)

		if next:
			self.endDuel (**kwargs)
			
		if register:
			client = self.getPlayerByName(register.group(1))
			self.register (client, **kwargs)
			
		if fail:
			killer = -1
			killed = -1

			client = self.getPlayerByName(fail.group(1))
			for each in self.activeduel:
				if each['clinum'] == client['clinum']:
					killed = each['clinum']
					each['loses'] = 3
					continue
				if each['clinum'] != client['clinum']:
				 	killer = each['clinum']
			
			if killer > -1 and killed > -1:
				self.onDeath(killer, killed, **kwargs)
				kwargs['Broadcast'].broadcast("SendMessage %s ^yAn administrator has removed you from the tournament" % (killed))

		if kick:
			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 blocker:
		
			self.doBlockers(blocker.group(1), **kwargs)

		if elim:
			if self.STARTED == 1:
				kwargs['Broadcast'].broadcast("SendMessage %s A tournament has already started" % (client['clinum']))
				return
			self.toggleDouble (client, **kwargs)

		if cancel:
			self.CANCEL = True
			self.endTourney(**kwargs)
			kwargs['Broadcast'].broadcast(\
						"Serverchat The tournament has been ended by an administrator")

		if help:
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s All commands on the server are done through server chat. The following are commands and a short description of what they do." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s As an admin you must ALWAYS register yourself by sending the message: ^rregister yourname" % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rtoggle official ^wsets the tournament between official and unofficial status.\
			 Admins MUST register people for official tournaments. Only admins can start tournaments in official mode." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rregister playername ^wwill register a player for the tournament. Must be used in official mode but also works in unofficial." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rblocker on/off ^wwill turn range blockers on/off around the arena." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rredo ^wwill force the players fighting in the arena to redo the last match. ONLY use after players have respawned as the next unit." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rremove playername ^wwill force a player to lose the match. Currently only works \
			when the player is on the server. If they have disconnected, it is best to just let them timeout." % (client['clinum']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rcancel ^wwill cancel the current tournament." % (client['clinum']))

	def onMessage(self, *args, **kwargs):
		
		name = args[1]
		message = args[2]
		
		client = self.getPlayerByName(name)
		admin = self.isAdmin(client, **kwargs)
		
		#pass to admincommands
		if admin:
			self.adminCommands(message, client, **kwargs)

		#only admins are allowed to start/add/redo/etc. if the tournament is official
		if self.OFFICIAL:
			return

		roundunit = re.match("Round (\S+) Unit (\S+)", message, flags=re.IGNORECASE)
		register = re.match("register", message, flags=re.IGNORECASE)
		


		if register:
			self.register (client, **kwargs)

		if roundunit:
			if client['clinum'] != self.ORGANIZER:
				return
			duelround = int(roundunit.group(1))
			unit = (roundunit.group(2))
			print duelround, unit
			self.unitlist[duelround-1] = ("Player_%s" % (unit))

	def doBlockers (self, toggle, **kwargs):

		if toggle == 'on':
			for each in self.blockerlist:
				kwargs['Broadcast'].broadcast(\
				"SpawnEntity Prop_Scenery model \"/world/props/tools/blocker_range.mdf\" position \"%s\" name \"%s\" angles \"%s\" scale \"%s\"" \
				% (each['position'], each['name'], each['angles'], each['scale']))

		if toggle == "off":
			for each in self.blockerlist:
				kwargs['Broadcast'].broadcast("RemoveEntity #GetIndexFromName(%s)#" % (each['name']))

		return

	def toggleOfficial (self, client, **kwargs):	
		
		if self.OFFICIAL:
			self.OFFICIAL = False
		else:
			self.OFFICIAL = True

		kwargs['Broadcast'].broadcast("SendMessage %s ^rOfficial Status: %s" % (client['clinum'], self.OFFICIAL))

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

		if self.DOUBLEELIM:
			self.OFFICIAL = False
		else:
			self.DOUBLEELIM = True

		kwargs['Broadcast'].broadcast("SendMessage %s ^rDouble Elimination Status: %s" % (client['clinum'], self.DOUBLEELIM))

	def redoDuel (self, **kwargs):	

		self.DUELROUND -= 1
		
		for each in self.activeduel:
			if (each['clinum'] == self.lastloser):
				each['loses'] -= 1
									
			if (each['clinum'] == self.lastwinner):
				each['wins'] -= 1
				kwargs['Broadcast'].broadcast("ExecScript GlobalSet var R%sS%s val %s" % (each['bracket'], each['column'], each['wins']))
				kwargs['Broadcast'].broadcast("ExecScript GlobalSync")
		
		kwargs['Broadcast'].broadcast("set _DUELER1 -1; set _DUELER2 -1")
		self.nextDuelRound(**kwargs)

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

		admin = self.isAdmin(client, **kwargs)
				
		if self.RECRUIT or self.STARTED == 1:
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rA tournament has already been started. You must wait till the current tournament ends to start a new one." % (client['clinum']))
			return

		activeplayers = 0
		for player in self.playerlist:
			if player['active'] == 1:
				activeplayers += 1

		if (activeplayers < self.MINIMUM):
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^rA minimum of two active players is required to call a tournament" % (client['clinum']))		
			return
		
		self.RegisterScripts(**kwargs)	
		self.RECRUIT = True
		kwargs['Broadcast'].broadcast(\
		"ServerChat ^r%s ^chas started a tournament! To join the tournament, send the message 'register' to ALL, SQUAD, or TEAM chat.; \
		 ExecScript starttourney; \
		 ExecScript GlobalSet var TSB val %s; \
		 ExecScript GlobalShowDuel" \
		 % (client['name'], client['name']))

		self.ORGANIZER = client['clinum']
		kwargs['Broadcast'].broadcast("ClientExecScript %s ClientShowOptions" % (self.ORGANIZER))
	

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

		kwargs['Broadcast'].broadcast("TakeItem #GetIndexFromClientNum(%s)# 10" % (client ['clinum']))

		if self.RECRUIT and client['register'] == 0:
			self.tourneylist ['players'].append ({'clinum' : client['clinum'],
							      'acctid' : client['acctid'],
							      'name' : client['name'],
							      'sf' : client['sf'],
							      'level' : client['level'],
							      'totalwins' : 0,
							      'totalloses' : 0,
							      'seed' : 0,
							      'advance' : 2,
							      'bye' : 0,
							      'bracket' : 0})	
			client['register'] = 1
			self.tourneylist ['totalplayers'] += 1
			kwargs['Broadcast'].broadcast(\
			"Serverchat ^r%s ^chas registered for the tournament." % (client ['name']))
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s ^yYou have successfully registered for the tournament." % (client ['clinum']))
			
		else:

			return

	def RegisterStart(self, **kwargs):

		self.RECRUIT = False
		self.STARTED = 1
		self.seedPlayers(**kwargs)
	
	def getTourneyinfo(self, **kwargs):

		entries = self.seededlist['totalplayers']
		self.tourneystats['entries'] = entries
		totalsf = 0

		for each in self.seededlist['players']:
			totalsf += each['sf']

		self.tourneystats['avgSF'] = int(totalsf/entries)


	def seedPlayers(self, **kwargs):
		
		self.TOURNEYROUND = 1
		kwargs['Broadcast'].broadcast(\
		"ExecScript GlobalSet var TR val 1")
		kwargs['Broadcast'].broadcast(\
		"ClientExecScript %s ClientHideOptions" % (self.ORGANIZER))
		if (self.tourneylist ['totalplayers'] < 4):
			self.tourneylist = {'totalplayers' : 0, 'players' : []}
			self.seededlist = []
			self.STARTED = 0
			self.ORGANIZER = -1
			self.RECRUIT = False
			for each in self.playerlist:
				each['register'] = 0
		
			kwargs['Broadcast'].broadcast(\
			"ClientExecScript -1 ClientClear")
			kwargs['Broadcast'].broadcast(\
			"Serverchat The tournament must have 4 people to start. Aborting.")
			
			return

		self.seededlist = sorted(self.tourneylist ['players'], key=itemgetter('sf', 'level', 'clinum'), reverse=True)
		seed = 0

		#Gets information about tournament for scoring purposes
		#self.getTourneyinfo()

		for player in self.seededlist:
			seed += 1
			player['seed'] += seed

		totalplayers = self.tourneylist['totalplayers']
		start = 0
		end = totalplayers - 1

		#round 1 seeding/bracket placement
		if (self.tourneylist['totalplayers'] % (2)) == 0:
	
			total_brackets = (totalplayers / 2)
			bracket = 1

			while (start < total_brackets):
				self.seededlist[start]['bracket'] = bracket
				self.seededlist[end]['bracket'] = bracket
				kwargs['Broadcast'].broadcast(\
				"ExecScript GlobalSet var R%sNA val %s;\
				 ExecScript GlobalSet var R%sFA val %s;\
				 ExecScript GlobalSet var R%sNB val %s;\
				 ExecScript GlobalSet var R%sFB val %s;"\
				 % (bracket, self.seededlist[start]['name'],bracket,self.seededlist[start]['sf'],bracket,self.seededlist[end]['name'],bracket,self.seededlist[end]['sf']))	
				start += 1
				end -= 1
				bracket += 1

		if (self.tourneylist['totalplayers'] % (2)) != 0:
			totalplayers = totalplayers+1 
			total_brackets = (totalplayers / 2)
			bracket = 1
			self.seededlist[start]['bye'] = 1
			self.seededlist[start]['bracket'] = bracket
			self.seededlist[start]['advance'] = 1
			self.winnerlist.append(self.seededlist[start])
			print self.winnerlist

			kwargs['Broadcast'].broadcast(\
			"ExecScript GlobalSet var R%sSA val 3;\
			 ExecScript GlobalSet var R%sNA val %s;\
			 ExecScript GlobalSet var R%sFA val %s;\
			 ExecScript GlobalSet var R%sNB val BYE"\
			 % (bracket,bracket,self.seededlist[start]['name'],bracket,self.seededlist[start]['sf'],bracket))
			start += 1
			bracket += 1

			while (start < total_brackets):
				self.seededlist[start]['bracket'] = bracket
				self.seededlist[end]['bracket'] = bracket
				kwargs['Broadcast'].broadcast(\
				"ExecScript GlobalSet var R%sNA val %s;\
				 ExecScript GlobalSet var R%sFA val %s; \
				 ExecScript GlobalSet var R%sNB val %s; \
				 ExecScript GlobalSet var R%sFB val %s;"\
				 % (bracket,self.seededlist[start]['name'],bracket,self.seededlist[start]['sf'],bracket,self.seededlist[end]['name'],bracket,self.seededlist[end]['sf']))
				bracket += 1
				start += 1
				end -= 1

		
		self.checkRound(**kwargs)
		

	def checkRound(self, **kwargs):
		#figure out who has yet to fight
		print 'at checkRound'
		bl = []
		for brackets in self.seededlist:
			bl.append(brackets['bracket'])
		print bl

		for item in set(bl):
			if (bl.count(item) > 1):
				print item
				self.nextDuel(item, **kwargs)
				return
			
		self.nextRound(**kwargs)
		print 'round over'
		self.TOURNEYROUND += 1

	def nextDuel(self, bracket, **kwargs):
		print bracket
		kwargs['Broadcast'].broadcast(\
		"ExecScript GlobalSet var CR val %s;\
		 ExecScript GlobalSync"\
		 % (bracket))

		for each in self.seededlist:
			if each['bracket'] == bracket:
				#added to kill each of the duelers before the start so they get out of their current duels
				kwargs['Broadcast'].broadcast(\
				"set _index #GetIndexFromClientNum(%s)#;\
				 KillEntity #_index#"\
				 % (each['clinum']))
				self.activeduel.append(each)

		for each in self.activeduel:
			each['loses'] = 0
			each['wins'] = 0

		self.activeduel[0]['column'] = "A"
		self.activeduel[1]['column'] = "B"
		
		self.getNextDuel(**kwargs)

	def getNextDuel(self, *args, **kwargs):
		self.nextDuelRound(**kwargs)

	def nextDuelRound(self, **kwargs):
		
		if self.fightersPresent(**kwargs):
			kwargs['Broadcast'].broadcast("set _DUEL 0")
			self.getUnit(**kwargs)
			kwargs['Broadcast'].broadcast(\
			"set _index #GetIndexFromClientNum(%s)#;\
			 GiveItem #_index# 9 Spell_CommanderHeal;\
			 StartEffectOnObject #_index# \"shared/effects/green_aura.effect\";\
			 ResetAttributes #_index#;\
			 SetPosition #_index# #_p1x# #_p1y# #_p1z#;\
			 ChangeUnit #_index# #_UNIT# true false false false false false false;\
			 ClientExecScript %s holdmove"\
			 % (self.activeduel[0]['clinum'],self.activeduel[0]['clinum']))

			kwargs['Broadcast'].broadcast(\
			"set _index #GetIndexFromClientNum(%s)#;\
			 GiveItem #_index# 9 Spell_CommanderHeal;\
			 StartEffectOnObject #_index# \"shared/effects/red_aura.effect\"; \
			 ResetAttributes #_index#; \
			 SetPosition #_index# #_p2x# #_p2y# #_p2z#;\
			 ChangeUnit #_index# #_UNIT# true false false false false false false;\
			 ClientExecScript %s holdmove"\
			 % (self.activeduel[1]['clinum'],self.activeduel[1]['clinum']))

			kwargs['Broadcast'].broadcast(\
			"ExecScript setdueler dueler1 %s dueler2 %s"\
			 % (self.activeduel[0]['clinum'], self.activeduel[1]['clinum']))

			kwargs['Broadcast'].broadcast(\
			"Execscript duelcountdown")	
		else:
			
			print 'player missing'

	def waitForPlayer(self, *args, **kwargs):
		action = args[0]

		if (action == 'Timeout'):
			for each in self.activeduel:
				if each['clinum'] == self.MISSING:
					each['loses'] = 3
					missing = each['clinum']
					self.MISSING = -1
				else:
					remaining = each['clinum']
			self.onDeath(remaining, missing,**kwargs)
					
		if (action == 'Connected'):
			#if (self.DUELROUND > 0):
				#self.DUELROUND -= 1
			self.MISSING = -1
			kwargs['Broadcast'].broadcast("set _DUELER1 -1; set _DUELER2 -1")
			self.nextDuelRound(**kwargs)					
			
	def getUnit(self, **kwargs):
		
		unit = self.unitlist[self.DUELROUND]
		kwargs['Broadcast'].broadcast("set _UNIT %s" % (unit))

	def fightersPresent(self, **kwargs):
		
		if self.MISSING > -1:
			return False
		
		for each in self.activeduel:
			clinum = each['clinum']
			for players in self.playerlist:
				if (players['clinum'] == clinum) and (players['active'] == 0):
					self.MISSING = players['clinum']
					name = players['name']
					kwargs['Broadcast'].broadcast(\
					"ServerChat ^cThe next duel is between ^r%s ^cand ^r%s^c, but ^r%s ^chas disconnected. They have 1 minute to reconnect or they will lose the round.;\
					 set _MISSING %s;\
					 ExecScript missingfighter"\
					 % (self.activeduel[0]['name'],self.activeduel[1]['name'], name, self.MISSING))
					return False
		return True

	def onDeath(self, *args, **kwargs):
		print 'got Death'
		#this will be called from a specific filter
		killer = args[0]
		killed = args[1]
		wasduel = 0
		print args
		if self.STARTED != 1 or self.MISSING > -1:
			return
		
		for each in self.activeduel:
			if (each['clinum'] == killed):
				wasduel += 1
				clikilled = each
			if (each['clinum'] == killer):
				wasduel += 1
				clikill = each

		if wasduel == 2:
			self.DUELROUND += 1
			self.lastloser = clikilled['clinum']
			clikilled['loses'] += 1
			kwargs['Broadcast'].broadcast(\
			"set _idx #GetIndexFromClientNum(%s)#;\
			 TakeItem #_idx# 9;\
			 set _DUELER1 -1;\
			 set _DUELER2 -1"\
			 % (clikilled['clinum']))

			self.lastwinner = clikill['clinum']
			clikill['wins'] += 1
			kwargs['Broadcast'].broadcast(\
			"ExecScript GlobalSet var R%sS%s val %s;\
			 ExecScript GlobalSync"\
			 % (clikill['bracket'], clikill['column'], clikill['wins']))
					
			for each in self.activeduel:		
				if each['loses'] > 2:
					self.checkendDuel(**kwargs)
					kwargs['Broadcast'].broadcast("ExecScript GlobalSync")
					return
	
			kwargs['Broadcast'].broadcast("ExecScript nextduelround")
		
	def checkendDuel(self, **kwargs):
		kwargs['Broadcast'].broadcast(\
		"set _index #GetIndexFromClientNum(%s)#;\
		 StopEffectOnObject #_index# \"shared/effects/green_aura.effect\";\
		 SetPosition #_index# #_e1x# #_e1y# #_e1z#;\
		 ChangeUnit #_index# Player_Savage  true false false false false false false"\
		 % (self.activeduel[0]['clinum']))

		kwargs['Broadcast'].broadcast(\
		"set _index #GetIndexFromClientNum(%s)#;\
		 StopEffectOnObject #_index# \"shared/effects/red_aura.effect\";\
		 SetPosition #_index# #_e2x# #_e2y# #_e2z#;\
		 ChangeUnit #_index# Player_Savage  true false false false false false false"\
		 % (self.activeduel[1]['clinum']))

		if not self.OFFICIAL:
			self.endDuel(**kwargs)
			return

		if self.OFFICIAL:
			kwargs['Broadcast'].broadcast(\
			"SendMessage %s This duel is over. Please send message 'next' to chat for the next duel, or 'redo' if there was an error."\
			 % (self.ORGANIZER))			
			
	def endDuel(self, **kwargs):
	
		for each in self.activeduel:
				if each['loses'] > 2:
					loser = each['name']
					clinum = each['clinum']
					each['totalloses'] += 1
					self.loserlist.append(each)
					self.tourneystats['runnerup'] = { 'name' : each['name'], 'acctid' : each['acctid'] }
					self.removePlayer(each['clinum'])
				if each['loses'] < 3:
					winner = each['name']
					self.tourneystats['winner'] = { 'name' : each['name'], 'acctid' : each['acctid'] }
					each['totalwins'] += 1
					if each['totalloses'] == 0:
						self.winnerlist.append(each)
					if each['totalloses'] == 1:
						self.loserlist.append(each)
		kwargs['Broadcast'].broadcast(\
		"ServerChat ^y%s ^chas defeated ^y%s ^cand moves on to the next round"\
		 % (winner, loser))

		self.activeduel = []
		self.DUELROUND = 0
		
		self.checkRound(**kwargs)

	def swapList(self, winners, losers, **kwargs):
		
		#gets if we are currently in winners or losers bracket, 1 = winner 2 = losers
		
		#special condition, all remaining players are in losers bracket
		if winners == 0:
			print 'condition: no winners'
			self.CURRENT = 2
			self.seededlist = list(self.loserlist)
			del self.loserlist[:]
			return

		#special condition, all are in winners bracket
		if losers == 0:
			print 'condition: no losers'
			self.CURRENT = 1
			self.seededlist = list(self.winnerlist)
			del self.winnerlist[:]
			return

		#special condition, split brackets
		if losers == 1 and winners == 1:
			print 'condition: split lists'
			self.seededlist = [self.winnerlist[0], self.loserlist[0]]
			del self.loserlist[:]
			del self.winnerlist[:]
			return		

		if self.CURRENT == 1:
			if losers > 1:
				print 'condition: start loser bracket'
				self.CURRENT = 2
				self.seededlist = list(self.loserlist)
				self.loserlist = []
				return
			elif losers < 2:
				self.CURRENT = 1
				self.seededlist = list(self.winnerlist)
				self.winnerlist = []
				return
		if self.CURRENT == 2:
			if winners > 1:
				print 'condition: start winner bracket'
				self.CURRENT = 1
				self.seededlist = list(self.winnerlist)
				self.winnerlist = []
				return
			elif winners < 2:
				self.CURRENT = 2
				self.seededlist = list(self.loserlist)
				self.loserlist = []
				return
		
		print self.seededlist
				
	def nextRound(self, **kwargs):
		kwargs['Broadcast'].broadcast("ExecScript GlobalClear; ClientExecScript -1 releasemove")
		
		print 'made it to nextRound'
		remaining = 0
		self.TOURNEYROUND += 1
		kwargs['Broadcast'].broadcast("ExecScript GlobalSet var TR val %s" % (self.TOURNEYROUND))
		
					
		if self.DOUBLEELIM:
			
			winners = self.getRemaining(self.winnerlist, **kwargs)
			losers = self.getRemaining(self.loserlist, **kwargs)
			remaining = winners + losers
			if remaining == 1:
				self.endTourney(**kwargs)
				return
			print winners, losers
			self.swapList(winners, losers)

		remaining = self.getRemaining(self.seededlist, **kwargs)
		kwargs['Broadcast'].broadcast("echo Remaining players: %s" % (remaining))
		if (remaining == 1):
			self.endTourney(**kwargs)		
			return

		if (remaining % (2)) != 0:
			self.getBye(**kwargs)
		
		self.seededlist = sorted(self.seededlist, key=itemgetter('advance', 'bracket'))

		#re-seed the list if we are switching to the loser bracket
		if self.CURRENT == 2:
			self.seededlist = sorted(self.seededlist, key=itemgetter('advance', 'seed', 'bracket'))

		#now to do the re-bracketing
		start = 0
		end = remaining - 1
		doround = True
		bracket = 0

		if (self.seededlist[start]['advance'] == 1):
			bracket = 1
			byer = self.seededlist[start]
			byer['bracket'] = bracket
			if byer['totalloses'] == 1:
				self.loserlist.append(self.seededlist[start])
			if byer['totalloses'] == 0:
				self.winnerlist.append(self.seededlist[start])
			kwargs['Broadcast'].broadcast(\
			"ExecScript GlobalSet var R%sSA val 3;\
			 ExecScript GlobalSet var R%sNA val %s;\
			 ExecScript GlobalSet var R%sFA val %s;\
			 ExecScript GlobalSet var R%sNB val BYE"\
			 % (bracket,bracket,self.seededlist[start]['name'],bracket,self.seededlist[start]['sf'],bracket))
			self.seededlist[start]['column'] = 'A'
			start += 1
		
		
		while doround:
			bracket += 1	
			self.seededlist[start]['bracket'] = bracket
			self.seededlist[end]['bracket'] = bracket
			kwargs['Broadcast'].broadcast(\
			"ExecScript GlobalSet var R%sNA val %s;\
			 ExecScript GlobalSet var R%sFA val %s;\
			 ExecScript GlobalSet var R%sNB val %s;\
			 ExecScript GlobalSet var R%sFB val %s;"\
			 % (bracket,self.seededlist[start]['name'],bracket,self.seededlist[start]['sf'],bracket,self.seededlist[end]['name'],bracket,self.seededlist[end]['sf']))
			self.seededlist[start]['column'] = "A"
			self.seededlist[end]['column'] = "B"
			if (end - start) == 1:
				doround = False
			start += 1
			end -= 1

		print self.seededlist
		self.checkRound(**kwargs)

	def getRemaining(self, getlist, **kwargs):
		remaining = 0

		for each in getlist:
			each['advance'] = 2
			remaining += 1

		return remaining

	def endTourney(self, **kwargs):

		if not self.CANCEL:
			winner = self.seededlist[0]
			name = winner['name']
			clinum = winner['clinum']
			wins = winner['totalwins']

			kwargs['Broadcast'].broadcast(\
			"ServerChat ^cThis tournament is over! The winner is %s with a total of %s wins."\
			 % (name, wins))

			kwargs['Broadcast'].broadcast(\
			"set _winnerind #GetIndexFromClientNum(%s);\
			 ClientExecScript %s ClientHideOptions"\
			 % (clinum, self.ORGANIZER))

			if self.SVRDESC:
				kwargs['Broadcast'].broadcast(\
				"set svr_desc \"%s\"%s" % (self.svr_desc, name))
			if self.SVRNAME:
				kwargs['Broadcast'].broadcast(\
				"set svr_name \"%s\"%s"\
				 % (self.svr_name, name))
			#Adds a statue
			kwargs['Broadcast'].broadcast(\
			"RemoveEntity #GetIndexFromName(player_%s)#;\
			 SpawnEntityAtEntity statue_%s Prop_Dynamic name player_%s maxhealth 999999999 model \"/world/props/arena/stone_legionnaire.mdf\" angles \"%s\" team 0 seed 0 scale 1.7627 propname %s"\
			 % (self.STATUE,self.STATUE,self.STATUE,self.statueangle[self.STATUE-1],name))
			self.STATUE += 1
			if self.STATUE > 6:
				self.STATUE = 1
			#add name to statue list
			self.statuelist.append(name)
			
			#Truncate statuelist to 6 winners
			size = len(self.statuelist)
			if size > 5:
				del self.statuelist[0]
			#writes file, winners.txt
			f = open('winners.txt', 'w')
			for each in self.statuelist:
				f.write("%s" % (each))
			f.close()
			
		self.tourneylist = {'totalplayers' : 0, 'players' : []}
		self.seededlist = []
		self.winnerlist = []
		self.loserlist = []
		self.activeduel = []
		self.CURRENT = 1
		self.STARTED = 0
		self.ORGANIZER = -1
		self.RECRUIT = False
		self.TOURNEYROUND = 0
		self.MISSING = -1
		self.CANCEL = False
		for each in self.playerlist:
			each['register'] = 0
		
		kwargs['Broadcast'].broadcast(\
		"ExecScript GlobalSet var TR val 0;\
		 ExecScript GlobalClear; ExecScript GlobalSync")

	def getBye(self, **kwargs):
		#give the bye to the highest seeded player that doesn't have a bye
		lowest = -1
		pick = None
		for each in self.seededlist:
			if each['bye'] == 1:
				continue
				
			ltarget = each['seed']
			if (lowest < 0):
				lowest = ltarget
				# wouldn't work if the first player was the one to pick, so had to do this here
				pick = each
				continue
			if (lowest < ltarget):
				continue
			lowest = ltarget
			pick = each

		print pick
		pick['bye'] = 1
		pick['advance'] = 1

	def removePlayer(self, clinum, **kwargs):
		#remove a player when they have been defeated, if double elimination they have been moved to self.loserlist with single loss.
		for each in self.seededlist:
			if each['clinum'] == clinum:
				self.seededlist.remove(each)
		#for double elimination, remove them all together if they have two loses
		for each in self.loserlist:
			if each['clinum'] == clinum:
				if each['totalloses'] > 1:
					self.loserlist.remove(each)

	def spawnStatues(self, **kwargs):
		for each in self.statuelist:
			kwargs['Broadcast'].broadcast(\
			"RemoveEntity #GetIndexFromName(player_%s)#;\
			 SpawnEntityAtEntity statue_%s Prop_Dynamic name player_%s maxhealth 999999999 model \"/world/props/arena/stone_legionnaire.mdf\" angles \"%s\" team 0 seed 0 scale 1.7627 propname %s"\
			 % (self.STATUE,self.STATUE,self.STATUE,self.statueangle[self.STATUE-1],each))

			self.STATUE += 1
			if self.STATUE > 6:
				self.STATUE = 1
Exemplo n.º 39
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)
Exemplo n.º 40
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)
Exemplo n.º 41
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']))
Exemplo n.º 42
0
 def __init__(self):
     master = MasterServer('Master3')
     master.run(['Slave31', 'Slave32'])
Exemplo n.º 43
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)		
Exemplo n.º 44
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)
Exemplo n.º 45
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)
Exemplo n.º 46
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))
Exemplo n.º 47
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)
Exemplo n.º 48
0
class balancer(ConsolePlugin):
	VERSION = "1.0.8"
	ms = None
	TIME = 0
	THRESHOLD = 6
	JOINTHRESHOLD = 8
	DIFFERENCE = -1
	GAMESTARTED = 0
	STARTSTAMP = 0
	DENY = 0
	OPTION = 0
	PICKING = 0
	CHAT_INTERVAL = 10
	CHAT_STAMP = 0
	PHASE = 0
	TOTAL1 = 0
	TOTAL2 = 0
	STAMPS = 0
	reason = "Your Skill Factor is 0. Please play some matches on official beginner servers to get some stats before you join this server."
	playerlist = []
	itemlist = []
	balancereport = []
	teamOne = {'size' : 0, 'avgBF' : -1, 'combinedBF' : 0, 'players' : []}
	teamTwo = {'size' : 0, 'avgBF' : -1, 'combinedBF' : 0, 'players' : []}
	game = {'size' : 0, 'avgBF' : -1}
	switchlist = []
	followlist = []

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

		ini = ConfigParser.ConfigParser()
		ini.read(config)
		for (name, value) in ini.items('balancer'):
			if (name == "threshold"):
				self.THRESHOLD = int(value)
			if (name == "jointhreshold"):
				self.JOINTHRESHOLD = int(value)
		
		
		pass

	def onStartServer(self, *args, **kwargs):
		
		self.TIME = 0
		self.THRESHOLD = 6
		self.DIFFERENCE = -1
		self.GAMESTARTED = 0
		self.STARTSTAMP = 0
		self.DENY = 0
		self.OPTION = 0
		self.PICKING = 0
		self.CHAT_INTERVAL = 10
		self.CHAT_STAMP = 0
		self.PHASE = 0
		self.TOTAL1 = 0
		self.TOTAL2 = 0
		self.STAMPS = 0
		self.playerlist = []
		self.itemlist = []
		self.balancereport = []
		self.teamOne = {'size' : 0, 'avgBF' : -1, 'combinedBF' : 0, 'players' : []}
		self.teamTwo = {'size' : 0, 'avgBF' : -1, 'combinedBF' : 0, 'players' : []}
		self.game = {'size' : 0, 'avgBF' : -1}
		self.switchlist = []
		self.followlist = []


	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 onRefresh(self, *args, **kwargs):
		
		del self.teamOne ['players'][:]
		del self.teamTwo ['players'][:]
		self.teamOne ['size'] = 0
		self.teamTwo ['size'] = 0
		
		
		for client in self.playerlist:
			if (client['active'] == 1):
				kwargs['Broadcast'].broadcast("set _idx #GetIndexFromClientNum(%s)#; set _team #GetTeam(|#_idx|#)#; echo CLIENT %s is on TEAM #_team#" % (client['clinum'], client['clinum']))
				

	def onRefreshTeams(self, *args, **kwargs):
		
		clinum = args[0]
		team = int(args[1])
		
		if (team > 0):
			client = self.getPlayerByClientNum(clinum)
			teamlists = self.GetTeamLists(client, team)
			fromteam = teamlists ['fromteam']
			
			self.addTeamMember(client, fromteam, team, **kwargs)
			
			return
		

		

	def onConnect(self, *args, **kwargs):
		
		id = args[0]
		
		for client in self.playerlist:
			if (client['clinum'] == id):
				#added 10/12. If a player DCs and reconnects, they are auto-joined to their old team
				#but there is no team join message. This automatically adds them back to the balancer team list.
				print 'already have entry with that clientnum!'
				team = int(client['team'])
				
				if (team > 0):
					teamlists = self.GetTeamLists(client, team)
					toteam = teamlists ['toteam']
					fromteam = teamlists ['fromteam']
					self.addTeamMember(client, fromteam, team, **kwargs)
					client ['active'] = 1
					return
				return
		self.playerlist.append ({'clinum' : id, 'acctid' : 0, 'level' : 0, 'sf' : 0, 'bf' : 0, 'lf' : 0, 'name' : 'X', 'team' : 0, 'moved' : 0, 'index' : 0, 'exp' : 2, 'value' : 150, 'prevent' : 0, 'active' : 0, 'gamelevel' : 1})
		

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

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

		client = self.getPlayerByClientNum(cli)

		client ['name'] = playername
		


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

		doKick = False

		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'])
		if sf == 0 and exp > 500:
			time = time/60
			sf = int(exp/time)
		client = self.getPlayerByClientNum(cli)

		client ['acctid'] = int(id)
		client ['level'] = level
		client ['sf'] = sf
		client ['lf'] = lf
		client ['exp'] = exp
		client ['active'] = 1
		if sf == 0:
			doKick = True
			
		if doKick:
			kwargs['Broadcast'].broadcast("kick %s \"%s\"" % (cli, self.reason))

		self.retrieveLevels(cli, **kwargs)

	def checkForSpectator (self, cli):
		player = self.getPlayerByClientNum(cli)

		if (player['team'] > 0):
			
			return cli
		else:
			return -1
	
	def getTeamMember (self, item, cli, fromteam):
		
		indice = -1
		
		for player in fromteam['players']:
			
			indice += 1
							
			if (player['clinum'] == cli):
				
				return indice
			
					
	def getPlayerIndex (self, cli):
		
		indice = -1
		for player in self.playlist:
			indice += 1
							
			if (player['clinum'] == cli):
				return indice
			
			
	def removeTeamMember (self, client, fromteam, team, **kwargs):
		print 'Removing player....'
		client ['team'] = team
		cli = client ['clinum']
		item = 'clinum'
		PLAYER_INDICE = self.getTeamMember(item, cli, fromteam)
		fromteam ['combinedBF'] -= fromteam['players'][PLAYER_INDICE]['bf']
		del fromteam['players'][PLAYER_INDICE]
		
		self.getGameInfo(**kwargs)

	def addTeamMember (self, client, toteam, team, **kwargs):
		
		print 'Adding player....'	
		cli = client['clinum']
		client ['active'] = 1
		NAME = client['name']
		level = client['level']
		SF = client['sf']
		#BF = SF + level + (client ['gamelevel'] * 4)
		BF = SF + (client ['gamelevel'] * 4)
		LF = client['lf'] + 10
		moved = client['moved']
		client ['team'] = team
		client ['bf'] = BF
		toteam ['players'].append ({'clinum' : cli, 'name' : NAME, 'sf' : SF,  'lf' : LF, 'level' : level, 'moved' : moved, 'bf' : BF})
		
		self.getGameInfo(**kwargs)

	def GetTeamLists (self, client, team):

		currentteam = client ['team']
		
		L = {'toteam' : '0', 'fromteam' : '0'}

		if (int(currentteam) == 1):
			L ['fromteam'] = self.teamOne
			L ['toteam'] = self.teamTwo
			return L
		if (int(currentteam) == 2):
			L ['fromteam'] = self.teamTwo
			L ['toteam'] = self.teamOne
			return L

		if (int(team) == 1):
			L ['toteam'] = self.teamOne
			
		if (int(team) == 2):
			L ['toteam'] = self.teamTwo
			
				
		return L
		#don't think I need this but I am leaving it in
		del L [0]

	def onTeamChange (self, *args, **kwargs):
		
		spec = -1
		team = int(args[1])
		cli = args[0]
		self.retrieveLevels(cli, **kwargs)
		client = self.getPlayerByClientNum(cli)
		currentteam = client ['team']
		prevented = int(client ['prevent'])
		teamlists = self.GetTeamLists(client, team)
		toteam = teamlists ['toteam']
		fromteam = teamlists ['fromteam']

		if (self.DENY == 1):
			self.DIFFERENCE = abs(self.evaluateBalance())
			diff = self.DIFFERENCE

		#check to see if the player is on a team and going to spectator. spec = -1 unless the player is already on a team
		if (int(team) == 0):
			spec = self.checkForSpectator(cli)
		#need to have this to avoid having players added multiple times as I have seen happen
		if (spec == -1) and (int(currentteam) == int(team)):
			
			return
		#if the player is switching teams, add them to the new team and remove from the old			
		if (spec == -1) and (int(currentteam) > 0):
			
			self.addTeamMember(client, toteam, team, **kwargs)
			self.removeTeamMember(client, fromteam, team, **kwargs)
		#if the player hasn't joined a team yet, go ahead and add them to the team	
		elif (spec == -1):
			self.addTeamMember(client, toteam, team, **kwargs)
			self.getGameInfo(**kwargs)
			#Players are prevented from joining in the deny phase if they will cause greater than a 10% stack
			#this applies to both even and uneven games. The player is forced back to team 0.
			if (self.DENY == 1):
				self.DIFFERENCE = abs(self.evaluateBalance())
				if (self.DIFFERENCE > self.JOINTHRESHOLD) and (self.DIFFERENCE > diff):
					action = 'PREVENT'
					self.retrieveIndex(client, action, **kwargs)
					return
				#There may be an issue if the player is forced back to team 0 that they can't join a team
				#even if conditions are met. This just forcibly puts the player on the team they are are trying to join
				#provided the above critera is not true.
				if (prevented == 1):
					action = 'ALLOW'
					self.retrieveIndex(client, action, **kwargs)
					
		#if the player is going to spec, just remove them from the team
		if (spec > -1):
			self.removeTeamMember(client, fromteam, team, **kwargs)
						
		self.OPTION = 0
						

	def onDisconnect(self, *args, **kwargs):
		
		cli = args[0]
		client = self.getPlayerByClientNum(cli)

		team = client ['team']

		if (int(team) > 0):

			teamlist = self.GetTeamLists(client, team)
			fromteam = teamlist ['fromteam']
			self.removeTeamMember(client, fromteam, team, **kwargs)
			
		#self.sendGameInfo(**kwargs)
		client ['active'] = 0

	def onCommResign(self, *args, **kwargs):
		name = args[0]
		
		client = self.getPlayerByName(name)
		team = client['team']
		cli = client['clinum']
		
		teamlist = self.GetTeamLists(client, team)
		fromteam = teamlist ['fromteam']
		item = 'clinum'
		PLAYER_INDICE = self.getTeamMember(item, cli, fromteam)
		
		fromteam['players'][PLAYER_INDICE]['bf'] = client['sf'] + (client['gamelevel']*4)
		#fromteam['players'][PLAYER_INDICE]['bf'] = int(client['sf'] + client['level'] + (client['gamelevel']*4))
		fromteam['players'][PLAYER_INDICE]['moved'] = 0
		
		client ['moved'] = 0	
		
		

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

		cli = args[0]
		client = self.getPlayerByClientNum(cli)
		team = client['team']
		teamlist = self.GetTeamLists(client, team)
		fromteam = teamlist ['fromteam']
		item = 'clinum'
		PLAYER_INDICE = self.getTeamMember(item, cli, fromteam)
		
		#fromteam['players'][PLAYER_INDICE]['bf'] = client ['lf']
		fromteam['players'][PLAYER_INDICE]['bf'] = fromteam['players'][PLAYER_INDICE]['lf']
		fromteam['players'][PLAYER_INDICE]['moved'] = 1
		#set moved to 1 to prevent the player from being auto-swapped as commander
		client['moved'] = 1
		
		

	def onPhaseChange(self, *args, **kwargs):
		phase = int(args[0])
		self.PHASE = phase
	
		if (phase == 7):
			self.onGameEnd(**kwargs)
		if (phase == 5):
			self.onGameStart(*args, **kwargs)
			self.PICKING = 0
		if (phase == 3):
			self.PICKING = 1
		if (phase == 6):
			self.onNewGame(*args, **kwargs)
			
		
	def onGameEnd(self, *args, **kwargs):
		
		avg1 = int(self.TOTAL1/self.STAMPS)
		avg2 = int(self.TOTAL2/self.STAMPS)
		print avg1, avg2, self.STAMPS
		kwargs['Broadcast'].broadcast("Serverchat ^cHow stacked was this game from start to finish? Humans had an average combined BF of ^r%s^c, Beasts had an average combined BF of ^r%s ^cfrom a total of ^y%s ^ctime points." % (avg1, avg2, self.STAMPS))
		#clear out the team dictionary info and globals when the map is reloaded
		del self.teamOne ['players'][:]
		del self.teamTwo ['players'][:]
		for player in self.playerlist:
			player ['active'] = 0
			player ['team'] = 0
			player ['gamelevel'] = 1
			player ['bf'] = int(player ['sf'] + player ['level'])
			player ['value'] = 150
		self.teamOne ['size'] = 0
		self.teamOne ['avgBF'] = -1
		self.teamOne ['combinedBF'] = 0
		self.teamTwo ['size'] = 0
		self.teamTwo ['avgBF'] = -1
		self.teamTwo ['combinedBF'] = 0
		self.GAMESTARTED = 0
		self.STARTSTAMP = 0
		self.DENY = 0
		self.OPTION = 0
		self.DIFFERENCE = -1
		self.PICKING = 0
		self.balancereport = []
		#self.playerlist = []		
		self.TOTAL1 = 0
		self.TOTAL2 = 0
		self.STAMPS = 0

	def onNewGame(self, *args, **kwargs):
		
		if (self.PICKING == 1):
			print 'team picking has begun, do not clear team player lists'
			kwargs['Broadcast'].broadcast("echo team picking has begun, do not clear team player lists!")
			
			self.PICKING = 0
			return

		
		#clear out the team dictionary info and globals when the map is reloaded
		del self.teamOne ['players'][:]
		del self.teamTwo ['players'][:]
		for player in self.playerlist:
			player ['active'] = 0
			player ['team'] = 0
			player ['gamelevel'] = 1
			player ['bf'] = int(player ['sf'] + player ['level'])
			player ['value'] = 150
		self.teamOne ['size'] = 0
		self.teamOne ['avgBF'] = -1
		self.teamOne ['combinedBF'] = 0
		self.teamTwo ['size'] = 0
		self.teamTwo ['avgBF'] = -1
		self.teamTwo ['combinedBF'] = 0
		self.GAMESTARTED = 0
		self.STARTSTAMP = 0
		self.DENY = 0
		self.OPTION = 0
		self.DIFFERENCE = -1
					

		self.RegisterScripts(**kwargs)

	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")
		#this makes sure we get an update every thirty seconds.
		kwargs['Broadcast'].broadcast("set sv_statusNotifyTime 30000")
		

	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 retrieveIndex(self, mover, action, **kwargs):
		#Use this for any manipulations when you need to get the current player index from the server. This is used for MOVE, PREVENT, ALLOW
		cli = mover['clinum']
		client = self.getPlayerByClientNum(cli)
		kwargs['Broadcast'].broadcast("set _value #GetIndexFromClientNum(%s)#; echo Sv: Client %s index is #_value#. ACTION: %s" % (cli, cli, action))

	def onRetrieveIndex(self, *args, **kwargs):
		#get stuff from parser
		clinum = args[0]
		index = args[1]
		action = args[2]
		if (action == 'MOVE'):
			self.move(clinum, index, **kwargs)
		if (action == 'PREVENT'):
			self.prevent(clinum, index, **kwargs)
		if (action == 'ALLOW'):
			self.allow(clinum, index, **kwargs)
		if (action == 'LEVEL'):
			self.level(clinum, index, **kwargs)

	def runBalancer (self, **kwargs):
		#determines if it is even or uneven balancer
		#3-23-11 - If there are fewer than 8 players, don't bother with balancer
		if (self.teamOne['size'] + self.teamTwo['size']) < 8:
			return
		
		diff = self.teamOne['size'] - self.teamTwo['size']
		print diff
		if (diff == 0):
			self.EvenTeamBalancer(**kwargs)
		#uneven balancer if there is a difference between 1-3. if it more than that, it would be best to restart, but that has not been implemented
		elif (abs(diff) > 0 and abs(diff) < 4):
			
			self.UnEvenTeamBalancer(**kwargs)
			
		else:
			return

	def onGameStart (self, *args, **kwargs):
		
		self.ItemList()
		self.STARTSTAMP = args[1]
		self.GAMESTARTED = 1
		kwargs['Broadcast'].broadcast("echo GAMESTARTED")

		self.sendGameInfo(**kwargs)
		
		
		kwargs['Broadcast'].broadcast("ServerChat ^cIf necessary, the teams will be auto-balanced at 1, 3, and 6 minutes of game time.")
		kwargs['Broadcast'].broadcast("ServerChat ^cAfter 6 minutes, joining will be limited to players that do not generate imbalance.")
		kwargs['Broadcast'].broadcast("ServerChat ^cAt 5 minute increments starting at minute 10, the server will check for imbalance and notify players that they will be switched in one minute unless they reject the move.")
		kwargs['Broadcast'].broadcast("ServerChat ^cSelected players may send the message 'reject' to ^bALL ^cchat to prevent the change.")
		
		self.RegisterScripts(**kwargs)
		self.startFollow(**kwargs)

	
	def onServerStatus(self, *args, **kwargs):
		CURRENTSTAMP = int(args[1])
		self.TIME = int(CURRENTSTAMP) - int(self.STARTSTAMP)
		#self.getTeamLevels(**kwargs)
		kwargs['Broadcast'].broadcast("set _team1num #GetNumClients(1)#; set _team2num #GetNumClients(2)#; echo SERVER-SIDE client count, Team 1 #_team1num#, Team 2 #_team2num#")
		
		if (self.GAMESTARTED == 1):
			self.TOTAL1 += self.teamOne['combinedBF']
			self.TOTAL2 += self.teamTwo['combinedBF']
			self.STAMPS += 1

	def evaluateBalance(self, BF1=0.0, BF2=0.0, moving=False, **kwargs):
		large = self.getLargeTeam()
		small = self.getSmallTeam()
		largebf = float(large ['combinedBF'])
		smallbf = float(small ['combinedBF'])
		totalbf = largebf + smallbf
		largeshare = (largebf - BF1 + BF2) / totalbf
		smallshare = (smallbf + BF1 - BF2) / totalbf
		largesize = float(large ['size'])
		smallsize = float(small ['size'])
		totalsize = largesize + smallsize
		if moving:
			largesize = float(large ['size']) - 1.0
			smallsize = float(small ['size']) + 1.0
		
		sizediff = largesize / totalsize
		largepercent = largeshare
		#largepercent = largeshare + sizediff
		return (largepercent - 0.5) * 100
		#return (largepercent - 1) * 100
 
	def getClosestPersonToTarget (self, team, **kwargs):
		
		lowest = -1
		pick = None
		
		
		for player1 in team ['players']:

			if (player1['moved'] == 1):
				continue

			
			ltarget = abs(self.evaluateBalance (float(player1 ['bf']), 0.0, True))
			print ltarget
			if (lowest < 0):
				lowest = ltarget
				# wouldn't work if the first player was the one to pick, so had to do this here
				pick = player1
				continue
			
			if (lowest < ltarget):
				continue
			
			lowest = ltarget
			pick = player1
		
		print pick

		if (pick == None):
			kwargs['Broadcast'].broadcast("echo BALANCER: UNEVEN balancer was not happy for some reason I can't figure out")
			return

				
		kwargs['Broadcast'].broadcast("echo BALANCER: UNEVEN balancer selections: Client %s with bf %s for a starting BF stacking of %s to %s" % (pick['clinum'], pick['bf'], self.DIFFERENCE, lowest))
		#if the selected option doesn't actually improve anything, terminate
		if (lowest > self.DIFFERENCE):
			kwargs['Broadcast'].broadcast("echo BALANCER: unproductive UNEVEN balance")
			return

		if (self.OPTION == 0):	
			#get the player index and move them
			action = 'MOVE'
			self.retrieveIndex(pick, action, **kwargs)
			return
		
		if (self.OPTION == 1):
			self.switchlist.append ({'name' : pick ['name'], 'clinum' : pick ['clinum'], 'accept' : 0})
			print self.switchlist
			self.giveOption (**kwargs)
	
	
	def getClosestTwoToTarget (self, team1, team2, **kwargs):
		
		lowest = -1
		pick1 = None
		pick2 = None
		

		for player1 in team1 ['players']:
			if (player1['moved'] == 1):
				continue
			for player2 in team2 ['players']:

				if (player2['moved'] == 1):
					continue
				
				ltarget = abs(self.evaluateBalance (float(player1 ['bf']), float(player2 ['bf'])))
				
				if (lowest < 0):
					lowest = ltarget
					pick1 = player1
					pick2 = player2
					continue
			
				if (lowest < ltarget):
					continue
			
				lowest = ltarget
				pick1 = player1
				pick2 = player2

		
		print pick1, pick2


		kwargs['Broadcast'].broadcast("echo Balancer selections: Clients %s, %s with BF %s, %s." % (pick1['clinum'], pick2['clinum'], pick1['bf'], pick2['bf']))

		if (lowest >= self.DIFFERENCE):
			print 'unproductive balance. terminate'
			kwargs['Broadcast'].broadcast("echo unproductive EVEN balance")
			return

		if (self.OPTION == 0):
			action = 'MOVE'
			self.retrieveIndex(pick1, action, **kwargs)
			self.retrieveIndex(pick2, action, **kwargs)
			return

		if (self.OPTION == 1):
			self.switchlist.append ({'name' : pick1['name'], 'clinum' : pick1['clinum'], 'accept' : 0})
			self.switchlist.append ({'name' : pick2['name'], 'clinum' : pick2['clinum'], 'accept' : 0})
			print self.switchlist
			self.giveOption (**kwargs)
	
	def giveOption(self, **kwargs):
		
		index = -1
		playermessage = "^cYou have been selected to change teams to promote balance. You have one minute to REJECT this change by sending the message 'reject' to ^bALL ^cchat."
		for player in self.switchlist:
			index += 1
			kwargs['Broadcast'].broadcast("SendMessage %s %s" % (player['clinum'], playermessage))

		if (index == 0):
			kwargs['Broadcast'].broadcast("Serverchat ^cTeams are currently unbalanced. ^r%s ^chas been selected to improve balance. They will automatically switch teams in one minute unless they reject the move by sending the message 'reject' to ^bALL ^cchat, or another player joins." % (self.switchlist[0]['name']))
		else:
			kwargs['Broadcast'].broadcast("Serverchat ^cTeams are currently unbalanced. ^r%s ^cand ^r%s ^chave been selected to improve balance. They will automatically switch teams in one minute unless one of them rejects the move by sending the message 'reject' to ^bALL ^cchat, or another player joins." % (self.switchlist[0]['name'], self.switchlist[1]['name']))
		

	def onMessage(self, *args, **kwargs):
		
		name = args[1]
		message = args[2]
		
		client = self.getPlayerByName(name)
		
		if (args[0] == "SQUAD") and (message == 'report balance'):
			self.getGameInfo()
			kwargs['Broadcast'].broadcast("SendMessage %s Balance Report: ^yTeam 1 combined: ^g%s (%s players, %s BF average), ^yTeam 2 combined: ^g%s (%s players, %s BF average). ^yStack percentage: ^r%s. ^yCurrent Phase: ^c%s. ^yCurrent time stamp: ^c%s. ^yBalancer active = ^r%s" % (client['clinum'], self.teamOne ['combinedBF'], self.teamOne ['size'], self.teamOne ['avgBF'], self.teamTwo ['combinedBF'], self.teamTwo ['size'], self.teamTwo ['avgBF'], round(self.evaluateBalance(), 1), self.PHASE, self.TIME, self.GAMESTARTED))
			for moves in self.balancereport:
				kwargs['Broadcast'].broadcast("SendMessage %s BALANCER: Balanced move for: %s at time %s" % (client['clinum'],moves ['name'], moves ['time']))

		if (args[0] == "SQUAD") and (message == 'report team one'):
			
			for player in self.teamOne ['players']:
				kwargs['Broadcast'].broadcast("SendMessage %s Team One Report: Player: ^c%s ^rBF: ^y%s" % (client['clinum'], player['name'], player['bf']))

		if (args[0] == "SQUAD") and (message == 'report team two'):
			
			for player in self.teamTwo ['players']:
				kwargs['Broadcast'].broadcast("SendMessage %s Team Two Report: Player: ^c%s ^rBF: ^y%s" % (client['clinum'], player['name'], player['bf']))

		if (args[0] == "SQUAD") and (message == 'report playerlist'):
			
			for active in self.playerlist: 
				if (active ['active'] == 1):
					kwargs['Broadcast'].broadcast("SendMessage %s Active Player List: Player: ^c%s ^rSF: ^y%s" % (client['clinum'], active['name'], active['sf']))
		if (args[0] == "SQUAD") and (message == 'report version'):
			
			kwargs['Broadcast'].broadcast("SendMessage %s Balancer version: ^y%s" % (client['clinum'], self.VERSION))

								
		if args[0] != "ALL":
			return

		
		
		if re.match(".*tell\s+(?:me\s+)?(?:the\s+)?(?:SFs?|balance)(?:\W.*)?$", message, flags=re.IGNORECASE):
			tm = time.time()
			if (tm - self.CHAT_STAMP) < self.CHAT_INTERVAL:
				return
			self.CHAT_STAMP = tm
			return self.sendGameInfo(**kwargs)

		if (self.OPTION == 1) and (message == 'reject'):
			for player in self.switchlist:
				if (player['name'] == name):
					kwargs['Broadcast'].broadcast("ServerChat ^r%s ^chas rejected a move to promote balance between the teams." % (name))
					del self.switchlist[:]

		

	def optionCheck(self, **kwargs):
		if (self.OPTION == 1):
			for player in self.switchlist:
				action = 'MOVE'
				self.retrieveIndex(player, action, **kwargs)
		del self.switchlist[:]

	def move(self, clinum, index, **kwargs):
		
		client = self.getPlayerByClientNum(clinum)
		
		client ['moved'] = 1
		name = client ['name']
		#only have to move players that are already on a team, and since they can only go to the other team we can use this
		if (int(client['team']) == 1):
			newteam = 2
		else:
			newteam = 1

		kwargs['Broadcast'].broadcast("SetTeam %s %s" % (index, newteam))
		kwargs['Broadcast'].broadcast("Serverchat ^r%s ^chas switched teams to promote balance." % (name))
		kwargs['Broadcast'].broadcast("ResetAttributes %s" % (index))
		

		self.balancereport.append ({'time' : self.TIME, 'client' : name})
		
		self.moveNotify(clinum, **kwargs)

	def prevent(self, clinum, index, **kwargs):
		client = self.getPlayerByClientNum(clinum)
		client ['prevent'] = 1
		newteam = 0
		kwargs['Broadcast'].broadcast("SetTeam %s %s" % (index, newteam))

		self.preventNotify(clinum, **kwargs)

	def allow(self, clinum, index, **kwargs):
		client = self.getPlayerByClientNum(clinum)
		team = client ['team']
		kwargs['Broadcast'].broadcast("SetTeam %s %s" % (index, team))
		client ['prevent'] = 0

	def level(self, clinum, index, **kwargs):
		client = self.getPlayerByClientNum(clinum)
		team = client ['team']		
		kwargs['Broadcast'].broadcast("set _plevel #GetLevel(%s)#; set team%s_level [team%s_level + _plevel]" % (index, team, team))
		

	def moveNotify(self, clinum, **kwargs):
		#this lets the player know the have been moved and compensates them for their purchased items. There is current no way to know
		#how much gold a player holds, though I think gold may actually transfer. Not 100% sure.
		client = self.getPlayerByClientNum(clinum)

		value = client ['value']

		kwargs['Broadcast'].broadcast("SendMessage %s ^cYou have automatically switched teams to promote balance." % (clinum))
		kwargs['Broadcast'].broadcast("SendMessage %s ^cYou have been compensated ^g%s ^cgold for your non-consumable items and your attributes have been reset." % (clinum, value))
		kwargs['Broadcast'].broadcast("GiveGold %s %s" % (clinum, value))
	

		client ['value'] = 0

	def preventNotify(self, clinum, **kwargs):
		kwargs['Broadcast'].broadcast("SendMessage %s ^cYou cannot join that team as it will create imbalance. Please wait for another player to join or leave." % (clinum))

	def getSmallTeam (self):
		#writing these all out explicitly because I was having trouble with them
		if (self.teamOne ['size'] < self.teamTwo ['size']):
			return self.teamOne
		if (self.teamTwo ['size'] < self.teamOne ['size']):
			return self.teamTwo
		if (self.teamTwo ['size'] == self.teamOne ['size']):
			return self.teamTwo

	def getLargeTeam (self):
		#writing these all out explicitly because I was having trouble with them
		if (self.teamOne ['size'] > self.teamTwo ['size']):
			return self.teamOne
		if (self.teamTwo ['size'] > self.teamOne ['size']):
			return self.teamTwo
		if (self.teamTwo ['size'] == self.teamOne ['size']):
			return self.teamOne

	def getHighTeam (self):
		if (self.teamOne ['avgBF'] > self.teamTwo ['avgBF']):
			return self.teamOne
		return self.teamTwo

	def getLowTeam (self):
		if (self.teamOne ['avgBF'] > self.teamTwo ['avgBF']):
			return self.teamTwo
		return self.teamOne

	def getTeamOne (self):
		return self.teamOne

	def getTeamTwo (self):
		return self.teamTwo

	def getTeamAvg (self, team):
		#this updates the info for a team
		
		team ['combinedBF'] = 0
		team ['size'] = 0
		for clients in team ['players']:
			team ['combinedBF'] += clients ['bf']
			team ['size'] += 1
		if (team ['size'] > 0):
			team ['avgBF'] = (team ['combinedBF'] / team ['size'])
		else:
			team ['avgBF'] = 0

	def getGameInfo (self, **kwargs):

		self.getTeamAvg (self.teamOne)
		self.getTeamAvg (self.teamTwo)
		self.game ['size'] = (self.teamOne ['size'] + self.teamTwo ['size'])
		self.game ['avgBF'] = ((self.teamOne ['avgBF'] +  self.teamTwo ['avgBF']) / 2)

		

	def sendGameInfo (self, **kwargs):
		self.getGameInfo(**kwargs)

		if (self.GAMESTARTED == 1):
			self.DIFFERENCE = abs(self.evaluateBalance())
			
		if self.GAMESTARTED == 1:
			kwargs['Broadcast'].broadcast("ServerChat ^cCurrent balance: ^yTeam 1 Avg. BF: ^g%s (%s players), ^yTeam 2 Avg. BF: ^g%s (%s players). Stack percentage: ^r%s" % (self.teamOne ['avgBF'], self.teamOne ['size'], self.teamTwo ['avgBF'], self.teamTwo ['size'], round(self.DIFFERENCE, 1) ))
			

	def EvenTeamBalancer(self, **kwargs):
		self.getGameInfo(**kwargs)
		#added these to prevent any moves if there is an error in BF calculation that has sprung up on occasion
		for clients in self.teamOne['players']:
			if clients['bf'] > 1000:
				kwargs['Broadcast'].broadcast("echo refresh")
				return
		for clients in self.teamTwo['players']:
			if clients['bf'] > 1000:
				kwargs['Broadcast'].broadcast("echo refresh")
				return

		self.DIFFERENCE = abs(self.evaluateBalance())
		print(self.DIFFERENCE)

		if (self.DIFFERENCE > self.THRESHOLD):
			self.getClosestTwoToTarget (self.getLargeTeam (), self.getSmallTeam (),  **kwargs)
		else:
			
			kwargs['Broadcast'].broadcast("Serverchat ^cEven team balancer initiated but current balance percentage of ^y%s ^cdoes not meet the threshold of ^y%s" % (round(self.DIFFERENCE, 1), self.THRESHOLD))

	def UnEvenTeamBalancer(self, **kwargs):
		self.getGameInfo(**kwargs)
		#added these to prevent any moves if there is an error in BF calculation that has sprung up on occasion
		for clients in self.teamOne['players']:
			if clients['bf'] > 1000:
				kwargs['Broadcast'].broadcast("echo refresh")
				return
		for clients in self.teamTwo['players']:
			if clients['bf'] > 1000:
				kwargs['Broadcast'].broadcast("echo refresh")
				return		

		overcheck = self.evaluateBalance()
		self.DIFFERENCE = abs(self.evaluateBalance())
		#In this scenario, the larger team has a much lower BF, so do a player swap instead of a single move.
		if (overcheck < 0) and (self.DIFFERENCE > self.THRESHOLD):
			self.getClosestTwoToTarget (self.getLargeTeam (), self.getSmallTeam (), **kwargs)
			kwargs['Broadcast'].broadcast("echo BALANCER: ^cUneven team balancer with swap initiated")
			return
		#In this scenario, the larger team has greater BF, so do a single mvoe.
		if (overcheck > 0) and (self.DIFFERENCE > self.THRESHOLD):
			self.getClosestPersonToTarget (self.getLargeTeam (), **kwargs)
		else:
			print 'threshold not met'
			kwargs['Broadcast'].broadcast("Serverchat ^cUneven team balancer initiated, but current balance percentage of ^y%s ^cdoes not meet the threshold of ^y%s" % (round(self.DIFFERENCE, 1), self.THRESHOLD))

	def onTeamCheck(self, *args, **kwargs):
		if (self.TIME % (60 * 1000)) == 0:				
			self.sendGameInfo(**kwargs)
					
		if (self.teamOne ['size'] == int(args[0])) and (self.teamTwo ['size'] == int(args[1])):
			kwargs['Broadcast'].broadcast("echo BALANCER: Team 1 count is correct")
			kwargs['Broadcast'].broadcast("echo BALANCER: Team 2 count is correct")
		
			if (self.PHASE == 5):

				self.GAMESTARTED = 1
				
				if (self.TIME == (1 * 60 * 1000)):
					self.runBalancer (**kwargs)
				elif (self.TIME == (3 * 60 * 1000)):
					self.runBalancer (**kwargs)
				elif (self.TIME == (6 * 60 * 1000)):
					self.runBalancer (**kwargs)
				if (self.TIME >= (6 * 60 * 1000)):
					self.DENY = 1
					self.optionCheck(**kwargs)
					self.OPTION = 1
				
					if (self.TIME % (5 * 60 * 1000)) == 0:
						self.runBalancer (**kwargs)
			return
		else:
			#kwargs['Broadcast'].broadcast("Serverchat ^cBalancer is currently off until player counts can be verified.")
			kwargs['Broadcast'].broadcast("ListClients")
			kwargs['Broadcast'].broadcast("echo refresh")
			#this initiates turns balancer off and tries to refresh the teams to get the proper count
			self.GAMESTARTED = 0
			self.DENY = 0

	def retrieveLevels(self, cli, **kwargs):

		kwargs['Broadcast'].broadcast("set _index #GetIndexFromClientNum(%s)#; set _plevel #GetLevel(|#_index|#)#;echo CLIENT %s is LEVEL #_plevel#; set _plevel 1" % (cli, cli))
		

	def getTeamLevels(self, **kwargs):
	
		if (self.GAMESTARTED == 1):
					
			for player1 in self.teamOne ['players']:
				self.retrieveLevels(player1 ['clinum'], **kwargs)
			for player2 in self.teamTwo ['players']:
				self.retrieveLevels(player2 ['clinum'], **kwargs)
				
			
	def onGetLevels(self, *args, **kwargs):
		clinum = args[0]
		level = int(args[1])
		client = self.getPlayerByClientNum(clinum)
		client ['gamelevel'] = level
		client ['bf'] = client ['sf'] + client ['level'] + (4*level)
		if (client ['team'] == 1):
			for player in self.teamOne ['players']:
				if client ['clinum'] == player ['clinum']:
					player ['bf'] = client ['bf']
		if (client ['team'] == 2):
			for player in self.teamTwo ['players']:
				if client ['clinum'] == player ['clinum']:
					player ['bf'] = client ['bf']

	def onListClients(self, *args, **kwargs):
		clinum = args[0]
		name = args[2]
		print 'making client active'
		client = self.getPlayerByName(name)
		client ['active'] = 1

	def onMapReset(self, *args, **kwargs):
		if (self.PHASE == 5):
			kwargs['Broadcast'].broadcast("prevphase")
			self.GAMESTARTED = 0
		else:
			return

	def startFollow(self, **kwargs):
		
		for followings in self.followlist:
			kwargs['Broadcast'].broadcast("set _follower #GetIndexFromClientNum(%s)#; set _followed #GetIndexFromClientNum(%s)#; set _x #GetPosX(|#_followed|#)#; set _y #GetPosY(|#_followed|#)#; set _z #GetPosZ(|#_followed|#)#; SetPosition #_follower# [_x + 200] [_y + 200] [_z + 200]" % (followings ['follower'], followings ['followed']))