private static PluginListingsProvider PluginListingsProvider(
            IDataDirectoryProvider dataDirectory,
            IGameReleaseContext gameContext,
            IPluginListingsPathProvider listingsPathProvider,
            bool throwOnMissingMods,
            IFileSystem fs)
        {
            var pluginListingParser = new PluginListingsParser(
                new ModListingParser(
                    new HasEnabledMarkersProvider(gameContext)));
            var provider = new PluginListingsProvider(
                gameContext,
                new TimestampedPluginListingsProvider(
                    new TimestampAligner(fs),
                    new TimestampedPluginListingsPreferences()
            {
                ThrowOnMissingMods = throwOnMissingMods
            },
                    new PluginRawListingsReader(
                        fs,
                        pluginListingParser),
                    dataDirectory,
                    listingsPathProvider),
                new EnabledPluginListingsProvider(
                    new PluginRawListingsReader(
                        fs,
                        pluginListingParser),
                    listingsPathProvider));

            return(provider);
        }
Beispiel #2
0
 public LoadOrderFilePathDecorator(
     IPluginListingsPathProvider provider,
     RunPatcherPipelineInstructions instructions)
 {
     Provider     = provider;
     Instructions = instructions;
 }
Beispiel #3
0
        public PluginsTxtMissingVm(
            ILogger logger,
            IPluginListingsPathProvider listingsPathProvider)
        {
            PluginFilePath = listingsPathProvider.Path;
            _InError       = Noggog.ObservableExt.WatchFile(PluginFilePath)
                             .StartWith(Unit.Default)
                             .Select(_ =>
            {
                try
                {
                    return(!File.Exists(PluginFilePath));
                }
                catch (Exception e)
                {
                    logger.Error(e, "Error checking for plugin.txt existence");
                    return(true);
                }
            })
                             .ToGuiProperty(this, nameof(InError), deferSubscription: true);

            ErrorString = $"Could not find plugin file to read the load order from. \n\n" +
                          $"- Run your game once, to generate the file\n" +
                          $"- If using MO2, make sure Synthesis is being started through MO2";
        }
 public EnabledPluginListingsProvider(
     IPluginRawListingsReader reader,
     IPluginListingsPathProvider pluginListingsPath)
 {
     Reader             = reader;
     PluginListingsPath = pluginListingsPath;
 }
Beispiel #5
0
 public PluginLiveLoadOrderProvider(
     IFileSystem fileSystem,
     IPluginListingsProvider listingsProvider,
     IPluginListingsPathProvider pluginListingsFilePath)
 {
     _fileSystem             = fileSystem;
     _listingsProvider       = listingsProvider;
     _pluginListingsFilePath = pluginListingsFilePath;
 }
 public void Typical(
     [Frozen] IPluginListingsPathProvider pathProvider,
     [Frozen] IPluginRawListingsReader reader,
     IEnumerable <IModListingGetter> listings,
     EnabledPluginListingsProvider sut)
 {
     reader.Read(pathProvider.Path).Returns(listings);
     sut.Get()
     .Should().Equal(listings);
 }
Beispiel #7
0
 public TimestampedPluginListingsProvider(
     ITimestampAligner timestampAligner,
     ITimestampedPluginListingsPreferences prefs,
     IPluginRawListingsReader rawListingsReader,
     IDataDirectoryProvider dataDirectoryProvider,
     IPluginListingsPathProvider pluginListingsPathProvider)
 {
     Aligner              = timestampAligner;
     Prefs                = prefs;
     RawListingsReader    = rawListingsReader;
     DirectoryProvider    = dataDirectoryProvider;
     ListingsPathProvider = pluginListingsPathProvider;
 }
Beispiel #8
0
 public GameEnvironmentProvider(
     IGameReleaseContext gameReleaseContext,
     ILoadOrderImporter loadOrderImporter,
     IDataDirectoryProvider dataDirectoryProvider,
     IPluginListingsPathProvider pluginListingsPathProvider,
     ICreationClubListingsPathProvider cccPath)
 {
     _gameReleaseContext         = gameReleaseContext;
     _loadOrderImporter          = loadOrderImporter;
     _dataDirectoryProvider      = dataDirectoryProvider;
     _pluginListingsPathProvider = pluginListingsPathProvider;
     _cccPath = cccPath;
 }
        public ProfileLoadOrder(
            ILogger logger,
            ILiveLoadOrderProvider liveLoadOrderProvider,
            IPluginListingsPathProvider listingsPathProvider,
            IProfileIdentifier ident,
            IProfileDataFolderVm dataFolder)
        {
            var loadOrderResult = dataFolder.WhenAnyValue(x => x.DataFolderResult)
                                  .ObserveOn(RxApp.TaskpoolScheduler)
                                  .Select(x =>
            {
                if (x.Failed)
                {
                    return(Results: Observable.Empty <IChangeSet <ReadOnlyModListingVM> >(), State: Observable.Return(ErrorResponse.Fail("Data folder not set")));
                }
                logger.Error("Getting live load order for {Release}. DataDirectory: {DataDirectory}, Plugin File Path: {PluginFilePath}", ident.Release, x.Value, listingsPathProvider.Path);
                var liveLo = liveLoadOrderProvider.Get(out var errors)
                             .Transform(listing => new ReadOnlyModListingVM(listing, x.Value))
                             .DisposeMany();
                return(Results: liveLo, State: errors);
            })
                                  .StartWith((Results: Observable.Empty <IChangeSet <ReadOnlyModListingVM> >(), State: Observable.Return(ErrorResponse.Fail("Load order uninitialized"))))
                                  .Replay(1)
                                  .RefCount();

            loadOrderResult.Select(lo => lo.State)
            .Switch()
            .Subscribe(loErr =>
            {
                if (loErr.Succeeded)
                {
                    logger.Information("Load order location successful");
                }
                else
                {
                    logger.Information("Load order location error: {Reason}", loErr.Reason);
                }
            })
            .DisposeWith(this);

            LoadOrder = loadOrderResult
                        .Select(x => x.Results)
                        .Switch()
                        .ObserveOnGui()
                        .AsObservableList();

            _state = loadOrderResult
                     .Select(x => x.State)
                     .Switch()
                     .ToGuiProperty(this, nameof(State), ErrorResponse.Success, deferSubscription: true);
        }
        public void LiveLoadOrder_DontReorderPluginsFile(
            [Frozen] IScheduler scheduler,
            [Frozen] MockFileSystem fs,
            [Frozen] ILiveLoadOrderTimings timings,
            [Frozen] IPluginListingsPathProvider pluginPath,
            [Frozen] IDataDirectoryProvider dataDir,
            [Frozen] ICreationClubListingsPathProvider cccPath)
        {
            fs.File.WriteAllText(Path.Combine(dataDir.Path, TestConstants.Skyrim.FileName), string.Empty);
            fs.File.WriteAllText(Path.Combine(dataDir.Path, TestConstants.LightMasterModKey.FileName), string.Empty);
            fs.File.WriteAllLines(pluginPath.Path,
                                  new string[]
            {
                $"*{TestConstants.PluginModKey}",
                $"*{TestConstants.MasterModKey}",
                $"*{TestConstants.PluginModKey2}",
            });
            fs.File.WriteAllLines(cccPath.Path,
                                  new string[]
            {
                TestConstants.LightMasterModKey.ToString(),
                TestConstants.LightMasterModKey2.ToString(),
            });
            var live = LoadOrder.GetLiveLoadOrder(
                GameRelease.SkyrimSE,
                pluginPath.Path,
                dataDir.Path,
                out var state,
                cccLoadOrderFilePath: cccPath.Path,
                scheduler: scheduler,
                fileSystem: fs,
                timings: timings);
            var list = live.AsObservableList();

            list.Items.Select(x => x.ModKey).Should().Equal(new ModKey[]
            {
                TestConstants.Skyrim,
                TestConstants.LightMasterModKey,
                TestConstants.PluginModKey,
                TestConstants.MasterModKey,
                TestConstants.PluginModKey2,
            });
        }
        public FileSyncedLoadOrderVM(
            IPluginLiveLoadOrderProvider liveLoadOrderProvider,
            ILoadOrderWriter writer,
            IPluginListingsPathProvider pluginPathContext,
            IDataDirectoryProvider dataDirectoryContext)
        {
            var loadOrder = liveLoadOrderProvider.Get(out var state)
                            .Transform(x => new FileSyncedLoadOrderListingVM(dataDirectoryContext, x))
                            .RefCount();

            _State = state
                     .ToGuiProperty(this, nameof(State), ErrorResponse.Fail("Uninitialized"));

            LoadOrder = loadOrder
                        .ToObservableCollection(this);

            // When listings change, resave to file
            Observable.Merge(
                loadOrder
                .AutoRefresh(x => x.Enabled)
                .Transform(x => x.Enabled, transformOnRefresh: true)
                .BufferInitial(TimeSpan.FromMilliseconds(500), RxApp.MainThreadScheduler)
                .QueryWhenChanged(x => x)
                .Unit(),
                loadOrder
                .AutoRefresh(x => x.GhostSuffix)
                .Transform(x => x.GhostSuffix ?? string.Empty, transformOnRefresh: true)
                .BufferInitial(TimeSpan.FromMilliseconds(500), RxApp.MainThreadScheduler)
                .QueryWhenChanged(x => x)
                .Unit())
            .Throttle(TimeSpan.FromMilliseconds(500), RxApp.MainThreadScheduler)
            .Select(x => LoadOrder.Select(x => new ModListing(x.ModKey, x.Enabled, x.GhostSuffix)).ToArray())
            .DistinctUntilChanged(new SequenceEqualityComparer())
            .Subscribe(x =>
            {
                writer.Write(
                    pluginPathContext.Path,
                    LoadOrder);
            });
        }
        public void LiveLoadOrder_PluginsCCListingReorders(
            [Frozen] IScheduler scheduler,
            [Frozen] MockFileSystemWatcher watcher,
            [Frozen] MockFileSystem fs,
            [Frozen] IImplicitListingModKeyProvider implicitListingsProvider,
            [Frozen] ILiveLoadOrderTimings timings,
            [Frozen] IPluginListingsPathProvider pluginPath,
            [Frozen] IDataDirectoryProvider dataDir,
            [Frozen] ICreationClubListingsPathProvider cccPath)
        {
            var implicitKeys = implicitListingsProvider.Listings.ToArray();

            foreach (var implicitListing in implicitKeys)
            {
                fs.File.WriteAllText(Path.Combine(dataDir.Path, implicitListing.FileName), string.Empty);
            }
            fs.File.WriteAllText(Path.Combine(dataDir.Path, TestConstants.LightMasterModKey.FileName), string.Empty);
            fs.File.WriteAllText(Path.Combine(dataDir.Path, TestConstants.LightMasterModKey2.FileName), string.Empty);
            fs.File.WriteAllLines(pluginPath.Path,
                                  new string[]
            {
                $"*{TestConstants.MasterModKey}",
                $"*{TestConstants.PluginModKey}",
            });
            fs.File.WriteAllLines(cccPath.Path,
                                  new string[]
            {
                TestConstants.LightMasterModKey.ToString(),
                TestConstants.LightMasterModKey2.ToString(),
            });
            var live = LoadOrder.GetLiveLoadOrder(
                GameRelease.SkyrimSE,
                pluginPath.Path,
                dataDir.Path,
                out var state,
                scheduler: scheduler,
                cccLoadOrderFilePath: cccPath.Path,
                fileSystem: fs,
                timings: timings);
            var list = live.AsObservableList();

            list.Items.Select(x => x.ModKey).Should().Equal(
                implicitKeys.Concat(
                    new ModKey[]
            {
                TestConstants.LightMasterModKey,
                TestConstants.LightMasterModKey2,
                TestConstants.MasterModKey,
                TestConstants.PluginModKey,
            }));

            fs.File.WriteAllLines(pluginPath.Path,
                                  new string[]
            {
                $"*{TestConstants.MasterModKey}",
                $"*{TestConstants.PluginModKey}",
                $"{TestConstants.LightMasterModKey}",
            });
            watcher.MarkChanged(pluginPath.Path);
            list.Items.Select(x => x.ModKey).Should().Equal(
                implicitKeys.Concat(
                    new ModKey[] {
                TestConstants.LightMasterModKey2,
                TestConstants.LightMasterModKey,
                TestConstants.MasterModKey,
                TestConstants.PluginModKey,
            }));

            fs.File.WriteAllLines(pluginPath.Path,
                                  new string[]
            {
                $"*{TestConstants.MasterModKey}",
                $"*{TestConstants.PluginModKey}",
                $"{TestConstants.LightMasterModKey}",
                $"{TestConstants.LightMasterModKey2}",
            });
            watcher.MarkChanged(pluginPath.Path);
            list.Items.Select(x => x.ModKey).Should().Equal(
                implicitKeys.Concat(
                    new ModKey[]
            {
                TestConstants.LightMasterModKey,
                TestConstants.LightMasterModKey2,
                TestConstants.MasterModKey,
                TestConstants.PluginModKey,
            }));
        }
        public void LiveLoadOrder(
            [Frozen] IScheduler scheduler,
            [Frozen] MockFileSystemWatcher watcher,
            [Frozen] MockFileSystem fs,
            [Frozen] ILiveLoadOrderTimings timings,
            [Frozen] IPluginListingsPathProvider pluginPath,
            [Frozen] IDataDirectoryProvider dataDir,
            [Frozen] ICreationClubListingsPathProvider cccPath)
        {
            var implicitKey      = Implicits.Get(GameRelease.SkyrimSE).Listings.First();
            var lightMasterPath  = Path.Combine(dataDir.Path, TestConstants.LightMasterModKey.FileName);
            var lightMaster2Path = Path.Combine(dataDir.Path, TestConstants.LightMasterModKey2.FileName);
            var master2Path      = Path.Combine(dataDir.Path, TestConstants.MasterModKey2.FileName);

            fs.File.WriteAllText(lightMasterPath, string.Empty);
            fs.File.WriteAllText(Path.Combine(dataDir.Path, TestConstants.Skyrim.FileName), string.Empty);
            fs.File.WriteAllLines(pluginPath.Path,
                                  new string[]
            {
                $"*{TestConstants.MasterModKey}",
                $"*{TestConstants.MasterModKey2}",
                $"*{TestConstants.PluginModKey}",
            });
            fs.File.WriteAllLines(cccPath.Path,
                                  new string[]
            {
                TestConstants.LightMasterModKey.ToString(),
                TestConstants.LightMasterModKey2.ToString(),
            });
            var live = LoadOrder.GetLiveLoadOrder(
                GameRelease.SkyrimSE,
                pluginPath.Path,
                dataDir.Path,
                out var state,
                scheduler: scheduler,
                cccLoadOrderFilePath: cccPath.Path,
                timings: timings,
                fileSystem: fs);

            state.Subscribe(x =>
            {
                if (x.Failed)
                {
                    throw x.Exception ?? new Exception();
                }
            });
            var list = live.AsObservableList();

            list.Items.Select(x => x.ModKey).Should().Equal(new ModKey[]
            {
                implicitKey,
                TestConstants.LightMasterModKey,
                TestConstants.MasterModKey,
                TestConstants.MasterModKey2,
                TestConstants.PluginModKey,
            });

            fs.File.WriteAllLines(pluginPath.Path,
                                  new string[]
            {
                $"*{TestConstants.MasterModKey}",
                $"*{TestConstants.PluginModKey}",
            });
            watcher.MarkChanged(pluginPath.Path);
            fs.File.WriteAllText(lightMaster2Path, string.Empty);
            watcher.MarkCreated(lightMaster2Path);
            fs.File.Delete(lightMasterPath);
            watcher.MarkDeleted(lightMasterPath);
            list.Items.Select(x => x.ModKey).Should().Equal(new ModKey[]
            {
                implicitKey,
                TestConstants.LightMasterModKey2,
                TestConstants.MasterModKey,
                TestConstants.PluginModKey,
            });

            fs.File.WriteAllLines(pluginPath.Path,
                                  new string[]
            {
                $"*{TestConstants.MasterModKey}",
                $"*{TestConstants.MasterModKey2}",
            });
            watcher.MarkChanged(pluginPath.Path);
            list.Items.Select(x => x.ModKey).Should().Equal(new ModKey[]
            {
                implicitKey,
                TestConstants.LightMasterModKey2,
                TestConstants.MasterModKey,
                TestConstants.MasterModKey2,
            });

            fs.File.WriteAllLines(pluginPath.Path,
                                  new string[]
            {
                $"*{TestConstants.MasterModKey}",
                $"*{TestConstants.MasterModKey2}",
                $"*{TestConstants.PluginModKey}",
            });
            watcher.MarkChanged(pluginPath.Path);
            fs.File.Delete(lightMaster2Path);
            watcher.MarkDeleted(lightMaster2Path);
            list.Items.Select(x => x.ModKey).Should().Equal(new ModKey[]
            {
                implicitKey,
                TestConstants.MasterModKey,
                TestConstants.MasterModKey2,
                TestConstants.PluginModKey,
            });

            // Does not respect just data folder modification
            // Since ModListing doesn't specify whether data folder is present
            // Data folder is just used for Timestamp alignment for Oblivion
            fs.File.Delete(master2Path);
            watcher.MarkDeleted(master2Path);
            list.Items.Select(x => x.ModKey).Should().Equal(new ModKey[]
            {
                implicitKey,
                TestConstants.MasterModKey,
                TestConstants.MasterModKey2,
                TestConstants.PluginModKey,
            });
        }
        public void LiveLoadOrder_EnsureReaddRetainsOrder(
            [Frozen] IScheduler scheduler,
            [Frozen] MockFileSystemWatcher watcher,
            [Frozen] MockFileSystem fs,
            [Frozen] ILiveLoadOrderTimings timings,
            [Frozen] IPluginListingsPathProvider pluginPath,
            [Frozen] IDataDirectoryProvider dataDir,
            [Frozen] ICreationClubListingsPathProvider cccPath)
        {
            var implicitKey = Implicits.Get(GameRelease.SkyrimSE).Listings.First();

            fs.File.WriteAllText(Path.Combine(dataDir.Path, TestConstants.LightMasterModKey.FileName), string.Empty);
            fs.File.WriteAllText(Path.Combine(dataDir.Path, implicitKey.FileName), string.Empty);
            fs.File.WriteAllLines(pluginPath.Path,
                                  new string[]
            {
                $"*{TestConstants.MasterModKey}",
                $"*{TestConstants.MasterModKey2}",
                $"*{TestConstants.MasterModKey3}",
                $"*{TestConstants.PluginModKey}",
            });
            fs.File.WriteAllLines(cccPath.Path,
                                  new string[]
            {
                TestConstants.LightMasterModKey.ToString(),
                TestConstants.LightMasterModKey2.ToString(),
            });
            var live = LoadOrder.GetLiveLoadOrder(
                GameRelease.SkyrimSE,
                pluginPath.Path,
                dataDir.Path,
                out var state,
                cccLoadOrderFilePath: cccPath.Path,
                scheduler: scheduler,
                fileSystem: fs,
                timings: timings);
            var list = live.AsObservableList();

            list.Items.Select(x => x.ModKey).Should().Equal(new ModKey[]
            {
                implicitKey,
                TestConstants.LightMasterModKey,
                TestConstants.MasterModKey,
                TestConstants.MasterModKey2,
                TestConstants.MasterModKey3,
                TestConstants.PluginModKey,
            });

            // Remove
            fs.File.WriteAllLines(pluginPath.Path,
                                  new string[]
            {
                $"*{TestConstants.MasterModKey}",
                $"*{TestConstants.MasterModKey3}",
                $"*{TestConstants.PluginModKey}",
            });
            watcher.MarkChanged(pluginPath.Path);
            list.Items.Select(x => x.ModKey).Should().Equal(new ModKey[]
            {
                implicitKey,
                TestConstants.LightMasterModKey,
                TestConstants.MasterModKey,
                TestConstants.MasterModKey3,
                TestConstants.PluginModKey,
            });

            // Then readd
            fs.File.WriteAllLines(pluginPath.Path,
                                  new string[]
            {
                $"*{TestConstants.MasterModKey}",
                $"*{TestConstants.MasterModKey2}",
                $"*{TestConstants.MasterModKey3}",
                $"*{TestConstants.PluginModKey}",
            });
            watcher.MarkChanged(pluginPath.Path);
            list.Items.Select(x => x.ModKey).Should().Equal(new ModKey[]
            {
                implicitKey,
                TestConstants.LightMasterModKey,
                TestConstants.MasterModKey,
                TestConstants.MasterModKey2,
                TestConstants.MasterModKey3,
                TestConstants.PluginModKey,
            });
        }