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); } }
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)); }
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")); }
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)); }
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)); }
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)); }
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(); }
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); }
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); }
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); }
public void CanRollback() { var mod = new OblivionMod(Utility.PluginModKey); using var allocator = CreateAllocator(mod); allocator.Rollback(); }
// 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(), });
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); }
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); }
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); }
/// 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 })); }
//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); }
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()); }
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")); }); }
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()); }
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); }
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()); }