Esempio n. 1
0
        public void Serialization()
        {
            var shopState     = new ShopState();
            var agentAddress  = new PrivateKey().ToAddress();
            var avatarAddress = new PrivateKey().ToAddress();
            var productId     = Guid.NewGuid();
            var weaponRow     = new EquipmentItemSheet.Row();

            weaponRow.Set(new[]
            {
                "10100000", "Weapon", "0", "Normal", "0", "ATK", "1", "2", "10100000",
            });
            var itemUsable = new Weapon(
                weaponRow,
                Guid.NewGuid(),
                0);
            var price    = new FungibleAssetValue(new Currency("NCG", 2, minter: null));
            var shopItem = new ShopItem(
                agentAddress,
                avatarAddress,
                productId,
                price,
                itemUsable);

            shopState.Register(shopItem);
            var serialized = (Dictionary)shopState.Serialize();

            shopState = new ShopState(serialized);

            Assert.Equal(1, shopState.Products.Count);
            Assert.Contains(productId, shopState.Products);
            Assert.Equal(shopItem, shopState.Products[productId]);
        }
Esempio n. 2
0
        public Sell0Test(ITestOutputHelper outputHelper)
        {
            Log.Logger = new LoggerConfiguration()
                         .MinimumLevel.Verbose()
                         .WriteTo.TestOutput(outputHelper)
                         .CreateLogger();

            _initialState = new State();
            var sheets = TableSheetsImporter.ImportSheets();

            foreach (var(key, value) in sheets)
            {
                _initialState = _initialState
                                .SetState(Addresses.TableSheet.Derive(key), value.Serialize());
            }

            _tableSheets = new TableSheets(sheets);

            _currency = new Currency("NCG", 2, minters: null);
            var goldCurrencyState = new GoldCurrencyState(_currency);

            var shopState = new ShopState();

            _agentAddress = new PrivateKey().ToAddress();
            var agentState = new AgentState(_agentAddress);

            _avatarAddress = new PrivateKey().ToAddress();
            var rankingMapAddress = new PrivateKey().ToAddress();

            _avatarState = new AvatarState(
                _avatarAddress,
                _agentAddress,
                0,
                _tableSheets.GetAvatarSheets(),
                new GameConfigState(),
                rankingMapAddress)
            {
                worldInformation = new WorldInformation(
                    0,
                    _tableSheets.WorldSheet,
                    GameConfig.RequireClearedStageLevel.ActionsInShop),
            };
            agentState.avatarAddresses[0] = _avatarAddress;

            var equipment = ItemFactory.CreateItemUsable(
                _tableSheets.EquipmentItemSheet.First,
                Guid.NewGuid(),
                0);

            _avatarState.inventory.AddItem2(equipment);

            _initialState = _initialState
                            .SetState(GoldCurrencyState.Address, goldCurrencyState.Serialize())
                            .SetState(Addresses.Shop, shopState.Serialize())
                            .SetState(_agentAddress, agentState.Serialize())
                            .SetState(_avatarAddress, _avatarState.Serialize());
        }
Esempio n. 3
0
        public BuyMultipleTest(ITestOutputHelper outputHelper)
        {
            Log.Logger = new LoggerConfiguration()
                         .MinimumLevel.Verbose()
                         .WriteTo.TestOutput(outputHelper)
                         .CreateLogger();

            _initialState = new State();
            var sheets = TableSheetsImporter.ImportSheets();

            foreach (var(key, value) in sheets)
            {
                _initialState = _initialState
                                .SetState(Addresses.TableSheet.Derive(key), value.Serialize());
            }

            _tableSheets = new TableSheets(sheets);

            var currency = new Currency("NCG", 2, minters: null);

            _goldCurrencyState = new GoldCurrencyState(currency);

            _sellerAgentStateMap = new Dictionary <AvatarState, AgentState>();

            _buyerAgentAddress = new PrivateKey().ToAddress();
            var buyerAgentState = new AgentState(_buyerAgentAddress);

            _buyerAvatarAddress = new PrivateKey().ToAddress();
            var rankingMapAddress = new PrivateKey().ToAddress();

            _buyerAvatarState = new AvatarState(
                _buyerAvatarAddress,
                _buyerAgentAddress,
                0,
                _tableSheets.GetAvatarSheets(),
                new GameConfigState(),
                rankingMapAddress)
            {
                worldInformation = new WorldInformation(
                    0,
                    _tableSheets.WorldSheet,
                    GameConfig.RequireClearedStageLevel.ActionsInShop),
            };
            buyerAgentState.avatarAddresses[0] = _buyerAvatarAddress;

            var shopState = new ShopState();

            _initialState = _initialState
                            .SetState(GoldCurrencyState.Address, _goldCurrencyState.Serialize())
                            .SetState(Addresses.Shop, shopState.Serialize())
                            .SetState(_buyerAgentAddress, buyerAgentState.Serialize())
                            .SetState(_buyerAvatarAddress, _buyerAvatarState.Serialize())
                            .MintAsset(_buyerAgentAddress, _goldCurrencyState.Currency * 100);
        }
Esempio n. 4
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IActionContext ctx              = context;
            var            states           = ctx.PreviousStates;
            var            weeklyArenaState = new WeeklyArenaState(0);

            if (ctx.Rehearsal)
            {
                states = states.SetState(RankingState.Address, MarkChanged);
                states = states.SetState(ShopState.Address, MarkChanged);
                states = states.SetState(TableSheetsState.Address, MarkChanged);
                states = states.SetState(weeklyArenaState.address, MarkChanged);
                states = states.SetState(GameConfigState.Address, MarkChanged);
                states = states.SetState(RedeemCodeState.Address, MarkChanged);
                states = states.SetState(AdminState.Address, MarkChanged);
                states = states.SetState(ActivatedAccountsState.Address, MarkChanged);
                states = states.SetState(GoldCurrencyState.Address, MarkChanged);
                states = states.SetState(Addresses.GoldDistribution, MarkChanged);
                return(states);
            }

            if (ctx.BlockIndex != 0)
            {
                return(states);
            }

            states = states
                     .SetState(weeklyArenaState.address, weeklyArenaState.Serialize())
                     .SetState(RankingState.Address, RankingState.Serialize())
                     .SetState(ShopState.Address, ShopState.Serialize())
                     .SetState(TableSheetsState.Address, TableSheetsState.Serialize())
                     .SetState(GameConfigState.Address, GameConfigState.Serialize())
                     .SetState(RedeemCodeState.Address, RedeemCodeState.Serialize())
                     .SetState(AdminState.Address, AdminAddressState.Serialize())
                     .SetState(ActivatedAccountsState.Address, ActivatedAccountsState.Serialize())
                     .SetState(GoldCurrencyState.Address, GoldCurrencyState.Serialize())
                     .SetState(Addresses.GoldDistribution, GoldDistributions.Select(v => v.Serialize()).Serialize());

            states = states.MintAsset(GoldCurrencyState.Address, GoldCurrencyState.Currency, 1000000000);
            return(states);
        }
Esempio n. 5
0
        public InitializeStates(
            RankingState rankingState,
            ShopState shopState,
            Dictionary <string, string> tableSheets,
            GameConfigState gameConfigState,
            RedeemCodeState redeemCodeState,
            AdminState adminAddressState,
            ActivatedAccountsState activatedAccountsState,
            GoldCurrencyState goldCurrencyState,
            GoldDistribution[] goldDistributions,
            PendingActivationState[] pendingActivationStates,
            AuthorizedMinersState authorizedMinersState = null,
            CreditsState creditsState = null)
        {
            Ranking           = (Bencodex.Types.Dictionary)rankingState.Serialize();
            Shop              = (Bencodex.Types.Dictionary)shopState.Serialize();
            TableSheets       = tableSheets;
            GameConfig        = (Bencodex.Types.Dictionary)gameConfigState.Serialize();
            RedeemCode        = (Bencodex.Types.Dictionary)redeemCodeState.Serialize();
            AdminAddress      = (Bencodex.Types.Dictionary)adminAddressState.Serialize();
            ActivatedAccounts = (Bencodex.Types.Dictionary)activatedAccountsState.Serialize();
            GoldCurrency      = (Bencodex.Types.Dictionary)goldCurrencyState.Serialize();
            GoldDistributions = new Bencodex.Types.List(
                goldDistributions.Select(d => d.Serialize()).Cast <Bencodex.Types.IValue>()
                );
            PendingActivations = new Bencodex.Types.List(pendingActivationStates.Select(p => p.Serialize()));

            if (!(authorizedMinersState is null))
            {
                AuthorizedMiners = (Bencodex.Types.Dictionary)authorizedMinersState.Serialize();
            }

            if (!(creditsState is null))
            {
                Credits = (Bencodex.Types.Dictionary)creditsState.Serialize();
            }
        }
Esempio n. 6
0
        public Buy3Test(ITestOutputHelper outputHelper)
        {
            Log.Logger = new LoggerConfiguration()
                         .MinimumLevel.Verbose()
                         .WriteTo.TestOutput(outputHelper)
                         .CreateLogger();

            _initialState = new State();
            var sheets = TableSheetsImporter.ImportSheets();

            foreach (var(key, value) in sheets)
            {
                _initialState = _initialState
                                .SetState(Addresses.TableSheet.Derive(key), value.Serialize());
            }

            _tableSheets = new TableSheets(sheets);

            var currency = new Currency("NCG", 2, minters: null);

            _goldCurrencyState = new GoldCurrencyState(currency);

            _sellerAgentAddress = new PrivateKey().ToAddress();
            var sellerAgentState = new AgentState(_sellerAgentAddress);

            _sellerAvatarAddress = new PrivateKey().ToAddress();
            var rankingMapAddress = new PrivateKey().ToAddress();
            var sellerAvatarState = new AvatarState(
                _sellerAvatarAddress,
                _sellerAgentAddress,
                0,
                _tableSheets.GetAvatarSheets(),
                new GameConfigState(),
                rankingMapAddress)
            {
                worldInformation = new WorldInformation(
                    0,
                    _tableSheets.WorldSheet,
                    GameConfig.RequireClearedStageLevel.ActionsInShop),
            };

            sellerAgentState.avatarAddresses[0] = _sellerAvatarAddress;

            _buyerAgentAddress = new PrivateKey().ToAddress();
            var buyerAgentState = new AgentState(_buyerAgentAddress);

            _buyerAvatarAddress = new PrivateKey().ToAddress();
            _buyerAvatarState   = new AvatarState(
                _buyerAvatarAddress,
                _buyerAgentAddress,
                0,
                _tableSheets.GetAvatarSheets(),
                new GameConfigState(),
                rankingMapAddress)
            {
                worldInformation = new WorldInformation(
                    0,
                    _tableSheets.WorldSheet,
                    GameConfig.RequireClearedStageLevel.ActionsInShop),
            };
            buyerAgentState.avatarAddresses[0] = _buyerAvatarAddress;

            var equipment = ItemFactory.CreateItemUsable(
                _tableSheets.EquipmentItemSheet.First,
                Guid.NewGuid(),
                0);

            var consumable = ItemFactory.CreateItemUsable(
                _tableSheets.ConsumableItemSheet.First,
                Guid.NewGuid(),
                0);

            var costume = ItemFactory.CreateCostume(
                _tableSheets.CostumeItemSheet.First,
                Guid.NewGuid());

            var shopState = new ShopState();

            shopState.Register(new ShopItem(
                                   _sellerAgentAddress,
                                   _sellerAvatarAddress,
                                   Guid.NewGuid(),
                                   new FungibleAssetValue(_goldCurrencyState.Currency, ProductPrice, 0),
                                   equipment));

            shopState.Register(new ShopItem(
                                   _sellerAgentAddress,
                                   _sellerAvatarAddress,
                                   Guid.NewGuid(),
                                   new FungibleAssetValue(_goldCurrencyState.Currency, ProductPrice, 0),
                                   consumable));

            shopState.Register(new ShopItem(
                                   _sellerAgentAddress,
                                   _sellerAvatarAddress,
                                   Guid.NewGuid(),
                                   new FungibleAssetValue(_goldCurrencyState.Currency, ProductPrice, 0),
                                   costume));

            _initialState = _initialState
                            .SetState(GoldCurrencyState.Address, _goldCurrencyState.Serialize())
                            .SetState(Addresses.Shop, shopState.Serialize())
                            .SetState(_sellerAgentAddress, sellerAgentState.Serialize())
                            .SetState(_sellerAvatarAddress, sellerAvatarState.Serialize())
                            .SetState(_buyerAgentAddress, buyerAgentState.Serialize())
                            .SetState(_buyerAvatarAddress, _buyerAvatarState.Serialize())
                            .MintAsset(_buyerAgentAddress, shopState.Products
                                       .Select(pair => pair.Value.Price)
                                       .Aggregate((totalPrice, next) => totalPrice + next));
        }
Esempio n. 7
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IActionContext ctx    = context;
            var            states = ctx.PreviousStates;

            if (ctx.Rehearsal)
            {
                states = states.SetState(ShopState.Address, MarkChanged);
                states = states.SetState(sellerAvatarAddress, MarkChanged);
                return(states.SetState(ctx.Signer, MarkChanged));
            }
            var sw = new Stopwatch();

            sw.Start();
            var started = DateTimeOffset.UtcNow;

            Log.Debug("Sell exec started.");


            if (price < 0)
            {
                return(LogError(context, "Aborted as the price is less than zero: {Price}.", price));
            }

            if (!states.TryGetAgentAvatarStates(ctx.Signer, sellerAvatarAddress, out AgentState agentState, out AvatarState avatarState))
            {
                return(LogError(context, "Aborted as the avatar state of the signer was failed to load."));
            }
            sw.Stop();
            Log.Debug("Sell Get AgentAvatarStates: {Elapsed}", sw.Elapsed);
            sw.Restart();

            if (!avatarState.worldInformation.TryGetUnlockedWorldByStageClearedBlockIndex(out var world))
            {
                return(LogError(context, "Aborted as the WorldInformation was failed to load."));
            }

            if (world.StageClearedId < GameConfig.RequireClearedStageLevel.ActionsInShop)
            {
                // 스테이지 클리어 부족 에러.
                return(LogError(
                           context,
                           "Aborted as the signer is not cleared the minimum stage level required to sell items yet: {ClearedLevel} < {RequiredLevel}.",
                           world.StageClearedId,
                           GameConfig.RequireClearedStageLevel.ActionsInShop
                           ));
            }

            if (!states.TryGetState(ShopState.Address, out Bencodex.Types.Dictionary d))
            {
                return(LogError(context, "Aborted as the shop state was failed to load."));
            }
            var shopState = new ShopState(d);

            sw.Stop();
            Log.Debug("Sell Get ShopState: {Elapsed}", sw.Elapsed);
            sw.Restart();

            Log.Debug("Execute Sell; seller: {SellerAvatarAddress}", sellerAvatarAddress);

            // 인벤토리에서 판매할 아이템을 선택하고 수량을 조절한다.
            if (!avatarState.inventory.TryGetNonFungibleItem(itemId, out ItemUsable nonFungibleItem))
            {
                return(LogError(
                           context,
                           "Aborted as the NonFungibleItem ({@Item}) was failed to load from avatar's inventory.",
                           itemId
                           ));
            }

            if (nonFungibleItem.RequiredBlockIndex > context.BlockIndex)
            {
                // 필요 블럭 인덱스 불충분 에러.
                return(LogError(
                           context,
                           "Aborted as the equipment to enhance ({@Item}) is not available yet; it will be available at the block #{RequiredBlockIndex}.",
                           itemId,
                           nonFungibleItem.RequiredBlockIndex
                           ));
            }

            avatarState.inventory.RemoveNonFungibleItem(nonFungibleItem);
            if (nonFungibleItem is Equipment equipment)
            {
                equipment.equipped = false;
            }

            // 상점에 아이템을 등록한다.
            shopState.Register(ctx.Signer, new ShopItem(
                                   sellerAvatarAddress,
                                   productId,
                                   nonFungibleItem,
                                   price
                                   ));
            sw.Stop();
            Log.Debug("Sell Get Register Item: {Elapsed}", sw.Elapsed);
            sw.Restart();

            avatarState.updatedAt  = DateTimeOffset.UtcNow;
            avatarState.blockIndex = ctx.BlockIndex;

            states = states.SetState(sellerAvatarAddress, avatarState.Serialize());
            sw.Stop();
            Log.Debug("Sell Set AvatarState: {Elapsed}", sw.Elapsed);
            sw.Restart();

            states = states.SetState(ShopState.Address, shopState.Serialize());
            sw.Stop();
            var ended = DateTimeOffset.UtcNow;

            Log.Debug("Sell Set ShopState: {Elapsed}", sw.Elapsed);
            Log.Debug("Sell Total Executed Time: {Elapsed}", ended - started);

            return(states);
        }
Esempio n. 8
0
        public void Execute(bool isAdmin, bool expire, Type exc)
        {
            var adminAddress = new Address("399bddF9F7B6d902ea27037B907B2486C9910730");
            var adminState = new AdminState(adminAddress, 100);
            var states = new State().SetState(Addresses.Admin, adminState.Serialize());
            var signer = isAdmin ? adminAddress : default;
            var blockIndex = expire ? 200 : 100;

            var action = new MigrationLegacyShop();

            var avatarAddress = new Address(action.AvatarAddressesHex.First());

            if (exc is null)
            {
                var agentState = new AgentState(adminAddress);
                var avatarState = new AvatarState(
                    avatarAddress,
                    adminAddress,
                    0,
                    _tableSheets.GetAvatarSheets(),
                    new GameConfigState(),
                    default);
                agentState.avatarAddresses[0] = avatarAddress;

                var shopState = new ShopState();
                var itemSubTypes = new[] { ItemSubType.Weapon, ItemSubType.FullCostume };
                var random = new TestRandom();
                var itemIds = new List<Guid>();
                foreach (var itemSubType in itemSubTypes)
                {
                    var item = (ITradableItem)ItemFactory.CreateItem(_tableSheets.ItemSheet.Values.First(r => r.ItemSubType == itemSubType), random);
                    var shopItem = new ShopItem(
                        adminAddress,
                        avatarAddress,
                        Guid.NewGuid(),
                        new FungibleAssetValue(new Currency("NCG", 2, minter: null), 100, 0),
                        item);
                    shopState.Register(shopItem);
                    itemIds.Add(item.TradableId);
                }

                states = states
                    .SetState(Addresses.Shop, shopState.Serialize())
                    .SetState(adminAddress, agentState.Serialize())
                    .SetState(avatarAddress, avatarState.Serialize());

                var nextState = action.Execute(new ActionContext
                {
                    BlockIndex = blockIndex,
                    PreviousStates = states,
                    Signer = signer,
                });

                var nextShopState = nextState.GetShopState();
                Assert.Empty(nextShopState.Products);
                var nextAvatarState = nextState.GetAvatarState(avatarAddress);
                Assert.All(itemIds, id => nextAvatarState.inventory.HasNonFungibleItem(id));
            }
            else
            {
                Assert.Throws(exc, () => action.Execute(new ActionContext
                {
                    BlockIndex = blockIndex,
                    PreviousStates = states,
                    Signer = signer,
                }));
            }
        }
Esempio n. 9
0
File: Buy.cs Progetto: rheehot/lib9c
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IActionContext ctx    = context;
            var            states = ctx.PreviousStates;

            if (ctx.Rehearsal)
            {
                states = states
                         .SetState(buyerAvatarAddress, MarkChanged)
                         .SetState(ctx.Signer, MarkChanged)
                         .SetState(sellerAvatarAddress, MarkChanged)
                         .MarkBalanceChanged(GoldCurrencyMock, ctx.Signer, sellerAgentAddress);
                return(states.SetState(ShopState.Address, MarkChanged));
            }

            if (ctx.Signer.Equals(sellerAgentAddress))
            {
                return(LogError(context, "Aborted as the signer is the seller."));
            }

            var sw = new Stopwatch();

            sw.Start();
            var started = DateTimeOffset.UtcNow;

            Log.Debug("Buy exec started.");

            if (!states.TryGetAgentAvatarStates(ctx.Signer, buyerAvatarAddress, out var buyerAgentState, out var buyerAvatarState))
            {
                return(LogError(context, "Aborted as the avatar state of the buyer was failed to load."));
            }
            sw.Stop();
            Log.Debug("Buy Get Buyer AgentAvatarStates: {Elapsed}", sw.Elapsed);
            sw.Restart();

            if (!buyerAvatarState.worldInformation.TryGetUnlockedWorldByStageClearedBlockIndex(out var world))
            {
                return(LogError(context, "Aborted as the WorldInformation was failed to load."));
            }

            if (world.StageClearedId < GameConfig.RequireClearedStageLevel.ActionsInShop)
            {
                // 스테이지 클리어 부족 에러.
                return(LogError(
                           context,
                           "Aborted as the signer is not cleared the minimum stage level required to use shop yet: {ClearedLevel} < {RequiredLevel}.",
                           world.StageClearedId,
                           GameConfig.RequireClearedStageLevel.ActionsInShop
                           ));
            }

            if (!states.TryGetState(ShopState.Address, out Bencodex.Types.Dictionary d))
            {
                return(LogError(context, "Aborted as the shop state was failed to load."));
            }

            var shopState = new ShopState(d);

            sw.Stop();
            Log.Debug("Buy Get ShopState: {Elapsed}", sw.Elapsed);
            sw.Restart();

            Log.Debug("Execute Buy; buyer: {Buyer} seller: {Seller}", buyerAvatarAddress, sellerAvatarAddress);
            // 상점에서 구매할 아이템을 찾는다.
            if (!shopState.TryGet(sellerAgentAddress, productId, out var outPair))
            {
                return(LogError(
                           context,
                           "Aborted as the shop item ({ProductId}) was failed to get from the seller agent ({SellerAgent}).",
                           productId,
                           sellerAgentAddress
                           ));
            }
            sw.Stop();
            Log.Debug($"Buy Get Item: {sw.Elapsed}");
            sw.Restart();

            if (!states.TryGetAgentAvatarStates(sellerAgentAddress, sellerAvatarAddress, out var sellerAgentState, out var sellerAvatarState))
            {
                return(LogError(
                           context,
                           "Aborted as the seller agent/avatar was filed to load from {SellerAgent}/{SellerAvatar}.",
                           sellerAgentAddress,
                           sellerAvatarAddress
                           ));
            }
            sw.Stop();
            Log.Debug($"Buy Get Seller AgentAvatarStates: {sw.Elapsed}");
            sw.Restart();

            // 돈은 있냐?
            BigInteger buyerBalance = states.GetBalance(context.Signer, states.GetGoldCurrency());

            if (buyerBalance < outPair.Value.Price)
            {
                return(LogError(
                           context,
                           "Aborted as the buyer ({Buyer}) has no sufficient gold: {BuyerBalance} < {ItemPrice}",
                           ctx.Signer,
                           buyerBalance,
                           outPair.Value.Price
                           ));
            }

            var taxedPrice = (BigInteger)decimal.Round((decimal)outPair.Value.Price * 0.92m);

            // 구매자의 돈을 판매자에게 송금한다.
            states = states.TransferAsset(context.Signer, sellerAgentAddress, states.GetGoldCurrency(), outPair.Value.Price);

            // 상점에서 구매할 아이템을 제거한다.
            if (!shopState.Unregister(sellerAgentAddress, outPair.Value))
            {
                return(LogError(
                           context,
                           "Aborted as the item ({@ProductId}) was failed to unregister from seller ({Seller})'s inventory.",
                           outPair.Value.ProductId,
                           sellerAgentAddress
                           ));
            }

            // 구매자, 판매자에게 결과 메일 전송
            buyerResult = new BuyerResult
            {
                shopItem   = outPair.Value,
                itemUsable = outPair.Value.ItemUsable
            };
            var buyerMail = new BuyerMail(buyerResult, ctx.BlockIndex, ctx.Random.GenerateRandomGuid(), ctx.BlockIndex);

            buyerResult.id = buyerMail.id;

            sellerResult = new SellerResult
            {
                shopItem   = outPair.Value,
                itemUsable = outPair.Value.ItemUsable,
                gold       = taxedPrice
            };
            var sellerMail = new SellerMail(sellerResult, ctx.BlockIndex, ctx.Random.GenerateRandomGuid(),
                                            ctx.BlockIndex);

            sellerResult.id = sellerMail.id;

            buyerAvatarState.Update(buyerMail);
            buyerAvatarState.UpdateFromAddItem(buyerResult.itemUsable, false);
            sellerAvatarState.Update(sellerMail);

            // 퀘스트 업데이트
            buyerAvatarState.questList.UpdateTradeQuest(TradeType.Buy, outPair.Value.Price);
            sellerAvatarState.questList.UpdateTradeQuest(TradeType.Sell, outPair.Value.Price);

            var timestamp = DateTimeOffset.UtcNow;

            buyerAvatarState.updatedAt   = timestamp;
            buyerAvatarState.blockIndex  = ctx.BlockIndex;
            sellerAvatarState.updatedAt  = timestamp;
            sellerAvatarState.blockIndex = ctx.BlockIndex;

            buyerAvatarState.UpdateQuestRewards(ctx);
            sellerAvatarState.UpdateQuestRewards(ctx);

            states = states.SetState(sellerAvatarAddress, sellerAvatarState.Serialize());
            sw.Stop();
            Log.Debug("Buy Set Seller AvatarState: {Elapsed}", sw.Elapsed);
            sw.Restart();

            states = states.SetState(buyerAvatarAddress, buyerAvatarState.Serialize());
            sw.Stop();
            Log.Debug("Buy Set Buyer AvatarState: {Elapsed}", sw.Elapsed);
            sw.Restart();

            states = states.SetState(ShopState.Address, shopState.Serialize());
            sw.Stop();
            var ended = DateTimeOffset.UtcNow;

            Log.Debug("Buy Set ShopState: {Elapsed}", sw.Elapsed);
            Log.Debug("Buy Total Executed Time: {Elapsed}", ended - started);

            return(states.SetState(ctx.Signer, buyerAgentState.Serialize()));
        }
Esempio n. 10
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IActionContext ctx    = context;
            var            states = ctx.PreviousStates;

            if (ctx.Rehearsal)
            {
                states = states.SetState(ShopState.Address, MarkChanged);
                return(states.SetState(sellerAvatarAddress, MarkChanged));
            }
            var sw = new Stopwatch();

            sw.Start();
            var started = DateTimeOffset.UtcNow;

            Log.Debug($"Sell Cancel exec started.");

            if (!states.TryGetAgentAvatarStates(ctx.Signer, sellerAvatarAddress, out _, out var avatarState))
            {
                return(states);
            }
            sw.Stop();
            Log.Debug($"Sell Cancel Get AgentAvatarStates: {sw.Elapsed}");
            sw.Restart();

            if (!avatarState.worldInformation.TryGetUnlockedWorldByStageClearedBlockIndex(
                    out var world))
            {
                return(states);
            }

            if (world.StageClearedId < GameConfig.RequireClearedStageLevel.ActionsInShop)
            {
                // 스테이지 클리어 부족 에러.
                return(states);
            }

            if (!states.TryGetState(ShopState.Address, out Bencodex.Types.Dictionary d))
            {
                return(states);
            }
            var shopState = new ShopState(d);

            sw.Stop();
            Log.Debug($"Sell Cancel Get ShopState: {sw.Elapsed}");
            sw.Restart();

            // 상점에서 아이템을 빼온다.
            if (!shopState.TryUnregister(ctx.Signer, productId, out var outUnregisteredItem))
            {
                return(states);
            }

            sw.Stop();
            Log.Debug($"Sell Cancel Get Unregister Item: {sw.Elapsed}");
            sw.Restart();

            //9c-beta 브랜치에서는 블록 인덱스도 확인 해야함 (이전 블록 유효성 보장)
            if (outUnregisteredItem.SellerAvatarAddress != sellerAvatarAddress)
            {
                Log.Error("Invalid Avatar Address");
                return(states);
            }

            // 메일에 아이템을 넣는다.
            result = new Result
            {
                shopItem   = outUnregisteredItem,
                itemUsable = outUnregisteredItem.ItemUsable
            };
            var mail = new SellCancelMail(result, ctx.BlockIndex, ctx.Random.GenerateRandomGuid(), ctx.BlockIndex);

            result.id = mail.id;

            avatarState.Update(mail);
            avatarState.UpdateFromAddItem(result.itemUsable, true);
            avatarState.updatedAt  = DateTimeOffset.UtcNow;
            avatarState.blockIndex = ctx.BlockIndex;
            sw.Stop();
            Log.Debug($"Sell Cancel Update AvatarState: {sw.Elapsed}");
            sw.Restart();

            states = states.SetState(sellerAvatarAddress, avatarState.Serialize());
            sw.Stop();
            Log.Debug($"Sell Cancel Set AvatarState: {sw.Elapsed}");
            sw.Restart();

            states = states.SetState(ShopState.Address, shopState.Serialize());
            sw.Stop();
            var ended = DateTimeOffset.UtcNow;

            Log.Debug($"Sell Cancel Set ShopState: {sw.Elapsed}");
            Log.Debug($"Sell Cancel Total Executed Time: {ended - started}");
            return(states);
        }