Exemple #1
0
        public void MasterOrderSync_EsmFirst()
        {
            WarmupOblivion.Init();
            using var folder = Utility.GetTempFolder(nameof(MasterSync_Tests));
            var obliv     = ModKey.FromNameAndExtension("Oblivion.esm");
            var first     = ModKey.FromNameAndExtension("First.esp");
            var second    = ModKey.FromNameAndExtension("Second.esp");
            var mod       = new OblivionMod(obliv);
            var secondNpc = new Npc(new FormKey(second, 0x123456));

            mod.Npcs.RecordCache.Set(secondNpc);
            var firstNpc = new Npc(new FormKey(first, 0x123456));

            mod.Npcs.RecordCache.Set(firstNpc);
            var modPath = Path.Combine(folder.Dir.Path, obliv.ToString());

            mod.WriteToBinary(modPath,
                              new BinaryWriteParameters()
            {
                ModKey              = BinaryWriteParameters.ModKeyOption.NoCheck,
                MastersListContent  = BinaryWriteParameters.MastersListContentOption.Iterate,
                MastersListOrdering = BinaryWriteParameters.MastersListOrderingOption.MastersFirst,
            });
            using var reimport = OblivionMod.CreateFromBinaryOverlay(modPath);
            Assert.Equal(
                new ModKey[]
            {
                first,
                second,
            },
                reimport.ModHeader.MasterReferences.Select(m => m.Master));
        }
        public void EnumerateDeepLinkInterface()
        {
            var mod = new OblivionMod(Utility.PluginModKey);

            mod.Cells.Records.Add(new CellBlock()
            {
                BlockNumber  = 0,
                GroupType    = GroupTypeEnum.InteriorCellBlock,
                LastModified = 4,
                SubBlocks    =
                {
                    new CellSubBlock()
                    {
                        BlockNumber  = 0,
                        GroupType    = GroupTypeEnum.InteriorCellSubBlock,
                        LastModified = 4,
                        Cells        =
                        {
                            new Cell(mod.GetNextFormKey())
                            {
                                Persistent =
                                {
                                    new PlacedNpc(mod.GetNextFormKey())
                                }
                            }
                        }
                    }
                }
            });
            var conv = ConvertMod(mod);

            Assert.NotEmpty(conv.EnumerateMajorRecords <ICellGetter>());
            Assert.NotEmpty(conv.EnumerateMajorRecords <IPlacedGetter>());
            Assert.Equal(Getter ? 0 : 1, conv.EnumerateMajorRecords <IPlaced>().Count());
        }
        public void OutOfOrderAllocationReturnsSameIdentifiersShared()
        {
            uint formID1, formID2;
            {
                var mod = new OblivionMod(Utility.PluginModKey);
                using var allocator = CreateNamedAllocator(mod, Patcher1);
                var formKey1 = allocator.GetNextFormKey(Utility.Edid1);
                formID1 = formKey1.ID;

                allocator.GetNextFormKey();

                var formKey2 = allocator.GetNextFormKey(Utility.Edid2);
                formID2 = formKey2.ID;

                allocator.Commit();
            }

            {
                var mod = new OblivionMod(Utility.PluginModKey);
                using var allocator = CreateNamedAllocator(mod, Patcher1);

                var formKey2 = allocator.GetNextFormKey(Utility.Edid2);
                Assert.Equal(formID2, formKey2.ID);

                allocator.GetNextFormKey();

                var formKey1 = allocator.GetNextFormKey(Utility.Edid1);
                Assert.Equal(formID1, formKey1.ID);
            }
        }
Exemple #4
0
        public void MasterOrderSync_Typical()
        {
            WarmupOblivion.Init();
            using var folder = Utility.GetTempFolder(nameof(MasterSync_Tests));
            var obliv      = ModKey.FromNameAndExtension("Oblivion.esm");
            var knights    = ModKey.FromNameAndExtension("Knights.esm");
            var other      = ModKey.FromNameAndExtension("Other.esp");
            var mod        = new OblivionMod(obliv);
            var knightsNpc = new Npc(new FormKey(knights, 0x123456));

            mod.Npcs.RecordCache.Set(knightsNpc);
            var otherNpc = new Npc(new FormKey(other, 0x123456));

            mod.Npcs.RecordCache.Set(otherNpc);
            var modPath = Path.Combine(folder.Dir.Path, obliv.ToString());

            mod.WriteToBinary(modPath,
                              new BinaryWriteParameters()
            {
                ModKey             = BinaryWriteParameters.ModKeyOption.NoCheck,
                MastersListContent = BinaryWriteParameters.MastersListContentOption.Iterate,
            });
            using var reimport = OblivionMod.CreateFromBinaryOverlay(modPath);
            Assert.Equal(
                new ModKey[]
            {
                knights,
                other,
            },
                reimport.ModHeader.MasterReferences.Select(m => m.Master));
        }
Exemple #5
0
        public void NonExistentEndpointProperlyConstructs()
        {
            using var temp = Utility.GetTempFolder(this.GetType().Name, nameof(NonExistentEndpointProperlyConstructs));
            var mod = new OblivionMod(Utility.PluginModKey);

            using var allocator = CreateAllocator(mod, Path.Combine(temp.Dir.Path, "DoesntExist"));
        }
Exemple #6
0
        public void MasterListSync_AddMissingToEmpty()
        {
            WarmupOblivion.Init();
            using var folder = TestPathing.GetTempFolder(nameof(MasterSync_Tests));
            var obliv    = ModKey.FromNameAndExtension("Oblivion.esm");
            var knights  = ModKey.FromNameAndExtension("Knights.esm");
            var other    = ModKey.FromNameAndExtension("Other.esp");
            var mod      = new OblivionMod(obliv);
            var otherNpc = new Npc(new FormKey(other, 0x123456));

            mod.Potions.RecordCache.Set(new Potion(new FormKey(obliv, 0x123456)));
            mod.Npcs.RecordCache.Set(otherNpc);
            otherNpc.Race.FormKey = new FormKey(knights, 0x123456);
            var modPath = Path.Combine(folder.Dir.Path, obliv.ToString());

            mod.WriteToBinary(modPath,
                              new BinaryWriteParameters()
            {
                ModKey             = ModKeyOption.NoCheck,
                MastersListContent = MastersListContentOption.Iterate,
            });
            using var reimport = OblivionMod.CreateFromBinaryOverlay(modPath);
            Assert.Equal(2, reimport.MasterReferences.Count);
            Assert.Contains(knights, reimport.MasterReferences.Select(m => m.Master));
            Assert.Contains(other, reimport.MasterReferences.Select(m => m.Master));
        }
Exemple #7
0
        public void MasterFlagSync_Correct()
        {
            WarmupOblivion.Init();
            using var folder = TestPathing.GetTempFolder(nameof(MasterSync_Tests));
            var masterMod  = new OblivionMod(new ModKey("Test", ModType.Master));
            var masterPath = Path.Combine(folder.Dir.Path, "Test.esm");

            masterMod.WriteToBinary(masterPath,
                                    new BinaryWriteParameters()
            {
                ModKey             = ModKeyOption.ThrowIfMisaligned,
                MastersListContent = MastersListContentOption.NoCheck,
            });
            using var reimport = OblivionMod.CreateFromBinaryOverlay(masterPath);
            Assert.True(reimport.ModHeader.Flags.HasFlag(OblivionModHeader.HeaderFlag.Master));
            var childMod  = new OblivionMod(new ModKey("Test", ModType.Plugin));
            var childPath = Path.Combine(folder.Dir.Path, "Test.esp");

            childMod.WriteToBinary(childPath,
                                   new BinaryWriteParameters()
            {
                ModKey             = ModKeyOption.ThrowIfMisaligned,
                MastersListContent = MastersListContentOption.NoCheck,
            });
            using var reimport2 = OblivionMod.CreateFromBinaryOverlay(childPath);
            Assert.False(reimport2.ModHeader.Flags.HasFlag(OblivionModHeader.HeaderFlag.Master));
        }
Exemple #8
0
        public void MasterOrderSync_ByLoadOrder()
        {
            WarmupOblivion.Init();
            using var folder = TestPathing.GetTempFolder(nameof(MasterSync_Tests));
            var obliv  = ModKey.FromNameAndExtension("Oblivion.esm");
            var esm    = ModKey.FromNameAndExtension("First.esm");
            var esp    = ModKey.FromNameAndExtension("Second.esp");
            var mod    = new OblivionMod(obliv);
            var espNpc = new Npc(new FormKey(esp, 0x123456));

            mod.Npcs.RecordCache.Set(espNpc);
            var esmNpc = new Npc(new FormKey(esm, 0x123456));

            mod.Npcs.RecordCache.Set(esmNpc);
            var modPath   = Path.Combine(folder.Dir.Path, obliv.ToString());
            var loadOrder = new ModKey[]
            {
                esm,
                esp,
            };

            mod.WriteToBinary(modPath,
                              new BinaryWriteParameters()
            {
                ModKey              = ModKeyOption.NoCheck,
                MastersListContent  = MastersListContentOption.Iterate,
                MastersListOrdering = new MastersListOrderingByLoadOrder(loadOrder)
            });
            using var reimport = OblivionMod.CreateFromBinaryOverlay(modPath);
            Assert.Equal(
                loadOrder,
                reimport.ModHeader.MasterReferences.Select(m => m.Master));
        }
Exemple #9
0
        public void EnumerateDeepMajorRecordType()
        {
            var mod    = new OblivionMod(Utility.PluginModKey);
            var placed = new PlacedNpc(mod);

            mod.Cells.Records.Add(new CellBlock()
            {
                BlockNumber  = 0,
                GroupType    = GroupTypeEnum.InteriorCellBlock,
                LastModified = 4,
                SubBlocks    =
                {
                    new CellSubBlock()
                    {
                        BlockNumber  = 0,
                        GroupType    = GroupTypeEnum.InteriorCellSubBlock,
                        LastModified = 4,
                        Cells        =
                        {
                            new Cell(mod.GetNextFormKey())
                            {
                                Persistent =
                                {
                                    placed
                                }
                            }
                        }
                    }
                }
            });
            var conv = ConvertMod(mod);

            conv.EnumerateMajorRecords <IOblivionMajorRecordGetter>().Any(p => p.FormKey == placed.FormKey).Should().BeTrue();
        }
Exemple #10
0
        public void AllocatesSameFormKeyAfterLoad()
        {
            uint nextFormID = 123;

            FormKey expectedFormKey;
            {
                var mod = new OblivionMod(Utility.PluginModKey);
                ((IMod)mod).NextFormID = nextFormID;

                using var allocator = CreateAllocator(mod);

                expectedFormKey = allocator.GetNextFormKey();

                allocator.Commit();
            }

            {
                var mod = new OblivionMod(Utility.PluginModKey);
                ((IMod)mod).NextFormID = nextFormID;

                using var allocator = CreateAllocator(mod);

                var formKey = allocator.GetNextFormKey();

                Assert.Equal(expectedFormKey, formKey);
            }
        }
        public void TypicalImport()
        {
            using var file = new TempFile(extraDirectoryPaths: Utility.TempFolderPath);
            uint nextID = 123;

            File.WriteAllLines(
                file.File.Path,
                new string[]
            {
                nextID.ToString(),
                Utility.Edid1,
                Utility.Form1.ToString(),
                Utility.Edid2,
                Utility.Form2.ToString(),
            });
            var mod       = new OblivionMod(Utility.PluginModKey);
            var allocator = TextFileFormKeyAllocator.FromFile(mod, file.File.Path);
            var formID    = allocator.GetNextFormKey();

            Assert.Equal(nextID, formID.ID);
            Assert.Equal(Utility.PluginModKey, formID.ModKey);
            formID = allocator.GetNextFormKey(Utility.Edid1);
            Assert.Equal(formID, Utility.Form1);
            formID = allocator.GetNextFormKey(Utility.Edid2);
            Assert.Equal(formID, Utility.Form2);
        }
        public void TypicalReimport()
        {
            uint nextID = 123;
            var  list   = new KeyValuePair <string, FormKey>[]
            {
                new KeyValuePair <string, FormKey>(Utility.Edid1, Utility.Form1),
                new KeyValuePair <string, FormKey>(Utility.Edid2, Utility.Form2),
            };

            using var file = new TempFile(extraDirectoryPaths: Utility.TempFolderPath);
            TextFileFormKeyAllocator.WriteToFile(
                file.File.Path,
                nextID,
                list);
            var mod       = new OblivionMod(Utility.PluginModKey);
            var allocator = TextFileFormKeyAllocator.FromFile(mod, file.File.Path);
            var formID    = allocator.GetNextFormKey();

            Assert.Equal(nextID, formID.ID);
            Assert.Equal(Utility.PluginModKey, formID.ModKey);
            formID = allocator.GetNextFormKey(Utility.Edid1);
            Assert.Equal(formID, Utility.Form1);
            formID = allocator.GetNextFormKey(Utility.Edid2);
            Assert.Equal(formID, Utility.Form2);
        }
Exemple #13
0
        public async Task RunTwice()
        {
            using var tmpFolder  = Utility.GetTempFolder();
            using var dataFolder = Utility.SetupDataFolder(tmpFolder, GameRelease.Oblivion);
            var outputFile = Utility.TypicalOutputFile(tmpFolder);
            var settings   = new CodeSnippetPatcherSettings()
            {
                On       = true,
                Code     = @"state.PatchMod.Npcs.AddNew();",
                Nickname = "UnitTests",
            };

            for (int i = 0; i < 2; i++)
            {
                var snippet = new CodeSnippetPatcherRun(settings);
                await snippet.Prep(GameRelease.Oblivion, CancellationToken.None);

                await snippet.Run(new RunSynthesisPatcher()
                {
                    OutputPath        = ModPath.FromPath(outputFile),
                    DataFolderPath    = dataFolder.Dir.Path,
                    GameRelease       = GameRelease.Oblivion,
                    LoadOrderFilePath = Utility.PathToLoadOrderFile,
                    SourcePath        = i == 1 ? outputFile.Path : null
                }, CancellationToken.None);
            }
            using var mod = OblivionMod.CreateFromBinaryOverlay(outputFile);
            Assert.Equal(2, mod.Npcs.Count);
        }
Exemple #14
0
        public static async Task OblivionESM_GroupMask_Export(TestingSettings settings, Target target)
        {
            var mod = OblivionMod.CreateFromBinary(
                new ModPath(
                    Mutagen.Bethesda.Oblivion.Constants.Oblivion,
                    Path.Combine(settings.DataFolderLocations.Oblivion, target.Path)));

            using var tmp = new TempFolder("Mutagen_Oblivion_Binary_GroupMask_Export");
            var oblivionOutputPath = Path.Combine(tmp.Dir.Path, TestingConstants.OBLIVION_ESM);

            mod.WriteToBinary(
                oblivionOutputPath,
                importMask: new GroupMask()
            {
                Npcs = true
            });
            var fileLocs = RecordLocator.GetFileLocations(oblivionOutputPath, GameRelease.Oblivion);

            using var reader = new BinaryReadStream(oblivionOutputPath);
            foreach (var rec in fileLocs.ListedRecords.Keys)
            {
                reader.Position = rec;
                var t = HeaderTranslation.ReadNextRecordType(reader);
                if (!t.Equals(Oblivion.Internals.RecordTypes.NPC_))
                {
                    throw new ArgumentException("Exported a non-NPC record.");
                }
            }
        }
        public static void DoSomeModifications(string pathToMod, string pathToExport, Action <string> output)
        {
            IArmorGetter sourceArmor;

            using (var mod = OblivionMod.CreateFromBinaryOverlay(pathToMod))
            {
                sourceArmor = mod.Armors.Records.FirstOrDefault();
            }
            if (sourceArmor == null)
            {
                return;
            }

            OblivionMod outgoingMod = new OblivionMod(new ModKey("Outgoing", master: false));

            // Can override by just making a copy, and modifying the copy. It will have the FormKey of the
            // original, so when added to our outgoing mod it will be considered an override.
            // Note: a cast is required here currently, but will eventually be unnecessary
            var armorOverride = sourceArmor.DeepCopy() as IArmor;

            armorOverride.Name = $"Overridden {sourceArmor.Name}";

            // By duplicating it, we instead create a copy with a new FormKey, originating from our outgoing mod.
            // This creates a record duplication, rather than an override
            var armorDuplicate = outgoingMod.Armors.AddNew();

            armorDuplicate.DeepCopyIn(sourceArmor);
            armorDuplicate.Name = $"Duplicated {sourceArmor.Name}";

            // Export both the overridden original record, as well as a duplicate new record
            outgoingMod.WriteToBinary(pathToExport);
        }
Exemple #16
0
        public void CanRollback()
        {
            var mod = new OblivionMod(Utility.PluginModKey);

            using var allocator = CreateAllocator(mod);

            allocator.Rollback();
        }
Exemple #17
0
 // TODO surely there's got to be a better way?
 static TMod NewMod(string name, TModGetter template)
 {
     return(template switch
     {
         SkyrimMod skyrimMod => (TMod)NewSkyrimMod(name, skyrimMod),
         OblivionMod oblivionMod => (TMod)NewOblivionMod(name, oblivionMod),
         _ => throw new NotImplementedException(),
     });
Exemple #18
0
        protected override async Task <IMod> ImportCopyIn(FilePath file)
        {
            var wrapper = OblivionMod.CreateFromBinaryOverlay(file.Path);
            var ret     = new OblivionMod(this.ModKey);

            ret.DeepCopyIn(wrapper);
            return(ret);
        }
Exemple #19
0
        protected override IOblivionModGetter ConvertMod(OblivionMod mod)
        {
            var stream = new MemoryTributary();

            mod.WriteToBinary(stream);
            stream.Position = 0;
            return(OblivionMod.CreateFromBinaryOverlay(stream, mod.ModKey));
        }
        public void AddNew()
        {
            var mod = new OblivionMod(TestConstants.PluginModKey);
            var rec = mod.Npcs.AddNew();

            Assert.Equal(1, mod.Npcs.Count);
            Assert.Same(mod.Npcs.Records.First(), rec);
        }
        public void AddWithFormKey()
        {
            var mod = new OblivionMod(TestConstants.PluginModKey);
            var rec = mod.Npcs.AddNew(TestConstants.Form1);

            Assert.Equal(1, mod.Npcs.Count);
            Assert.Same(mod.Npcs.Records.First(), rec);
            rec.FormKey.Should().Be(TestConstants.Form1);
        }
        public void AddNew_DifferentForSecond()
        {
            var mod  = new OblivionMod(TestConstants.PluginModKey);
            var rec  = mod.Npcs.AddNew();
            var rec2 = mod.Npcs.AddNew();

            Assert.Equal(2, mod.Npcs.Count);
            Assert.NotSame(rec, rec2);
        }
Exemple #23
0
        public void AddWithFormKey()
        {
            var mod = new OblivionMod(Utility.PluginModKey);
            var rec = mod.Npcs.AddNew(Utility.Form1);

            Assert.Equal(1, mod.Npcs.Count);
            Assert.Same(mod.Npcs.Records.First(), rec);
            rec.FormKey.Should().BeEquivalentTo(Utility.Form1);
        }
Exemple #24
0
 /// This route will load a mod's contents, and fill an object's fields in memory with the parsed content.
 /// As such, it needs a hint of what you're interested in importing, so it can skip unrelated record types.
 ///
 /// Downsides to this method is that all the records need to live in memory as parsed and filled objects.  This can
 /// be a surprising amount in some cases.  Unless the fields are going to be accessed many times each, this import
 /// method should be avoided.
 public static async Task <IOblivionModGetter> ImportIntoInMemoryObject(string pathToMod)
 {
     return(await OblivionMod.CreateFromBinary(
                pathToMod,
                importMask : new GroupMask()
     {
         NPCs = true
     }));
 }
Exemple #25
0
        //public static async Task BaseGroupIterator(Target settings, DataFolderLocations locs)
        //{
        //    if (!settings.ExpectedBaseGroupCount.TryGet(out var expected)) return;
        //    var loc = settings.GetFilePath(locs);
        //    using var stream = new MutagenBinaryReadStream(loc.Path, settings.GameRelease);
        //    var grups = RecordLocator.IterateBaseGroupLocations(stream).ToArray();
        //    Assert.Equal(expected, grups.Length);
        //}

        public static async Task RecordEnumerations(TestingSettings settings, Target target)
        {
            var mod = OblivionMod.CreateFromBinaryOverlay(
                Path.Combine(settings.DataFolderLocations.Oblivion, target.Path));
            var set1 = new HashSet <FormKey>(mod.EnumerateMajorRecords().Select(m => m.FormKey));
            var set2 = new HashSet <FormKey>(mod.EnumerateMajorRecords <IMajorRecordCommonGetter>().Select(m => m.FormKey));

            set1.Count.Should().Equals(set2.Count);
            set1.Should().Equals(set2);
        }
Exemple #26
0
        public void EnumerateAll()
        {
            var mod = new OblivionMod(Utility.PluginModKey);

            mod.Npcs.AddNew();
            mod.Ammunitions.AddNew();
            var conv = ConvertMod(mod);

            Assert.Equal(2, conv.EnumerateMajorRecords().Count());
        }
Exemple #27
0
        public void NonExistentParentDirThrows()
        {
            using var temp = Utility.GetTempFolder(this.GetType().Name, nameof(NonExistentEndpointProperlyConstructs));
            var mod = new OblivionMod(Utility.PluginModKey);

            Assert.ThrowsAny <Exception>(() =>
            {
                CreateAllocator(mod, Path.Combine(temp.Dir.Path, "DoesntExist", "AlsoDoesntExist"));
            });
        }
Exemple #28
0
        public void Typeless_Typical()
        {
            var mod  = new OblivionMod(TestConstants.PluginModKey);
            var npc1 = mod.Npcs.AddNew();
            var npc2 = mod.Npcs.AddNew();

            mod.Remove(npc2.FormKey);
            Assert.Single(mod.Npcs);
            Assert.Same(npc1, mod.Npcs.First());
        }
Exemple #29
0
        public void DuplicateAllocationThrows()
        {
            var mod       = new OblivionMod(Utility.PluginModKey);
            var allocator = CreateAllocator(mod);

            var formKey1 = allocator.GetNextFormKey(Utility.Edid1);

            var e = Assert.Throws <ConstraintException>(() => allocator.GetNextFormKey(Utility.Edid1));

            DisposeFormKeyAllocator(allocator);
        }
Exemple #30
0
        public void EnumerateLinkInterface()
        {
            var mod = new OblivionMod(Utility.PluginModKey);

            mod.Factions.AddNew();
            var conv = ConvertMod(mod);

            Assert.NotEmpty(conv.EnumerateMajorRecords <IFactionGetter>());
            Assert.NotEmpty(conv.EnumerateMajorRecords <IOwnerGetter>());
            Assert.Equal(Getter ? 0 : 1, conv.EnumerateMajorRecords <IOwner>().Count());
        }