public void Serialize() { var state = new RankingState1(); var avatarAddress = new PrivateKey().ToAddress(); state.UpdateRankingMap(avatarAddress); var serialized = state.Serialize(); var des = new RankingState1((Dictionary)serialized); Assert.Equal(Addresses.Ranking, des.address); Assert.Contains(des.RankingMap, m => m.Value.Contains(avatarAddress)); }
public void Deterministic_Between_SerializeV1_And_SerializeV1_With_Deterministic_Problem() { var state = new RankingState1(); for (var i = 0; i < 1000; i++) { state.UpdateRankingMap(new PrivateKey().ToAddress()); } var serializedV1 = state.Serialize(); var serializedV1WithDeterministicProblem = SerializeV1_With_Deterministic_Problem(state); Assert.Equal(serializedV1WithDeterministicProblem, serializedV1); var deserialized = new RankingState1((Bencodex.Types.Dictionary)serializedV1); var deserializedV1 = new RankingState1((Bencodex.Types.Dictionary)serializedV1WithDeterministicProblem); serializedV1 = deserialized.Serialize(); serializedV1WithDeterministicProblem = deserializedV1.Serialize(); Assert.Equal(serializedV1WithDeterministicProblem, serializedV1); }
public static MakeInitialStateResult MakeInitialState() { var goldCurrencyState = new GoldCurrencyState(new Currency("NCG", 2, minter: null)); var ranking = new RankingState1(); for (var i = 0; i < RankingState1.RankingMapCapacity; i++) { ranking.RankingMap[RankingState1.Derive(i)] = new HashSet <Address>().ToImmutableHashSet(); } var sheets = TableSheetsImporter.ImportSheets(); var weeklyArenaAddress = WeeklyArenaState.DeriveAddress(0); var initialState = new Tests.Action.State() .SetState(GoldCurrencyState.Address, goldCurrencyState.Serialize()) .SetState( Addresses.GoldDistribution, GoldDistributionTest.Fixture.Select(v => v.Serialize()).Serialize() ) .SetState( Addresses.GameConfig, new GameConfigState(sheets[nameof(GameConfigSheet)]).Serialize() ) .SetState(Addresses.Ranking, ranking.Serialize()) .SetState(weeklyArenaAddress, new WeeklyArenaState(0).Serialize()); foreach (var(key, value) in sheets) { initialState = initialState.SetState(Addresses.TableSheet.Derive(key), value.Serialize()); } var tableSheets = new TableSheets(sheets); var rankingMapAddress = new PrivateKey().ToAddress(); var agentAddress = new PrivateKey().ToAddress(); var agentState = new AgentState(agentAddress); var avatarAddress = 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 initCurrencyGold = goldCurrencyState.Currency * 100000000000; var agentCurrencyGold = goldCurrencyState.Currency * 1000; var remainCurrencyGold = initCurrencyGold - agentCurrencyGold; initialState = initialState .SetState(GoldCurrencyState.Address, goldCurrencyState.Serialize()) .SetState(agentAddress, agentState.Serialize()) .SetState(avatarAddress, avatarState.Serialize()) .SetState(Addresses.Shop, new ShopState().Serialize()) .MintAsset(GoldCurrencyState.Address, initCurrencyGold) .TransferAsset(Addresses.GoldCurrency, agentAddress, agentCurrencyGold); var action = new CreateTestbed { weeklyArenaAddress = weeklyArenaAddress, }; var nextState = action.Execute(new ActionContext() { BlockIndex = 0, PreviousStates = initialState, Random = new TestRandom(), Rehearsal = false, }); return(new MakeInitialStateResult( nextState, action, agentState, avatarState, goldCurrencyState, rankingMapAddress, tableSheets, remainCurrencyGold, agentCurrencyGold)); }
public override IAccountStateDelta Execute(IActionContext context) { IActionContext ctx = context; var states = ctx.PreviousStates; var avatarAddress = ctx.Signer.Derive( string.Format( CultureInfo.InvariantCulture, DeriveFormat, index ) ); var inventoryAddress = avatarAddress.Derive(LegacyInventoryKey); var worldInformationAddress = avatarAddress.Derive(LegacyWorldInformationKey); var questListAddress = avatarAddress.Derive(LegacyQuestListKey); 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) .SetState(inventoryAddress, MarkChanged) .SetState(worldInformationAddress, MarkChanged) .SetState(questListAddress, MarkChanged) .MarkBalanceChanged(GoldCurrencyMock, GoldCurrencyState.Address, context.Signer)); } 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>(); RankingState1 rankingState = ctx.PreviousStates.GetRankingState1(); 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.UpdateQuestRewards(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(inventoryAddress, avatarState.inventory.Serialize()) .SetState(worldInformationAddress, avatarState.worldInformation.Serialize()) .SetState(questListAddress, avatarState.questList.Serialize()) .SetState(avatarAddress, avatarState.SerializeV2())); }