Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        private void OnServerInformation(InPacket packet)
        {
            var worldInformation = new WorldInformation();

            worldInformation.Decode(packet);
            Logger.Info($"Updated {worldInformation.Name} server information");
        }
Esempio n. 3
0
        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();
        }
Esempio n. 4
0
 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();
 }
Esempio n. 5
0
        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}");
        }
Esempio n. 6
0
        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();
        }
Esempio n. 7
0
        public void HandleData(ConnectionData data)
        {
            WorldInformation world = data.WorldInformation;

            if (world.RoleList.ContainsKey(ObjectId))
            {
                world.RoleList.Remove(ObjectId);
            }
        }
Esempio n. 8
0
        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}");
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        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);
            }
        }
Esempio n. 15
0
        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());
            }
        }
Esempio n. 16
0
        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 _));
        }
Esempio n. 17
0
        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();
        }