Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,11 @@ public void ClearOwnedNftRegistry()
throw new NotImplementedException();
}

public void ClearOwnedNftForUrn(URN nftUrn)
{
throw new NotImplementedException();
}

public bool TryGetLatestTransferredAt(URN nftUrn, out DateTime latestTransferredAt)
{
throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ public interface IAvatarElementStorage<TElement, in TDTO> where TElement: IAvata
int GetOwnedNftCount(URN nftUrn);

void ClearOwnedNftRegistry();

/// <summary>
/// Clears the owned NFT entries for a specific base URN.
/// Call this before repopulating with fresh data from the API.
/// </summary>
void ClearOwnedNftForUrn(URN nftUrn);
}

public static class AvatarElementCache
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ private async UniTask<TAvatarElement> ProcessElementAsync(ILambdaResponseElement
await AssetBundleManifestFallbackHelper.CheckAssetBundleManifestFallbackAsync(World, avatarElement.DTO, partition, ct);

// Process individual data (this part needs to remain sequential per element for thread safety)
// Note: We use API's amount directly for display, registry is only for token ID tracking
foreach (ElementIndividualDataDto individualData in element.IndividualData)
{
// Probably a base wearable, wrongly return individual data. Skip it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,16 @@ public struct LambdaResponse : IAttachmentLambdaResponse<LambdaResponseElementDt
public class LambdaResponseElementDto : ILambdaResponseElement<TrimmedWearableDTO>
{
public TrimmedWearableDTO entity;
public int amount;

[JsonIgnore]
public TrimmedWearableDTO Entity => entity;

[JsonIgnore]
public IReadOnlyList<ElementIndividualDataDto> IndividualData => entity.individualData;

[JsonIgnore]
public int Amount => amount;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using CommunicationData.URLHelpers;
using DCL.AvatarRendering.Wearables.Components;
Expand Down Expand Up @@ -50,6 +50,21 @@ public void ClearOwnedNftRegistry()
}
}

/// <summary>
/// Clears the owned NFT entries for a specific base URN.
/// Call this before repopulating with fresh data from the API.
/// </summary>
public void ClearOwnedNftForUrn(URN nftUrn)
{
lock (lockObject)
{
if (ownedNftRegistry.TryGetValue(nftUrn, out var registry))
{
registry.Clear();
}
}
}

public bool TryGetLatestTransferredAt(URN nftUrn, out DateTime latestTransferredAt)
{
lock (lockObject)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ protected sealed override async UniTask<StreamableLoadingResult<WearablesRespons

var url = BuildUrlFromIntention(in intention);

ReportHub.Log(ReportCategory.GIFTING, $"[LoadWearablesByParamSystem] Fetching wearables from: {url}");

if (intention.NeedsBuilderAPISigning)
{
var lambdaResponse =
Expand All @@ -115,6 +117,8 @@ await ParseResponseAsync(
)
);

ReportHub.Log(ReportCategory.GIFTING, $"[LoadWearablesByParamSystem] API returned {lambdaResponse.TotalAmount} total, {lambdaResponse.Page.Count} on this page");

var assetBundlesVersions = await GetABVersionsAsync(lambdaResponse, ct);

await using (await ExecuteOnThreadPoolScope.NewScopeWithReturnOnMainThreadAsync())
Expand Down Expand Up @@ -172,8 +176,17 @@ private async UniTask<ITrimmedWearable> ProcessElementAsync(ILambdaResponseEleme
else
await AssetBundleManifestFallbackHelper.CheckAssetBundleManifestFallbackAsync(World, wearable.TrimmedDTO, partition, ct);

// Get amount directly from API response if available (more reliable than registry count)
int apiAmount = 0;
if (element is TrimmedWearableDTO.LambdaResponseElementDto trimmedElement)
apiAmount = trimmedElement.Amount;

ReportHub.Log(ReportCategory.GIFTING, $"[LoadWearablesByParamSystem] Processing: {elementDTO.Metadata.id}, API Amount: {apiAmount}, IndividualData count: {element.IndividualData?.Count ?? 0}");

if (element.IndividualData != null)
{
// Process individual data (this part needs to remain sequential per element for thread safety)
// Note: We use API's amount directly for display, registry is only for token ID tracking
foreach (var individualData in element.IndividualData)
{
// Probably a base wearable, wrongly return individual data. Skip it
Expand All @@ -194,8 +207,11 @@ private async UniTask<ITrimmedWearable> ProcessElementAsync(ILambdaResponseEleme

ReportHub.Log(ReportCategory.OUTFITS, $"<color=green>[WEARABLE_STORAGE_POPULATED]</color> Key: '{elementDTO.Metadata.id}' now maps to Value: '{individualData.id}' (Token: {individualData.tokenId})");
}
}

int ownedAmount = avatarElementStorage.GetOwnedNftCount(elementDTO.Metadata.id);
// Use API amount directly - it's the source of truth from the indexer
// Fall back to registry count only if API amount not available
int ownedAmount = apiAmount > 0 ? apiAmount : avatarElementStorage.GetOwnedNftCount(elementDTO.Metadata.id);
wearable.SetAmount(ownedAmount);
return wearable;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ MonoBehaviour:
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
Expand Down Expand Up @@ -176,6 +177,26 @@ PrefabInstance:
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3950903425550913156, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3950903425550913156, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3950903425550913156, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3950903425550913156, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3950903425550913156, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4450241265784993082, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
propertyPath: m_PixelsPerUnitMultiplier
value: 2
Expand Down Expand Up @@ -288,6 +309,10 @@ PrefabInstance:
propertyPath: m_Name
value: BackpackEmoteGridItem
objectReference: {fileID: 0}
- target: {fileID: 6687238669057343753, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8326074706031102082, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
propertyPath: m_AnchoredPosition.y
value: 6.5
Expand Down Expand Up @@ -344,6 +369,11 @@ PrefabInstance:
insertIndex: -1
addedObject: {fileID: 7445961164079291941}
m_SourcePrefab: {fileID: 100100000, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
--- !u!1 &122965643622874184 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 2117753677444134449, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
m_PrefabInstance: {fileID: 2078157404631091833}
m_PrefabAsset: {fileID: 0}
--- !u!114 &719150229022247077 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 1526146829364839132, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
Expand Down Expand Up @@ -392,6 +422,11 @@ GameObject:
m_CorrespondingSourceObject: {fileID: 3604137211807971006, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
m_PrefabInstance: {fileID: 2078157404631091833}
m_PrefabAsset: {fileID: 0}
--- !u!1 &3839358371985702382 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 2999183216935663511, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
m_PrefabInstance: {fileID: 2078157404631091833}
m_PrefabAsset: {fileID: 0}
--- !u!1 &4228669688390808703 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 2772064026238959110, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
Expand All @@ -408,6 +443,17 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &4890261822838372131 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 6848473177564986714, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
m_PrefabInstance: {fileID: 2078157404631091833}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
--- !u!1 &5091980877140501665 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 6520438785063841496, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
Expand All @@ -429,6 +475,8 @@ MonoBehaviour:
<ContainerTransform>k__BackingField: {fileID: 5337782633102568864}
<HoverBackgroundTransform>k__BackingField: {fileID: 6749943394813585919}
<EquipButton>k__BackingField: {fileID: 5665178272263481625}
<EquipSpinner>k__BackingField: {fileID: 0}
<EquipButtonText>k__BackingField: {fileID: 0}
<UnEquipButton>k__BackingField: {fileID: 7903757533396073920}
<EquippedIcon>k__BackingField: {fileID: 1877216464682181992}
<NewTag>k__BackingField: {fileID: 1516561254018689797}
Expand All @@ -441,6 +489,10 @@ MonoBehaviour:
<IsEquipped>k__BackingField: 0
incompatibleWithBodyShapeContainer: {fileID: 3374162131891453127}
incompatibleWithBodyShapeHoverContainer: {fileID: 4228669688390808703}
pendingTransferContainer: {fileID: 3839358371985702382}
pendingTransferHoverContainer: {fileID: 8045011785916068164}
nftCountContainer: {fileID: 122965643622874184}
nftCountText: {fileID: 4890261822838372131}
<SmartWearableBadgeContainer>k__BackingField: {fileID: 0}
<EquipWearableAudio>k__BackingField: {fileID: 11400000, guid: d1d7149ae3c90e449b657edfd7109eff, type: 2}
<UnEquipWearableAudio>k__BackingField: {fileID: 11400000, guid: b78ff33cb1d284d4b8938bf362676581, type: 2}
Expand Down Expand Up @@ -500,3 +552,8 @@ GameObject:
m_CorrespondingSourceObject: {fileID: 8241648339715965561, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
m_PrefabInstance: {fileID: 2078157404631091833}
m_PrefabAsset: {fileID: 0}
--- !u!1 &8045011785916068164 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 8318859614241815357, guid: aabac5666448b4345a76347f94ea32a4, type: 3}
m_PrefabInstance: {fileID: 2078157404631091833}
m_PrefabAsset: {fileID: 0}
Loading