def handler()

in Editor/Resources/CloudFormation/scenario3_mrf_queue/lambda/results_request.py [0:0]


def handler(event, context):
    """
    Handles requests to describe the game session connection information after a StartGame request.
     This function will look up the MatchmakingRequest table to find a pending matchmaking request by
     the player, and if it is QUEUED, look up the GameSessionPlacement table to find the game's
     connection information.
    :param event: lambda event, contains the region to player latency mapping in `regionToLatencyMapping` key, as well
     as the player information from the Cognito id tokens.
    :param context: lambda context, not used by this function
    :return:
     - 200 (OK) if the game connection is ready, along with server info: "IpAddress", "Port", "DnsName"
     - 204 (No Content) if the requested game is still in progress of matchmaking
     - 404 (Not Found) if no game has been started by the player, or if all started game were expired
     - 500 (Internal Error) if errors occurred during matchmaking or placement
    """
    player_id = event["requestContext"]["authorizer"]["claims"]["sub"]
    print(f'Handling request result request. PlayerId: {player_id}')

    matchmaking_request_table_name = os.environ['MatchmakingRequestTableName']
    game_session_placement_table_name = os.environ['GameSessionPlacementTableName']

    dynamodb = boto3.resource('dynamodb')
    matchmaking_request_table = dynamodb.Table(matchmaking_request_table_name)
    game_session_placement_table = dynamodb.Table(game_session_placement_table_name)

    matchmaking_requests = matchmaking_request_table.query(
        KeyConditionExpression=Key('PlayerId').eq(player_id),
        ScanIndexForward=False
    )

    if matchmaking_requests['Count'] <= 0:
        return {
            'headers': {
                'Content-Type': 'text/plain'
            },
            'statusCode': 404
        }

    latest_matchmaking_request = matchmaking_requests['Items'][0]

    if latest_matchmaking_request['Status'] != STATUS_QUEUED:
        # still waiting for more players to start matchmaking
        return {
            'headers': {
                'Content-Type': 'text/plain'
            },
            'statusCode': 204
        }

    placement_id = latest_matchmaking_request['PlacementId']

    placement = game_session_placement_table.get_item(
        Key={
            'PlacementId': placement_id
        }
    ).get('Item')

    print(f'Placement: {placement}')

    if not placement:
        # start-game-session-placement has just started and no game session event has been received
        return {
            'headers': {
                'Content-Type': 'text/plain'
            },
            'statusCode': 204
        }

    if placement['Status'] != 'PlacementFulfilled':
        # We count PlacementCancelled as internal error also because cancelling placement requests is not
        # in the current implementation, so it should never happen.
        return {
            'headers': {
                'Content-Type': 'text/plain'
            },
            'statusCode': 500
        }

    player_session_id = parse_player_session_id(player_id, placement)
    if player_session_id is None:
        # PlayerSession should always be created and present in the dynamo table for a PlacementFulfilled Event
        return {
            'headers': {
                'Content-Type': 'text/plain'
            },
            'statusCode': 500
        }

    game_session_connection_info = dict((k, placement[k]) for k in ('IpAddress', 'Port', 'DnsName', 'GameSessionArn'))
    game_session_connection_info['PlayerSessionId'] = player_session_id
    return {
        'body': json.dumps(game_session_connection_info),
        'headers': {
            'Content-Type': 'text/plain'
        },
        'statusCode': 200
    }