コード例 #1
0
        public void CheckRequiredMods_WhenRequiredVersionInvalid_GetExpectedRequiredMod()
        {
            const string requiredMod          = "SMLHelper";
            const string invalidVersionString = "1.X.0.Y";

            var versionDependentMod = new QMod
            {
                // Mod with a bad version string in its version dependencies.
                VersionDependencies = new Dictionary <string, string>
                {
                    { requiredMod, invalidVersionString }
                }
            };

            var validator = new ManifestValidator();

            validator.CheckRequiredMods(versionDependentMod);

            // The entry is added to RequiredMods but without a minimum version.
            Assert.AreEqual(1, versionDependentMod.RequiredMods.Count());

            RequiredQMod expected = new RequiredQMod(requiredMod);
            RequiredQMod actual   = versionDependentMod.RequiredMods.First();

            Assert.AreEqual(requiredMod, actual.Id);
            Assert.AreEqual(expected.RequiresMinimumVersion, actual.RequiresMinimumVersion);
            Assert.AreEqual(expected.MinimumVersion, actual.MinimumVersion);
        }
コード例 #2
0
        public void CheckRequiredMods_WhenRequirementsRedundant_GetExpectedRequiredMod()
        {
            const string requiredMod           = "SMLHelper";
            const string requiredVersionString = "8.6.7";

            var versionDependentMod = new QMod
            {
                // Mod that redundantly includes the same mod both ID and minimum version.
                // Unnecessary, but should not cause errors.
                Dependencies        = new[] { requiredMod },
                VersionDependencies = new Dictionary <string, string>
                {
                    { requiredMod, requiredVersionString }
                }
            };

            var validator = new ManifestValidator();

            validator.CheckRequiredMods(versionDependentMod);

            // Only a single entry is added to RequiredMods.
            Assert.AreEqual(1, versionDependentMod.RequiredMods.Count());

            RequiredQMod expected = new RequiredQMod(requiredMod, requiredVersionString);
            RequiredQMod actual   = versionDependentMod.RequiredMods.First();

            Assert.AreEqual(requiredMod, actual.Id);
            Assert.AreEqual(expected.RequiresMinimumVersion, actual.RequiresMinimumVersion);
            Assert.AreEqual(expected.MinimumVersion, actual.MinimumVersion);
        }
コード例 #3
0
        public void TestDependencies_SML_CC2_ConfirmCorrectOrder()
        {
            var validator = new ManifestValidator();
            var tree      = new SortedCollection <string, QMod>();

            var cc2 = new QMod
            {
                Id           = "CustomCraft2SML",
                Dependencies = new[] { "SMLHelper" }
            };

            var sml = new QMod
            {
                Id = "SMLHelper"
            };

            validator.CheckRequiredMods(cc2);
            validator.CheckRequiredMods(sml);

            tree.AddSorted(cc2);
            tree.AddSorted(sml);

            List <QMod> list = tree.GetSortedList();

            Console.WriteLine(ListToString(list));

            Assert.AreEqual(2, list.Count);
            Assert.AreEqual("CustomCraft2SML", list[0].Id);
            Assert.AreEqual("SMLHelper", list[1].Id);
        }
コード例 #4
0
        public void TestDependencies_SSS_SE_ConfirmCorrectOrder()
        {
            var validator = new ManifestValidator();
            var tree      = new SortedCollection <string, QMod>();

            var sss = new QMod
            {
                Id         = "SeamothStorageSlots",
                LoadBefore = new[] { "SlotExtender" }
            };

            var se = new QMod
            {
                Id = "SlotExtender"
            };

            validator.CheckRequiredMods(sss);
            validator.CheckRequiredMods(se);

            tree.AddSorted(sss);
            tree.AddSorted(se);

            List <QMod> list = tree.GetSortedList();

            Console.WriteLine(ListToString(list));

            Assert.AreEqual(2, list.Count);
            Assert.AreEqual("SeamothStorageSlots", list[0].Id);
            Assert.AreEqual("SlotExtender", list[1].Id);
        }
コード例 #5
0
        public void CheckRequiredMods_WhenRequiresVersion_GetExpectedRequiredMod()
        {
            const string requiredMod           = "SMLHelper";
            const string requiredVersionString = "8.6.7";

            var versionDependentMod = new QMod
            {
                // Mod that requires a minimum version of another mod.
                VersionDependencies = new Dictionary <string, string>
                {
                    { requiredMod, requiredVersionString }
                }
            };

            var validator = new ManifestValidator();

            validator.CheckRequiredMods(versionDependentMod);

            Assert.AreEqual(1, versionDependentMod.RequiredMods.Count());

            RequiredQMod expected = new RequiredQMod(requiredMod, requiredVersionString);
            RequiredQMod actual   = versionDependentMod.RequiredMods.First();

            Assert.AreEqual(requiredMod, actual.Id);
            Assert.AreEqual(expected.RequiresMinimumVersion, actual.RequiresMinimumVersion);
            Assert.AreEqual(expected.MinimumVersion, actual.MinimumVersion);
        }
コード例 #6
0
        public void TestList_MixedDependenciesAndPreferences_OrderInCycle_PreferenceIgnored_AllModsLinked()
        {
            var tree = new SortedCollection <string, QMod>();

            var coreMod = new QMod
            {
                Id         = "Core",
                LoadBefore = new[] { "NonCore" }
            };

            var nonCoreMod = new QMod
            {
                Id           = "NonCore",
                Dependencies = new[] { "Core" }
            };

            tree.AddSorted(coreMod);
            tree.AddSorted(nonCoreMod);

            List <QMod> list = tree.GetSortedList();

            Console.WriteLine(ListToString(list));

            Assert.AreEqual(2, list.Count);
            Assert.AreEqual("NonCore", list[0].Id);
            Assert.AreEqual("Core", list[1].Id);
        }
コード例 #7
0
 public void SetUpTestMod()
 {
     qmod = new QMod
     {
         Id             = nameof(QMMTests),
         SupportedGame  = QModGame.Subnautica,
         LoadedAssembly = Assembly.GetExecutingAssembly()
     };
 }
コード例 #8
0
        /// <summary>
        /// Validates the that modder has read the documentation.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <param name="mod">The mod.</param>
        /// <exception cref="FatalPatchingException">This modder has not read the documentation and should not be using prepatch/postpatch functions.</exception>
        internal void ValidateSecretPassword(MethodInfo method, QMod mod)
        {
            switch (this.PatchOrder)
            {
            case PatchingOrder.PreInitialize:
            case PatchingOrder.NormalInitialize:
            case PatchingOrder.PostInitialize:
                return;
            }

            /*
             * What is all this for?
             * This is to make sure that modders don't start using elevated PrePatching and PostPatching in place of normal Pre/Post Patching without a second thought.
             * Elevated Pre/Post patching should be reserved for mods that absolutely require it; Primarily, mods that interact with all other mods.
             * Mods that only interact with one or two mods can likely do just fine with basic load order.
             *
             * Now, if you are convinced that your mod should be using these features, then this is what you do.
             */
            using (var md5 = MD5.Create())
            {
                string c1 = method.Name; // Step 1: Start with the name of your pre or post patching method.
                string c2 = mod.Id;      // Step 2: Get the ID of your mod
                string c;

                // Step 3: Check if you are doing a PrePatch or PostPatch
                if (this.PatchOrder < 0)
                {
                    // Step 3 Option A: For a PrePatch, create a string by placing the prepatch method name before the assembly name.
                    c = c1 + c2;
                }
                else
                {
                    // Step 3 Option B: For a PostPatch, create a string by placing the postpatch method name after the assembly name.
                    c = c2 + c1;
                }

                // Step 4: Compute the MD5 Hash of that string
                // You don't need to write code for this. You can do it online: http://onlinemd5.com/
                byte[] inputBytes = Encoding.ASCII.GetBytes(c);
                byte[] hashBytes  = md5.ComputeHash(inputBytes);

                // Step 5: Use the resulting string as the parameter for [QModPrePatch()] or [QModPostPatch()] depending on which one you built.
                var sb = new StringBuilder();
                for (int i = 0; i < hashBytes.Length; i++)
                {
                    sb.Append(hashBytes[i].ToString("X2"));
                }

                if (sb.ToString() != _secretPasword)
                {
                    throw new FatalPatchingException("This modder has not read the documentation and should not be using prepatch/postpatch functions.");
                }
            }
        }
コード例 #9
0
        public void CheckRequiredMods_WhenRequiresNothing_GetEmptyRequiredMods()
        {
            // Mod that requires no other mods.
            var standaloneMod = new QMod();

            var validator = new ManifestValidator();

            validator.CheckRequiredMods(standaloneMod);

            Assert.AreEqual(0, standaloneMod.RequiredMods.Count());
        }
コード例 #10
0
        public void TwoModTest_BothOrdersDefined_GetExpectedOrder()
        {
            Patcher.loadedMods.Clear();
            Patcher.foundMods.Clear();
            Patcher.sortedMods.Clear();
            Patcher.erroredMods.Clear();

            QMod mod1 = new QMod
            {
                Id         = "Mod1",
                LoadBefore = new string[1]
                {
                    "Mod2"
                }
            };

            QMod mod2 = new QMod
            {
                Id        = "Mod2",
                LoadAfter = new string[1]
                {
                    "Mod1"
                }
            };

            Patcher.foundMods = new List <QMod>
            {
                mod2, mod1 // Simulate being picked up in the wrong order
            };

            Patcher.sortedMods = new List <QMod>(Patcher.foundMods);

            foreach (QMod mod in Patcher.foundMods)
            {
                Console.WriteLine("Now Loading: " + mod.Id);
                Patcher.modSortingChain.Clear();
                Assert.IsTrue(Patcher.SortMod(mod));
            }

            foreach (QMod mod in Patcher.sortedMods)
            {
                Console.WriteLine(mod.Id);
            }

            int indexOfMod1 = Patcher.sortedMods.IndexOf(mod1);
            int indexOfMod2 = Patcher.sortedMods.IndexOf(mod2);

            Assert.IsTrue(indexOfMod1 < indexOfMod2);
            Assert.IsTrue(indexOfMod2 > indexOfMod1);
        }
コード例 #11
0
        public void TestDependencies_Multiple_Mod_Dependencies_ConfirmCorrectOrder()
        {
            var validator = new ManifestValidator();
            var tree      = new SortedCollection <string, QMod>();

            var st = new QMod
            {
                Id           = "SpecialtyManifold",
                Dependencies = new[] { "NitrogenMod", "ScubaManifold" }
            };

            var no2 = new QMod
            {
                Id           = "NitrogenMod",
                Dependencies = new[] { "SMLHelper" }
            };

            var sm = new QMod
            {
                Id           = "ScubaManifold",
                Dependencies = new[] { "SMLHelper" }
            };

            var sml = new QMod
            {
                Id = "SMLHelper"
            };

            validator.CheckRequiredMods(st);
            validator.CheckRequiredMods(no2);
            validator.CheckRequiredMods(sm);
            validator.CheckRequiredMods(sml);

            tree.AddSorted(st);
            tree.AddSorted(no2);
            tree.AddSorted(sm);
            tree.AddSorted(sml);

            List <QMod> list = tree.GetSortedList();

            Console.WriteLine(ListToString(list));

            Assert.AreEqual(4, list.Count);
            Assert.AreEqual("SpecialtyManifold", list[0].Id);
            Assert.AreEqual("ScubaManifold", list[1].Id);
            Assert.AreEqual("NitrogenMod", list[2].Id);
            Assert.AreEqual("SMLHelper", list[3].Id);
        }
コード例 #12
0
        public void CreateModStatusList_WhenMissingVersionDependencies_StatusUpdates(string missingOrOutdatedMod, ModStatus expectedStatus)
        {
            // Arange
            var factory = new QModFactory(new DummyPluginCollection(), new DummyValidator())
            {
            };

            var noModsRequired = new RequiredQMod[0];

            var earlyErrors = new List <QMod>
            {
                new QMod {
                    Id = "5", Status = ModStatus.MissingPatchMethod, RequiredMods = noModsRequired
                },
            };

            var modToInspect = new QMod
            {
                Id           = "8",
                Status       = ModStatus.Success,
                RequiredMods = new List <RequiredQMod>
                {
                    new RequiredQMod(missingOrOutdatedMod, "1.0.2")
                }
            };

            var modsToLoad = new List <QMod>
            {
                new QMod {
                    Id = "6", Status = ModStatus.Success, RequiredMods = noModsRequired
                },
                new QMod
                {
                    Id             = "7", Status = ModStatus.Success,
                    ParsedVersion  = new Version(1, 0, 1),
                    LoadedAssembly = Assembly.GetExecutingAssembly(),
                    RequiredMods   = noModsRequired
                },
                modToInspect
            };

            // Act
            List <QMod> combinedList = factory.CreateModStatusList(earlyErrors, modsToLoad);

            // Assert
            Assert.AreEqual(expectedStatus, modToInspect.Status);
        }
コード例 #13
0
        public void TwoModTest_CircularDependency_SortModReturnsFalse()
        {
            Patcher.loadedMods.Clear();
            Patcher.foundMods.Clear();
            Patcher.sortedMods.Clear();
            Patcher.erroredMods.Clear();

            QMod mod1 = new QMod
            {
                Id         = "Mod1",
                LoadBefore = new string[1]
                {
                    "Mod2"
                }
            };

            QMod mod2 = new QMod
            {
                Id         = "Mod2",
                LoadBefore = new string[1]
                {
                    "Mod1"
                }
            };

            Patcher.foundMods = new List <QMod>
            {
                mod2, mod1 // Simulate being picked up in the wrong order
            };

            Patcher.sortedMods = new List <QMod>(Patcher.foundMods);

            // Mod 1
            Console.WriteLine("Now Loading: " + Patcher.foundMods[0].Id);
            Patcher.modSortingChain.Clear();
            Assert.IsTrue(Patcher.SortMod(Patcher.foundMods[0]));

            // Mod 2 - Circular dependency encountered
            Console.WriteLine("Now Loading: " + Patcher.foundMods[1].Id);
            Patcher.modSortingChain.Clear();
            Assert.IsFalse(Patcher.SortMod(Patcher.foundMods[1]));
        }
コード例 #14
0
ファイル: QModFactoryTests.cs プロジェクト: Z4t4r/QModManager
        public void CreateModStatusList_WhenMissingVersionDependencies_StatusUpdates(string missingOrOutdatedMod, ModStatus expectedStatus)
        {
            // Arange
            var earlyErrors = new List <QMod>
            {
                new QMod {
                    Id = "5", Status = ModStatus.MissingPatchMethod
                },
            };

            var modToInspect = new QMod
            {
                Id           = "8",
                Status       = ModStatus.Success,
                RequiredMods = new List <RequiredQMod>
                {
                    new RequiredQMod(missingOrOutdatedMod, new Version(1, 0, 2))
                }
            };

            var modsToLoad = new List <QMod>
            {
                new QMod {
                    Id = "6", Status = ModStatus.Success
                },
                new QMod
                {
                    Id            = "7", Status = ModStatus.Success,
                    ParsedVersion = new Version(1, 0, 1)
                },
                modToInspect
            };

            // Act
            List <QMod> combinedList = QModFactory.CreateModStatusList(earlyErrors, modsToLoad);

            // Assert
            Assert.AreEqual(expectedStatus, modToInspect.Status);
        }
コード例 #15
0
        public void CheckRequiredMods_WhenRequiresIdOnly_GetExpectedRequiredMod()
        {
            const string requiredMod        = "SMLHelper";
            var          simpleDependentMod = new QMod
            {
                // Mod that requires one other mod, only by ID.
                Dependencies = new[] { requiredMod }
            };

            var validator = new ManifestValidator();

            validator.CheckRequiredMods(simpleDependentMod);

            Assert.AreEqual(1, simpleDependentMod.RequiredMods.Count());

            RequiredQMod expected = new RequiredQMod(requiredMod);
            RequiredQMod actual   = simpleDependentMod.RequiredMods.First();

            Assert.AreEqual(requiredMod, actual.Id);
            Assert.AreEqual(expected.RequiresMinimumVersion, actual.RequiresMinimumVersion);
            Assert.AreEqual(expected.MinimumVersion, actual.MinimumVersion);
        }
コード例 #16
0
        public void CheckRequiredMods_WhenRequirementsMixed_GetExpectedRequiredMods()
        {
            const string requiredModA           = "SMLHelper";
            const string requiredModB           = "MoreCyclopsUpgrades";
            const string requiredVersionBString = "8.6.7";

            var versionDependentMod = new QMod
            {
                // Mod that requires one mod by id only and another at a minimum verison.
                Dependencies        = new[] { requiredModA },
                VersionDependencies = new Dictionary <string, string>
                {
                    { requiredModB, requiredVersionBString }
                }
            };

            var validator = new ManifestValidator();

            validator.CheckRequiredMods(versionDependentMod);

            Assert.AreEqual(2, versionDependentMod.RequiredMods.Count());

            RequiredQMod expectedA = new RequiredQMod(requiredModA);
            RequiredQMod actualA   = versionDependentMod.RequiredMods.ElementAt(0);

            Assert.AreEqual(requiredModA, actualA.Id);
            Assert.AreEqual(expectedA.RequiresMinimumVersion, actualA.RequiresMinimumVersion);
            Assert.AreEqual(expectedA.MinimumVersion, actualA.MinimumVersion);

            RequiredQMod expectedB = new RequiredQMod(requiredModB, requiredVersionBString);
            RequiredQMod actualB   = versionDependentMod.RequiredMods.ElementAt(1);

            Assert.AreEqual(requiredModB, actualB.Id);
            Assert.AreEqual(expectedB.RequiresMinimumVersion, actualB.RequiresMinimumVersion);
            Assert.AreEqual(expectedB.MinimumVersion, actualB.MinimumVersion);
        }
コード例 #17
0
 public void ValidateManifest(QMod mod)
 {
 }
コード例 #18
0
 public void CheckRequiredMods(QMod mod)
 {
 }
コード例 #19
0
 public void ValidateBasicManifest(QMod mod)
 {
 }
コード例 #20
0
 public void LoadAssembly(QMod mod)
 {
 }
コード例 #21
0
 public void FindPatchMethods(QMod qMod)
 {
 }
コード例 #22
0
        public void FourModTest()
        {
            Patcher.loadedMods.Clear();
            Patcher.foundMods.Clear();
            Patcher.sortedMods.Clear();
            Patcher.erroredMods.Clear();

            QMod mod1 = new QMod
            {
                Id         = "Mod1",
                LoadBefore = new string[2]
                {
                    "Mod2",
                    "Mod3"
                },
                LoadAfter = new string[1]
                {
                    "Mod4"
                }
            };

            QMod mod2 = new QMod
            {
                Id        = "Mod2",
                LoadAfter = new string[2]
                {
                    "Mod1",
                    "Mod3"
                }
            };

            QMod mod3 = new QMod
            {
                Id = "Mod3"
            };

            QMod mod4 = new QMod
            {
                Id = "Mod4"
            };

            Patcher.foundMods = new List <QMod>
            {
                mod1,
                mod2,
                mod3,
                mod4
            };

            Patcher.sortedMods = new List <QMod>(Patcher.foundMods);

            foreach (QMod mod in Patcher.foundMods)
            {
                Console.WriteLine("Now Loading: " + mod.Id);
                Patcher.modSortingChain.Clear();
                Assert.IsTrue(Patcher.SortMod(mod));
            }

            foreach (QMod mod in Patcher.sortedMods)
            {
                Console.WriteLine(mod.Id);
            }

            int indexOfMod1 = Patcher.sortedMods.IndexOf(mod1);
            int indexOfMod2 = Patcher.sortedMods.IndexOf(mod2);
            int indexOfMod3 = Patcher.sortedMods.IndexOf(mod3);
            int indexOfMod4 = Patcher.sortedMods.IndexOf(mod4);

            Assert.IsTrue(indexOfMod1 < indexOfMod2);
            Assert.IsTrue(indexOfMod1 < indexOfMod3);
            Assert.IsTrue(indexOfMod2 > indexOfMod1);
            Assert.IsTrue(indexOfMod2 > indexOfMod3);
        }