X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=xonstat%2Fviews%2Fsubmission.py;h=908bf8667a9c45416dc299098407706b7a6623c0;hb=049092239f938bd50e000228a849196c7068be82;hp=55e1fd73245c047c476a679496cb48971830b466;hpb=5a605fae688cc083f82227364014dd0e6b9e4988;p=xonotic%2Fxonstat.git diff --git a/xonstat/views/submission.py b/xonstat/views/submission.py index 55e1fd7..908bf86 100644 --- a/xonstat/views/submission.py +++ b/xonstat/views/submission.py @@ -6,7 +6,7 @@ import re import pyramid.httpexceptions from sqlalchemy import Sequence -from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound +from sqlalchemy.orm.exc import NoResultFound from xonstat.elo import EloProcessor from xonstat.models import DBSession, Server, Map, Game, PlayerGameStat, PlayerWeaponStat from xonstat.models import PlayerRank, PlayerCaptime @@ -91,6 +91,8 @@ class Submission(object): # does any human have a fastest cap? self.human_fastest = False + self.parse() + def next_item(self): """Returns the next key:value pair off the queue.""" try: @@ -127,7 +129,7 @@ class Submission(object): """Construct a player events listing from the submission.""" # all of the keys related to player records - player_keys = ['i', 'n', 't', 'e'] + player_keys = ['i', 'n', 't', 'r', 'e'] player = {key: pid} @@ -338,7 +340,7 @@ def has_minimum_real_players(settings, submission): except: minimum_required_players = 2 - return len(submission.human_players) >= minimum_required_players + return len(submission.humans) >= minimum_required_players def do_precondition_checks(settings, submission): @@ -1046,21 +1048,29 @@ def submit_stats(request): """ Entry handler for POST stats submissions. """ - try: - # placeholder for the actual session - session = None + # placeholder for the actual session + session = None + try: log.debug("\n----- BEGIN REQUEST BODY -----\n" + request.body + - "----- END REQUEST BODY -----\n\n") + "----- END REQUEST BODY -----\n\n") (idfp, status) = verify_request(request) - submission = Submission(request.body, request.headers) + 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 @@ -1089,36 +1099,44 @@ def submit_stats(request): ) events_by_hashkey = {elem["P"]: elem for elem in submission.humans + submission.bots} - get_or_create_players(session, game, gmap, events_by_hashkey) + players_by_hashkey = get_or_create_players(session, events_by_hashkey) - # keep track of the players we've seen - player_ids = [] pgstats = [] - hashkeys = {} - for events in submission.humans + submission.bots: - player = get_or_create_player(session, events['P'], events.get('n', None)) + 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) + # player ranking opt-out + if 'r' in events and events['r'] != "0": + log.debug("excluding player {} from Elo calculations".format(events['i'])) + 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[player.player_id] = events['P'] + 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) - # store them on games for easy access + # 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, pgstats) + ep = EloProcessor(session, game, elo_pgstats) ep.save(session) + elos = ep.wip + else: + elos = {} session.commit() log.debug('Success! Stats recorded.') @@ -1135,8 +1153,8 @@ def submit_stats(request): "game": game, "gmap": gmap, "player_ids": player_ids, - "hashkeys": hashkeys, - "elos": ep.wip, + "hashkeys": hashkeys_by_player_id, + "elos": elos, "ranks": ranks, }