Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        /// <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
        }