public void RegisterThrowShopStateAlreadyContainsException() { 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); Assert.Throws <ShopStateAlreadyContainsException>(() => shopState.Register(shopItem)); }
public void TryGet() { 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); Assert.True(shopState.TryGet(agentAddress, shopItem.ProductId, out var outShopItem)); Assert.Equal(shopItem, outShopItem); shopState.Unregister(shopItem); Assert.False(shopState.TryGet(agentAddress, shopItem.ProductId, out _)); }
public void Register() { 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); Assert.Equal(1, shopState.Products.Count); Assert.Contains(productId, shopState.Products); Assert.Equal(shopItem, shopState.Products[productId]); }
public void Unregister() { 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, itemUsable, price ); shopState.Register(shopItem); shopState.Unregister(agentAddress, shopItem); Assert.Equal(0, shopState.Products.Count); Assert.Equal(0, shopState.AgentProducts.Count); Assert.Equal(0, shopState.ItemSubTypeProducts.Count); Assert.Throws <FailedToUnregisterInShopStateException>(() => shopState.Unregister(agentAddress, shopItem)); }
public SellCancellation2Test(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()); } var tableSheets = new TableSheets(sheets); var currency = new Currency("NCG", 2, minters: null); var goldCurrencyState = new GoldCurrencyState(currency); _agentAddress = new PrivateKey().ToAddress(); var agentState = new AgentState(_agentAddress); _avatarAddress = new PrivateKey().ToAddress(); var rankingMapAddress = new PrivateKey().ToAddress(); var 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); var shopState = new ShopState(); shopState.Register(new ShopItem( _agentAddress, _avatarAddress, Guid.NewGuid(), new FungibleAssetValue(goldCurrencyState.Currency, 100, 0), equipment)); var result = new CombinationConsumable.ResultModel() { id = default,
public void Register() { 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, itemUsable, price ); shopState.Register(shopItem); Assert.Equal(1, shopState.Products.Count); Assert.Contains(productId, shopState.Products); Assert.Equal(shopItem, shopState.Products[productId]); Assert.Equal(1, shopState.AgentProducts.Count); Assert.True(shopState.AgentProducts.ContainsKey(agentAddress)); Assert.Single(shopState.AgentProducts[agentAddress]); Assert.Contains(productId, shopState.AgentProducts[agentAddress]); Assert.Equal(1, shopState.ItemSubTypeProducts.Count); Assert.Contains(ItemSubType.Weapon, shopState.ItemSubTypeProducts); Assert.Single(shopState.ItemSubTypeProducts[ItemSubType.Weapon]); Assert.Contains(productId, shopState.ItemSubTypeProducts[ItemSubType.Weapon]); Assert.Throws <ShopStateAlreadyContainsException>(() => shopState.Register(shopItem)); }
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)); }
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); }
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, })); } }