Пример #1
0
        public void Execute(
            ItemType itemType,
            bool orderExist,
            int itemCount,
            bool backward
            )
        {
            var avatarState = _initialState.GetAvatarState(_avatarAddress);

            ITradableItem tradableItem;

            switch (itemType)
            {
            case ItemType.Consumable:
                tradableItem = ItemFactory.CreateItemUsable(
                    _tableSheets.ConsumableItemSheet.First,
                    Guid.NewGuid(),
                    0);
                break;

            case ItemType.Costume:
                tradableItem = ItemFactory.CreateCostume(
                    _tableSheets.CostumeItemSheet.First,
                    Guid.NewGuid());
                break;

            case ItemType.Equipment:
                tradableItem = ItemFactory.CreateItemUsable(
                    _tableSheets.EquipmentItemSheet.First,
                    Guid.NewGuid(),
                    0);
                break;

            case ItemType.Material:
                var tradableMaterialRow = _tableSheets.MaterialItemSheet.OrderedList
                                          .First(row => row.ItemSubType == ItemSubType.Hourglass);
                tradableItem = ItemFactory.CreateTradableMaterial(tradableMaterialRow);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(itemType), itemType, null);
            }

            Assert.Equal(0, tradableItem.RequiredBlockIndex);
            avatarState.inventory.AddItem2((ItemBase)tradableItem, itemCount);

            var previousStates = _initialState;

            if (backward)
            {
                previousStates = previousStates.SetState(_avatarAddress, avatarState.Serialize());
            }
            else
            {
                previousStates = previousStates
                                 .SetState(_avatarAddress.Derive(LegacyInventoryKey), avatarState.inventory.Serialize())
                                 .SetState(_avatarAddress.Derive(LegacyWorldInformationKey), avatarState.worldInformation.Serialize())
                                 .SetState(_avatarAddress.Derive(LegacyQuestListKey), avatarState.questList.Serialize())
                                 .SetState(_avatarAddress, avatarState.SerializeV2());
            }

            var currencyState      = previousStates.GetGoldCurrency();
            var price              = new FungibleAssetValue(currencyState, ProductPrice, 0);
            var orderId            = new Guid("6f460c1a755d48e4ad6765d5f519dbc8");
            var existOrderId       = new Guid("229e5f8c-fabe-4c04-bab9-45325cfa69a4");
            var orderAddress       = Order.DeriveAddress(orderId);
            var shardedShopAddress = ShardedShopStateV2.DeriveAddress(
                tradableItem.ItemSubType,
                orderId);
            long blockIndex = 1;

            if (orderExist)
            {
                var shardedShopState = new ShardedShopStateV2(shardedShopAddress);
                var existOrder       = OrderFactory.Create(
                    _agentAddress,
                    _avatarAddress,
                    existOrderId,
                    price,
                    tradableItem.TradableId,
                    0,
                    tradableItem.ItemSubType,
                    1
                    );
                existOrder.Sell2(avatarState);
                blockIndex = existOrder.ExpiredBlockIndex;
                shardedShopState.Add(existOrder.Digest2(avatarState, _tableSheets.CostumeStatSheet), blockIndex);
                Assert.Single(shardedShopState.OrderDigestList);
                previousStates = previousStates.SetState(
                    shardedShopAddress,
                    shardedShopState.Serialize());
            }
            else
            {
                Assert.Null(previousStates.GetState(shardedShopAddress));
            }

            var sellAction = new Sell7
            {
                sellerAvatarAddress = _avatarAddress,
                tradableId          = tradableItem.TradableId,
                count       = itemCount,
                price       = price,
                itemSubType = tradableItem.ItemSubType,
                orderId     = orderId,
            };
            var nextState = sellAction.Execute(new ActionContext
            {
                BlockIndex     = blockIndex,
                PreviousStates = previousStates,
                Rehearsal      = false,
                Signer         = _agentAddress,
                Random         = new TestRandom(),
            });

            long expiredBlockIndex = Order.ExpirationInterval + blockIndex;

            // Check AvatarState and Inventory
            var nextAvatarState = nextState.GetAvatarStateV2(_avatarAddress);

            Assert.Single(nextAvatarState.inventory.Items);
            Assert.True(nextAvatarState.inventory.TryGetTradableItems(
                            tradableItem.TradableId,
                            expiredBlockIndex,
                            1,
                            out var inventoryItems));
            Assert.Single(inventoryItems);
            ITradableItem nextTradableItem = (ITradableItem)inventoryItems.First().item;

            Assert.Equal(expiredBlockIndex, nextTradableItem.RequiredBlockIndex);

            // Check ShardedShopState
            var nextSerializedShardedShopState = nextState.GetState(shardedShopAddress);

            Assert.NotNull(nextSerializedShardedShopState);
            var nextShardedShopState =
                new ShardedShopStateV2((Dictionary)nextSerializedShardedShopState);
            var expectedCount = orderExist ? 2 : 1;

            Assert.Equal(expectedCount, nextShardedShopState.OrderDigestList.Count);
            var orderDigest = nextShardedShopState.OrderDigestList.First(o => o.OrderId.Equals(orderId));

            Assert.Equal(price, orderDigest.Price);
            Assert.Equal(blockIndex, orderDigest.StartedBlockIndex);
            Assert.Equal(expiredBlockIndex, orderDigest.ExpiredBlockIndex);
            Assert.Equal(((ItemBase)tradableItem).Id, orderDigest.ItemId);
            Assert.Equal(tradableItem.TradableId, orderDigest.TradableId);

            var serializedOrder = nextState.GetState(orderAddress);

            Assert.NotNull(serializedOrder);
            var serializedItem = nextState.GetState(Addresses.GetItemAddress(tradableItem.TradableId));

            Assert.NotNull(serializedItem);

            var           order     = OrderFactory.Deserialize((Dictionary)serializedOrder);
            ITradableItem orderItem = (ITradableItem)ItemFactory.Deserialize((Dictionary)serializedItem);

            Assert.Equal(price, order.Price);
            Assert.Equal(orderId, order.OrderId);
            Assert.Equal(tradableItem.TradableId, order.TradableId);
            Assert.Equal(blockIndex, order.StartedBlockIndex);
            Assert.Equal(expiredBlockIndex, order.ExpiredBlockIndex);
            Assert.Equal(_agentAddress, order.SellerAgentAddress);
            Assert.Equal(_avatarAddress, order.SellerAvatarAddress);
            Assert.Equal(expiredBlockIndex, orderItem.RequiredBlockIndex);

            var mailList = nextAvatarState.mailBox.OfType <OrderExpirationMail>().ToList();

            Assert.Single(mailList);
            var mail = mailList.First();

            Assert.NotNull(mail);
            Assert.Equal(expiredBlockIndex, mail.requiredBlockIndex);
            Assert.Equal(orderId, mail.OrderId);

            var receiptDict = nextState.GetState(OrderDigestListState.DeriveAddress(_avatarAddress));

            Assert.NotNull(receiptDict);
            var orderDigestList = new OrderDigestListState((Dictionary)receiptDict);

            Assert.Single(orderDigestList.OrderDigestList);
            OrderDigest orderDigest2 = orderDigestList.OrderDigestList.First();

            Assert.Equal(orderDigest, orderDigest2);
        }
Пример #2
0
        public void Execute(
            ItemType itemType,
            string guid,
            int itemCount,
            int inventoryCount,
            int expectedCount,
            bool fromPreviousAction,
            bool legacy
            )
        {
            var           avatarState = _initialState.GetAvatarState(_avatarAddress);
            ITradableItem tradableItem;
            var           itemId            = new Guid(guid);
            var           orderId           = Guid.NewGuid();
            var           updateSellOrderId = Guid.NewGuid();
            ItemSubType   itemSubType;
            const long    requiredBlockIndex = Order.ExpirationInterval;

            switch (itemType)
            {
            case ItemType.Equipment:
            {
                var itemUsable = ItemFactory.CreateItemUsable(
                    _tableSheets.EquipmentItemSheet.First,
                    itemId,
                    requiredBlockIndex);
                tradableItem = itemUsable;
                itemSubType  = itemUsable.ItemSubType;
                break;
            }

            case ItemType.Costume:
            {
                var costume = ItemFactory.CreateCostume(_tableSheets.CostumeItemSheet.First, itemId);
                costume.Update(requiredBlockIndex);
                tradableItem = costume;
                itemSubType  = costume.ItemSubType;
                break;
            }

            default:
            {
                var material = ItemFactory.CreateTradableMaterial(
                    _tableSheets.MaterialItemSheet.OrderedList.First(r => r.ItemSubType == ItemSubType.Hourglass));
                itemSubType = material.ItemSubType;
                material.RequiredBlockIndex = requiredBlockIndex;
                tradableItem = material;
                break;
            }
            }

            var shardedShopAddress = ShardedShopStateV2.DeriveAddress(itemSubType, orderId);
            var shopState          = new ShardedShopStateV2(shardedShopAddress);
            var order = OrderFactory.Create(
                _agentAddress,
                _avatarAddress,
                orderId,
                new FungibleAssetValue(_goldCurrencyState.Currency, 100, 0),
                tradableItem.TradableId,
                requiredBlockIndex,
                itemSubType,
                itemCount
                );

            var orderDigestList = new OrderDigestListState(OrderDigestListState.DeriveAddress(_avatarAddress));
            var prevState       = _initialState;

            if (inventoryCount > 1)
            {
                for (int i = 0; i < inventoryCount; i++)
                {
                    // Different RequiredBlockIndex for divide inventory slot.
                    if (tradableItem is ITradableFungibleItem tradableFungibleItem)
                    {
                        var tradable = (TradableMaterial)tradableFungibleItem.Clone();
                        tradable.RequiredBlockIndex = tradableItem.RequiredBlockIndex - i;
                        avatarState.inventory.AddItem2(tradable, 2 - i);
                    }
                }
            }
            else
            {
                avatarState.inventory.AddItem2((ItemBase)tradableItem, itemCount);
            }

            var sellItem    = legacy ? order.Sell2(avatarState) : order.Sell3(avatarState);
            var orderDigest = legacy ? order.Digest2(avatarState, _tableSheets.CostumeStatSheet)
                                     : order.Digest(avatarState, _tableSheets.CostumeStatSheet);

            shopState.Add(orderDigest, requiredBlockIndex);
            orderDigestList.Add(orderDigest);

            if (legacy)
            {
                Assert.True(avatarState.inventory.TryGetTradableItems(itemId, requiredBlockIndex * 2, itemCount, out _));
            }
            else
            {
                Assert.True(avatarState.inventory.TryGetLockedItem(new OrderLock(orderId), out _));
            }

            Assert.Equal(inventoryCount, avatarState.inventory.Items.Count);
            Assert.Equal(expectedCount, avatarState.inventory.Items.Sum(i => i.count));

            Assert.Single(shopState.OrderDigestList);
            Assert.Single(orderDigestList.OrderDigestList);

            Assert.Equal(requiredBlockIndex * 2, sellItem.RequiredBlockIndex);

            if (fromPreviousAction)
            {
                prevState = prevState.SetState(_avatarAddress, avatarState.Serialize());
            }
            else
            {
                prevState = prevState
                            .SetState(_avatarAddress.Derive(LegacyInventoryKey), avatarState.inventory.Serialize())
                            .SetState(_avatarAddress.Derive(LegacyWorldInformationKey), avatarState.worldInformation.Serialize())
                            .SetState(_avatarAddress.Derive(LegacyQuestListKey), avatarState.questList.Serialize())
                            .SetState(_avatarAddress, avatarState.SerializeV2());
            }

            prevState = prevState
                        .SetState(Addresses.GetItemAddress(itemId), sellItem.Serialize())
                        .SetState(Order.DeriveAddress(order.OrderId), order.Serialize())
                        .SetState(orderDigestList.Address, orderDigestList.Serialize())
                        .SetState(shardedShopAddress, shopState.Serialize());

            var currencyState = prevState.GetGoldCurrency();
            var price         = new FungibleAssetValue(currencyState, ProductPrice, 0);
            var action        = new UpdateSell0
            {
                orderId             = orderId,
                updateSellOrderId   = updateSellOrderId,
                tradableId          = itemId,
                sellerAvatarAddress = _avatarAddress,
                itemSubType         = itemSubType,
                price = price,
                count = itemCount,
            };
            var nextState = action.Execute(new ActionContext
            {
                BlockIndex     = 101,
                PreviousStates = prevState,
                Random         = new TestRandom(),
                Rehearsal      = false,
                Signer         = _agentAddress,
            });

            var updateSellShopAddress = ShardedShopStateV2.DeriveAddress(itemSubType, updateSellOrderId);
            var nextShopState         = new ShardedShopStateV2((Dictionary)nextState.GetState(updateSellShopAddress));

            Assert.Equal(1, nextShopState.OrderDigestList.Count);
            Assert.NotEqual(orderId, nextShopState.OrderDigestList.First().OrderId);
            Assert.Equal(updateSellOrderId, nextShopState.OrderDigestList.First().OrderId);
            Assert.Equal(itemId, nextShopState.OrderDigestList.First().TradableId);
            Assert.Equal(requiredBlockIndex + 101, nextShopState.OrderDigestList.First().ExpiredBlockIndex);
        }