/// <summary> /// Takes in the main line command arguments, and handles PatcherRunSettings CLI inputs. /// </summary> /// <typeparam name="TMod">Setter mod interface</typeparam> /// <typeparam name="TModGetter">Getter only mod interface</typeparam> /// <param name="settings">Patcher run settings</param> /// <param name="patcher">Patcher func that processes a load order, and returns a mod object to export.</param> /// <param name="userPreferences">Any custom user preferences</param> public void Patch <TMod, TModGetter>( RunSynthesisMutagenPatcher settings, PatcherFunction <TMod, TModGetter> patcher, UserPreferences?userPreferences = null) where TMod : class, IMod, TModGetter where TModGetter : class, IModGetter { try { System.Console.WriteLine("Prepping state."); WarmupAll.Init(); using var state = Utility.ToState <TMod, TModGetter>(settings, userPreferences ?? new UserPreferences()); System.Console.WriteLine("Running patch."); patcher(state); if (!settings.OutputPath.IsNullOrWhitespace()) { System.Console.WriteLine($"Writing to output: {settings.OutputPath}"); state.PatchMod.WriteToBinaryParallel(path: settings.OutputPath, param: GetWriteParams(state.RawLoadOrder.Select(x => x.ModKey))); } } catch (Exception ex) when(Environment.GetCommandLineArgs().Length == 0 && (userPreferences?.ActionsForEmptyArgs?.BlockAutomaticExit ?? false)) { System.Console.Error.WriteLine(ex); System.Console.Error.WriteLine("Error occurred. Press enter to exit"); System.Console.ReadLine(); } }
static void Main(string[] args) { // ToDo // Set your SE Skyrim.esm path here var pathToSESkyrimESM = @"D:\Games\steamapps\common\Skyrim Special Edition\Data\Skyrim.esm"; // ToDo // Set your desired output location here var outputPath = @"output.esp"; // Just checking you have set your data path if (string.IsNullOrWhiteSpace(pathToSESkyrimESM) || !File.Exists(pathToSESkyrimESM)) { System.Console.WriteLine("Set your Skyrim path in the main function! Exiting."); return; } // Not necessary, but slightly speeds up initial bootstrapping if done explicitly WarmupAll.Init(); // Run some examples try { PrintAllWeapons(pathToSESkyrimESM); DoSomeLinking(pathToSESkyrimESM); MakeAMod(pathToSESkyrimESM, outputPath); } catch (Exception ex) { // Print errors if things go wrong System.Console.WriteLine(); System.Console.WriteLine("Oh no:"); System.Console.WriteLine(ex.ToString()); } // Print that we are done, and wait for user System.Console.WriteLine("Done! Press enter to exit."); System.Console.ReadLine(); }
public MainVM(HostSettings host) { WindowName = $"{host.PatcherName} Settings"; WarmupAll.Init(); var loadOrderResult = Observable.Return(Unit.Default) .ObserveOn(RxApp.TaskpoolScheduler) .Select(_ => { System.Console.Error.WriteLine($"Getting live load order for {host.GameRelease} -> {host.DataFolderPath}"); var liveLo = Mutagen.Bethesda.LoadOrder.GetLiveLoadOrder(host.GameRelease, host.DataFolderPath, out IObservable <ErrorResponse> errors) .Transform(listing => new LoadOrderEntryVM(listing, host.DataFolderPath)) .DisposeMany(); return(Results: liveLo, State: errors); }) .StartWith((Results: Observable.Empty <IChangeSet <LoadOrderEntryVM> >(), State: Observable.Return(ErrorResponse.Fail("Load order uninitialized")))) .Replay(1) .RefCount(); loadOrderResult.Select(x => x.State) .Switch() .Subscribe(e => { Console.Error.WriteLine(e); }) .DisposeWith(this); var loadOrder = loadOrderResult .Select(x => x.Results) .Switch() .AsObservableList(); var linkCache = loadOrder.Connect() .QueryWhenChanged() .Select(q => q.Where(x => x.Listing.Enabled).Select(x => x.Listing.ModKey).ToArray()) .StartWithEmpty() .Throttle(TimeSpan.FromMilliseconds(100), RxApp.TaskpoolScheduler) .Select(x => { return(Observable.Create <ILinkCache>(obs => { var loadOrder = Mutagen.Bethesda.LoadOrder.Import( host.DataFolderPath, x, factory: (modPath) => ModInstantiator.Importer(modPath, host.GameRelease)); obs.OnNext(loadOrder.ToUntypedImmutableLinkCache(LinkCachePreferences.OnlyIdentifiers())); obs.OnCompleted(); return Disposable.Empty; })); }) .Switch() .Replay(1) .RefCount(); _AutogeneratedSettings = Observable.Return(Unit.Default) .ObserveOn(RxApp.TaskpoolScheduler) .SelectTask(async _ => { try { var config = await Synthesis.Bethesda.Execution.CLI.Commands.GetSettingsStyle( host.PatcherPath, directExe: false, cancel: CancellationToken.None, build: false, log: (s) => Console.WriteLine(s)); return(new AutogeneratedSettingsVM( config, projPath: host.PatcherPath, displayName: host.PatcherName, loadOrder: loadOrder.Connect(), linkCache: linkCache, log: (s) => Console.WriteLine(s))); } catch (Exception ex) { Console.WriteLine(ex); return(default(AutogeneratedSettingsVM?)); } }) .ToGuiProperty(this, nameof(AutogeneratedSettings), default); }