public override IAccountStateDelta Execute(IActionContext context) { IActionContext ctx = context; var states = ctx.PreviousStates; if (ctx.Rehearsal) { states = states.SetState(sellerAvatarAddress, MarkChanged); states = ShardedShopState.AddressKeys.Aggregate(states, (current, addressKey) => current.SetState(ShardedShopState.DeriveAddress(itemSubType, addressKey), MarkChanged)); return(states .SetState(ctx.Signer, MarkChanged)); } CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context); var addressesHex = GetSignerAndOtherAddressesHex(context, sellerAvatarAddress); var sw = new Stopwatch(); sw.Start(); var started = DateTimeOffset.UtcNow; Log.Verbose("{AddressesHex}Sell exec started", addressesHex); if (price.Sign < 0) { throw new InvalidPriceException($"{addressesHex}Aborted as the price is less than zero: {price}."); } if (!states.TryGetAgentAvatarStates(ctx.Signer, sellerAvatarAddress, out AgentState agentState, out AvatarState avatarState)) { throw new FailedLoadStateException($"{addressesHex}Aborted as the avatar state of the signer was failed to load."); } sw.Stop(); Log.Verbose("{AddressesHex}Sell Get AgentAvatarStates: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); if (!avatarState.worldInformation.IsStageCleared(GameConfig.RequireClearedStageLevel.ActionsInShop)) { avatarState.worldInformation.TryGetLastClearedStageId(out var current); throw new NotEnoughClearedStageLevelException(addressesHex, GameConfig.RequireClearedStageLevel.ActionsInShop, current); } Log.Verbose("{AddressesHex}Sell IsStageCleared: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); Log.Verbose("{AddressesHex}Execute Sell; seller: {SellerAvatarAddress}", addressesHex, sellerAvatarAddress); var productId = context.Random.GenerateRandomGuid(); long expiredBlockIndex = context.BlockIndex + ExpiredBlockIndex; // Select an item to sell from the inventory and adjust the quantity. if (!avatarState.inventory.TryGetNonFungibleItem(itemId, out INonFungibleItem nonFungibleItem)) { throw new ItemDoesNotExistException( $"{addressesHex}Aborted as the NonFungibleItem ({itemId}) was failed to load from avatar's inventory."); } ItemSubType nonFungibleItemType = nonFungibleItem is Costume costume ? costume.ItemSubType : ((ItemUsable)nonFungibleItem).ItemSubType; if (!nonFungibleItemType.Equals(itemSubType)) { throw new InvalidItemTypeException($"Expected ItemType: {nonFungibleItemType}. Actual ItemType: {itemSubType}"); } if (nonFungibleItem.RequiredBlockIndex > context.BlockIndex) { throw new RequiredBlockIndexException( $"{addressesHex}Aborted as the itemUsable to sell ({itemId}) is not available yet; it will be available at the block #{nonFungibleItem.RequiredBlockIndex}."); } if (nonFungibleItem is Equipment equipment) { equipment.Unequip(); } nonFungibleItem.RequiredBlockIndex = expiredBlockIndex; ShopItem shopItem = new ShopItem(ctx.Signer, sellerAvatarAddress, productId, price, expiredBlockIndex, nonFungibleItem); Address shardedShopAddress = ShardedShopState.DeriveAddress(itemSubType, productId); if (!states.TryGetState(shardedShopAddress, out Bencodex.Types.Dictionary shopStateDict)) { ShardedShopState shardedShopState = new ShardedShopState(shardedShopAddress); shopStateDict = (Dictionary)shardedShopState.Serialize(); } Log.Verbose("{AddressesHex}Sell Get ShardedShopState: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); List products = (List)shopStateDict[ProductsKey]; string productKey = LegacyItemUsableKey; string itemIdKey = LegacyItemIdKey; string requiredBlockIndexKey = LegacyRequiredBlockIndexKey; if (nonFungibleItem is Costume) { productKey = LegacyCostumeKey; itemIdKey = LegacyCostumeItemIdKey; requiredBlockIndexKey = RequiredBlockIndexKey; } #pragma warning disable LAA1002 Dictionary productSerialized = products .Select(p => (Dictionary)p) .FirstOrDefault(p => ((Dictionary)p[productKey])[itemIdKey].Equals(nonFungibleItem.NonFungibleId.Serialize())); #pragma warning restore LAA1002 // Register new ShopItem if (productSerialized.Equals(Dictionary.Empty)) { IValue shopItemSerialized = shopItem.Serialize(); products = products.Add(shopItemSerialized); } // Update Registered ShopItem else { // Delete current ShopItem products = (List)products.Remove(productSerialized); // Update INonfungibleItem.RequiredBlockIndex Dictionary item = (Dictionary)productSerialized[productKey]; item = item.SetItem(requiredBlockIndexKey, expiredBlockIndex.Serialize()); // Update ShopItem.ExpiredBlockIndex productSerialized = productSerialized .SetItem(ExpiredBlockIndexKey, expiredBlockIndex.Serialize()) .SetItem(productKey, item); products = products.Add(productSerialized); shopItem = new ShopItem(productSerialized); } shopStateDict = shopStateDict.SetItem(ProductsKey, new List <IValue>(products)); sw.Stop(); Log.Verbose("{AddressesHex}Sell Get Register Item: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); avatarState.updatedAt = ctx.BlockIndex; avatarState.blockIndex = ctx.BlockIndex; var result = new SellCancellation.Result { shopItem = shopItem, itemUsable = shopItem.ItemUsable, costume = shopItem.Costume }; var mail = new SellCancelMail(result, ctx.BlockIndex, ctx.Random.GenerateRandomGuid(), expiredBlockIndex); result.id = mail.id; avatarState.Update(mail); states = states.SetState(sellerAvatarAddress, avatarState.Serialize()); sw.Stop(); Log.Verbose("{AddressesHex}Sell Set AvatarState: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); states = states.SetState(shardedShopAddress, shopStateDict); sw.Stop(); var ended = DateTimeOffset.UtcNow; Log.Verbose("{AddressesHex}Sell Set ShopState: {Elapsed}", addressesHex, sw.Elapsed); Log.Verbose("{AddressesHex}Sell Total Executed Time: {Elapsed}", addressesHex, ended - started); return(states); }
public bool Equals(DestinyInventoryItemDefinition input) { if (input == null) { return(false); } return (( DisplayProperties == input.DisplayProperties || (DisplayProperties != null && DisplayProperties.Equals(input.DisplayProperties)) ) && ( TooltipNotifications == input.TooltipNotifications || (TooltipNotifications != null && TooltipNotifications.SequenceEqual(input.TooltipNotifications)) ) && ( CollectibleHash == input.CollectibleHash || (CollectibleHash.Equals(input.CollectibleHash)) ) && ( IconWatermark == input.IconWatermark || (IconWatermark != null && IconWatermark.Equals(input.IconWatermark)) ) && ( IconWatermarkShelved == input.IconWatermarkShelved || (IconWatermarkShelved != null && IconWatermarkShelved.Equals(input.IconWatermarkShelved)) ) && ( SecondaryIcon == input.SecondaryIcon || (SecondaryIcon != null && SecondaryIcon.Equals(input.SecondaryIcon)) ) && ( SecondaryOverlay == input.SecondaryOverlay || (SecondaryOverlay != null && SecondaryOverlay.Equals(input.SecondaryOverlay)) ) && ( SecondarySpecial == input.SecondarySpecial || (SecondarySpecial != null && SecondarySpecial.Equals(input.SecondarySpecial)) ) && ( BackgroundColor == input.BackgroundColor || (BackgroundColor != null && BackgroundColor.Equals(input.BackgroundColor)) ) && ( Screenshot == input.Screenshot || (Screenshot != null && Screenshot.Equals(input.Screenshot)) ) && ( ItemTypeDisplayName == input.ItemTypeDisplayName || (ItemTypeDisplayName != null && ItemTypeDisplayName.Equals(input.ItemTypeDisplayName)) ) && ( FlavorText == input.FlavorText || (FlavorText != null && FlavorText.Equals(input.FlavorText)) ) && ( UiItemDisplayStyle == input.UiItemDisplayStyle || (UiItemDisplayStyle != null && UiItemDisplayStyle.Equals(input.UiItemDisplayStyle)) ) && ( ItemTypeAndTierDisplayName == input.ItemTypeAndTierDisplayName || (ItemTypeAndTierDisplayName != null && ItemTypeAndTierDisplayName.Equals(input.ItemTypeAndTierDisplayName)) ) && ( DisplaySource == input.DisplaySource || (DisplaySource != null && DisplaySource.Equals(input.DisplaySource)) ) && ( TooltipStyle == input.TooltipStyle || (TooltipStyle != null && TooltipStyle.Equals(input.TooltipStyle)) ) && ( Action == input.Action || (Action != null && Action.Equals(input.Action)) ) && ( Inventory == input.Inventory || (Inventory != null && Inventory.Equals(input.Inventory)) ) && ( SetData == input.SetData || (SetData != null && SetData.Equals(input.SetData)) ) && ( Stats == input.Stats || (Stats != null && Stats.Equals(input.Stats)) ) && ( EmblemObjectiveHash == input.EmblemObjectiveHash || (EmblemObjectiveHash.Equals(input.EmblemObjectiveHash)) ) && ( EquippingBlock == input.EquippingBlock || (EquippingBlock != null && EquippingBlock.Equals(input.EquippingBlock)) ) && ( TranslationBlock == input.TranslationBlock || (TranslationBlock != null && TranslationBlock.Equals(input.TranslationBlock)) ) && ( Preview == input.Preview || (Preview != null && Preview.Equals(input.Preview)) ) && ( Quality == input.Quality || (Quality != null && Quality.Equals(input.Quality)) ) && ( Value == input.Value || (Value != null && Value.Equals(input.Value)) ) && ( SourceData == input.SourceData || (SourceData != null && SourceData.Equals(input.SourceData)) ) && ( Objectives == input.Objectives || (Objectives != null && Objectives.Equals(input.Objectives)) ) && ( Metrics == input.Metrics || (Metrics != null && Metrics.Equals(input.Metrics)) ) && ( Plug == input.Plug || (Plug != null && Plug.Equals(input.Plug)) ) && ( Gearset == input.Gearset || (Gearset != null && Gearset.Equals(input.Gearset)) ) && ( Sack == input.Sack || (Sack != null && Sack.Equals(input.Sack)) ) && ( Sockets == input.Sockets || (Sockets != null && Sockets.Equals(input.Sockets)) ) && ( Summary == input.Summary || (Summary != null && Summary.Equals(input.Summary)) ) && ( TalentGrid == input.TalentGrid || (TalentGrid != null && TalentGrid.Equals(input.TalentGrid)) ) && ( InvestmentStats == input.InvestmentStats || (InvestmentStats != null && InvestmentStats.SequenceEqual(input.InvestmentStats)) ) && ( Perks == input.Perks || (Perks != null && Perks.SequenceEqual(input.Perks)) ) && ( LoreHash == input.LoreHash || (LoreHash.Equals(input.LoreHash)) ) && ( SummaryItemHash == input.SummaryItemHash || (SummaryItemHash.Equals(input.SummaryItemHash)) ) && ( Animations == input.Animations || (Animations != null && Animations.SequenceEqual(input.Animations)) ) && ( AllowActions == input.AllowActions || (AllowActions != null && AllowActions.Equals(input.AllowActions)) ) && ( Links == input.Links || (Links != null && Links.SequenceEqual(input.Links)) ) && ( DoesPostmasterPullHaveSideEffects == input.DoesPostmasterPullHaveSideEffects || (DoesPostmasterPullHaveSideEffects != null && DoesPostmasterPullHaveSideEffects.Equals(input.DoesPostmasterPullHaveSideEffects)) ) && ( NonTransferrable == input.NonTransferrable || (NonTransferrable != null && NonTransferrable.Equals(input.NonTransferrable)) ) && ( ItemCategoryHashes == input.ItemCategoryHashes || (ItemCategoryHashes != null && ItemCategoryHashes.SequenceEqual(input.ItemCategoryHashes)) ) && ( SpecialItemType == input.SpecialItemType || (SpecialItemType != null && SpecialItemType.Equals(input.SpecialItemType)) ) && ( ItemType == input.ItemType || (ItemType != null && ItemType.Equals(input.ItemType)) ) && ( ItemSubType == input.ItemSubType || (ItemSubType != null && ItemSubType.Equals(input.ItemSubType)) ) && ( ClassType == input.ClassType || (ClassType != null && ClassType.Equals(input.ClassType)) ) && ( BreakerType == input.BreakerType || (BreakerType != null && BreakerType.Equals(input.BreakerType)) ) && ( BreakerTypeHash == input.BreakerTypeHash || (BreakerTypeHash.Equals(input.BreakerTypeHash)) ) && ( Equippable == input.Equippable || (Equippable != null && Equippable.Equals(input.Equippable)) ) && ( DamageTypeHashes == input.DamageTypeHashes || (DamageTypeHashes != null && DamageTypeHashes.SequenceEqual(input.DamageTypeHashes)) ) && ( DamageTypes == input.DamageTypes || (DamageTypes != null && DamageTypes.SequenceEqual(input.DamageTypes)) ) && ( DefaultDamageType == input.DefaultDamageType || (DefaultDamageType != null && DefaultDamageType.Equals(input.DefaultDamageType)) ) && ( DefaultDamageTypeHash == input.DefaultDamageTypeHash || (DefaultDamageTypeHash.Equals(input.DefaultDamageTypeHash)) ) && ( SeasonHash == input.SeasonHash || (SeasonHash.Equals(input.SeasonHash)) ) && ( IsWrapper == input.IsWrapper || (IsWrapper != null && IsWrapper.Equals(input.IsWrapper)) ) && ( TraitIds == input.TraitIds || (TraitIds != null && TraitIds.SequenceEqual(input.TraitIds)) ) && ( TraitHashes == input.TraitHashes || (TraitHashes != null && TraitHashes.SequenceEqual(input.TraitHashes)) ) && ( Hash == input.Hash || (Hash.Equals(input.Hash)) ) && ( Index == input.Index || (Index.Equals(input.Index)) ) && ( Redacted == input.Redacted || (Redacted != null && Redacted.Equals(input.Redacted)) )); }