Esempio n. 1
0
    def _emitLastState(self, zero_zero_bug=False):
        _players = self._lastState._players
        _reliable = False
        # no ragequit in here
        if len(_players) != 2:
            log.log(
                "[%s] DuelInfo::_emitLastState: len(_players) != 2 (%s)?" % (str(datetime.datetime.now()), _players)
            )
            return

        if zero_zero_bug:
            _currtime = self._lastState._currtime
            _timelimit = self._lastState._timelimit
            # if we were very close to the end use the scoreline as reliable
            if _currtime and _timelimit and cutepig.total_seconds(_timelimit - _currtime) < 5:
                _reliable = True
                # DEBUG
        _matchtime = self._lastState._matchtime if self._lastState._matchtime != None else "unknown"
        log.log(
            "[%s] DuelInfo: LAST SCORE %s - %s: %d - %d (%s)(%s)"
            % (
                str(datetime.datetime.now()),
                _players[0]._name,
                _players[1]._name,
                _players[0]._score,
                _players[1]._score,
                "reliable" if (_reliable) else "non reliable",
                _matchtime,
            )
        )

        self._emitAnyState(self._lastState, _reliable)
Esempio n. 2
0
	def __call__(self, msg):
		# get the current mem usage
		fp = open( '/proc/%d/statm' % self.pid, 'r' )
		statm = fp.read()
		fp.close()
		
		# all of this in pages
		# progSize, rssSize, sharedSize, codeSize, libSize, stackSize, dirtySize
		stats = statm.split()
		rssSize = int( stats[1] ) * self.pageSize
		
		log.log( '%s ( mem usage: %s )' % ( msg, self.prettyprint(rssSize)))
Esempio n. 3
0
	def __call__(self, *args):
		t = time.time()
		self.run(args)
		d = time.time() - t
		if(d > self._WARN_TIME):
			log.log("Task::__call__: execution time took %f seconds (%s)" % (d, self.__class__.__name__))
		
		self._event = None
		# TODO: check nextupdate and stuff
		# reschedule
		if( self._registered ) :
			self._insertJob()
Esempio n. 4
0
	def checkMasterQuery( self, query ) :
		# FIXME: add internal asynchronous timeout to support nonblocking sockets!
		# this relying on timeout dont work well in new pigbrowser taskmanager..
		try :
			r, addr = cutepig.net.getResponse2 ( query.socket )
			if( not r and not addr ) :
				return False
			query.incoming += len ( r )
			if ( addr != query.addr ) :
				log.log( "Warning: getting response2 from different address??" )
				return False
			
			ofs = self.checkMasterResponse ( r )
			if ( ofs == -1 ) :
				log.log( "Malicious packet from master %s" % ( cutepig.ip_int_str_full(query,addr) ) )
				query.error = True
				return True
				
			# master server query stores the ip's in the buffer directly
			ips = self.parseMasterResponse ( r[ofs:] )
			if ( not len(ips) ) :
				log.log( "Empty ip list from master %s %s" % ( cutepig.ip_int_str_full(query.addr), r ) )
				return True	# dont take as error?
				
			else :
				# log.log( "Read %d ips (last %s)" % (len(ips), ips[-1]) )
				query.buffers.extend ( ips )
				
		except socket.timeout :
			if ( not len(query.buffers) ) :
				log.log( "Master server %s timeouted" % ( cutepig.ip_int_str_full(query.addr) ) )
				
			return True	# we can stop now (quake specific: timeout=no more data)
			
		return False	# keep going badass
Esempio n. 5
0
	def __call__(self, addr ):
		if( not self.geo ) :
			return ( 'ZZ', 'ZZ' )
		
		loc = self.geo.country_code_by_addr ( ip_int_str (addr) )
		if ( loc not in cutepig.continents.countries ) :
			# theres the occasional bug where we get the continent for
			# the country so should we check that out in here?
			log.log( "geolocator: %s not found in continents" % loc )
			loc = 'ZZ'
			cont = 'ZZ'
		else :
			cont = cutepig.continents.countries[loc]
			
		return ( loc, cont )
Esempio n. 6
0
	def checkServerQuery ( self, query ) :
		try :
			r, addr = cutepig.net.getResponse2 ( query.socket )
		except :
			return True
		if( not r and not addr ) :
			return False
		query.incoming += len ( r )
		if ( addr != query.addr ) :
			log.log( "Warning: getting response2 from different address??" )
			return False
	
		# quake doesnt need no stinking stages
		query.buffers.append ( r )
		return True
Esempio n. 7
0
	def getRules ( self, rulestr ) :
	
		# the "rulestring" is divided with backward-slashes
		# and they are just key-value pairs, there should
		# be even amount of these
		
		split = rulestr.split ( '\\' )
		
		# now its list of [ key, value, key, value.. ]
		if ( len(split) & 1 ) :
			log.log( "uneven amount in rules?" )
			
		# key\\value\\key\\value[0x0a]
		rules = {}
		for i in range(0,len(split),2 ) :
			rules[split[i].lower()] = self.string(split[i+1])
			
		return rules
Esempio n. 8
0
    def processInfo(self, info):
        # SWAP NEW/OLD STATE
        self._lastState = self._currentState
        if not self._currentState:
            self._currentState = DuelState(self, info)
            if len(self._currentState._players) == 2:
                log.log(
                    "[%s] Starting to follow %s - %s"
                    % (
                        str(datetime.datetime.now()),
                        self._currentState._players[0]._name,
                        self._currentState._players[1]._name,
                    )
                )
        else:
            self._currentState = DuelState(self, info)

            # DO STUFF.. LOGIC..
        if not self._currentState.isValid():
            # num timeouts/errors?
            # do what? use lastState?
            self._dropSelf("NOT VALID")
            return

        if self._currentState.checkFinished(self._lastState):
            self._emitCurrentState()
            self._dropSelf("FINISHED")
            return

        if self._currentState.checkNewGame(self._lastState):
            self._emitLastState()
            self._dropSelf("NEW GAME")
            return

            # DEBUG inform score here
        _players = self._currentState._players
        # log.log("[%s] Intermediate score %s - %s: %d - %d @ %s" % (str(datetime.datetime.now()),
        # 	_players[0]._name, _players[1]._name, _players[0]._score,_players[1]._score, self._currentState._matchtime))

        # schedule next update, minimum interval 1 second, max 30
        delta = self._currentState.getRemainingSeconds() * 0.8
        delta = min(30.0, max(1.0, delta))
        self.setNextUpdate(self.time() + delta)
Esempio n. 9
0
    def run(self, args):
        if not self._query.checkServerQuery():
            # no data, schedule a new update and wait for it
            self.setNextUpdate(self.time() + self.QUERY_UPDATE_INTERVAL)
            return

            # ok, get the info, nullify the query and socket
        info = self._query.finishServerQuery()
        self._query = None
        self._socket.close()
        self._socket = None

        self.removeSelf()
        self._pusher.serverinfoStopped(self)

        # emit the serverinfo to database
        _serverinfo = self._emitServerInfo(info)

        # here, check if we have valid duel going on, if so pass it back to app
        # which will initiate new duelinfofetcher process
        if _serverinfo.numplayers == 2 and _serverinfo.flags != FLAG_TIMEOUT:
            self._app.checkActiveDuel(info)
        else:
            pass
            # log.log("not checking active duel (%s)" % ("numplayers" if _serverinfo.numplayers!=2 else "timeout"))

        return

        # comment out above return to print this
        if "timeout" in info:
            log.log("serverinfo finished %s (timeout)" % (ip_int_str_full(self._ip)))
        elif "error" in info:
            log.log("serverinfo finished %s (error)" % (ip_int_str_full(self._ip)))
        else:
            log.log("serverinfo finished %s" % (ip_int_str_full(self._ip)))
Esempio n. 10
0
	def finishServerQuery ( self, query ) :
		# do the parsing thing
		if ( len(query.buffers) ) :
			ofs = self.checkServerResponse ( query.buffers[0], query.isfull )
			if ( ofs == -1 ) :
				log.log( "getInfos, malicious packet from %s" % ( ip_int_str_full(query.addr) ) )
				# if ( not return_timeouts ) :
				#	return None
				info = { 'addr' : query.addr, 'error' : 1 }
				return info	# or None

			i = self.parseServerResponse ( query.buffers[0][ofs:], query.isfull )
			if ( i ) :
				i['addr'] = query.addr
				# if ( query.gametype and query.gametype != i['gt'] ) :
				#	return None
				
			return i
			
		else :
			info = { 'addr' : query.addr, 'timeout' : 1 }
			return info # or None
Esempio n. 11
0
    def fromDict(self, d):
        # TODO: clamp the names to their maximum sizes
        # Theres sometimes strange excessive amounts of whitespace
        # in some server names.. please remove them!!

        # DEBUG:
        if not "rules" in d:
            log.log("NO RULES IN: %s" % d)

            # ch : added strip..
        name = d["name"].strip()
        self.name = name[0:128]  # 128
        self.mapname = d["map"][0:32]  # 32
        self.maxclients = d["maxp"]  # actually the number of ckueb
        self.gamename = d["mod"][0:32]  # 32
        self.flags = d["flags"]

        # ch : added sortname, only alphabetical characters
        pattern = re.compile("[\W_]+")
        self.sortname = pattern.sub("", name)

        if "rules" in d and "sv_skilllevel" in d["rules"]:
            self.skilllevel = d["rules"]["sv_skilllevel"]
        else:
            self.skilllevel = -1

            # TODO: return qi + players

            # the number of players is # of in-game players
            # not the spectators
        n = 0
        if "players" in d:
            for pl in d["players"]:
                if pl["team"] > 1:
                    n += 1

        self.numplayers = n
        self.numspecs = d["nump"] - n
Esempio n. 12
0
	def parseServerResponse ( self, buf, isfull ) :
		ls = buf.split ( '\x0a' )
		if ( len(ls) < 1 ) :
			log.log( 'empty server response??\n%s' % buf )
			return None
			
		rules = self.getRules ( ls[0] )
		
		players = []
		# number score time ping "name" "skin" color1 color2
		if (isfull and len(ls) > 1 ) :
			for player in ls[1:] :
				player = player.strip()
				if ( len(player) <= 1 ) :
					continue
				d = self.parsePlayer ( player )
				if ( d ) :
					players.append ( d )
		
		if ( isfull ) :
			return self.fullInfo ( rules, players )
		else :
			return self.quickInfo ( rules )
Esempio n. 13
0
	def isReliable(self):
		if(self._matchtime != 'finished'):
			log.log("DuelState::isReliable: matchtime")
			return False
		# check the score line for 0-0 bug
		if(len(self._players) != 2 ):
			log.log("DuelState::isReliable: len(players) != 2 (%d)" % (len(self._players)))
			return False
		if(self._players[0]._score == 0 and self._players[1]._score == 0):
			log.log("DuelState::isReliable: 0-0 bug")
			return False
	
		# hmm, what else	
		return True
Esempio n. 14
0
	def checkNewGame(self, last):
		if(not last):
			return False
		# first validate that the last state had a matchtime
		if(not last._currtime):
			return False
		if(last._matchtime in ['countdown', 'warmup','finished']):
			return False
		# ok, lets check if current time is something else
		if(self._matchtime in ['countdown', 'warmup']):
			log.log("DuelState::checkNewGame: matchtime @ %s" % self._matchtime)
			return True
		if(not self._currtime):
			log.log("DuelState::checkNewGame: currtime null")
			return True
		if(self._currtime < last._currtime):
			# overtime logic
			if(not self._overtime):
				log.log("DuelState::checkNewGame: currtime smaller %s %s" % (self._currtime, last._currtime))
				return True
		return False
Esempio n. 15
0
    def _emitCurrentState(self):
        _players = self._currentState._players
        _reliable = self._currentState.isReliable()
        _ragequit = self._currentState.checkRagequit(self._lastState)
        if _ragequit:
            # _players.append(_ragequit)
            _reliable = False
            log.log("** RAGEQUIT: %s" % (_ragequit._name))
        if not _reliable:
            zero_zero_bug = False
            if len(_players) == 2 and _players[0]._score == 0 and _players[1]._score == 0:
                zero_zero_bug = True
            self._emitLastState(zero_zero_bug)
            return

        if len(_players) != 2:
            log.log(
                "[%s] DuelInfo::_emitCurrentState: len(_players) != 2 (%s)?" % (str(datetime.datetime.now()), _players)
            )
            return

            # fix the overtime flag from laststate
        if self._lastState:
            self._currentState._overtime = self._lastState._overtime

            # DEBUG
        log.log(
            "[%s] DuelInfo: FINAL SCORE %s - %s: %d - %d (%s)"
            % (
                str(datetime.datetime.now()),
                _players[0]._name,
                _players[1]._name,
                _players[0]._score,
                _players[1]._score,
                "reliable" if (_reliable) else "non reliable",
            )
        )

        self._emitAnyState(self._currentState, _reliable)
Esempio n. 16
0
	def duelStopped(self, duel):
		if(duel in self._activeServers):
			self._activeServers.remove(duel)
		else:
			log.log("Application::duelStopped: job not in the list")
Esempio n. 17
0
	def __call__(self, s):
		endTime = datetime.datetime.now()
		log.log( "%s ( time %s )" % ( s, (endTime - self.startTime)))
Esempio n. 18
0
 def _dropSelf(self, msg=None):
     self._app.duelStopped(self)
     self.removeSelf()
     if msg:
         log.log("[%s] DuelInfo dropped: %s" % (str(datetime.datetime.now()), msg))
Esempio n. 19
0
	def __init__(self, s):
		self.startTime = datetime.datetime.now()
		log.log( "%s - %s" % ( self.startTime, s ) )