예제 #1
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));
        }
예제 #2
0
        public async Task TrimsAtypicalOutputFromLoadOrder()
        {
            using var tmpFolder  = Utility.GetTempFolder();
            using var dataFolder = Utility.SetupDataFolder(tmpFolder, GameRelease.SkyrimLE);
            ModKey atypicalKey = ModKey.FromNameAndExtension("Atypical.esp");
            var    output      = Path.Combine(tmpFolder.Dir.Path, atypicalKey.FileName);
            var    patcher     = new DummyPatcher();
            await Runner.Run(
                workingDirectory : tmpFolder.Dir.Path,
                outputPath : output,
                dataFolder : dataFolder.Dir.Path,
                release : GameRelease.SkyrimLE,
                loadOrder : Utility.TypicalLoadOrder(GameRelease.SkyrimLE, dataFolder.Dir)
                .And(new LoadOrderListing(Constants.SynthesisModKey, true))
                .And(new LoadOrderListing(atypicalKey, true))
                .And(new LoadOrderListing(Utility.RandomModKey, true)),
                patchers : patcher.AsEnumerable().ToList(),
                cancel : CancellationToken.None);

            Assert.Equal(
                new string[]
            {
                Utility.TestModKey.FileName,
                Utility.OverrideModKey.FileName,
                Constants.SynthesisModKey.FileName,
            }, File.ReadAllLines(Path.Combine(tmpFolder.Dir.Path, "Plugins.txt")));
        }
예제 #3
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));
        }
예제 #4
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));
        }
예제 #5
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));
        }
예제 #6
0
        public void Comparer_Alphabetical_ByNameGreater()
        {
            ModKey k1      = ModKey.FromNameAndExtension("Knights.esm");
            ModKey k2      = ModKey.FromNameAndExtension("Oblivion.esm");
            var    compare = ModKey.AlphabeticalAndMastersFirst;

            Assert.True(compare.Compare(k2, k1) > 0);
        }
예제 #7
0
        public void Comparer_Alphabetical_Equal()
        {
            ModKey k1      = ModKey.FromNameAndExtension("Oblivion.esm");
            ModKey k2      = ModKey.FromNameAndExtension("Oblivion.esm");
            var    compare = ModKey.AlphabeticalAndMastersFirst;

            Assert.Equal(0, compare.Compare(k2, k1));
        }
예제 #8
0
        public void Comparer_Alphabetical_ByMaster()
        {
            ModKey k1      = ModKey.FromNameAndExtension("Oblivion.esm");
            ModKey k2      = ModKey.FromNameAndExtension("Oblivion.esp");
            var    compare = ModKey.AlphabeticalAndMastersFirst;

            Assert.True(compare.Compare(k1, k2) < 0);
        }
예제 #9
0
    public void IteratesContainedFormLinks()
    {
        var mod = new SkyrimMod(ModKey.FromNameAndExtension("Test.esp"), SkyrimRelease.SkyrimSE);
        var npc = mod.Npcs.AddNew();
        var key = FormKey.Factory("123456:Skyrim.esm");

        npc.Class.SetTo(key);
        mod.ContainedFormLinks.Select(x => x.FormKey).Should().Contain(key);
    }
    public void StreamModKeyCtorDoesNotDisposeStream()
    {
        var stream     = new DisposeTesterWrapStream(File.OpenRead(TestDataPathing.SkyrimOverrideMod));
        var mutaStream = new MutagenBinaryReadStream(
            stream,
            ModKey.FromNameAndExtension("Skyrim.esm"),
            GameRelease.SkyrimSE);

        stream.Disposed.Should().BeFalse();
    }
 public IEnumerable <IModListingGetter> Read(Stream stream)
 {
     using var streamReader = new StreamReader(stream);
     while (!streamReader.EndOfStream)
     {
         var str    = streamReader.ReadLine().AsSpan();
         var modKey = ModKey.FromNameAndExtension(str);
         yield return(new ModListing(modKey, enabled: true));
     }
 }
예제 #12
0
 public static IEnumerable <IModListingGetter> ListingsFromPath(
     FilePath cccFilePath,
     DirectoryPath dataPath)
 {
     return(File.ReadAllLines(cccFilePath.Path)
            .Select(x => ModKey.FromNameAndExtension(x))
            .Where(x => File.Exists(Path.Combine(dataPath.Path, x.FileName)))
            .Select(x => new ModListing(x, enabled: true))
            .ToList());
 }
예제 #13
0
        public static IObservable <IChangeSet <IModListingGetter> > GetLiveLoadOrder(
            FilePath cccFilePath,
            DirectoryPath dataFolderPath,
            out IObservable <ErrorResponse> state,
            bool orderListings = true)
        {
            var raw = ObservableExt.WatchFile(cccFilePath.Path)
                      .StartWith(Unit.Default)
                      .Select(_ =>
            {
                try
                {
                    return(GetResponse <IObservable <IChangeSet <ModKey> > > .Succeed(
                               File.ReadAllLines(cccFilePath.Path)
                               .Select(x => ModKey.FromNameAndExtension(x))
                               .AsObservableChangeSet()));
                }
                catch (Exception ex)
                {
                    return(GetResponse <IObservable <IChangeSet <ModKey> > > .Fail(ex));
                }
            })
                      .Replay(1)
                      .RefCount();

            state = raw
                    .Select(r => (ErrorResponse)r);
            var ret = ObservableListEx.And(
                raw
                .Select(r =>
            {
                return(r.Value ?? Observable.Empty <IChangeSet <ModKey> >());
            })
                .Switch(),
                ObservableExt.WatchFolderContents(dataFolderPath.Path)
                .Transform(x =>
            {
                if (ModKey.TryFromNameAndExtension(Path.GetFileName(x), out var modKey))
                {
                    return(TryGet <ModKey> .Succeed(modKey));
                }
                return(TryGet <ModKey> .Failure);
            })
                .Filter(x => x.Succeeded)
                .Transform(x => x.Value)
                .RemoveKey())
                      .Transform <ModKey, IModListingGetter>(x => new ModListing(x, true));

            if (orderListings)
            {
                ret = ret.OrderListings();
            }
            return(ret);
        }
예제 #14
0
        public static string CreateDummyPlugin(string folder, string fileName, Action <SkyrimMod> addRecords)
        {
            Directory.CreateDirectory(folder);
            var outputPath = Path.Combine(folder, fileName);

            var mod = new SkyrimMod(ModKey.FromNameAndExtension(fileName), SkyrimRelease.SkyrimSE);

            addRecords(mod);
            mod.WriteToBinary(outputPath, Utils.SafeBinaryWriteParameters);
            return(fileName);
        }
예제 #15
0
        public void IsApplicable_MatchesDespiteNameHavingDelimiter()
        {
            var release = GameRelease.Fallout4;
            var name    = "SomeName - ExtraTitleNonsense";
            var modKey  = ModKey.FromNameAndExtension($"{name}.esp");

            Archive.IsApplicable(
                release,
                modKey,
                $"{name}{Archive.GetExtension(release)}")
            .Should().BeTrue();
        }
예제 #16
0
        public void ModNameIncludesSpecialSuffix()
        {
            var release = GameRelease.Fallout4;
            var name    = $"SomeName - Textures";
            var modKey  = ModKey.FromNameAndExtension($"{name}.esp");

            Archive.IsApplicable(
                release,
                modKey,
                $"{name}{Archive.GetExtension(release)}")
            .Should().BeTrue();
        }
        public static void ClassifyAThing()
        {
            var theItemFormLink = Skyrim.Ingestible.Ale;

            SkyrimMod masterMod = new(theItemFormLink.FormKey.ModKey, SkyrimRelease.SkyrimSE);

            var theItem = new Ingestible(theItemFormLink.FormKey, masterMod.SkyrimRelease);

            masterMod.Ingestibles.Add(theItem);

            ModKey modKey = ModKey.FromNameAndExtension("Patch.esp");

            ISkyrimMod patchMod = new SkyrimMod(modKey, SkyrimRelease.SkyrimSE);

            var formListLink = GeneralStores.FormList.xGSxAlchCookFLST;
            var flst         = new FormList(formListLink.FormKey, patchMod.SkyrimRelease)
            {
                EditorID = nameof(GeneralStores.FormList.xGSxAlchCookFLST)
            };

            patchMod.FormLists.Add(flst);

            var newRecipe = patchMod.ConstructibleObjects.AddNew("newRecipe");

            (newRecipe.Items ??= new()).Add(new()
            {
                Item = new()
                {
                    Item = theItemFormLink
                }
            });
            newRecipe.WorkbenchKeyword.SetTo(Skyrim.Keyword.CraftingCookpot);

            LoadOrder <IModListing <ISkyrimModGetter> > loadOrder = new()
            {
                new ModListing <ISkyrimMod>(masterMod, true),
                new ModListing <ISkyrimMod>(patchMod, true)
            };

            ILinkCache <ISkyrimMod, ISkyrimModGetter> linkCache = loadOrder.ToImmutableLinkCache();

            var program = new Program(loadOrder, linkCache, patchMod, GameRelease.SkyrimSE, new());


            program.RunPatch();


            var itemLink = patchMod.FormLists.Single().Items.Single();

            Assert.Equal(theItemFormLink, itemLink.Cast <IIngestibleGetter>());
        }
    }
예제 #18
0
        public void Comparer_LoadOrder_Unknown()
        {
            var loadOrder = new LoadOrder <OblivionMod>()
            {
                new OblivionMod(ModKey.FromNameAndExtension("Oblivion.esm")),
                new OblivionMod(ModKey.FromNameAndExtension("Knights.esm")),
            };
            FormKey k1      = FormKey.Factory("00C51A:MyMod.esm");
            FormKey k2      = FormKey.Factory("00C51B:Oblivion.esm");
            var     compare = FormKey.LoadOrderComparer(loadOrder);

            Assert.Throws <ArgumentOutOfRangeException>(() => compare.Compare(k1, k2));
        }
예제 #19
0
        public void Comparer_LoadOrder_FallbackGreater()
        {
            var loadOrder = new LoadOrder <OblivionMod>()
            {
                new OblivionMod(ModKey.FromNameAndExtension("Oblivion.esm")),
                new OblivionMod(ModKey.FromNameAndExtension("Knights.esm")),
            };
            FormKey k1      = FormKey.Factory("00C51A:Oblivion.esm");
            FormKey k2      = FormKey.Factory("00C51B:Oblivion.esm");
            var     compare = FormKey.LoadOrderComparer(loadOrder);

            Assert.True(compare.Compare(k2, k1) > 0);
        }
예제 #20
0
        public void Comparer_ModKeyList_FallbackGreater()
        {
            List <ModKey> modKeys = new List <ModKey>()
            {
                ModKey.FromNameAndExtension("Oblivion.esm"),
                ModKey.FromNameAndExtension("Knights.esm"),
            };
            FormKey k1      = FormKey.Factory("00C51A:Oblivion.esm");
            FormKey k2      = FormKey.Factory("00C51B:Oblivion.esm");
            var     compare = FormKey.LoadOrderComparer(modKeys);

            Assert.True(compare.Compare(k2, k1) > 0);
        }
예제 #21
0
        public void Comparer_ModKeyList_Typical()
        {
            List <ModKey> modKeys = new List <ModKey>()
            {
                ModKey.FromNameAndExtension("Oblivion.esm"),
                ModKey.FromNameAndExtension("Knights.esm"),
            };
            FormKey k1      = FormKey.Factory("00C51A:Oblivion.esm");
            FormKey k2      = FormKey.Factory("00C51A:Knights.esm");
            var     compare = FormKey.LoadOrderComparer(modKeys);

            Assert.True(compare.Compare(k1, k2) < 0);
        }
예제 #22
0
        public void Comparer_LoadOrder_Typical()
        {
            var loadOrder = new LoadOrder <OblivionMod>()
            {
                new OblivionMod(ModKey.FromNameAndExtension("Oblivion.esm")),
                new OblivionMod(ModKey.FromNameAndExtension("Knights.esm")),
            };
            FormKey k1      = FormKey.Factory("00C51A:Oblivion.esm");
            FormKey k2      = FormKey.Factory("00C51A:Knights.esm");
            var     compare = FormKey.LoadOrderComparer(loadOrder);

            Assert.True(compare.Compare(k1, k2) < 0);
        }
예제 #23
0
        public void Comparer_ModKeyList_TypicalGreater()
        {
            List <ModKey> modKeys = new List <ModKey>()
            {
                ModKey.FromNameAndExtension("Oblivion.esm"),
                ModKey.FromNameAndExtension("Knights.esm"),
            };
            ModKey k1      = ModKey.FromNameAndExtension("Oblivion.esm");
            ModKey k2      = ModKey.FromNameAndExtension("Knights.esm");
            var    compare = ModKey.LoadOrderComparer(modKeys);

            Assert.True(compare.Compare(k2, k1) > 0);
        }
예제 #24
0
        public void Comparer_ModKeyList_Unknown()
        {
            List <ModKey> modKeys = new List <ModKey>()
            {
                ModKey.FromNameAndExtension("Oblivion.esm"),
                ModKey.FromNameAndExtension("Knights.esm"),
            };
            ModKey k1      = ModKey.FromNameAndExtension("MyMod.esm");
            ModKey k2      = ModKey.FromNameAndExtension("Oblivion.esm");
            var    compare = ModKey.LoadOrderComparer(modKeys);

            Assert.Throws <ArgumentOutOfRangeException>(() => compare.Compare(k1, k2));
        }
        public void MatchesDespiteNameHavingDelimiter()
        {
            var release = GameRelease.Fallout4;
            var name    = "SomeName - ExtraTitleNonsense";
            var modKey  = ModKey.FromNameAndExtension($"{name}.esp");

            new CheckArchiveApplicability(
                new ArchiveExtensionProvider(
                    new GameReleaseInjection(release)))
            .IsApplicable(
                modKey,
                $"{name}{Archive.GetExtension(release)}")
            .Should().BeTrue();
        }
        public void ModNameIncludesSpecialSuffix()
        {
            var release = GameRelease.Fallout4;
            var name    = $"SomeName - Textures";
            var modKey  = ModKey.FromNameAndExtension($"{name}.esp");

            new CheckArchiveApplicability(
                new ArchiveExtensionProvider(
                    new GameReleaseInjection(release)))
            .IsApplicable(
                modKey,
                $"{name}{Archive.GetExtension(release)}")
            .Should().BeTrue();
        }
예제 #27
0
        public override object?ConvertFrom(ITypeDescriptorContext?context, CultureInfo?culture, object value)
        {
            switch (value)
            {
            case string str:
                return(ModKey.FromNameAndExtension(str));

            case ModPath modPath:
                return(modPath.ModKey);

            default:
                throw new NotImplementedException();
            }
        }
예제 #28
0
        public static string CreateDummyPlugin(string folder, string fileName, Action <SkyrimMod> addRecords)
        {
            Directory.CreateDirectory(folder);
            var outputPath = Path.Combine(folder, fileName);

            var mod = new SkyrimMod(ModKey.FromNameAndExtension(fileName), SkyrimRelease.SkyrimSE);

            addRecords(mod);
            mod.WriteToBinary(outputPath, new BinaryWriteParameters
            {
                MasterFlag  = BinaryWriteParameters.MasterFlagOption.ExceptionOnMismatch,
                RecordCount = BinaryWriteParameters.RecordCountOption.Iterate
            });
            return(fileName);
        }
예제 #29
0
        public static EnumerableModKeySettingsVM Factory(ReflectionSettingsParameters param, FieldMeta fieldMeta, object?defaultVal)
        {
            var defaultKeys = new List <ModKey>();

            if (defaultVal is IEnumerable e)
            {
                foreach (var item in e)
                {
                    defaultKeys.Add(ModKey.FromNameAndExtension(item.ToString()));
                }
            }
            return(new EnumerableModKeySettingsVM(
                       param.DetectedLoadOrder.Transform(x => x.ModKey),
                       fieldMeta,
                       defaultKeys));
        }
        public static void DoNothing()
        {
            ModKey modKey = ModKey.FromNameAndExtension("Patch.esp");

            ISkyrimMod patchMod = new SkyrimMod(modKey, SkyrimRelease.SkyrimSE);

            LoadOrder <IModListing <ISkyrimModGetter> > loadOrder = new()
            {
                new ModListing <ISkyrimMod>(patchMod, true)
            };

            ILinkCache <ISkyrimMod, ISkyrimModGetter> linkCache = loadOrder.ToImmutableLinkCache();

            var program = new Program(loadOrder, linkCache, patchMod, GameRelease.SkyrimSE, new());

            program.RunPatch();
        }