public static AvatarState CreateAvatarState(string name, Address avatarAddress, IActionContext ctx, MaterialItemSheet materialItemSheet, Address rankingMapAddress) { var state = ctx.PreviousStates; var gameConfigState = state.GetGameConfigState(); var avatarState = new AvatarState( avatarAddress, ctx.Signer, ctx.BlockIndex, state.GetAvatarSheets(), gameConfigState, rankingMapAddress, name ); #if LIB9C_DEV_EXTENSIONS || UNITY_EDITOR var data = TestbedHelper.LoadData <TestbedCreateAvatar>("TestbedCreateAvatar"); var costumeItemSheet = ctx.PreviousStates.GetSheet <CostumeItemSheet>(); var equipmentItemSheet = ctx.PreviousStates.GetSheet <EquipmentItemSheet>(); AddItemsForTest( avatarState: avatarState, random: ctx.Random, costumeItemSheet: costumeItemSheet, materialItemSheet: materialItemSheet, equipmentItemSheet: equipmentItemSheet, data.MaterialCount, data.TradableMaterialCount); var skillSheet = ctx.PreviousStates.GetSheet <SkillSheet>(); var optionSheet = ctx.PreviousStates.GetSheet <EquipmentItemOptionSheet>(); var items = data.CustomEquipmentItems; foreach (var item in items) { AddCustomEquipment( avatarState: avatarState, random: ctx.Random, skillSheet: skillSheet, equipmentItemSheet: equipmentItemSheet, equipmentItemOptionSheet: optionSheet, // Set level of equipment here. level: item.Level, // Set recipeId of target equipment here. recipeId: item.ID, // Add optionIds here. item.OptionIds); } #endif return(avatarState); }
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); }
/// <summary> /// Gets a <see cref="BlockPolicy"/> constructed from given parameters. /// </summary> /// <param name="minimumDifficulty">The minimum difficulty that a <see cref="Block{T}"/> /// can have. This is ignored for genesis blocks.</param> /// <param name="minTransactionsPerBlockPolicy">Used for minimum number of transactions /// required per block.</param> /// <param name="maxTransactionsPerBlockPolicy">The maximum number of /// <see cref="Transaction{T}"/>s that a <see cref="Block{T}"/> can have.</param> /// <param name="maxTransactionsPerSignerPerBlockPolicy">The maximum number of /// <see cref="Transaction{T}"/>s from a single miner that a <see cref="Block{T}"/> /// can have.</param> /// <param name="authorizedMinersPolicy">Used for authorized mining.</param> /// <param name="permissionedMinersPolicy">Used for permissioned mining.</param> /// <returns>A <see cref="BlockPolicy"/> constructed from given parameters.</returns> internal IBlockPolicy <NCAction> GetPolicy( long minimumDifficulty, IVariableSubPolicy <HashAlgorithmType> hashAlgorithmTypePolicy, IVariableSubPolicy <long> maxBlockBytesPolicy, IVariableSubPolicy <int> minTransactionsPerBlockPolicy, IVariableSubPolicy <int> maxTransactionsPerBlockPolicy, IVariableSubPolicy <int> maxTransactionsPerSignerPerBlockPolicy, IVariableSubPolicy <ImmutableHashSet <Address> > authorizedMinersPolicy, IVariableSubPolicy <ImmutableHashSet <Address> > permissionedMinersPolicy) { #if LIB9C_DEV_EXTENSIONS || UNITY_EDITOR var data = TestbedHelper.LoadData <TestbedCreateAvatar>("TestbedCreateAvatar"); return(new DebugPolicy(data.BlockDifficulty)); #else hashAlgorithmTypePolicy = hashAlgorithmTypePolicy ?? HashAlgorithmTypePolicy.Default; maxBlockBytesPolicy = maxBlockBytesPolicy ?? MaxBlockBytesPolicy.Default; minTransactionsPerBlockPolicy = minTransactionsPerBlockPolicy ?? MinTransactionsPerBlockPolicy.Default; maxTransactionsPerBlockPolicy = maxTransactionsPerBlockPolicy ?? MaxTransactionsPerBlockPolicy.Default; maxTransactionsPerSignerPerBlockPolicy = maxTransactionsPerSignerPerBlockPolicy ?? MaxTransactionsPerSignerPerBlockPolicy.Default; authorizedMinersPolicy = authorizedMinersPolicy ?? AuthorizedMinersPolicy.Default; permissionedMinersPolicy = permissionedMinersPolicy ?? PermissionedMinersPolicy.Default; // FIXME: Ad hoc solution to poorly defined tx validity. ImmutableHashSet <Address> allAuthorizedMiners = authorizedMinersPolicy.SpannedSubPolicies .Select(spannedSubPolicy => spannedSubPolicy.Value) #pragma warning disable LAA1002 .Aggregate( authorizedMinersPolicy.DefaultValue, (union, next) => union.Union(next)); #pragma warning restore LAA1002 Func <BlockChain <NCAction>, Transaction <NCAction>, TxPolicyViolationException> validateNextBlockTx = (blockChain, transaction) => ValidateNextBlockTxRaw( blockChain, transaction, allAuthorizedMiners); Func <BlockChain <NCAction>, Block <NCAction>, BlockPolicyViolationException> validateNextBlock = (blockChain, block) => ValidateNextBlockRaw( blockChain, block, hashAlgorithmTypePolicy, maxBlockBytesPolicy, minTransactionsPerBlockPolicy, maxTransactionsPerBlockPolicy, maxTransactionsPerSignerPerBlockPolicy, authorizedMinersPolicy, permissionedMinersPolicy); Func <BlockChain <NCAction>, long> getNextBlockDifficulty = blockChain => GetNextBlockDifficultyRaw( blockChain, BlockInterval, DifficultyStability, minimumDifficulty, authorizedMinersPolicy, defaultAlgorithm: chain => DifficultyAdjustment <NCAction> .BaseAlgorithm( chain, BlockInterval, DifficultyStability, minimumDifficulty)); Func <Address, long, bool> isAllowedToMine = (address, index) => IsAllowedToMineRaw( address, index, authorizedMinersPolicy, permissionedMinersPolicy); // FIXME: Slight inconsistency due to pre-existing delegate. HashAlgorithmGetter getHashAlgorithmType = index => hashAlgorithmTypePolicy.Getter(index); return(new BlockPolicy( new RewardGold(), blockInterval: BlockInterval, difficultyStability: DifficultyStability, minimumDifficulty: minimumDifficulty, canonicalChainComparer: new TotalDifficultyComparer(), hashAlgorithmGetter: getHashAlgorithmType, validateNextBlockTx: validateNextBlockTx, validateNextBlock: validateNextBlock, getMaxBlockBytes: maxBlockBytesPolicy.Getter, getMinTransactionsPerBlock: minTransactionsPerBlockPolicy.Getter, getMaxTransactionsPerBlock: maxTransactionsPerBlockPolicy.Getter, getMaxTransactionsPerSignerPerBlock: maxTransactionsPerSignerPerBlockPolicy.Getter, getNextBlockDifficulty: getNextBlockDifficulty, isAllowedToMine: isAllowedToMine)); #endif }