public void SerializeCombinationSlotStateWithResult() { var address = new PrivateKey().PublicKey.ToAddress(); var state = new CombinationSlotState(address, 1); var item = ItemFactory.CreateItemUsable(_tableSheets.EquipmentItemSheet.Values.First(), Guid.Empty, default); var result = new CombinationConsumable.ResultModel { actionPoint = 1, gold = 1, materials = new Dictionary <Nekoyume.Model.Item.Material, int>(), itemUsable = item }; state.Update(result, 1, 10); var serialized = (Dictionary)state.Serialize(); Assert.IsTrue(serialized.ContainsKey((IKey)(Text)"address")); Assert.IsTrue(serialized.ContainsKey((IKey)(Text)"unlockBlockIndex")); Assert.IsTrue(serialized.ContainsKey((IKey)(Text)"unlockStage")); Assert.IsTrue(serialized.ContainsKey((IKey)(Text)"result")); Assert.IsTrue(serialized.ContainsKey((IKey)(Text)"startBlockIndex")); var deserialize = new CombinationSlotState(serialized); Assert.AreEqual(state.UnlockStage, deserialize.UnlockStage); Assert.AreEqual(state.UnlockBlockIndex, deserialize.UnlockBlockIndex); Assert.AreEqual(state.address, deserialize.address); Assert.AreEqual(state.Result.itemUsable, deserialize.Result.itemUsable); Assert.AreEqual(state.StartBlockIndex, deserialize.StartBlockIndex); }
public HackAndSlash10Test() { _sheets = TableSheetsImporter.ImportSheets(); _tableSheets = new TableSheets(_sheets); var privateKey = new PrivateKey(); _agentAddress = privateKey.PublicKey.ToAddress(); var agentState = new AgentState(_agentAddress); _avatarAddress = _agentAddress.Derive("avatar"); var gameConfigState = new GameConfigState(_sheets[nameof(GameConfigSheet)]); _rankingMapAddress = _avatarAddress.Derive("ranking_map"); _avatarState = new AvatarState( _avatarAddress, _agentAddress, 0, _tableSheets.GetAvatarSheets(), gameConfigState, _rankingMapAddress ) { level = 100, }; _inventoryAddress = _avatarAddress.Derive(LegacyInventoryKey); _worldInformationAddress = _avatarAddress.Derive(LegacyWorldInformationKey); _questListAddress = _avatarAddress.Derive(LegacyQuestListKey); agentState.avatarAddresses.Add(0, _avatarAddress); _weeklyArenaState = new WeeklyArenaState(0); _initialState = new State() .SetState(_weeklyArenaState.address, _weeklyArenaState.Serialize()) .SetState(_agentAddress, agentState.SerializeV2()) .SetState(_avatarAddress, _avatarState.SerializeV2()) .SetState(_inventoryAddress, _avatarState.inventory.Serialize()) .SetState(_worldInformationAddress, _avatarState.worldInformation.Serialize()) .SetState(_questListAddress, _avatarState.questList.Serialize()) .SetState(_rankingMapAddress, new RankingMapState(_rankingMapAddress).Serialize()) .SetState(gameConfigState.address, gameConfigState.Serialize()); foreach (var(key, value) in _sheets) { _initialState = _initialState .SetState(Addresses.TableSheet.Derive(key), value.Serialize()); } foreach (var address in _avatarState.combinationSlotAddresses) { var slotState = new CombinationSlotState( address, GameConfig.RequireClearedStageLevel.CombinationEquipmentAction); _initialState = _initialState.SetState(address, slotState.Serialize()); } }
public void SerializeCombinationSlotStateWithOutResult() { var address = new PrivateKey().PublicKey.ToAddress(); var state = new CombinationSlotState(address, 1); var serialized = (Dictionary)state.Serialize(); Assert.IsTrue(serialized.ContainsKey((IKey)(Text)"address")); Assert.IsTrue(serialized.ContainsKey((IKey)(Text)"unlockBlockIndex")); Assert.IsTrue(serialized.ContainsKey((IKey)(Text)"unlockStage")); Assert.IsFalse(serialized.ContainsKey((IKey)(Text)"result")); var deserialize = new CombinationSlotState(serialized); Assert.AreEqual(state.UnlockStage, deserialize.UnlockStage); Assert.AreEqual(state.UnlockBlockIndex, deserialize.UnlockBlockIndex); Assert.AreEqual(state.address, deserialize.address); }
public override IAccountStateDelta Execute(IActionContext context) { IActionContext ctx = context; var states = ctx.PreviousStates; var avatarAddress = ctx.Signer.Derive( string.Format( CultureInfo.InvariantCulture, DeriveFormat, index ) ); if (ctx.Rehearsal) { states = states.SetState(ctx.Signer, MarkChanged); for (var i = 0; i < AvatarState.CombinationSlotCapacity; i++) { var slotAddress = avatarAddress.Derive( string.Format( CultureInfo.InvariantCulture, CombinationSlotState.DeriveFormat, i ) ); states = states.SetState(slotAddress, MarkChanged); } return(states .SetState(avatarAddress, MarkChanged) .SetState(Addresses.Ranking, MarkChanged) .MarkBalanceChanged(GoldCurrencyMock, GoldCurrencyState.Address, context.Signer)); } CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context); var addressesHex = GetSignerAndOtherAddressesHex(context, avatarAddress); if (!Regex.IsMatch(name, GameConfig.AvatarNickNamePattern)) { throw new InvalidNamePatternException( $"{addressesHex}Aborted as the input name {name} does not follow the allowed name pattern."); } var sw = new Stopwatch(); sw.Start(); var started = DateTimeOffset.UtcNow; Log.Verbose("{AddressesHex}CreateAvatar exec started", addressesHex); AgentState existingAgentState = states.GetAgentState(ctx.Signer); var agentState = existingAgentState ?? new AgentState(ctx.Signer); var avatarState = states.GetAvatarState(avatarAddress); if (!(avatarState is null)) { throw new InvalidAddressException( $"{addressesHex}Aborted as there is already an avatar at {avatarAddress}."); } if (!(0 <= index && index < GameConfig.SlotCount)) { throw new AvatarIndexOutOfRangeException( $"{addressesHex}Aborted as the index is out of range #{index}."); } if (agentState.avatarAddresses.ContainsKey(index)) { throw new AvatarIndexAlreadyUsedException( $"{addressesHex}Aborted as the signer already has an avatar at index #{index}."); } sw.Stop(); Log.Verbose("{AddressesHex}CreateAvatar Get AgentAvatarStates: {Elapsed}", addressesHex, sw.Elapsed); sw.Restart(); Log.Verbose("{AddressesHex}Execute CreateAvatar; player: {AvatarAddress}", addressesHex, avatarAddress); agentState.avatarAddresses.Add(index, avatarAddress); // Avoid NullReferenceException in test var materialItemSheet = ctx.PreviousStates.GetSheet <MaterialItemSheet>(); var rankingState = ctx.PreviousStates.GetRankingState(); var rankingMapAddress = rankingState.UpdateRankingMap(avatarAddress); avatarState = CreateAvatar0.CreateAvatarState(name, avatarAddress, ctx, materialItemSheet, rankingMapAddress); if (hair < 0) { hair = 0; } if (lens < 0) { lens = 0; } if (ear < 0) { ear = 0; } if (tail < 0) { tail = 0; } avatarState.Customize(hair, lens, ear, tail); foreach (var address in avatarState.combinationSlotAddresses) { var slotState = new CombinationSlotState(address, GameConfig.RequireClearedStageLevel.CombinationEquipmentAction); states = states.SetState(address, slotState.Serialize()); } avatarState.UpdateQuestRewards2(materialItemSheet); sw.Stop(); Log.Verbose("{AddressesHex}CreateAvatar CreateAvatarState: {Elapsed}", addressesHex, sw.Elapsed); var ended = DateTimeOffset.UtcNow; Log.Verbose("{AddressesHex}CreateAvatar Total Executed Time: {Elapsed}", addressesHex, ended - started); return(states .SetState(ctx.Signer, agentState.Serialize()) .SetState(Addresses.Ranking, rankingState.Serialize()) .SetState(avatarAddress, avatarState.Serialize())); }
public CombinationAndRapidCombinationTest(ITestOutputHelper outputHelper) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.TestOutput(outputHelper) .CreateLogger(); var sheets = TableSheetsImporter.ImportSheets(); _tableSheets = new TableSheets(sheets); var gold = new GoldCurrencyState(new Currency("NCG", 2, minter: null)); var gameConfigState = new GameConfigState(sheets[nameof(GameConfigSheet)]); _agentAddress = new PrivateKey().ToAddress(); _avatarAddress = _agentAddress.Derive("avatar"); _slot0Address = _avatarAddress.Derive( string.Format( CultureInfo.InvariantCulture, CombinationSlotState.DeriveFormat, 0 ) ); var slot0State = new CombinationSlotState( _slot0Address, GameConfig.RequireClearedStageLevel.CombinationEquipmentAction); var agentState = new AgentState(_agentAddress); agentState.avatarAddresses[0] = _avatarAddress; var avatarState = new AvatarState( _avatarAddress, _agentAddress, 1, _tableSheets.GetAvatarSheets(), gameConfigState, default ) { worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, GameConfig.RequireClearedStageLevel.CombinationEquipmentAction), }; _inventoryAddress = _avatarAddress.Derive(LegacyInventoryKey); _worldInformationAddress = _avatarAddress.Derive(LegacyWorldInformationKey); _questListAddress = _avatarAddress.Derive(LegacyQuestListKey); _initialState = new Tests.Action.State() .SetState(GoldCurrencyState.Address, gold.Serialize()) .SetState(gameConfigState.address, gameConfigState.Serialize()) .SetState(_agentAddress, agentState.Serialize()) .SetState(_avatarAddress, avatarState.SerializeV2()) .SetState(_inventoryAddress, avatarState.inventory.Serialize()) .SetState(_worldInformationAddress, avatarState.worldInformation.Serialize()) .SetState(_questListAddress, avatarState.questList.Serialize()) .SetState(_slot0Address, slot0State.Serialize()); foreach (var(key, value) in sheets) { _initialState = _initialState .SetState(Addresses.TableSheet.Derive(key), value.Serialize()); } }
public override IAccountStateDelta Execute(IActionContext context) { var data = TestbedHelper.LoadData <TestbedSell>("TestbedSell"); var addedItemInfos = data.Items .Select(item => new TestbedHelper.AddedItemInfo( context.Random.GenerateRandomGuid(), context.Random.GenerateRandomGuid())) .ToList(); var agentAddress = _privateKey.PublicKey.ToAddress(); var states = context.PreviousStates; var avatarAddress = agentAddress.Derive( string.Format( CultureInfo.InvariantCulture, CreateAvatar.DeriveFormat, _slotIndex ) ); var inventoryAddress = avatarAddress.Derive(LegacyInventoryKey); var worldInformationAddress = avatarAddress.Derive(LegacyWorldInformationKey); var questListAddress = avatarAddress.Derive(LegacyQuestListKey); var orderReceiptAddress = OrderDigestListState.DeriveAddress(avatarAddress); if (context.Rehearsal) { states = states.SetState(agentAddress, MarkChanged); for (var i = 0; i < AvatarState.CombinationSlotCapacity; i++) { var slotAddress = avatarAddress.Derive( string.Format(CultureInfo.InvariantCulture, CombinationSlotState.DeriveFormat, i)); states = states.SetState(slotAddress, MarkChanged); } states = states.SetState(avatarAddress, MarkChanged) .SetState(Addresses.Ranking, MarkChanged) .SetState(worldInformationAddress, MarkChanged) .SetState(questListAddress, MarkChanged) .SetState(inventoryAddress, MarkChanged); for (var i = 0; i < data.Items.Length; i++) { var itemAddress = Addresses.GetItemAddress(addedItemInfos[i].TradableId); var orderAddress = Order.DeriveAddress(addedItemInfos[i].OrderId); var shopAddress = ShardedShopStateV2.DeriveAddress( data.Items[i].ItemSubType, addedItemInfos[i].OrderId); states = states.SetState(avatarAddress, MarkChanged) .SetState(inventoryAddress, MarkChanged) .MarkBalanceChanged(GoldCurrencyMock, agentAddress, GoldCurrencyState.Address) .SetState(orderReceiptAddress, MarkChanged) .SetState(itemAddress, MarkChanged) .SetState(orderAddress, MarkChanged) .SetState(shopAddress, MarkChanged); } return(states); } // Create Agent and avatar var existingAgentState = states.GetAgentState(agentAddress); var agentState = existingAgentState ?? new AgentState(agentAddress); var avatarState = states.GetAvatarState(avatarAddress); if (!(avatarState is null)) { throw new InvalidAddressException( $"Aborted as there is already an avatar at {avatarAddress}."); } if (agentState.avatarAddresses.ContainsKey(_slotIndex)) { throw new AvatarIndexAlreadyUsedException( $"borted as the signer already has an avatar at index #{_slotIndex}."); } agentState.avatarAddresses.Add(_slotIndex, avatarAddress); var rankingState = context.PreviousStates.GetRankingState(); var rankingMapAddress = rankingState.UpdateRankingMap(avatarAddress); avatarState = TestbedHelper.CreateAvatarState(data.avatar.Name, agentAddress, avatarAddress, context.BlockIndex, context.PreviousStates.GetAvatarSheets(), context.PreviousStates.GetSheet <WorldSheet>(), context.PreviousStates.GetGameConfigState(), rankingMapAddress); // Add item var costumeItemSheet = context.PreviousStates.GetSheet <CostumeItemSheet>(); var equipmentItemSheet = context.PreviousStates.GetSheet <EquipmentItemSheet>(); var optionSheet = context.PreviousStates.GetSheet <EquipmentItemOptionSheet>(); var skillSheet = context.PreviousStates.GetSheet <SkillSheet>(); var materialItemSheet = context.PreviousStates.GetSheet <MaterialItemSheet>(); var consumableItemSheet = context.PreviousStates.GetSheet <ConsumableItemSheet>(); for (var i = 0; i < data.Items.Length; i++) { TestbedHelper.AddItem(costumeItemSheet, equipmentItemSheet, optionSheet, skillSheet, materialItemSheet, consumableItemSheet, context.Random, data.Items[i], addedItemInfos[i], avatarState); } avatarState.Customize(0, 0, 0, 0); foreach (var address in avatarState.combinationSlotAddresses) { var slotState = new CombinationSlotState(address, GameConfig.RequireClearedStageLevel.CombinationEquipmentAction); states = states.SetState(address, slotState.Serialize()); } avatarState.UpdateQuestRewards(materialItemSheet); states = states.SetState(agentAddress, agentState.Serialize()) .SetState(Addresses.Ranking, rankingState.Serialize()) .SetState(inventoryAddress, avatarState.inventory.Serialize()) .SetState(worldInformationAddress, avatarState.worldInformation.Serialize()) .SetState(questListAddress, avatarState.questList.Serialize()) .SetState(avatarAddress, avatarState.SerializeV2()); // for sell for (var i = 0; i < data.Items.Length; i++) { var itemAddress = Addresses.GetItemAddress(addedItemInfos[i].TradableId); var orderAddress = Order.DeriveAddress(addedItemInfos[i].OrderId); var shopAddress = ShardedShopStateV2.DeriveAddress( data.Items[i].ItemSubType, addedItemInfos[i].OrderId); var balance = context.PreviousStates.GetBalance(agentAddress, states.GetGoldCurrency()); var price = new FungibleAssetValue(balance.Currency, data.Items[i].Price, 0); var order = OrderFactory.Create(agentAddress, avatarAddress, addedItemInfos[i].OrderId, price, addedItemInfos[i].TradableId, context.BlockIndex, data.Items[i].ItemSubType, data.Items[i].Count); Orders.Add(order); order.Validate(avatarState, data.Items[i].Count); var tradableItem = order.Sell(avatarState); var shardedShopState = states.TryGetState(shopAddress, out Dictionary serializedState) ? new ShardedShopStateV2(serializedState) : new ShardedShopStateV2(shopAddress); var costumeStatSheet = states.GetSheet <CostumeStatSheet>(); var orderDigest = order.Digest(avatarState, costumeStatSheet); shardedShopState.Add(orderDigest, context.BlockIndex); var orderReceiptList = states.TryGetState(orderReceiptAddress, out Dictionary receiptDict) ? new OrderDigestListState(receiptDict) : new OrderDigestListState(orderReceiptAddress); orderReceiptList.Add(orderDigest); states = states.SetState(orderReceiptAddress, orderReceiptList.Serialize()) .SetState(inventoryAddress, avatarState.inventory.Serialize()) .SetState(avatarAddress, avatarState.SerializeV2()) .SetState(itemAddress, tradableItem.Serialize()) .SetState(orderAddress, order.Serialize()) .SetState(shopAddress, shardedShopState.Serialize()); } result.SellerAgentAddress = agentAddress; result.SellerAvatarAddress = avatarAddress; result.ItemInfos = new List <ItemInfos>(); for (var i = 0; i < data.Items.Length; i++) { result.ItemInfos.Add(new ItemInfos( addedItemInfos[i].OrderId, addedItemInfos[i].TradableId, data.Items[i].ItemSubType, data.Items[i].Price, data.Items[i].Count)); } return(states); }
public override IAccountStateDelta Execute(IActionContext context) { IActionContext ctx = context; var states = ctx.PreviousStates; if (ctx.Rehearsal) { states = states.SetState(ctx.Signer, MarkChanged); for (var i = 0; i < AvatarState.CombinationSlotCapacity; i++) { var slotAddress = avatarAddress.Derive( string.Format( CultureInfo.InvariantCulture, CombinationSlotState.DeriveFormat, i ) ); states = states.SetState(slotAddress, MarkChanged); } return(states .SetState(avatarAddress, MarkChanged) .MarkBalanceChanged(GoldCurrencyMock, GoldCurrencyState.Address, context.Signer)); } if (!Regex.IsMatch(name, GameConfig.AvatarNickNamePattern)) { return(LogError( context, "Aborted as the input name {@Name} does not follow the allowed name pattern.", name )); } var sw = new Stopwatch(); sw.Start(); var started = DateTimeOffset.UtcNow; Log.Debug("CreateAvatar exec started."); AgentState existingAgentState = states.GetAgentState(ctx.Signer); var agentState = existingAgentState ?? new AgentState(ctx.Signer); var avatarState = states.GetAvatarState(avatarAddress); if (!(avatarState is null)) { return(LogError(context, "Aborted as there is already an avatar at {Address}.", avatarAddress)); } if (agentState.avatarAddresses.ContainsKey(index)) { return(LogError(context, "Aborted as the signer already has an avatar at index #{Index}.", index)); } sw.Stop(); Log.Debug("CreateAvatar Get AgentAvatarStates: {Elapsed}", sw.Elapsed); sw.Restart(); if (existingAgentState is null) { // 첫 아바타 생성이면 계정당 기본 소지금 부여. states = states.TransferAsset( GoldCurrencyState.Address, ctx.Signer, states.GetGoldCurrency(), InitialGoldBalance ); } Log.Debug("Execute CreateAvatar; player: {AvatarAddress}", avatarAddress); agentState.avatarAddresses.Add(index, avatarAddress); // Avoid NullReferenceException in test avatarState = CreateAvatarState(name, avatarAddress, ctx); if (hair < 0) { hair = 0; } if (lens < 0) { lens = 0; } if (ear < 0) { ear = 0; } if (tail < 0) { tail = 0; } avatarState.Customize(hair, lens, ear, tail); foreach (var address in avatarState.combinationSlotAddresses) { var slotState = new CombinationSlotState(address, GameConfig.RequireClearedStageLevel.CombinationEquipmentAction); states = states.SetState(address, slotState.Serialize()); } avatarState.UpdateQuestRewards(ctx); sw.Stop(); Log.Debug("CreateAvatar CreateAvatarState: {Elapsed}", sw.Elapsed); var ended = DateTimeOffset.UtcNow; Log.Debug("CreateAvatar Total Executed Time: {Elapsed}", ended - started); return(states .SetState(ctx.Signer, agentState.Serialize()) .SetState(avatarAddress, avatarState.Serialize())); }