diff --git a/browser-interface/packages/shared/types.ts b/browser-interface/packages/shared/types.ts index eac741375f..3499005b53 100644 --- a/browser-interface/packages/shared/types.ts +++ b/browser-interface/packages/shared/types.ts @@ -606,7 +606,8 @@ export type KernelConfigForRenderer = { kernelVersion: string rendererVersion: string avatarTextureAPIBaseUrl: string - urlParamsForWearablesDebug: boolean // temporal field until the whole the wearables catalog sagas flow is migrated to Unity + urlParamsForWearablesDebug: boolean, // temporal field until the whole the wearables catalog sagas flow is migrated to Unity + builderUrl: string } export type RealmsInfoForRenderer = { diff --git a/browser-interface/packages/unity-interface/kernelConfigForRenderer.ts b/browser-interface/packages/unity-interface/kernelConfigForRenderer.ts index 306faddfce..0d8ab82d43 100644 --- a/browser-interface/packages/unity-interface/kernelConfigForRenderer.ts +++ b/browser-interface/packages/unity-interface/kernelConfigForRenderer.ts @@ -8,7 +8,7 @@ import { PREVIEW, DEBUG, getTLD, - ETHEREUM_NETWORK + ETHEREUM_NETWORK, BUILDER_SERVER_URL } from 'config' import { nameValidCharacterRegex, nameValidRegex } from 'lib/decentraland/profiles/names' import { getWorld } from '@dcl/schemas' @@ -31,6 +31,7 @@ export function kernelConfigForRenderer(): KernelConfigForRenderer { PREVIEW || ((DEBUG || getTLD() !== 'org') && network !== ETHEREUM_NETWORK.MAINNET) const urlParamsForWearablesDebug = !!(WITH_FIXED_ITEMS || WITH_FIXED_COLLECTIONS || COLLECTIONS_OR_ITEMS_ALLOWED) + const builderUrl = BUILDER_SERVER_URL; return { ...globalState.meta.config.world, @@ -54,6 +55,7 @@ export function kernelConfigForRenderer(): KernelConfigForRenderer { /** @deprecated */ rendererVersion: explorerVersion, avatarTextureAPIBaseUrl: getAvatarTextureAPIBaseUrl(getSelectedNetwork(globalState)), - urlParamsForWearablesDebug: urlParamsForWearablesDebug + urlParamsForWearablesDebug: urlParamsForWearablesDebug, + builderUrl: builderUrl } } diff --git a/unity-renderer/Assets/DCLServices/EmotesCatalog/EmotesCatalogService/LambdasEmotesCatalogService.cs b/unity-renderer/Assets/DCLServices/EmotesCatalog/EmotesCatalogService/LambdasEmotesCatalogService.cs index 62ff93ab22..e39b1ea4be 100644 --- a/unity-renderer/Assets/DCLServices/EmotesCatalog/EmotesCatalogService/LambdasEmotesCatalogService.cs +++ b/unity-renderer/Assets/DCLServices/EmotesCatalog/EmotesCatalogService/LambdasEmotesCatalogService.cs @@ -37,6 +37,7 @@ private class EmoteCollectionResponse private readonly ICatalyst catalyst; private readonly ILambdasService lambdasService; private readonly DataStore dataStore; + private readonly KernelConfig kernelConfig; private readonly Dictionary ownedUrns = new (new Dictionary(), StringIgnoreCaseEqualityComparer.Default); private EmbeddedEmotesSO embeddedEmotesSo; @@ -49,13 +50,15 @@ public LambdasEmotesCatalogService(IEmotesRequestSource emoteSource, IAddressableResourceProvider addressableResourceProvider, ICatalyst catalyst, ILambdasService lambdasService, - DataStore dataStore) + DataStore dataStore, + KernelConfig kernelConfig) { this.emoteSource = emoteSource; this.addressableResourceProvider = addressableResourceProvider; this.catalyst = catalyst; this.lambdasService = lambdasService; this.dataStore = dataStore; + this.kernelConfig = kernelConfig; } private async UniTaskVoid InitializeAsyncEmbeddedEmotes() @@ -108,13 +111,14 @@ public bool TryGetLoadedEmote(string id, out WearableItem emote) public async UniTask RequestEmoteFromBuilderAsync(string emoteId, CancellationToken cancellationToken) { - const string TEMPLATE_URL = "https://builder-api.decentraland.org/v1/items/:emoteId/"; - string url = TEMPLATE_URL.Replace(":emoteId", emoteId); + string domain = GetBuilderDomainUrl(); + string url = $"{domain}/items/{emoteId}/"; + string templateUrl = $"{domain}/items/{emoteId}/"; try { (WearableItemResponseFromBuilder response, bool success) = await lambdasService.GetFromSpecificUrl( - TEMPLATE_URL, url, + templateUrl, url, isSigned: true, cancellationToken: cancellationToken); @@ -122,7 +126,7 @@ public async UniTask RequestEmoteFromBuilderAsync(string emoteId, throw new Exception($"The request of wearables from builder '{emoteId}' failed!"); WearableItem wearable = response.data.ToWearableItem( - "https://builder-api.decentraland.org/v1/storage/contents/", + $"{domain}/storage/contents/", assetBundlesUrl); if (!wearable.IsEmote()) return null; @@ -348,8 +352,7 @@ public async UniTask GetEmbeddedEmotes() public async UniTask> RequestEmoteCollectionInBuilderAsync(IEnumerable collectionIds, CancellationToken cancellationToken, List emoteBuffer = null) { - const string TEMPLATE_URL = "https://builder-api.decentraland.org/v1/collections/:collectionId/items/"; - + string domain = GetBuilderDomainUrl(); var emotes = emoteBuffer ?? new List(); var queryParams = new[] @@ -360,10 +363,11 @@ public async UniTask> RequestEmoteCollectionInBuilde foreach (string collectionId in collectionIds) { - string url = TEMPLATE_URL.Replace(":collectionId", collectionId); + var url = $"{domain}/collections/{collectionId}"; + var templateUrl = $"{domain}/collections/:collectionId/items/"; (WearableCollectionResponseFromBuilder response, bool success) = await lambdasService.GetFromSpecificUrl( - TEMPLATE_URL, url, + templateUrl, url, cancellationToken: cancellationToken, isSigned: true, urlEncodedParams: queryParams); @@ -373,7 +377,7 @@ public async UniTask> RequestEmoteCollectionInBuilde foreach (BuilderWearable bw in response.data.results) { - var wearable = bw.ToWearableItem("https://builder-api.decentraland.org/v1/storage/contents/", + var wearable = bw.ToWearableItem($"{domain}/storage/contents/", assetBundlesUrl); if (!wearable.IsEmote()) continue; emotes.Add(wearable); @@ -460,4 +464,13 @@ private void EmbedEmotes() emotesOnUse[embeddedEmote.id] = 5000; } } + + private string GetBuilderDomainUrl() + { + string domain = kernelConfig.Get().builderUrl; + + if (string.IsNullOrEmpty(domain)) + domain = "https://builder-api.decentraland.org/v1"; + return domain; + } } diff --git a/unity-renderer/Assets/DCLServices/EmotesCatalog/Tests/EmotesCatalogServiceShould.cs b/unity-renderer/Assets/DCLServices/EmotesCatalog/Tests/EmotesCatalogServiceShould.cs index 32a6efd221..5be21579a9 100644 --- a/unity-renderer/Assets/DCLServices/EmotesCatalog/Tests/EmotesCatalogServiceShould.cs +++ b/unity-renderer/Assets/DCLServices/EmotesCatalog/Tests/EmotesCatalogServiceShould.cs @@ -27,7 +27,7 @@ public void SetUp() IAddressableResourceProvider addressableResourceProvider = Substitute.For(); addressableResourceProvider.GetAddressable(Arg.Any(), Arg.Any()).Returns(GetEmbeddedEmotesSO()); catalog = new LambdasEmotesCatalogService(emotesRequestSource, addressableResourceProvider, Substitute.For(), - Substitute.For(), new DataStore()); + Substitute.For(), new DataStore(), KernelConfig.i); catalog.Initialize(); } @@ -342,7 +342,7 @@ public void EmbedEmotes() IAddressableResourceProvider addressableResourceProvider = Substitute.For(); addressableResourceProvider.GetAddressable(Arg.Any(), Arg.Any()).Returns(GetExampleEmbeddedEmotesSO()); catalog = new LambdasEmotesCatalogService(Substitute.For(), addressableResourceProvider, - Substitute.For(), Substitute.For(), new DataStore()); + Substitute.For(), Substitute.For(), new DataStore(), KernelConfig.i); catalog.Initialize(); Assert.AreEqual(catalog.emotes["id1"], embededEmotes[0]); diff --git a/unity-renderer/Assets/DCLServices/EmotesCatalog/Tests/EmotesCatalogTests.asmdef b/unity-renderer/Assets/DCLServices/EmotesCatalog/Tests/EmotesCatalogTests.asmdef index ccf7fa5b18..f08339a742 100644 --- a/unity-renderer/Assets/DCLServices/EmotesCatalog/Tests/EmotesCatalogTests.asmdef +++ b/unity-renderer/Assets/DCLServices/EmotesCatalog/Tests/EmotesCatalogTests.asmdef @@ -14,7 +14,8 @@ "GUID:68069f49d86442cd9618861b4d74b1aa", "GUID:dffbb581f2650ea4990781f603ac258a", "GUID:a4bf61c057a098f4ca05b539a6d8c0fe", - "GUID:28f74c468a54948bfa9f625c5d428f56" + "GUID:28f74c468a54948bfa9f625c5d428f56", + "GUID:c44f6fd10d3d94432a107d581e0096b5" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/unity-renderer/Assets/DCLServices/WearablesCatalogService/LambdasWearablesCatalogService.cs b/unity-renderer/Assets/DCLServices/WearablesCatalogService/LambdasWearablesCatalogService.cs index 68481810ab..62d8567f03 100644 --- a/unity-renderer/Assets/DCLServices/WearablesCatalogService/LambdasWearablesCatalogService.cs +++ b/unity-renderer/Assets/DCLServices/WearablesCatalogService/LambdasWearablesCatalogService.cs @@ -53,6 +53,7 @@ public WearableCollectionResponse(EntityDto[] entities) private readonly List pendingWearablesToRequest = new (); private readonly BaseVariable featureFlags; private readonly DataStore dataStore; + private readonly KernelConfig kernelConfig; private readonly ICatalyst catalyst; private string assetBundlesUrl => featureFlags.Get().IsFeatureEnabled("ab-new-cdn") ? "https://ab-cdn.decentraland.org/" : "https://content-assets-as-bundle.decentraland.org/"; @@ -64,10 +65,12 @@ public LambdasWearablesCatalogService(BaseDictionary weara ILambdasService lambdasService, IServiceProviders serviceProviders, BaseVariable featureFlags, - DataStore dataStore) + DataStore dataStore, + KernelConfig kernelConfig) { this.featureFlags = featureFlags; this.dataStore = dataStore; + this.kernelConfig = kernelConfig; this.lambdasService = lambdasService; WearablesCatalog = wearablesCatalog; catalyst = serviceProviders.catalyst; @@ -285,11 +288,11 @@ public async UniTask RequestWearableFromBuilderAsync(string wearab return wearable; } - const string TEMPLATE_URL = "https://builder-api.decentraland.org/v1/items/:wearableId/"; - string url = TEMPLATE_URL.Replace(":wearableId", wearableId); + string domain = GetBuilderDomainUrl(); + var url = $"{domain}/items/{wearableId}"; (WearableItemResponseFromBuilder response, bool success) = await lambdasService.GetFromSpecificUrl( - TEMPLATE_URL, url, + domain, url, isSigned: true, cancellationToken: ct); @@ -299,7 +302,7 @@ public async UniTask RequestWearableFromBuilderAsync(string wearab List ws = new List { response.data.ToWearableItem( - "https://builder-api.decentraland.org/v1/storage/contents/", + $"{domain}/storage/contents/", assetBundlesUrl), }; @@ -346,8 +349,7 @@ public async UniTask> RequestWearableCollection(IEnu public async UniTask> RequestWearableCollectionInBuilder(IEnumerable collectionIds, CancellationToken cancellationToken, List collectionBuffer = null) { - const string TEMPLATE_URL = "https://builder-api.decentraland.org/v1/collections/:collectionId/items/"; - + string domain = GetBuilderDomainUrl(); var wearables = collectionBuffer ?? new List(); var queryParams = new[] @@ -358,10 +360,11 @@ public async UniTask> RequestWearableCollectionInBui foreach (string collectionId in collectionIds) { - string url = TEMPLATE_URL.Replace(":collectionId", collectionId); + var url = $"{domain}/collections/{collectionId}/items/"; + var templateUrl = $"{domain}/collections/:collectionId/items/"; (WearableCollectionResponseFromBuilder response, bool success) = await lambdasService.GetFromSpecificUrl( - TEMPLATE_URL, url, + templateUrl, url, isSigned: true, urlEncodedParams: queryParams, cancellationToken: cancellationToken); @@ -371,7 +374,7 @@ public async UniTask> RequestWearableCollectionInBui List ws = response.data.results .Select(bw => bw.ToWearableItem( - "https://builder-api.decentraland.org/v1/storage/contents/", + $"{domain}/storage/contents/", assetBundlesUrl)) .Where(bw => !bw.IsEmote()) .ToList(); @@ -701,5 +704,14 @@ private bool IsInvalidWearable(EntityDto.MetadataDto metadata) private bool IsLocalPreview() => dataStore.realm.playerRealm.Get()?.serverName?.Equals("LocalPreview", StringComparison.OrdinalIgnoreCase) ?? false; + + private string GetBuilderDomainUrl() + { + string domain = kernelConfig.Get().builderUrl; + + if (string.IsNullOrEmpty(domain)) + domain = "https://builder-api.decentraland.org/v1"; + return domain; + } } } diff --git a/unity-renderer/Assets/DCLServices/WearablesCatalogService/Tests/LambdasWearablesCatalogServiceShould.cs b/unity-renderer/Assets/DCLServices/WearablesCatalogService/Tests/LambdasWearablesCatalogServiceShould.cs index ba9e8b1040..4afea86d4a 100644 --- a/unity-renderer/Assets/DCLServices/WearablesCatalogService/Tests/LambdasWearablesCatalogServiceShould.cs +++ b/unity-renderer/Assets/DCLServices/WearablesCatalogService/Tests/LambdasWearablesCatalogServiceShould.cs @@ -70,7 +70,7 @@ public void SetUp() BaseVariable featureFlags = new BaseVariable(); featureFlags.Set(new FeatureFlag()); - service = new LambdasWearablesCatalogService(initialCatalog, lambdasService, serviceProviders, featureFlags, new DataStore()); + service = new LambdasWearablesCatalogService(initialCatalog, lambdasService, serviceProviders, featureFlags, new DataStore(), KernelConfig.i); service.Initialize(); } diff --git a/unity-renderer/Assets/DCLServices/WearablesCatalogService/Tests/WarablesCatalogServiceTests.asmdef b/unity-renderer/Assets/DCLServices/WearablesCatalogService/Tests/WarablesCatalogServiceTests.asmdef index 91971269a3..405fea6b45 100644 --- a/unity-renderer/Assets/DCLServices/WearablesCatalogService/Tests/WarablesCatalogServiceTests.asmdef +++ b/unity-renderer/Assets/DCLServices/WearablesCatalogService/Tests/WarablesCatalogServiceTests.asmdef @@ -14,7 +14,8 @@ "CatalystInterfaces", "FeatureFlagData", "Utils", - "DataStore" + "DataStore", + "KernelConfiguration" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/unity-renderer/Assets/Scripts/MainScripts/DCL/Environment/Factories/ServiceLocatorFactory/ServiceLocatorFactory.cs b/unity-renderer/Assets/Scripts/MainScripts/DCL/Environment/Factories/ServiceLocatorFactory/ServiceLocatorFactory.cs index 65b0f8fac6..dd84b499f0 100644 --- a/unity-renderer/Assets/Scripts/MainScripts/DCL/Environment/Factories/ServiceLocatorFactory/ServiceLocatorFactory.cs +++ b/unity-renderer/Assets/Scripts/MainScripts/DCL/Environment/Factories/ServiceLocatorFactory/ServiceLocatorFactory.cs @@ -133,7 +133,7 @@ public static ServiceLocator CreateDefault() featureFlagsDataStore); var lambdasEmotesCatalogService = new LambdasEmotesCatalogService(emotesRequest, addressableResourceProvider, - result.Get().catalyst, result.Get(), DataStore.i); + result.Get().catalyst, result.Get(), DataStore.i, KernelConfig.i); var webInterfaceEmotesCatalogService = new WebInterfaceEmotesCatalogService(EmotesCatalogBridge.GetOrCreate(), addressableResourceProvider); return new EmotesCatalogServiceProxy(lambdasEmotesCatalogService, webInterfaceEmotesCatalogService, featureFlagsDataStore, KernelConfig.i); }); @@ -149,7 +149,8 @@ public static ServiceLocator CreateDefault() result.Get(), result.Get(), featureFlagsDataStore, - DataStore.i), + DataStore.i, + KernelConfig.i), WebInterfaceWearablesCatalogService.Instance, DataStore.i.common.wearables, KernelConfig.i, diff --git a/unity-renderer/Assets/Scripts/MainScripts/DCL/KernelConfiguration/KernelConfigModel.cs b/unity-renderer/Assets/Scripts/MainScripts/DCL/KernelConfiguration/KernelConfigModel.cs index b7ab18a413..d818be511d 100644 --- a/unity-renderer/Assets/Scripts/MainScripts/DCL/KernelConfiguration/KernelConfigModel.cs +++ b/unity-renderer/Assets/Scripts/MainScripts/DCL/KernelConfiguration/KernelConfigModel.cs @@ -21,6 +21,7 @@ public class KernelConfigModel public ProceduralSkybox proceduralSkyboxConfig = new ProceduralSkybox(); public string avatarTextureAPIBaseUrl = string.Empty; public bool urlParamsForWearablesDebug = false; + public string builderUrl = string.Empty; public override bool Equals(object obj) { return obj is KernelConfigModel other && Equals(other); } @@ -48,7 +49,8 @@ public bool Equals(KernelConfigModel other) && debugConfig.Equals(other.debugConfig) && proceduralSkyboxConfig.Equals(other.proceduralSkyboxConfig) && avatarTextureAPIBaseUrl == other.avatarTextureAPIBaseUrl - && urlParamsForWearablesDebug == other.urlParamsForWearablesDebug; + && urlParamsForWearablesDebug == other.urlParamsForWearablesDebug + && builderUrl == other.builderUrl; } public string GetTld() => @@ -70,6 +72,7 @@ public KernelConfigModel Clone() clone.proceduralSkyboxConfig = proceduralSkyboxConfig.Clone(); clone.avatarTextureAPIBaseUrl = avatarTextureAPIBaseUrl; clone.urlParamsForWearablesDebug = urlParamsForWearablesDebug; + clone.builderUrl = builderUrl; return clone; } }