diff --git a/Explorer/Assets/DCL/AssetsProvision/Contextual/ContextualImage.cs b/Explorer/Assets/DCL/AssetsProvision/Contextual/ContextualImage.cs index e58775aa2c6..d493d3bc47f 100644 --- a/Explorer/Assets/DCL/AssetsProvision/Contextual/ContextualImage.cs +++ b/Explorer/Assets/DCL/AssetsProvision/Contextual/ContextualImage.cs @@ -51,14 +51,16 @@ private async UniTask LoadAsync() private void OnDisable() { - image.sprite = null!; - asset.Release(); + if (image != null) + image.sprite = null!; + asset?.Release(); } private void OnDestroy() { - image.sprite = null!; - asset.Dispose(); + if (image != null) + image.sprite = null!; + asset?.Dispose(); } public UniTask TriggerOrWaitReadyAsync(CancellationToken token) => diff --git a/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenAudio.cs b/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenAudio.cs index 08954e79ead..e44564c439f 100644 --- a/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenAudio.cs +++ b/Explorer/Assets/DCL/AuthenticationScreenFlow/AuthenticationScreenAudio.cs @@ -62,7 +62,7 @@ private void OnMuteButtonClicked() private void OnContinuousAudioStarted(AudioClipConfig audioClipConfig) { - if (audioClipConfig.GetInstanceID() != backgroundMusic.GetInstanceID()) + if (audioClipConfig.GetEntityId() != backgroundMusic.GetEntityId()) return; UIAudioEventsBus.Instance.PlayContinuousUIAudioEvent -= OnContinuousAudioStarted; diff --git a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LobbyForExistingAccountAuthView.cs b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LobbyForExistingAccountAuthView.cs index cdf916988b2..97c4fd78a9e 100644 --- a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LobbyForExistingAccountAuthView.cs +++ b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LobbyForExistingAccountAuthView.cs @@ -46,13 +46,13 @@ public void Show(string profileName) JumpIntoWorldButton.interactable = true; DiffAccountButton.interactable = true; - ShowAsync(CancellationToken.None).Forget(); + ShowAsync(destroyCancellationToken).Forget(); } public void Hide(int animHash) { hideAnimHash = animHash; - HideAsync(CancellationToken.None).Forget(); + HideAsync(destroyCancellationToken).Forget(); } public override async UniTask ShowAsync(CancellationToken ct) diff --git a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LobbyForNewAccountAuthView.cs b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LobbyForNewAccountAuthView.cs index 3c7c68f8229..d72468172cd 100644 --- a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LobbyForNewAccountAuthView.cs +++ b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LobbyForNewAccountAuthView.cs @@ -106,13 +106,13 @@ private async UniTaskVoid UpdateBodyTypeLabelAsync(bool isMale) public void Show() { - ShowAsync(CancellationToken.None).Forget(); + ShowAsync(destroyCancellationToken).Forget(); } public void Hide(int animHash) { hideAnimHash = animHash; - HideAsync(CancellationToken.None).Forget(); + HideAsync(destroyCancellationToken).Forget(); } public override async UniTask ShowAsync(CancellationToken ct) diff --git a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LoginSelectionAuthView.cs b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LoginSelectionAuthView.cs index dd8d862cf7c..d89213dccb9 100644 --- a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LoginSelectionAuthView.cs +++ b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/LoginSelectionAuthView.cs @@ -106,7 +106,7 @@ private void SetOptionsPanelVisibility(bool isExpanded) public void Show(int animHash, bool moreOptionsExpanded) { showAnimHash = animHash; - ShowAsync(CancellationToken.None).Forget(); + ShowAsync(destroyCancellationToken).Forget(); areOptionsExpanded = moreOptionsExpanded; SetOptionsPanelVisibility(areOptionsExpanded); @@ -120,7 +120,7 @@ public void Hide() loadingSpinner.SetActive(false); SetEmailInputFieldSpinnerActive(false); - HideAsync(CancellationToken.None).Forget(); + HideAsync(destroyCancellationToken).Forget(); } public void SetLoadingSpinnerVisibility(bool isLoading) diff --git a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/ProfileFetchingAuthView.cs b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/ProfileFetchingAuthView.cs index 295ced18d14..1e00fb94e00 100644 --- a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/ProfileFetchingAuthView.cs +++ b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/ProfileFetchingAuthView.cs @@ -23,13 +23,13 @@ public class ProfileFetchingAuthView : ViewBase public void Show() { - ShowAsync(CancellationToken.None).Forget(); + ShowAsync(destroyCancellationToken).Forget(); } public void Hide(int hideAnimHash) { this.hideAnimHash = hideAnimHash; - HideAsync(CancellationToken.None).Forget(); + HideAsync(destroyCancellationToken).Forget(); } public override async UniTask ShowAsync(CancellationToken ct) diff --git a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/VerificationDappAuthView.cs b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/VerificationDappAuthView.cs index 930bb6d26f2..8007a4233b5 100644 --- a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/VerificationDappAuthView.cs +++ b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/VerificationDappAuthView.cs @@ -60,13 +60,13 @@ public void Show(int dataCode, DateTime expiration) code.text = dataCode.ToString(); DoCountdownAsync(expiration).Forget(); - ShowAsync(CancellationToken.None).Forget(); + ShowAsync(destroyCancellationToken).Forget(); } public void Hide(int hideAnimHash) { this.hideAnimHash = hideAnimHash; - HideAsync(CancellationToken.None).Forget(); + HideAsync(destroyCancellationToken).Forget(); } public override async UniTask ShowAsync(CancellationToken ct) diff --git a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/VerificationOTPAuthView.cs b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/VerificationOTPAuthView.cs index 2d5132642ce..de622b6d026 100644 --- a/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/VerificationOTPAuthView.cs +++ b/Explorer/Assets/DCL/AuthenticationScreenFlow/Views/VerificationOTPAuthView.cs @@ -33,14 +33,14 @@ public class VerificationOTPAuthView : ViewBase public void Show(string email) { InputField.Clear(); - ShowAsync(CancellationToken.None).Forget(); + ShowAsync(destroyCancellationToken).Forget(); description.text = description.text.Replace("your@email.com", email); // Update description with user email } public void Hide(int hideAnimHash) { this.hideAnimHash = hideAnimHash; - HideAsync(CancellationToken.None).Forget(); + HideAsync(destroyCancellationToken).Forget(); } public override async UniTask ShowAsync(CancellationToken ct) diff --git a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Components/AvatarCustomSkinningComponent.cs b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Components/AvatarCustomSkinningComponent.cs index cc4215b8cc7..cd3f4a4415f 100644 --- a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Components/AvatarCustomSkinningComponent.cs +++ b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Components/AvatarCustomSkinningComponent.cs @@ -45,8 +45,9 @@ public void AssignBuffer(ComputeSkinningBufferContainer container) public void DisposeBuffers() { - computeSkinningBufferContainer.Dispose(); - bones.Dispose(); + // a default(Buffers) (empty avatar) owns nothing to dispose + computeSkinningBufferContainer?.Dispose(); + bones?.Dispose(); } } @@ -117,6 +118,10 @@ public readonly void SetFadingDistance(float distance) public Result ComputeSkinning(NativeArray bonesResult, GlobalJobArrayIndex indexInGlobalJobArray) { + // an empty avatar (no vertices) has nothing to skin + if (VertCount == 0) + return Result.SuccessResult(); + if (indexInGlobalJobArray.TryGetValue(out int validIndex) == false) { return Result.ErrorResult("Attempt to process an invalid avatar"); diff --git a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/ComputeShader/ComputeShaderSkinning.cs b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/ComputeShader/ComputeShaderSkinning.cs index f61ffeb1c52..ef35a52bde9 100644 --- a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/ComputeShader/ComputeShaderSkinning.cs +++ b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/ComputeShader/ComputeShaderSkinning.cs @@ -28,6 +28,18 @@ public override AvatarCustomSkinningComponent Initialize(IList (int vertCount, int totalBoneBufferCount) = SetupCounters(meshesData, boneCount); + if (vertCount == 0 || boneCount == 0) + { + ReportHub.LogWarning(ReportCategory.AVATAR, + $"[ComputeShaderSkinning] Empty avatar mesh data (vertCount={vertCount}, boneCount={boneCount}); skipping skinning."); + ListPool.Release(meshesData); + + // VertCount == 0 with default Buffers marks the component as empty: ComputeSkinning and + // DisposeBuffers no-op on it, and the materials list is pool-rented so Dispose's + // unconditional USED_SLOTS_POOL.Release stays balanced. + return new AvatarCustomSkinningComponent(0, 0, default, AvatarCustomSkinningComponent.USED_SLOTS_POOL.Get(), skinningShader, default); + } + AvatarCustomSkinningComponent.Buffers buffers = SetupComputeShader(meshesData, skinningShader, vertCount, totalBoneBufferCount, boneCount); List materialSetups = SetupMeshRenderer(meshesData, avatarMaterialPool, avatarShapeComponent, facialFeatureTexture); diff --git a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/ComputeShader/FixedComputeBufferHandler.cs b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/ComputeShader/FixedComputeBufferHandler.cs index 14f7be2259f..d25cc5008da 100644 --- a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/ComputeShader/FixedComputeBufferHandler.cs +++ b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/ComputeShader/FixedComputeBufferHandler.cs @@ -93,6 +93,10 @@ public void Release(Slice slice) // Merge the region with any adjacent free regions in the freeRegions list. // The freeRegions list should always be kept sorted. If you merge regions, make sure the result is still sorted. + // a zero-length slice was never rented (Rent rejects 0): nothing to release + if (slice.Length == 0) + return; + if (!rentedRegions.Remove(slice)) { ReportHub.LogError(ReportCategory.AVATAR, "Trying to release a slice that was not rented"); diff --git a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/DemoScripts/Systems/PlayableDirectorUpdatingSystem.cs b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/DemoScripts/Systems/PlayableDirectorUpdatingSystem.cs index b7f123c4c80..5c92c978e47 100644 --- a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/DemoScripts/Systems/PlayableDirectorUpdatingSystem.cs +++ b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/DemoScripts/Systems/PlayableDirectorUpdatingSystem.cs @@ -31,7 +31,7 @@ protected override void Update(float t) { // Just taking the one and only playable director from the scene is ok for now if (playableDirector == null) - playableDirector = GameObject.FindObjectOfType(); + playableDirector = Object.FindAnyObjectByType(); if (playableDirector != null) { diff --git a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/AvatarInstantiatorSystem.cs b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/AvatarInstantiatorSystem.cs index f5ade536adc..1964e7dbf91 100644 --- a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/AvatarInstantiatorSystem.cs +++ b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/AvatarInstantiatorSystem.cs @@ -287,7 +287,9 @@ private void InstantiateExistingAvatar(ref AvatarShapeComponent avatarShapeCompo foreach (var renderer in cachedAttachment.Renderers) renderer.enabled = false; - skinningComponent.SetVertOutRegion(vertOutBuffer.Rent(skinningComponent.VertCount)); + // an empty avatar (VertCount == 0) owns no region of the shared buffer (Rent rejects 0) + if (skinningComponent.VertCount > 0) + skinningComponent.SetVertOutRegion(vertOutBuffer.Rent(skinningComponent.VertCount)); avatarBase.gameObject.SetActive(true); avatarBase.UpdateHeadWearableOffset(skinningComponent.LocalBounds, wearableIntention); // Update cached head wearable offset for nametag positioning diff --git a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/MakeVertsOutBufferDefragmentationSystem.cs b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/MakeVertsOutBufferDefragmentationSystem.cs index 760c869a824..6115bd4e902 100644 --- a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/MakeVertsOutBufferDefragmentationSystem.cs +++ b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/MakeVertsOutBufferDefragmentationSystem.cs @@ -35,6 +35,11 @@ protected override void Update(float t) [Query] private void UpdateIndices([Data] IReadOnlyDictionary remapping, ref AvatarCustomSkinningComponent avatarCustomSkinningComponent) { + // a zero-length region owns no slice of the buffer; its default StartIndex (0) must not + // match a real region that starts at 0 + if (avatarCustomSkinningComponent.VertsOutRegion.Length == 0) + return; + if (remapping.TryGetValue(avatarCustomSkinningComponent.VertsOutRegion.StartIndex, out FixedComputeBufferHandler.Slice newRegion)) avatarCustomSkinningComponent.SetVertOutRegion(newRegion); } diff --git a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Tests/EditMode/AvatarShapeVisibilitySystemShould.cs b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Tests/EditMode/AvatarShapeVisibilitySystemShould.cs index 0500365d224..7f62f5296fe 100644 --- a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Tests/EditMode/AvatarShapeVisibilitySystemShould.cs +++ b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/Tests/EditMode/AvatarShapeVisibilitySystemShould.cs @@ -421,10 +421,6 @@ public void ResetDitherStateWhenAvatarShapeIsDirty() ref var shapeRef = ref world.Get(playerEntity); shapeRef.IsDirty = true; - // Add skinning component for dither test - var skinningMaterials = new List(); - var skinningComponent = new AvatarCustomSkinningComponent(); - // Act - This update should trigger ResetDitherState due to IsDirty system.Update(0); diff --git a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/UnityInterface/AvatarBase.cs b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/UnityInterface/AvatarBase.cs index 4d1be6b251f..4aa6702a660 100644 --- a/Explorer/Assets/DCL/AvatarRendering/AvatarShape/UnityInterface/AvatarBase.cs +++ b/Explorer/Assets/DCL/AvatarRendering/AvatarShape/UnityInterface/AvatarBase.cs @@ -192,6 +192,8 @@ private MaskedLegacyEmoteBlender AddOrGetMaskedLegacyBlender() public void StartMaskedLegacyEmote(AnimationClip clip, AvatarMask avatarMask, bool loop) { + if (AvatarAnimator == null) return; + // Keep the Animator enabled so locomotion stays driving the bones we restore each frame. AvatarAnimator.enabled = true; AddOrGetMaskedLegacyBlender().Play(clip, avatarMask, loop); @@ -200,15 +202,22 @@ public void StartMaskedLegacyEmote(AnimationClip clip, AvatarMask avatarMask, bo public void StopMaskedLegacyEmote() => maskedLegacyBlender?.Stop(); - public void SetPointAtLayerWeight(float weight) => + public void SetPointAtLayerWeight(float weight) + { + if (AvatarAnimator == null) return; AvatarAnimator.SetLayerWeight(rightPointAtLayerIndex, weight); + } - public void SetRotationLayerWeight(float weight) => + public void SetRotationLayerWeight(float weight) + { + if (AvatarAnimator == null) return; AvatarAnimator.SetLayerWeight(rotationLayerIndex, weight); + } public void SetAnimatorFloat(int hash, float value) { if (IsLegacyAnimationPlaying) return; + if (AvatarAnimator == null) return; if (AvatarAnimator.GetFloat(hash).Equals(value)) return; AvatarAnimator.enabled = true; @@ -218,6 +227,7 @@ public void SetAnimatorFloat(int hash, float value) public void SetAnimatorInt(int hash, int value) { if (IsLegacyAnimationPlaying) return; + if (AvatarAnimator == null) return; if (AvatarAnimator.GetInteger(hash).Equals(value)) return; AvatarAnimator.enabled = true; @@ -227,22 +237,28 @@ public void SetAnimatorInt(int hash, int value) public void SetAnimatorTrigger(int hash) { if (IsLegacyAnimationPlaying) return; + if (AvatarAnimator == null) return; AvatarAnimator.enabled = true; AvatarAnimator.SetTrigger(hash); } public bool IsAnimatorInTag(int hashTag) => - AvatarAnimator.GetCurrentAnimatorStateInfo(0).tagHash == hashTag; + AvatarAnimator != null && AvatarAnimator.GetCurrentAnimatorStateInfo(0).tagHash == hashTag; public int GetAnimatorCurrentStateTag(string layerName) { + if (AvatarAnimator == null) return 0; + int layerIndex = AvatarAnimator.GetLayerIndex(layerName); return AvatarAnimator.GetCurrentAnimatorStateInfo(layerIndex).tagHash; } - public void ResetAnimatorTrigger(int hash) => + public void ResetAnimatorTrigger(int hash) + { + if (AvatarAnimator == null) return; AvatarAnimator.ResetTrigger(hash); + } public void ResetArmatureInclination() { @@ -260,7 +276,7 @@ public void ResetState() transform.localPosition = Vector3.zero; LegacyAnimation?.Stop(); maskedLegacyBlender?.Stop(); - AvatarAnimator.Rebind(); + if (AvatarAnimator != null) AvatarAnimator.Rebind(); HipsConstraint.data.offset = Vector3.zero; HipsConstraint.weight = 0; FeetIKRig.enabled = false; @@ -268,16 +284,19 @@ public void ResetState() public void SetLayerWeight(string layerName, float weight) { + if (AvatarAnimator == null) return; + int index = AvatarAnimator.GetLayerIndex(layerName); AvatarAnimator.SetLayerWeight(index, weight); } public bool GetAnimatorBool(int hash) => - AvatarAnimator.GetBool(hash); + AvatarAnimator != null && AvatarAnimator.GetBool(hash); public void SetAnimatorBool(int hash, bool value) { if (IsLegacyAnimationPlaying) return; + if (AvatarAnimator == null) return; if (AvatarAnimator.GetBool(hash) == value) return; AvatarAnimator.enabled = true; @@ -285,11 +304,12 @@ public void SetAnimatorBool(int hash, bool value) } public float GetAnimatorFloat(int hash) => - AvatarAnimator.GetFloat(hash); + AvatarAnimator != null ? AvatarAnimator.GetFloat(hash) : 0f; public void ReplaceEmoteAnimation(AnimationClip animationClip) { if (lastEmote == animationClip) return; + if (AvatarAnimator == null) return; overrideController["Emote"] = animationClip; AvatarAnimator.runtimeAnimatorController = overrideController; diff --git a/Explorer/Assets/DCL/Communities/CommunitiesCard/Announcements/AnnouncementCreationCardView.cs b/Explorer/Assets/DCL/Communities/CommunitiesCard/Announcements/AnnouncementCreationCardView.cs index 400e5ee34bb..ddfe3092efe 100644 --- a/Explorer/Assets/DCL/Communities/CommunitiesCard/Announcements/AnnouncementCreationCardView.cs +++ b/Explorer/Assets/DCL/Communities/CommunitiesCard/Announcements/AnnouncementCreationCardView.cs @@ -1,5 +1,6 @@ using DCL.Audio; using DCL.Chat; +using DCL.Clipboard; using DCL.Emoji; using DCL.Profiles; using DCL.UI.CustomInputField; @@ -40,6 +41,7 @@ public class AnnouncementCreationCardView : MonoBehaviour private string currentProfileThumbnailUrl = null!; private AnnouncementEmojiController? announcementEmojiController; + private ClipboardManager? subscribedClipboardManager; private void Awake() { @@ -50,17 +52,23 @@ private void Awake() announcementInput.onValueChanged.AddListener(OnAnnouncementInputValueChanged); announcementInput.PasteShortcutPerformed += OnAnnouncementInputPasteShortcut; createAnnouncementButton.onClick.AddListener(OnCreateAnnouncementButton); - ViewDependencies.ClipboardManager.OnPaste += OnPasteClipboardText; + subscribedClipboardManager = ViewDependencies.ClipboardManager; + subscribedClipboardManager.OnPaste += OnPasteClipboardText; } private void OnDestroy() { - announcementInput.onSelect.RemoveListener(OnAnnouncementInputSelected); - announcementInput.onDeselect.RemoveListener(OnAnnouncementInputDeselected); - announcementInput.onValueChanged.RemoveListener(OnAnnouncementInputValueChanged); - announcementInput.PasteShortcutPerformed -= OnAnnouncementInputPasteShortcut; - createAnnouncementButton.onClick.RemoveListener(OnCreateAnnouncementButton); - ViewDependencies.ClipboardManager.OnPaste -= OnPasteClipboardText; + if (announcementInput != null) + { + announcementInput.onSelect.RemoveListener(OnAnnouncementInputSelected); + announcementInput.onDeselect.RemoveListener(OnAnnouncementInputDeselected); + announcementInput.onValueChanged.RemoveListener(OnAnnouncementInputValueChanged); + announcementInput.PasteShortcutPerformed -= OnAnnouncementInputPasteShortcut; + } + if (createAnnouncementButton != null) + createAnnouncementButton.onClick.RemoveListener(OnCreateAnnouncementButton); + if (subscribedClipboardManager != null) + subscribedClipboardManager.OnPaste -= OnPasteClipboardText; announcementEmojiController?.Dispose(); } diff --git a/Explorer/Assets/DCL/Communities/CommunitiesCard/Events/EventListItemView.cs b/Explorer/Assets/DCL/Communities/CommunitiesCard/Events/EventListItemView.cs index 81c9df67a82..b865fa33a3b 100644 --- a/Explorer/Assets/DCL/Communities/CommunitiesCard/Events/EventListItemView.cs +++ b/Explorer/Assets/DCL/Communities/CommunitiesCard/Events/EventListItemView.cs @@ -91,10 +91,6 @@ public void UpdateInterestedCounter() { //Disabled because of https://github.com/decentraland/unity-explorer/issues/5154 interestedContainer.SetActive(false); - return; - - eventInterestedUsersText.text = eventData!.Value.Event.total_attendees.ToString(); - interestedContainer.SetActive(eventData!.Value.Event is { live: false, total_attendees: > 0 }); } public void SubscribeToInteractions(Action mainAction, diff --git a/Explorer/Assets/DCL/InWorldCamera/InWorldCamera/Systems/InWorldCameraPlugin.cs b/Explorer/Assets/DCL/InWorldCamera/InWorldCamera/Systems/InWorldCameraPlugin.cs index 7a9cc9346bc..352c7d25660 100644 --- a/Explorer/Assets/DCL/InWorldCamera/InWorldCamera/Systems/InWorldCameraPlugin.cs +++ b/Explorer/Assets/DCL/InWorldCamera/InWorldCamera/Systems/InWorldCameraPlugin.cs @@ -56,6 +56,7 @@ public class InWorldCameraPlugin : IDCLGlobalPlugin private readonly InWorldCameraFactory factory; private readonly ICameraReelStorageService cameraReelStorageService; private readonly ICameraReelScreenshotsStorage cameraReelScreenshotsStorage; + private readonly CancellationTokenSource pluginCts = new (); private readonly IMVCManager mvcManager; private readonly ISystemClipboard systemClipboard; private readonly IDecentralandUrlsSource decentralandUrlsSource; @@ -133,6 +134,8 @@ public InWorldCameraPlugin(SelfProfile selfProfile, public void Dispose() { + web3IdentityCache.OnIdentityChanged -= FetchCameraReelStorage; + pluginCts.SafeCancelAndDispose(); factory.Dispose(); dclInput.InWorldCamera.ToggleInWorldCamera.performed -= OnShortcutToggleInWorldCameraPressed; } @@ -212,7 +215,7 @@ private void FetchCameraReelStorage() if (web3IdentityCache.Identity == null) return; - cameraReelStorageService.GetUserGalleryStorageInfoAsync(web3IdentityCache.Identity.Address, CancellationToken.None).Forget(); + cameraReelStorageService.GetUserGalleryStorageInfoAsync(web3IdentityCache.Identity.Address, pluginCts.Token).Forget(); } [Serializable] diff --git a/Explorer/Assets/DCL/InWorldCamera/InWorldCamera/UI/InWorldCameraController.cs b/Explorer/Assets/DCL/InWorldCamera/InWorldCamera/UI/InWorldCameraController.cs index 501d32a8892..55b16b01810 100644 --- a/Explorer/Assets/DCL/InWorldCamera/InWorldCamera/UI/InWorldCameraController.cs +++ b/Explorer/Assets/DCL/InWorldCamera/InWorldCamera/UI/InWorldCameraController.cs @@ -159,7 +159,7 @@ private void ToggleShortcutsInfoAsync(bool toOpen) { if (toOpen) { - viewInstance!.ShortcutsInfoPanel.ShowAsync(CancellationToken.None).Forget(); + viewInstance!.ShortcutsInfoPanel.ShowAsync(ctx.Token).Forget(); viewInstance.ShortcutsInfoPanel.Closed += OnShortcutsInfoPanelClosed; viewInstance.ShortcutsInfoButton.OnSelect(null); shortcutPanelIsOpen = true; @@ -169,7 +169,7 @@ private void ToggleShortcutsInfoAsync(bool toOpen) if (viewInstance != null) { viewInstance.ShortcutsInfoPanel.Closed -= OnShortcutsInfoPanelClosed; - viewInstance.ShortcutsInfoPanel.HideAsync(CancellationToken.None).Forget(); + viewInstance.ShortcutsInfoPanel.HideAsync(ctx.Token).Forget(); viewInstance.ShortcutsInfoButton.OnDeselect(null); } diff --git a/Explorer/Assets/DCL/Infrastructure/ECS/Unity/GLTFContainer/Systems/ConfigureGltfContainerColliders.cs b/Explorer/Assets/DCL/Infrastructure/ECS/Unity/GLTFContainer/Systems/ConfigureGltfContainerColliders.cs index b61744b6ea2..3a1570a5e60 100644 --- a/Explorer/Assets/DCL/Infrastructure/ECS/Unity/GLTFContainer/Systems/ConfigureGltfContainerColliders.cs +++ b/Explorer/Assets/DCL/Infrastructure/ECS/Unity/GLTFContainer/Systems/ConfigureGltfContainerColliders.cs @@ -93,7 +93,7 @@ private static void TryInstantiateVisibleMeshesColliders(GltfContainerAsset asse MeshCollider newCollider = go.AddComponent(); // TODO Jobify: can be invoked from a worker thread - Physics.BakeMesh(mesh.GetInstanceID(), false); + Physics.BakeMesh(mesh.GetEntityId(), false); newCollider.sharedMesh = mesh; diff --git a/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/DebugSettings/DebugSettings.cs b/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/DebugSettings/DebugSettings.cs index 3c7c64ba976..028e0f3e6ac 100644 --- a/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/DebugSettings/DebugSettings.cs +++ b/Explorer/Assets/DCL/Infrastructure/Global/Dynamic/DebugSettings/DebugSettings.cs @@ -43,7 +43,7 @@ [SerializeField] [Tooltip("Base gatekeeper URL used only when Gatekeeper Mode is private string customGatekeeperUrl = string.Empty; [Space] [SerializeField] - private string[] appParameters; + private string[] appParameters = System.Array.Empty(); public static DebugSettings Release() => new () diff --git a/Explorer/Assets/DCL/Infrastructure/Global/Versioning/DCLVersion.cs b/Explorer/Assets/DCL/Infrastructure/Global/Versioning/DCLVersion.cs index 69312d0075d..bb8ad6bf924 100644 --- a/Explorer/Assets/DCL/Infrastructure/Global/Versioning/DCLVersion.cs +++ b/Explorer/Assets/DCL/Infrastructure/Global/Versioning/DCLVersion.cs @@ -55,8 +55,9 @@ static string FromGitCommand(string arguments) return output.Trim(); } -#endif +#else return null; +#endif } } } diff --git a/Explorer/Assets/DCL/Infrastructure/SceneLifeCycle/Systems/LoadSmartWearablePreviewSceneSystem.cs b/Explorer/Assets/DCL/Infrastructure/SceneLifeCycle/Systems/LoadSmartWearablePreviewSceneSystem.cs index 4fb5076a18e..0187741056e 100644 --- a/Explorer/Assets/DCL/Infrastructure/SceneLifeCycle/Systems/LoadSmartWearablePreviewSceneSystem.cs +++ b/Explorer/Assets/DCL/Infrastructure/SceneLifeCycle/Systems/LoadSmartWearablePreviewSceneSystem.cs @@ -19,6 +19,7 @@ using System.Linq; using System.Text; using System.Threading; +using Utility; namespace ECS.SceneLifeCycle.Systems { @@ -31,12 +32,19 @@ public partial class LoadSmartWearablePreviewSceneSystem : BaseUnityLoopSystem private readonly IWebRequestController webRequestController; private readonly IDecentralandUrlsSource urlsSource; + private readonly CancellationTokenSource systemCts = new (); + public LoadSmartWearablePreviewSceneSystem(World world, IWebRequestController webRequestController, IDecentralandUrlsSource urlsSource) : base(world) { this.webRequestController = webRequestController; this.urlsSource = urlsSource; } + protected override void OnDispose() + { + systemCts.SafeCancelAndDispose(); + } + protected override void Update(float t) { LoadPreviewSceneQuery(World); @@ -49,7 +57,7 @@ private void LoadPreviewScene(Entity entity, RealmComponent realm) { World.Add(entity, new SmartWearablePreviewScene { Value = Entity.Null }); - TryLoadPreviewSceneAsync(entity, realm.Ipfs, CancellationToken.None).Forget(); + TryLoadPreviewSceneAsync(entity, realm.Ipfs, systemCts.Token).Forget(); } [Query] diff --git a/Explorer/Assets/DCL/Infrastructure/SceneRunner/Scene/HibridScene/IGetHash.cs b/Explorer/Assets/DCL/Infrastructure/SceneRunner/Scene/HibridScene/IGetHash.cs index a9330509cd7..f35ed56b476 100644 --- a/Explorer/Assets/DCL/Infrastructure/SceneRunner/Scene/HibridScene/IGetHash.cs +++ b/Explorer/Assets/DCL/Infrastructure/SceneRunner/Scene/HibridScene/IGetHash.cs @@ -36,7 +36,11 @@ public class GetHashGoerli : IGetHash } } catch (OperationCanceledException) { throw; } - catch (Exception) { } + catch (Exception e) + { + ReportHub.LogError(reportCategory, $"Hybrid scene fetch failed at {coordinate}: {e.GetType().Name}: {e.Message}"); + return (false, ""); + } ReportHub.LogError(reportCategory, $"Trying to load hybrid scene with coordinates {coordinate} failed. You wont get the asset bundles"); return (false, ""); @@ -77,7 +81,11 @@ public GetHashWorld(string world, string? worldContentServerBaseUrl = null) } } catch (OperationCanceledException) { throw; } - catch (Exception) { } + catch (Exception e) + { + ReportHub.LogError(reportCategory, $"Hybrid scene fetch failed at {coordinate}: {e.GetType().Name}: {e.Message}"); + return (false, ""); + } ReportHub.LogError(reportCategory, $"Trying to load hybrid scene with coordinates {coordinate} failed. You wont get the asset bundles"); return (false, ""); @@ -97,10 +105,11 @@ public class GetHashGenesis : IGetHash return (true, getSceneDefinition[0].id!); } catch (OperationCanceledException) { throw; } - catch (Exception) { } - - ReportHub.LogError(reportCategory, $"Trying to load hybrid scene with coordinates {coordinate} failed. You wont get the asset bundles"); - return (false, ""); + catch (Exception e) + { + ReportHub.LogError(reportCategory, $"Hybrid scene fetch failed at {coordinate}: {e.GetType().Name}: {e.Message}"); + return (false, ""); + } } } } diff --git a/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFactory.cs b/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFactory.cs index 57b80df8ba6..e5e2093a497 100644 --- a/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFactory.cs +++ b/Explorer/Assets/DCL/Infrastructure/SceneRunner/SceneFactory.cs @@ -198,6 +198,10 @@ private async UniTask CreateSceneAsync(ISceneData sceneData, IJsAp var engineAPIMutexOwner = new MultiThreadSync.Owner(nameof(EngineAPIImplementation)); var ethereumApiImpl = new RestrictedEthereumApi(ethereumApi, permissionsProvider); + // ENABLE_SDK_OBSERVABLES is a deliberate compile-time toggle; the else branch is kept intact + // so the SDK-observables feature can be disabled by flipping the constant. Suppress the + // unreachable-code warning for the currently-disabled branch without removing it. +#pragma warning disable CS0162 if (ENABLE_SDK_OBSERVABLES) { var sdkCommsControllerAPI = new SDKMessageBusCommsAPIImplementation(sceneData, messagePipesHub, sceneRuntime); @@ -262,6 +266,7 @@ private async UniTask CreateSceneAsync(ISceneData sceneData, IJsAp deps.RuntimeMetrics ); } +#pragma warning restore CS0162 try { diff --git a/Explorer/Assets/DCL/Landscape/Systems/CollideTerrainSystem.cs b/Explorer/Assets/DCL/Landscape/Systems/CollideTerrainSystem.cs index 0071fe28204..506bed31b69 100644 --- a/Explorer/Assets/DCL/Landscape/Systems/CollideTerrainSystem.cs +++ b/Explorer/Assets/DCL/Landscape/Systems/CollideTerrainSystem.cs @@ -141,7 +141,7 @@ protected override void Update(float t) NativeArrayOptions.UninitializedMemory); for (int i = 0; i < dirtyParcels.Count; i++) - meshes[i] = dirtyParcels[i].Mesh.GetInstanceID(); + meshes[i] = dirtyParcels[i].Mesh.GetEntityId(); var bakeColliderMeshesJob = new BakeColliderMeshes() { Meshes = meshes }; bakeColliderMeshesJob.Schedule(meshes.Length, 1).Complete(); diff --git a/Explorer/Assets/DCL/MapRenderer/MapLayers/Categories/CategoryControllers/CategoryMarkersController.cs b/Explorer/Assets/DCL/MapRenderer/MapLayers/Categories/CategoryControllers/CategoryMarkersController.cs index df96304c909..992d066e41f 100644 --- a/Explorer/Assets/DCL/MapRenderer/MapLayers/Categories/CategoryControllers/CategoryMarkersController.cs +++ b/Explorer/Assets/DCL/MapRenderer/MapLayers/Categories/CategoryControllers/CategoryMarkersController.cs @@ -108,10 +108,7 @@ private void OnPlaceSearched(INavmapBus.SearchPlaceParams searchparams, IReadOnl } } - public async UniTask InitializeAsync(CancellationToken cancellationToken) - { - - } + public UniTask InitializeAsync(CancellationToken cancellationToken) => UniTask.CompletedTask; private void ShowPlaces(IReadOnlyList places, CategoriesEnum mapLayer) { @@ -181,7 +178,7 @@ public UniTask Disable(CancellationToken cancellationToken) return UniTask.CompletedTask; } - public async UniTask EnableAsync(CancellationToken cancellationToken) + public UniTask EnableAsync(CancellationToken cancellationToken) { foreach (ICategoryMarker marker in markers.Values) mapCullingController.StartTracking(marker, this); @@ -193,6 +190,7 @@ public async UniTask EnableAsync(CancellationToken cancellationToken) } isEnabled = true; + return UniTask.CompletedTask; } public void ResetToBaseScale() diff --git a/Explorer/Assets/DCL/MapRenderer/MapLayers/HomeMarker/HomeMarkerController.cs b/Explorer/Assets/DCL/MapRenderer/MapLayers/HomeMarker/HomeMarkerController.cs index 4c571085eb4..c7d7ced7959 100644 --- a/Explorer/Assets/DCL/MapRenderer/MapLayers/HomeMarker/HomeMarkerController.cs +++ b/Explorer/Assets/DCL/MapRenderer/MapLayers/HomeMarker/HomeMarkerController.cs @@ -183,7 +183,7 @@ public bool TryHighlightObject(GameObject gameObject, out IMapRendererMarker? ma { mapMarker = null; - if (gameObject.GetInstanceID() != homeMarker.MarkerObject.gameObject.GetInstanceID()) + if (gameObject.GetEntityId() != homeMarker.MarkerObject.gameObject.GetEntityId()) return false; mapMarker = homeMarker; @@ -194,7 +194,7 @@ public bool TryHighlightObject(GameObject gameObject, out IMapRendererMarker? ma public bool TryDeHighlightObject(GameObject gameObject) { - if (gameObject.GetInstanceID() != homeMarker.MarkerObject.gameObject.GetInstanceID()) + if (gameObject.GetEntityId() != homeMarker.MarkerObject.gameObject.GetEntityId()) return false; deHighlightCt = deHighlightCt.SafeRestart(); @@ -206,7 +206,7 @@ public bool TryClickObject(GameObject gameObject, CancellationTokenSource cts, o { mapRenderMarker = null; - if (gameObject.GetInstanceID() != homeMarker.MarkerObject.gameObject.GetInstanceID()) + if (gameObject.GetEntityId() != homeMarker.MarkerObject.gameObject.GetEntityId()) return false; DisplayPlacesInfoPanelAsync(CurrentCoordinates).Forget(); diff --git a/Explorer/Assets/DCL/MapRenderer/MapLayers/LiveEvents/LiveEventsMarkersController.cs b/Explorer/Assets/DCL/MapRenderer/MapLayers/LiveEvents/LiveEventsMarkersController.cs index 0b5a4a5616e..02ee0b0417d 100644 --- a/Explorer/Assets/DCL/MapRenderer/MapLayers/LiveEvents/LiveEventsMarkersController.cs +++ b/Explorer/Assets/DCL/MapRenderer/MapLayers/LiveEvents/LiveEventsMarkersController.cs @@ -68,9 +68,7 @@ public LiveEventsMarkersController( this.navmapBus = navmapBus; } - public async UniTask InitializeAsync(CancellationToken cancellationToken) - { - } + public UniTask InitializeAsync(CancellationToken cancellationToken) => UniTask.CompletedTask; public void ApplyCameraZoom(float baseZoom, float zoom, int zoomLevel) { diff --git a/Explorer/Assets/DCL/MapRenderer/MapLayers/PointsOfInterest/ScenesOfInterestMarkersController.cs b/Explorer/Assets/DCL/MapRenderer/MapLayers/PointsOfInterest/ScenesOfInterestMarkersController.cs index 76b2d4fc696..8d1ef3b101e 100644 --- a/Explorer/Assets/DCL/MapRenderer/MapLayers/PointsOfInterest/ScenesOfInterestMarkersController.cs +++ b/Explorer/Assets/DCL/MapRenderer/MapLayers/PointsOfInterest/ScenesOfInterestMarkersController.cs @@ -72,7 +72,7 @@ public ScenesOfInterestMarkersController( this.navmapBus = navmapBus; } - public async UniTask InitializeAsync(CancellationToken cancellationToken) { } + public UniTask InitializeAsync(CancellationToken cancellationToken) => UniTask.CompletedTask; protected override void DisposeImpl() { diff --git a/Explorer/Assets/DCL/MapRenderer/MapLayers/SearchResults/SearchResultMarkersController.cs b/Explorer/Assets/DCL/MapRenderer/MapLayers/SearchResults/SearchResultMarkersController.cs index b392f7f1050..2db034a19e1 100644 --- a/Explorer/Assets/DCL/MapRenderer/MapLayers/SearchResults/SearchResultMarkersController.cs +++ b/Explorer/Assets/DCL/MapRenderer/MapLayers/SearchResults/SearchResultMarkersController.cs @@ -79,7 +79,7 @@ private void OnClearPlacesFromMap() ReleaseMarkers(); } - public async UniTask InitializeAsync(CancellationToken cancellationToken) { } + public UniTask InitializeAsync(CancellationToken cancellationToken) => UniTask.CompletedTask; private void OnPlaceSearched(INavmapBus.SearchPlaceParams searchParams, IReadOnlyList places, int totalResultCount) @@ -148,7 +148,7 @@ public UniTask Disable(CancellationToken cancellationToken) return UniTask.CompletedTask; } - public async UniTask EnableAsync(CancellationToken cancellationToken) + public UniTask EnableAsync(CancellationToken cancellationToken) { foreach (ISearchResultMarker marker in markers.Values) mapCullingController.StartTracking(marker, this); @@ -160,6 +160,7 @@ public async UniTask EnableAsync(CancellationToken cancellationToken) } isEnabled = true; + return UniTask.CompletedTask; } public void ResetToBaseScale() diff --git a/Explorer/Assets/DCL/PluginSystem/Global/ChatPlugin.cs b/Explorer/Assets/DCL/PluginSystem/Global/ChatPlugin.cs index dfba2e786b7..c9f2577c247 100644 --- a/Explorer/Assets/DCL/PluginSystem/Global/ChatPlugin.cs +++ b/Explorer/Assets/DCL/PluginSystem/Global/ChatPlugin.cs @@ -193,6 +193,9 @@ public ChatPlugin( public void Dispose() { + web3IdentityCache.OnIdentityCleared -= OnIdentityCleared; + web3IdentityCache.OnIdentityChanged -= OnIdentityChanged; + if (messageReactionService != null && chatStorage != null) messageReactionService.ReactionPersistenceRequested -= chatStorage.OnReactionPersistenceRequested; @@ -448,7 +451,7 @@ private void OnIdentityCleared() commandRegistry?.ResetChat.Execute(); if (chatSharedAreaController is { IsVisible: true }) - chatSharedAreaController.HideViewAsync(CancellationToken.None).Forget(); + chatSharedAreaController.HideViewAsync(pluginCts.Token).Forget(); } private void OnIdentityChanged() diff --git a/Explorer/Assets/DCL/PluginSystem/Global/InputPlugin.cs b/Explorer/Assets/DCL/PluginSystem/Global/InputPlugin.cs index bed9c725dba..bbf1c7a88a2 100644 --- a/Explorer/Assets/DCL/PluginSystem/Global/InputPlugin.cs +++ b/Explorer/Assets/DCL/PluginSystem/Global/InputPlugin.cs @@ -93,6 +93,7 @@ public void InjectToWorld(ref ArchSystemsWorldBuilder builder, public void Dispose() { + DCLInput.Instance.Disable(); DCLInput.Reset(); } } diff --git a/Explorer/Assets/DCL/Roads/Data/Editor/RoadAssetGenerator.cs b/Explorer/Assets/DCL/Roads/Data/Editor/RoadAssetGenerator.cs index 6cd686dd136..a0ca8ba09d2 100644 --- a/Explorer/Assets/DCL/Roads/Data/Editor/RoadAssetGenerator.cs +++ b/Explorer/Assets/DCL/Roads/Data/Editor/RoadAssetGenerator.cs @@ -56,7 +56,7 @@ private static void BuildRoads() if (child.name.Contains("_collider")) { MeshFilter meshFilter = child.GetComponent(); - Physics.BakeMesh(meshFilter.sharedMesh.GetInstanceID(), false); + Physics.BakeMesh(meshFilter.sharedMesh.GetEntityId(), false); meshFilter.gameObject.AddComponent(); if (meshFilter != null) diff --git a/Explorer/Assets/DCL/Settings/Configuration/SettingsModuleBindings.cs b/Explorer/Assets/DCL/Settings/Configuration/SettingsModuleBindings.cs index e1db2bf283e..daff07fb07e 100644 --- a/Explorer/Assets/DCL/Settings/Configuration/SettingsModuleBindings.cs +++ b/Explorer/Assets/DCL/Settings/Configuration/SettingsModuleBindings.cs @@ -49,9 +49,9 @@ public abstract class SettingsModuleBinding : S where TConfig : SettingsModuleViewConfiguration where TControllerType : Enum { - [field: SerializeField] public ViewRef View { get; private set; } - [field: SerializeField] public TConfig Config { get; private set; } - [field: SerializeField] public TControllerType Feature { get; private set; } + [field: SerializeField] public ViewRef View { get; private set; } = null!; + [field: SerializeField] public TConfig Config { get; private set; } = null!; + [field: SerializeField] public TControllerType Feature { get; private set; } = default!; [Serializable] public class ViewRef : ComponentReference diff --git a/Explorer/Assets/DCL/SkyBox/SkyboxRenderController.cs b/Explorer/Assets/DCL/SkyBox/SkyboxRenderController.cs index 4baa9eb56cc..395a818a26d 100644 --- a/Explorer/Assets/DCL/SkyBox/SkyboxRenderController.cs +++ b/Explorer/Assets/DCL/SkyBox/SkyboxRenderController.cs @@ -55,26 +55,26 @@ public class LensFlareTimeEntry private LensFlareDataSRP? activeLensFlareData; [Header("Skybox Color")] - [GradientUsage(true)] [SerializeField] private Gradient skyZenitColorRamp; - [GradientUsage(true)] [SerializeField] private Gradient skyHorizonColorRamp; - [GradientUsage(true)] [SerializeField] private Gradient skyNadirColorRamp; + [GradientUsage(true)] [SerializeField] private Gradient skyZenitColorRamp = null!; + [GradientUsage(true)] [SerializeField] private Gradient skyHorizonColorRamp = null!; + [GradientUsage(true)] [SerializeField] private Gradient skyNadirColorRamp = null!; [InspectorName("Rim Light Color")] - [GradientUsage(true)] [SerializeField] private Gradient rimColorRamp; + [GradientUsage(true)] [SerializeField] private Gradient rimColorRamp = null!; [Header("Indirect Lighting")] [InspectorName("Enabled")] [SerializeField] private bool indirectLight = true; - [GradientUsage(true)] [SerializeField] private Gradient indirectSkyRamp; - [GradientUsage(true)] [SerializeField] private Gradient indirectEquatorRamp; - [GradientUsage(true)] [SerializeField] private Gradient groundEquatorRamp; + [GradientUsage(true)] [SerializeField] private Gradient indirectSkyRamp = null!; + [GradientUsage(true)] [SerializeField] private Gradient indirectEquatorRamp = null!; + [GradientUsage(true)] [SerializeField] private Gradient groundEquatorRamp = null!; [Header("Clouds")] - [GradientUsage(true)] [SerializeField] private Gradient cloudsColorRamp; - [SerializeField] private AnimationCurve cloudsHighlightsIntensity; + [GradientUsage(true)] [SerializeField] private Gradient cloudsColorRamp = null!; + [SerializeField] private AnimationCurve cloudsHighlightsIntensity = null!; [Header("Fog")] [InspectorName("Enabled")] [SerializeField] private bool fog = true; - [GradientUsage(true)] [SerializeField] private Gradient fogColorRamp; + [GradientUsage(true)] [SerializeField] private Gradient fogColorRamp = null!; private Material skyboxMaterial; diff --git a/Explorer/Assets/DCL/UserInAppInitializationFlow/RealUserInAppInitializationFlow.cs b/Explorer/Assets/DCL/UserInAppInitializationFlow/RealUserInAppInitializationFlow.cs index 7ea1443c8be..1b989d4e286 100644 --- a/Explorer/Assets/DCL/UserInAppInitializationFlow/RealUserInAppInitializationFlow.cs +++ b/Explorer/Assets/DCL/UserInAppInitializationFlow/RealUserInAppInitializationFlow.cs @@ -233,8 +233,13 @@ await UniTask.WhenAll( if (result.Success == false) { //Fail straight away - string message = result.Error.AsMessage(); - ReportHub.LogError(ReportCategory.AUTHENTICATION, message); + // Do not log cancellation as an error (CLAUDE.md §9): on shutdown the loading result + // is a propagated TaskError.Cancelled, not a genuine auth failure. + if (result.Error?.State != TaskError.Cancelled && !ct.IsCancellationRequested) + { + string message = result.Error.AsMessage(); + ReportHub.LogError(ReportCategory.AUTHENTICATION, message); + } } } while (result.Success == false && parameters.ShowAuthentication); diff --git a/Explorer/Assets/DCL/UserInAppInitializationFlow/StartupOperations/LoadPlayerAvatarStartupOperation.cs b/Explorer/Assets/DCL/UserInAppInitializationFlow/StartupOperations/LoadPlayerAvatarStartupOperation.cs index 7b2c77b6f24..7f0bbb3b3ab 100644 --- a/Explorer/Assets/DCL/UserInAppInitializationFlow/StartupOperations/LoadPlayerAvatarStartupOperation.cs +++ b/Explorer/Assets/DCL/UserInAppInitializationFlow/StartupOperations/LoadPlayerAvatarStartupOperation.cs @@ -33,6 +33,12 @@ protected override async UniTask InternalExecuteAsync(IStartupOperation.Params a Profile? profile = await selfProfile.ProfileAsync(ct); args.Report.SetProgress(finalizationProgress); + // A null profile must fail the operation: adding it to the world poisons every + // Profile-querying system with a per-frame NRE (observed when the profiles endpoint + // returns no avatars for the signed-in wallet). + if (profile == null) + throw new System.InvalidOperationException("Self profile could not be resolved (profiles endpoint returned no avatar for the signed-in wallet) — cannot create the player avatar."); + // Add the profile into the player entity so it will create the avatar in world World world = args.FlowParameters.World; diff --git a/Explorer/Assets/DCL/VoiceChat/CommunityVoiceChat/VoiceChatParticipantEntryPresenter.cs b/Explorer/Assets/DCL/VoiceChat/CommunityVoiceChat/VoiceChatParticipantEntryPresenter.cs index 0873ab7a374..af58734c4dd 100644 --- a/Explorer/Assets/DCL/VoiceChat/CommunityVoiceChat/VoiceChatParticipantEntryPresenter.cs +++ b/Explorer/Assets/DCL/VoiceChat/CommunityVoiceChat/VoiceChatParticipantEntryPresenter.cs @@ -75,6 +75,8 @@ private void OnOpenPassport() { if (string.IsNullOrEmpty(currentParticipantState.WalletId)) return; + // deliberately not tied to this pooled entry's cts: the open passport must survive + // the entry being recycled (participant leaves, list rebuild) OpenPassportAsync(currentParticipantState.WalletId, CancellationToken.None).Forget(); return; diff --git a/Explorer/Assets/DCL/VoiceChat/PrivateVoiceChat/PrivateVoiceChatCallStatusServiceNull.cs b/Explorer/Assets/DCL/VoiceChat/PrivateVoiceChat/PrivateVoiceChatCallStatusServiceNull.cs index 312b02d96bc..305f0361b93 100644 --- a/Explorer/Assets/DCL/VoiceChat/PrivateVoiceChat/PrivateVoiceChatCallStatusServiceNull.cs +++ b/Explorer/Assets/DCL/VoiceChat/PrivateVoiceChat/PrivateVoiceChatCallStatusServiceNull.cs @@ -7,7 +7,7 @@ namespace DCL.VoiceChat public class PrivateVoiceChatCallStatusServiceNull : IPrivateVoiceChatCallStatusService { public string CurrentTargetWallet { get; } - public event Action? PrivateVoiceChatUpdateReceived; + public event Action? PrivateVoiceChatUpdateReceived { add { } remove { } } public IReadonlyReactiveProperty Status { get; } = new ReactiveProperty(VoiceChatStatus.DISCONNECTED); public IReadonlyReactiveProperty CallId { get; } = new ReactiveProperty(string.Empty); public string ConnectionUrl { get; }