public void Serialize_DotNet_API() { Guid guid = new Guid("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4"); Address address = new Address("8d9f76aF8Dc5A812aCeA15d8bf56E2F790F47fd7"); List <MonsterCollectionRewardSheet.RewardInfo> rewards = _tableSheets.MonsterCollectionRewardSheet.First !.Rewards; Assert.Single(rewards); MonsterCollectionResult result = new MonsterCollectionResult(guid, address, rewards); MonsterCollectionMail mail = new MonsterCollectionMail(result, 1, guid, 2); BinaryFormatter formatter = new BinaryFormatter(); using MemoryStream ms = new MemoryStream(); formatter.Serialize(ms, mail); ms.Seek(0, SeekOrigin.Begin); MonsterCollectionMail deserialized = (MonsterCollectionMail)formatter.Deserialize(ms); Assert.Equal(1, deserialized.blockIndex); Assert.Equal(2, deserialized.requiredBlockIndex); Assert.Equal(guid, deserialized.id); MonsterCollectionResult attachment = (MonsterCollectionResult)deserialized.attachment; Assert.Single(attachment.rewards); Assert.Equal(rewards.First(), attachment.rewards.First()); }
public void Execute_Throw_RequiredBlockIndexException(long startedBlockIndex, long blockIndex) { Address collectionAddress = MonsterCollectionState0.DeriveAddress(_signer, 0); MonsterCollectionState0 monsterCollectionState = new MonsterCollectionState0(collectionAddress, 1, startedBlockIndex, _tableSheets.MonsterCollectionRewardSheet); List <MonsterCollectionRewardSheet.RewardInfo> rewards = _tableSheets.MonsterCollectionRewardSheet[1].Rewards; MonsterCollectionResult result = new MonsterCollectionResult(Guid.NewGuid(), _avatarAddress, rewards); monsterCollectionState.UpdateRewardMap(1, result, 0); _state = _state.SetState(collectionAddress, monsterCollectionState.Serialize()); ClaimMonsterCollectionReward0 action = new ClaimMonsterCollectionReward0 { avatarAddress = _avatarAddress, collectionRound = 0, }; Assert.Throws <RequiredBlockIndexException>(() => action.Execute(new ActionContext { PreviousStates = _state, Signer = _signer, BlockIndex = blockIndex, }) ); }
public void UpdateRewardMap_Throw_ArgumentOutOfRangeException(long rewardLevel) { MonsterCollectionState0 monsterCollectionState = new MonsterCollectionState0(_address, 1, 10000, _tableSheets.MonsterCollectionRewardSheet); List <MonsterCollectionRewardSheet.RewardInfo> rewards = _tableSheets.MonsterCollectionRewardSheet[1].Rewards; MonsterCollectionResult result = new MonsterCollectionResult(Guid.NewGuid(), _address, rewards); Assert.Throws <ArgumentOutOfRangeException>(() => monsterCollectionState.UpdateRewardMap(rewardLevel, result, 0)); }
public void UpdateRewardMap() { MonsterCollectionState0 monsterCollectionState = new MonsterCollectionState0(_address, 1, 10000, _tableSheets.MonsterCollectionRewardSheet); Assert.Empty(monsterCollectionState.RewardMap); Address avatarAddress = default; List <MonsterCollectionRewardSheet.RewardInfo> rewards = _tableSheets.MonsterCollectionRewardSheet[1].Rewards; MonsterCollectionResult result = new MonsterCollectionResult(Guid.NewGuid(), avatarAddress, rewards); monsterCollectionState.UpdateRewardMap(1, result, 14000); Assert.Single(monsterCollectionState.RewardMap); Assert.Equal(result, monsterCollectionState.RewardMap[1]); Assert.Equal(14000, monsterCollectionState.ReceivedBlockIndex); Assert.Equal(1, monsterCollectionState.RewardLevel); }
public void Serialize() { Guid guid = new Guid("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4"); Address address = new Address("8d9f76aF8Dc5A812aCeA15d8bf56E2F790F47fd7"); List <MonsterCollectionRewardSheet.RewardInfo> rewards = _tableSheets.MonsterCollectionRewardSheet.First !.Rewards; Assert.Single(rewards); MonsterCollectionResult result = new MonsterCollectionResult(guid, address, rewards); MonsterCollectionMail mail = new MonsterCollectionMail(result, 1, guid, 2); Dictionary serialized = (Dictionary)mail.Serialize(); MonsterCollectionMail deserialized = new MonsterCollectionMail(serialized); Assert.Equal(1, deserialized.blockIndex); Assert.Equal(2, deserialized.requiredBlockIndex); Assert.Equal(guid, deserialized.id); MonsterCollectionResult attachment = (MonsterCollectionResult)deserialized.attachment; Assert.Single(attachment.rewards); Assert.Equal(rewards.First(), attachment.rewards.First()); }
public void Execute(int rewardLevel, int prevRewardLevel, int collectionLevel) { Address collectionAddress = MonsterCollectionState0.DeriveAddress(_signer, 0); List <MonsterCollectionRewardSheet.RewardInfo> rewards = _tableSheets.MonsterCollectionRewardSheet[1].Rewards; MonsterCollectionState0 monsterCollectionState = new MonsterCollectionState0(collectionAddress, 1, 0, _tableSheets.MonsterCollectionRewardSheet); for (int i = 0; i < prevRewardLevel; i++) { int level = i + 1; MonsterCollectionResult result = new MonsterCollectionResult(Guid.NewGuid(), _avatarAddress, rewards); monsterCollectionState.UpdateRewardMap(level, result, i * MonsterCollectionState0.RewardInterval); } List <MonsterCollectionRewardSheet.RewardInfo> collectionRewards = _tableSheets.MonsterCollectionRewardSheet[collectionLevel].Rewards; monsterCollectionState.Update(collectionLevel, rewardLevel, _tableSheets.MonsterCollectionRewardSheet); for (long i = rewardLevel; i < 4; i++) { Assert.Equal(collectionRewards, monsterCollectionState.RewardLevelMap[i + 1]); } Dictionary <int, int> rewardExpectedMap = new Dictionary <int, int>(); foreach (var(key, value) in monsterCollectionState.RewardLevelMap) { if (monsterCollectionState.RewardMap.ContainsKey(key) || key > rewardLevel) { continue; } foreach (var info in value) { if (rewardExpectedMap.ContainsKey(info.ItemId)) { rewardExpectedMap[info.ItemId] += info.Quantity; } else { rewardExpectedMap[info.ItemId] = info.Quantity; } } } AvatarState prevAvatarState = _state.GetAvatarState(_avatarAddress); Assert.Empty(prevAvatarState.mailBox); Currency currency = _state.GetGoldCurrency(); int collectionRound = _state.GetAgentState(_signer).MonsterCollectionRound; _state = _state .SetState(collectionAddress, monsterCollectionState.Serialize()); FungibleAssetValue balance = 0 * currency; if (rewardLevel == 4) { foreach (var row in _tableSheets.MonsterCollectionSheet) { if (row.Level <= collectionLevel) { balance += row.RequiredGold * currency; } } collectionRound += 1; _state = _state .MintAsset(collectionAddress, balance); } Assert.Equal(prevRewardLevel, monsterCollectionState.RewardLevel); Assert.Equal(0, _state.GetAgentState(_signer).MonsterCollectionRound); ClaimMonsterCollectionReward0 action = new ClaimMonsterCollectionReward0 { avatarAddress = _avatarAddress, collectionRound = 0, }; IAccountStateDelta nextState = action.Execute(new ActionContext { PreviousStates = _state, Signer = _signer, BlockIndex = rewardLevel * MonsterCollectionState0.RewardInterval, Random = new TestRandom(), }); MonsterCollectionState0 nextMonsterCollectionState = new MonsterCollectionState0((Dictionary)nextState.GetState(collectionAddress)); Assert.Equal(rewardLevel, nextMonsterCollectionState.RewardLevel); AvatarState nextAvatarState = nextState.GetAvatarState(_avatarAddress); foreach (var(itemId, qty) in rewardExpectedMap) { Assert.True(nextAvatarState.inventory.HasItem(itemId, qty)); } Assert.Equal(rewardLevel - prevRewardLevel, nextAvatarState.mailBox.Count); Assert.All(nextAvatarState.mailBox, mail => { Assert.IsType <MonsterCollectionMail>(mail); MonsterCollectionMail monsterCollectionMail = (MonsterCollectionMail)mail; Assert.IsType <MonsterCollectionResult>(monsterCollectionMail.attachment); MonsterCollectionResult result = (MonsterCollectionResult)monsterCollectionMail.attachment; Assert.Equal(result.id, mail.id); }); for (int i = 0; i < nextMonsterCollectionState.RewardLevel; i++) { int level = i + 1; List <MonsterCollectionRewardSheet.RewardInfo> rewardInfos = _tableSheets.MonsterCollectionRewardSheet[collectionLevel].Rewards; Assert.Contains(level, nextMonsterCollectionState.RewardMap.Keys); Assert.Equal(_avatarAddress, nextMonsterCollectionState.RewardMap[level].avatarAddress); } Assert.Equal(0 * currency, nextState.GetBalance(collectionAddress, currency)); Assert.Equal(balance, nextState.GetBalance(_signer, currency)); Assert.Equal(collectionRound, nextState.GetAgentState(_signer).MonsterCollectionRound); Assert.Equal(nextMonsterCollectionState.End, rewardLevel == 4); }
public override IAccountStateDelta Execute(IActionContext context) { IAccountStateDelta states = context.PreviousStates; Address inventoryAddress = avatarAddress.Derive(LegacyInventoryKey); Address worldInformationAddress = avatarAddress.Derive(LegacyWorldInformationKey); Address questListAddress = avatarAddress.Derive(LegacyQuestListKey); if (context.Rehearsal) { return(states .SetState(avatarAddress, MarkChanged) .SetState(inventoryAddress, MarkChanged) .SetState(worldInformationAddress, MarkChanged) .SetState(questListAddress, MarkChanged) .SetState(MonsterCollectionState.DeriveAddress(context.Signer, 0), MarkChanged) .SetState(MonsterCollectionState.DeriveAddress(context.Signer, 1), MarkChanged) .SetState(MonsterCollectionState.DeriveAddress(context.Signer, 2), MarkChanged) .SetState(MonsterCollectionState.DeriveAddress(context.Signer, 3), MarkChanged)); } CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context); if (!states.TryGetAgentAvatarStatesV2(context.Signer, avatarAddress, out AgentState agentState, out AvatarState avatarState)) { throw new FailedLoadStateException($"Aborted as the avatar state of the signer failed to load."); } Address collectionAddress = MonsterCollectionState.DeriveAddress(context.Signer, agentState.MonsterCollectionRound); if (!states.TryGetState(collectionAddress, out Dictionary stateDict)) { throw new FailedLoadStateException($"Aborted as the monster collection state failed to load."); } var monsterCollectionState = new MonsterCollectionState(stateDict); List <MonsterCollectionRewardSheet.RewardInfo> rewards = monsterCollectionState.CalculateRewards( states.GetSheet <MonsterCollectionRewardSheet>(), context.BlockIndex ); if (rewards.Count == 0) { throw new RequiredBlockIndexException($"{collectionAddress} is not available yet"); } Guid id = context.Random.GenerateRandomGuid(); var result = new MonsterCollectionResult(id, avatarAddress, rewards); var mail = new MonsterCollectionMail(result, context.BlockIndex, id, context.BlockIndex); avatarState.Update(mail); ItemSheet itemSheet = states.GetItemSheet(); foreach (MonsterCollectionRewardSheet.RewardInfo rewardInfo in rewards) { ItemSheet.Row row = itemSheet[rewardInfo.ItemId]; ItemBase item = row is MaterialItemSheet.Row materialRow ? ItemFactory.CreateTradableMaterial(materialRow) : ItemFactory.CreateItem(row, context.Random); avatarState.inventory.AddItem2(item, rewardInfo.Quantity); } monsterCollectionState.Claim(context.BlockIndex); return(states .SetState(avatarAddress, avatarState.SerializeV2()) .SetState(inventoryAddress, avatarState.inventory.Serialize()) .SetState(worldInformationAddress, avatarState.worldInformation.Serialize()) .SetState(questListAddress, avatarState.questList.Serialize()) .SetState(collectionAddress, monsterCollectionState.Serialize())); }
public override IAccountStateDelta Execute(IActionContext context) { IAccountStateDelta states = context.PreviousStates; Address collectionAddress = MonsterCollectionState0.DeriveAddress(context.Signer, collectionRound); if (context.Rehearsal) { return(states .SetState(context.Signer, MarkChanged) .SetState(avatarAddress, MarkChanged) .SetState(collectionAddress, MarkChanged)); } CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context); if (!states.TryGetAgentAvatarStates(context.Signer, avatarAddress, out AgentState agentState, out AvatarState avatarState)) { throw new FailedLoadStateException($"Aborted as the avatar state of the signer failed to load."); } if (!states.TryGetState(collectionAddress, out Dictionary stateDict)) { throw new FailedLoadStateException($"Aborted as the monster collection state failed to load."); } MonsterCollectionState0 monsterCollectionState = new MonsterCollectionState0(stateDict); if (monsterCollectionState.End) { throw new MonsterCollectionExpiredException($"{collectionAddress} has already expired on {monsterCollectionState.ExpiredBlockIndex}"); } if (!monsterCollectionState.CanReceive(context.BlockIndex)) { throw new RequiredBlockIndexException( $"{collectionAddress} is not available yet; it will be available after {Math.Max(monsterCollectionState.StartedBlockIndex, monsterCollectionState.ReceivedBlockIndex) + MonsterCollectionState0.RewardInterval}"); } long rewardLevel = monsterCollectionState.GetRewardLevel(context.BlockIndex); ItemSheet itemSheet = states.GetItemSheet(); for (int i = 0; i < rewardLevel; i++) { int level = i + 1; if (level <= monsterCollectionState.RewardLevel) { continue; } List <MonsterCollectionRewardSheet.RewardInfo> rewards = monsterCollectionState.RewardLevelMap[level]; Guid id = context.Random.GenerateRandomGuid(); MonsterCollectionResult result = new MonsterCollectionResult(id, avatarAddress, rewards); MonsterCollectionMail mail = new MonsterCollectionMail(result, context.BlockIndex, id, context.BlockIndex); avatarState.Update(mail); foreach (var rewardInfo in rewards) { var row = itemSheet[rewardInfo.ItemId]; var item = row is MaterialItemSheet.Row materialRow ? ItemFactory.CreateTradableMaterial(materialRow) : ItemFactory.CreateItem(row, context.Random); avatarState.inventory.AddItem2(item, rewardInfo.Quantity); } monsterCollectionState.UpdateRewardMap(level, result, context.BlockIndex); } // Return gold at the end of monster collect. if (rewardLevel == 4) { MonsterCollectionSheet monsterCollectionSheet = states.GetSheet <MonsterCollectionSheet>(); Currency currency = states.GetGoldCurrency(); // Set default gold value. FungibleAssetValue gold = currency * 0; for (int i = 0; i < monsterCollectionState.Level; i++) { int level = i + 1; gold += currency * monsterCollectionSheet[level].RequiredGold; } agentState.IncreaseCollectionRound(); states = states.SetState(context.Signer, agentState.Serialize()); if (gold > currency * 0) { states = states.TransferAsset(collectionAddress, context.Signer, gold); } } return(states .SetState(avatarAddress, avatarState.Serialize()) .SetState(collectionAddress, monsterCollectionState.Serialize())); }