Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: logout flow #3018

Merged
merged 14 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ private void TeleportPlayer(Entity entity, CharacterController controller, ref C

switch (status.TaskStatus)
{
case UniTaskStatus.Pending:
// Teleport the character to a far away place while the teleport is executed
controller.transform.position = MordorConstants.PLAYER_MORDOR_POSITION;
return;
case UniTaskStatus.Succeeded:
ResolveAsSuccess(entity, in teleportIntent, controller, ref platformComponent);
return;
Expand Down
8 changes: 8 additions & 0 deletions Explorer/Assets/DCL/PluginSystem/Utils.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Explorer/Assets/DCL/PluginSystem/Utils/MordorConstants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public static class MordorConstants
fcolarich marked this conversation as resolved.
Show resolved Hide resolved
{
public static Vector3 PLAYER_MORDOR_POSITION = new(15000, 0, 15000);
public static Vector3 SCENE_MORDOR_POSITION = new(0, -10000, 0);
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ private void CreateReservedTransforms(ArchSystemsWorldBuilder<Arch.Core.World> b
{
//The scene container, which is only modified by the client, starts in a position that cannot be seen by the player. Once it finished loading
//in GatherGLTFAssetSystem.cs, it will be moved to the correct position.
var sceneRootContainerTransform = GetNewTransform(position: new Vector3(0, -10000, 0));
var sceneRootContainerTransform = GetNewTransform(position: MordorConstants.SCENE_MORDOR_POSITION);
sceneRootContainerTransform.name = $"{sharedDependencies.SceneData.SceneShortInfo.BaseParcel}_{sharedDependencies.SceneData.SceneShortInfo.Name}_Container";
builder.World.Add(persistentEntities.SceneContainer, new TransformComponent(sceneRootContainerTransform));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ await userInAppInitializationFlow.ExecuteAsync(
{
ShowAuthentication = true,
ShowLoading = true,
ReloadRealm = true,
FromLogout = false,
World = world,
PlayerEntity = playerEntity,
Expand Down
4 changes: 0 additions & 4 deletions Explorer/Assets/DCL/UI/SystemMenu/SystemMenuController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,6 @@ await userInAppInitializationFlow.ExecuteAsync(
{
ShowAuthentication = true,
ShowLoading = true,
// We have to reload the realm so the scenes are recreated when coming back to the world
// The realm fetches the scene entity definitions again and creates the components in ecs
// so the SceneFacade can be later attached into the entity
ReloadRealm = true,
FromLogout = true,
World = world,
PlayerEntity = playerEntity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"GUID:f1eaef1b40a68e74cb90cbedebf57bbf",
"GUID:8c4c611b27046bc4a848721d1fdd4a9f",
"GUID:4725c02394ab4ce19f889e4e8001f989",
"GUID:e25ef972de004615a22937e739de2def"
"GUID:e25ef972de004615a22937e739de2def",
"GUID:766b242fb43af451aaa331f39872177d"
],
"includePlatforms": [],
"excludePlatforms": [],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using CommunicationData.URLHelpers;
using System;
using System.Threading;
using System.Threading.Tasks;
using CommunicationData.URLHelpers;
using Cysharp.Threading.Tasks;
using DCL.Audio;
using DCL.AuthenticationScreenFlow;
using DCL.AvatarRendering.AvatarShape.UnityInterface;
using DCL.Chat.History;
using DCL.Diagnostics;
using DCL.FeatureFlags;
using DCL.Multiplayer.Connections.DecentralandUrls;
Expand All @@ -31,16 +33,20 @@ public class RealUserInAppInitializationFlow : IUserInAppInitializationFlow
private static readonly ILoadingScreen.EmptyLoadingScreen EMPTY_LOADING_SCREEN = new ();

private readonly ILoadingStatus loadingStatus;
private readonly IDecentralandUrlsSource decentralandUrlsSource;
private readonly IMVCManager mvcManager;
private readonly AudioClipConfig backgroundMusic;
private readonly IRealmNavigator realmNavigator;
private readonly ILoadingScreen loadingScreen;
private readonly IRoomHub roomHub;
private readonly LoadPlayerAvatarStartupOperation loadPlayerAvatarStartupOperation;
private readonly CheckOnboardingStartupOperation checkOnboardingStartupOperation;
private readonly RestartRealmStartupOperation restartRealmStartupOperation;
private readonly IStartupOperation startupOperation;
private readonly IStartupOperation reloginOperation;
private readonly IDecentralandUrlsSource decentralandUrlsSource;
private readonly IChatHistory chatHistory;

private readonly IRealmController realmController;
private readonly IRoomHub roomHub;
private readonly IPortableExperiencesController portableExperiencesController;

public RealUserInAppInitializationFlow(
ILoadingStatus loadingStatus,
Expand All @@ -61,15 +67,17 @@ public RealUserInAppInitializationFlow(
IAppArgs appParameters,
IDebugSettings debugSettings,
IPortableExperiencesController portableExperiencesController,
IRoomHub roomHub,
DiagnosticsContainer diagnosticsContainer)
DiagnosticsContainer diagnosticsContainer, IChatHistory chatHistory, IRoomHub roomHub)
{
this.loadingStatus = loadingStatus;
this.decentralandUrlsSource = decentralandUrlsSource;
this.mvcManager = mvcManager;
this.backgroundMusic = backgroundMusic;
this.realmNavigator = realmNavigator;
this.loadingScreen = loadingScreen;
this.realmController = realmController;
this.portableExperiencesController = portableExperiencesController;
this.chatHistory = chatHistory;
this.roomHub = roomHub;

var ensureLivekitConnectionStartupOperation = new EnsureLivekitConnectionStartupOperation(loadingStatus, livekitHealthCheck);
Expand All @@ -79,7 +87,6 @@ public RealUserInAppInitializationFlow(
loadPlayerAvatarStartupOperation = new LoadPlayerAvatarStartupOperation(loadingStatus, selfProfile, mainPlayerAvatarBaseProxy);
var loadLandscapeStartupOperation = new LoadLandscapeStartupOperation(loadingStatus, landscape);
checkOnboardingStartupOperation = new CheckOnboardingStartupOperation(loadingStatus, selfProfile, featureFlagsCache, decentralandUrlsSource, appParameters, realmNavigator);
restartRealmStartupOperation = new RestartRealmStartupOperation(loadingStatus, realmController);
var teleportStartupOperation = new TeleportStartupOperation(loadingStatus, realmNavigator, startParcel);
var loadGlobalPxOperation = new LoadGlobalPortableExperiencesStartupOperation(loadingStatus, selfProfile, featureFlagsCache, debugSettings, portableExperiencesController);
var sentryDiagnostics = new SentryDiagnosticStartupOperation(realmController, diagnosticsContainer);
Expand All @@ -93,71 +100,72 @@ public RealUserInAppInitializationFlow(
loadPlayerAvatarStartupOperation,
loadLandscapeStartupOperation,
checkOnboardingStartupOperation,
restartRealmStartupOperation,
teleportStartupOperation,
loadGlobalPxOperation,
sentryDiagnostics
);

reloginOperation = new SequentialStartupOperation(
loadingStatus,
ensureLivekitConnectionStartupOperation,
preloadProfileStartupOperation,
switchRealmMiscVisibilityStartupOperation,
loadPlayerAvatarStartupOperation,
loadLandscapeStartupOperation,
checkOnboardingStartupOperation,
teleportStartupOperation,
loadGlobalPxOperation,
sentryDiagnostics);
}


public async UniTask ExecuteAsync(UserInAppInitializationFlowParameters parameters, CancellationToken ct)
{
loadingStatus.SetCurrentStage(LoadingStatus.LoadingStage.Init);

Result result = default;

loadPlayerAvatarStartupOperation.AssignWorld(parameters.World, parameters.PlayerEntity);
restartRealmStartupOperation.EnableReload(parameters.ReloadRealm);

using UIAudioEventsBus.PlayAudioScope playAudioScope = UIAudioEventsBus.Instance.NewPlayAudioScope(backgroundMusic);

do
{
if (parameters.FromLogout)

// Disconnect current livekit connection on logout so the avatar is removed from other peers
await roomHub.StopAsync().Timeout(TimeSpan.FromSeconds(10));

if (parameters.ShowAuthentication)
{
loadingStatus.SetCurrentStage(LoadingStatus.LoadingStage.AuthenticationScreenShowing);
await ShowAuthenticationScreenAsync(ct);
if (parameters.FromLogout)
{
await DoLogoutOperations();
//Restart the realm and show the authentications screen simultaneously to avoid the "empty space" flicker
await UniTask.WhenAll(ShowAuthenticationScreenAsync(ct),
realmController.SetRealmAsync(
URLDomain.FromString(decentralandUrlsSource.Url(DecentralandUrl.Genesis)), ct));
}
else
{
await ShowAuthenticationScreenAsync(ct);
}
}

if (parameters.FromLogout)
{
// If we are coming from a logout, we teleport the user to Genesis Plaza and force realm change to reset the scene properly
var url = URLDomain.FromString(decentralandUrlsSource.Url(DecentralandUrl.Genesis));
var changeRealmResult = await realmNavigator.TryChangeRealmAsync(url, ct);

if (changeRealmResult.Success == false)
ReportHub.LogError(ReportCategory.AUTHENTICATION, changeRealmResult.AsResult().ErrorMessage!);
var flowToRun = parameters.FromLogout ? reloginOperation : startupOperation;

// Restart livekit connection
await roomHub.StartAsync().Timeout(TimeSpan.FromSeconds(10));
result = changeRealmResult.AsResult();
var loadingResult = await LoadingScreen(parameters.ShowLoading)
.ShowWhileExecuteTaskAsync(
async (parentLoadReport, ct) =>
{
result = await flowToRun.ExecuteAsync(parentLoadReport, ct);

// We need to flag the process as completed, otherwise the multiplayer systems will not run
loadingStatus.SetCurrentStage(LoadingStatus.LoadingStage.Completed);
}
else
{
Result loadingResult = await LoadingScreen(parameters.ShowLoading)
.ShowWhileExecuteTaskAsync(
async (parentLoadReport, ct) =>
{
result = await startupOperation.ExecuteAsync(parentLoadReport, ct);
if (result.Success)
parentLoadReport.SetProgress(
loadingStatus.SetCurrentStage(LoadingStatus.LoadingStage.Completed));

if (result.Success)
parentLoadReport.SetProgress(loadingStatus.SetCurrentStage(LoadingStatus.LoadingStage.Completed));
return result;
},
ct
);

return result;
},
ct
);

ApplyErrorIfLoadingScreenError(ref result, loadingResult);
}
ApplyErrorIfLoadingScreenError(ref result, loadingResult);

if (result.Success == false)
ReportHub.LogError(ReportCategory.DEBUG, result.ErrorMessage!);
Expand All @@ -170,6 +178,14 @@ public async UniTask ExecuteAsync(UserInAppInitializationFlowParameters paramete
loadingStatus.SetCurrentStage(LoadingStatus.LoadingStage.Completed);
}

private async UniTask DoLogoutOperations()
{
portableExperiencesController.UnloadAllPortableExperiences();
realmNavigator.RemoveCameraSamplingData();
chatHistory.Clear();
await roomHub.StopAsync().Timeout(TimeSpan.FromSeconds(10));
}

private static void ApplyErrorIfLoadingScreenError(ref Result result, Result showResult)
{
if (!showResult.Success)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ public struct UserInAppInitializationFlowParameters
{
public bool ShowAuthentication { get; set; }
public bool ShowLoading { get; set; }
public bool ReloadRealm { get; set; }
public bool FromLogout { get; set; }
public World World { get; set; }
public Entity PlayerEntity { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ UniTask<EnumResult<ChangeRealmError>> TryChangeRealmAsync(

UniTask InitializeTeleportToSpawnPointAsync(AsyncLoadProcessReport teleportLoadReport, CancellationToken ct, Vector2Int parcelToTeleport);

void RemoveCameraSamplingData();

void SwitchMiscVisibilityAsync();

UniTask ChangeRealmAsync(URLDomain realm, CancellationToken ct);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private void UnloadLoadedPortableExperienceScene(in Entity entity, ref SceneDefi
{
sceneFacade.DisposeAsync().Forget();
scenesCache.RemovePortableExperienceFacade(definitionComponent.IpfsPath.EntityId);
World.Remove<ISceneFacade, SceneDefinitionComponent>(entity);
World.Destroy(entity);
}

[Query]
Expand Down
1 change: 0 additions & 1 deletion Explorer/Assets/Scripts/Global/Dynamic/Bootstraper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ await dynamicWorldContainer.UserInAppInAppInitializationFlow.ExecuteAsync(
{
ShowAuthentication = debugSettings.ShowAuthentication,
ShowLoading = debugSettings.ShowLoading,
ReloadRealm = false,
FromLogout = false,
World = globalWorld.EcsWorld,
PlayerEntity = playerEntity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@ IMultiPool MultiPoolFactory() =>

livekitHealthCheck.WithRetries();

var chatHistory = new ChatHistory();

container.UserInAppInAppInitializationFlow = new RealUserInAppInitializationFlow(
staticContainer.LoadingStatus,
livekitHealthCheck,
Expand All @@ -400,8 +402,9 @@ IMultiPool MultiPoolFactory() =>
dynamicWorldParams.AppParameters,
bootstrapContainer.DebugSettings,
staticContainer.PortableExperiencesController,
container.RoomHub,
bootstrapContainer.DiagnosticsContainer);
bootstrapContainer.DiagnosticsContainer,
chatHistory,
container.RoomHub);

var worldInfoHub = new LocationBasedWorldInfoHub(
new WorldInfoHub(staticContainer.SingletonSharedDependencies.SceneMapping),
Expand All @@ -412,8 +415,6 @@ IMultiPool MultiPoolFactory() =>

container.CharacterDataPropagationUtility = new CharacterDataPropagationUtility(staticContainer.ComponentsContainer.ComponentPoolsRegistry.AddComponentPool<SDKProfile>());

var chatHistory = new ChatHistory();

var currentSceneInfo = new CurrentSceneInfo();
var connectionStatusPanelPlugin = new ConnectionStatusPanelPlugin(container.UserInAppInAppInitializationFlow, container.MvcManager, mainUIView, roomsStatus, currentSceneInfo, container.reloadSceneController, globalWorld, playerEntity, debugBuilder);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ public bool CanKillPortableExperience(ENS ens)
return spawnResponsesList;
}

public void UnloadAllPortableExperiences()
{
foreach (var spawnResponse in GetAllPortableExperiences())
UnloadPortableExperienceByEns(new ENS(spawnResponse.ens));
}

public IPortableExperiencesController.ExitResponse UnloadPortableExperienceByEns(ENS ens)
{
if (!ens.IsValid) throw new ArgumentException($"The provided ens {ens.ToString()} is invalid");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ public struct ExitResponse
{
public bool status;
}

void UnloadAllPortableExperiences();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class RealmController : IGlobalRealmController
// TODO it can be dangerous to clear the realm, instead we may destroy it fully and reconstruct but we will need to
// TODO construct player/camera entities again and allocate more memory. Evaluate
// Realms + Promises
private static readonly QueryDescription CLEAR_QUERY = new QueryDescription().WithAny<RealmComponent, GetSceneDefinition, GetSceneDefinitionList, SceneDefinitionComponent, SceneLODInfo, EmptySceneComponent>();
private static readonly QueryDescription CLEAR_QUERY = new QueryDescription().WithAny<RealmComponent, GetSceneDefinition, GetSceneDefinitionList, SceneDefinitionComponent, SceneLODInfo, EmptySceneComponent>().WithNone<PortableExperienceComponent>();

private readonly List<ISceneFacade> allScenes = new (PoolConstants.SCENES_COUNT);
private readonly ServerAbout serverAbout = new ();
Expand Down
Loading
Loading