/// <summary>
        /// Analyzes the mods asynchronous.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <param name="mode">The mode.</param>
        /// <returns>Task.</returns>
        protected virtual async Task AnalyzeModsAsync(long id, PatchStateMode mode)
        {
            SubscribeToProgressReport(id, Disposables);

            var overlayProgress = Smart.Format(localizationManager.GetResource(LocalizationResources.Mod_Actions.ConflictSolver.Overlay_Conflict_Solver_Progress), new
            {
                PercentDone = 0.ToLocalizedPercentage(),
                Count       = 1,
                TotalCount  = 4
            });
            var message = localizationManager.GetResource(LocalizationResources.Mod_Actions.ConflictSolver.Overlay_Conflict_Solver_Loading_Definitions);

            await TriggerOverlayAsync(id, true, message, overlayProgress);

            modPatchCollectionService.InvalidatePatchModState(CollectionMods.SelectedModCollection.Name);
            modPatchCollectionService.ResetPatchStateCache();

            var definitions = await Task.Run(async() =>
            {
                return(await modPatchCollectionService.GetModObjectsAsync(gameService.GetSelected(), CollectionMods.SelectedMods, CollectionMods.SelectedModCollection.Name).ConfigureAwait(false));
            }).ConfigureAwait(false);

            var conflicts = await Task.Run(() =>
            {
                if (definitions != null)
                {
                    return(modPatchCollectionService.FindConflicts(definitions, CollectionMods.SelectedMods.Select(p => p.Name).ToList(), mode));
                }
                return(null);
            }).ConfigureAwait(false);

            var syncedConflicts = await Task.Run(async() =>
            {
                return(await modPatchCollectionService.InitializePatchStateAsync(conflicts, CollectionMods.SelectedModCollection.Name).ConfigureAwait(false));
            }).ConfigureAwait(false);

            if (syncedConflicts != null)
            {
                conflicts = syncedConflicts;
            }
            var args = new NavigationEventArgs()
            {
                SelectedCollection = CollectionMods.SelectedModCollection,
                Results            = conflicts,
                State        = NavigationState.ConflictSolver,
                SelectedMods = CollectionMods.SelectedMods.Select(p => p.Name).ToList()
            };

            ReactiveUI.MessageBus.Current.SendMessage(args);
            await TriggerOverlayAsync(id, false);

            definitionAnalyzeLoadHandler?.Dispose();
            definitionLoadHandler?.Dispose();
            definitionSyncHandler?.Dispose();
            // I know, I know... but I wanna force a cleanup
            GC.Collect();
        }
Exemplo n.º 2
0
        /// <summary>
        /// Called when [activated].
        /// </summary>
        /// <param name="disposables">The disposables.</param>
        protected override void OnActivated(CompositeDisposable disposables)
        {
            ShowAdvancedFeatures = (gameService.GetSelected()?.AdvancedFeaturesSupported).GetValueOrDefault();

            var allowModSelectionEnabled = this.WhenAnyValue(v => v.AllowModSelection);

            RenameCommand = ReactiveCommand.Create(() =>
            {
                return(new CommandResult <ModifyAction>(ModifyAction.Rename, CommandState.Success));
            }, allowModSelectionEnabled).DisposeWith(disposables);

            DuplicateCommand = ReactiveCommand.CreateFromTask(async() =>
            {
                if (ActiveCollection != null)
                {
                    var copy = CopyCollection(ActiveCollection.Name);
                    if (modCollectionService.Save(copy))
                    {
                        var id = idGenerator.GetNextId();
                        await TriggerOverlayAsync(id, true, localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Duplicate_Message));
                        await Task.Run(async() =>
                        {
                            await modPatchCollectionService.CopyPatchCollectionAsync(ActiveCollection.Name, copy.Name).ConfigureAwait(false);
                        }).ConfigureAwait(false);
                        await TriggerOverlayAsync(id, false);
                        return(new CommandResult <ModifyAction>(ModifyAction.Duplicate, CommandState.Success));
                    }
                    else
                    {
                        return(new CommandResult <ModifyAction>(ModifyAction.Duplicate, CommandState.Failed));
                    }
                }
                return(new CommandResult <ModifyAction>(ModifyAction.Duplicate, CommandState.NotExecuted));
            }, allowModSelectionEnabled).DisposeWith(disposables);

            MergeOpenCommand = ReactiveCommand.Create(() =>
            {
                IsMergeOpen = true;
            }, allowModSelectionEnabled).DisposeWith(disposables);

            MergeCloseCommand = ReactiveCommand.Create(() =>
            {
                IsMergeOpen = false;
            }).DisposeWith(disposables);

            MergeAdvancedCommand = ReactiveCommand.CreateFromTask(async() =>
            {
                if (ActiveCollection != null && ActiveCollection.Mods?.Count() > 0)
                {
                    var copy = await GetMergedCollectionAsync();

                    var id = idGenerator.GetNextId();
                    await TriggerOverlayAsync(id, true, localizationManager.GetResource(LocalizationResources.App.WaitBackgroundOperationMessage));
                    await shutDownState.WaitUntilFreeAsync();

                    var savedCollection = modCollectionService.GetAll().FirstOrDefault(p => p.IsSelected);
                    while (savedCollection == null)
                    {
                        await Task.Delay(25);
                        savedCollection = modCollectionService.GetAll().FirstOrDefault(p => p.IsSelected);
                    }

                    SubscribeToProgressReports(id, disposables, MergeType.Advanced);

                    var mode = await modPatchCollectionService.GetPatchStateModeAsync(ActiveCollection.Name);
                    if (mode == PatchStateMode.None)
                    {
                        // fallback to default mod if no patch collection specified
                        mode = PatchStateMode.Default;
                    }

                    var overlayProgress = Smart.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.MergeCollection.Overlay_Progress), new
                    {
                        PercentDone = 0.ToLocalizedPercentage(),
                        Count       = 1,
                        TotalCount  = 4
                    });
                    var message = localizationManager.GetResource(LocalizationResources.Collection_Mods.MergeCollection.Advanced.Overlay_Loading_Definitions);
                    await TriggerOverlayAsync(id, true, message, overlayProgress);

                    modPatchCollectionService.ResetPatchStateCache();
                    var definitions = await Task.Run(async() =>
                    {
                        return(await modPatchCollectionService.GetModObjectsAsync(gameService.GetSelected(), SelectedMods, copy.Name).ConfigureAwait(false));
                    }).ConfigureAwait(false);

                    var conflicts = await Task.Run(() =>
                    {
                        if (definitions != null)
                        {
                            return(modPatchCollectionService.FindConflicts(definitions, SelectedMods.Select(p => p.Name).ToList(), mode));
                        }
                        return(null);
                    }).ConfigureAwait(false);

                    await modPatchCollectionService.CleanPatchCollectionAsync(copy.Name);

                    var mergeMod = await Task.Run(async() =>
                    {
                        return(await modMergeService.MergeCollectionByDefinitionsAsync(conflicts, SelectedMods.Select(p => p.Name).ToList(), copy.Name).ConfigureAwait(false));
                    }).ConfigureAwait(false);
                    copy.Mods = new List <string>()
                    {
                        mergeMod.DescriptorFile
                    };

                    await TriggerOverlayAsync(id, false);

                    definitionAnalyzeLoadHandler?.Dispose();
                    definitionLoadHandler?.Dispose();
                    definitionMergeProgressHandler?.Dispose();

                    modCollectionService.Delete(copy.Name);
                    modPatchCollectionService.InvalidatePatchModState(copy.Name);
                    if (modCollectionService.Save(copy))
                    {
                        return(new CommandResult <ModifyAction>(ModifyAction.Merge, CommandState.Success));
                    }
                    else
                    {
                        return(new CommandResult <ModifyAction>(ModifyAction.Merge, CommandState.Failed));
                    }
                }
                return(new CommandResult <ModifyAction>(ModifyAction.Merge, CommandState.NotExecuted));
            }, allowModSelectionEnabled).DisposeWith(disposables);

            MergeBasicCommand = ReactiveCommand.CreateFromTask(async() =>
            {
                if (ActiveCollection != null && ActiveCollection.Mods?.Count() > 0)
                {
                    var copy = await GetMergedCollectionAsync();
                    var id   = idGenerator.GetNextId();

                    await TriggerOverlayAsync(id, true, localizationManager.GetResource(LocalizationResources.App.WaitBackgroundOperationMessage));
                    await shutDownState.WaitUntilFreeAsync();

                    var savedCollection = modCollectionService.GetAll().FirstOrDefault(p => p.IsSelected);
                    while (savedCollection == null)
                    {
                        await Task.Delay(25);
                        savedCollection = modCollectionService.GetAll().FirstOrDefault(p => p.IsSelected);
                    }

                    SubscribeToProgressReports(id, disposables, MergeType.Basic);

                    var overlayProgress = Smart.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.MergeCollection.Overlay_Progress), new
                    {
                        PercentDone = 0.ToLocalizedPercentage(),
                        Count       = 1,
                        TotalCount  = 2
                    });
                    var message = localizationManager.GetResource(LocalizationResources.Collection_Mods.MergeCollection.Basic.Overlay_Gathering_Mod_Info);
                    await TriggerOverlayAsync(id, true, message, overlayProgress);

                    await modPatchCollectionService.CleanPatchCollectionAsync(copy.Name);

                    var mergeMod = await Task.Run(async() =>
                    {
                        return(await modMergeService.MergeCollectionByFilesAsync(copy.Name));
                    }).ConfigureAwait(false);
                    copy.Mods = new List <string>()
                    {
                        mergeMod.DescriptorFile
                    };

                    await TriggerOverlayAsync(id, false);
                    fileMergeProgressHandler?.Dispose();

                    modCollectionService.Delete(copy.Name);
                    modPatchCollectionService.InvalidatePatchModState(copy.Name);
                    if (modCollectionService.Save(copy))
                    {
                        return(new CommandResult <ModifyAction>(ModifyAction.Merge, CommandState.Success));
                    }
                    else
                    {
                        return(new CommandResult <ModifyAction>(ModifyAction.Merge, CommandState.Failed));
                    }
                }
                return(new CommandResult <ModifyAction>(ModifyAction.Merge, CommandState.NotExecuted));
            }, allowModSelectionEnabled).DisposeWith(disposables);

            MergeCompressCommand = ReactiveCommand.CreateFromTask(async() =>
            {
                if (ActiveCollection != null && ActiveCollection.Mods?.Count() > 0)
                {
                    var copy = await GetMergedCollectionAsync();
                    var id   = idGenerator.GetNextId();

                    await TriggerOverlayAsync(id, true, localizationManager.GetResource(LocalizationResources.App.WaitBackgroundOperationMessage));
                    await shutDownState.WaitUntilFreeAsync();

                    var savedCollection = modCollectionService.GetAll().FirstOrDefault(p => p.IsSelected);
                    while (savedCollection == null)
                    {
                        await Task.Delay(25);
                        savedCollection = modCollectionService.GetAll().FirstOrDefault(p => p.IsSelected);
                    }

                    SubscribeToProgressReports(id, disposables, MergeType.Compress);

                    var overlayProgress = Smart.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.MergeCollection.Overlay_Progress), new
                    {
                        PercentDone = 0.ToLocalizedPercentage(),
                        Count       = 1,
                        TotalCount  = 2
                    });
                    var message = localizationManager.GetResource(LocalizationResources.Collection_Mods.MergeCollection.Compress.Overlay_Gathering_Mod_Info);
                    await TriggerOverlayAsync(id, true, message, overlayProgress);

                    await modPatchCollectionService.CleanPatchCollectionAsync(copy.Name);

                    var mergeMods = await Task.Run(async() =>
                    {
                        return(await modMergeService.MergeCompressCollectionAsync(copy.Name, Smart.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.MergeCollection.MergeCompressModPrefix), new
                        {
                            Name = copy.Name.Replace($"{localizationManager.GetResource(LocalizationResources.Collection_Mods.MergeCollection.MergedCollectionPrefix)} ", string.Empty)
                        })));
                    }).ConfigureAwait(false);
                    copy.Mods = mergeMods.Select(p => p.DescriptorFile).ToList();

                    await TriggerOverlayAsync(id, false);
                    fileMergeProgressHandler?.Dispose();

                    modCollectionService.Delete(copy.Name);
                    modPatchCollectionService.InvalidatePatchModState(copy.Name);
                    await modService.InstallModsAsync(null);
                    if (modCollectionService.Save(copy))
                    {
                        return(new CommandResult <ModifyAction>(ModifyAction.Merge, CommandState.Success));
                    }
                    else
                    {
                        return(new CommandResult <ModifyAction>(ModifyAction.Merge, CommandState.Failed));
                    }
                }
                return(new CommandResult <ModifyAction>(ModifyAction.Merge, CommandState.NotExecuted));
            }, allowModSelectionEnabled).DisposeWith(disposables);

            base.OnActivated(disposables);
        }
        /// <summary>
        /// Analyzes the mods asynchronous.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <param name="mode">The mode.</param>
        /// <param name="versions">The versions.</param>
        /// <returns>Task.</returns>
        protected virtual async Task AnalyzeModsAsync(long id, PatchStateMode mode, IEnumerable <string> versions)
        {
            var totalSteps = versions != null && versions.Any() ? 6 : 4;

            SubscribeToProgressReport(id, Disposables, totalSteps);

            var overlayProgress = Smart.Format(localizationManager.GetResource(LocalizationResources.Mod_Actions.ConflictSolver.Overlay_Conflict_Solver_Progress), new
            {
                PercentDone = 0.ToLocalizedPercentage(),
                Count       = 1,
                TotalCount  = totalSteps
            });
            var message = localizationManager.GetResource(LocalizationResources.Mod_Actions.ConflictSolver.Overlay_Conflict_Solver_Loading_Definitions);

            await TriggerOverlayAsync(id, true, message, overlayProgress);

            modPatchCollectionService.InvalidatePatchModState(CollectionMods.SelectedModCollection.Name);
            modPatchCollectionService.ResetPatchStateCache();

            var game        = gameService.GetSelected();
            var definitions = await Task.Run(async() =>
            {
                var result = await modPatchCollectionService.GetModObjectsAsync(gameService.GetSelected(), CollectionMods.SelectedMods, CollectionMods.SelectedModCollection.Name).ConfigureAwait(false);
                // To stop people from whining
                GC.Collect();
                return(result);
            }).ConfigureAwait(false);

            if (versions != null && versions.Any())
            {
                await Task.Run(async() =>
                {
                    await gameIndexService.IndexDefinitionsAsync(game, versions, definitions);
                    // To stop people from whining
                    GC.Collect();
                });

                definitions = await Task.Run(async() =>
                {
                    var result = await gameIndexService.LoadDefinitionsAsync(definitions, game, versions);
                    // To stop people from whining
                    GC.Collect();
                    return(result);
                }).ConfigureAwait(false);
            }
            var conflicts = await Task.Run(() =>
            {
                if (definitions != null)
                {
                    // To stop people from whining
                    var result = modPatchCollectionService.FindConflicts(definitions, CollectionMods.SelectedMods.Select(p => p.Name).ToList(), mode);
                    GC.Collect();
                    return(result);
                }
                return(null);
            }).ConfigureAwait(false);

            var syncedConflicts = await Task.Run(async() =>
            {
                var result = await modPatchCollectionService.InitializePatchStateAsync(conflicts, CollectionMods.SelectedModCollection.Name).ConfigureAwait(false);
                // To stop people from whining
                GC.Collect();
                return(result);
            }).ConfigureAwait(false);

            if (syncedConflicts != null)
            {
                conflicts = syncedConflicts;
            }
            var args = new NavigationEventArgs()
            {
                SelectedCollection = CollectionMods.SelectedModCollection,
                Results            = conflicts,
                State        = mode == PatchStateMode.ReadOnly ? NavigationState.ReadOnlyConflictSolver : NavigationState.ConflictSolver,
                SelectedMods = CollectionMods.SelectedMods.Select(p => p.Name).ToList()
            };

            ReactiveUI.MessageBus.Current.SendMessage(args);
            await TriggerOverlayAsync(id, false);

            definitionAnalyzeLoadHandler?.Dispose();
            definitionLoadHandler?.Dispose();
            definitionSyncHandler?.Dispose();
            gameIndexHandler?.Dispose();
            gameDefinitionLoadHandler?.Dispose();
            // I know, I know... but I wanna force a cleanup
            GC.Collect();
        }