public void IsEnabled_WhenPercentageIsAboveMinimum_ShouldReturnTrue()
        {
            var groupId = string.Empty;

            var minimumPercentage = StrategyUtils.GetNormalizedNumber(SessionId, groupId);

            var context    = new UnleashContext.Builder().SessionId(SessionId).Build();
            var parameters = new Dictionary <string, string>();

            for (var percentage = 0; percentage <= 100; percentage++)
            {
                parameters[GradualRolloutSessionIdStrategy.Percentage] = percentage.ToString();
                parameters[GradualRolloutSessionIdStrategy.GroupId]    = groupId;

                var actual = Strategy.IsEnabled(parameters, context);

                if (percentage < minimumPercentage)
                {
                    Assert.False(actual);
                }
                else
                {
                    Assert.True(actual);
                }
            }
        }
        public void GetPercentageVariants()
        {
            StrategyUtils.GetPercentage(null).Should().Be(0);
            StrategyUtils.GetPercentage("").Should().Be(0);

            // Normal cases
            StrategyUtils.GetPercentage("0").Should().Be(0);
            StrategyUtils.GetPercentage("50").Should().Be(50);
            StrategyUtils.GetPercentage("100").Should().Be(100);

            // Whitespace
            StrategyUtils.GetPercentage(" 0 ").Should().Be(0);
            StrategyUtils.GetPercentage(" 50 ").Should().Be(50);
            StrategyUtils.GetPercentage(" 100 ").Should().Be(100);

            // Edge cases
            StrategyUtils.GetPercentage("-1").Should().Be(0);
            StrategyUtils.GetPercentage("101").Should().Be(100);

            // Min/max
            StrategyUtils.GetPercentage(int.MaxValue.ToString()).Should().Be(100);
            StrategyUtils.GetPercentage(int.MinValue.ToString()).Should().Be(0);

            // Overflow
            StrategyUtils.GetPercentage(int.MaxValue + "0").Should().Be(0);
            StrategyUtils.GetPercentage(int.MinValue + "0").Should().Be(0);
        }
        public static Variant SelectVariant(FeatureToggle featureToggle, UnleashContext context, Variant defaultVariant)
        {
            var variantDefinitions = featureToggle.Variants;
            var totalWeight        = variantDefinitions.Sum(v => v.Weight);

            if (totalWeight == 0)
            {
                return(defaultVariant);
            }

            var variantOverride = GetOverride(variantDefinitions, context);

            if (variantOverride != null)
            {
                return(variantOverride.ToVariant());
            }

            var target = StrategyUtils.GetNormalizedNumber(GetIdentifier(context), featureToggle.Name, totalWeight);

            var counter = 0;

            foreach (var variantDefinition in variantDefinitions)
            {
                if (variantDefinition.Weight != 0)
                {
                    counter += variantDefinition.Weight;
                    if (counter >= target)
                    {
                        return(variantDefinition.ToVariant());
                    }
                }
            }

            return(defaultVariant);
        }
        public void GetNormalizedNumber_Variants()
        {
            // Normal cases
            StrategyUtils.GetNormalizedNumber("user1", "group1").Should().BeInRange(0, 100);

            // Strange inputs
            StrategyUtils.GetNormalizedNumber(null, null).Should().BeInRange(0, 100);
            StrategyUtils.GetNormalizedNumber("", "").Should().BeInRange(0, 100);
            StrategyUtils.GetNormalizedNumber("#%&/(", "§~:<>&nbsp;").Should().BeInRange(0, 100);
        }
        public void should_be_enabled_above_minimum_percentage()
        {
            var userId            = "1574576830";
            var groupId           = "";
            var minimumPercentage = StrategyUtils.GetNormalizedNumber(userId, groupId);

            var context = UnleashContext.New().UserId(userId).Build();
            var gradualRolloutStrategy = new GradualRolloutUserIdStrategy();

            for (var p = minimumPercentage; p <= 100; p++)
            {
                var paramseters = buildParams(p, groupId);
                var actual      = gradualRolloutStrategy.IsEnabled(paramseters, context);

                actual.Should().BeTrue("should be enabled when " + p + "% rollout");
            }
        }
Esempio n. 6
0
        public void should_be_enabled_above_minimum_percentage()
        {
            const string sessionId         = "1574576830";
            const string groupId           = "";
            var          minimumPercentage = StrategyUtils.GetNormalizedNumber(sessionId, groupId);

            var context = UnleashContext.CreateBuilder().SessionId(sessionId).Build();

            var gradualRolloutStrategy = new GradualRolloutSessionIdStrategy();

            for (int p = minimumPercentage; p <= 100; p++)
            {
                var parms  = BuildParams(p, groupId);
                var actual = gradualRolloutStrategy.IsEnabled(parms, context);
                Assert.True(actual); //"should be enabled when " + p + "% rollout"
            }
        }
        private static StructureOffset IngameDataOffsets(StructureOffset inGameState)
        {
            var inGameDataAreaNameStructSearch = StrategyUtils.StringInSubStruct("Lush Hideout", subStructSize: 0x10, checkVmt: false);
            var inGameDataStructSearch         = inGameDataAreaNameStructSearch.SubStructSearch(subStructSize: 0x600, checkVmt: true);
            var inGameData = new StructureOffset("InGameData", inGameDataStructSearch, maxStructSize: 0x800);//don't set to 0x1000 coz it can find multiple player offsets

            inGameState.Child.Add(inGameData);

            inGameData.Child.Add(new DataOffset("Area Name", inGameDataAreaNameStructSearch));
            inGameData.AddByteSearch("Area Level", 60, false, 8);


            inGameData.Child.Add(new DataOffset("Tgt.Cols/Tgt.Rows(+0x8)/PtrAddr(+0x10)", new ValueReaderStrategy(new MultipleIntValueReader(
                                                                                                                      new DefaultValueCompare <int>(33),
                                                                                                                      new DefaultValueCompare <int>(0),
                                                                                                                      new DefaultValueCompare <int>(33),
                                                                                                                      new DefaultValueCompare <int>(0)
                                                                                                                      ), 4)));

            inGameData.Child.Add(new DataOffset("NavPtr", new ValueReaderStrategy(new ArrayByteLengthValueCompare(288420), 8)));//288420 / 8
            inGameData.Child.Add(new DataOffset("MapWidth", new ValueReaderStrategy(new IntValueReader(new DefaultValueCompare <int>(380)), 4)));

            return(inGameData);
        }
Esempio n. 8
0
 protected override bool Run()
 {
     _ctrlRebellionOrganize.Run();
     return(StrategyUtils.ChkStateRebellionTaskIsRun(StrategyRebellionTaskManagerMode.Organize));
 }
 public void GetNormalizedNumber_Is_Compatible_With_Java_And_Go_Implementations()
 {
     Assert.AreEqual(73, StrategyUtils.GetNormalizedNumber("123", "gr1"));
     Assert.AreEqual(25, StrategyUtils.GetNormalizedNumber("999", "groupX"));
 }
Esempio n. 10
0
 public bool IsEnabled(Dictionary <string, string> parameters, UnleashContext context, List <Constraint> constraints)
 {
     return(StrategyUtils.IsEnabled(this, parameters, context, constraints));
 }
 protected override bool Run()
 {
     return(StrategyUtils.ChkStateRebellionTaskIsRun(StrategyRebellionTaskManagerMode.StrategyRebellionTaskManager_ST));
 }
Esempio n. 12
0
 public void normalized_values_are_the_same_across_node_java_go_and_dotnet_clients()
 {
     Assert.Equal(73, StrategyUtils.GetNormalizedNumber("123", "gr1"));
     Assert.Equal(25, StrategyUtils.GetNormalizedNumber("999", "groupX"));
 }
        private void PlayerOffsets(StructureOffset inGameData)
        {
            var player = new StructureOffset("Player",
                                             StrategyUtils.StringSearch(new StringValueComparer("Metadata/Characters/", StringCompareType.StartWith)).SubStructSearch(0x50, true)
                                             .SubStructSearch(8, false),
                                             maxStructSize: 0x60);

            #region PositionedComponent

            var worldX         = new FloatValueCompare(compareValue: 2375, tolerance: 50);
            var worldY         = new FloatValueCompare(compareValue: 3646.739f, tolerance: 50);
            var worldPos       = new MultipleFloatValueReader(worldX, worldY);
            var worldPosReader = new ValueReaderStrategy(worldPos, alignment: 4);

            var entityPositionedComponent = new StructureOffset("Entity.PositionedComponent",
                                                                new SubPointersSearchStrategy(worldPosReader.Adapter(), subStructSize: 0x200, checkVmt: true),
                                                                maxStructSize: 0x300);

            player.Child.Add(entityPositionedComponent);
            inGameData.Child.Add(player);

            #endregion

            #region Entity.ComponentLookup

            //Positioned seems always the first component, so you can pointerscan inside Entity to Positioned string using Structure Spider Advanced
            var entityComponentLookupSearch =
                new PointersSearchStrategy(new EntityComponentLookupPointerCompare(new List <string> {
                "Life", "Player"
            }));

            var entityLookupDeph2 = entityComponentLookupSearch.SubStructSearch(0x100, false);
            var entityLookupDeph1 = entityLookupDeph2.SubStructSearch(0x100, true);

            var entityInternalStruct = new StructureOffset("Entity.ComponentLookup", entityLookupDeph1, 8);
            player.Child.Add(entityInternalStruct);

            entityInternalStruct.OnOffsetsFound += delegate
            {
                var finalOffsets = new List <int>();
                finalOffsets.AddRange(entityLookupDeph1.FoundOffsets);
                finalOffsets.AddRange(entityLookupDeph2.FoundOffsets);
                finalOffsets.AddRange(entityComponentLookupSearch.FoundOffsets);
                entityInternalStruct.FoundOffsets = finalOffsets;

                entityInternalStruct.DebugInfo = $"({entityLookupDeph1.FoundOffsets.Format()}, " +
                                                 $"{entityLookupDeph2.FoundOffsets.Format()}, " +
                                                 $"{entityComponentLookupSearch.FoundOffsets.Format()})";

                if (entityInternalStruct.SearchStatus == OffsetSearchStatus.FoundSingle)
                {
                    Entity.ComponentLookupOffset1 = entityLookupDeph1.FoundOffsets[0];
                    Entity.ComponentLookupOffset2 = entityLookupDeph2.FoundOffsets[0];
                    Entity.ComponentLookupOffset3 = entityComponentLookupSearch.FoundOffsets[0];
                }
            };

            var listSearch          = new PointerValueCompare(new DelegateReferenceValueCompare <long>(() => entityPositionedComponent.BaseAddress));
            var listPointerSearch   = new PointersSearchStrategy(listSearch).SubStructSearch(100, false);
            var entityComponentList = new StructureOffset("Entity.ComponentList", listPointerSearch, 0x30); //not 0x30, actually it is on 0x8
            entityComponentList.ShouldProcess = () => entityPositionedComponent.OffsetIsFound;
            player.Child.Add(entityComponentList);

            entityComponentList.OnOffsetsFound += delegate
            {
                if (entityComponentList.SearchStatus == OffsetSearchStatus.FoundSingle)
                {
                    Entity.ComponentListOffset = entityComponentList.FoundOffsets[0];
                }
            };

            #endregion

            #region Components Fix

            #region Life

            var lifeComponent = new StructureOffset("LifeComponent", null, maxStructSize: 0x300);
            _initialStates.Add(lifeComponent);

            player.OnOffsetsFound += delegate { lifeComponent.BaseAddress = Entity.GetComponentAddress(player.BaseAddress, "Life"); };

            //var searchMaxHp = new ValueReaderStrategy(new MultipleIntValueReader(
            //    new DefaultValueCompare<int>(97),
            //    new DefaultValueCompare<int>(97)), 4);
            //lifeComponent.Child.Add(new DataOffset("MaxHp", searchMaxHp));     //this will work only when they goes strictly one after another
            //lifeComponent.Child.Add(new DataOffset("CurHp", new ReturnExistingOffsetStrategy(searchMaxHp, 0x4)));

            lifeComponent.Child.Add(new DataOffset("MaxHp",
                                                   new MultipleOffsetsSelectorOffsetSearch(new ValueReaderStrategy(new IntValueReader(new DefaultValueCompare <int>(97)), 4), 2, 0)));

            lifeComponent.Child.Add(new DataOffset("CurHp",
                                                   new MultipleOffsetsSelectorOffsetSearch(new ValueReaderStrategy(new IntValueReader(new DefaultValueCompare <int>(97)), 4), 2, 1)));

            //var searchMaxMana = new ValueReaderStrategy(new MultipleIntValueReader(
            //    new DefaultValueCompare<int>(74),
            //    new DefaultValueCompare<int>(66)), 4);
            //lifeComponent.Child.Add(new DataOffset("MaxMana", searchMaxMana));
            //lifeComponent.Child.Add(new DataOffset("CurMana", new ReturnExistingOffsetStrategy(searchMaxMana, 0x4)));
            lifeComponent.Child.Add(new DataOffset("MaxMana", new ValueReaderStrategy(new IntValueReader(new DefaultValueCompare <int>(74)), 4)));
            lifeComponent.Child.Add(new DataOffset("CurMana", new ValueReaderStrategy(new IntValueReader(new DefaultValueCompare <int>(66)), 4)));

            //var searchReservedMana = new ValueReaderStrategy(new MultipleIntValueReader(
            //    new DefaultValueCompare<int>(0),
            //    new DefaultValueCompare<int>(10)), 4);
            //lifeComponent.Child.Add(new DataOffset("ReservedFlatMana", searchReservedMana));
            //lifeComponent.Child.Add(new DataOffset("ReservedPercentMana", new ReturnExistingOffsetStrategy(searchReservedMana, 0x4)));
            lifeComponent.Child.Add(new DataOffset("ReservedFlatMana", new ValueReaderStrategy(new IntValueReader(new DefaultValueCompare <int>(0)), 4)));
            lifeComponent.Child.Add(new DataOffset("ReservedPercentMana", new ValueReaderStrategy(new IntValueReader(new DefaultValueCompare <int>(10)), 4)));

            //var searchEs = new ValueReaderStrategy(new MultipleIntValueReader(
            //    new DefaultValueCompare<int>(34),
            //    new DefaultValueCompare<int>(34)), 4);
            //lifeComponent.Child.Add(new DataOffset("MaxEs", searchEs));
            //lifeComponent.Child.Add(new DataOffset("CurEs", new ReturnExistingOffsetStrategy(searchEs, 0x4)));
            lifeComponent.Child.Add(new DataOffset("MaxEs", new ValueReaderStrategy(new IntValueReader(new DefaultValueCompare <int>(34)), 4)));
            lifeComponent.Child.Add(new DataOffset("CurEs", new ValueReaderStrategy(new IntValueReader(new DefaultValueCompare <int>(34)), 4)));

            var buffStruct  = StrategyUtils.StringInSubStruct("sand_stance", 0x20, false, false); //todo:set to 0x10
            var buffStruct1 = buffStruct.SubStructSearch(0x20, false);
            var buffStruct2 = buffStruct1.SubStructSearch(0x20, false);
            var buffStruct3 = buffStruct2.SubStructSearch(0x20, false);

            lifeComponent.Child.Add(new StructureOffset("Buffs", buffStruct3, 0x20));

            #endregion

            #region Positioned

            var positionedComponent = new StructureOffset("PositionedComponent", null, maxStructSize: 0x300);

            _initialStates.Add(positionedComponent);
            player.OnOffsetsFound += delegate { positionedComponent.BaseAddress = Entity.GetComponentAddress(player.BaseAddress, "Positioned"); };

            positionedComponent.AddIntSearch("GridPosX", 218);
            positionedComponent.AddIntSearch("GridPosY", 335);
            positionedComponent.AddFloatSearch("WorldPosX", 2375, 50);
            positionedComponent.AddFloatSearch("WorldPosY", 3646.739f, 50);
            positionedComponent.AddFloatSearch("Rotation", 1.570f, 0.02f);
            positionedComponent.AddByteSearch("Reaction", 1);

            #endregion

            #region PlayerComponent

            var playerComponent = new StructureOffset("PlayerComponent", null, maxStructSize: 0x100);

            _initialStates.Add(playerComponent);
            player.OnOffsetsFound += delegate { playerComponent.BaseAddress = Entity.GetComponentAddress(player.BaseAddress, "Player"); };

            playerComponent.AddIntSearch("Exp", 4219);
            playerComponent.AddIntSearch("Strength", 14);
            playerComponent.AddIntSearch("Dexterity", 29);
            playerComponent.AddIntSearch("Intelligence", 32);
            playerComponent.AddIntSearch("Level", 4);

            #endregion

            #endregion
        }