Skip to content

Commit c5c4235

Browse files
Merge pull request #6263 from decentraland/release/release20250127
Release: 20250127
2 parents 474ae12 + 85fec7a commit c5c4235

File tree

11 files changed

+123
-59
lines changed

11 files changed

+123
-59
lines changed

browser-interface/packages/config/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ export const BYPASS_CONTENT_ALLOWLIST = qs.has('BYPASS_CONTENT_ALLOWLIST')
107107
? qs.get('BYPASS_CONTENT_ALLOWLIST') === 'true'
108108
: PIN_CATALYST || globalThis.location.hostname !== 'play.decentraland.org'
109109

110+
export const PEER_TESTING_CATALYST = 'https://peer-testing.decentraland.org'
111+
110112
const META_CONFIG_URL = ensureSingleString(qs.get('META_CONFIG_URL'))
111113

112114
export const CHANNEL_TO_JOIN_CONFIG_URL = ensureSingleString(qs.get('CHANNEL'))

browser-interface/packages/shared/catalogs/sagas.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
ETHEREUM_NETWORK,
1010
BUILDER_SERVER_URL,
1111
rootURLPreviewMode,
12-
WITH_FIXED_ITEMS
12+
WITH_FIXED_ITEMS,
13+
PEER_TESTING_CATALYST
1314
} from 'config'
1415

1516
import { authorizeBuilderHeaders } from 'lib/decentraland/authentication/authorizeBuilderHeaders'
@@ -122,8 +123,12 @@ function* fetchItemsFromCatalyst(
122123
const identity: ExplorerIdentity = yield select(getCurrentIdentity)
123124
const client: CatalystClient = new CatalystClient({ catalystUrl })
124125
const network: ETHEREUM_NETWORK = yield select(getSelectedNetwork)
125-
const COLLECTIONS_OR_ITEMS_ALLOWED =
126-
PREVIEW || ((DEBUG || getTLD() !== 'org') && network !== ETHEREUM_NETWORK.MAINNET)
126+
const isPreviewMode = PREVIEW
127+
const isDebugOrNonOrgTLD = DEBUG || getTLD() !== 'org'
128+
const isNonMainnetOrTestingPeer =
129+
network !== ETHEREUM_NETWORK.MAINNET ||
130+
(network === ETHEREUM_NETWORK.MAINNET && catalystUrl === PEER_TESTING_CATALYST)
131+
const COLLECTIONS_OR_ITEMS_ALLOWED = isPreviewMode || (isDebugOrNonOrgTLD && isNonMainnetOrTestingPeer)
127132
const isRequestingEmotes = action.type === EMOTES_REQUEST
128133
const catalystFetchFn = isRequestingEmotes ? client.fetchEmotes : client.fetchWearables
129134
const result: PartialItem[] = []
@@ -264,7 +269,7 @@ function fetchOwnedEmotes(ethAddress: string, client: CatalystClient) {
264269

265270
export function urnWithoutToken(urn: string): string {
266271
const value = urn.split(':')
267-
if (value.length === 7 && !urn.includes("collections-thirdparty")) {
272+
if (value.length === 7 && !urn.includes('collections-thirdparty')) {
268273
return value.slice(0, 6).join(':')
269274
}
270275
return urn

unity-renderer/Assets/DCLServices/EmotesCatalog/EmotesCatalogService/LambdasEmotesCatalogService.cs

+2
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,8 @@ public async UniTask<IReadOnlyList<WearableItem>> RequestEmoteCollectionInBuilde
375375
if (!success)
376376
throw new Exception($"The request for collection of emotes '{collectionId}' failed!");
377377

378+
if (response.data?.results == null) continue;
379+
378380
foreach (BuilderWearable bw in response.data.results)
379381
{
380382
var wearable = bw.ToWearableItem($"{domain}/storage/contents/",

unity-renderer/Assets/DCLServices/WearablesCatalogService/IWearablesCatalogService.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public interface IWearablesCatalogService : IService
2626
UniTask<WearableItem> RequestWearableAsync(string wearableId, CancellationToken ct);
2727
UniTask<WearableItem> RequestWearableFromBuilderAsync(string wearableId, CancellationToken ct);
2828
UniTask<IReadOnlyList<WearableItem>> RequestWearableCollection(IEnumerable<string> collectionIds, CancellationToken cancellationToken, List<WearableItem> collectionBuffer = null);
29-
UniTask<IReadOnlyList<WearableItem>> RequestWearableCollectionInBuilder(IEnumerable<string> collectionIds, CancellationToken cancellationToken, List<WearableItem> collectionBuffer = null);
29+
UniTask<(IReadOnlyList<WearableItem> wearables, int totalAmount)> RequestWearableCollectionInBuilder(IEnumerable<string> collectionIds, CancellationToken cancellationToken, List<WearableItem> collectionBuffer = null, string nameFilter = null, int pageNumber = 1, int pageSize = 5000);
3030

3131
void AddWearablesToCatalog(IEnumerable<WearableItem> wearableItems);
3232
void RemoveWearablesFromCatalog(IEnumerable<string> wearableIds);

unity-renderer/Assets/DCLServices/WearablesCatalogService/LambdasWearablesCatalogService.cs

+11-5
Original file line numberDiff line numberDiff line change
@@ -346,18 +346,22 @@ public async UniTask<IReadOnlyList<WearableItem>> RequestWearableCollection(IEnu
346346
return wearables;
347347
}
348348

349-
public async UniTask<IReadOnlyList<WearableItem>> RequestWearableCollectionInBuilder(IEnumerable<string> collectionIds,
350-
CancellationToken cancellationToken, List<WearableItem> collectionBuffer = null)
349+
public async UniTask<(IReadOnlyList<WearableItem> wearables, int totalAmount)> RequestWearableCollectionInBuilder(IEnumerable<string> collectionIds,
350+
CancellationToken cancellationToken, List<WearableItem> collectionBuffer = null, string nameFilter = null,
351+
int pageNumber = 1, int pageSize = 5000)
351352
{
352353
string domain = GetBuilderDomainUrl();
353354
var wearables = collectionBuffer ?? new List<WearableItem>();
354355

355356
var queryParams = new[]
356357
{
357-
("page", "1"),
358-
("limit", "5000"),
358+
("page", pageNumber.ToString()),
359+
("limit", pageSize.ToString()),
360+
("name", nameFilter),
359361
};
360362

363+
var totalAmount = 0;
364+
361365
foreach (string collectionId in collectionIds)
362366
{
363367
var url = $"{domain}/collections/{collectionId}/items/";
@@ -366,6 +370,7 @@ public async UniTask<IReadOnlyList<WearableItem>> RequestWearableCollectionInBui
366370
(WearableCollectionResponseFromBuilder response, bool success) = await lambdasService.GetFromSpecificUrl<WearableCollectionResponseFromBuilder>(
367371
templateUrl, url,
368372
isSigned: true,
373+
// urlEncodedParams: queryParams.Select(pair => (pair.Key, pair.Value)).ToArray(),
369374
urlEncodedParams: queryParams,
370375
cancellationToken: cancellationToken);
371376

@@ -382,9 +387,10 @@ public async UniTask<IReadOnlyList<WearableItem>> RequestWearableCollectionInBui
382387
AddWearablesToCatalog(ws);
383388

384389
wearables.AddRange(ws);
390+
totalAmount = response.data.total;
385391
}
386392

387-
return wearables;
393+
return (wearables, totalAmount);
388394
}
389395

390396
public void AddWearablesToCatalog(IEnumerable<WearableItem> wearableItems)

unity-renderer/Assets/DCLServices/WearablesCatalogService/WearablesCatalogServiceProxy.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,15 @@ public async UniTask<IReadOnlyList<WearableItem>> RequestWearableCollection(IEnu
124124
return await lambdasWearablesCatalogService.RequestWearableCollection(collectionIds, cancellationToken, wearableBuffer);
125125
}
126126

127-
public async UniTask<IReadOnlyList<WearableItem>> RequestWearableCollectionInBuilder(IEnumerable<string> collectionIds,
128-
CancellationToken cancellationToken, List<WearableItem> wearableBuffer = null)
127+
public async UniTask<(IReadOnlyList<WearableItem> wearables, int totalAmount)> RequestWearableCollectionInBuilder(
128+
IEnumerable<string> collectionIds, CancellationToken cancellationToken,
129+
List<WearableItem> collectionBuffer = null, string nameFilter = null, int pageNumber = 1, int pageSize = 5000)
129130
{
130131
if (!isInitialized)
131132
await UniTask.WaitUntil(() => isInitialized, cancellationToken: cancellationToken);
132133

133-
return await lambdasWearablesCatalogService.RequestWearableCollectionInBuilder(collectionIds, cancellationToken, wearableBuffer);
134+
return await lambdasWearablesCatalogService.RequestWearableCollectionInBuilder(collectionIds, cancellationToken,
135+
collectionBuffer, nameFilter, pageNumber, pageSize);
134136
}
135137

136138
public void AddWearablesToCatalog(IEnumerable<WearableItem> wearableItems) =>

unity-renderer/Assets/DCLServices/WearablesCatalogService/WebInterfaceWearablesCatalogService.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,9 @@ public UniTask<IReadOnlyList<WearableItem>> RequestWearableCollection(IEnumerabl
130130
CancellationToken cancellationToken, List<WearableItem> wearableBuffer = null) =>
131131
throw new NotImplementedException("Supported by LambdasWearablesCatalogService");
132132

133-
public UniTask<IReadOnlyList<WearableItem>> RequestWearableCollectionInBuilder(IEnumerable<string> collectionIds,
134-
CancellationToken cancellationToken, List<WearableItem> wearableBuffer = null) =>
133+
public UniTask<(IReadOnlyList<WearableItem> wearables, int totalAmount)> RequestWearableCollectionInBuilder(
134+
IEnumerable<string> collectionIds, CancellationToken cancellationToken,
135+
List<WearableItem> collectionBuffer = null, string nameFilter = null, int pageNumber = 1, int pageSize = 5000) =>
135136
throw new NotImplementedException("Supported by LambdasWearablesCatalogService");
136137

137138
private async UniTask<IReadOnlyList<WearableItem>> RequestWearablesByContextAsync(

unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/BackpackEditorHUDV2/Tests/WearableGridControllerShould.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1121,12 +1121,13 @@ public IEnumerator IncludeCustomWearableCollection()
11211121
};
11221122

11231123
wearablesCatalogService.RequestWearableCollectionInBuilder(Arg.Is<IEnumerable<string>>(i => i.Count() == 1 && i.ElementAt(0) == "builder:collection"),
1124-
Arg.Any<CancellationToken>(), Arg.Any<List<WearableItem>>())
1124+
Arg.Any<CancellationToken>(), Arg.Any<List<WearableItem>>(),
1125+
Arg.Any<string>(), Arg.Any<int>(), Arg.Any<int>())
11251126
.Returns(call =>
11261127
{
11271128
List<WearableItem> wearables = (List<WearableItem>) call[2];
11281129
wearables.AddRange(nonPublishedWearableList);
1129-
return UniTask.FromResult(nonPublishedWearableList);
1130+
return UniTask.FromResult((nonPublishedWearableList, nonPublishedWearableList.Count));
11301131
});
11311132

11321133
wearablesCatalogService.RequestWearableCollection(Arg.Is<IEnumerable<string>>(i => i.Count() == 1 && i.ElementAt(0) == "urn:collection"),

unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/BackpackEditorHUDV2/WearableGridController.cs

+83-40
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Collections.Generic;
1010
using System.Linq;
1111
using System.Threading;
12+
using System.Threading.Tasks;
1213
using UnityEngine;
1314
using UnityEngine.Pool;
1415

@@ -266,29 +267,9 @@ private async UniTask<int> RequestWearablesAndShowThem(int page, CancellationTok
266267

267268
try
268269
{
269-
int ownedWearablesCount = wearables.Count;
270-
int ownedWearablesTotalAmount = totalAmount;
271-
272-
customWearablesBuffer.Clear();
273-
274-
await UniTask.WhenAll(FetchCustomWearableCollections(customWearablesBuffer, cancellationToken),
275-
FetchCustomWearableItems(customWearablesBuffer, cancellationToken));
276-
277-
int customWearablesCount = customWearablesBuffer.Count;
278-
totalAmount += customWearablesCount;
279-
280-
if (ownedWearablesCount < PAGE_SIZE && customWearablesCount > 0)
281-
{
282-
int ownedWearablesStartingPage = (ownedWearablesTotalAmount / PAGE_SIZE) + 1;
283-
int customWearablesOffsetPage = page - ownedWearablesStartingPage;
284-
int skip = customWearablesOffsetPage * PAGE_SIZE;
285-
// Fill the page considering the existing owned wearables
286-
int count = PAGE_SIZE - ownedWearablesCount;
287-
int until = skip + count;
288-
289-
for (int i = skip; i < customWearablesBuffer.Count && i < until; i++)
290-
wearables.Add(customWearablesBuffer[i]);
291-
}
270+
totalAmount += await MergePublishedWearableCollections(page, wearables, totalAmount, cancellationToken);
271+
totalAmount += await MergeBuilderWearableCollections(page, wearables, totalAmount, cancellationToken);
272+
totalAmount += await MergeCustomWearableItems(page, wearables, totalAmount, cancellationToken);
292273

293274
customWearablesBuffer.Clear();
294275
}
@@ -299,7 +280,7 @@ await UniTask.WhenAll(FetchCustomWearableCollections(customWearablesBuffer, canc
299280
currentWearables = wearables.Select(ToWearableGridModel)
300281
.ToDictionary(item => ExtendedUrnParser.GetShortenedUrn(item.WearableId), model => model);
301282

302-
view.SetWearablePages(page, Mathf.CeilToInt((float) totalAmount / PAGE_SIZE));
283+
view.SetWearablePages(page, Mathf.CeilToInt((float)totalAmount / PAGE_SIZE));
303284

304285
// TODO: mark the wearables to be disposed if no references left
305286
view.ClearWearables();
@@ -313,6 +294,53 @@ await UniTask.WhenAll(FetchCustomWearableCollections(customWearablesBuffer, canc
313294
return 0;
314295
}
315296

297+
private async UniTask<int> MergeCustomWearableItems(int page, List<WearableItem> wearables,
298+
int totalAmount, CancellationToken cancellationToken) =>
299+
await MergeToWearableResults(page, wearables, totalAmount, FetchCustomWearableItems, cancellationToken);
300+
301+
private async UniTask<int> MergePublishedWearableCollections(int page, List<WearableItem> wearables, int totalAmount,
302+
CancellationToken cancellationToken) =>
303+
await MergeToWearableResults(page, wearables, totalAmount, FetchPublishedWearableCollections, cancellationToken);
304+
305+
private async UniTask<int> MergeToWearableResults(int page, List<WearableItem> wearables, int totalAmount,
306+
Func<List<WearableItem>, CancellationToken, UniTask> fetchOperation,
307+
CancellationToken cancellationToken)
308+
{
309+
int startingPage = (totalAmount / PAGE_SIZE) + 1;
310+
int pageOffset = page - startingPage;
311+
int pageSize = PAGE_SIZE - wearables.Count;
312+
int skip = pageOffset * PAGE_SIZE;
313+
int until = skip + pageSize;
314+
315+
customWearablesBuffer.Clear();
316+
317+
await fetchOperation.Invoke(customWearablesBuffer, cancellationToken);
318+
319+
if (skip < 0) return customWearablesBuffer.Count;
320+
321+
for (int i = skip; i < customWearablesBuffer.Count && i < until; i++)
322+
wearables.Add(customWearablesBuffer[i]);
323+
324+
return customWearablesBuffer.Count;
325+
}
326+
327+
private async UniTask<int> MergeBuilderWearableCollections(int page, List<WearableItem> wearables, int totalAmount, CancellationToken cancellationToken)
328+
{
329+
int startingPage = (totalAmount / PAGE_SIZE) + 1;
330+
int pageOffset = Mathf.Max(1, page - startingPage);
331+
int pageSize = PAGE_SIZE - wearables.Count;
332+
333+
customWearablesBuffer.Clear();
334+
335+
int collectionsWearableCount = await FetchBuilderWearableCollections(pageOffset, PAGE_SIZE,
336+
customWearablesBuffer, cancellationToken);
337+
338+
for (var i = 0; i < pageSize && i < customWearablesBuffer.Count; i++)
339+
wearables.Add(customWearablesBuffer[i]);
340+
341+
return collectionsWearableCount;
342+
}
343+
316344
private async UniTask FetchCustomWearableItems(ICollection<WearableItem> wearables, CancellationToken cancellationToken)
317345
{
318346
IReadOnlyList<string> customItems = await customNftCollectionService.GetConfiguredCustomNftItemsAsync(cancellationToken);
@@ -337,30 +365,46 @@ private async UniTask FetchCustomWearableItems(ICollection<WearableItem> wearabl
337365
}
338366
}
339367

340-
private async UniTask FetchCustomWearableCollections(
368+
private async UniTask FetchPublishedWearableCollections(
341369
List<WearableItem> wearableBuffer, CancellationToken cancellationToken)
342370
{
343371
IReadOnlyList<string> customCollections =
344372
await customNftCollectionService.GetConfiguredCustomNftCollectionAsync(cancellationToken);
345373

346-
Debug.Log($"FetchCustomWearableCollections: {customCollections}");
347-
348-
HashSet<string> publishedCollections = HashSetPool<string>.Get();
349-
HashSet<string> collectionsInBuilder = HashSetPool<string>.Get();
374+
HashSet<string> collectionsToRequest = HashSetPool<string>.Get();
350375

351376
foreach (string collectionId in customCollections)
352-
{
353377
if (collectionId.StartsWith("urn", StringComparison.OrdinalIgnoreCase))
354-
publishedCollections.Add(collectionId);
355-
else
356-
collectionsInBuilder.Add(collectionId);
357-
}
378+
collectionsToRequest.Add(collectionId);
358379

359-
await UniTask.WhenAll(wearablesCatalogService.RequestWearableCollection(publishedCollections, cancellationToken, wearableBuffer),
360-
wearablesCatalogService.RequestWearableCollectionInBuilder(collectionsInBuilder, cancellationToken, wearableBuffer));
380+
await wearablesCatalogService.RequestWearableCollection(collectionsToRequest, cancellationToken, wearableBuffer);
361381

362-
HashSetPool<string>.Release(publishedCollections);
363-
HashSetPool<string>.Release(collectionsInBuilder);
382+
HashSetPool<string>.Release(collectionsToRequest);
383+
}
384+
385+
private async UniTask<int> FetchBuilderWearableCollections(
386+
int pageNumber, int pageSize,
387+
List<WearableItem> wearableBuffer,
388+
CancellationToken cancellationToken)
389+
{
390+
IReadOnlyList<string> customCollections =
391+
await customNftCollectionService.GetConfiguredCustomNftCollectionAsync(cancellationToken);
392+
393+
HashSet<string> collectionsToRequest = HashSetPool<string>.Get();
394+
395+
foreach (string collectionId in customCollections)
396+
if (!collectionId.StartsWith("urn", StringComparison.OrdinalIgnoreCase))
397+
collectionsToRequest.Add(collectionId);
398+
399+
(IReadOnlyList<WearableItem> _, int totalAmount) = await wearablesCatalogService.RequestWearableCollectionInBuilder(
400+
collectionsToRequest, cancellationToken,
401+
collectionBuffer: wearableBuffer,
402+
nameFilter: nameFilter,
403+
pageNumber: pageNumber, pageSize: pageSize);
404+
405+
HashSetPool<string>.Release(collectionsToRequest);
406+
407+
return totalAmount;
364408
}
365409

366410
private WearableGridItemModel ToWearableGridModel(WearableItem wearable)
@@ -369,8 +413,7 @@ private WearableGridItemModel ToWearableGridModel(WearableItem wearable)
369413

370414
if (string.IsNullOrEmpty(wearable.rarity))
371415
rarity = NftRarity.None;
372-
else
373-
if (!Enum.TryParse(wearable.rarity, true, out NftRarity result))
416+
else if (!Enum.TryParse(wearable.rarity, true, out NftRarity result))
374417
{
375418
rarity = NftRarity.None;
376419
Debug.LogWarning($"Could not parse the rarity \"{wearable.rarity}\" of the wearable '{wearable.id}'. Fallback to common.");

unity-renderer/Assets/Scripts/MainScripts/DCL/Environment/TestEnvironment/ServiceLocatorTestFactory.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ public static ServiceLocator CreateMocked()
3939
{
4040
IWearablesCatalogService wearablesCatalogService = Substitute.For<IWearablesCatalogService>();
4141

42+
43+
4244
wearablesCatalogService.RequestWearableCollectionInBuilder(default, default, default)
43-
.ReturnsForAnyArgs(UniTask.FromResult((IReadOnlyList<WearableItem>) Array.Empty<WearableItem>()));
45+
.ReturnsForAnyArgs(UniTask.FromResult(((IReadOnlyList<WearableItem>) Array.Empty<WearableItem>(), 0)));
4446

4547
wearablesCatalogService.RequestWearableFromBuilderAsync(default, default)
4648
.ReturnsForAnyArgs(UniTask.FromResult<WearableItem>(null));

unity-renderer/Assets/Scripts/MainScripts/DCL/Models/AvatarAssets/Tests/Helpers/AvatarAssetsTestHelpers.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public static IWearablesCatalogService CreateTestCatalogLocal()
9191
.ReturnsForAnyArgs(UniTask.FromResult<IReadOnlyList<WearableItem>>(Array.Empty<WearableItem>()));
9292

9393
wearablesCatalogService.RequestWearableCollectionInBuilder(default, default, default)
94-
.ReturnsForAnyArgs(UniTask.FromResult<IReadOnlyList<WearableItem>>(Array.Empty<WearableItem>()));
94+
.ReturnsForAnyArgs(UniTask.FromResult(((IReadOnlyList<WearableItem>) Array.Empty<WearableItem>(), 0)));
9595

9696
return wearablesCatalogService;
9797
}

0 commit comments

Comments
 (0)