private static bool AddServerInfoIfDoesNotExist(RoomServerInfo serverInfo) { // TODO [bgish]: Need to make this a call to Redis lock (ServerInfosLock) { if (RoomIdToServerInfoMap.ContainsKey(serverInfo.RoomId) == false) { RoomIdToServerInfoMap.Add(serverInfo.RoomId, serverInfo); return(true); } return(false); } }
public static async Task <RoomServerInfo> EnterRoom(CloudFunctionContext context, string roomId) { //// TODO [bgish]: Verify this is an actual room... //// TODO [bgish]: Verify this user has the right to enter this room... // Querying Title Data to figure out what server info we should be using var gameServerInfoKey = "GameServerInfo"; var getTitleData = await global::PlayFab.PlayFabServerAPI.GetTitleDataAsync(new global::PlayFab.ServerModels.GetTitleDataRequest { Keys = new List <string> { gameServerInfoKey }, AuthenticationContext = context.TitleAuthenticationContext, }); GameServerInfo gameServerInfo = JsonUtil.Deserialize <GameServerInfo>(getTitleData.Result.Data[gameServerInfoKey]); // Querying if the server info already exists RoomServerInfo serverInfo = GetServerInfoForRoom(roomId); if (serverInfo == null) { serverInfo = new RoomServerInfo { RoomId = roomId, SessionId = Guid.NewGuid().ToString("D"), BuildId = gameServerInfo.BuildId, }; if (AddServerInfoIfDoesNotExist(serverInfo)) { DateTime start = DateTime.Now; // We were successful registering our ServerInfo, they we need to spin up an actual server and set that data too var request = await PlayFabMultiplayerAPI.RequestMultiplayerServerAsync(new RequestMultiplayerServerRequest { SessionId = serverInfo.SessionId, BuildId = serverInfo.BuildId, PreferredRegions = gameServerInfo.Regions, AuthenticationContext = context.TitleAuthenticationContext, }); DateTime end = DateTime.Now; UnityEngine.Debug.Log($"RequestMultiplayerServerRequest Time = {end.Subtract(start).TotalMilliseconds}"); serverInfo.FQDN = request.Result.FQDN; serverInfo.Ports = request.Result.Ports; serverInfo.Region = request.Result.Region; serverInfo.ServerId = request.Result.ServerId; if (serverInfo.SessionId != request.Result.SessionId) { UnityEngine.Debug.LogError($"Multiplayer Session Id Changed from {serverInfo.SessionId} to {request.Result.SessionId}"); serverInfo.SessionId = request.Result.SessionId; } UpdateServerInfo(serverInfo); return(serverInfo); } else { // NOTE [bgish]: This will fail if the winner has the RequestMultiplayerServerAsync fail due to lack of availability // Someone beat us to the punch and added one before us, so lets poll till we get the server info serverInfo = GetServerInfoForRoom(roomId); int retryCount = 0; while (string.IsNullOrEmpty(serverInfo?.FQDN)) { await Task.Delay(100); serverInfo = GetServerInfoForRoom(roomId); retryCount++; if (retryCount > 30) { throw new Exception("Retry Count Max Met!"); } } return(serverInfo); } } else { var getServerInfo = await PlayFabMultiplayerAPI.GetMultiplayerServerDetailsAsync(new GetMultiplayerServerDetailsRequest { BuildId = serverInfo.BuildId, Region = serverInfo.Region, SessionId = serverInfo.SessionId, AuthenticationContext = context.TitleAuthenticationContext, }); if (getServerInfo.Error == null) { // If it didn't return an error, it should still be good return(serverInfo); } else { // We know this session is no longer valid, so remove it from the cache and get a new one DeleteServerInfoIfDataHasntChanged(serverInfo.RoomId, serverInfo.SessionId, serverInfo.Region); return(await EnterRoom(context, roomId)); } } }