Example #1
0
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 {}
Example #2
0
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 {}
Example #3
0
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
Example #4
0
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