From 8e9aa549a671c6d041060d860d7a716b9f7c9cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20D=C3=ADaz?= Date: Fri, 18 Oct 2024 14:54:56 -0300 Subject: [PATCH 01/16] refactor: Use the bucket public url (#2486) * fix: Use the bucket public url * fix: Branch name reference * refactor: Use a defined github var --- .github/workflows/pr-comment-artifact-url.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr-comment-artifact-url.yml b/.github/workflows/pr-comment-artifact-url.yml index 6668c5a81d..6e1b13e99b 100644 --- a/.github/workflows/pr-comment-artifact-url.yml +++ b/.github/workflows/pr-comment-artifact-url.yml @@ -58,7 +58,9 @@ jobs: if [[ $GITHUB_REF == refs/tags/v* ]]; then ARTIFACT_S3_DESTINATION_PATH="@dcl/$REPO/releases/$GITHUB_REF_NAME" else - ARTIFACT_S3_DESTINATION_PATH="@dcl/$REPO/branch/${GITHUB_HEAD_REF:-$GITHUB_REF_NAME}" + HEAD_BRANCH=$(jq -r '.pull_requests[0].head.ref' \ + <<< "$WORKFLOW_RUN_EVENT_OBJ") + ARTIFACT_S3_DESTINATION_PATH="@dcl/$REPO/branch/$HEAD_BRANCH" fi echo "Artifact S3 Destination Path: $ARTIFACT_S3_DESTINATION_PATH" @@ -90,9 +92,9 @@ jobs: env: JOB_PATH: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ env.PREVIOUS_JOB_ID }}" WINDOWS_ARTIFACT_URL: "${{ github.server_url }}/${{ github.repository }}/suites/${{ env.SUITE_ID }}/artifacts/${{ env.WINDOWS_ARTIFACT_ID }}" - WINDOWS_ARTIFACT_S3_URL: "${{ format('https://{0}.s3.amazonaws.com/{1}/Decentraland_windows64.zip', secrets.EXPLORER_TEAM_S3_BUCKET, env.ARTIFACT_S3_DESTINATION_PATH) }}" + WINDOWS_ARTIFACT_S3_URL: "${{ format('{0}/{1}/Decentraland_windows64.zip', vars.EXPLORER_TEAM_S3_BUCKET_PUBLIC_URL, env.ARTIFACT_S3_DESTINATION_PATH) }}" MAC_ARTIFACT_URL: "${{ github.server_url }}/${{ github.repository }}/suites/${{ env.SUITE_ID }}/artifacts/${{ env.MAC_ARTIFACT_ID }}" - MAC_ARTIFACT_S3_URL: "${{ format('https://{0}.s3.amazonaws.com/{1}/Decentraland_macos.zip', secrets.EXPLORER_TEAM_S3_BUCKET, env.ARTIFACT_S3_DESTINATION_PATH) }}" + MAC_ARTIFACT_S3_URL: "${{ format('{0}/{1}/Decentraland_macos.zip', vars.EXPLORER_TEAM_S3_BUCKET_PUBLIC_URL, env.ARTIFACT_S3_DESTINATION_PATH) }}" HEAD_SHA: "${{ env.HEAD_SHA }}" uses: peter-evans/create-or-update-comment@v3 with: From cf56e37bae980a3fc90b6ff799bf946c29dad8cb Mon Sep 17 00:00:00 2001 From: Nicolas Lorusso <56365551+lorux0@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:53:47 -0300 Subject: [PATCH 02/16] add support for global sounds (#2495) --- .../DCL/SDKComponents/AudioSources/AudioSourceExtensions.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Explorer/Assets/DCL/SDKComponents/AudioSources/AudioSourceExtensions.cs b/Explorer/Assets/DCL/SDKComponents/AudioSources/AudioSourceExtensions.cs index 4f993e720f..f60865ca4f 100644 --- a/Explorer/Assets/DCL/SDKComponents/AudioSources/AudioSourceExtensions.cs +++ b/Explorer/Assets/DCL/SDKComponents/AudioSources/AudioSourceExtensions.cs @@ -25,6 +25,11 @@ public static void ApplyPBAudioSource(this AudioSource audioSource, PBAudioSourc audioSource.pitch = pbAudioSource.HasPitch ? pbAudioSource.Pitch : Default.PITCH; audioSource.volume = pbAudioSource.HasVolume ? pbAudioSource.Volume : Default.VOLUME; + if (pbAudioSource.HasGlobal) + audioSource.spatialBlend = pbAudioSource.Global ? 0 : 1; + else + audioSource.spatialBlend = 1; + if (audioSource.clip == null) return; audioSource.Stop(); From ed3fe4a09e0aff1e65e81bfbccddb9b518826d33 Mon Sep 17 00:00:00 2001 From: Geoff Birch <137780197+GBirch33@users.noreply.github.com> Date: Fri, 18 Oct 2024 21:12:09 +0100 Subject: [PATCH 03/16] fix: Scene Parallax Dynamic Branching fix (#2459) * Scene Parallax Dynamic Branching fix * Add the Mac shaders --- .../Assets/StreamingAssets/AssetBundles/dcl/scene_ignore_mac | 4 ++-- .../StreamingAssets/AssetBundles/dcl/scene_ignore_windows | 4 ++-- Explorer/Assets/git-submodules/unity-shared-dependencies | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Explorer/Assets/StreamingAssets/AssetBundles/dcl/scene_ignore_mac b/Explorer/Assets/StreamingAssets/AssetBundles/dcl/scene_ignore_mac index 78bc0bbd62..ecc3757fc5 100644 --- a/Explorer/Assets/StreamingAssets/AssetBundles/dcl/scene_ignore_mac +++ b/Explorer/Assets/StreamingAssets/AssetBundles/dcl/scene_ignore_mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7002bf83f45b952e7367fcfb1d1abf37530a005862ac1e5c314cb1c6280cfdaa -size 34621184 +oid sha256:1a8dba348a487140bec26eb65266e4daec7fd4d8c6f78e01e241fbfa6a4d2362 +size 3512400 diff --git a/Explorer/Assets/StreamingAssets/AssetBundles/dcl/scene_ignore_windows b/Explorer/Assets/StreamingAssets/AssetBundles/dcl/scene_ignore_windows index c7bcf62205..c0b169fb45 100644 --- a/Explorer/Assets/StreamingAssets/AssetBundles/dcl/scene_ignore_windows +++ b/Explorer/Assets/StreamingAssets/AssetBundles/dcl/scene_ignore_windows @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c0357795a51760d34098487ef6183f56c23be79df90b818bf4b1d0de706b7c6 -size 499312 +oid sha256:2388b8798dd7928076b3dad1dd4288450ef9e9f0ebadc9e2714aaaf042a7ea98 +size 660704 diff --git a/Explorer/Assets/git-submodules/unity-shared-dependencies b/Explorer/Assets/git-submodules/unity-shared-dependencies index 3eb2e64ef2..121bee35eb 160000 --- a/Explorer/Assets/git-submodules/unity-shared-dependencies +++ b/Explorer/Assets/git-submodules/unity-shared-dependencies @@ -1 +1 @@ -Subproject commit 3eb2e64ef209f47dc5adc29289fae2cd370d56cd +Subproject commit 121bee35ebc8fbca0bce5f34edfac50001f53ccd From 1c563e18c006cd1235a61b46fc84d151826a1b85 Mon Sep 17 00:00:00 2001 From: Juan Ignacio Molteni Date: Sat, 19 Oct 2024 10:07:08 -0300 Subject: [PATCH 04/16] chore: 'Cannot connect to destination hsot' mac mitigation (#2425) * Hacky force unload * More force unloading * private force unloading * Remove dependency unload * Remove Resources.Unload in aggresive strategy. Not useful * Fix cacheable url * Fixed dependency unloading * Fix main asset unload * Fix test * Fixed more tests * Fixed more tests * more mote tests * Revert priority * null check in GatherGLTFAssetsSystem.cs * Revert "Remove Resources.Unload in aggresive strategy. Not useful" This reverts commit 383e5fe9d2c73a4aa0c2cfb2581694e60d7b9f4f. * refactored unload strategy * Test coverage --- .../ResolveAvatarAttachmentThumbnailSystem.cs | 1 - .../URLHelpers/URLAddress.cs | 14 ---- .../Global/ResourceUnloadingPlugin.cs | 3 +- .../Tests/ReleaseMemorySystemShould.cs | 67 ++++++++++++------- .../AggressiveUnloadStrategy.cs | 64 ------------------ .../UnloadStrategies/IUnloadStrategy.cs | 27 +++++++- .../ReduceLoadingRadiusUnloadStrategy.cs | 24 +++++++ ...ReduceLoadingRadiusUnloadStrategy.cs.meta} | 0 .../StandardUnloadStrategy.cs | 14 +--- .../UnloadStrategies/UnloadStrategyHandler.cs | 28 ++------ .../UnloadUnusedAssetUnloadStrategy.cs | 35 ++++++++++ .../UnloadUnusedAssetUnloadStrategy.cs.meta | 3 + .../AssetBundles/AssetBundleData.cs | 44 ++++++++---- ...eAssetBundleLoadingParametersSystemBase.cs | 1 + .../Cache/RefCountStreamableCacheBase.cs | 2 + .../Components/CommonLoadingArguments.cs | 10 +++ .../Common/Systems/LoadSystemBase.cs | 10 +-- .../Asset/Tests/GltfContainerTestResources.cs | 7 +- .../Scene/SceneAssetBundleManifest.cs | 7 ++ 19 files changed, 203 insertions(+), 158 deletions(-) delete mode 100644 Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/AggressiveUnloadStrategy.cs create mode 100644 Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/ReduceLoadingRadiusUnloadStrategy.cs rename Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/{AggressiveUnloadStrategy.cs.meta => ReduceLoadingRadiusUnloadStrategy.cs.meta} (100%) create mode 100644 Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadUnusedAssetUnloadStrategy.cs create mode 100644 Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadUnusedAssetUnloadStrategy.cs.meta diff --git a/Explorer/Assets/DCL/AvatarRendering/Thumbnails/Systems/ResolveAvatarAttachmentThumbnailSystem.cs b/Explorer/Assets/DCL/AvatarRendering/Thumbnails/Systems/ResolveAvatarAttachmentThumbnailSystem.cs index 806ec9d17d..c6271ab45b 100644 --- a/Explorer/Assets/DCL/AvatarRendering/Thumbnails/Systems/ResolveAvatarAttachmentThumbnailSystem.cs +++ b/Explorer/Assets/DCL/AvatarRendering/Thumbnails/Systems/ResolveAvatarAttachmentThumbnailSystem.cs @@ -37,7 +37,6 @@ private void CompleteWearableABThumbnailDownload(Entity entity, ref IAvatarAttac if (promise.TryConsume(World, out var result)) { wearable.ThumbnailAssetResult = result.ToFullRectSpriteData(LoadThumbnailsUtils.DEFAULT_THUMBNAIL); - World.Destroy(entity); } } diff --git a/Explorer/Assets/DCL/CommunicationData/URLHelpers/URLAddress.cs b/Explorer/Assets/DCL/CommunicationData/URLHelpers/URLAddress.cs index 76540727f3..6b586700ee 100644 --- a/Explorer/Assets/DCL/CommunicationData/URLHelpers/URLAddress.cs +++ b/Explorer/Assets/DCL/CommunicationData/URLHelpers/URLAddress.cs @@ -9,21 +9,11 @@ namespace CommunicationData.URLHelpers public readonly struct URLAddress : IEquatable, IEquatable { public static readonly URLAddress EMPTY = new (string.Empty); - public readonly string Value; - private readonly string CacheableURL; - - private static readonly string HTTP_STARTER = "https"; - private static readonly string VALIDATION_PATTERN = "/v[0-9]+/"; internal URLAddress(string value) { Value = value; - - if (!string.IsNullOrEmpty(Value) && Value.StartsWith(HTTP_STARTER)) - CacheableURL = Regex.Replace(Value, VALIDATION_PATTERN, "/"); - else - CacheableURL = Value; } public static implicit operator string(in URLAddress address) => @@ -56,9 +46,5 @@ public override int GetHashCode() => public override string ToString() => Value; - public string GetCacheableURL() - { - return CacheableURL; - } } } diff --git a/Explorer/Assets/DCL/PluginSystem/Global/ResourceUnloadingPlugin.cs b/Explorer/Assets/DCL/PluginSystem/Global/ResourceUnloadingPlugin.cs index daf09236dc..09a7146375 100644 --- a/Explorer/Assets/DCL/PluginSystem/Global/ResourceUnloadingPlugin.cs +++ b/Explorer/Assets/DCL/PluginSystem/Global/ResourceUnloadingPlugin.cs @@ -11,7 +11,6 @@ public class ResourceUnloadingPlugin : IDCLGlobalPluginWithoutSettings { private readonly MemoryBudget memoryBudget; private readonly UnloadStrategyHandler unloadStrategyHandler; - private const int FRAME_FAIL_THRESHOLD = 60; public ResourceUnloadingPlugin(MemoryBudget memoryBudget, CacheCleaner cacheCleaner, @@ -19,7 +18,7 @@ public ResourceUnloadingPlugin(MemoryBudget memoryBudget, CacheCleaner cacheClea { this.memoryBudget = memoryBudget; unloadStrategyHandler = - new UnloadStrategyHandler(realmPartitionSettings, FRAME_FAIL_THRESHOLD, cacheCleaner); + new UnloadStrategyHandler(realmPartitionSettings, cacheCleaner); } public void InjectToWorld(ref ArchSystemsWorldBuilder builder, in GlobalPluginArguments arguments) diff --git a/Explorer/Assets/DCL/ResourcesUnloading/Tests/ReleaseMemorySystemShould.cs b/Explorer/Assets/DCL/ResourcesUnloading/Tests/ReleaseMemorySystemShould.cs index d08f59e61e..a523ad7e8a 100644 --- a/Explorer/Assets/DCL/ResourcesUnloading/Tests/ReleaseMemorySystemShould.cs +++ b/Explorer/Assets/DCL/ResourcesUnloading/Tests/ReleaseMemorySystemShould.cs @@ -18,7 +18,6 @@ public class ReleaseMemorySystemShould : UnitySystemTestBase(); cacheCleaner = Substitute.For(); + standardStrategy = Substitute.For(); + aggresiveStrategy = Substitute.For(); unloadStrategies = new[] { - standardStrategy = Substitute.For(), - aggresiveStrategy = Substitute.For() + standardStrategy, + aggresiveStrategy }; - frameFailThreshold = 2; var partitionSettings = Substitute.For(); - unloadStrategyHandler = new UnloadStrategyHandler(partitionSettings, frameFailThreshold, cacheCleaner); + unloadStrategyHandler = new UnloadStrategyHandler(partitionSettings, cacheCleaner); unloadStrategyHandler.unloadStrategies = unloadStrategies; releaseMemorySystem = new ReleaseMemorySystem(world, memoryBudgetProvider, unloadStrategyHandler); @@ -54,6 +54,7 @@ public void UnloadCacheWhenMemoryUsageIsNotNormal(MemoryUsageStatus memoryUsageS { // Arrange memoryBudgetProvider.GetMemoryUsageStatus().Returns(memoryUsageStatus); + standardStrategy.FailedOverThreshold().Returns(true); // Act releaseMemorySystem.Update(0); @@ -67,13 +68,23 @@ public void ResetUnloadStrategyIndexWhenMemoryUsageIsNormal() { // Arrange memoryBudgetProvider.GetMemoryUsageStatus().Returns(MemoryUsageStatus.WARNING); + standardStrategy.FailedOverThreshold().Returns(true); // Act - for (var i = 0; i < frameFailThreshold + 1; i++) - releaseMemorySystem.Update(0); + releaseMemorySystem.Update(0); // Assert Assert.AreEqual(unloadStrategyHandler.currentUnloadStrategy, 1); + standardStrategy.Received(1).TryUnload(cacheCleaner); + + // Act + releaseMemorySystem.Update(0); + + // Assert + Assert.AreEqual(unloadStrategyHandler.currentUnloadStrategy, 1); + standardStrategy.Received(1).TryUnload(cacheCleaner); + aggresiveStrategy.Received(1).TryUnload(cacheCleaner); + // Act memoryBudgetProvider.GetMemoryUsageStatus().Returns(MemoryUsageStatus.NORMAL); @@ -81,32 +92,42 @@ public void ResetUnloadStrategyIndexWhenMemoryUsageIsNormal() // Assert Assert.AreEqual(unloadStrategyHandler.currentUnloadStrategy, 0); - - standardStrategy.Received(frameFailThreshold).TryUnload(cacheCleaner); - aggresiveStrategy.Received(1).TryUnload(cacheCleaner); + standardStrategy.Received(1).ResetStrategy(); + aggresiveStrategy.Received(1).ResetStrategy(); } - + [Test] - public void UnloadDoesntGetCalledAgainIfRunningInStrategy() + public void IncreaseTierAggresiveness() { // Arrange memoryBudgetProvider.GetMemoryUsageStatus().Returns(MemoryUsageStatus.WARNING); - + standardStrategy.FailedOverThreshold().Returns(true); + // Act - //Run until the fail and one more - for (var i = 0; i < frameFailThreshold + 1; i++) - releaseMemorySystem.Update(0); + releaseMemorySystem.Update(0); - //Simulate that it started running - aggresiveStrategy.IsRunning.Returns(true); + // Assert + Assert.AreEqual(unloadStrategyHandler.currentUnloadStrategy, 1); + standardStrategy.Received(1).TryUnload(cacheCleaner); - for (var i = 0; i < frameFailThreshold + 5; i++) - releaseMemorySystem.Update(0); + // Act + releaseMemorySystem.Update(0); - standardStrategy.Received(frameFailThreshold).TryUnload(cacheCleaner); + // Assert + Assert.AreEqual(unloadStrategyHandler.currentUnloadStrategy, 1); + standardStrategy.Received(1).TryUnload(cacheCleaner); aggresiveStrategy.Received(1).TryUnload(cacheCleaner); + + // Act + releaseMemorySystem.Update(0); + + // Assert + Assert.AreEqual(unloadStrategyHandler.currentUnloadStrategy, 1); + standardStrategy.Received(1).TryUnload(cacheCleaner); + aggresiveStrategy.Received(2).TryUnload(cacheCleaner); } - + + } - + } diff --git a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/AggressiveUnloadStrategy.cs b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/AggressiveUnloadStrategy.cs deleted file mode 100644 index 52df0a5d65..0000000000 --- a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/AggressiveUnloadStrategy.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using Cysharp.Threading.Tasks; -using ECS.Prioritization; -using UnityEngine; - -namespace DCL.ResourcesUnloading.UnloadStrategies -{ - public class AggressiveUnloadStrategy : IUnloadStrategy - { - public bool IsRunning { get; set; } - - private readonly IRealmPartitionSettings realmPartitionSettings; - private const int FORCE_UNLOADING_FRAMES_AMOUNT = 200; - - public AggressiveUnloadStrategy(IRealmPartitionSettings realmPartitionSettings) - { - this.realmPartitionSettings = realmPartitionSettings; - } - - public void TryUnload(ICacheCleaner cacheCleaner) - { - IsRunning = true; - - //Forces MaxLoadingDistanceInParcels to the minimum value - //TODO (Juani): A message warning that the distance has been silently modified - realmPartitionSettings.MaxLoadingDistanceInParcels = realmPartitionSettings.MinLoadingDistanceInParcels; - - StartAggressiveUnloadAsync(cacheCleaner).Forget(); - } - - private async UniTaskVoid StartAggressiveUnloadAsync(ICacheCleaner cacheCleaner) - { - var currentFrameRunning = 0; - try - { - while (currentFrameRunning < FORCE_UNLOADING_FRAMES_AMOUNT) - { - cacheCleaner.UnloadCache(); - cacheCleaner.UpdateProfilingCounters(); - currentFrameRunning++; - await UniTask.Yield(); - } - } - catch (Exception e) - { - // On any exception, lets keep running the unloading process until the end - while (currentFrameRunning < FORCE_UNLOADING_FRAMES_AMOUNT) - { - currentFrameRunning++; - await UniTask.Yield(); - } - } - finally - { - IsRunning = false; - //Finally, we unload assets that are unreferenced by no one - //Its a safe-check for any asset we may have missed in the cache - //Careful, because it will produce a hiccupe - Resources.UnloadUnusedAssets(); - } - } - - } -} diff --git a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/IUnloadStrategy.cs b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/IUnloadStrategy.cs index 9a70f11122..abebc7464e 100644 --- a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/IUnloadStrategy.cs +++ b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/IUnloadStrategy.cs @@ -1,9 +1,34 @@ namespace DCL.ResourcesUnloading.UnloadStrategies { + public interface IUnloadStrategy { + void ResetStrategy(); void TryUnload(ICacheCleaner cacheCleaner); + bool FailedOverThreshold(); + } + + public abstract class UnloadStrategy : IUnloadStrategy + { + + private int currentFailureCount; + private readonly int FAILURE_THRESHOLD = 250; + + public virtual void ResetStrategy() + { + currentFailureCount = 0; + } + + public bool FailedOverThreshold() + { + return currentFailureCount > FAILURE_THRESHOLD; + } - bool IsRunning { get; } + public virtual void TryUnload(ICacheCleaner cacheCleaner) + { + cacheCleaner.UnloadCache(); + cacheCleaner.UpdateProfilingCounters(); + currentFailureCount++; + } } } \ No newline at end of file diff --git a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/ReduceLoadingRadiusUnloadStrategy.cs b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/ReduceLoadingRadiusUnloadStrategy.cs new file mode 100644 index 0000000000..da8855151c --- /dev/null +++ b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/ReduceLoadingRadiusUnloadStrategy.cs @@ -0,0 +1,24 @@ +using System; +using ECS.Prioritization; + +namespace DCL.ResourcesUnloading.UnloadStrategies +{ + public class ReduceLoadingRadiusUnloadStrategy : UnloadStrategy + { + private readonly IRealmPartitionSettings realmPartitionSettings; + + public ReduceLoadingRadiusUnloadStrategy(IRealmPartitionSettings realmPartitionSettings) + { + this.realmPartitionSettings = realmPartitionSettings; + } + + public override void TryUnload(ICacheCleaner cacheCleaner) + { + //Forces MaxLoadingDistanceInParcels to the minimum value + //TODO (Juani): A message warning that the distance has been silently modified + realmPartitionSettings.MaxLoadingDistanceInParcels = realmPartitionSettings.MinLoadingDistanceInParcels; + base.TryUnload(cacheCleaner); + } + + } +} diff --git a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/AggressiveUnloadStrategy.cs.meta b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/ReduceLoadingRadiusUnloadStrategy.cs.meta similarity index 100% rename from Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/AggressiveUnloadStrategy.cs.meta rename to Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/ReduceLoadingRadiusUnloadStrategy.cs.meta diff --git a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/StandardUnloadStrategy.cs b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/StandardUnloadStrategy.cs index 68c0ee6299..bc9deaaced 100644 --- a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/StandardUnloadStrategy.cs +++ b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/StandardUnloadStrategy.cs @@ -1,16 +1,8 @@ -using UnityEngine; - namespace DCL.ResourcesUnloading.UnloadStrategies { - public class StandardUnloadStrategy : IUnloadStrategy + public class StandardUnloadStrategy : UnloadStrategy { - public bool IsRunning => false; - - - public void TryUnload(ICacheCleaner cacheCleaner) - { - cacheCleaner.UnloadCache(); - cacheCleaner.UpdateProfilingCounters(); - } + + } } \ No newline at end of file diff --git a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadStrategyHandler.cs b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadStrategyHandler.cs index 7dfa96cf9c..c297780046 100644 --- a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadStrategyHandler.cs +++ b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadStrategyHandler.cs @@ -9,53 +9,39 @@ public class UnloadStrategyHandler internal int currentUnloadStrategy; private readonly ICacheCleaner cacheCleaner; - //Determines how many frames we need to fail to increase the aggressiveness tier - private int consecutiveFailedFrames; - private readonly int failuresFrameThreshold; - - - public UnloadStrategyHandler(IRealmPartitionSettings realmPartitionSettings, int failuresFrameThreshold, + public UnloadStrategyHandler(IRealmPartitionSettings realmPartitionSettings, ICacheCleaner cacheCleaner) { this.cacheCleaner = cacheCleaner; - this.failuresFrameThreshold = failuresFrameThreshold; currentUnloadStrategy = 0; //Higher the index, more aggressive the strategy unloadStrategies = new IUnloadStrategy[] { new StandardUnloadStrategy(), - new AggressiveUnloadStrategy(realmPartitionSettings) + new ReduceLoadingRadiusUnloadStrategy(realmPartitionSettings), + new UnloadUnusedAssetUnloadStrategy() }; } public void TryUnload() { - if (IsRunning()) - return; - - consecutiveFailedFrames++; - if (consecutiveFailedFrames > failuresFrameThreshold) + unloadStrategies[currentUnloadStrategy].TryUnload(cacheCleaner); + if( unloadStrategies[currentUnloadStrategy].FailedOverThreshold()) IncreaseAggresivenessTier(); - - unloadStrategies[currentUnloadStrategy].TryUnload(cacheCleaner); } - private bool IsRunning() - { - return unloadStrategies[currentUnloadStrategy].IsRunning; - } public void ResetToNormal() { currentUnloadStrategy = 0; - consecutiveFailedFrames = 0; + for (var i = 0; i < unloadStrategies.Length; i++) + unloadStrategies[i].ResetStrategy(); } private void IncreaseAggresivenessTier() { currentUnloadStrategy = Math.Clamp(currentUnloadStrategy + 1, 0, unloadStrategies.Length - 1); - consecutiveFailedFrames = 0; } } } \ No newline at end of file diff --git a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadUnusedAssetUnloadStrategy.cs b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadUnusedAssetUnloadStrategy.cs new file mode 100644 index 0000000000..865f9e427b --- /dev/null +++ b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadUnusedAssetUnloadStrategy.cs @@ -0,0 +1,35 @@ +using UnityEngine; + +namespace DCL.ResourcesUnloading.UnloadStrategies +{ + public class UnloadUnusedAssetUnloadStrategy : UnloadStrategy + { + + private int FRAMES_UNTIL_UNLOAD_IS_INVOKED = 1000; + private int currentFrameCountForUnloadAssets; + + public UnloadUnusedAssetUnloadStrategy() + { + //We equalize it so its invoked on first invocation of TryUnload + currentFrameCountForUnloadAssets = FRAMES_UNTIL_UNLOAD_IS_INVOKED; + } + + public override void TryUnload(ICacheCleaner cacheCleaner) + { + currentFrameCountForUnloadAssets++; + if (currentFrameCountForUnloadAssets > FRAMES_UNTIL_UNLOAD_IS_INVOKED) + { + Resources.UnloadUnusedAssets(); + currentFrameCountForUnloadAssets = 0; + } + base.TryUnload(cacheCleaner); + } + + public override void ResetStrategy() + { + base.ResetStrategy(); + currentFrameCountForUnloadAssets = FRAMES_UNTIL_UNLOAD_IS_INVOKED; + } + + } +} \ No newline at end of file diff --git a/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadUnusedAssetUnloadStrategy.cs.meta b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadUnusedAssetUnloadStrategy.cs.meta new file mode 100644 index 0000000000..c681112070 --- /dev/null +++ b/Explorer/Assets/DCL/ResourcesUnloading/UnloadStrategies/UnloadUnusedAssetUnloadStrategy.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8f002a3129b1493097155fde08aced55 +timeCreated: 1729262561 \ No newline at end of file diff --git a/Explorer/Assets/Scripts/ECS/StreamableLoading/AssetBundles/AssetBundleData.cs b/Explorer/Assets/Scripts/ECS/StreamableLoading/AssetBundles/AssetBundleData.cs index 0973f6f56c..f3f3ef1df1 100644 --- a/Explorer/Assets/Scripts/ECS/StreamableLoading/AssetBundles/AssetBundleData.cs +++ b/Explorer/Assets/Scripts/ECS/StreamableLoading/AssetBundles/AssetBundleData.cs @@ -4,6 +4,7 @@ using Unity.Profiling; using UnityEngine; using UnityEngine.Assertions; +using Utility; using Object = UnityEngine.Object; namespace ECS.StreamableLoading.AssetBundles @@ -16,14 +17,16 @@ public class AssetBundleData : StreamableRefCountData private readonly Object? mainAsset; private readonly Type? assetType; - public AssetBundle AssetBundle => Asset; + internal AssetBundle AssetBundle => Asset; public readonly AssetBundleData[] Dependencies; public readonly AssetBundleMetrics? Metrics; - private readonly string version; - private readonly string source; + private readonly string description; + + + private bool unloaded; public AssetBundleData(AssetBundle assetBundle, AssetBundleMetrics? metrics, Object mainAsset, Type assetType, AssetBundleData[] dependencies, string version = "", string source = "") : base(assetBundle, ReportCategory.ASSET_BUNDLES) @@ -33,12 +36,14 @@ public AssetBundleData(AssetBundle assetBundle, AssetBundleMetrics? metrics, Obj this.mainAsset = mainAsset; Dependencies = dependencies; this.assetType = assetType; - this.version = version; - this.source = source; + + description = $"AB:{AssetBundle?.name}_{version}_{source}"; + UnloadAB(); } public AssetBundleData(AssetBundle assetBundle, AssetBundleMetrics? metrics, AssetBundleData[] dependencies) : base(assetBundle, ReportCategory.ASSET_BUNDLES) { + //Dependencies cant be unloaded, since we dont know who will need them =( Metrics = metrics; this.mainAsset = null; @@ -55,15 +60,29 @@ public AssetBundleData(AssetBundle assetBundle, AssetBundleMetrics? metrics, Gam protected override ref ProfilerCounterValue referencedCount => ref ProfilingCounters.ABReferencedAmount; + + private void UnloadAB() + { + //We immediately unload the asset bundle, as we don't need it anymore. + //Very hacky, because the asset will remain in cache as AssetBundle == null + //When DestroyObject is invoked, it will do nothing. + //When cache in cleaned, the AssetBundleData will be removed from the list. Its there doing nothing + if (unloaded) + return; + unloaded = true; + AssetBundle?.UnloadAsync(false); + } + protected override void DestroyObject() { - if (AssetBundle != null) - { - foreach (AssetBundleData child in Dependencies) - child.Dereference(); + foreach (AssetBundleData child in Dependencies) + child.Dereference(); + + if(mainAsset!=null) + Object.DestroyImmediate(mainAsset, true); + if (!unloaded) AssetBundle.UnloadAsync(unloadAllLoadedObjects: true); - } } public T GetMainAsset() where T : Object @@ -72,11 +91,10 @@ public T GetMainAsset() where T : Object if (assetType != typeof(T)) throw new ArgumentException("Asset type mismatch: " + typeof(T) + " != " + assetType); - return (T)mainAsset!; } - public string GetInstanceName() => - $"AB:{AssetBundle.name}_{version}_{source}"; + public string GetInstanceName() => description; + } } diff --git a/Explorer/Assets/Scripts/ECS/StreamableLoading/AssetBundles/PrepareAssetBundleLoadingParametersSystemBase.cs b/Explorer/Assets/Scripts/ECS/StreamableLoading/AssetBundles/PrepareAssetBundleLoadingParametersSystemBase.cs index 5d38e4f17a..2713a5df75 100644 --- a/Explorer/Assets/Scripts/ECS/StreamableLoading/AssetBundles/PrepareAssetBundleLoadingParametersSystemBase.cs +++ b/Explorer/Assets/Scripts/ECS/StreamableLoading/AssetBundles/PrepareAssetBundleLoadingParametersSystemBase.cs @@ -68,6 +68,7 @@ protected void PrepareCommonArguments(in Entity entity, ref GetAssetBundleIntent ca.Timeout = StreamableLoadingDefaults.TIMEOUT; ca.CurrentSource = AssetSource.WEB; ca.URL = assetBundleIntention.Manifest.GetAssetBundleURL(assetBundleIntention.Hash); + ca.CacheableURL = assetBundleIntention.Manifest.GetCacheableURL(assetBundleIntention.Hash); assetBundleIntention.CommonArguments = ca; assetBundleIntention.cacheHash = assetBundleIntention.Manifest.ComputeHash(assetBundleIntention.Hash); } diff --git a/Explorer/Assets/Scripts/ECS/StreamableLoading/Cache/RefCountStreamableCacheBase.cs b/Explorer/Assets/Scripts/ECS/StreamableLoading/Cache/RefCountStreamableCacheBase.cs index 65f22a32e0..eb36169248 100644 --- a/Explorer/Assets/Scripts/ECS/StreamableLoading/Cache/RefCountStreamableCacheBase.cs +++ b/Explorer/Assets/Scripts/ECS/StreamableLoading/Cache/RefCountStreamableCacheBase.cs @@ -3,7 +3,9 @@ using ECS.StreamableLoading.Common.Components; using System; using System.Collections.Generic; +using ECS.StreamableLoading.AssetBundles; using Unity.Profiling; +using UnityEngine; namespace ECS.StreamableLoading.Cache { diff --git a/Explorer/Assets/Scripts/ECS/StreamableLoading/Common/Components/CommonLoadingArguments.cs b/Explorer/Assets/Scripts/ECS/StreamableLoading/Common/Components/CommonLoadingArguments.cs index 09d193fe70..ecd0d67814 100644 --- a/Explorer/Assets/Scripts/ECS/StreamableLoading/Common/Components/CommonLoadingArguments.cs +++ b/Explorer/Assets/Scripts/ECS/StreamableLoading/Common/Components/CommonLoadingArguments.cs @@ -8,6 +8,7 @@ namespace ECS.StreamableLoading.Common.Components public struct CommonLoadingArguments { public URLAddress URL; + public URLAddress? CacheableURL; public int Attempts; public int Timeout; @@ -43,6 +44,7 @@ public CommonLoadingArguments(URLAddress url, Attempts = attempts; PermittedSources = permittedSources; CurrentSource = currentSource; + CacheableURL = null; CancellationTokenSource = cancellationTokenSource ?? new CancellationTokenSource(); } @@ -61,5 +63,13 @@ public CommonLoadingArguments(string url, // Always override attempts count for streamable assets as repetitions are handled in LoadSystemBase public static implicit operator CommonArguments(in CommonLoadingArguments commonLoadingArguments) => new (commonLoadingArguments.URL, attemptsCount: 1, timeout: commonLoadingArguments.Timeout); + + public string GetCacheableURL() + { + //Needed to handle the different versioning and entityIDs of the ABs + if(CacheableURL.HasValue) + return CacheableURL.Value.Value; + return URL; + } } } diff --git a/Explorer/Assets/Scripts/ECS/StreamableLoading/Common/Systems/LoadSystemBase.cs b/Explorer/Assets/Scripts/ECS/StreamableLoading/Common/Systems/LoadSystemBase.cs index 979ad916e7..8af6e1bd90 100644 --- a/Explorer/Assets/Scripts/ECS/StreamableLoading/Common/Systems/LoadSystemBase.cs +++ b/Explorer/Assets/Scripts/ECS/StreamableLoading/Common/Systems/LoadSystemBase.cs @@ -117,7 +117,7 @@ CancellationToken disposalCt // if the request is cached wait for it // If there is an ongoing request it means that the result is neither cached, nor failed - if (cache.OngoingRequests.SyncTryGetValue(intention.CommonArguments.URL.GetCacheableURL(), out var cachedSource)) + if (cache.OngoingRequests.SyncTryGetValue(intention.CommonArguments.GetCacheableURL(), out var cachedSource)) { // Release budget immediately, if we don't do it and load a lot of bundles with dependencies sequentially, it will be a deadlock acquiredBudget.Release(); @@ -141,7 +141,7 @@ CancellationToken disposalCt // Try load from cache first // If the given URL failed irrecoverably just return the failure - if (cache.IrrecoverableFailures.TryGetValue(intention.CommonArguments.URL.GetCacheableURL(), out var failure)) + if (cache.IrrecoverableFailures.TryGetValue(intention.CommonArguments.GetCacheableURL(), out var failure)) { result = failure; return; @@ -245,7 +245,7 @@ private void IncreaseRefCount(in TIntention intention, TAsset asset) var source = new UniTaskCompletionSource?>(); //AutoResetUniTaskCompletionSource?>.Create(); // ReportHub.Log(GetReportCategory(), $"OngoingRequests.SyncAdd {intention.CommonArguments.URL}"); - cache.OngoingRequests.SyncAdd(intention.CommonArguments.URL.GetCacheableURL(), source); + cache.OngoingRequests.SyncAdd(intention.CommonArguments.GetCacheableURL(), source); var ongoingRequestRemoved = false; @@ -299,7 +299,7 @@ void TryRemoveOngoingRequest() if (!ongoingRequestRemoved) { // ReportHub.Log(GetReportCategory(), $"OngoingRequests.SyncRemove {intention.CommonArguments.URL}"); - cache.OngoingRequests.SyncRemove(intention.CommonArguments.URL.GetCacheableURL()); + cache.OngoingRequests.SyncRemove(intention.CommonArguments.GetCacheableURL()); ongoingRequestRemoved = true; } } @@ -313,7 +313,7 @@ void TryRemoveOngoingRequest() private StreamableLoadingResult SetIrrecoverableFailure(TIntention intention, StreamableLoadingResult failure) { - cache.IrrecoverableFailures.Add(intention.CommonArguments.URL.GetCacheableURL(), failure); + cache.IrrecoverableFailures.Add(intention.CommonArguments.GetCacheableURL(), failure); return failure; } } diff --git a/Explorer/Assets/Scripts/ECS/Unity/GLTFContainer/Asset/Tests/GltfContainerTestResources.cs b/Explorer/Assets/Scripts/ECS/Unity/GLTFContainer/Asset/Tests/GltfContainerTestResources.cs index 7722e0adac..6cd2a93a2f 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/GLTFContainer/Asset/Tests/GltfContainerTestResources.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/GLTFContainer/Asset/Tests/GltfContainerTestResources.cs @@ -29,6 +29,7 @@ public class GltfContainerTestResources internal static readonly string TEST_FOLDER = $"file://{Application.dataPath + "/../TestResources/AssetBundles/"}"; internal AssetBundle assetBundle; + private StreamableLoadingResult assetBundleData; public async UniTask> LoadAssetBundle(string hash) { @@ -38,16 +39,16 @@ public async UniTask> LoadAssetBundle(s try { - return await LoadAssetBundleSystem.CreateAssetBundleDataAsync(assetBundle, null, typeof(GameObject), "", new AssetBundleLoadingMutex(), Array.Empty(), + assetBundleData = await LoadAssetBundleSystem.CreateAssetBundleDataAsync(assetBundle, null, typeof(GameObject), "", new AssetBundleLoadingMutex(), Array.Empty(), ReportCategory.ASSET_BUNDLES, "", "", CancellationToken.None); + return assetBundleData; } catch (Exception e) { return new StreamableLoadingResult(ReportCategory.ASSET_BUNDLES, e); } } public void UnloadBundle() { - assetBundle?.Unload(false); - assetBundle = null; + assetBundleData.Asset?.Dispose(); } } } diff --git a/Explorer/Assets/Scripts/SceneRunner/Scene/SceneAssetBundleManifest.cs b/Explorer/Assets/Scripts/SceneRunner/Scene/SceneAssetBundleManifest.cs index 8986e60f37..45bdbcd1a2 100644 --- a/Explorer/Assets/Scripts/SceneRunner/Scene/SceneAssetBundleManifest.cs +++ b/Explorer/Assets/Scripts/SceneRunner/Scene/SceneAssetBundleManifest.cs @@ -77,5 +77,12 @@ public URLAddress GetAssetBundleURL(string hash) public string GetVersion() => version; + + //Used for the OngoingRequests cache. We need to avoid version and sceneID in this URL to able to reuse assets. + //The first loaded hash will be the one used for all the other requests + public URLAddress GetCacheableURL(string hash) + { + return assetBundlesBaseUrl.Append(new URLPath(hash)); + } } } From 5fe1b335213cfe85dfa334cf94f139f7c40c0505 Mon Sep 17 00:00:00 2001 From: Alex Villalba Date: Mon, 21 Oct 2024 09:57:34 +0200 Subject: [PATCH 05/16] Textures leaked when leaving and entering Genesis plaza (#2129) (#2484) * fix: Unable to recover initial memory state in GP (#2129) Now cached texture intentions are compared using the texture file hash instead of the URL that was used to download it. Now it does not matter which content server is the candidate to get the texture from, if the instance was previously stored, it will reuse it when entering Genesis plaza. * Cleaning code, step 1 Created a separated method to get the file hash. * Cleaning step 2 * Cleaning step 3 --- .../DCL/MapPins/Systems/MapPinLoaderSystem.cs | 2 +- .../UIBackgroundInstantiationSystem.cs | 2 +- .../Tests/MultipleLoadSystemShould.cs | 2 +- .../Textures/GetTextureIntention.cs | 9 +++-- .../Textures/Tests/LoadTextureSystemShould.cs | 2 +- .../Systems/StartMaterialsLoadingSystem.cs | 2 +- .../Tests/CreateBasicMaterialSystemShould.cs | 2 +- .../Tests/CreatePBRMaterialSystemShould.cs | 8 ++--- .../LoadMaterialFromCacheSystemShould.cs | 12 +++---- .../Extensions/TextureDefaultsExtension.cs | 34 +++++++++++++++++-- .../Textures/Components/TextureComponent.cs | 8 +++-- .../Textures/Utils/TextureComponentUtils.cs | 2 +- .../SceneRunner/EmptyScene/EmptySceneData.cs | 9 +++++ .../Scripts/SceneRunner/Scene/ISceneData.cs | 8 +++++ .../Scripts/SceneRunner/Scene/SceneData.cs | 16 +++++++++ .../SceneRunner/Scene/SceneHashedContent.cs | 2 -- 16 files changed, 92 insertions(+), 28 deletions(-) diff --git a/Explorer/Assets/DCL/MapPins/Systems/MapPinLoaderSystem.cs b/Explorer/Assets/DCL/MapPins/Systems/MapPinLoaderSystem.cs index 9c5e7f5d6e..0c6c5a40d1 100644 --- a/Explorer/Assets/DCL/MapPins/Systems/MapPinLoaderSystem.cs +++ b/Explorer/Assets/DCL/MapPins/Systems/MapPinLoaderSystem.cs @@ -166,7 +166,7 @@ private bool TryCreateGetTexturePromise(in TextureComponent? textureComponent, r DereferenceTexture(ref promise); - promise = Promise.Create(World, new GetTextureIntention(textureComponentValue.Src, textureComponentValue.WrapMode, textureComponentValue.FilterMode, attemptsCount: ATTEMPTS_COUNT), partitionComponent); + promise = Promise.Create(World, new GetTextureIntention(textureComponentValue.Src, textureComponentValue.FileHash, textureComponentValue.WrapMode, textureComponentValue.FilterMode, attemptsCount: ATTEMPTS_COUNT), partitionComponent); return true; } diff --git a/Explorer/Assets/DCL/SDKComponents/SceneUI/Systems/UIBackground/UIBackgroundInstantiationSystem.cs b/Explorer/Assets/DCL/SDKComponents/SceneUI/Systems/UIBackground/UIBackgroundInstantiationSystem.cs index 159222403a..ccb77d729c 100644 --- a/Explorer/Assets/DCL/SDKComponents/SceneUI/Systems/UIBackground/UIBackgroundInstantiationSystem.cs +++ b/Explorer/Assets/DCL/SDKComponents/SceneUI/Systems/UIBackground/UIBackgroundInstantiationSystem.cs @@ -147,7 +147,7 @@ private void TryCreateGetTexturePromise(in TextureComponent? textureComponent, r // If component is being reused forget the previous promise TryAddAbortIntention(World, ref promise); - promise = Promise.Create(World, new GetTextureIntention(textureComponentValue.Src, textureComponentValue.WrapMode, textureComponentValue.FilterMode, attemptsCount: ATTEMPTS_COUNT), partitionComponent); + promise = Promise.Create(World, new GetTextureIntention(textureComponentValue.Src, textureComponentValue.FileHash, textureComponentValue.WrapMode, textureComponentValue.FilterMode, attemptsCount: ATTEMPTS_COUNT), partitionComponent); } private static void TryAddAbortIntention(World world, ref Promise? promise) diff --git a/Explorer/Assets/Scripts/ECS/StreamableLoading/Tests/MultipleLoadSystemShould.cs b/Explorer/Assets/Scripts/ECS/StreamableLoading/Tests/MultipleLoadSystemShould.cs index 009d95e82a..83bca857c7 100644 --- a/Explorer/Assets/Scripts/ECS/StreamableLoading/Tests/MultipleLoadSystemShould.cs +++ b/Explorer/Assets/Scripts/ECS/StreamableLoading/Tests/MultipleLoadSystemShould.cs @@ -39,7 +39,7 @@ public void MultipleLoadsShould() private Promise NewPromise(World world) { - var intention = new GetTextureIntention(successPath, TextureWrapMode.Repeat, FilterMode.Bilinear, true); + var intention = new GetTextureIntention(successPath, string.Empty,TextureWrapMode.Repeat, FilterMode.Bilinear, true); var partition = PartitionComponent.TOP_PRIORITY; return Promise.Create(world, intention, partition); diff --git a/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/GetTextureIntention.cs b/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/GetTextureIntention.cs index ff43220f95..bbfeff552d 100644 --- a/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/GetTextureIntention.cs +++ b/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/GetTextureIntention.cs @@ -18,10 +18,11 @@ public struct GetTextureIntention : ILoadingIntention, IEquatable CommonArguments.CancellationTokenSource; - public GetTextureIntention(string url, TextureWrapMode wrapMode, FilterMode filterMode, bool isReadable = false, int attemptsCount = StreamableLoadingDefaults.ATTEMPTS_COUNT) + public GetTextureIntention(string url, string fileHash, TextureWrapMode wrapMode, FilterMode filterMode, bool isReadable = false, int attemptsCount = StreamableLoadingDefaults.ATTEMPTS_COUNT) { CommonArguments = new CommonLoadingArguments(url, attempts: attemptsCount); WrapMode = wrapMode; @@ -29,11 +30,13 @@ public GetTextureIntention(string url, TextureWrapMode wrapMode, FilterMode filt IsReadable = isReadable; IsVideoTexture = false; VideoPlayerEntity = -1; + FileHash = fileHash; } public GetTextureIntention(CRDTEntity videoPlayerEntity) { CommonArguments = new CommonLoadingArguments(string.Empty); + FileHash = string.Empty; WrapMode = TextureWrapMode.Clamp; FilterMode = FilterMode.Bilinear; IsReadable = false; @@ -42,7 +45,7 @@ public GetTextureIntention(CRDTEntity videoPlayerEntity) } public bool Equals(GetTextureIntention other) => - this.AreUrlEquals(other) && + FileHash == other.FileHash && IsReadable == other.IsReadable && WrapMode == other.WrapMode && FilterMode == other.FilterMode && @@ -53,7 +56,7 @@ public override bool Equals(object obj) => obj is GetTextureIntention other && Equals(other); public override int GetHashCode() => - HashCode.Combine(IsReadable, (int)WrapMode, (int)FilterMode, CommonArguments.URL, IsVideoTexture, VideoPlayerEntity); + HashCode.Combine(IsReadable, (int)WrapMode, (int)FilterMode, FileHash, IsVideoTexture, VideoPlayerEntity); public override string ToString() => $"Get Texture: {(IsVideoTexture ? $"Video {VideoPlayerEntity}" : CommonArguments.URL)}"; diff --git a/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/Tests/LoadTextureSystemShould.cs b/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/Tests/LoadTextureSystemShould.cs index e92cbfb5fa..95d817e341 100644 --- a/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/Tests/LoadTextureSystemShould.cs +++ b/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/Tests/LoadTextureSystemShould.cs @@ -19,7 +19,7 @@ public class LoadTextureSystemShould : LoadSystemBaseShould $"file://{Application.dataPath + "/../TestResources/CRDT/arraybuffer.test"}"; protected override GetTextureIntention CreateSuccessIntention() => - new (successPath, TextureWrapMode.MirrorOnce, FilterMode.Trilinear); + new (successPath, string.Empty, TextureWrapMode.MirrorOnce, FilterMode.Trilinear); protected override GetTextureIntention CreateNotFoundIntention() => new () { CommonArguments = new CommonLoadingArguments(failPath) }; diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs index b7bfb5f7a5..d7fa63423e 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs @@ -197,7 +197,7 @@ private bool TryCreateGetTexturePromise(in TextureComponent? textureComponent, : new StreamableLoadingResult(GetReportCategory(), CreateException(new EcsEntityNotFoundException(textureComponentValue.VideoPlayerEntity, $"Entity {textureComponentValue.VideoPlayerEntity} not found!. VideoTexture will not be created.")))); } else - promise = Promise.Create(World!, new GetTextureIntention(textureComponentValue.Src, textureComponentValue.WrapMode, textureComponentValue.FilterMode, attemptsCount: attemptsCount), partitionComponent); + promise = Promise.Create(World!, new GetTextureIntention(textureComponentValue.Src, textureComponentValue.FileHash, textureComponentValue.WrapMode, textureComponentValue.FilterMode, attemptsCount: attemptsCount), partitionComponent); return true; } diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreateBasicMaterialSystemShould.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreateBasicMaterialSystemShould.cs index 7fd1a83d81..a2822082bd 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreateBasicMaterialSystemShould.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreateBasicMaterialSystemShould.cs @@ -81,7 +81,7 @@ private void CreateAndFinalizeTexturePromise(ref AssetPromise new (MaterialData.CreateBasicMaterial( - new TextureComponent("albedo", TextureWrapMode.Mirror, FilterMode.Point), + new TextureComponent("albedo", string.Empty, TextureWrapMode.Mirror, FilterMode.Point), 0, Color.red, false)); diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreatePBRMaterialSystemShould.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreatePBRMaterialSystemShould.cs index 81b422cd59..7ae3b6f913 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreatePBRMaterialSystemShould.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreatePBRMaterialSystemShould.cs @@ -89,10 +89,10 @@ private void CreateAndFinalizeTexturePromise(ref AssetPromise new (MaterialData.CreatePBRMaterial( - new TextureComponent("albedo", TextureWrapMode.Mirror, FilterMode.Point), - new TextureComponent("alpha", TextureWrapMode.Mirror, FilterMode.Trilinear), - new TextureComponent("emissive", TextureWrapMode.Mirror, FilterMode.Bilinear), - new TextureComponent("bump", TextureWrapMode.Mirror, FilterMode.Point), + new TextureComponent("albedo", string.Empty, TextureWrapMode.Mirror, FilterMode.Point), + new TextureComponent("alpha", string.Empty, TextureWrapMode.Mirror, FilterMode.Trilinear), + new TextureComponent("emissive", string.Empty, TextureWrapMode.Mirror, FilterMode.Bilinear), + new TextureComponent("bump", string.Empty, TextureWrapMode.Mirror, FilterMode.Point), 0.5f, true, Color.red, diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/LoadMaterialFromCacheSystemShould.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/LoadMaterialFromCacheSystemShould.cs index c3d9484731..5f755c50d4 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/LoadMaterialFromCacheSystemShould.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/LoadMaterialFromCacheSystemShould.cs @@ -24,7 +24,7 @@ public void SetUp() public void FinishLoadingIfPresentInCache() { var materialComponent = new MaterialComponent(MaterialData.CreateBasicMaterial( - new TextureComponent("test-texture", TextureWrapMode.Mirror, FilterMode.Bilinear), + new TextureComponent("test-texture", "file-hash", TextureWrapMode.Mirror, FilterMode.Bilinear), 0.5f, Color.red, true)); @@ -54,7 +54,7 @@ public void FinishLoadingIfPresentInCache() public void DoNothingIfLoadingStarted([Values(StreamableLoading.LifeCycle.LoadingInProgress, StreamableLoading.LifeCycle.LoadingFinished, StreamableLoading.LifeCycle.Applied)] StreamableLoading.LifeCycle status) { var materialComponent = new MaterialComponent(MaterialData.CreateBasicMaterial( - new TextureComponent("test-texture", TextureWrapMode.Mirror, FilterMode.Bilinear), + new TextureComponent("test-texture", "file-hash", TextureWrapMode.Mirror, FilterMode.Bilinear), 0.5f, Color.red, true)); @@ -84,10 +84,10 @@ public void DoNothingIfLoadingStarted([Values(StreamableLoading.LifeCycle.Loadin public void NotFinishLoadingIfNotPresentInCache() { var materialComponent = new MaterialComponent(MaterialData.CreatePBRMaterial( - new TextureComponent("1", TextureWrapMode.Mirror, FilterMode.Bilinear), - new TextureComponent("2", TextureWrapMode.MirrorOnce, FilterMode.Trilinear), - new TextureComponent("3", TextureWrapMode.Repeat, FilterMode.Point), - new TextureComponent("4", TextureWrapMode.Clamp, FilterMode.Point), + new TextureComponent("1", "file-hash", TextureWrapMode.Mirror, FilterMode.Bilinear), + new TextureComponent("2", "file-hash", TextureWrapMode.MirrorOnce, FilterMode.Trilinear), + new TextureComponent("3", "file-hash", TextureWrapMode.Repeat, FilterMode.Point), + new TextureComponent("4", "file-hash", TextureWrapMode.Clamp, FilterMode.Point), 0.5f, true, Color.red, diff --git a/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/Extensions/TextureDefaultsExtension.cs b/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/Extensions/TextureDefaultsExtension.cs index 531488b002..222b72623e 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/Extensions/TextureDefaultsExtension.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/Extensions/TextureDefaultsExtension.cs @@ -16,12 +16,15 @@ public static class TextureDefaultsExtensions if (self.IsVideoTexture()) { - var textureComponent = new TextureComponent(URLAddress.EMPTY, self.GetWrapMode(), self.GetFilterMode(), true, self.GetVideoTextureId()); + var textureComponent = new TextureComponent(URLAddress.EMPTY, string.Empty, self.GetWrapMode(), self.GetFilterMode(), true, self.GetVideoTextureId()); return textureComponent; } - return self.TryGetTextureUrl(data, out URLAddress url) - ? new TextureComponent(url, self.GetWrapMode(), self.GetFilterMode()) + bool success = self.TryGetTextureUrl(data, out URLAddress url); + self.TryGetTextureFileHash(data, out string fileHash); + + return success + ? new TextureComponent(url, fileHash, self.GetWrapMode(), self.GetFilterMode()) : null; } @@ -40,6 +43,21 @@ public static bool TryGetTextureUrl(this TextureUnion self, ISceneData data, out } } + public static bool TryGetTextureFileHash(this TextureUnion self, ISceneData data, out string fileHash) + { + switch (self.TexCase) + { + case TextureUnion.TexOneofCase.AvatarTexture: + return self.AvatarTexture.TryGetTextureFileHash(out fileHash); + case TextureUnion.TexOneofCase.VideoTexture: + fileHash = string.Empty; + return false; + case TextureUnion.TexOneofCase.Texture: + default: + return self.Texture.TryGetTextureFileHash(data, out fileHash); + } + } + public static int GetVideoTextureId(this TextureUnion self) { switch (self.TexCase) @@ -85,6 +103,9 @@ public static FilterMode GetFilterMode(this TextureUnion self) public static bool TryGetTextureUrl(this Texture self, ISceneData data, out URLAddress url) => data.TryGetMediaUrl(self.Src, out url); + public static bool TryGetTextureFileHash(this Texture self, ISceneData data, out string fileHash) => + data.TryGetMediaFileHash(self.Src, out fileHash); + public static bool TryGetTextureUrl(this AvatarTexture self, out URLAddress url) { // Not implemented @@ -92,6 +113,13 @@ public static bool TryGetTextureUrl(this AvatarTexture self, out URLAddress url) return false; } + public static bool TryGetTextureFileHash(this AvatarTexture self, out string fileHash) + { + // Not implemented + fileHash = string.Empty; + return false; + } + public static TextureWrapMode GetWrapMode(this Texture self) => self.HasWrapMode ? self.WrapMode.ToUnityWrapMode() : TextureWrapMode.Clamp; diff --git a/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/TextureComponent.cs b/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/TextureComponent.cs index 13d1f3363b..f50ba53857 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/TextureComponent.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/TextureComponent.cs @@ -10,10 +10,12 @@ namespace ECS.Unity.Textures.Components public readonly FilterMode FilterMode; public readonly bool IsVideoTexture; public readonly int VideoPlayerEntity; + public readonly string FileHash; - public TextureComponent(string src, TextureWrapMode wrapMode = TextureWrapMode.Clamp, FilterMode filterMode = FilterMode.Bilinear, bool isVideoTexture = false, int videoPlayerEntity = 0) + public TextureComponent(string src, string fileHash, TextureWrapMode wrapMode = TextureWrapMode.Clamp, FilterMode filterMode = FilterMode.Bilinear, bool isVideoTexture = false, int videoPlayerEntity = 0) { Src = src; + FileHash = fileHash; WrapMode = wrapMode; FilterMode = filterMode; IsVideoTexture = isVideoTexture; @@ -21,12 +23,12 @@ public TextureComponent(string src, TextureWrapMode wrapMode = TextureWrapMode.C } public bool Equals(TextureComponent other) => - Src == other.Src && WrapMode == other.WrapMode && FilterMode == other.FilterMode && IsVideoTexture == other.IsVideoTexture && VideoPlayerEntity == other.VideoPlayerEntity; + FileHash == other.FileHash && WrapMode == other.WrapMode && FilterMode == other.FilterMode && IsVideoTexture == other.IsVideoTexture && VideoPlayerEntity == other.VideoPlayerEntity; public override bool Equals(object obj) => obj is TextureComponent other && Equals(other); public override int GetHashCode() => - HashCode.Combine(Src, (int)WrapMode, (int)FilterMode, IsVideoTexture, VideoPlayerEntity); + HashCode.Combine(FileHash, (int)WrapMode, (int)FilterMode, IsVideoTexture, VideoPlayerEntity); } } diff --git a/Explorer/Assets/Scripts/ECS/Unity/Textures/Utils/TextureComponentUtils.cs b/Explorer/Assets/Scripts/ECS/Unity/Textures/Utils/TextureComponentUtils.cs index f49183d4d5..058b6f72c2 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Textures/Utils/TextureComponentUtils.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Textures/Utils/TextureComponentUtils.cs @@ -14,7 +14,7 @@ public static bool Equals(ref TextureComponent textureComponent, ref Promise? pr Promise promiseValue = promise.Value; GetTextureIntention intention = promiseValue.LoadingIntention; - return textureComponent.Src == promiseValue.LoadingIntention.CommonArguments.URL && + return textureComponent.FileHash == promiseValue.LoadingIntention.FileHash && textureComponent.WrapMode == intention.WrapMode && textureComponent.FilterMode == intention.FilterMode; } diff --git a/Explorer/Assets/Scripts/SceneRunner/EmptyScene/EmptySceneData.cs b/Explorer/Assets/Scripts/SceneRunner/EmptyScene/EmptySceneData.cs index 524d33a81c..782f530eb2 100644 --- a/Explorer/Assets/Scripts/SceneRunner/EmptyScene/EmptySceneData.cs +++ b/Explorer/Assets/Scripts/SceneRunner/EmptyScene/EmptySceneData.cs @@ -44,12 +44,21 @@ public bool TryGetMainScriptUrl(out URLAddress result) => public bool TryGetContentUrl(string url, out URLAddress result) => throw new NotImplementedException(); + public bool TryGetContentUrl(string url, out URLAddress result, out string fileHash) => + throw new NotImplementedException(); + public bool TryGetHash(string name, out string hash) => throw new NotImplementedException(); public bool TryGetMediaUrl(string url, out URLAddress result) => throw new NotImplementedException(); + public bool TryGetMediaFileHash(string url, out string fileHash) => + throw new NotImplementedException(); + + public bool TryGetMediaUrl(string url, out URLAddress result, out string fileHash) => + throw new NotImplementedException(); + public bool IsUrlDomainAllowed(string url) => throw new NotImplementedException(); diff --git a/Explorer/Assets/Scripts/SceneRunner/Scene/ISceneData.cs b/Explorer/Assets/Scripts/SceneRunner/Scene/ISceneData.cs index 67652f4ab9..34326de570 100644 --- a/Explorer/Assets/Scripts/SceneRunner/Scene/ISceneData.cs +++ b/Explorer/Assets/Scripts/SceneRunner/Scene/ISceneData.cs @@ -55,6 +55,8 @@ public interface ISceneData /// bool TryGetMediaUrl(string url, out URLAddress result); + bool TryGetMediaFileHash(string url, out string fileHash); + bool IsUrlDomainAllowed(string url); bool IsSdk7(); @@ -105,6 +107,12 @@ public bool TryGetMediaUrl(string url, out URLAddress result) return false; } + public bool TryGetMediaFileHash(string url, out string fileHash) + { + fileHash = string.Empty; + return false; + } + public bool IsUrlDomainAllowed(string url) => false; diff --git a/Explorer/Assets/Scripts/SceneRunner/Scene/SceneData.cs b/Explorer/Assets/Scripts/SceneRunner/Scene/SceneData.cs index 2364cc5834..7193d98974 100644 --- a/Explorer/Assets/Scripts/SceneRunner/Scene/SceneData.cs +++ b/Explorer/Assets/Scripts/SceneRunner/Scene/SceneData.cs @@ -95,6 +95,22 @@ public bool TryGetMediaUrl(string url, out URLAddress result) return false; } + public bool TryGetMediaFileHash(string url, out string fileHash) + { + if (string.IsNullOrEmpty(url)) + { + fileHash = string.Empty; + return false; + } + + // Try resolve an internal URL + if (TryGetHash(url, out fileHash)) + return true; + + fileHash = string.Empty; + return false; + } + public bool IsUrlDomainAllowed(string url) { if (Uri.TryCreate(url, UriKind.Absolute, out Uri uri)) diff --git a/Explorer/Assets/Scripts/SceneRunner/Scene/SceneHashedContent.cs b/Explorer/Assets/Scripts/SceneRunner/Scene/SceneHashedContent.cs index 11e709ce5b..7ddc1042e1 100644 --- a/Explorer/Assets/Scripts/SceneRunner/Scene/SceneHashedContent.cs +++ b/Explorer/Assets/Scripts/SceneRunner/Scene/SceneHashedContent.cs @@ -1,8 +1,6 @@ using CommunicationData.URLHelpers; using DCL.Diagnostics; using DCL.Ipfs; -using Google.Protobuf; -using Ipfs; using System; using System.Collections.Generic; From 8c3c525614b4e44f0fabdd326dd02c40329b2396 Mon Sep 17 00:00:00 2001 From: Juan Ignacio Molteni Date: Mon, 21 Oct 2024 04:57:46 -0300 Subject: [PATCH 06/16] Null check (#2501) --- .../ECS/SceneLifeCycle/Systems/GatherGltfAssetsSystem.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Explorer/Assets/Scripts/ECS/SceneLifeCycle/Systems/GatherGltfAssetsSystem.cs b/Explorer/Assets/Scripts/ECS/SceneLifeCycle/Systems/GatherGltfAssetsSystem.cs index 2bda2014be..b2ff42462f 100644 --- a/Explorer/Assets/Scripts/ECS/SceneLifeCycle/Systems/GatherGltfAssetsSystem.cs +++ b/Explorer/Assets/Scripts/ECS/SceneLifeCycle/Systems/GatherGltfAssetsSystem.cs @@ -62,8 +62,11 @@ public override void Initialize() public override void Dispose() { - HashSetPool.Release(entitiesUnderObservation); - entitiesUnderObservation = null; + if (entitiesUnderObservation != null) + { + HashSetPool.Release(entitiesUnderObservation); + entitiesUnderObservation = null; + } sceneData.SceneLoadingConcluded = true; } From b715342d9c5065318286dd4e52b65e214218368f Mon Sep 17 00:00:00 2001 From: Juan Ignacio Molteni Date: Mon, 21 Oct 2024 05:18:48 -0300 Subject: [PATCH 07/16] replaced data type in query: (#2504) --- .../ECS/GlobalPartitioning/GlobalDeferredLoadingSystem.cs | 8 ++++---- .../DeferredLoading/AssetsDeferredLoadingSystem.cs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Explorer/Assets/DCL/ECS/GlobalPartitioning/GlobalDeferredLoadingSystem.cs b/Explorer/Assets/DCL/ECS/GlobalPartitioning/GlobalDeferredLoadingSystem.cs index 48820622b1..fd82cfbd11 100644 --- a/Explorer/Assets/DCL/ECS/GlobalPartitioning/GlobalDeferredLoadingSystem.cs +++ b/Explorer/Assets/DCL/ECS/GlobalPartitioning/GlobalDeferredLoadingSystem.cs @@ -56,12 +56,12 @@ static GlobalDeferredLoadingSystem() CreateQuery(), CreateQuery(), CreateQuery(), - CreateQuery(), - CreateQuery(), - CreateQuery(), + CreateQuery(), + CreateQuery(), + CreateQuery(), CreateQuery(), CreateQuery(), - CreateQuery(), + CreateQuery(), }; } diff --git a/Explorer/Assets/Scripts/ECS/StreamableLoading/DeferredLoading/AssetsDeferredLoadingSystem.cs b/Explorer/Assets/Scripts/ECS/StreamableLoading/DeferredLoading/AssetsDeferredLoadingSystem.cs index 4a385f5a14..4dda858f31 100644 --- a/Explorer/Assets/Scripts/ECS/StreamableLoading/DeferredLoading/AssetsDeferredLoadingSystem.cs +++ b/Explorer/Assets/Scripts/ECS/StreamableLoading/DeferredLoading/AssetsDeferredLoadingSystem.cs @@ -29,9 +29,9 @@ static AssetsDeferredLoadingSystem() { CreateQuery(), CreateQuery(), - CreateQuery(), - CreateQuery(), - CreateQuery(), + CreateQuery(), + CreateQuery(), + CreateQuery(), }; } From ccac6325a0f2ac500d70c2f7492eac2393b72b27 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 09:25:23 +0100 Subject: [PATCH 08/16] chore: sync main to dev (#2507) Co-authored-by: Ashley Canning From 3f1afc9c63eab0bc4c70bed099ca97bebfcb4a12 Mon Sep 17 00:00:00 2001 From: Pravus Date: Mon, 21 Oct 2024 10:33:08 +0200 Subject: [PATCH 09/16] added missing IFinalizeWorldSystem implementation in system (#2506) --- .../Assets/DCL/PluginSystem/World/InputModifierPlugin.cs | 1 + .../InputModifier/Systems/InputModifierHandlerSystem.cs | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Explorer/Assets/DCL/PluginSystem/World/InputModifierPlugin.cs b/Explorer/Assets/DCL/PluginSystem/World/InputModifierPlugin.cs index 7463a10b9b..53b35ccd07 100644 --- a/Explorer/Assets/DCL/PluginSystem/World/InputModifierPlugin.cs +++ b/Explorer/Assets/DCL/PluginSystem/World/InputModifierPlugin.cs @@ -35,6 +35,7 @@ public void InjectToWorld(ref ArchSystemsWorldBuilder builder, ResetDirtyFlagSystem.InjectToWorld(ref builder); var system = InputModifierHandlerSystem.InjectToWorld(ref builder, world, playerEntity, sharedDependencies.SceneStateProvider); sceneIsCurrentListeners.Add(system); + finalizeWorldSystems.Add(system); } } } diff --git a/Explorer/Assets/DCL/SDKComponents/InputModifier/Systems/InputModifierHandlerSystem.cs b/Explorer/Assets/DCL/SDKComponents/InputModifier/Systems/InputModifierHandlerSystem.cs index a1e8b8c7b2..2cacf36378 100644 --- a/Explorer/Assets/DCL/SDKComponents/InputModifier/Systems/InputModifierHandlerSystem.cs +++ b/Explorer/Assets/DCL/SDKComponents/InputModifier/Systems/InputModifierHandlerSystem.cs @@ -11,7 +11,7 @@ namespace DCL.SDKComponents.PlayerInputMovement.Systems { [UpdateInGroup(typeof(SyncedInitializationSystemGroup))] - public partial class InputModifierHandlerSystem : BaseUnityLoopSystem, ISceneIsCurrentListener + public partial class InputModifierHandlerSystem : BaseUnityLoopSystem, ISceneIsCurrentListener, IFinalizeWorldSystem { private readonly Entity playerEntity; private readonly World globalWorld; @@ -67,5 +67,10 @@ public void OnSceneIsCurrentChanged(bool value) if (!value) ResetModifiersOnLeave(); } + + public void FinalizeComponents(in Query query) + { + ResetModifiersOnLeave(); + } } } From a0fc61add6ebd4dc1bcd1810bb671c04205de4e0 Mon Sep 17 00:00:00 2001 From: Vitaly Popuzin <35366872+popuz@users.noreply.github.com> Date: Mon, 21 Oct 2024 15:27:46 +0300 Subject: [PATCH 10/16] Fix: UnityWebRequest exception request aborted (#2498) ## What does this PR change? Add dispose for the request and exception not thrown after that ## How to test the changes? not needed --- .../WebRequests/WebContentSizes/RangeBasedWebContentSizes.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Explorer/Assets/DCL/WebRequests/WebContentSizes/RangeBasedWebContentSizes.cs b/Explorer/Assets/DCL/WebRequests/WebContentSizes/RangeBasedWebContentSizes.cs index 7c98d50868..6902c7222a 100644 --- a/Explorer/Assets/DCL/WebRequests/WebContentSizes/RangeBasedWebContentSizes.cs +++ b/Explorer/Assets/DCL/WebRequests/WebContentSizes/RangeBasedWebContentSizes.cs @@ -30,7 +30,7 @@ public RangeBasedWebContentSizes(IMaxSize maxSize, Action reasonLog) public async UniTask IsOkSizeAsync(string url, CancellationToken token) { - var request = NewRequest(url); + using var request = NewRequest(url); request.SendWebRequest().WithCancellation(token); while (token.IsCancellationRequested == false From f3913475a96eaf8b76702f4a7c5218dfaed27580 Mon Sep 17 00:00:00 2001 From: Mikhail Agapov <118179774+mikhail-dcl@users.noreply.github.com> Date: Mon, 21 Oct 2024 17:26:06 +0400 Subject: [PATCH 11/16] Fix: Handle RunConnectCycleStepAsync safer (#2478) * Handle RunConnectCycleStepAsync safer * Add logs in case of failed delivery * More logs * Preserve the previous connection if the players returns to the scene * Fix connectedScene assigning * Restore ConnectiveRoom.Fake --- .../MessageBus/SelfResendChatMessageBus.cs | 2 +- .../AutoReconnectLiveConnection.cs | 2 +- .../LogArchipelagoLiveConnection.cs | 18 ++--- .../Rooms/ArchipelagoIslandRoom.cs | 8 +- .../Rooms/Fixed/FixedConnectiveRoom.cs | 4 +- .../SignFlow/LogArchipelagoSignFlow.cs | 2 +- .../Meta/ISceneRoomMetaDataSource.cs | 6 +- .../Connections/GateKeeper/Meta/MetaData.cs | 33 +++++++- .../Meta/SceneRoomLogMetaDataSource.cs | 19 ++--- .../Meta/SceneRoomMetaDataSource.cs | 38 +++------ .../GateKeeper/Rooms/GateKeeperSceneRoom.cs | 81 +++++++++++++------ .../GateKeeper/Rooms/IGateKeeperSceneRoom.cs | 4 +- .../Rooms/Connective/ConnectiveRoom.cs | 63 ++++++++++++--- .../Profiles/DCL.Multiplayer.Profiles.asmdef | 3 +- .../Profiles/Poses/RemoteMetadata.cs | 5 +- .../Handlers/DebugLogReportHandler.cs | 2 +- .../ReportsHandling/ReportCategory.cs | 4 +- .../ReportsHandlingSettingsDevelopment.asset | 6 ++ ...mmunicationsControllerAPIImplementation.cs | 1 - ...icationsControllerAPIImplementationBase.cs | 19 ++++- .../Communications/ISceneCommunicationPipe.cs | 15 +++- .../SDKMessageBusCommsAPIImplementation.cs | 2 +- .../Communications/SceneCommunicationPipe.cs | 17 +++- ...cationControllerAPIImplementationShould.cs | 2 +- 24 files changed, 242 insertions(+), 114 deletions(-) diff --git a/Explorer/Assets/DCL/Chat/MessageBus/SelfResendChatMessageBus.cs b/Explorer/Assets/DCL/Chat/MessageBus/SelfResendChatMessageBus.cs index 0b338a9c98..e102c505e8 100644 --- a/Explorer/Assets/DCL/Chat/MessageBus/SelfResendChatMessageBus.cs +++ b/Explorer/Assets/DCL/Chat/MessageBus/SelfResendChatMessageBus.cs @@ -50,7 +50,7 @@ private async UniTaskVoid SendSelfAsync(string message) if (identity == null) { - ReportHub.LogWarning(ReportCategory.ARCHIPELAGO_REQUEST, "SelfResendChatMessageBus.Send: Identity is null, can't send message"); + ReportHub.LogWarning(ReportCategory.COMMS_SCENE_HANDLER, "SelfResendChatMessageBus.Send: Identity is null, can't send message"); return; } diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/LiveConnections/AutoReconnectLiveConnection.cs b/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/LiveConnections/AutoReconnectLiveConnection.cs index 9b26cb6eb9..e7e79a9aad 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/LiveConnections/AutoReconnectLiveConnection.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/LiveConnections/AutoReconnectLiveConnection.cs @@ -17,7 +17,7 @@ public class AutoReconnectLiveConnection : IArchipelagoLiveConnection public AutoReconnectLiveConnection(IArchipelagoLiveConnection origin) : this( origin, - m => ReportHub.Log(ReportCategory.ARCHIPELAGO_REQUEST, m) + m => ReportHub.Log(ReportCategory.COMMS_SCENE_HANDLER, m) ) { } public AutoReconnectLiveConnection(IArchipelagoLiveConnection origin, Action log) diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/LiveConnections/LogArchipelagoLiveConnection.cs b/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/LiveConnections/LogArchipelagoLiveConnection.cs index 435abfd724..502e18fe75 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/LiveConnections/LogArchipelagoLiveConnection.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/LiveConnections/LogArchipelagoLiveConnection.cs @@ -23,7 +23,7 @@ public bool IsConnected if (previousConnected != result) { ReportHub - .WithReport(ReportCategory.ARCHIPELAGO_REQUEST) + .WithReport(ReportCategory.COMMS_SCENE_HANDLER) .Log($"ArchipelagoLiveConnection connected: {result}"); previousConnected = result; } @@ -40,11 +40,11 @@ public LogArchipelagoLiveConnection(IArchipelagoLiveConnection origin) public async UniTask ConnectAsync(string adapterUrl, CancellationToken token) { ReportHub - .WithReport(ReportCategory.ARCHIPELAGO_REQUEST) + .WithReport(ReportCategory.COMMS_SCENE_HANDLER) .Log($"ArchipelagoLiveConnection ConnectAsync start to: {adapterUrl}"); var result = await origin.ConnectAsync(adapterUrl, token); ReportHub - .WithReport(ReportCategory.ARCHIPELAGO_REQUEST) + .WithReport(ReportCategory.COMMS_SCENE_HANDLER) .Log($"ArchipelagoLiveConnection ConnectAsync finished to: {adapterUrl} with result: {result.Success}"); return result; } @@ -52,22 +52,22 @@ public async UniTask ConnectAsync(string adapterUrl, CancellationToken t public async UniTask DisconnectAsync(CancellationToken token) { ReportHub - .WithReport(ReportCategory.ARCHIPELAGO_REQUEST) + .WithReport(ReportCategory.COMMS_SCENE_HANDLER) .Log("ArchipelagoLiveConnection DisconnectAsync start"); await origin.DisconnectAsync(token); ReportHub - .WithReport(ReportCategory.ARCHIPELAGO_REQUEST) + .WithReport(ReportCategory.COMMS_SCENE_HANDLER) .Log("ArchipelagoLiveConnection DisconnectAsync finished"); } public async UniTask> SendAsync(MemoryWrap data, CancellationToken token) { ReportHub - .WithReport(ReportCategory.ARCHIPELAGO_REQUEST) + .WithReport(ReportCategory.COMMS_SCENE_HANDLER) .Log($"ArchipelagoLiveConnection SendAsync start with size: {data.Length} and content: {data.HexReadableString()}"); var result = await origin.SendAsync(data, token); ReportHub - .WithReport(ReportCategory.ARCHIPELAGO_REQUEST) + .WithReport(ReportCategory.COMMS_SCENE_HANDLER) .Log($"ArchipelagoLiveConnection SendAsync finished with size: {data.Length} and content: {data.HexReadableString()}"); return result; } @@ -75,11 +75,11 @@ public async UniTask DisconnectAsync(CancellationToken token) public async UniTask> ReceiveAsync(CancellationToken token) { ReportHub - .WithReport(ReportCategory.ARCHIPELAGO_REQUEST) + .WithReport(ReportCategory.COMMS_SCENE_HANDLER) .Log("ArchipelagoLiveConnection ReceiveAsync start"); var result = await origin.ReceiveAsync(token); ReportHub - .WithReport(ReportCategory.ARCHIPELAGO_REQUEST) + .WithReport(ReportCategory.COMMS_SCENE_HANDLER) .Log($"ArchipelagoLiveConnection ReceiveAsync finished with error: {result.Error?.Message ?? "no error"}, size: {(result.Success ? result.Value.Length : 0)}"); return result; } diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/Rooms/ArchipelagoIslandRoom.cs b/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/Rooms/ArchipelagoIslandRoom.cs index f79d4db724..0dff4cd0d0 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/Rooms/ArchipelagoIslandRoom.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/Rooms/ArchipelagoIslandRoom.cs @@ -99,14 +99,14 @@ private async UniTask SendHeartbeatAsync(ConnectToRoomAsyncDelegate connectDeleg var result = await signFlow.SendHeartbeatAsync(position, token); if (result.Success == false) - ReportHub.LogWarning(ReportCategory.ARCHIPELAGO_REQUEST, $"Cannot send heartbeat, connection is closed: {result.ErrorMessage}"); + ReportHub.LogWarning(ReportCategory.COMMS_SCENE_HANDLER, $"Cannot send heartbeat, connection is closed: {result.ErrorMessage}"); } private void OnNewConnectionString(string connectionString, CancellationToken token) { if (CurrentState() is IConnectiveRoom.State.Stopped) throw new InvalidOperationException("Room is not running"); connectToRoomAsyncDelegate.EnsureNotNull("Connection delegate is not passed yet"); - connectToRoomAsyncDelegate!(connectionString, token).Forget(); + connectToRoomAsyncDelegate!(connectionString, static () => RoomSelection.NEW, token).Forget(); } private async UniTask ConnectToArchipelagoAsync(CancellationToken token) @@ -127,12 +127,12 @@ private async UniTask> WelcomePeerIdAsync(string adapterUrl, if (messageForSignResult.Success == false || !HandshakePayloadIsValid(messageForSignResult.Result)) { - ReportHub.LogError(ReportCategory.ARCHIPELAGO_REQUEST, $"Cannot obtain a message to sign a welcome peer"); + ReportHub.LogError(ReportCategory.COMMS_SCENE_HANDLER, "Cannot obtain a message to sign a welcome peer"); return LightResult.FAILURE; } string signedMessage = identity.Sign(messageForSignResult.Result).ToJson(); - ReportHub.Log(ReportCategory.ARCHIPELAGO_REQUEST, $"Signed message: {signedMessage}"); + ReportHub.Log(ReportCategory.COMMS_SCENE_HANDLER, $"Signed message: {signedMessage}"); return await signFlow.WelcomePeerIdAsync(signedMessage, token); } diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/Rooms/Fixed/FixedConnectiveRoom.cs b/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/Rooms/Fixed/FixedConnectiveRoom.cs index d9ad243240..e63daf8273 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/Rooms/Fixed/FixedConnectiveRoom.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/Rooms/Fixed/FixedConnectiveRoom.cs @@ -45,7 +45,7 @@ private async UniTask RunConnectCycleStepAsync(ConnectToRoomAsyncDelegate connec if (connectiveRoom.CurrentState() is not IConnectiveRoom.State.Running) { string connectionString = await ConnectionStringAsync(token); - await connectToRoomAsyncDelegate(connectionString, token); + await connectToRoomAsyncDelegate(connectionString, static () => RoomSelection.NEW, token); } } @@ -56,7 +56,7 @@ private async UniTask ConnectionStringAsync(CancellationToken token) var result = webRequests.SignedFetchPostAsync(adapterUrl, metadata, token); AdapterResponse response = await result.CreateFromJson(WRJsonParser.Unity); string connectionString = response.fixedAdapter; - ReportHub.WithReport(ReportCategory.ARCHIPELAGO_REQUEST).Log($"String is: {connectionString}"); + ReportHub.WithReport(ReportCategory.COMMS_SCENE_HANDLER).Log($"String is: {connectionString}"); return connectionString; } diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/SignFlow/LogArchipelagoSignFlow.cs b/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/SignFlow/LogArchipelagoSignFlow.cs index aac1aaacd5..300a40c4ae 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/SignFlow/LogArchipelagoSignFlow.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/Archipelago/SignFlow/LogArchipelagoSignFlow.cs @@ -16,7 +16,7 @@ public class LogArchipelagoSignFlow : IArchipelagoSignFlow public LogArchipelagoSignFlow(IArchipelagoSignFlow origin) : this( origin, - m => ReportHub.Log(ReportCategory.ARCHIPELAGO_REQUEST, m) + m => ReportHub.Log(ReportCategory.COMMS_SCENE_HANDLER, m) ) { } public LogArchipelagoSignFlow(IArchipelagoSignFlow origin, Action log) diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/ISceneRoomMetaDataSource.cs b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/ISceneRoomMetaDataSource.cs index 4beb0c527b..d36cf75d41 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/ISceneRoomMetaDataSource.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/ISceneRoomMetaDataSource.cs @@ -10,8 +10,10 @@ public interface ISceneRoomMetaDataSource /// bool ScenesCommunicationIsIsolated { get; } - UniTask MetaDataAsync(CancellationToken token); + MetaData.Input GetMetadataInput(); - UniTask WaitForMetaDataIsDirtyAsync(CancellationToken token); + UniTask MetaDataAsync(MetaData.Input input, CancellationToken token); + + bool MetadataIsDirty { get; } } } diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/MetaData.cs b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/MetaData.cs index fff6be8d49..d4661e3fe6 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/MetaData.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/MetaData.cs @@ -8,22 +8,49 @@ namespace DCL.Multiplayer.Connections.GateKeeper.Meta [SuppressMessage("ReSharper", "NotAccessedField.Local")] public struct MetaData : IEquatable { + public readonly struct Input : IEquatable + { + public readonly string RealmName; + public readonly Vector2Int Parcel; + + public Input(string realmName, Vector2Int parcel) + { + RealmName = realmName; + Parcel = parcel; + } + + public bool Equals(Input other) => + RealmName == other.RealmName && Parcel.Equals(other.Parcel); + + public override bool Equals(object? obj) => + obj is Input other && Equals(other); + + public override int GetHashCode() => + HashCode.Combine(RealmName, Parcel); + + public override string ToString() => + $"Realm: {RealmName}, Parcel: {Parcel}"; + } + public string realmName; public string? sceneId; [NonSerialized] public readonly Vector2Int Parcel; - public MetaData(string realmName, string? sceneId, Vector2Int parcel) + public MetaData(string? sceneId, Input input) { - this.realmName = realmName; + realmName = input.RealmName; + Parcel = input.Parcel; this.sceneId = sceneId; - Parcel = parcel; } public string ToJson() => JsonUtility.ToJson(this)!; + public override string ToString() => + $"Realm: {realmName}, Scene: {sceneId}, Parcel: {Parcel}"; + public bool Equals(MetaData other) => realmName == other.realmName && sceneId == other.sceneId; diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/SceneRoomLogMetaDataSource.cs b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/SceneRoomLogMetaDataSource.cs index 30ebe2ffcf..7e9822c1fe 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/SceneRoomLogMetaDataSource.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/SceneRoomLogMetaDataSource.cs @@ -10,7 +10,6 @@ public class SceneRoomLogMetaDataSource : ISceneRoomMetaDataSource private const string PREFIX = "MetaDataSource:"; private readonly ISceneRoomMetaDataSource origin; - private readonly Action log; public SceneRoomLogMetaDataSource(ISceneRoomMetaDataSource origin) { @@ -19,19 +18,21 @@ public SceneRoomLogMetaDataSource(ISceneRoomMetaDataSource origin) public bool ScenesCommunicationIsIsolated => origin.ScenesCommunicationIsIsolated; - public async UniTask MetaDataAsync(CancellationToken token) + public MetaData.Input GetMetadataInput() { - ReportHub.WithReport(ReportCategory.LIVEKIT).Log($"{PREFIX} MetaDataAsync start"); - MetaData result = await origin.MetaDataAsync(token); - ReportHub.WithReport(ReportCategory.LIVEKIT).Log($"{PREFIX} MetaDataAsync finish {result.realmName} {result.sceneId}"); + ReportHub.WithReport(ReportCategory.LIVEKIT).Log($"{PREFIX} {nameof(GetMetadataInput)}"); + MetaData.Input result = origin.GetMetadataInput(); return result; } - public async UniTask WaitForMetaDataIsDirtyAsync(CancellationToken token) + public async UniTask MetaDataAsync(MetaData.Input input, CancellationToken token) { - ReportHub.WithReport(ReportCategory.LIVEKIT).Log($"{PREFIX} WaitForMetaDataIsDirtyAsync start"); - await origin.WaitForMetaDataIsDirtyAsync(token); - ReportHub.WithReport(ReportCategory.LIVEKIT).Log($"{PREFIX} WaitForMetaDataIsDirtyAsync finish"); + ReportHub.WithReport(ReportCategory.LIVEKIT).Log($"{PREFIX} {nameof(MetaDataAsync)} start: {input}"); + MetaData result = await origin.MetaDataAsync(input, token); + ReportHub.WithReport(ReportCategory.LIVEKIT).Log($"{PREFIX} {nameof(MetaDataAsync)} finish {result.realmName} {result.sceneId}"); + return result; } + + public bool MetadataIsDirty => origin.MetadataIsDirty; } } diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/SceneRoomMetaDataSource.cs b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/SceneRoomMetaDataSource.cs index 9be6eb3934..4a83ed4fbc 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/SceneRoomMetaDataSource.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Meta/SceneRoomMetaDataSource.cs @@ -14,9 +14,6 @@ public class SceneRoomMetaDataSource : ISceneRoomMetaDataSource private readonly IExposedTransform characterTransform; private readonly IPlacesAPIService placesAPIService; - private readonly Func waitForGenesisCity; - private readonly Func waitForPlayerPositionChange; - private readonly bool forceSceneIsolation; public SceneRoomMetaDataSource(IRealmData realmData, IExposedTransform characterTransform, IPlacesAPIService placesAPIService, bool forceSceneIsolation) @@ -25,40 +22,31 @@ public SceneRoomMetaDataSource(IRealmData realmData, IExposedTransform character this.characterTransform = characterTransform; this.placesAPIService = placesAPIService; this.forceSceneIsolation = forceSceneIsolation; - - waitForGenesisCity = () => !realmData.ScenesAreFixed; - waitForPlayerPositionChange = () => this.characterTransform.Position.IsDirty; } public bool ScenesCommunicationIsIsolated => forceSceneIsolation || !realmData.ScenesAreFixed; - public async UniTask MetaDataAsync(CancellationToken token) + public MetaData.Input GetMetadataInput() => + realmData.ScenesAreFixed + ? new MetaData.Input(realmData.RealmName, Vector2Int.zero) + : new MetaData.Input(realmData.RealmName, characterTransform.Position.ToParcel()); + + public async UniTask MetaDataAsync(MetaData.Input input, CancellationToken token) { // Places API is relevant for Genesis City only if (realmData.ScenesAreFixed) - return new MetaData(realmData.RealmName, realmData.RealmName, Vector2Int.zero); + return new MetaData(input.RealmName, input); - (string? id, Vector2Int parcel) tuple = await ParcelIdAsync(token); - return new MetaData(realmData.RealmName, tuple.id, tuple.parcel); + string? id = await ParcelIdAsync(input, token); + return new MetaData(id, input); } - public UniTask WaitForMetaDataIsDirtyAsync(CancellationToken token) - { - if (realmData.ScenesAreFixed) - - // Wait for realm change - return UniTask.WaitUntil(waitForGenesisCity, cancellationToken: token); - - // Wait for player position change (ideally for parcel change) - return UniTask.WaitUntil(waitForPlayerPositionChange, cancellationToken: token); - } + public bool MetadataIsDirty => !realmData.ScenesAreFixed && characterTransform.Position.IsDirty; - private async UniTask<(string? id, Vector2Int parcel)> ParcelIdAsync(CancellationToken token) + private async UniTask ParcelIdAsync(MetaData.Input input, CancellationToken token) { - Vector3 position = characterTransform.Position; - Vector2Int parcel = position.ToParcel(); - PlacesData.PlaceInfo? result = await placesAPIService.GetPlaceAsync(parcel, token); - return (result?.id, parcel); + PlacesData.PlaceInfo? result = await placesAPIService.GetPlaceAsync(input.Parcel, token); + return result?.id; } } } diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Rooms/GateKeeperSceneRoom.cs b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Rooms/GateKeeperSceneRoom.cs index 07e7b93068..35a9800ce1 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Rooms/GateKeeperSceneRoom.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Rooms/GateKeeperSceneRoom.cs @@ -18,7 +18,6 @@ public class GateKeeperSceneRoom : IGateKeeperSceneRoom private readonly ISceneRoomMetaDataSource metaDataSource; private readonly IConnectiveRoom connectiveRoom; private readonly string sceneHandleUrl; - private readonly Func roomIsNotRunning; private readonly IScenesCache scenesCache; @@ -27,7 +26,7 @@ public class GateKeeperSceneRoom : IGateKeeperSceneRoom /// private ISceneFacade? connectedScene; - private MetaData previousMetaData; + private MetaData.Input previousMetaData; public GateKeeperSceneRoom( IWebRequestController webRequests, @@ -45,11 +44,9 @@ public GateKeeperSceneRoom( RunConnectCycleStepAsync, nameof(GateKeeperSceneRoom) ); - - roomIsNotRunning = () => connectiveRoom.CurrentState() is not IConnectiveRoom.State.Running; } - public SceneShortInfo? ConnectedScene => connectedScene?.SceneData.SceneShortInfo; + public ISceneData? ConnectedScene => connectedScene?.SceneData; public bool IsSceneConnected(string? sceneId) => !metaDataSource.ScenesCommunicationIsIsolated || sceneId == connectedScene?.SceneData.SceneEntityDefinition.id; @@ -73,36 +70,70 @@ public IRoom Room() => private async UniTask RunConnectCycleStepAsync(ConnectToRoomAsyncDelegate connectToRoomAsyncDelegate, DisconnectCurrentRoomAsyncDelegate disconnectCurrentRoomAsyncDelegate, CancellationToken token) { - MetaData meta = await metaDataSource.MetaDataAsync(token); - - // Connect or disconnect, at the same time check if metadata has potentially changed - await UniTask.WhenAll(WaitForMetadataDirtyAsync(token), ProcessMetaDataAsync(token)); + MetaData meta = default; - async UniTask ProcessMetaDataAsync(CancellationToken token) + try { + MetaData.Input metaInput = metaDataSource.GetMetadataInput(); + meta = await metaDataSource.MetaDataAsync(metaInput, token); + + UniTask waitForReconnectionRequiredTask; + + // Disconnect if no sceneId assigned, disconnection can't be interrupted if (meta.sceneId == null) { connectedScene = null; await disconnectCurrentRoomAsyncDelegate(token); + + // After disconnection we need to wait for metadata to change + waitForReconnectionRequiredTask = WaitForMetadataIsDirtyAsync(token); + + previousMetaData = metaInput; + + async UniTask WaitForMetadataIsDirtyAsync(CancellationToken token) + { + while (!metaDataSource.MetadataIsDirty) + await UniTask.Yield(token); + } } - else if (!meta.Equals(previousMetaData)) + else { - string connectionString = await ConnectionStringAsync(meta, token); - await connectToRoomAsyncDelegate(connectionString, token); - scenesCache.TryGetByParcel(meta.Parcel, out connectedScene); + if (!metaInput.Equals(previousMetaData)) + { + string connectionString = await ConnectionStringAsync(meta, token); + + // if the player returns to the previous scene but the new room has been connected, the previous connection should be preserved + // and the new connection should be discarded + RoomSelection roomSelection = await connectToRoomAsyncDelegate( + connectionString, + () => metaDataSource.GetMetadataInput().Equals(previousMetaData) ? RoomSelection.PREVIOUS : RoomSelection.NEW, + token); + + if (roomSelection == RoomSelection.NEW) + { + previousMetaData = metaInput; + scenesCache.TryGetByParcel(metaInput.Parcel, out connectedScene); + } + } + + waitForReconnectionRequiredTask = WaitForReconnectionRequiredAsync(token); + + // Either room has disconnected or metadata has changed + async UniTask WaitForReconnectionRequiredAsync(CancellationToken token) + { + while (connectiveRoom.CurrentState() is IConnectiveRoom.State.Running + && !metaDataSource.MetadataIsDirty) + await UniTask.Yield(token); + } } - previousMetaData = meta; + await waitForReconnectionRequiredTask; + } + catch (Exception e) when (e is not OperationCanceledException) + { + // if we don't catch an exception, any failure leads to the loop being stopped + ReportHub.Log(ReportCategory.COMMS_SCENE_HANDLER, $"Exception occured in {nameof(RunConnectCycleStepAsync)} when {meta} was being processed: {e}"); } - } - - /// - /// Either room has disconnected or metadata has changed - /// - /// - private async UniTask WaitForMetadataDirtyAsync(CancellationToken token) - { - await UniTask.WhenAny(UniTask.WaitUntil(roomIsNotRunning, cancellationToken: token), metaDataSource.WaitForMetaDataIsDirtyAsync(token)); } private async UniTask ConnectionStringAsync(MetaData meta, CancellationToken token) @@ -114,7 +145,7 @@ private async UniTask ConnectionStringAsync(MetaData meta, CancellationT .CreateFromJson(WRJsonParser.Unity); string connectionString = response.adapter; - ReportHub.WithReport(ReportCategory.ARCHIPELAGO_REQUEST).Log($"String is: {connectionString}"); + ReportHub.WithReport(ReportCategory.COMMS_SCENE_HANDLER).Log($"String is: {connectionString}"); return connectionString; } diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Rooms/IGateKeeperSceneRoom.cs b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Rooms/IGateKeeperSceneRoom.cs index 1530fb7ac8..022db67738 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Rooms/IGateKeeperSceneRoom.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/GateKeeper/Rooms/IGateKeeperSceneRoom.cs @@ -17,7 +17,7 @@ public interface IGateKeeperSceneRoom : IConnectiveRoom /// bool IsSceneConnected(string? sceneId); - public SceneShortInfo? ConnectedScene { get; } + public ISceneData? ConnectedScene { get; } class Fake : IGateKeeperSceneRoom { @@ -36,7 +36,7 @@ public IRoom Room() => public bool IsSceneConnected(string sceneId) => false; - public SceneShortInfo? ConnectedScene => new SceneShortInfo(); + public ISceneData? ConnectedScene { get; } = new ISceneData.Fake(); } } } diff --git a/Explorer/Assets/DCL/Multiplayer/Connections/Rooms/Connective/ConnectiveRoom.cs b/Explorer/Assets/DCL/Multiplayer/Connections/Rooms/Connective/ConnectiveRoom.cs index a331c908b7..c0d5d255ff 100644 --- a/Explorer/Assets/DCL/Multiplayer/Connections/Rooms/Connective/ConnectiveRoom.cs +++ b/Explorer/Assets/DCL/Multiplayer/Connections/Rooms/Connective/ConnectiveRoom.cs @@ -27,7 +27,18 @@ public delegate UniTask CycleStepDelegate( CancellationToken token ); - public delegate UniTask ConnectToRoomAsyncDelegate(string connectionString, CancellationToken token); + public enum RoomSelection : byte + { + NEW, + PREVIOUS, + } + + /// + /// When the new room is connected, it can be invalid so it's possible to revert to the previous one + /// + public delegate RoomSelection SelectValidRoom(); + + public delegate UniTask ConnectToRoomAsyncDelegate(string connectionString, SelectValidRoom selectValidRoom, CancellationToken token); public delegate UniTask DisconnectCurrentRoomAsyncDelegate(CancellationToken token); @@ -138,7 +149,7 @@ private async UniTask DisconnectCurrentRoomAsync(CancellationToken token) .Log($"{logPrefix} - Trying to disconnect current room finished"); } - private async UniTask TryConnectToRoomAsync(string connectionString, CancellationToken token) + private async UniTask TryConnectToRoomAsync(string connectionString, SelectValidRoom selectValidRoom, CancellationToken token) { ReportHub .WithReport(ReportCategory.LIVEKIT) @@ -150,20 +161,43 @@ private async UniTask TryConnectToRoomAsync(string connectionString, Cancellatio bool connectResult = await newRoom.ConnectAsync(credentials, token); - attemptToConnectState.Set(connectResult ? AttemptToConnectState.Success : AttemptToConnectState.Error); + AttemptToConnectState connectionState = connectResult ? AttemptToConnectState.Success : AttemptToConnectState.Error; + attemptToConnectState.Set(connectionState); if (connectResult == false) { roomPool.Release(newRoom); ReportHub.LogWarning(ReportCategory.LIVEKIT, $"{logPrefix} - Cannot connect to room with url: {credentials.Url} with token: {credentials.AuthToken}"); - return; + return RoomSelection.PREVIOUS; } - await AssignNewRoomAndReleasePreviousAsync(newRoom, token); - roomState.Set(IConnectiveRoom.State.Running); - ReportHub - .WithReport(ReportCategory.LIVEKIT) - .Log($"{logPrefix} - Trying to connect to finished successfully: {connectionString}"); + RoomSelection roomSelection = selectValidRoom(); + + switch (roomSelection) + { + case RoomSelection.NEW: + await AssignNewRoomAndReleasePreviousAsync(newRoom, token); + roomState.Set(IConnectiveRoom.State.Running); + + ReportHub + .WithReport(ReportCategory.LIVEKIT) + .Log($"{logPrefix} - Trying to connect to finished successfully {connectionString}"); + + break; + case RoomSelection.PREVIOUS: + // drop the new room + await ReleaseRoomAsync(newRoom, token); + + // preserve the previous state (for whatever reason) + ReportHub + .WithReport(ReportCategory.LIVEKIT) + .Log($"{logPrefix} - Connection to the previous room was preserved"); + + break; + default: throw new ArgumentOutOfRangeException(nameof(roomSelection)); + } + + return roomSelection; } private async UniTask AssignNewRoomAndReleasePreviousAsync(IRoom newRoom, CancellationToken token) @@ -171,10 +205,13 @@ private async UniTask AssignNewRoomAndReleasePreviousAsync(IRoom newRoom, Cancel room.Assign(newRoom, out IRoom? previous); if (previous is not null) - { - await previous.DisconnectAsync(token); - roomPool.Release(previous); - } + await ReleaseRoomAsync(previous, token); + } + + private async UniTask ReleaseRoomAsync(IRoom room, CancellationToken token) + { + await room.DisconnectAsync(token); + roomPool.Release(room); } } } diff --git a/Explorer/Assets/DCL/Multiplayer/Profiles/DCL.Multiplayer.Profiles.asmdef b/Explorer/Assets/DCL/Multiplayer/Profiles/DCL.Multiplayer.Profiles.asmdef index 0c21ec17e5..102aef7b5d 100644 --- a/Explorer/Assets/DCL/Multiplayer/Profiles/DCL.Multiplayer.Profiles.asmdef +++ b/Explorer/Assets/DCL/Multiplayer/Profiles/DCL.Multiplayer.Profiles.asmdef @@ -19,7 +19,8 @@ "GUID:5ab29fa8ae5769b49ab29e390caca7a4", "GUID:3c7b57a14671040bd8c549056adc04f5", "GUID:e25ef972de004615a22937e739de2def", - "GUID:8322ea9340a544c59ddc56d4793eac74" + "GUID:8322ea9340a544c59ddc56d4793eac74", + "GUID:286980af24684da6acc1caa413039811" ], "includePlatforms": [], diff --git a/Explorer/Assets/DCL/Multiplayer/Profiles/Poses/RemoteMetadata.cs b/Explorer/Assets/DCL/Multiplayer/Profiles/Poses/RemoteMetadata.cs index d84bfffb40..8fd1b9ede5 100644 --- a/Explorer/Assets/DCL/Multiplayer/Profiles/Poses/RemoteMetadata.cs +++ b/Explorer/Assets/DCL/Multiplayer/Profiles/Poses/RemoteMetadata.cs @@ -6,6 +6,7 @@ using ECS; using LiveKit.Rooms; using LiveKit.Rooms.Participants; +using SceneRunner.Scene; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -76,7 +77,7 @@ private void OnUpdatesFromParticipantInSceneRoom(Participant participant, Update return; IGateKeeperSceneRoom sceneRoom = roomHub.SceneRoom(); - SceneShortInfo? sceneInfo = sceneRoom.ConnectedScene; + ISceneData? sceneInfo = sceneRoom.ConnectedScene; if (sceneInfo == null) return; SceneRoomMetadata message; @@ -84,7 +85,7 @@ private void OnUpdatesFromParticipantInSceneRoom(Participant participant, Update try { message = JsonUtility.FromJson(participant.Metadata); } catch (Exception) { return; } - ParticipantsOnUpdatesFromParticipant(participant, new IRemoteMetadata.ParticipantMetadata(sceneInfo.Value.BaseParcel, URLDomain.FromString(message.lambdasEndpoint))); + ParticipantsOnUpdatesFromParticipant(participant, new IRemoteMetadata.ParticipantMetadata(sceneInfo.SceneShortInfo.BaseParcel, URLDomain.FromString(message.lambdasEndpoint))); } } diff --git a/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/Handlers/DebugLogReportHandler.cs b/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/Handlers/DebugLogReportHandler.cs index e2d950e9cf..28a21376f0 100644 --- a/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/Handlers/DebugLogReportHandler.cs +++ b/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/Handlers/DebugLogReportHandler.cs @@ -19,7 +19,7 @@ public class DebugLogReportHandler : ReportHandlerBase { ReportCategory.GENERIC_WEB_REQUEST, ColorUtility.ToHtmlStringRGB(new Color(0.902f, 0.886f, 0.082f)) }, // Rooms - { ReportCategory.ARCHIPELAGO_REQUEST, ColorUtility.ToHtmlStringRGB(new Color(0.982f, 0.996f, 0.182f)) }, + { ReportCategory.COMMS_SCENE_HANDLER, ColorUtility.ToHtmlStringRGB(new Color(0.982f, 0.996f, 0.182f)) }, { ReportCategory.LIVEKIT, ColorUtility.ToHtmlStringRGB(new Color(0.982f, 0.996f, 0.282f)) }, { ReportCategory.SDK_LOCAL_SCENE_DEVELOPMENT, ColorUtility.ToHtmlStringRGB(new Color(0.982f, 0.996f, 0.282f)) }, diff --git a/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/ReportCategory.cs b/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/ReportCategory.cs index c6253d7388..15c820a49a 100644 --- a/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/ReportCategory.cs +++ b/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/ReportCategory.cs @@ -65,9 +65,9 @@ public static class ReportCategory public const string JAVASCRIPT = nameof(JAVASCRIPT); /// - /// Archipelago requests + /// Archipelago and gatekeeper requests /// - public const string ARCHIPELAGO_REQUEST = nameof(ARCHIPELAGO_REQUEST); + public const string COMMS_SCENE_HANDLER = nameof(COMMS_SCENE_HANDLER); /// /// Unspecified ECS World Exceptions diff --git a/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/ReportsHandlingSettingsDevelopment.asset b/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/ReportsHandlingSettingsDevelopment.asset index 6a6def5b71..75aec8271b 100644 --- a/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/ReportsHandlingSettingsDevelopment.asset +++ b/Explorer/Assets/DCL/PerformanceAndDiagnostics/Diagnostics/ReportsHandling/ReportsHandlingSettingsDevelopment.asset @@ -486,6 +486,12 @@ MonoBehaviour: Severity: 1 - Category: WEARABLE Severity: 1 + - Category: COMMS_SCENE_HANDLER + Severity: 0 + - Category: COMMS_SCENE_HANDLER + Severity: 4 + - Category: COMMS_SCENE_HANDLER + Severity: 1 sentryMatrix: entries: [] debounceEnabled: 1 diff --git a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementation.cs b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementation.cs index a0c0f8889c..3de2142b42 100644 --- a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementation.cs +++ b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementation.cs @@ -1,5 +1,4 @@ using CRDT.Memory; -using CrdtEcsBridge.PoolsProviders; using SceneRunner.Scene; using SceneRuntime; using System; diff --git a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementationBase.cs b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementationBase.cs index a7086063bb..19e0fd00d1 100644 --- a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementationBase.cs +++ b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/CommunicationsControllerAPIImplementationBase.cs @@ -12,6 +12,11 @@ namespace CrdtEcsBridge.JsModulesImplementation.Communications { public abstract class CommunicationsControllerAPIImplementationBase : ICommunicationsControllerAPI { + /// + /// Special signal to receive CRDT State from a peer + /// + private const byte REQ_CRDT_STATE = 2; + protected readonly List> eventsToProcess = new (); private readonly CancellationTokenSource cancellationTokenSource = new (); private readonly ISceneCommunicationPipe sceneCommunicationPipe; @@ -52,7 +57,14 @@ public object SendBinary(IReadOnlyList data) { foreach (PoolableByteArray poolable in data) if (poolable.Length > 0) - EncodeAndSendMessage(ISceneCommunicationPipe.MsgType.Uint8Array, poolable.Memory.Span); + { + ISceneCommunicationPipe.ConnectivityAssertiveness assertiveness = poolable.Span[0] == REQ_CRDT_STATE + ? ISceneCommunicationPipe.ConnectivityAssertiveness.DELIVERY_ASSERTED + : ISceneCommunicationPipe.ConnectivityAssertiveness.DROP_IF_NOT_CONNECTED; + + EncodeAndSendMessage(ISceneCommunicationPipe.MsgType.Uint8Array, poolable.Memory.Span, assertiveness); + } + lock (eventsToProcess) { @@ -71,12 +83,13 @@ private void CleanUpReceivedMessages() eventsToProcess.Clear(); } - protected void EncodeAndSendMessage(ISceneCommunicationPipe.MsgType msgType, ReadOnlySpan message) + protected void EncodeAndSendMessage(ISceneCommunicationPipe.MsgType msgType, ReadOnlySpan message, ISceneCommunicationPipe.ConnectivityAssertiveness assertiveness) { Span encodedMessage = stackalloc byte[message.Length + 1]; encodedMessage[0] = (byte)msgType; message.CopyTo(encodedMessage[1..]); - sceneCommunicationPipe.SendMessage(encodedMessage, sceneId, cancellationTokenSource.Token); + + sceneCommunicationPipe.SendMessage(encodedMessage, sceneId, assertiveness, cancellationTokenSource.Token); } protected abstract void OnMessageReceived(ISceneCommunicationPipe.DecodedMessage decodedMessage); diff --git a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/ISceneCommunicationPipe.cs b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/ISceneCommunicationPipe.cs index abe69be4ad..ed6ab93bdb 100644 --- a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/ISceneCommunicationPipe.cs +++ b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/ISceneCommunicationPipe.cs @@ -13,13 +13,26 @@ public enum MsgType Uint8Array = 2, } + public enum ConnectivityAssertiveness + { + /// + /// Message will be dropped silently if the scene is not connected + /// + DROP_IF_NOT_CONNECTED = 0, + + /// + /// Additional information will be printed if the scene is not connected + /// + DELIVERY_ASSERTED = 1, + } + public delegate void SceneMessageHandler(DecodedMessage message); void AddSceneMessageHandler(string sceneId, MsgType msgType, SceneMessageHandler onSceneMessage); void RemoveSceneMessageHandler(string sceneId, MsgType msgType, SceneMessageHandler onSceneMessage); - void SendMessage(ReadOnlySpan message, string sceneId, CancellationToken ct); + void SendMessage(ReadOnlySpan message, string sceneId, ConnectivityAssertiveness assertiveness, CancellationToken ct); readonly ref struct DecodedMessage { diff --git a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/SDKMessageBus/SDKMessageBusCommsAPIImplementation.cs b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/SDKMessageBus/SDKMessageBusCommsAPIImplementation.cs index 8e0d8e3ba4..f51286f4d7 100644 --- a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/SDKMessageBus/SDKMessageBusCommsAPIImplementation.cs +++ b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/SDKMessageBus/SDKMessageBusCommsAPIImplementation.cs @@ -25,7 +25,7 @@ public void ClearMessages() public void Send(string data) { byte[] dataBytes = Encoding.UTF8.GetBytes(data); - EncodeAndSendMessage(ISceneCommunicationPipe.MsgType.String, dataBytes); + EncodeAndSendMessage(ISceneCommunicationPipe.MsgType.String, dataBytes, ISceneCommunicationPipe.ConnectivityAssertiveness.DROP_IF_NOT_CONNECTED); } protected override void OnMessageReceived(ISceneCommunicationPipe.DecodedMessage message) diff --git a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/SceneCommunicationPipe.cs b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/SceneCommunicationPipe.cs index 9d22616f40..1fcc549296 100644 --- a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/SceneCommunicationPipe.cs +++ b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Communications/SceneCommunicationPipe.cs @@ -1,4 +1,5 @@ -using DCL.Multiplayer.Connections.GateKeeper.Rooms; +using DCL.Diagnostics; +using DCL.Multiplayer.Connections.GateKeeper.Rooms; using DCL.Multiplayer.Connections.Messaging; using DCL.Multiplayer.Connections.Messaging.Hubs; using DCL.Multiplayer.Connections.Messaging.Pipe; @@ -7,7 +8,6 @@ using LiveKit.Proto; using System; using System.Collections.Generic; -using System.Runtime.CompilerServices; using System.Threading; namespace CrdtEcsBridge.JsModulesImplementation.Communications @@ -68,9 +68,18 @@ public void RemoveSceneMessageHandler(string sceneId, ISceneCommunicationPipe.Ms sceneMessageHandlers.Remove(key); } - public void SendMessage(ReadOnlySpan message, string sceneId, CancellationToken ct) + public void SendMessage(ReadOnlySpan message, string sceneId, ISceneCommunicationPipe.ConnectivityAssertiveness assertiveness, CancellationToken ct) { - if (!sceneRoom.IsSceneConnected(sceneId)) return; + if (!sceneRoom.IsSceneConnected(sceneId)) + { + if (assertiveness == ISceneCommunicationPipe.ConnectivityAssertiveness.DELIVERY_ASSERTED) + ReportHub.LogError(ReportCategory.COMMS_SCENE_HANDLER, $"Scene \"{sceneId}\" expected to deliver the message but {nameof(GateKeeperSceneRoom)} is connected to \"{sceneRoom.ConnectedScene?.SceneEntityDefinition.id}\""); + + return; + } + + if (assertiveness == ISceneCommunicationPipe.ConnectivityAssertiveness.DELIVERY_ASSERTED) + ReportHub.Log(ReportCategory.COMMS_SCENE_HANDLER, $"Sending scene message to {sceneRoom.Room().Participants.RemoteParticipantIdentities().Count} peers"); MessageWrap sceneMessage = messagePipe.NewMessage(); sceneMessage.Payload.Data = ByteString.CopyFrom(message); diff --git a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Tests/CommunicationControllerAPIImplementationShould.cs b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Tests/CommunicationControllerAPIImplementationShould.cs index 5cc9a08ae2..980aea625c 100644 --- a/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Tests/CommunicationControllerAPIImplementationShould.cs +++ b/Explorer/Assets/Scripts/CrdtEcsBridge/JsModulesImplementation/Tests/CommunicationControllerAPIImplementationShould.cs @@ -114,7 +114,7 @@ public void AddSceneMessageHandler(string sceneId, ISceneCommunicationPipe.MsgTy public void RemoveSceneMessageHandler(string sceneId, ISceneCommunicationPipe.MsgType msgType, ISceneCommunicationPipe.SceneMessageHandler onSceneMessage) { } - public void SendMessage(ReadOnlySpan message, string sceneId, CancellationToken ct) + public void SendMessage(ReadOnlySpan message, string sceneId, ISceneCommunicationPipe.ConnectivityAssertiveness assertiveness, CancellationToken ct) { sendMessageCalls.Add(message.ToArray()); } From f0612eb6a8fd47f858800b4ea23178f6004f33db Mon Sep 17 00:00:00 2001 From: lorenzo-ranciaffi <41125365+lorenzo-ranciaffi@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:17:15 +0200 Subject: [PATCH 12/16] fix: bind connection status panel visibility to debug command (#2441) --- .../Global/ConnectionStatusPanelPlugin.cs | 40 +++++++++++------- .../ConnectionStatusPanelController.cs | 12 +++++- .../UI.ConnectionStatusPanel.asmdef | 3 +- .../UI/MainUIContainer/MainUIContainer.prefab | 42 ++++++++++--------- .../ChatCommands/DebugPanelChatCommand.cs | 6 ++- .../Global/Dynamic/DynamicWorldContainer.cs | 9 ++-- 6 files changed, 70 insertions(+), 42 deletions(-) diff --git a/Explorer/Assets/DCL/PluginSystem/Global/ConnectionStatusPanelPlugin.cs b/Explorer/Assets/DCL/PluginSystem/Global/ConnectionStatusPanelPlugin.cs index b4a87d6cad..dcb25ea6bb 100644 --- a/Explorer/Assets/DCL/PluginSystem/Global/ConnectionStatusPanelPlugin.cs +++ b/Explorer/Assets/DCL/PluginSystem/Global/ConnectionStatusPanelPlugin.cs @@ -1,6 +1,7 @@ using Arch.Core; using Arch.SystemGroups; using Cysharp.Threading.Tasks; +using DCL.DebugUtilities; using DCL.Multiplayer.Connections.Rooms.Status; using DCL.UI.ConnectionStatusPanel; using DCL.UI.MainUI; @@ -22,6 +23,8 @@ public class ConnectionStatusPanelPlugin : IDCLGlobalPlugin builder, in GlobalPluginArguments arguments) { } + public void SetVisibility(bool visibility) => + connectionStatusPanelController?.SetVisibility(visibility); + public async UniTask InitializeAsync(ConnectionStatusPanelSettings settings, CancellationToken ct) { - mvcManager.RegisterController( - new ConnectionStatusPanelController(() => - { - var view = mainUIView.ConnectionStatusPanelView; - view!.gameObject.SetActive(true); - return view; - }, - userInAppInitializationFlow, - mvcManager, - currentSceneInfo, - ecsReloadScene, - roomsStatus, - world, - playerEntity - ) + connectionStatusPanelController = new ConnectionStatusPanelController(() => + { + var view = mainUIView.ConnectionStatusPanelView; + view!.gameObject.SetActive(true); + return view; + }, + userInAppInitializationFlow, + mvcManager, + currentSceneInfo, + ecsReloadScene, + roomsStatus, + world, + playerEntity, + debugBuilder ); + mvcManager.RegisterController(connectionStatusPanelController); } public class ConnectionStatusPanelSettings : IDCLPluginSettings { } diff --git a/Explorer/Assets/DCL/UI/ConnectionStatusPanel/ConnectionStatusPanelController.cs b/Explorer/Assets/DCL/UI/ConnectionStatusPanel/ConnectionStatusPanelController.cs index 8551d6aae9..53f482f5f1 100644 --- a/Explorer/Assets/DCL/UI/ConnectionStatusPanel/ConnectionStatusPanelController.cs +++ b/Explorer/Assets/DCL/UI/ConnectionStatusPanel/ConnectionStatusPanelController.cs @@ -1,5 +1,6 @@ using Arch.Core; using Cysharp.Threading.Tasks; +using DCL.DebugUtilities; using DCL.Multiplayer.Connections.Rooms.Status; using DCL.UI.ConnectionStatusPanel.StatusEntry; using DCL.UI.ErrorPopup; @@ -25,6 +26,7 @@ public partial class ConnectionStatusPanelController : ControllerBase subscriptions = new (2); private bool isSceneReloading; @@ -39,7 +41,8 @@ public ConnectionStatusPanelController( ECSReloadScene ecsReloadScene, IRoomsStatus roomsStatus, World world, - Entity playerEntity + Entity playerEntity, + IDebugContainerBuilder debugBuilder ) : base(viewFactory) { this.userInAppInitializationFlow = userInAppInitializationFlow; @@ -49,6 +52,7 @@ Entity playerEntity this.roomsStatus = roomsStatus; this.world = world; this.playerEntity = playerEntity; + this.debugBuilder = debugBuilder; } protected override void OnViewInstantiated() @@ -59,6 +63,12 @@ protected override void OnViewInstantiated() Bind(roomsStatus.ConnectionQualityIsland, viewInstance.GlobalRoom); } + protected override void OnViewShow() => + SetVisibility(debugBuilder.IsVisible); + + public void SetVisibility(bool isVisible) => + viewInstance?.gameObject.SetActive(isVisible); + private void SceneStatusOnUpdate(ICurrentSceneInfo.Status? obj) { const float DELAY = 5f; diff --git a/Explorer/Assets/DCL/UI/ConnectionStatusPanel/UI.ConnectionStatusPanel.asmdef b/Explorer/Assets/DCL/UI/ConnectionStatusPanel/UI.ConnectionStatusPanel.asmdef index e1d5ed36f1..38da60f89a 100644 --- a/Explorer/Assets/DCL/UI/ConnectionStatusPanel/UI.ConnectionStatusPanel.asmdef +++ b/Explorer/Assets/DCL/UI/ConnectionStatusPanel/UI.ConnectionStatusPanel.asmdef @@ -12,6 +12,7 @@ "GUID:702f733b4deb246808c6ce84d93b5c9c", "GUID:a285ec5e26824438b1b2ab8f22969298", "GUID:254c118155004a75a699a9410d44311f", - "GUID:fa7b3fdbb04d67549916da7bd2af58ab" + "GUID:fa7b3fdbb04d67549916da7bd2af58ab", + "GUID:4725c02394ab4ce19f889e4e8001f989" ] } diff --git a/Explorer/Assets/DCL/UI/MainUIContainer/MainUIContainer.prefab b/Explorer/Assets/DCL/UI/MainUIContainer/MainUIContainer.prefab index 4ec320b065..c78dbc4522 100644 --- a/Explorer/Assets/DCL/UI/MainUIContainer/MainUIContainer.prefab +++ b/Explorer/Assets/DCL/UI/MainUIContainer/MainUIContainer.prefab @@ -1939,7 +1939,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 243621710923428424, guid: f3b1d401bc50845629a6b982f9793f16, type: 3} propertyPath: m_Value - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 510719210599564447, guid: f3b1d401bc50845629a6b982f9793f16, type: 3} propertyPath: m_AnchorMax.y @@ -2236,27 +2236,27 @@ PrefabInstance: m_Modifications: - target: {fileID: 2706396233118463039, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 2706396233118463039, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 2706396233118463039, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 348 objectReference: {fileID: 0} - target: {fileID: 2706396233118463039, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 52 objectReference: {fileID: 0} - target: {fileID: 2706396233118463039, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 174 objectReference: {fileID: 0} - target: {fileID: 2706396233118463039, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -26 objectReference: {fileID: 0} - target: {fileID: 3382456182348012152, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchoredPosition.x @@ -2360,56 +2360,60 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 9082214662459176086, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 9082214662459176086, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 9082214662459176086, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 348 objectReference: {fileID: 0} - target: {fileID: 9082214662459176086, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 52 objectReference: {fileID: 0} - target: {fileID: 9082214662459176086, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 174 objectReference: {fileID: 0} - target: {fileID: 9082214662459176086, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -78 objectReference: {fileID: 0} - target: {fileID: 9129438995921044100, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 9129438995921044100, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 9129438995921044100, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 348 objectReference: {fileID: 0} - target: {fileID: 9129438995921044100, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 52 objectReference: {fileID: 0} - target: {fileID: 9129438995921044100, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 174 objectReference: {fileID: 0} - target: {fileID: 9129438995921044100, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -130 objectReference: {fileID: 0} - target: {fileID: 9152785347356188261, guid: 6077eff354abb4953be2d4d994be830e, type: 3} propertyPath: m_Name value: ConnectionStatus objectReference: {fileID: 0} + - target: {fileID: 9152785347356188261, guid: 6077eff354abb4953be2d4d994be830e, type: 3} + propertyPath: m_IsActive + value: 0 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] diff --git a/Explorer/Assets/Scripts/Global/Dynamic/ChatCommands/DebugPanelChatCommand.cs b/Explorer/Assets/Scripts/Global/Dynamic/ChatCommands/DebugPanelChatCommand.cs index c6e73ec54d..1967c7f25e 100644 --- a/Explorer/Assets/Scripts/Global/Dynamic/ChatCommands/DebugPanelChatCommand.cs +++ b/Explorer/Assets/Scripts/Global/Dynamic/ChatCommands/DebugPanelChatCommand.cs @@ -2,6 +2,7 @@ using DCL.Chat.Commands; using DCL.DebugUtilities; using DCL.DebugUtilities.Views; +using DCL.PluginSystem.Global; using System; using System.Text.RegularExpressions; using System.Threading; @@ -13,12 +14,14 @@ public class DebugPanelChatCommand : IChatCommand public static readonly Regex REGEX = new (@"^/debug(?:\s+(\w+))?$", RegexOptions.Compiled); private readonly IDebugContainerBuilder debugContainerBuilder; + private readonly ConnectionStatusPanelPlugin connectionStatusPanelPlugin; private string? param; - public DebugPanelChatCommand(IDebugContainerBuilder debugContainerBuilder) + public DebugPanelChatCommand(IDebugContainerBuilder debugContainerBuilder, ConnectionStatusPanelPlugin connectionStatusPanelPlugin) { this.debugContainerBuilder = debugContainerBuilder; + this.connectionStatusPanelPlugin = connectionStatusPanelPlugin; } public UniTask ExecuteAsync(Match match, CancellationToken _) @@ -29,6 +32,7 @@ public UniTask ExecuteAsync(Match match, CancellationToken _) { bool visible = !debugContainerBuilder.IsVisible; debugContainerBuilder.IsVisible = visible; + connectionStatusPanelPlugin.SetVisibility(visible); return UniTask.FromResult(string.Empty); } diff --git a/Explorer/Assets/Scripts/Global/Dynamic/DynamicWorldContainer.cs b/Explorer/Assets/Scripts/Global/Dynamic/DynamicWorldContainer.cs index fbfce787a3..f2db9d42fd 100644 --- a/Explorer/Assets/Scripts/Global/Dynamic/DynamicWorldContainer.cs +++ b/Explorer/Assets/Scripts/Global/Dynamic/DynamicWorldContainer.cs @@ -390,11 +390,14 @@ IMultiPool MultiPoolFactory() => var chatHistory = new ChatHistory(); + var currentSceneInfo = new CurrentSceneInfo(); + ConnectionStatusPanelPlugin connectionStatusPanelPlugin = new ConnectionStatusPanelPlugin(container.UserInAppInAppInitializationFlow, container.MvcManager, mainUIView, roomsStatus, currentSceneInfo, container.reloadSceneController, globalWorld, playerEntity, debugBuilder); + var chatCommandsFactory = new Dictionary> { { GoToChatCommand.REGEX, () => new GoToChatCommand(realmNavigator) }, { ChangeRealmChatCommand.REGEX, () => new ChangeRealmChatCommand(realmNavigator, bootstrapContainer.DecentralandUrlsSource) }, - { DebugPanelChatCommand.REGEX, () => new DebugPanelChatCommand(debugBuilder) }, + { DebugPanelChatCommand.REGEX, () => new DebugPanelChatCommand(debugBuilder, connectionStatusPanelPlugin) }, { ShowEntityInfoChatCommand.REGEX, () => new ShowEntityInfoChatCommand(worldInfoHub) }, { ClearChatCommand.REGEX, () => new ClearChatCommand(chatHistory) }, { ReloadSceneChatCommand.REGEX, () => new ReloadSceneChatCommand(container.reloadSceneController) }, @@ -438,8 +441,6 @@ IMultiPool MultiPoolFactory() => AudioMixer generalAudioMixer = (await assetsProvisioner.ProvideMainAssetAsync(dynamicSettings.GeneralAudioMixer, ct)).Value; var audioMixerVolumesController = new AudioMixerVolumesController(generalAudioMixer); - var currentSceneInfo = new CurrentSceneInfo(); - container.multiplayerMovementMessageBus = new MultiplayerMovementMessageBus(container.MessagePipesHub, entityParticipantTable, globalWorld); var badgesAPIClient = new BadgesAPIClient(staticContainer.WebRequestsContainer.WebRequestController, bootstrapContainer.DecentralandUrlsSource); @@ -510,7 +511,7 @@ IMultiPool MultiPoolFactory() => profileCache, sidebarBus, chatEntryConfiguration, globalWorld, playerEntity), new ErrorPopupPlugin(container.MvcManager, assetsProvisioner), - new ConnectionStatusPanelPlugin(container.UserInAppInAppInitializationFlow, container.MvcManager, mainUIView, roomsStatus, currentSceneInfo, container.reloadSceneController, globalWorld, playerEntity), + connectionStatusPanelPlugin, new MinimapPlugin(container.MvcManager, container.MapRendererContainer, placesAPIService, staticContainer.RealmData, container.ChatMessagesBus, realmNavigator, staticContainer.ScenesCache, mainUIView, mapPathEventBus), new ChatPlugin(assetsProvisioner, container.MvcManager, container.ChatMessagesBus, chatHistory, entityParticipantTable, nametagsData, dclInput, unityEventSystem, mainUIView, staticContainer.InputBlock, globalWorld, playerEntity), new ExplorePanelPlugin( From 50fbf7da3234208c8afd877e7115fadf58d4112b Mon Sep 17 00:00:00 2001 From: Juan Ignacio Molteni Date: Mon, 21 Oct 2024 11:37:29 -0300 Subject: [PATCH 13/16] fix: weekly release page (#2513) Signed-off-by: Juan Ignacio Molteni --- .github/workflows/build-release-main-page.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-release-main-page.yml b/.github/workflows/build-release-main-page.yml index 4284547d42..3854fb3a38 100644 --- a/.github/workflows/build-release-main-page.yml +++ b/.github/workflows/build-release-main-page.yml @@ -21,6 +21,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + ref: 'main' - name: Get version id: get_version From dde6404a9e4544cde056e2dcf8d4f5a2a2a7a970 Mon Sep 17 00:00:00 2001 From: Alejandro Alvarez Melucci <163010988+AlejandroAlvarezMelucciDCL@users.noreply.github.com> Date: Mon, 21 Oct 2024 13:18:17 -0300 Subject: [PATCH 14/16] chore: move alpha_texture from PBRMaterial to UnlitMaterial (#2482) Implemented support for alpha texture on SDK unlit material component --- .../DecentralandProtocol/Material.gen.cs | 117 +++++++++++++----- .../Materials/Components/MaterialData.cs | 4 +- .../MaterialReference/BasicShapeMaterial.mat | 11 +- .../Systems/CreateBasicMaterialSystem.cs | 63 +++++++++- .../Systems/CreatePBRMaterialSystem.cs | 9 +- .../Systems/StartMaterialsLoadingSystem.cs | 10 +- .../Tests/CreateBasicMaterialSystemShould.cs | 3 +- .../LoadMaterialFromCacheSystemShould.cs | 14 ++- scripts/package-lock.json | 14 +-- scripts/package.json | 2 +- 10 files changed, 185 insertions(+), 62 deletions(-) diff --git a/Explorer/Assets/Protocol/DecentralandProtocol/Material.gen.cs b/Explorer/Assets/Protocol/DecentralandProtocol/Material.gen.cs index 5a730df92f..90c927e6e0 100644 --- a/Explorer/Assets/Protocol/DecentralandProtocol/Material.gen.cs +++ b/Explorer/Assets/Protocol/DecentralandProtocol/Material.gen.cs @@ -27,46 +27,48 @@ static MaterialReflection() { "CipkZWNlbnRyYWxhbmQvc2RrL2NvbXBvbmVudHMvbWF0ZXJpYWwucHJvdG8S", "G2RlY2VudHJhbGFuZC5zZGsuY29tcG9uZW50cxogZGVjZW50cmFsYW5kL2Nv", "bW1vbi9jb2xvcnMucHJvdG8aIWRlY2VudHJhbGFuZC9jb21tb24vdGV4dHVy", - "ZS5wcm90byKGCwoKUEJNYXRlcmlhbBJGCgV1bmxpdBgBIAEoCzI1LmRlY2Vu", + "ZS5wcm90byLXCwoKUEJNYXRlcmlhbBJGCgV1bmxpdBgBIAEoCzI1LmRlY2Vu", "dHJhbGFuZC5zZGsuY29tcG9uZW50cy5QQk1hdGVyaWFsLlVubGl0TWF0ZXJp", "YWxIABJCCgNwYnIYAiABKAsyMy5kZWNlbnRyYWxhbmQuc2RrLmNvbXBvbmVu", - "dHMuUEJNYXRlcmlhbC5QYnJNYXRlcmlhbEgAGvMBCg1VbmxpdE1hdGVyaWFs", + "dHMuUEJNYXRlcmlhbC5QYnJNYXRlcmlhbEgAGsQCCg1VbmxpdE1hdGVyaWFs", "EjcKB3RleHR1cmUYASABKAsyIS5kZWNlbnRyYWxhbmQuY29tbW9uLlRleHR1", "cmVVbmlvbkgAiAEBEhcKCmFscGhhX3Rlc3QYAiABKAJIAYgBARIZCgxjYXN0", "X3NoYWRvd3MYAyABKAhIAogBARI3Cg1kaWZmdXNlX2NvbG9yGAQgASgLMhsu", - "ZGVjZW50cmFsYW5kLmNvbW1vbi5Db2xvcjRIA4gBAUIKCghfdGV4dHVyZUIN", - "CgtfYWxwaGFfdGVzdEIPCg1fY2FzdF9zaGFkb3dzQhAKDl9kaWZmdXNlX2Nv", - "bG9yGukHCgtQYnJNYXRlcmlhbBI3Cgd0ZXh0dXJlGAEgASgLMiEuZGVjZW50", - "cmFsYW5kLmNvbW1vbi5UZXh0dXJlVW5pb25IAIgBARIXCgphbHBoYV90ZXN0", - "GAIgASgCSAGIAQESGQoMY2FzdF9zaGFkb3dzGAMgASgISAKIAQESPQoNYWxw", - "aGFfdGV4dHVyZRgEIAEoCzIhLmRlY2VudHJhbGFuZC5jb21tb24uVGV4dHVy", - "ZVVuaW9uSAOIAQESQAoQZW1pc3NpdmVfdGV4dHVyZRgFIAEoCzIhLmRlY2Vu", - "dHJhbGFuZC5jb21tb24uVGV4dHVyZVVuaW9uSASIAQESPAoMYnVtcF90ZXh0", - "dXJlGAYgASgLMiEuZGVjZW50cmFsYW5kLmNvbW1vbi5UZXh0dXJlVW5pb25I", - "BYgBARI2CgxhbGJlZG9fY29sb3IYByABKAsyGy5kZWNlbnRyYWxhbmQuY29t", - "bW9uLkNvbG9yNEgGiAEBEjgKDmVtaXNzaXZlX2NvbG9yGAggASgLMhsuZGVj", - "ZW50cmFsYW5kLmNvbW1vbi5Db2xvcjNIB4gBARI8ChJyZWZsZWN0aXZpdHlf", - "Y29sb3IYCSABKAsyGy5kZWNlbnRyYWxhbmQuY29tbW9uLkNvbG9yM0gIiAEB", - "ElUKEXRyYW5zcGFyZW5jeV9tb2RlGAogASgOMjUuZGVjZW50cmFsYW5kLnNk", - "ay5jb21wb25lbnRzLk1hdGVyaWFsVHJhbnNwYXJlbmN5TW9kZUgJiAEBEhUK", - "CG1ldGFsbGljGAsgASgCSAqIAQESFgoJcm91Z2huZXNzGAwgASgCSAuIAQES", - "HwoSc3BlY3VsYXJfaW50ZW5zaXR5GA4gASgCSAyIAQESHwoSZW1pc3NpdmVf", - "aW50ZW5zaXR5GA8gASgCSA2IAQESHQoQZGlyZWN0X2ludGVuc2l0eRgQIAEo", - "AkgOiAEBQgoKCF90ZXh0dXJlQg0KC19hbHBoYV90ZXN0Qg8KDV9jYXN0X3No", - "YWRvd3NCEAoOX2FscGhhX3RleHR1cmVCEwoRX2VtaXNzaXZlX3RleHR1cmVC", - "DwoNX2J1bXBfdGV4dHVyZUIPCg1fYWxiZWRvX2NvbG9yQhEKD19lbWlzc2l2", - "ZV9jb2xvckIVChNfcmVmbGVjdGl2aXR5X2NvbG9yQhQKEl90cmFuc3BhcmVu", - "Y3lfbW9kZUILCglfbWV0YWxsaWNCDAoKX3JvdWdobmVzc0IVChNfc3BlY3Vs", - "YXJfaW50ZW5zaXR5QhUKE19lbWlzc2l2ZV9pbnRlbnNpdHlCEwoRX2RpcmVj", - "dF9pbnRlbnNpdHlKBAgNEA5CCgoIbWF0ZXJpYWwqhQEKGE1hdGVyaWFsVHJh", - "bnNwYXJlbmN5TW9kZRIOCgpNVE1fT1BBUVVFEAASEgoOTVRNX0FMUEhBX1RF", - "U1QQARITCg9NVE1fQUxQSEFfQkxFTkQQAhIiCh5NVE1fQUxQSEFfVEVTVF9B", - "TkRfQUxQSEFfQkxFTkQQAxIMCghNVE1fQVVUTxAEQhSqAhFEQ0wuRUNTQ29t", - "cG9uZW50c2IGcHJvdG8z")); + "ZGVjZW50cmFsYW5kLmNvbW1vbi5Db2xvcjRIA4gBARI9Cg1hbHBoYV90ZXh0", + "dXJlGAUgASgLMiEuZGVjZW50cmFsYW5kLmNvbW1vbi5UZXh0dXJlVW5pb25I", + "BIgBAUIKCghfdGV4dHVyZUINCgtfYWxwaGFfdGVzdEIPCg1fY2FzdF9zaGFk", + "b3dzQhAKDl9kaWZmdXNlX2NvbG9yQhAKDl9hbHBoYV90ZXh0dXJlGukHCgtQ", + "YnJNYXRlcmlhbBI3Cgd0ZXh0dXJlGAEgASgLMiEuZGVjZW50cmFsYW5kLmNv", + "bW1vbi5UZXh0dXJlVW5pb25IAIgBARIXCgphbHBoYV90ZXN0GAIgASgCSAGI", + "AQESGQoMY2FzdF9zaGFkb3dzGAMgASgISAKIAQESPQoNYWxwaGFfdGV4dHVy", + "ZRgEIAEoCzIhLmRlY2VudHJhbGFuZC5jb21tb24uVGV4dHVyZVVuaW9uSAOI", + "AQESQAoQZW1pc3NpdmVfdGV4dHVyZRgFIAEoCzIhLmRlY2VudHJhbGFuZC5j", + "b21tb24uVGV4dHVyZVVuaW9uSASIAQESPAoMYnVtcF90ZXh0dXJlGAYgASgL", + "MiEuZGVjZW50cmFsYW5kLmNvbW1vbi5UZXh0dXJlVW5pb25IBYgBARI2Cgxh", + "bGJlZG9fY29sb3IYByABKAsyGy5kZWNlbnRyYWxhbmQuY29tbW9uLkNvbG9y", + "NEgGiAEBEjgKDmVtaXNzaXZlX2NvbG9yGAggASgLMhsuZGVjZW50cmFsYW5k", + "LmNvbW1vbi5Db2xvcjNIB4gBARI8ChJyZWZsZWN0aXZpdHlfY29sb3IYCSAB", + "KAsyGy5kZWNlbnRyYWxhbmQuY29tbW9uLkNvbG9yM0gIiAEBElUKEXRyYW5z", + "cGFyZW5jeV9tb2RlGAogASgOMjUuZGVjZW50cmFsYW5kLnNkay5jb21wb25l", + "bnRzLk1hdGVyaWFsVHJhbnNwYXJlbmN5TW9kZUgJiAEBEhUKCG1ldGFsbGlj", + "GAsgASgCSAqIAQESFgoJcm91Z2huZXNzGAwgASgCSAuIAQESHwoSc3BlY3Vs", + "YXJfaW50ZW5zaXR5GA4gASgCSAyIAQESHwoSZW1pc3NpdmVfaW50ZW5zaXR5", + "GA8gASgCSA2IAQESHQoQZGlyZWN0X2ludGVuc2l0eRgQIAEoAkgOiAEBQgoK", + "CF90ZXh0dXJlQg0KC19hbHBoYV90ZXN0Qg8KDV9jYXN0X3NoYWRvd3NCEAoO", + "X2FscGhhX3RleHR1cmVCEwoRX2VtaXNzaXZlX3RleHR1cmVCDwoNX2J1bXBf", + "dGV4dHVyZUIPCg1fYWxiZWRvX2NvbG9yQhEKD19lbWlzc2l2ZV9jb2xvckIV", + "ChNfcmVmbGVjdGl2aXR5X2NvbG9yQhQKEl90cmFuc3BhcmVuY3lfbW9kZUIL", + "CglfbWV0YWxsaWNCDAoKX3JvdWdobmVzc0IVChNfc3BlY3VsYXJfaW50ZW5z", + "aXR5QhUKE19lbWlzc2l2ZV9pbnRlbnNpdHlCEwoRX2RpcmVjdF9pbnRlbnNp", + "dHlKBAgNEA5CCgoIbWF0ZXJpYWwqhQEKGE1hdGVyaWFsVHJhbnNwYXJlbmN5", + "TW9kZRIOCgpNVE1fT1BBUVVFEAASEgoOTVRNX0FMUEhBX1RFU1QQARITCg9N", + "VE1fQUxQSEFfQkxFTkQQAhIiCh5NVE1fQUxQSEFfVEVTVF9BTkRfQUxQSEFf", + "QkxFTkQQAxIMCghNVE1fQVVUTxAEQhSqAhFEQ0wuRUNTQ29tcG9uZW50c2IG", + "cHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Decentraland.Common.ColorsReflection.Descriptor, global::Decentraland.Common.TextureReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::DCL.ECSComponents.MaterialTransparencyMode), }, null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::DCL.ECSComponents.PBMaterial), global::DCL.ECSComponents.PBMaterial.Parser, new[]{ "Unlit", "Pbr" }, new[]{ "Material" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::DCL.ECSComponents.PBMaterial.Types.UnlitMaterial), global::DCL.ECSComponents.PBMaterial.Types.UnlitMaterial.Parser, new[]{ "Texture", "AlphaTest", "CastShadows", "DiffuseColor" }, new[]{ "Texture", "AlphaTest", "CastShadows", "DiffuseColor" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::DCL.ECSComponents.PBMaterial), global::DCL.ECSComponents.PBMaterial.Parser, new[]{ "Unlit", "Pbr" }, new[]{ "Material" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::DCL.ECSComponents.PBMaterial.Types.UnlitMaterial), global::DCL.ECSComponents.PBMaterial.Types.UnlitMaterial.Parser, new[]{ "Texture", "AlphaTest", "CastShadows", "DiffuseColor", "AlphaTexture" }, new[]{ "Texture", "AlphaTest", "CastShadows", "DiffuseColor", "AlphaTexture" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::DCL.ECSComponents.PBMaterial.Types.PbrMaterial), global::DCL.ECSComponents.PBMaterial.Types.PbrMaterial.Parser, new[]{ "Texture", "AlphaTest", "CastShadows", "AlphaTexture", "EmissiveTexture", "BumpTexture", "AlbedoColor", "EmissiveColor", "ReflectivityColor", "TransparencyMode", "Metallic", "Roughness", "SpecularIntensity", "EmissiveIntensity", "DirectIntensity" }, new[]{ "Texture", "AlphaTest", "CastShadows", "AlphaTexture", "EmissiveTexture", "BumpTexture", "AlbedoColor", "EmissiveColor", "ReflectivityColor", "TransparencyMode", "Metallic", "Roughness", "SpecularIntensity", "EmissiveIntensity", "DirectIntensity" }, null, null, null)}) })); } @@ -413,6 +415,7 @@ public UnlitMaterial(UnlitMaterial other) : this() { alphaTest_ = other.alphaTest_; castShadows_ = other.castShadows_; diffuseColor_ = other.diffuseColor_ != null ? other.diffuseColor_.Clone() : null; + alphaTexture_ = other.alphaTexture_ != null ? other.alphaTexture_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -508,6 +511,21 @@ public void ClearCastShadows() { } } + /// Field number for the "alpha_texture" field. + public const int AlphaTextureFieldNumber = 5; + private global::Decentraland.Common.TextureUnion alphaTexture_; + /// + /// default = null + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Decentraland.Common.TextureUnion AlphaTexture { + get { return alphaTexture_; } + set { + alphaTexture_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] public override bool Equals(object other) { @@ -527,6 +545,7 @@ public bool Equals(UnlitMaterial other) { if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(AlphaTest, other.AlphaTest)) return false; if (CastShadows != other.CastShadows) return false; if (!object.Equals(DiffuseColor, other.DiffuseColor)) return false; + if (!object.Equals(AlphaTexture, other.AlphaTexture)) return false; return Equals(_unknownFields, other._unknownFields); } @@ -538,6 +557,7 @@ public override int GetHashCode() { if (HasAlphaTest) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(AlphaTest); if (HasCastShadows) hash ^= CastShadows.GetHashCode(); if (diffuseColor_ != null) hash ^= DiffuseColor.GetHashCode(); + if (alphaTexture_ != null) hash ^= AlphaTexture.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -572,6 +592,10 @@ public void WriteTo(pb::CodedOutputStream output) { output.WriteRawTag(34); output.WriteMessage(DiffuseColor); } + if (alphaTexture_ != null) { + output.WriteRawTag(42); + output.WriteMessage(AlphaTexture); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -598,6 +622,10 @@ public void WriteTo(pb::CodedOutputStream output) { output.WriteRawTag(34); output.WriteMessage(DiffuseColor); } + if (alphaTexture_ != null) { + output.WriteRawTag(42); + output.WriteMessage(AlphaTexture); + } if (_unknownFields != null) { _unknownFields.WriteTo(ref output); } @@ -620,6 +648,9 @@ public int CalculateSize() { if (diffuseColor_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(DiffuseColor); } + if (alphaTexture_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(AlphaTexture); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -650,6 +681,12 @@ public void MergeFrom(UnlitMaterial other) { } DiffuseColor.MergeFrom(other.DiffuseColor); } + if (other.alphaTexture_ != null) { + if (alphaTexture_ == null) { + AlphaTexture = new global::Decentraland.Common.TextureUnion(); + } + AlphaTexture.MergeFrom(other.AlphaTexture); + } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -687,6 +724,13 @@ public void MergeFrom(pb::CodedInputStream input) { input.ReadMessage(DiffuseColor); break; } + case 42: { + if (alphaTexture_ == null) { + AlphaTexture = new global::Decentraland.Common.TextureUnion(); + } + input.ReadMessage(AlphaTexture); + break; + } } } #endif @@ -724,6 +768,13 @@ public void MergeFrom(pb::CodedInputStream input) { input.ReadMessage(DiffuseColor); break; } + case 42: { + if (alphaTexture_ == null) { + AlphaTexture = new global::Decentraland.Common.TextureUnion(); + } + input.ReadMessage(AlphaTexture); + break; + } } } } @@ -866,7 +917,7 @@ public void ClearCastShadows() { public const int AlphaTextureFieldNumber = 4; private global::Decentraland.Common.TextureUnion alphaTexture_; /// - /// default = null + /// @deprecated Alpha textures are no longer supported on PBRMaterial and UnlitMaterial.alphaTexture should be used instead. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Components/MaterialData.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Components/MaterialData.cs index 3e87210e37..8b8e1e5a42 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Components/MaterialData.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Components/MaterialData.cs @@ -82,11 +82,11 @@ internal MaterialData(bool isPbrMaterial, TextureComponent? albedoTexture, Textu DirectIntensity = directIntensity; } - internal static MaterialData CreateBasicMaterial(TextureComponent? albedoTexture, float alphaTest, Color diffuseColor, bool castShadows) + internal static MaterialData CreateBasicMaterial(TextureComponent? albedoTexture, TextureComponent? alphaTexture, float alphaTest, Color diffuseColor, bool castShadows) { Color defaultColor = Color.white; - return new MaterialData(false, albedoTexture, null, null, null, + return new MaterialData(false, albedoTexture, alphaTexture, null, null, alphaTest, castShadows, defaultColor, diffuseColor, defaultColor, defaultColor, MaterialTransparencyMode.Auto, 0, 0, 0, 0, 0); } diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/MaterialReference/BasicShapeMaterial.mat b/Explorer/Assets/Scripts/ECS/Unity/Materials/MaterialReference/BasicShapeMaterial.mat index 4bff5200ae..24d5f542d6 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Materials/MaterialReference/BasicShapeMaterial.mat +++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/MaterialReference/BasicShapeMaterial.mat @@ -8,7 +8,7 @@ Material: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: BasicShapeMaterial - m_Shader: {fileID: 4800000, guid: 56a9743f8d94f684190dc11bb521fb78, type: 3} + m_Shader: {fileID: 4800000, guid: d77b7a7570974707a3c094386b19c6bc, type: 3} m_Parent: {fileID: 0} m_ModifiedSerializedProperties: 0 m_ValidKeywords: [] @@ -17,12 +17,17 @@ Material: m_EnableInstancingVariants: 0 m_DoubleSidedGI: 0 m_CustomRenderQueue: -1 - stringTagMap: {} + stringTagMap: + RenderType: Opaque disabledShaderPasses: [] m_LockedProperties: m_SavedProperties: serializedVersion: 3 m_TexEnvs: + - _AlphaTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} - _BaseMap: m_Texture: {fileID: 0} m_Scale: {x: 1, y: 1} @@ -61,6 +66,7 @@ Material: - _AlphaToMask: 0 - _Blend: 0 - _BlendModePreserveSpecular: 1 + - _BlendOp: 0 - _BumpScale: 1 - _Cull: 2 - _CullYPlane: 0 @@ -93,6 +99,7 @@ Material: - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _PlaneClipping: {r: -2.1474836e+9, g: 2.1474836e+9, b: -2.1474836e+9, a: 2.1474836e+9} - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + - _VerticalClipping: {r: -2.1474836e+9, g: 2.1474836e+9, b: 0, a: 0} m_BuildTextureStacks: [] --- !u!114 &5218572137218344763 MonoBehaviour: diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CreateBasicMaterialSystem.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CreateBasicMaterialSystem.cs index d6c941be7e..074763994d 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CreateBasicMaterialSystem.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CreateBasicMaterialSystem.cs @@ -6,6 +6,7 @@ using ECS.StreamableLoading.Common.Components; using ECS.StreamableLoading.Textures; using ECS.Unity.Materials.Components; +using ECS.Unity.Textures.Components; using UnityEngine; using UnityEngine.Pool; using UnityEngine.Rendering; @@ -48,7 +49,8 @@ private void ConstructMaterial(ref MaterialComponent materialComponent) // Check if all promises are finished // Promises are finished if: all of their entities are invalid, no promises at all, or the result component exists - if (TryGetTextureResult(ref materialComponent.AlbedoTexPromise, out StreamableLoadingResult albedoResult)) + if (TryGetTextureResult(ref materialComponent.AlbedoTexPromise, out StreamableLoadingResult albedoResult) && + TryGetTextureResult(ref materialComponent.AlphaTexPromise, out StreamableLoadingResult alphaResult)) { materialComponent.Status = StreamableLoading.LifeCycle.LoadingFinished; @@ -56,12 +58,71 @@ private void ConstructMaterial(ref MaterialComponent materialComponent) SetUp(materialComponent.Result, materialComponent.Data.AlphaTest, materialComponent.Data.DiffuseColor); + SetUpTransparency(materialComponent.Result, materialComponent.Data.TransparencyMode, in materialComponent.Data.Textures.AlphaTexture, materialComponent.Data.AlbedoColor, materialComponent.Data.AlphaTest); + TrySetTexture(materialComponent.Result, ref albedoResult, ShaderUtils.BaseMap, in materialComponent.Data.Textures.AlbedoTexture); + TrySetTexture(materialComponent.Result, ref alphaResult, ShaderUtils.AlphaTexture, in materialComponent.Data.Textures.AlphaTexture); DestroyEntityReference(ref materialComponent.AlbedoTexPromise); } } + public static void SetUpTransparency(Material material, MaterialTransparencyMode transparencyMode, + in TextureComponent? alphaTexture, Color albedoColor, float alphaTest) + { + transparencyMode.ResolveAutoMode(alphaTexture, albedoColor); + + // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault + switch (transparencyMode) + { + case MaterialTransparencyMode.Opaque: + material.DisableKeyword("_ALPHATEST_ON"); // Cut Out Transparency + material.DisableKeyword("_ALPHABLEND_ON"); // Fade Transparency + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); // Transparent + + material.renderQueue = (int)RenderQueue.Geometry; + material.SetFloat(ShaderUtils.AlphaClip, 0); + break; + case MaterialTransparencyMode.AlphaTest: // ALPHATEST + material.EnableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); // Fade Transparency + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); // Transparent + + material.SetInt(ShaderUtils.SrcBlend, (int)BlendMode.One); + material.SetInt(ShaderUtils.DstBlend, (int)BlendMode.Zero); + material.SetInt(ShaderUtils.ZWrite, 1); + material.SetFloat(ShaderUtils.AlphaClip, 1); + material.SetFloat(ShaderUtils.Cutoff, alphaTest); + material.SetInt(ShaderUtils.Surface, 0); + material.renderQueue = (int)RenderQueue.AlphaTest; + break; + case MaterialTransparencyMode.AlphaBlend: // ALPHABLEND + material.DisableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); // Transparent + material.EnableKeyword("_ALPHABLEND_ON"); + + material.SetInt(ShaderUtils.SrcBlend, (int)BlendMode.SrcAlpha); + material.SetInt(ShaderUtils.DstBlend, (int)BlendMode.OneMinusSrcAlpha); + material.SetInt(ShaderUtils.ZWrite, 0); + material.SetFloat(ShaderUtils.AlphaClip, 0); + material.renderQueue = (int)RenderQueue.Transparent; + material.SetInt(ShaderUtils.Surface, 1); + break; + case MaterialTransparencyMode.AlphaTestAndAlphaBlend: + material.DisableKeyword("_ALPHATEST_ON"); // Cut Out Transparency + material.DisableKeyword("_ALPHABLEND_ON"); // Fade Transparency + material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); // Transparent + + material.SetInt(ShaderUtils.SrcBlend, (int)BlendMode.One); + material.SetInt(ShaderUtils.DstBlend, (int)BlendMode.OneMinusSrcAlpha); + material.SetInt(ShaderUtils.ZWrite, 0); + material.SetFloat(ShaderUtils.AlphaClip, 1); + material.renderQueue = (int)RenderQueue.Transparent; + material.SetInt(ShaderUtils.Surface, 1); + break; + } + } + public static void SetUp(Material material, float alphaTest, Color diffuseColor) { material.EnableKeyword("_ALPHATEST_ON"); diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CreatePBRMaterialSystem.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CreatePBRMaterialSystem.cs index 21e74a3ecc..d92035a6d4 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CreatePBRMaterialSystem.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/CreatePBRMaterialSystem.cs @@ -55,7 +55,6 @@ private void ConstructMaterial(Entity entity, ref MaterialComponent materialComp if (TryGetTextureResult(ref materialComponent.AlbedoTexPromise, out StreamableLoadingResult albedoResult) && TryGetTextureResult(ref materialComponent.EmissiveTexPromise, out StreamableLoadingResult emissiveResult) - && TryGetTextureResult(ref materialComponent.AlphaTexPromise, out StreamableLoadingResult alphaResult) && TryGetTextureResult(ref materialComponent.BumpTexPromise, out StreamableLoadingResult bumpResult)) { materialComponent.Status = StreamableLoading.LifeCycle.LoadingFinished; @@ -64,11 +63,10 @@ private void ConstructMaterial(Entity entity, ref MaterialComponent materialComp SetUpColors(materialComponent.Result, materialComponent.Data.AlbedoColor, materialComponent.Data.EmissiveColor, materialComponent.Data.ReflectivityColor, materialComponent.Data.EmissiveIntensity); SetUpProps(materialComponent.Result, materialComponent.Data.Metallic, materialComponent.Data.Roughness, materialComponent.Data.SpecularIntensity, materialComponent.Data.DirectIntensity); - SetUpTransparency(materialComponent.Result, materialComponent.Data.TransparencyMode, in materialComponent.Data.Textures.AlphaTexture, materialComponent.Data.AlbedoColor, materialComponent.Data.AlphaTest); + SetUpTransparency(materialComponent.Result, materialComponent.Data.TransparencyMode, materialComponent.Data.AlbedoColor, materialComponent.Data.AlphaTest); TrySetTexture(materialComponent.Result, ref albedoResult, ShaderUtils.BaseMap, in materialComponent.Data.Textures.AlbedoTexture); TrySetTexture(materialComponent.Result, ref emissiveResult, ShaderUtils.EmissionMap, in materialComponent.Data.Textures.EmissiveTexture); - TrySetTexture(materialComponent.Result, ref alphaResult, ShaderUtils.AlphaTexture, in materialComponent.Data.Textures.AlphaTexture); TrySetTexture(materialComponent.Result, ref bumpResult, ShaderUtils.BumpMap, in materialComponent.Data.Textures.BumpTexture); DestroyEntityReferencesForPromises(ref materialComponent); @@ -98,10 +96,9 @@ public static void SetUpProps(Material material, float metallic, float roughness material.SetFloat(ShaderUtils.SpecularHighlights, specularIntensity * directIntensity); } - public static void SetUpTransparency(Material material, MaterialTransparencyMode transparencyMode, - in TextureComponent? alphaTexture, Color albedoColor, float alphaTest) + public static void SetUpTransparency(Material material, MaterialTransparencyMode transparencyMode, Color albedoColor, float alphaTest) { - transparencyMode.ResolveAutoMode(alphaTexture, albedoColor); + transparencyMode.ResolveAutoMode(null, albedoColor); // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault switch (transparencyMode) diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs index d7fa63423e..3cefb86d95 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Systems/StartMaterialsLoadingSystem.cs @@ -115,7 +115,7 @@ private void CreateMaterialComponent(Entity entity, ref PBMaterial material, ref private MaterialData CreateMaterialData(in PBMaterial material) { if (material.Unlit != null) - return CreateBasicMaterialData(material, albedoTexture: material.Unlit.Texture.CreateTextureComponent(sceneData)); + return CreateBasicMaterialData(material, albedoTexture: material.Unlit.Texture.CreateTextureComponent(sceneData), material.Unlit.AlphaTexture.CreateTextureComponent(sceneData)); TextureComponent? albedoTexture = material.Pbr.Texture.CreateTextureComponent(sceneData); TextureComponent? alphaTexture = material.Pbr.AlphaTexture.CreateTextureComponent(sceneData); @@ -160,10 +160,14 @@ private void CreateGetTexturePromises(ref MaterialComponent materialComponent, TryCreateGetTexturePromise(in materialComponent.Data.Textures.EmissiveTexture, oldTexturesData?.EmissiveTexture, ref materialComponent.EmissiveTexPromise, partitionComponent); TryCreateGetTexturePromise(in materialComponent.Data.Textures.BumpTexture, oldTexturesData?.BumpTexture, ref materialComponent.BumpTexPromise, partitionComponent); } + else + { + TryCreateGetTexturePromise(in materialComponent.Data.Textures.AlphaTexture, oldTexturesData?.AlphaTexture, ref materialComponent.AlphaTexPromise, partitionComponent); + } } - private static MaterialData CreateBasicMaterialData(in PBMaterial pbMaterial, in TextureComponent? albedoTexture) => - MaterialData.CreateBasicMaterial(albedoTexture, pbMaterial.GetAlphaTest(), pbMaterial.GetDiffuseColor(), pbMaterial.GetCastShadows()); + private static MaterialData CreateBasicMaterialData(in PBMaterial pbMaterial, in TextureComponent? albedoTexture, in TextureComponent? alphaTexture) => + MaterialData.CreateBasicMaterial(albedoTexture, alphaTexture, pbMaterial.GetAlphaTest(), pbMaterial.GetDiffuseColor(), pbMaterial.GetCastShadows()); private bool TryCreateGetTexturePromise(in TextureComponent? textureComponent, in TextureComponent? oldTextureComponent, diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreateBasicMaterialSystemShould.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreateBasicMaterialSystemShould.cs index a2822082bd..74d398c1e3 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreateBasicMaterialSystemShould.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/CreateBasicMaterialSystemShould.cs @@ -81,7 +81,8 @@ private void CreateAndFinalizeTexturePromise(ref AssetPromise new (MaterialData.CreateBasicMaterial( - new TextureComponent("albedo", string.Empty, TextureWrapMode.Mirror, FilterMode.Point), + new TextureComponent("albedo",string.Empty, TextureWrapMode.Mirror, FilterMode.Point), + null, 0, Color.red, false)); diff --git a/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/LoadMaterialFromCacheSystemShould.cs b/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/LoadMaterialFromCacheSystemShould.cs index 5f755c50d4..2bc5eb45b6 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/LoadMaterialFromCacheSystemShould.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Materials/Tests/LoadMaterialFromCacheSystemShould.cs @@ -24,7 +24,8 @@ public void SetUp() public void FinishLoadingIfPresentInCache() { var materialComponent = new MaterialComponent(MaterialData.CreateBasicMaterial( - new TextureComponent("test-texture", "file-hash", TextureWrapMode.Mirror, FilterMode.Bilinear), + new TextureComponent("test-texture","file-hash", TextureWrapMode.Mirror, FilterMode.Bilinear), + null, 0.5f, Color.red, true)); @@ -54,7 +55,8 @@ public void FinishLoadingIfPresentInCache() public void DoNothingIfLoadingStarted([Values(StreamableLoading.LifeCycle.LoadingInProgress, StreamableLoading.LifeCycle.LoadingFinished, StreamableLoading.LifeCycle.Applied)] StreamableLoading.LifeCycle status) { var materialComponent = new MaterialComponent(MaterialData.CreateBasicMaterial( - new TextureComponent("test-texture", "file-hash", TextureWrapMode.Mirror, FilterMode.Bilinear), + new TextureComponent("test-texture","file-hash", TextureWrapMode.Mirror, FilterMode.Bilinear), + null, 0.5f, Color.red, true)); @@ -84,10 +86,10 @@ public void DoNothingIfLoadingStarted([Values(StreamableLoading.LifeCycle.Loadin public void NotFinishLoadingIfNotPresentInCache() { var materialComponent = new MaterialComponent(MaterialData.CreatePBRMaterial( - new TextureComponent("1", "file-hash", TextureWrapMode.Mirror, FilterMode.Bilinear), - new TextureComponent("2", "file-hash", TextureWrapMode.MirrorOnce, FilterMode.Trilinear), - new TextureComponent("3", "file-hash", TextureWrapMode.Repeat, FilterMode.Point), - new TextureComponent("4", "file-hash", TextureWrapMode.Clamp, FilterMode.Point), + new TextureComponent("1","file-hash", TextureWrapMode.Mirror, FilterMode.Bilinear), + new TextureComponent("2","file-hash", TextureWrapMode.MirrorOnce, FilterMode.Trilinear), + new TextureComponent("3","file-hash", TextureWrapMode.Repeat, FilterMode.Point), + new TextureComponent("4","file-hash", TextureWrapMode.Clamp, FilterMode.Point), 0.5f, true, Color.red, diff --git a/scripts/package-lock.json b/scripts/package-lock.json index a99f36086d..09ba2bf708 100644 --- a/scripts/package-lock.json +++ b/scripts/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "@dcl/protocol": "^1.0.0-10955038136.commit-7fe9554", + "@dcl/protocol": "^1.0.0-11406954347.commit-ba19c4f", "@protobuf-ts/protoc": "^2.8.2", "@types/fs-extra": "^11.0.1", "@types/glob": "^8.0.1", @@ -36,9 +36,9 @@ } }, "node_modules/@dcl/protocol": { - "version": "1.0.0-10955038136.commit-7fe9554", - "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-10955038136.commit-7fe9554.tgz", - "integrity": "sha512-0BcRTJxFhxpX1k4oN8ErL+HiJYDmd98aDh6Kti54zoCph3SlJqkq0r1KshHAeMaXLSKNRtljjgkf4KkB8MriKA==", + "version": "1.0.0-11406954347.commit-ba19c4f", + "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-11406954347.commit-ba19c4f.tgz", + "integrity": "sha512-oMoq5IKAe1gout5SbP2w3Jq3Im+tbUiREW70BC+aVwwOly0YDtTWTZG9FyjeF36RDhyCg7z6jwtHL/rbWp0skw==", "dependencies": { "@dcl/ts-proto": "1.154.0" } @@ -569,9 +569,9 @@ } }, "@dcl/protocol": { - "version": "1.0.0-10955038136.commit-7fe9554", - "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-10955038136.commit-7fe9554.tgz", - "integrity": "sha512-0BcRTJxFhxpX1k4oN8ErL+HiJYDmd98aDh6Kti54zoCph3SlJqkq0r1KshHAeMaXLSKNRtljjgkf4KkB8MriKA==", + "version": "1.0.0-11406954347.commit-ba19c4f", + "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-11406954347.commit-ba19c4f.tgz", + "integrity": "sha512-oMoq5IKAe1gout5SbP2w3Jq3Im+tbUiREW70BC+aVwwOly0YDtTWTZG9FyjeF36RDhyCg7z6jwtHL/rbWp0skw==", "requires": { "@dcl/ts-proto": "1.154.0" } diff --git a/scripts/package.json b/scripts/package.json index c4c5cb535f..5f97affe78 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -16,7 +16,7 @@ "typescript": "^4.2.3" }, "dependencies": { - "@dcl/protocol": "^1.0.0-10955038136.commit-7fe9554", + "@dcl/protocol": "^1.0.0-11406954347.commit-ba19c4f", "@protobuf-ts/protoc": "^2.8.2", "@types/fs-extra": "^11.0.1", "@types/glob": "^8.0.1", From 51cb4602a32ac3b7ef29e87495e01aa7edd50152 Mon Sep 17 00:00:00 2001 From: Alex Villalba Date: Mon, 21 Oct 2024 18:49:01 +0200 Subject: [PATCH 15/16] fix: Textures in the panels at Genesis plaza main spawn area are not appearing (#2514) Those panels use textures downloaded from arbitrary URLs and not from the content servers, which means they will not have a file hash available. File hashes were being used as "key" in the texture cache (GetTextureIntention are the actual key, but they compare using a hash partially formed by the file hash). Now either the hash or the source URL is used to form the key/hash, depending on whether the file hash is available. --- .../ECS/StreamableLoading/Textures/GetTextureIntention.cs | 7 +++++-- .../ECS/Unity/Textures/Components/TextureComponent.cs | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/GetTextureIntention.cs b/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/GetTextureIntention.cs index bbfeff552d..a67872c758 100644 --- a/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/GetTextureIntention.cs +++ b/Explorer/Assets/Scripts/ECS/StreamableLoading/Textures/GetTextureIntention.cs @@ -22,6 +22,9 @@ public struct GetTextureIntention : ILoadingIntention, IEquatable CommonArguments.CancellationTokenSource; + // Note: Depending on the origin of the texture, it may not have a file hash, so the source URL is used in equality comparisons + private string cacheKey => string.IsNullOrEmpty(FileHash) ? CommonArguments.URL.Value : FileHash; + public GetTextureIntention(string url, string fileHash, TextureWrapMode wrapMode, FilterMode filterMode, bool isReadable = false, int attemptsCount = StreamableLoadingDefaults.ATTEMPTS_COUNT) { CommonArguments = new CommonLoadingArguments(url, attempts: attemptsCount); @@ -45,7 +48,7 @@ public GetTextureIntention(CRDTEntity videoPlayerEntity) } public bool Equals(GetTextureIntention other) => - FileHash == other.FileHash && + cacheKey == other.cacheKey && IsReadable == other.IsReadable && WrapMode == other.WrapMode && FilterMode == other.FilterMode && @@ -56,7 +59,7 @@ public override bool Equals(object obj) => obj is GetTextureIntention other && Equals(other); public override int GetHashCode() => - HashCode.Combine(IsReadable, (int)WrapMode, (int)FilterMode, FileHash, IsVideoTexture, VideoPlayerEntity); + HashCode.Combine(IsReadable, (int)WrapMode, (int)FilterMode, cacheKey, IsVideoTexture, VideoPlayerEntity); public override string ToString() => $"Get Texture: {(IsVideoTexture ? $"Video {VideoPlayerEntity}" : CommonArguments.URL)}"; diff --git a/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/TextureComponent.cs b/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/TextureComponent.cs index f50ba53857..594aff2595 100644 --- a/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/TextureComponent.cs +++ b/Explorer/Assets/Scripts/ECS/Unity/Textures/Components/TextureComponent.cs @@ -12,6 +12,8 @@ namespace ECS.Unity.Textures.Components public readonly int VideoPlayerEntity; public readonly string FileHash; + private string cacheKey => string.IsNullOrEmpty(FileHash) ? Src : FileHash; + public TextureComponent(string src, string fileHash, TextureWrapMode wrapMode = TextureWrapMode.Clamp, FilterMode filterMode = FilterMode.Bilinear, bool isVideoTexture = false, int videoPlayerEntity = 0) { Src = src; @@ -23,12 +25,12 @@ public TextureComponent(string src, string fileHash, TextureWrapMode wrapMode = } public bool Equals(TextureComponent other) => - FileHash == other.FileHash && WrapMode == other.WrapMode && FilterMode == other.FilterMode && IsVideoTexture == other.IsVideoTexture && VideoPlayerEntity == other.VideoPlayerEntity; + cacheKey == other.cacheKey && WrapMode == other.WrapMode && FilterMode == other.FilterMode && IsVideoTexture == other.IsVideoTexture && VideoPlayerEntity == other.VideoPlayerEntity; public override bool Equals(object obj) => obj is TextureComponent other && Equals(other); public override int GetHashCode() => - HashCode.Combine(FileHash, (int)WrapMode, (int)FilterMode, IsVideoTexture, VideoPlayerEntity); + HashCode.Combine(cacheKey, (int)WrapMode, (int)FilterMode, IsVideoTexture, VideoPlayerEntity); } } From ea1936fb26d3b6b33ee2f2affd5098212727936c Mon Sep 17 00:00:00 2001 From: Vitaly Popuzin <35366872+popuz@users.noreply.github.com> Date: Mon, 21 Oct 2024 20:22:43 +0300 Subject: [PATCH 16/16] bumped cache version for landscape (#2515) ## What does this PR change? see title ## How to test the changes? check if [#2190](https://github.com/decentraland/unity-explorer/issues/2190) is fixed --- Explorer/Assets/DCL/Landscape/TerrainGenerator.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Explorer/Assets/DCL/Landscape/TerrainGenerator.cs b/Explorer/Assets/DCL/Landscape/TerrainGenerator.cs index 2b5c95df55..68a0a14021 100644 --- a/Explorer/Assets/DCL/Landscape/TerrainGenerator.cs +++ b/Explorer/Assets/DCL/Landscape/TerrainGenerator.cs @@ -16,7 +16,6 @@ using Unity.Jobs; using Unity.Mathematics; using UnityEngine; -using UnityEngine.Profiling; using Utility; using JobHandle = Unity.Jobs.JobHandle; @@ -28,7 +27,7 @@ public class TerrainGenerator : IDisposable, IContainParcel private const float ROOT_VERTICAL_SHIFT = -0.01f; // fix for not clipping with scene (potential) floor // increment this number if we want to force the users to generate a new terrain cache - private const int CACHE_VERSION = 7; + private const int CACHE_VERSION = 8; private const float PROGRESS_COUNTER_EMPTY_PARCEL_DATA = 0.1f; private const float PROGRESS_COUNTER_TERRAIN_DATA = 0.3f;