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()); } }