def merge(request): '''A simple merge view. The merge.mako template does the work.''' s = DBSession() # only do a merge if we have all of the required data if request.params.has_key("csrf_token"): # check the token to prevent request forgery st = request.session.get_csrf_token() check_csrf_token(request) if request.params.has_key("w_pid") and request.params.has_key("l_pid"): w_pid = request.params.get("w_pid") l_pid = request.params.get("l_pid") # do the merge, hope for the best! try: s.execute("select merge_players(:w_pid, :l_pid)", { "w_pid": w_pid, "l_pid": l_pid }) s.commit() request.session.flash( "Successfully merged player %s into %s!" % (l_pid, w_pid), "success") except: s.rollback() request.session.flash( "Could not merge player %s into %s." % (l_pid, w_pid), "failure") return {}
def merge(request): '''A simple merge view. The merge.mako template does the work.''' s = DBSession() # only do a merge if we have all of the required data if request.params.has_key("csrf_token"): # check the token to prevent request forgery st = request.session.get_csrf_token() check_csrf_token(request) if request.params.has_key("w_pid") and request.params.has_key("l_pid"): w_pid = request.params.get("w_pid") l_pid = request.params.get("l_pid") # do the merge, hope for the best! try: s.execute("select merge_players(:w_pid, :l_pid)", {"w_pid": w_pid, "l_pid": l_pid}) s.commit() request.session.flash( "Successfully merged player %s into %s!" % (l_pid, w_pid), "success") except: s.rollback() request.session.flash( "Could not merge player %s into %s." % (l_pid, w_pid), "failure") return {}
def submit_stats(request): """ Entry handler for POST stats submissions. """ try: # placeholder for the actual session session = None log.debug("\n----- BEGIN REQUEST BODY -----\n" + request.body + "----- END REQUEST BODY -----\n\n") (idfp, status) = verify_request(request) (game_meta, raw_players, raw_teams) = parse_stats_submission(request.body) revision = game_meta.get('R', 'unknown') duration = game_meta.get('D', None) # only players present at the end of the match are eligible for stats raw_players = filter(played_in_game, raw_players) do_precondition_checks(request, game_meta, raw_players) # the "duel" gametype is fake if len(raw_players) == 2 \ and num_real_players(raw_players) == 2 \ and game_meta['G'] == 'dm': game_meta['G'] = 'duel' #---------------------------------------------------------------------- # Actual setup (inserts/updates) below here #---------------------------------------------------------------------- session = DBSession() game_type_cd = game_meta['G'] # All game types create Game, Server, Map, and Player records # the same way. server = get_or_create_server( session = session, hashkey = idfp, name = game_meta['S'], revision = revision, ip_addr = get_remote_addr(request), port = game_meta.get('U', None), impure_cvars = game_meta.get('C', 0)) gmap = get_or_create_map( session = session, name = game_meta['M']) game = create_game( session = session, start_dt = datetime.datetime.utcnow(), server_id = server.server_id, game_type_cd = game_type_cd, map_id = gmap.map_id, match_id = game_meta['I'], duration = duration, mod = game_meta.get('O', None)) # keep track of the players we've seen player_ids = [] pgstats = [] hashkeys = {} for events in raw_players: player = get_or_create_player( session = session, hashkey = events['P'], nick = events.get('n', None)) pgstat = create_game_stat(session, game_meta, game, server, gmap, player, events) pgstats.append(pgstat) if player.player_id > 1: anticheats = create_anticheats(session, pgstat, game, player, events) if player.player_id > 2: player_ids.append(player.player_id) hashkeys[player.player_id] = events['P'] if should_do_weapon_stats(game_type_cd) and player.player_id > 1: pwstats = create_weapon_stats(session, game_meta, game, player, pgstat, events) # store them on games for easy access game.players = player_ids for events in raw_teams: try: teamstat = create_team_stat(session, game, events) except Exception as e: raise e if server.elo_ind and gametype_elo_eligible(game_type_cd): ep = EloProcessor(session, game, pgstats) ep.save(session) session.commit() log.debug('Success! Stats recorded.') # ranks are fetched after we've done the "real" processing ranks = get_ranks(session, player_ids, game_type_cd) # plain text response request.response.content_type = 'text/plain' return { "now" : calendar.timegm(datetime.datetime.utcnow().timetuple()), "server" : server, "game" : game, "gmap" : gmap, "player_ids" : player_ids, "hashkeys" : hashkeys, "elos" : ep.wip, "ranks" : ranks, } except Exception as e: if session: session.rollback() raise e
def submit_stats(request): """ Entry handler for POST stats submissions. """ # placeholder for the actual session session = None try: log.debug("\n----- BEGIN REQUEST BODY -----\n" + request.body + "----- END REQUEST BODY -----\n\n") (idfp, status) = verify_request(request) try: submission = Submission(request.body, request.headers) except: msg = "Invalid submission" log.debug(msg) raise pyramid.httpexceptions.HTTPUnprocessableEntity( body=msg, content_type="text/plain") do_precondition_checks(request.registry.settings, submission) ####################################################################### # Actual setup (inserts/updates) below here ####################################################################### session = DBSession() # All game types create Game, Server, Map, and Player records # the same way. server = get_or_create_server( session=session, hashkey=idfp, name=submission.server_name, revision=submission.revision, ip_addr=get_remote_addr(request), port=submission.port_number, impure_cvars=submission.impure_cvar_changes) gmap = get_or_create_map(session, submission.map_name) game = create_game(session=session, game_type_cd=submission.game_type_cd, mod=submission.mod, server_id=server.server_id, map_id=gmap.map_id, match_id=submission.match_id, start_dt=datetime.datetime.utcnow(), duration=submission.duration) events_by_hashkey = { elem["P"]: elem for elem in submission.humans + submission.bots } players_by_hashkey = get_or_create_players(session, events_by_hashkey) pgstats = [] elo_pgstats = [] player_ids = [] hashkeys_by_player_id = {} for hashkey, player in players_by_hashkey.items(): events = events_by_hashkey[hashkey] pgstat = create_game_stat(session, game, gmap, player, events) pgstats.append(pgstat) if should_do_frag_matrix(submission.game_type_cd): create_frag_matrix(session, submission.player_indexes, pgstat, events) # player ranking opt-out if 'r' in events and events['r'] == '0': log.debug( "Excluding player {} from ranking calculations (opt-out)". format(pgstat.player_id)) else: elo_pgstats.append(pgstat) if player.player_id > 1: create_anticheats(session, pgstat, game, player, events) if player.player_id > 2: player_ids.append(player.player_id) hashkeys_by_player_id[player.player_id] = hashkey if should_do_weapon_stats( submission.game_type_cd) and player.player_id > 1: create_weapon_stats(session, submission.version, game, player, pgstat, events) # player_ids for human players get stored directly on games for fast indexing game.players = player_ids for events in submission.teams: create_team_stat(session, game, events) if server.elo_ind and gametype_elo_eligible(submission.game_type_cd): ep = EloProcessor(session, game, elo_pgstats) ep.save(session) elos = ep.wip else: elos = {} session.commit() log.debug('Success! Stats recorded.') # ranks are fetched after we've done the "real" processing ranks = get_ranks(session, player_ids, submission.game_type_cd) # plain text response request.response.content_type = 'text/plain' return { "now": calendar.timegm(datetime.datetime.utcnow().timetuple()), "server": server, "game": game, "gmap": gmap, "player_ids": player_ids, "hashkeys": hashkeys_by_player_id, "elos": elos, "ranks": ranks, } except Exception as e: if session: session.rollback() raise e