diff --git a/Explorer/Assets/Scripts/Global/Dynamic/RealmNavigator.cs b/Explorer/Assets/Scripts/Global/Dynamic/RealmNavigator.cs index 25eab3fe3f..9ae2b7fc93 100644 --- a/Explorer/Assets/Scripts/Global/Dynamic/RealmNavigator.cs +++ b/Explorer/Assets/Scripts/Global/Dynamic/RealmNavigator.cs @@ -34,6 +34,8 @@ namespace Global.Dynamic { public class RealmNavigator : IRealmNavigator { + private const int MAX_REALM_CHANGE_RETRIES = 3; + private readonly ILoadingScreen loadingScreen; private readonly IMapRenderer mapRenderer; private readonly IGlobalRealmController realmController; @@ -49,7 +51,8 @@ public class RealmNavigator : IRealmNavigator private readonly ObjectProxy cameraEntity; private readonly CameraSamplingData cameraSamplingData; - private URLDomain? CurrentRealm; + private URLDomain currentRealm; + private Vector2Int currentParcel; public event Action? RealmChanged; @@ -107,7 +110,7 @@ public RealmNavigator( public bool CheckIsNewRealm(URLDomain realm) { - if (realm == CurrentRealm || realm == realmController.RealmData.Ipfs.CatalystBaseUrl) + if (realm == currentRealm || realm == realmController.RealmData.Ipfs.CatalystBaseUrl) return false; return true; @@ -126,6 +129,8 @@ public async UniTask TryChangeRealmAsync(URLDomain realm, CancellationTo Vector2Int parcelToTeleport = default) { ct.ThrowIfCancellationRequested(); + + currentRealm = realmController.RealmData.Ipfs.CatalystBaseUrl; var loadResult = await loadingScreen.ShowWhileExecuteTaskAsync(DoChangeRealmAsync(realm, parcelToTeleport, ct), ct); @@ -154,6 +159,41 @@ private Func> DoChangeRealmAsync(URLDoma CurrentDestinationRealm = realm, ParentReport = parentLoadReport }; + + for (int attempt = 0; attempt < MAX_REALM_CHANGE_RETRIES; attempt++) + { + bool success = true; + foreach (var realmChangeOperation in realmChangeOperations) + { + try + { + var currentOperationResult = await realmChangeOperation.ExecuteAsync(teleportParams, ct); + if (!currentOperationResult.Success) + { + success = false; + ReportHub.LogError(ReportCategory.REALM, $"Operation failed on realm change attempt {attempt + 1}: {currentOperationResult.ErrorMessage}"); + break; + } + } + catch (Exception e) + { + success = false; + ReportHub.LogError(ReportCategory.REALM, $"Unhandled exception on realm change attempt {attempt + 1}: {e}"); + break; + } + } + + if (success) + { + return Result.SuccessResult(); + } + } + + // All retries failed, try with the previous realm and parcel + ReportHub.LogWarning(ReportCategory.REALM, "All attempts failed. Trying with previous realm and parcel."); + teleportParams.CurrentDestinationRealm = currentRealm; + teleportParams.CurrentDestinationParcel = currentParcel; + foreach (var realmChangeOperation in realmChangeOperations) { try @@ -172,7 +212,7 @@ private Func> DoChangeRealmAsync(URLDoma } } - return Result.SuccessResult(); + return Result.ErrorResult("Change realm failed, returned to previous realm"); }; } @@ -308,7 +348,7 @@ private async UniTask TeleportToWorldSpawnPointAsync(Vector2Int parcelT public async UniTask ChangeRealmAsync(URLDomain realm, CancellationToken ct) { await realmController.SetRealmAsync(realm, ct); - CurrentRealm = realm; + currentRealm = realm; await SwitchMiscVisibilityAsync(); }