Пример #1
0
def createGame(the_players, templateID, tourney_id):
	"""This calls the WarLight.net API to create a game, and then creates the Game and GamePlayer rows in the local DB"""
	gameName = ' vs '.join([p.name for p in the_players])[:50]  #game names are limited to %) characters by the api

	config = main.getClotConfig(tourney_id)
	apiRetStr = main.postToApi('/API/CreateGame', json.dumps( { 
															 'hostEmail': config.adminEmail, 
															 'hostAPIToken': config.adminApiToken,
															 'templateID': templateID,
															 'gameName': gameName,
															 'personalMessage': 'a game from one of unknwonsoldiers tourneys',
															 'players': [ { 'token': p.inviteToken, 'team': 'None' } for p in the_players]
															 }))
	apiRet = json.loads(apiRetStr)

	gid = int(apiRet.get('gameID', -1))
	if gid == -1:
		raise Exception("CreateGame returned error: " + apiRet.get('error', apiRetStr))

	g = Game(wlnetGameID=gid, name=gameName, tourney_id=tourney_id)
	g.save()

	for p in the_players:
		gameplayer = games.GamePlayer(playerID = p.key().id(), gameID = g.key().id(), tourney_id=tourney_id)
		gameplayer.save()

	logging.info("Created game " + str(g.key().id()) + " '" + gameName + "'")

	return g
Пример #2
0
def createGame(request, container, players, templateID):
  """This calls the WarLight.net API to create a game, and then creates the Game rows in the local DB"""
  gameName = ' vs '.join([p.name for p in players])[:50]

  config = getClotConfig()
  apiRetStr = postToApi('/API/CreateGame', json.dumps( { 
                               'hostEmail': config.adminEmail, 
                               'hostAPIToken': config.adminApiToken,
                               'templateID': templateID,
                               'gameName': gameName,
                               'personalMessage': 'Created by the CLOT at http://' + urlparse.urlparse(request.url).netloc,
                               'players': [ { 'token': p.inviteToken, 'team': 'None' } for p in players]
                               }))
  apiRet = json.loads(apiRetStr)

  gid = long(apiRet.get('gameID', -1))
  if gid == -1:
    raise Exception("CreateGame returned error: " + apiRet.get('error', apiRetStr))

  g = Game(lotID=container.lot.key.id(), wlnetGameID=gid, name=gameName)
  g.players = [p.key.id() for p in players]
  g.put()

  #Ensure we update the container with the new game.  The players may already be there, but put them in in case they're not
  container.games.append(g)
  for p in players:
    container.players[p.key.id()] = p

  logging.info("Created game " + str(g.key.id()) + " '" + gameName + "', wlnetGameID=" + str(gid))

  return g
Пример #3
0
 def get(self):
   
     cache = memcache.get('home')
     #if cache is not None:
     #    return self.response.write(cache)
     
     #Check if we need to do first-time setup
     if getClotConfig() is None:
         return self.redirect('/setup')
     
     html = get_template('home.html').render({ 'lots': list(lot.LOT.query()) })
     
     if not memcache.add('home', html):
         logging.info("Memcache add failed")
     
     self.response.write(html)
Пример #4
0
    def get(self):

        cache = memcache.get('home')
        #if cache is not None:
        #    return self.response.write(cache)

        #Check if we need to do first-time setup
        if getClotConfig() is None:
            return self.redirect('/setup')

        html = get_template('home.html').render(
            {'lots': list(lot.LOT.query())})

        if not memcache.add('home', html):
            logging.info("Memcache add failed")

        self.response.write(html)
Пример #5
0
def go(request, tourney_id, playerID):
	tourney_id = int(tourney_id)
	tourney_clotconfig = main.getClotConfig(tourney_id)
	playerID = int(playerID)
	p = players.Player.get_by_id(playerID)
	gameIDs = set([g.gameID for g in games.GamePlayer.all().filter("tourney_id =", int(tourney_id)).filter('playerID =', playerID)]) ###.run(batch_size=1000)])
	the_games = [g for g in games.Game.all() if g.key().id() in gameIDs]

	if not main.doesTourneyExist(tourney_id, tourney_clotconfig):
		logging.info('tourney does not exist')
		return shortcuts.render_to_response('tourney_does_not_exist.html')
	
	
		return shortcuts.render_to_response('player_does_not_exist_in_this_tourney.html')

	return shortcuts.render_to_response('viewplayer.html', {'player': p, 'games': the_games, 'tourney_id': tourney_id, 
	'tourney_name': main.getTourneyName(int(tourney_id), tourney_clotconfig),
	'tourney_path': '/tourneys/' + str(tourney_id)
	})
Пример #6
0
def go(request):
	"""Create a player.	GET shows a blank form, POST processes it."""
	logging.info('in join.go')

	form = JoinForm(data=request.POST or None)

	#now deal with the form etc

	if not request.POST:
		return shortcuts.render_to_response('join.html', {'form': form})

	if not form.is_valid():
		return shortcuts.render_to_response('join.html', {'form': form})

	#see if we are letting more players join.
	tourney_id = int(form.clean_data['tourney_id'])
	tourney_clotconfig = main.getClotConfig(tourney_id)#.run(batch_size=1000)
	if not tourney_clotconfig:
		form.errors['tourney_id'] = 'tourney_id is invalid.'
		return shortcuts.render_to_response('join.html', {'form': form})
	
	players_are_gated_q = False
	if main.arePlayersGated(tourney_id, tourney_clotconfig):
		players_are_gated_q = True
		logging.info('players_are_gated_q = '+str(players_are_gated_q))
		return http.HttpResponseRedirect('/players_are_gated')

	if players.numPlayersParticipating(tourney_id) >= main.getMaximumNumberOfPlayers(tourney_id, tourney_clotconfig):
		logging.info('too many players')
		return http.HttpResponseRedirect('/cannot_join') 


	inviteToken = form.clean_data['inviteToken']

	#Call the warlight API to get the name, color, and verify that the invite token is correct
	apiret = main.hitapi('/API/ValidateInviteToken', { 'Token':  inviteToken })

	if not "tokenIsValid" in apiret:
		form.errors['inviteToken'] = 'The supplied invite token is invalid. Please ensure you copied it from WarLight.net correctly.'
		return shortcuts.render_to_response('join.html', {'form': form})

	tourney_password = str(form.clean_data['tourney_password'])
	if main.getIfRequirePasswordToJoin(tourney_id, tourney_clotconfig):
		if tourney_password != main.getTourneyPassword(tourney_id, tourney_clotconfig):
			form.errors['tourney_password'] = '******'
			return shortcuts.render_to_response('join.html', {'form': form})

	#Ensure this invite token doesn't already exist
	existing = players.Player.all().filter('inviteToken =', inviteToken).filter("tourney_id =", tourney_id).get()
	if existing:
		#If someone tries to join when they're already in the DB, just set their isParticipating flag back to true
		existing.isParticipating = True
		existing.save()
		return http.HttpResponseRedirect('tourneys/' + str(tourney_id) + '/player/' + str(existing.key().id()))

	data = json.loads(apiret)

	player_name = data['name']
	if type(data['name']) is unicode:
		logging.info('dealing with unicode player name ...')
		player_name = player_name.encode('ascii','ignore')  #this deals with special characters that would mess up our code, by removing them. 
		logging.info('player_name:')
		logging.info(player_name)
		logging.info('player-name looks ok or not?')

	player = players.Player(inviteToken=inviteToken, name=player_name, color=data['color'], isMember=data['isMember'].lower() == 'true') 

	if main.getIsMembersOnly(tourney_id, tourney_clotconfig) and not player.isMember:
		form.errors['inviteToken'] = 'This site only allows members to join.	See the Membership tab on WarLight.net for information about memberships.'
		return shortcuts.render_to_response('join.html', {'form': form})

	player.put()
	player.player_id = str(player.key().id())
	player.tourney_id = tourney_id
	player.save()
	logging.info("Created player")
	logging.info(player)
	
	return http.HttpResponseRedirect('tourneys/' + str(tourney_id) + '/player/' + str(player.key().id()))
Пример #7
0
def checkInProgressGames(container):
    """This is called periodically to look for games that are finished.  If we find a finished game, we record the winner"""

    #Find all games that we think aren't finished
    activeGames = [g for g in container.games if g.winner is None]

    for g in activeGames:
        #call WarLight's GameFeed API so that it can tell us if it's finished or not
        apiret = hitapi('/API/GameFeed?GameID=' + str(g.wlnetGameID), {})
        data = json.loads(apiret)
        state = data.get('state', 'err')
        if state == 'err': raise Exception("GameFeed API failed.  Message = " + data.get('error', apiret))
        
        if state == 'Finished':        
            #It's finished. Record the winner and save it back.
            winner = findWinner(container, data)
            logging.info('Identified the winner of game ' + str(g.wlnetGameID) + ' is ' + unicode(winner))
            g.winner = winner.key.id()
            g.dateEnded = datetime.datetime.now()
            g.put()        
        elif state == 'WaitingForPlayers':
            #It's in the lobby still. Check if it's been too long.
            elapsed = datetime.datetime.now() - g.dateCreated
            players = data.get('players', 'err')
            if players == 'err' : raise Exception("GameFeed API failed.  Message = " + data.get('error', apiret))
            
            hasEitherPlayerDeclined = False
            for p in players:
                playerState = p.get('state', 'err')
                if playerState =='err' : raise Exception("GameFeed API failed.  Message = " + data.get('error', apiret)) 
                if playerState == 'Declined':
                    hasEitherPlayerDeclined = True
                    break
            
            if clot.gameFailedToStart(elapsed) or hasEitherPlayerDeclined == True:
                logging.info('Game ' + str(g.wlnetGameID) + " is stuck in the lobby. Marking it as a loss for anyone who didn't join and deleting it.")
            
                #Delete it over at warlight.net so that players know we no longer consider it a real game
                config = getClotConfig()
                deleteRet = postToApi('/API/DeleteLobbyGame', json.dumps( { 
                                             'Email': config.adminEmail, 
                                             'APIToken': config.adminApiToken,
                                             'gameID': g.wlnetGameID }))
                
                #If the API doesn't return success, just ignore this game on this run. This can happen if the game just started between when we checked its status and when we told it to delete.
                if 'success' not in deleteRet:
                    logging.info("DeleteLobbyGame did not return success. Ignoring this game for this run.  Return=" + deleteRet)
                else:
                    #We deleted the game.  Mark it as deleted and finished
                    g.deleted = True
                    g.winner = findWinnerOfDeletedGame(container, data).key.id()
                    g.put()
                    
                    #Also remove anyone that declines or fails to join from the ladder.  This is important for real-time ladders since we don't want idle people staying in forever, but you may not want this for your situation
                    for playerID in [getPlayerByInviteToken(container, p['id']).key.id() for p in data['players'] if p['state'] != 'Playing']:
                        if playerID in container.lot.playersParticipating:
                            container.lot.playersParticipating.remove(playerID)
                            logging.info("Removed " + str(playerID) + " from ladder since they did not join game " + str(g.wlnetGameID))    
            else :
                logging.info("Game " + str(g.wlnetGameID) + " is in the lobby for " + str(elapsed.days) + " days.")    
        else:
            #It's still going.
            logging.info('Game ' + str(g.wlnetGameID) + ' is not finished, state=' + state + ', numTurns=' + data['numberOfTurns'])
Пример #8
0
def hitapi(api, params):
    config = getClotConfig()
    return hitapiwithauth(api, params, config.adminEmail, config.adminApiToken)
Пример #9
0
def index_new(request,tourney_id):
	"""Request / """
	logging.info('in index_new(' +str(tourney_id)+ ')')

	tourney_id = int(tourney_id)
	logging.info('tourney_id = '+str(tourney_id))
	tourney_clotconfig = main.getClotConfig(tourney_id)

	if not main.doesTourneyExist(tourney_id, tourney_clotconfig):
		logging.info('tourney does not exist, redirecting user to tourneys info instead')
		return shortcuts.render_to_response('tourney_does_not_exist.html' )

	#arrange players by rank
	the_players = players.Player.all().filter("tourney_id =", tourney_id)#.run(batch_size=1000)
	the_players = sorted(the_players, key=lambda z: z.currentRank)

	gamePlayers = main.group(games.GamePlayer.all().filter("tourney_id =", tourney_id), lambda z: z.gameID)  #.run(batch_size=1000)

	#arrange games by reverse of created date
	the_games = games.Game.all().filter("tourney_id =", tourney_id)#.run(batch_size=1000)
	the_games = sorted(the_games, key=lambda z: z.dateCreated, reverse=True)
	#for game in the_games:
	#	logging.info('game: '+str(game))
	#	logging.info('game.winningTeamName = '+str(game.winningTeamName))


	#do the head-to-head table
	biggermat, head_to_head_2d = new_utility_functions.getHeadToHeadTable(tourney_id)
	biggermat_str = deepcopy(biggermat)
	for i in range(1,len(biggermat_str)):
		for j in range(1,len(biggermat_str[i])):
			if i==j:
				biggermat_str[i][j] = "---"
			else:
				biggermat_str[i][j] = str(biggermat_str[i][j][0]) + "-" + str(biggermat_str[i][j][1])

	#see if players are gated
	players_gated_string = "players may join or leave"
	if main.arePlayersGated(tourney_id, tourney_clotconfig):
		players_gated_string = "players may NOT join or leave"

	#get tourney_status_string
	tourney_status_string = 'Tourney Not Yet Started'
	if main.isTourneyInPlay(tourney_id, tourney_clotconfig):
		if str(main.getTourneyType(tourney_id, tourney_clotconfig)) == 'swiss':
			tourney_status_string = 'Tourney In Progress.  Round '+str(main.getRoundNumber(tourney_id, tourney_clotconfig))+' of '+str(main.getNumRounds(tourney_id, tourney_clotconfig))
		else:
			tourney_status_string = 'Tourney In Progress.'
	elif main.hasTourneyFinished(tourney_id, tourney_clotconfig):
		winner = the_players[0]
		winner_name = winner.name
		tourney_status_string = 'Tourney has finished.  Congratulations to '+str(winner_name)+'!'

	minNumPlayersString= 'minNumPlayers: '+str(main.getMinimumNumberOfPlayers(tourney_id, tourney_clotconfig))
	maxNumPlayersString= 'maxNumPlayers: '+str(main.getMaximumNumberOfPlayers(tourney_id, tourney_clotconfig))
	starttimeString = 'starttime will be:  '+str(main.getStarttime(tourney_id, tourney_clotconfig))+'    provided we have minimum number of players.'
	currentTimeString = 'current time =     '+str(main.getCurrentTime())
	tourney_type_string = str(main.getTourneyType(tourney_id, tourney_clotconfig)) + ' tourney'
	how_long_you_have_to_join_games_string = 'You have '+str(main.getHowLongYouHaveToJoinGames(tourney_id, tourney_clotconfig))+' minutes to join your auto-created games.  After that you may lose that game!!'
	template_id = main.getTemplateID(tourney_id, tourney_clotconfig)

	#things for specific tourney types
	if main.getTourneyType(tourney_id, tourney_clotconfig)=='swiss':
		swiss_games_info_table = tournament_swiss.getTourneyRoundsAndGameInfo(tourney_id)
	else:
		swiss_games_info_table = 0
	#end of things for specific tourney types

	return shortcuts.render_to_response('tourney_home.html',{'players': the_players, 'config': tourney_clotconfig, 'games': the_games, 
			'biggermat':biggermat_str,
			'players_gated_string':players_gated_string,
			'minNumPlayersString':minNumPlayersString,
			'maxNumPlayersString':maxNumPlayersString,
			'tourney_status_string':tourney_status_string,
			'starttimeString':starttimeString,
			'currentTimeString':currentTimeString,
			'tourney_type_string':tourney_type_string,
			'how_long_you_have_to_join_games_string':how_long_you_have_to_join_games_string,
			'template_title_string':'Game Template',
			'template_id':template_id,
			'swiss_games_info_table':swiss_games_info_table,
			'join_url':'/tourneys/'+str(tourney_id)+'/join',
			'leave_url':'/tourneys/'+str(tourney_id)+'/leave',
			'tourney_id':str(tourney_id)
			})
Пример #10
0
def hitapi(api, params):
  config = getClotConfig()
  return hitapiwithauth(api, params, config.adminEmail, config.adminApiToken)