public void Update(StageSimulator stageSimulator) { var player = stageSimulator.Player; characterId = player.RowData.Id; level = player.Level; exp = player.Exp.Current; inventory = player.Inventory; worldInformation = player.worldInformation; foreach (var pair in player.monsterMap) { monsterMap.Add(pair); } foreach (var pair in player.eventMap) { eventMap.Add(pair); } if (stageSimulator.Log.IsClear) { stageMap.Add(new KeyValuePair <int, int>(stageSimulator.StageId, 1)); } foreach (var pair in stageSimulator.ItemMap) { itemMap.Add(pair); } UpdateStageQuest(stageSimulator.Rewards); }
private void OnServerInformation(InPacket packet) { var worldInformation = new WorldInformation(); worldInformation.Decode(packet); Logger.Info($"Updated {worldInformation.Name} server information"); }
public AvatarState(AvatarState avatarState) : base(avatarState.address) { if (avatarState == null) { throw new ArgumentNullException(nameof(avatarState)); } name = avatarState.name; characterId = avatarState.characterId; level = avatarState.level; exp = avatarState.exp; inventory = avatarState.inventory; worldInformation = avatarState.worldInformation; updatedAt = avatarState.updatedAt; agentAddress = avatarState.agentAddress; questList = avatarState.questList; mailBox = avatarState.mailBox; blockIndex = avatarState.blockIndex; dailyRewardReceivedIndex = avatarState.dailyRewardReceivedIndex; actionPoint = avatarState.actionPoint; stageMap = avatarState.stageMap; monsterMap = avatarState.monsterMap; itemMap = avatarState.itemMap; eventMap = avatarState.eventMap; hair = avatarState.hair; lens = avatarState.lens; ear = avatarState.ear; tail = avatarState.tail; combinationSlotAddresses = avatarState.combinationSlotAddresses; RankingMapAddress = avatarState.RankingMapAddress; PostConstructor(); }
public AvatarState(Dictionary serialized) : base(serialized) { name = ((Text)serialized["name"]).Value; characterId = (int)((Integer)serialized["characterId"]).Value; level = (int)((Integer)serialized["level"]).Value; exp = (long)((Integer)serialized["exp"]).Value; inventory = new Inventory((List)serialized["inventory"]); worldInformation = new WorldInformation((Dictionary)serialized["worldInformation"]); updatedAt = serialized["updatedAt"].ToLong(); agentAddress = new Address(((Binary)serialized["agentAddress"]).Value); questList = new QuestList((Dictionary)serialized["questList"]); mailBox = new MailBox((List)serialized["mailBox"]); blockIndex = (long)((Integer)serialized["blockIndex"]).Value; dailyRewardReceivedIndex = (long)((Integer)serialized["dailyRewardReceivedIndex"]).Value; actionPoint = (int)((Integer)serialized["actionPoint"]).Value; stageMap = new CollectionMap((Dictionary)serialized["stageMap"]); serialized.TryGetValue((Text)"monsterMap", out var value2); monsterMap = value2 is null ? new CollectionMap() : new CollectionMap((Dictionary)value2); itemMap = new CollectionMap((Dictionary)serialized["itemMap"]); eventMap = new CollectionMap((Dictionary)serialized["eventMap"]); hair = (int)((Integer)serialized["hair"]).Value; lens = (int)((Integer)serialized["lens"]).Value; ear = (int)((Integer)serialized["ear"]).Value; tail = (int)((Integer)serialized["tail"]).Value; combinationSlotAddresses = serialized["combinationSlotAddresses"].ToList(StateExtensions.ToAddress); RankingMapAddress = serialized["ranking_map_address"].ToAddress(); if (serialized.TryGetValue((Text)"nonce", out var nonceValue)) { Nonce = nonceValue.ToInteger(); } PostConstructor(); }
public async Task Run() { var options = _container.GetInstance <WvsCenterOptions>(); var info = options.CenterInfo; WorldInformation = new WorldInformation { ID = info.ID, Name = info.Name, State = info.State, EventDesc = info.EventDesc, EventEXP = info.EventEXP, EventDrop = info.EventDrop, BlockCharCreation = info.BlockCharCreation }; InteropServer = new Server <CenterClientSocket>( options.InteropServerOptions, _container.GetInstance <CenterClientSocketFactory>() ); await InteropServer.Run(); Logger.Info($"Bounded {WorldInformation.Name} on {InteropServer.Channel.LocalAddress}"); }
public AvatarState(Address address, Address agentAddress, long blockIndex, TableSheets sheets, GameConfigState gameConfigState, string name = null) : base(address) { if (address == null) { throw new ArgumentNullException(nameof(address)); } this.name = name ?? string.Empty; characterId = GameConfig.DefaultAvatarCharacterId; level = 1; exp = 0; inventory = new Inventory(); worldInformation = new WorldInformation(blockIndex, sheets.WorldSheet, GameConfig.IsEditor); updatedAt = DateTimeOffset.UtcNow; this.agentAddress = agentAddress; questList = new QuestList( sheets.QuestSheet, sheets.QuestRewardSheet, sheets.QuestItemRewardSheet, sheets.EquipmentItemRecipeSheet, sheets.EquipmentItemSubRecipeSheet ); mailBox = new MailBox(); this.blockIndex = blockIndex; actionPoint = gameConfigState.ActionPointMax; stageMap = new CollectionMap(); monsterMap = new CollectionMap(); itemMap = new CollectionMap(); const QuestEventType createEvent = QuestEventType.Create; const QuestEventType levelEvent = QuestEventType.Level; eventMap = new CollectionMap { new KeyValuePair <int, int>((int)createEvent, 1), new KeyValuePair <int, int>((int)levelEvent, level), }; combinationSlotAddresses = new List <Address>(CombinationSlotCapacity); for (var i = 0; i < CombinationSlotCapacity; i++) { var slotAddress = address.Derive( string.Format( CultureInfo.InvariantCulture, CombinationSlotState.DeriveFormat, i ) ); combinationSlotAddresses.Add(slotAddress); } UpdateGeneralQuest(new[] { createEvent, levelEvent }); UpdateCompletedQuest(); PostConstructor(); }
public void HandleData(ConnectionData data) { WorldInformation world = data.WorldInformation; if (world.RoleList.ContainsKey(ObjectId)) { world.RoleList.Remove(ObjectId); } }
private void OnServerRegisterResult(InPacket packet) { if (packet.Decode <bool>()) { return; // TODO: disconnect? } var worldInformation = new WorldInformation(); worldInformation.Decode(packet); Logger.Info($"Registered Center server, {worldInformation.Name}"); }
public void TryGetLastClearedStageId(int worldId, int stageId) { var wi = new WorldInformation(0, _tableSheets.WorldSheet, stageId - 1); Assert.False(wi.IsStageCleared(stageId)); Assert.NotEqual( stageId, wi.TryGetLastClearedStageId(out var clearedStageId) ? clearedStageId : 0); wi.ClearStage(worldId, stageId, 0, _tableSheets.WorldSheet, _tableSheets.WorldUnlockSheet); Assert.True(wi.IsStageCleared(stageId)); Assert.True(wi.TryGetLastClearedStageId(out clearedStageId)); Assert.Equal(stageId, clearedStageId); }
public void TryGetFirstWorld() { var worldSheet = _tableSheets.WorldSheet; var wi = new WorldInformation(Bencodex.Types.Dictionary.Empty); Assert.False(wi.TryGetFirstWorld(out _)); foreach (var row in worldSheet.Values.OrderByDescending(r => r.Id)) { wi.TryAddWorld(row, out _); } wi.TryGetFirstWorld(out var world); Assert.Equal(1, world.Id); }
public void HandleData(ConnectionData data) { WorldInformation world = data.WorldInformation; foreach (RoleMainStruct role in Roles) { if (world.RoleList.ContainsKey(role.RoleId)) { world.RoleList[role.RoleId] = role; } else { world.RoleList.Add(role.RoleId, role); } } }
private void OnCheckSPWRequest(InPacket packet, bool vac) { var spw = packet.Decode <string>(); var characterID = packet.Decode <int>(); packet.Decode <string>(); // sMacAddress packet.Decode <string>(); // sMacAddressWithHDDSerial if (string.IsNullOrEmpty(Account.SPW)) { return; } if (!BCrypt.Net.BCrypt.Verify(spw, Account.SPW)) { using (var p = new OutPacket(LoginSendOperations.CheckSPWResult)) { p.Encode <bool>(false); // Unused byte SendPacket(p); } return; } if (vac) { var character = Account.Data .SelectMany(a => a.Characters) .Single(c => c.ID == characterID); _selectedWorld = _wvsLogin.InteropClients .Select(c => c.Socket.WorldInformation) .SingleOrDefault(w => w.ID == character.Data.WorldID); _selectedChannel = _selectedWorld.Channels.First(); } var world = _wvsLogin.InteropClients.Single(c => c.Socket.WorldInformation.ID == _selectedWorld.ID); using (var p = new OutPacket(InteropRecvOperations.MigrationRequest)) { p.Encode <byte>((byte)ServerType.Game); p.Encode <byte>(_selectedChannel.ID); p.Encode <string>(SessionKey); p.Encode <int>(characterID); world.Socket.SendPacket(p); } }
public void Case(int randomSeed, int[] optionNumbers) { var gameConfigState = _initialState.GetGameConfigState(); Assert.NotNull(gameConfigState); var subRecipeRow = _tableSheets.EquipmentItemSubRecipeSheetV2.OrderedList.First(e => e.Options.Count == 4 && e.RequiredBlockIndex > GameConfig.RequiredAppraiseBlock && e.RequiredGold == 0); var recipeRow = _tableSheets.EquipmentItemRecipeSheet.OrderedList.First(e => e.SubRecipeIds.Contains(subRecipeRow.Id)); var combinationEquipmentAction = new CombinationEquipment { avatarAddress = _avatarAddress, slotIndex = 0, recipeId = recipeRow.Id, subRecipeId = subRecipeRow.Id, }; var inventoryValue = _initialState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); var inventoryState = new Inventory((List)inventoryValue); inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, recipeRow.MaterialId), recipeRow.MaterialCount); foreach (var materialInfo in subRecipeRow.Materials) { inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, materialInfo.Id), materialInfo.Count); } var worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, recipeRow.UnlockStage); var nextState = _initialState .SetState(_inventoryAddress, inventoryState.Serialize()) .SetState(_worldInformationAddress, worldInformation.Serialize()); var random = new TestRandom(randomSeed); nextState = combinationEquipmentAction.Execute(new ActionContext { PreviousStates = nextState, BlockIndex = 0, Random = random, Signer = _agentAddress, }); var slot0Value = nextState.GetState(_slot0Address); Assert.NotNull(slot0Value); var slot0State = new CombinationSlotState((Dictionary)slot0Value); Assert.NotNull(slot0State.Result.itemUsable); var equipment = (Equipment)slot0State.Result.itemUsable; var additionalStats = equipment.StatsMap .GetAdditionalStats(true) .ToArray(); var skills = equipment.Skills; Assert.Equal(optionNumbers.Length, equipment.optionCountFromCombination); var optionSheet = _tableSheets.EquipmentItemOptionSheet; var mainAdditionalStatMin = 0; var mainAdditionalStatMax = 0; var requiredBlockIndex = recipeRow.RequiredBlockIndex + subRecipeRow.RequiredBlockIndex; var orderedOptions = subRecipeRow.Options .OrderByDescending(e => e.Ratio) .ThenBy(e => e.RequiredBlockIndex) .ThenBy(e => e.Id) .ToArray(); foreach (var optionNumber in optionNumbers) { var optionInfo = orderedOptions[optionNumber - 1]; requiredBlockIndex += optionInfo.RequiredBlockIndex; var optionRow = optionSheet[optionInfo.Id]; if (optionRow.StatMin > 0 || optionRow.StatMax > 0) { if (optionRow.StatType == equipment.UniqueStatType) { mainAdditionalStatMin += optionRow.StatMin; mainAdditionalStatMax += optionRow.StatMax; continue; } var additionalStatValue = additionalStats .First(e => e.statType == optionRow.StatType) .additionalValue; Assert.True(additionalStatValue >= optionRow.StatMin); Assert.True(additionalStatValue <= optionRow.StatMax + 1); } else if (optionRow.SkillId != default) { var skill = skills.First(e => e.SkillRow.Id == optionRow.SkillId); Assert.True(skill.Chance >= optionRow.SkillChanceMin); Assert.True(skill.Chance <= optionRow.SkillChanceMax + 1); Assert.True(skill.Power >= optionRow.SkillDamageMin); Assert.True(skill.Power <= optionRow.SkillDamageMax + 1); } } var mainAdditionalStatValue = additionalStats .First(e => e.statType == equipment.UniqueStatType) .additionalValue; Assert.True(mainAdditionalStatValue >= mainAdditionalStatMin); Assert.True(mainAdditionalStatValue <= mainAdditionalStatMax + 1); Assert.Equal(requiredBlockIndex, slot0State.RequiredBlockIndex); if (requiredBlockIndex == 0) { return; } var hourglassRow = _tableSheets.MaterialItemSheet .First(pair => pair.Value.ItemSubType == ItemSubType.Hourglass) .Value; inventoryValue = nextState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); inventoryState = new Inventory((List)inventoryValue); Assert.False(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out _)); var diff = slot0State.RequiredBlockIndex - GameConfig.RequiredAppraiseBlock; var hourglassCount = RapidCombination0.CalculateHourglassCount(gameConfigState, diff); inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, hourglassRow.Id), hourglassCount); Assert.True(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out var hourglasses)); Assert.Equal(hourglassCount, hourglasses.Sum(e => e.count)); nextState = nextState.SetState(_inventoryAddress, inventoryState.Serialize()); var rapidCombinationAction = new RapidCombination { avatarAddress = _avatarAddress, slotIndex = 0, }; nextState = rapidCombinationAction.Execute(new ActionContext { PreviousStates = nextState, BlockIndex = GameConfig.RequiredAppraiseBlock, Random = random, Signer = _agentAddress, }); inventoryValue = nextState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); inventoryState = new Inventory((List)inventoryValue); Assert.False(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out _)); }
private void OnSelectWorld(InPacket packet) { packet.Decode <byte>(); var worldID = packet.Decode <byte>(); var channelID = packet.Decode <byte>() + 1; using (var p = new OutPacket(LoginSendOperations.SelectWorldResult)) { byte result = 0x0; var world = _wvsLogin.InteropClients .Select(c => c.Socket.WorldInformation) .SingleOrDefault(w => w.ID == worldID); var channel = world?.Channels.SingleOrDefault(c => c.ID == channelID); if (world == null) { result = 0x1; } if (channel == null) { result = 0x1; } p.Encode <byte>(result); if (result == 0) { _selectedWorld = world; _selectedChannel = channel; using (var db = _container.GetInstance <DataContext>()) { var data = Account.Data.SingleOrDefault(d => d.WorldID == worldID); if (data == null) { data = new AccountData { WorldID = worldID, SlotCount = 3 }; Account.Data.Add(data); db.Update(Account); db.SaveChanges(); } var characters = data.Characters; p.Encode <byte>((byte)characters.Count); characters.ForEach(c => { c.EncodeStats(p); c.EncodeLook(p); p.Encode <bool>(false); p.Encode <bool>(false); }); p.Encode <bool>(!string.IsNullOrEmpty(Account.SPW)); // bLoginOpt TODO: proper bLoginOpt stuff p.Encode <int>(data.SlotCount); // nSlotCount p.Encode <int>(0); // nBuyCharCount } } SendPacket(p); } }
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 void Case(int randomSeed, int[] optionNumbers) { var gameConfigState = _initialState.GetGameConfigState(); Assert.NotNull(gameConfigState); var recipeRow = _tableSheets.EquipmentItemRecipeSheet.OrderedList.First(e => e.SubRecipeIds.Any()); var subRecipeRow = _tableSheets.EquipmentItemSubRecipeSheetV2[recipeRow.SubRecipeIds.First()]; var combinationEquipmentAction = new CombinationEquipment { avatarAddress = _avatarAddress, slotIndex = 0, recipeId = recipeRow.Id, subRecipeId = subRecipeRow.Id, }; var inventoryValue = _initialState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); var inventoryState = new Inventory((List)inventoryValue); inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, recipeRow.MaterialId), recipeRow.MaterialCount); foreach (var materialInfo in subRecipeRow.Materials) { inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, materialInfo.Id), materialInfo.Count); } var worldInformation = new WorldInformation( 0, _tableSheets.WorldSheet, recipeRow.UnlockStage); var nextState = _initialState .SetState(_inventoryAddress, inventoryState.Serialize()) .SetState(_worldInformationAddress, worldInformation.Serialize()); var random = new TestRandom(randomSeed); nextState = combinationEquipmentAction.Execute(new ActionContext { PreviousStates = nextState, BlockIndex = 0, Random = random, Signer = _agentAddress, }); var slot0Value = nextState.GetState(_slot0Address); Assert.NotNull(slot0Value); var slot0State = new CombinationSlotState((Dictionary)slot0Value); Assert.NotNull(slot0State.Result.itemUsable); var equipment = (Equipment)slot0State.Result.itemUsable; var additionalStats = equipment.StatsMap .GetAdditionalStats(true) .ToArray(); var skills = equipment.Skills; Assert.Equal(optionNumbers.Length, equipment.optionCountFromCombination); var optionSheet = _tableSheets.EquipmentItemOptionSheet; var mainAdditionalStatMin = 0; var mainAdditionalStatMax = 0; var requiredBlockIndex = 0; foreach (var optionNumber in optionNumbers) { var optionInfo = subRecipeRow.Options[optionNumber - 1]; requiredBlockIndex += optionInfo.RequiredBlockIndex; var optionRow = optionSheet[optionInfo.Id]; if (optionRow.StatMin > 0 || optionRow.StatMax > 0) { if (optionRow.StatType == equipment.UniqueStatType) { mainAdditionalStatMin += optionRow.StatMin; mainAdditionalStatMax += optionRow.StatMax; continue; } var additionalStatValue = additionalStats .First(e => e.statType == optionRow.StatType) .additionalValue; Assert.True(additionalStatValue >= optionRow.StatMin); Assert.True(additionalStatValue <= optionRow.StatMax + 1); } else if (optionRow.SkillId != default) { var skill = skills.First(e => e.SkillRow.Id == optionRow.SkillId); Assert.True(skill.Chance >= optionRow.SkillChanceMin); Assert.True(skill.Chance <= optionRow.SkillChanceMax + 1); Assert.True(skill.Power >= optionRow.SkillDamageMin); Assert.True(skill.Power <= optionRow.SkillDamageMax + 1); } } var mainAdditionalStatValue = additionalStats .First(e => e.statType == equipment.UniqueStatType) .additionalValue; Assert.True(mainAdditionalStatValue >= mainAdditionalStatMin); Assert.True(mainAdditionalStatValue <= mainAdditionalStatMax + 1); Assert.Equal(requiredBlockIndex + 1, slot0State.RequiredBlockIndex); // FIXME // https://github.com/planetarium/lib9c/pull/517#discussion_r679218764 // The tests after this line should be finished. However, since then the logic is being developed by // different developers in different branches. I wrote a test beforehand, but it's failing. // I plan to move to another branch after this PR is merged and finish writing the tests. return; if (requiredBlockIndex == 0) { return; } var hourglassRow = _tableSheets.MaterialItemSheet .First(pair => pair.Value.ItemSubType == ItemSubType.Hourglass) .Value; inventoryValue = nextState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); inventoryState = new Inventory((List)inventoryValue); Assert.False(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out _)); var hourglassCount = requiredBlockIndex * gameConfigState.HourglassPerBlock; inventoryState.AddFungibleItem( ItemFactory.CreateMaterial(_tableSheets.MaterialItemSheet, hourglassRow.Id), hourglassCount); Assert.True(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out var hourglasses)); Assert.Equal(hourglassCount, hourglasses.Sum(e => e.count)); nextState = nextState.SetState(_inventoryAddress, inventoryState.Serialize()); var rapidCombinationAction = new RapidCombination { avatarAddress = _avatarAddress, slotIndex = 0, }; nextState = rapidCombinationAction.Execute(new ActionContext { PreviousStates = nextState, BlockIndex = 1, Random = random, Signer = _agentAddress, }); inventoryValue = nextState.GetState(_inventoryAddress); Assert.NotNull(inventoryValue); inventoryState = new Inventory((List)inventoryValue); Assert.False(inventoryState.TryGetFungibleItems(hourglassRow.ItemId, out _)); }
public AvatarState(Dictionary serialized) : base(serialized) { string nameKey = NameKey; string characterIdKey = CharacterIdKey; string levelKey = LevelKey; string expKey = ExpKey; string inventoryKey = LegacyInventoryKey; string worldInformationKey = LegacyWorldInformationKey; string updatedAtKey = UpdatedAtKey; string agentAddressKey = AgentAddressKey; string questListKey = LegacyQuestListKey; string mailBoxKey = MailBoxKey; string blockIndexKey = BlockIndexKey; string dailyRewardReceivedIndexKey = DailyRewardReceivedIndexKey; string actionPointKey = ActionPointKey; string stageMapKey = StageMapKey; string monsterMapKey = MonsterMapKey; string itemMapKey = ItemMapKey; string eventMapKey = EventMapKey; string hairKey = HairKey; string lensKey = LensKey; string earKey = EarKey; string tailKey = TailKey; string combinationSlotAddressesKey = CombinationSlotAddressesKey; string rankingMapAddressKey = RankingMapAddressKey; if (serialized.ContainsKey(LegacyNameKey)) { nameKey = LegacyNameKey; characterIdKey = LegacyCharacterIdKey; levelKey = LegacyLevelKey; updatedAtKey = LegacyUpdatedAtKey; agentAddressKey = LegacyAgentAddressKey; mailBoxKey = LegacyMailBoxKey; blockIndexKey = LegacyBlockIndexKey; dailyRewardReceivedIndexKey = LegacyDailyRewardReceivedIndexKey; actionPointKey = LegacyActionPointKey; stageMapKey = LegacyStageMapKey; monsterMapKey = LegacyMonsterMapKey; itemMapKey = LegacyItemMapKey; eventMapKey = LegacyEventMapKey; hairKey = LegacyHairKey; earKey = LegacyEarKey; tailKey = LegacyTailKey; combinationSlotAddressesKey = LegacyCombinationSlotAddressesKey; rankingMapAddressKey = LegacyRankingMapAddressKey; } name = serialized[nameKey].ToDotnetString(); characterId = (int)((Integer)serialized[characterIdKey]).Value; level = (int)((Integer)serialized[levelKey]).Value; exp = (long)((Integer)serialized[expKey]).Value; updatedAt = serialized[updatedAtKey].ToLong(); agentAddress = serialized[agentAddressKey].ToAddress(); mailBox = new MailBox((List)serialized[mailBoxKey]); blockIndex = (long)((Integer)serialized[blockIndexKey]).Value; dailyRewardReceivedIndex = (long)((Integer)serialized[dailyRewardReceivedIndexKey]).Value; actionPoint = (int)((Integer)serialized[actionPointKey]).Value; stageMap = new CollectionMap((Dictionary)serialized[stageMapKey]); serialized.TryGetValue((Text)monsterMapKey, out var value2); monsterMap = value2 is null ? new CollectionMap() : new CollectionMap((Dictionary)value2); itemMap = new CollectionMap((Dictionary)serialized[itemMapKey]); eventMap = new CollectionMap((Dictionary)serialized[eventMapKey]); hair = (int)((Integer)serialized[hairKey]).Value; lens = (int)((Integer)serialized[lensKey]).Value; ear = (int)((Integer)serialized[earKey]).Value; tail = (int)((Integer)serialized[tailKey]).Value; combinationSlotAddresses = serialized[combinationSlotAddressesKey].ToList(StateExtensions.ToAddress); RankingMapAddress = serialized[rankingMapAddressKey].ToAddress(); if (serialized.ContainsKey(inventoryKey)) { inventory = new Inventory((List)serialized[inventoryKey]); } if (serialized.ContainsKey(worldInformationKey)) { worldInformation = new WorldInformation((Dictionary)serialized[worldInformationKey]); } if (serialized.ContainsKey(questListKey)) { questList = new QuestList((Dictionary)serialized[questListKey]); } PostConstructor(); }