question

Ben Trewhella avatar image
Ben Trewhella asked

Unable to list servers or virtual machines - only entities of type: title

In Unity with SDK2.85.200421 (chosen for existing tutorials) I am trying to list available servers prior to allow the player to choose one to connect to - for this game this is more appropriate than matchmaking (I think).


I am able to authenticate user with playfab (silent) then list builds. However when I try to list servers or virtual machines, I receive

/MultiplayerServer/ListVirtualMachineSummaries: Only entities of the following types may call this API: title

I understand that the player is authenticated as a title_player_account, however I am unable to work out where to autheticate with the title entity. I've tried creating a token using GetEntityToken however this does not provide a new authentication context, and I've tried using PlayFabSettings.staticPlayer.

What am I missing - am I forced to use matchmaking, or is there a way I can request a list of servers / VMs available to the player? I have enabled Client API, Entity API and Server API in the editor helper.

Code:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using PlayFab;

using PlayFab.ClientModels;

using PlayFab.MultiplayerModels;

using PlayFab.AuthenticationModels;

//using PlayFab.Helpers;



public class FindServers : MonoBehaviour

{

    //PlayFabAuthService _authService;



    public string Email;

    public string Username;

    public string Password;

    public string AuthTicket;

    public GetPlayerCombinedInfoRequestParams InfoRequestParams;



    //Accessbility for PlayFab ID & Session Tickets

    public static string PlayFabId { get { return _playFabId; } }

    private static string _playFabId;

    public static string SessionTicket { get { return _sessionTicket; } }

    private static string _sessionTicket;



    EntityTokenResponse _entityToken;

    PlayFabAuthenticationContext _authenticationContext;



    string entityTokenForVMS;



    BuildSummary buildSummary;



    // Start is called before the first frame update

    void Start()

    {

        //getEntity();



        authenticate();

    }







    public void authenticate()

    {

        PlayFabClientAPI.LoginWithCustomID(new LoginWithCustomIDRequest()

        {

            TitleId = PlayFabSettings.TitleId,

            CustomId = SystemInfo.deviceUniqueIdentifier,

            CreateAccount = true,

            InfoRequestParameters = InfoRequestParams

        }, (result) =>

        {

            //Store Identity and session

            _playFabId = result.PlayFabId;

            _sessionTicket = result.SessionTicket;

            _entityToken = result.EntityToken;

            _authenticationContext = result.AuthenticationContext;



            authenticatedWithPlayfab(result);



        }, errorAuthenticatingPlayfab);





    }





    public void authenticatedWithPlayfab(LoginResult loginResult)

    {

        Debug.Log($"Logged in to playfab, with id {PlayFabId} and session {SessionTicket}");



        Debug.Log($"Authentication {_authenticationContext.EntityType} + {_authenticationContext.EntityId} + {_authenticationContext.EntityToken}");

        getEntityToken();



    }



    public void errorAuthenticatingPlayfab(PlayFabError error)

    {

        Debug.Log("Error authenticating");

        Debug.LogError(error.GenerateErrorReport());

    }



    public void getEntityToken()

    {

        PlayFabAuthenticationAPI.GetEntityToken(new PlayFab.AuthenticationModels.GetEntityTokenRequest()

        {

            AuthenticationContext = _authenticationContext

        },

        gotEntityToken, errorOnGetEntityToken);

    }



    public void gotEntityToken(PlayFab.AuthenticationModels.GetEntityTokenResponse response)

    {

        Debug.Log($"Got token {response.Entity}: {response.EntityToken}");



        entityTokenForVMS = response.EntityToken;



        PlayFabMultiplayerAPI.ListBuildSummaries(new ListBuildSummariesRequest()

        {

            AuthenticationContext = _authenticationContext

        }, gotBuilds, errorOnRequestBuilds);

    }



    public void errorOnGetEntityToken(PlayFabError error)

    {

        Debug.Log("Error getting token");

        Debug.LogError(error.GenerateErrorReport());

    }





    public void gotBuilds(ListBuildSummariesResponse buildSummariesResponse)

    {

        foreach (BuildSummary bs in buildSummariesResponse.BuildSummaries)

        {

            Debug.Log($"Found build {bs.BuildName}: {bs.BuildId} ");

            buildSummary = bs;

        }

        if (buildSummary == null)

        {

            Debug.Log("No builds found");

            return;

        }



        Debug.Log("Requesting with type " + PlayFabSettings.staticPlayer.EntityType);

        // otherwise request servers

        PlayFabMultiplayerAPI.ListVirtualMachineSummaries(new ListVirtualMachineSummariesRequest()

        {

            AuthenticationContext = PlayFabSettings.staticPlayer,

            BuildId = buildSummary.BuildId,

            Region = AzureRegion.EastUs.ToString()

        }, gotVirtualServers, errorOnRequestVirtualServers);

    }



    public void errorOnRequestBuilds(PlayFabError error)

    {

        Debug.Log("Error getting builds: " + error.ApiEndpoint);

        Debug.LogError(error.GenerateErrorReport());

    }



    public void gotVirtualServers(ListVirtualMachineSummariesResponse serversResponse)

    {

        foreach(VirtualMachineSummary virtualMachineSummarys in serversResponse.VirtualMachines)

        {

            Debug.Log($"Got server {virtualMachineSummarys.VmId} in {virtualMachineSummarys.State}");

        }

    }



    public void errorOnRequestVirtualServers(PlayFabError error)

    {

        Debug.Log("Error getting servers");

        Debug.LogError(error.GenerateErrorReport());

    }

}



1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Ben Trewhella avatar image Ben Trewhella commented ·

Update: I have now worked this out - I need to look up servers etc before logging in as a player, seems odd (to me with my limited understanding right now) but it works!

0 Likes 0 ·

1 Answer

·
Sarah Zhang avatar image
Sarah Zhang answered

Firstly, you can refer to the documentation -- Entities, especially this section -- Supported Entity types to learn about the basics of Entity types. Title(type) and title_player_account(type) are two different entity types that are separated from each other.

In your case, the player’s session tickets and entity token would be filled in the Authentication context automatically after the player logged in, you don’t need to fill them manually. So the response “Only entities of the following types may call this API: title” means the entity type(title_player_account) in your context does not have access to call the multiplayer.ListVirtualMachineSummaries API. Only the Title entity, in other words, the admin tier’s entity can access the API ListVirtualMachineSummaries.

In consideration of safety, we would not suggest enabling Admin API in any client or get the Title entity in the client. (So you may need to evaluate the security of your solution.) Classic admin APIs can only be called in the administration tools and custom servers. But such multiplayer APIs can be called on the PlayFab CloudScript. The corresponding CloudScript function for your case would be something like this.

handlers.ListVMSummaries = function (args, context) {
    var VMSummaries = multiplayer.ListVirtualMachineSummaries({
        "BuildId": "[YourBuildId]",
        "Region": "EastUs", //Your region.
    });
    return VMSummaries;
};

After you deploy this function to CloudScript, clients can get the response of it via calling Client API ExecuteCloudScript.

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Ben Trewhella avatar image Ben Trewhella commented ·

Ok makes sense - many thanks! Yes will use Cloudscript, am just getting the bare bones up and running for now

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.