示例#1
0
文件: utils.py 项目: mrozekma/spades
def getPlayerColor(username):
	shimmed = Shim.onPlayerColor(username)
	if shimmed is None:
		bgHex = hex(hash(username))[2:][-6:].zfill(6) # Strip the 0x prefix and take the last 6 characters (if there aren't enough, left-pad with 0s)
		r, g, b = int(bgHex[0:2], 16), int(bgHex[2:4], 16), int(bgHex[4:6], 16)
		if getBrightness(r, g, b) > 230:
			return getPlayerColor(username + '-')
	else:
		r, g, b = shimmed
	return r, g, b
示例#2
0
	def tick(self):
		if self.gameCon is None:
			# Get list of logs (['YYYY-mm-dd_HHMMSS.log'])
			# Unfortunately the server doesn't return an etag for this page; instead we cache based on the number of logs displayed, on the assumption that logs will never be removed
			req = requests.get(logURL)
			if req.status_code != 200:
				raise RuntimeError("Server returned %d looking up log list" % req.status_code)
			logs = map(str, lxml.html.fromstring(req.text).xpath('//a[substring-after(@href, ".")="log"]/@href'))
			logs = filter(None, map(Shim.onLogLoad, logs))

			numGames = len(getGames())
			if len(logs) < numGames:
				raise RuntimeError("Only got %d %s from server (have %d in database)" % (len(logs), 'log' if len(logs) == 1 else 'logs', numGames))
			elif len(logs) == numGames: # No new logs
				return

			# Find the first one we don't have a game for
			for log in logs:
				if log not in db['games']:
					console('event thread', "Starting new game for %s" % log)
					self.gameCon = Shim.onGameCon(GameConstructor(log, self.onGameEnd))
					break
			else:
				console('event thread', "No games in progress")
				return

		# Look for new events in the current log
		data = self.cachedGet(logURL + self.gameCon.logFilename)
		if data is None: # Nothing new
			console('event thread', "No new data in %s" % self.gameCon.logFilename)
			return
		elif data is False: # Server is down. Hopefully temporarily; try again next tick
			console('event thread', "Failed to fetch data from %s" % self.gameCon.logFilename)
			return
		elif len(data) < self.gameCon.logOffset:
			raise RuntimeError("Fetched %d-byte log file %s, but next event expected at %d" % (len(data), self.gameCon.logFilename, self.gameCon.logOffset))
		while self.gameCon and self.gameCon.logOffset < len(data) and self.test != 0:
			line = data[self.gameCon.logOffset:data.index('\n', self.gameCon.logOffset)+1]
			print "%8d %s" % (self.gameCon.logOffset, line)
			originalLen = len(line)
			line = Shim.onLine(self.gameCon, self.gameCon.logOffset, unpretty(line))
			if line is None:
				self.gameCon.logOffset += originalLen
				continue
			# print "Searching for pattern at %s offset %d: %s" % (self.gameCon.logFilename, self.gameCon.logOffset, line)
			for pattern, fns in eventPatterns:
				match = pattern.match(line)
				if match:
					for fn in fns:
						g = match.groupdict() # Copy; the original match groupdict is not changed below
						# Bit of a hack. We want to rewrite any group that contains a PLAY, but there's no way to tell now. Currently all those groups are named 'play', so we only rewrite those
						if 'play' in g:
							g['play'] = unpretty(g['play'])
						# Same hack with USER
						for k in ('user', 'user1', 'user2'):
							if k in g:
								shimmed = Shim.onUsername(g[k])
								if shimmed != g[k]:
									self.gameCon.usernameShims[shimmed] = g[k]
									g[k] = shimmed
						tz = int(round((datetime.now() - datetime.utcnow()).total_seconds() / 3600))
						event = {'ts': datetime.strptime(g['ts'], '%Y-%m-%d %H:%M:%S') + timedelta(hours = tz), 'off': self.gameCon.logOffset}
						del g['ts']
						event.update(fn(**g))
						if self.test > 0:
							self.test -= 1
						event = Shim.onEvent(self.gameCon, self.gameCon.logOffset, event)
						if event is not None:
							self.gameCon.pump(event)
					# pump() may have triggered onGameEnd and killed the current gameCon
					if self.gameCon is not None:
						self.gameCon.logOffset += originalLen
					break
			else:
				raise RuntimeError("Unrecognized log line at %s:%d: %s" % (self.gameCon.logFilename, self.gameCon.logOffset, line))
		if hasattr(self.gameCon, 'game'):
			self.gameCon.game.out()
			WSSpadesHandler.on_game_change(self.gameCon.game)