├── ENBManager.App ├── favicon.ico ├── AssemblyInfo.cs ├── App.xaml └── ENBManager.App.csproj ├── ENBManager.Infrastructure ├── Resources │ ├── Icons │ │ ├── favicon.ico │ │ ├── skyrim.png │ │ ├── fallout3.png │ │ ├── fallout4.png │ │ ├── falloutnv.png │ │ └── skyrimse.png │ ├── TabControls.xaml │ └── Dialogs │ │ └── Dialogs.xaml ├── Enums │ ├── KeywordType.cs │ └── VersionMismatch.cs ├── BusinessEntities │ ├── FileNode.cs │ ├── Keywords.cs │ ├── Dialogs │ │ ├── ConfirmDialog.cs │ │ ├── MessageDialog.cs │ │ ├── TreeViewDialog.cs │ │ ├── InputDialog.cs │ │ ├── ProgressDialog.cs │ │ ├── Node.cs │ │ └── Base │ │ │ └── BaseDialog.cs │ ├── DirectoryNode.cs │ ├── ColorScheme.cs │ ├── GameSettings.cs │ ├── Base │ │ └── Node.cs │ └── AppSettings.cs ├── Constants │ ├── ApplicationName.cs │ ├── FileTypes.cs │ ├── Urls.cs │ ├── ModuleNames.cs │ ├── RegionNames.cs │ ├── DefaultKeywords.cs │ └── Paths.cs ├── Properties │ └── AssemblyInfo.cs ├── Exceptions │ └── IdenticalNameException.cs ├── ValueConverters │ ├── BoolToBoolValueConverter.cs │ ├── EnumToCollectionValueConverter.cs │ └── EmptyCollectionToVisibilityValueConverter.cs ├── packages.config ├── Interfaces │ └── IGameService.cs ├── Helpers │ ├── DialogHelper.cs │ ├── KeywordsHelper.cs │ └── TreeViewHelper.cs └── Services │ └── GameService.cs ├── ENBManager.Modules ├── Shared │ ├── Interfaces │ │ ├── ITabItem.cs │ │ ├── IGameModuleCatalog.cs │ │ ├── IScreenshotWatcher.cs │ │ ├── IScreenshotManager.cs │ │ └── IPresetManager.cs │ ├── Views │ │ ├── ModuleShell.xaml.cs │ │ ├── PresetsView.xaml.cs │ │ ├── DashboardView.xaml.cs │ │ ├── ScreenshotView.xaml.cs │ │ ├── AddPresetDialog.xaml.cs │ │ └── ModuleShell.xaml │ ├── Events │ │ └── Events.cs │ ├── ViewModels │ │ ├── Base │ │ │ └── TabItemBase.cs │ │ └── ModuleShellViewModel.cs │ ├── Services │ │ ├── GameModuleCatalog.cs │ │ ├── ScreenshotWatcher.cs │ │ └── ScreenshotManager.cs │ └── Models │ │ ├── Notification.cs │ │ ├── Preset.cs │ │ └── GameModule.cs ├── AssemblyInfo.cs ├── Skyrim │ └── SkyrimModule.cs ├── Fallout3 │ └── Fallout3Module.cs ├── FalloutNV │ └── FalloutNVModule.cs ├── Fallout4 │ └── Fallout4Module.cs ├── ENBManager.Modules.csproj └── SkyrimSE │ └── SkyrimSEModule.cs ├── ENBManager.Logging ├── Properties │ └── AssemblyInfo.cs ├── Enums │ └── LogLevel.cs ├── NLog.config ├── packages.config ├── Services │ └── PrismLogger.cs └── ENBManager.Logging.csproj ├── ENBManager.Configuration ├── Properties │ └── AssemblyInfo.cs ├── packages.config ├── Models │ └── BaseSettings.cs ├── Interfaces │ └── IConfigurationManager.cs ├── Services │ └── ConfigurationManager.cs └── ENBManager.Configuration.csproj ├── SharedAssemblyInfo.cs ├── ENBManager.Core ├── Views │ ├── MainView.xaml.cs │ ├── AboutDialog.xaml.cs │ ├── SideMenuView.xaml.cs │ ├── NotifyIconView.xaml.cs │ ├── AppSettingsDialog.xaml.cs │ ├── DiscoverGamesDialog.xaml.cs │ ├── GameSettingsDialog.xaml.cs │ ├── MainView.xaml │ ├── Shell.xaml.cs │ ├── Shell.xaml │ ├── NotifyIconView.xaml │ ├── GameSettingsDialog.xaml │ └── AboutDialog.xaml ├── AssemblyInfo.cs ├── Helpers │ ├── GameLocator.cs │ └── ThemeHelper.cs ├── ENBManager.Core.csproj └── ViewModels │ ├── AboutViewModel.cs │ ├── AppSettingsViewModel.cs │ ├── GameSettingsViewModel.cs │ ├── ShellViewModel.cs │ └── DiscoverGamesDialogViewModel.cs ├── ENBManager.Core.Tests ├── Helpers │ └── ThemeHelperTests.cs ├── ViewModels │ ├── AppSettingsViewModelTests.cs │ ├── AboutViewModelTests.cs │ ├── GameSettingsViewModelTests.cs │ └── DiscoverGamesDialogViewModelTests.cs ├── ENBManager.Core.Tests.csproj └── Stubs │ └── FileServiceStub.cs ├── ENBManager.Configuration.Tests ├── Stubs │ ├── SettingsAStub.cs │ └── SettingsBStub.cs ├── ENBManager.Configuration.Tests.csproj └── Services │ └── ConfigurationManagerTests.cs ├── ENBManager.Localization └── ENBManager.Localization.csproj ├── ENBManager.Modules.Tests ├── ENBManager.Modules.Tests.csproj └── Shared │ └── Services │ └── GameModuleCatalogTests.cs ├── ENBManager.TestUtils ├── ENBManager.TestUtils.csproj └── TestValues.cs ├── .gitattributes ├── .gitignore └── README.md /ENBManager.App/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andretoll/ENBManager/HEAD/ENBManager.App/favicon.ico -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Resources/Icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andretoll/ENBManager/HEAD/ENBManager.Infrastructure/Resources/Icons/favicon.ico -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Resources/Icons/skyrim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andretoll/ENBManager/HEAD/ENBManager.Infrastructure/Resources/Icons/skyrim.png -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Resources/Icons/fallout3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andretoll/ENBManager/HEAD/ENBManager.Infrastructure/Resources/Icons/fallout3.png -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Resources/Icons/fallout4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andretoll/ENBManager/HEAD/ENBManager.Infrastructure/Resources/Icons/fallout4.png -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Resources/Icons/falloutnv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andretoll/ENBManager/HEAD/ENBManager.Infrastructure/Resources/Icons/falloutnv.png -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Resources/Icons/skyrimse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andretoll/ENBManager/HEAD/ENBManager.Infrastructure/Resources/Icons/skyrimse.png -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Enums/KeywordType.cs: -------------------------------------------------------------------------------- 1 | namespace ENBManager.Infrastructure.Enums 2 | { 3 | public enum KeywordType 4 | { 5 | Folder, 6 | File 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Interfaces/ITabItem.cs: -------------------------------------------------------------------------------- 1 | namespace ENBManager.Modules.Shared.Interfaces 2 | { 3 | public interface ITabItem 4 | { 5 | string Name { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /ENBManager.Logging/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | [assembly: AssemblyTitle("Logging")] 4 | [assembly: AssemblyDescription("This assembly contains logging functionality")] -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/FileNode.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities.Base; 2 | 3 | namespace ENBManager.Infrastructure.BusinessEntities 4 | { 5 | public class FileNode : Node { } 6 | } 7 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Constants/ApplicationName.cs: -------------------------------------------------------------------------------- 1 | namespace ENBManager.Infrastructure.Constants 2 | { 3 | public static class ApplicationName 4 | { 5 | public static string NAME = "Toll's ENB Manager"; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /ENBManager.Configuration/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | [assembly: AssemblyTitle("Configuration")] 4 | [assembly: AssemblyDescription("This assembly contains functionality related to application configuration")] 5 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Enums/VersionMismatch.cs: -------------------------------------------------------------------------------- 1 | namespace ENBManager.Infrastructure.Enums 2 | { 3 | public enum VersionMismatch 4 | { 5 | Matching = 0, 6 | Above = 1, 7 | Below = 2 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ENBManager.Configuration/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Constants/FileTypes.cs: -------------------------------------------------------------------------------- 1 | namespace ENBManager.Infrastructure.Constants 2 | { 3 | public static class FileTypes 4 | { 5 | public static string[] ScreenshotFileTypes => new string[] { "*.png", "*.bmp", "*.jpg" }; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | [assembly: AssemblyTitle("Infrastructure")] 4 | [assembly: AssemblyDescription("This assembly contains business entities, business logic, services and resources shared across the application")] -------------------------------------------------------------------------------- /SharedAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | [assembly: AssemblyCompany("André Toll")] 4 | [assembly: AssemblyProduct("Toll's ENB Manager")] 5 | [assembly: AssemblyCopyright("Copyright © André Toll 2020")] 6 | [assembly: AssemblyTrademark("")] 7 | [assembly: AssemblyVersion("0.9.*")] -------------------------------------------------------------------------------- /ENBManager.Logging/Enums/LogLevel.cs: -------------------------------------------------------------------------------- 1 | namespace ENBManager.Logging.Enums 2 | { 3 | /// 4 | /// Defines the level of logging. 5 | /// 6 | public enum LogLevel 7 | { 8 | Debug = 0, 9 | Information = 1, 10 | Error = 2 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Constants/Urls.cs: -------------------------------------------------------------------------------- 1 | namespace ENBManager.Infrastructure.Constants 2 | { 3 | public static class Urls 4 | { 5 | public const string ENBDEV = "http://enbdev.com/download.html"; 6 | public const string SOURCE_CODE = "https://github.com/andretoll/ENBManager"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Exceptions/IdenticalNameException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ENBManager.Infrastructure.Exceptions 4 | { 5 | public class IdenticalNameException : Exception 6 | { 7 | public IdenticalNameException(string message) 8 | : base(message) { } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/MainView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Core.Views 4 | { 5 | /// 6 | /// Interaction logic for MainView.xaml 7 | /// 8 | public partial class MainView : UserControl 9 | { 10 | public MainView() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/AboutDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Core.Views 4 | { 5 | /// 6 | /// Interaction logic for AboutDialog.xaml 7 | /// 8 | public partial class AboutDialog : UserControl 9 | { 10 | public AboutDialog() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/SideMenuView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Core.Views 4 | { 5 | /// 6 | /// Interaction logic for SideMenuView.xaml 7 | /// 8 | public partial class SideMenuView : UserControl 9 | { 10 | public SideMenuView() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/NotifyIconView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Core.Views 4 | { 5 | /// 6 | /// Interaction logic for NotifyIconView.xaml 7 | /// 8 | public partial class NotifyIconView : UserControl 9 | { 10 | public NotifyIconView() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/Keywords.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ENBManager.Infrastructure.BusinessEntities 4 | { 5 | public class Keywords 6 | { 7 | #region Public Properties 8 | 9 | public ICollection Directories { get; set; } 10 | public ICollection Files { get; set; } 11 | 12 | #endregion 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Views/ModuleShell.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Modules.Shared.Views 4 | { 5 | /// 6 | /// Interaction logic for ModuleShell.xaml 7 | /// 8 | public partial class ModuleShell : UserControl 9 | { 10 | public ModuleShell() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Views/PresetsView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Modules.Shared.Views 4 | { 5 | /// 6 | /// Interaction logic for PresetsView.xaml 7 | /// 8 | public partial class PresetsView : UserControl 9 | { 10 | public PresetsView() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/AppSettingsDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Core.Views 4 | { 5 | /// 6 | /// Interaction logic for AppSettingsDialog.xaml 7 | /// 8 | public partial class AppSettingsDialog : UserControl 9 | { 10 | public AppSettingsDialog() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/DiscoverGamesDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Core.Views 4 | { 5 | /// 6 | /// Interaction logic for DetectGamesDialog.xaml 7 | /// 8 | public partial class DiscoverGamesDialog : UserControl 9 | { 10 | public DiscoverGamesDialog() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/GameSettingsDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Core.Views 4 | { 5 | /// 6 | /// Interaction logic for GameSettingsDialog.xaml 7 | /// 8 | public partial class GameSettingsDialog : UserControl 9 | { 10 | public GameSettingsDialog() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Views/DashboardView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Modules.Shared.Views 4 | { 5 | /// 6 | /// Interaction logic for DashboardView.xaml 7 | /// 8 | public partial class DashboardView : UserControl 9 | { 10 | public DashboardView() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Views/ScreenshotView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Modules.Shared.Views 4 | { 5 | /// 6 | /// Interaction logic for ScreenshotView.xaml 7 | /// 8 | public partial class ScreenshotView : UserControl 9 | { 10 | public ScreenshotView() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/Dialogs/ConfirmDialog.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities.Dialogs.Base; 2 | 3 | namespace ENBManager.Infrastructure.BusinessEntities.Dialogs 4 | { 5 | public class ConfirmDialog : BaseDialog 6 | { 7 | #region Constructor 8 | 9 | public ConfirmDialog(string message) 10 | : base(message) { } 11 | 12 | #endregion 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/Dialogs/MessageDialog.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities.Dialogs.Base; 2 | 3 | namespace ENBManager.Infrastructure.BusinessEntities.Dialogs 4 | { 5 | public class MessageDialog : BaseDialog 6 | { 7 | #region Constructor 8 | 9 | public MessageDialog(string message) 10 | : base (message) { } 11 | 12 | #endregion 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Views/AddPresetDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ENBManager.Modules.Shared.Views 4 | { 5 | /// 6 | /// Interaction logic for AddPresetDialog.xaml 7 | /// 8 | public partial class AddPresetDialog : UserControl 9 | { 10 | public AddPresetDialog() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Constants/ModuleNames.cs: -------------------------------------------------------------------------------- 1 | namespace ENBManager.Infrastructure.Constants 2 | { 3 | public static class ModuleNames 4 | { 5 | public const string SKYRIM = "Skyrim"; 6 | public const string SKYRIMSE = "SkyrimSE"; 7 | public const string FALLOUT3 = "Fallout3"; 8 | public const string FALLOUT4 = "Fallout4"; 9 | public const string FALLOUTNV = "FalloutNV"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ENBManager.Logging/NLog.config: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | -------------------------------------------------------------------------------- /ENBManager.Logging/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Events/Events.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using Prism.Events; 3 | 4 | namespace ENBManager.Modules.Shared.Events 5 | { 6 | public class ShowSnackbarMessageEvent : PubSubEvent { } 7 | public class ModuleActivatedEvent : PubSubEvent { } 8 | public class ScreenshotsStatusChangedModuleEvent : PubSubEvent { } 9 | public class ScreenshotsStatusChangedExternalEvent : PubSubEvent { } 10 | } 11 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Constants/RegionNames.cs: -------------------------------------------------------------------------------- 1 | namespace ENBManager.Infrastructure.Constants 2 | { 3 | public static class RegionNames 4 | { 5 | public static string MainRegion = "MainRegion"; 6 | public static string SideMenuRegion = "SideMenuRegion"; 7 | public static string TabRegion = "TabRegion"; 8 | 9 | public static string RootDialogHost = "RootDialogHost"; 10 | public static string AddPresetDialogHost = "AddPresetDialogHost"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ENBManager.Core.Tests/Helpers/ThemeHelperTests.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Core.Helpers; 2 | using NUnit.Framework; 3 | using System.Linq; 4 | 5 | namespace ENBManager.Core.Tests.Helpers 6 | { 7 | [TestFixture] 8 | public class ThemeHelperTests 9 | { 10 | [Test] 11 | public void ShouldGetColorSchemes() 12 | { 13 | // Act 14 | var colorSchemes = ThemeHelper.GetColorSchemes(); 15 | 16 | // Assert 17 | Assert.That(colorSchemes.Count(), Is.GreaterThan(0)); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ENBManager.Configuration.Tests/Stubs/SettingsAStub.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Configuration.Models; 2 | using ENBManager.Infrastructure.Constants; 3 | using System.IO; 4 | 5 | namespace ENBManager.Configuration.Tests.Stubs 6 | { 7 | internal class SettingsAStub : BaseSettings 8 | { 9 | private static readonly string PATH = Path.Combine(Paths.GetBaseDirectory(), "appsettings_a//appsettings_a.json"); 10 | 11 | public string Text { get; set; } 12 | public bool Condition { get; set; } 13 | 14 | public SettingsAStub() 15 | : base(PATH) 16 | { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ENBManager.Configuration.Tests/Stubs/SettingsBStub.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Configuration.Models; 2 | using ENBManager.Infrastructure.Constants; 3 | using System.IO; 4 | 5 | namespace ENBManager.Configuration.Tests.Stubs 6 | { 7 | internal class SettingsBStub : BaseSettings 8 | { 9 | private static readonly string PATH = Path.Combine(Paths.GetBaseDirectory(), "appsettings_b//appsettings_b.json"); 10 | 11 | public string Text { get; set; } 12 | public bool Condition { get; set; } 13 | 14 | public SettingsBStub() 15 | : base(PATH) 16 | { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/DirectoryNode.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities.Base; 2 | using System.Collections.ObjectModel; 3 | 4 | namespace ENBManager.Infrastructure.BusinessEntities 5 | { 6 | public class DirectoryNode : Node 7 | { 8 | #region Public Properties 9 | 10 | public ObservableCollection Items { get; set; } 11 | 12 | #endregion 13 | 14 | #region Constructor 15 | 16 | public DirectoryNode() 17 | { 18 | Items = new ObservableCollection(); 19 | } 20 | 21 | #endregion 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/ValueConverters/BoolToBoolValueConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace ENBManager.Infrastructure.ValueConverters 6 | { 7 | public class BoolToBoolValueConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | return !(bool)value; 12 | } 13 | 14 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | throw new NotImplementedException(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/ValueConverters/EnumToCollectionValueConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace ENBManager.Infrastructure.ValueConverters 6 | { 7 | public class EnumToCollectionValueConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | return Enum.GetValues(value.GetType()); 12 | } 13 | 14 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | throw new NotImplementedException(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/Dialogs/TreeViewDialog.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities.Base; 2 | using ENBManager.Infrastructure.BusinessEntities.Dialogs.Base; 3 | using System.Collections.Generic; 4 | 5 | namespace ENBManager.Infrastructure.BusinessEntities.Dialogs 6 | { 7 | public class TreeViewDialog : BaseDialog 8 | { 9 | #region Public Properties 10 | 11 | public IEnumerable Nodes { get; set; } 12 | 13 | #endregion 14 | 15 | #region Constructor 16 | 17 | public TreeViewDialog(string message, IEnumerable nodes) 18 | : base(message) 19 | { 20 | Nodes = nodes; 21 | } 22 | 23 | #endregion 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ENBManager.Localization/ENBManager.Localization.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | AnyCPU;x64 6 | 7 | 8 | 9 | 10 | True 11 | True 12 | Strings.resx 13 | 14 | 15 | 16 | 17 | 18 | PublicResXFileCodeGenerator 19 | Strings.Designer.cs 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ENBManager.Configuration/Models/BaseSettings.cs: -------------------------------------------------------------------------------- 1 | namespace ENBManager.Configuration.Models 2 | { 3 | public abstract class BaseSettings 4 | { 5 | #region Private Members 6 | 7 | private string _fullPath; 8 | 9 | #endregion 10 | 11 | #region Constructor 12 | 13 | public BaseSettings(string fullPath) 14 | { 15 | _fullPath = fullPath; 16 | } 17 | 18 | #endregion 19 | 20 | #region Public Methods 21 | 22 | public string GetFullPath() 23 | { 24 | return _fullPath; 25 | } 26 | 27 | public void SetFullPath(string fullPath) 28 | { 29 | _fullPath = fullPath; 30 | } 31 | 32 | #endregion 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ENBManager.Modules.Tests/ENBManager.Modules.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | false 7 | 8 | AnyCPU;x64 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Interfaces/IGameModuleCatalog.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using Prism.Ioc; 3 | using System.Collections.Generic; 4 | 5 | namespace ENBManager.Modules.Shared.Interfaces 6 | { 7 | public interface IGameModuleCatalog 8 | { 9 | /// 10 | /// Returns the registered game modules. 11 | /// 12 | IEnumerable GameModules { get; } 13 | 14 | /// 15 | /// Registers a module to the catalog. Accepts a dependency container as argument. 16 | /// 17 | /// 18 | /// 19 | void Register(IContainerProvider container) where T : GameModule; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/ColorScheme.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Media; 2 | 3 | namespace ENBManager.Infrastructure.BusinessEntities 4 | { 5 | public class ColorScheme 6 | { 7 | #region Public Properties 8 | 9 | public string Name { get; set; } 10 | public Color Primary { get; set; } 11 | public Color Secondary { get; set; } 12 | 13 | #endregion 14 | 15 | #region Constructor 16 | 17 | public ColorScheme(string name, string primaryHex, string secondaryHex) 18 | { 19 | Name = name; 20 | Primary = (Color)ColorConverter.ConvertFromString(primaryHex); 21 | Secondary = (Color)ColorConverter.ConvertFromString(secondaryHex); 22 | } 23 | 24 | #endregion 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ENBManager.TestUtils/ENBManager.TestUtils.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | AnyCPU;x64 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\PresentationCore.dll 15 | 16 | 17 | C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\WindowsBase.dll 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /ENBManager.App/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Windows; 3 | 4 | [assembly: ThemeInfo( 5 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 6 | //(used if a resource is not found in the page, 7 | // or application resource dictionaries) 8 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 9 | //(used if a resource is not found in the page, 10 | // app, or any theme specific resource dictionaries) 11 | )] 12 | 13 | [assembly: AssemblyTitle("Application")] 14 | [assembly: AssemblyDescription("This is the entry point for the application")] 15 | -------------------------------------------------------------------------------- /ENBManager.Modules/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Windows; 3 | 4 | [assembly: ThemeInfo( 5 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 6 | //(used if a resource is not found in the page, 7 | // or application resource dictionaries) 8 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 9 | //(used if a resource is not found in the page, 10 | // app, or any theme specific resource dictionaries) 11 | )] 12 | 13 | [assembly: AssemblyTitle("Modules")] 14 | [assembly: AssemblyDescription("This assembly contains all game modules supported by the application")] 15 | -------------------------------------------------------------------------------- /ENBManager.Core/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Windows; 3 | 4 | [assembly: ThemeInfo( 5 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 6 | //(used if a resource is not found in the page, 7 | // or application resource dictionaries) 8 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 9 | //(used if a resource is not found in the page, 10 | // app, or any theme specific resource dictionaries) 11 | )] 12 | 13 | [assembly: AssemblyTitle("Core")] 14 | [assembly: AssemblyDescription("This assembly contains views and business logic not related to specific modules")] 15 | -------------------------------------------------------------------------------- /ENBManager.Configuration.Tests/ENBManager.Configuration.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | false 7 | 8 | AnyCPU;x64 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ENBManager.Core.Tests/ViewModels/AppSettingsViewModelTests.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Configuration.Interfaces; 2 | using ENBManager.Configuration.Services; 3 | using ENBManager.Core.ViewModels; 4 | using ENBManager.Infrastructure.BusinessEntities; 5 | using NUnit.Framework; 6 | 7 | namespace ENBManager.Core.Tests.ViewModels 8 | { 9 | [TestFixture] 10 | public class AppSettingsViewModelTests 11 | { 12 | private AppSettingsViewModel _viewModel; 13 | 14 | [SetUp] 15 | public void Setup() 16 | { 17 | IConfigurationManager configManager = new ConfigurationManager(); 18 | _viewModel = new AppSettingsViewModel(configManager); 19 | } 20 | 21 | [Test] 22 | public void ShouldHaveDialogTitle() 23 | { 24 | // Assert 25 | Assert.That(string.IsNullOrEmpty(_viewModel.Title), Is.False); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ENBManager.Core.Tests/ENBManager.Core.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | false 7 | 8 | AnyCPU;x64 9 | 10 | 11 | 12 | 13 | 14 | all 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ENBManager.App/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Interfaces/IScreenshotWatcher.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace ENBManager.Modules.Shared.Interfaces 4 | { 5 | public interface IScreenshotWatcher 6 | { 7 | event FileSystemEventHandler FileCreated; 8 | 9 | /// 10 | /// Stops the watcher and unsubscribes from any events. 11 | /// 12 | void Stop(); 13 | 14 | /// 15 | /// Configures the watcher with directory and filters. 16 | /// 17 | /// 18 | /// 19 | void Configure(string directory, params string[] filters); 20 | 21 | /// 22 | /// Starts the watcher and monitors the configured directory. 23 | /// 24 | /// 25 | /// 26 | void Start(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ENBManager.Core.Tests/ViewModels/AboutViewModelTests.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Core.ViewModels; 2 | using NUnit.Framework; 3 | 4 | namespace ENBManager.Core.Tests.ViewModels 5 | { 6 | [TestFixture] 7 | public class AboutViewModelTests 8 | { 9 | private AboutViewModel _viewModel; 10 | 11 | [SetUp] 12 | public void Setup() 13 | { 14 | _viewModel = new AboutViewModel(); 15 | } 16 | 17 | [Test] 18 | public void ShouldHaveDialogTitle() 19 | { 20 | // Assert 21 | Assert.That(string.IsNullOrEmpty(_viewModel.Title), Is.False); 22 | } 23 | 24 | [Test] 25 | public void ShouldHaveAppName() 26 | { 27 | // Assert 28 | Assert.That(string.IsNullOrEmpty(_viewModel.Name), Is.False); 29 | } 30 | 31 | [Test] 32 | public void ShouldHaveAppVersion() 33 | { 34 | // Assert 35 | Assert.That(string.IsNullOrEmpty(_viewModel.Version), Is.False); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/Dialogs/InputDialog.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities.Dialogs.Base; 2 | using System.ComponentModel; 3 | 4 | namespace ENBManager.Infrastructure.BusinessEntities.Dialogs 5 | { 6 | public class InputDialog : BaseDialog, INotifyPropertyChanged 7 | { 8 | #region Private Members 9 | 10 | private string _value; 11 | 12 | #endregion 13 | 14 | #region Public Properties 15 | 16 | public string Value 17 | { 18 | get { return _value; } 19 | set 20 | { 21 | _value = value; 22 | OnPropertyChanged(); 23 | OnPropertyChanged(nameof(Valid)); 24 | } 25 | } 26 | public bool Valid => !string.IsNullOrWhiteSpace(Value); 27 | 28 | #endregion 29 | 30 | #region Constructor 31 | 32 | public InputDialog(string message, string value = "") 33 | : base (message) 34 | { 35 | Value = value; 36 | } 37 | 38 | #endregion 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ENBManager.Logging/Services/PrismLogger.cs: -------------------------------------------------------------------------------- 1 | using NLog; 2 | using Prism.Logging; 3 | 4 | namespace ENBManager.Logging.Services 5 | { 6 | public class PrismLogger : ILoggerFacade 7 | { 8 | #region Private Members 9 | 10 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 11 | 12 | #endregion 13 | 14 | #region ILoggerFacade Implementation 15 | 16 | public void Log(string message, Category category, Priority priority) 17 | { 18 | switch(category) 19 | { 20 | case Category.Debug: 21 | _logger.Debug(message); 22 | break; 23 | case Category.Exception: 24 | _logger.Error(message); 25 | break; 26 | case Category.Info: 27 | _logger.Info(message); 28 | break; 29 | case Category.Warn: 30 | _logger.Warn(message); 31 | break; 32 | } 33 | } 34 | 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ENBManager.Configuration/Interfaces/IConfigurationManager.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Configuration.Models; 2 | 3 | namespace ENBManager.Configuration.Interfaces 4 | { 5 | public interface IConfigurationManager where T : BaseSettings 6 | { 7 | /// 8 | /// The current in-memory settings. 9 | /// 10 | T Settings { get; } 11 | 12 | /// 13 | /// Loads the settings stored from the JSON file. 14 | /// 15 | /// 16 | void LoadSettings(); 17 | 18 | /// 19 | /// Saves the current settings to the JSON file. 20 | /// 21 | /// 22 | void SaveSettings(); 23 | 24 | /// 25 | /// Initializes the current settings if the JSON file does not exists. 26 | /// 27 | void InitializeSettings(); 28 | 29 | /// 30 | /// Sets the read-only attribute of the JSON file. 31 | /// 32 | /// 33 | void SetReadOnly(bool readOnly); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/ViewModels/Base/TabItemBase.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using ENBManager.Modules.Shared.Events; 3 | using ENBManager.Modules.Shared.Interfaces; 4 | using NLog; 5 | using Prism.Events; 6 | using Prism.Mvvm; 7 | 8 | namespace ENBManager.Modules.Shared.ViewModels.Base 9 | { 10 | public abstract class TabItemBase : BindableBase, ITabItem 11 | { 12 | #region Private Members 13 | 14 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 15 | 16 | #endregion 17 | 18 | #region Constructor 19 | 20 | public TabItemBase(IEventAggregator eventAggregator) 21 | { 22 | eventAggregator.GetEvent().Subscribe(OnModuleActivated); 23 | 24 | _logger.Debug($"{this.GetType().Name} initialized"); 25 | } 26 | 27 | #endregion 28 | 29 | #region ITabItem Implementation 30 | 31 | public abstract string Name { get; } 32 | 33 | #endregion 34 | 35 | #region Abstract Methods 36 | 37 | protected abstract void OnModuleActivated(GameModule game); 38 | 39 | #endregion 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/ValueConverters/EmptyCollectionToVisibilityValueConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Globalization; 4 | using System.Windows; 5 | using System.Windows.Data; 6 | 7 | namespace ENBManager.Infrastructure.ValueConverters 8 | { 9 | public class EmptyCollectionToVisibilityValueConverter : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | if (value == null) 14 | return Visibility.Visible; 15 | 16 | else 17 | { 18 | if (value is ICollection list) 19 | { 20 | if (list.Count == 0) 21 | return Visibility.Visible; 22 | else 23 | return Visibility.Collapsed; 24 | } 25 | else 26 | return Visibility.Visible; 27 | } 28 | } 29 | 30 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 31 | { 32 | throw new NotImplementedException(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/GameSettings.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Configuration.Models; 2 | using ENBManager.Infrastructure.Constants; 3 | using System.IO; 4 | 5 | namespace ENBManager.Infrastructure.BusinessEntities 6 | { 7 | public class GameSettings : BaseSettings 8 | { 9 | #region Private Members 10 | 11 | private static readonly string PATH = Paths.GetGamesDirectory(); 12 | private const string FILE_NAME = "gamesettings.json"; 13 | 14 | #endregion 15 | 16 | #region Settings 17 | 18 | public string InstalledLocation { get; set; } = null; 19 | public string ActivePreset { get; set; } = null; 20 | public bool ScreenshotsEnabled { get; set; } = false; 21 | public bool VirtualExecutableEnabled { get; set; } = false; 22 | public string VirtualExecutablePath { get; set; } = null; 23 | 24 | #endregion 25 | 26 | #region Constructors 27 | 28 | public GameSettings(string directory) 29 | : base(Path.Combine(PATH, directory, FILE_NAME)) 30 | { 31 | } 32 | 33 | public GameSettings() 34 | : base("") 35 | { 36 | 37 | } 38 | 39 | #endregion 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Services/GameModuleCatalog.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using ENBManager.Modules.Shared.Interfaces; 3 | using NLog; 4 | using Prism.Ioc; 5 | using System; 6 | using System.Collections.Generic; 7 | 8 | namespace ENBManager.Modules.Shared.Services 9 | { 10 | public class GameModuleCatalog : IGameModuleCatalog 11 | { 12 | #region Private Members 13 | 14 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 15 | 16 | private readonly List _gameModules; 17 | 18 | #endregion 19 | 20 | #region Constructor 21 | 22 | public GameModuleCatalog() 23 | { 24 | _gameModules = new List(); 25 | } 26 | 27 | #endregion 28 | 29 | #region IGameModuleCatalog Implementation 30 | 31 | public IEnumerable GameModules => _gameModules; 32 | 33 | public void Register(IContainerProvider container) where T : GameModule 34 | { 35 | _logger.Debug($"Registering {typeof(T).Name}"); 36 | 37 | _gameModules.Add((GameModule)Activator.CreateInstance(typeof(T), container)); 38 | } 39 | 40 | #endregion 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/ViewModels/ModuleShellViewModel.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Modules.Shared.Events; 2 | using MaterialDesignThemes.Wpf; 3 | using NLog; 4 | using Prism.Events; 5 | using Prism.Mvvm; 6 | 7 | namespace ENBManager.Modules.Shared.ViewModels 8 | { 9 | public class ModuleShellViewModel : BindableBase 10 | { 11 | #region Private Members 12 | 13 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 14 | 15 | #endregion 16 | 17 | #region Public Properties 18 | 19 | public ISnackbarMessageQueue MessageQueue { get; } 20 | 21 | #endregion 22 | 23 | #region Constructor 24 | 25 | public ModuleShellViewModel(IEventAggregator eventAggregator, ISnackbarMessageQueue messageQueue) 26 | { 27 | MessageQueue = messageQueue; 28 | 29 | eventAggregator.GetEvent().Subscribe(ShowSnackbarMessage); 30 | } 31 | 32 | #endregion 33 | 34 | #region Private Methods 35 | 36 | private void ShowSnackbarMessage(string message) 37 | { 38 | _logger.Debug($"Showing message: {message}"); 39 | 40 | MessageQueue.Enqueue(message); 41 | } 42 | 43 | #endregion 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Interfaces/IScreenshotManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ENBManager.Modules.Shared.Interfaces 4 | { 5 | public interface IScreenshotManager 6 | { 7 | /// 8 | /// Gets the screenshots in the provided directory. 9 | /// 10 | /// 11 | /// 12 | List GetScreenshots(string directory, bool includeSubdirectories = false); 13 | 14 | /// 15 | /// Saves a screenshot to the provided directory. 16 | /// 17 | /// 18 | /// 19 | void SaveScreenshot(string directory, string path); 20 | 21 | /// 22 | /// Renames a screenshot directory. 23 | /// 24 | /// 25 | /// 26 | void RenameScreenshotDirectory(string directory, string newName); 27 | 28 | /// 29 | /// Deletes a screenshot directory. 30 | /// 31 | /// 32 | void DeleteScreenshotDirectory(string directory); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/Dialogs/ProgressDialog.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities.Dialogs.Base; 2 | using System; 3 | 4 | namespace ENBManager.Infrastructure.BusinessEntities.Dialogs 5 | { 6 | public class ProgressDialog : BaseDialog, IDisposable 7 | { 8 | #region Private Members 9 | 10 | private int _progress; 11 | 12 | #endregion 13 | 14 | #region Public Properties 15 | 16 | public int Progress 17 | { 18 | get { return _progress; } 19 | set 20 | { 21 | _progress = value; 22 | OnPropertyChanged(); 23 | } 24 | } 25 | 26 | public bool IsIndeterminate { get; set; } 27 | 28 | #endregion 29 | 30 | #region Constructor 31 | 32 | public ProgressDialog(bool isIndeterminate, string message = "") 33 | : base (message) 34 | { 35 | IsIndeterminate = isIndeterminate; 36 | 37 | if (isIndeterminate) 38 | Progress = 0; 39 | } 40 | 41 | #endregion 42 | 43 | #region IDisposable Implementation 44 | 45 | public void Dispose() 46 | { 47 | Close(); 48 | } 49 | 50 | #endregion 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ENBManager.Modules/Skyrim/SkyrimModule.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using ENBManager.Infrastructure.Constants; 3 | using ENBManager.Modules.Shared.Views; 4 | using Prism.Ioc; 5 | using System; 6 | using System.Windows.Media.Imaging; 7 | 8 | namespace ENBManager.Modules.Skyrim 9 | { 10 | public class SkyrimModule : GameModule 11 | { 12 | #region Constructor 13 | 14 | public SkyrimModule(IContainerProvider container) 15 | : base(container) { } 16 | 17 | #endregion 18 | 19 | #region GameModule Override 20 | 21 | public override string Title => "The Elder Scrolls V: Skyrim"; 22 | public override string Executable => "TESV.exe"; 23 | public override string Module => ModuleNames.SKYRIM; 24 | public override BitmapImage Icon => new BitmapImage(new Uri("pack://application:,,,/ENBManager.Infrastructure;component/Resources/Icons/skyrim.png")); 25 | public override string[] Binaries => new[] { "d3d9.dll" }; 26 | public override string Url => "https://www.nexusmods.com/skyrim"; 27 | 28 | public override void Activate() 29 | { 30 | ActivateModule(typeof(DashboardView), typeof(PresetsView), typeof(ScreenshotView)); 31 | } 32 | 33 | #endregion 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ENBManager.Modules/Fallout3/Fallout3Module.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using ENBManager.Infrastructure.Constants; 3 | using ENBManager.Modules.Shared.Views; 4 | using Prism.Ioc; 5 | using System; 6 | using System.Windows.Media.Imaging; 7 | 8 | namespace ENBManager.Modules.Fallout4 9 | { 10 | public class Fallout3Module : GameModule 11 | { 12 | #region Constructor 13 | 14 | public Fallout3Module(IContainerProvider container) 15 | : base(container) { } 16 | 17 | #endregion 18 | 19 | #region GameModule Override 20 | 21 | public override string Title => "Fallout 3"; 22 | public override string Executable => "Fallout3.exe"; 23 | public override string Module => ModuleNames.FALLOUT3; 24 | public override BitmapImage Icon => new BitmapImage(new Uri("pack://application:,,,/ENBManager.Infrastructure;component/Resources/Icons/fallout3.png")); 25 | public override string[] Binaries => new[] { "d3d9.dll" }; 26 | public override string Url => "https://www.nexusmods.com/fallout3"; 27 | 28 | public override void Activate() 29 | { 30 | ActivateModule(typeof(DashboardView), typeof(PresetsView), typeof(ScreenshotView)); 31 | } 32 | 33 | #endregion 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ENBManager.Modules/FalloutNV/FalloutNVModule.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using ENBManager.Infrastructure.Constants; 3 | using ENBManager.Modules.Shared.Views; 4 | using Prism.Ioc; 5 | using System; 6 | using System.Windows.Media.Imaging; 7 | 8 | namespace ENBManager.Modules.Fallout4 9 | { 10 | public class FalloutNVModule : GameModule 11 | { 12 | #region Constructor 13 | 14 | public FalloutNVModule(IContainerProvider container) 15 | : base(container) { } 16 | 17 | #endregion 18 | 19 | #region GameModule Override 20 | 21 | public override string Title => "Fallout: New Vegas"; 22 | public override string Executable => "FalloutNV.exe"; 23 | public override string Module => ModuleNames.FALLOUTNV; 24 | public override BitmapImage Icon => new BitmapImage(new Uri("pack://application:,,,/ENBManager.Infrastructure;component/Resources/Icons/falloutnv.png")); 25 | public override string[] Binaries => new[] { "d3d9.dll" }; 26 | public override string Url => "https://www.nexusmods.com/newvegas"; 27 | 28 | public override void Activate() 29 | { 30 | ActivateModule(typeof(DashboardView), typeof(PresetsView), typeof(ScreenshotView)); 31 | } 32 | 33 | #endregion 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ENBManager.Core/Helpers/GameLocator.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using NLog; 3 | using System.Threading.Tasks; 4 | 5 | namespace ENBManager.Core.Helpers 6 | { 7 | /// 8 | /// A static helper class that provides functions related to locate installed games. 9 | /// 10 | public static class GameLocator 11 | { 12 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 13 | 14 | public static async Task Find(string title) 15 | { 16 | _logger.Debug($"Attempts to find game '{title}'"); 17 | 18 | string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; 19 | using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key)) 20 | { 21 | foreach (var subkeyName in key.GetSubKeyNames()) 22 | { 23 | using (RegistryKey subkey = key.OpenSubKey(subkeyName)) 24 | { 25 | if ((subkey.GetValue("DisplayName") as string) == title) 26 | return await Task.FromResult(subkey.GetValue("InstallLocation") as string); 27 | } 28 | } 29 | } 30 | 31 | return await Task.FromResult(string.Empty); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ENBManager.Modules/Fallout4/Fallout4Module.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using ENBManager.Infrastructure.Constants; 3 | using ENBManager.Modules.Shared.Views; 4 | using Prism.Ioc; 5 | using System; 6 | using System.Windows.Media.Imaging; 7 | 8 | namespace ENBManager.Modules.Fallout4 9 | { 10 | public class Fallout4Module : GameModule 11 | { 12 | #region Constructor 13 | 14 | public Fallout4Module(IContainerProvider container) 15 | : base(container) { } 16 | 17 | #endregion 18 | 19 | #region GameModule Override 20 | 21 | public override string Title => "Fallout 4"; 22 | public override string Executable => "Fallout4.exe"; 23 | public override string Module => ModuleNames.FALLOUT4; 24 | public override BitmapImage Icon => new BitmapImage(new Uri("pack://application:,,,/ENBManager.Infrastructure;component/Resources/Icons/fallout4.png")); 25 | public override string[] Binaries => new[] { "d3d11.dll", "d3dcompiler_46e.dll" }; 26 | public override string Url => "https://www.nexusmods.com/fallout4"; 27 | 28 | public override void Activate() 29 | { 30 | ActivateModule(typeof(DashboardView), typeof(PresetsView), typeof(ScreenshotView)); 31 | } 32 | 33 | #endregion 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ENBManager.Modules/ENBManager.Modules.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | true 6 | AnyCPU;x64 7 | False 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /ENBManager.Modules/SkyrimSE/SkyrimSEModule.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using ENBManager.Infrastructure.Constants; 3 | using ENBManager.Modules.Shared.Views; 4 | using Prism.Ioc; 5 | using System; 6 | using System.Windows.Media.Imaging; 7 | 8 | namespace ENBManager.Modules.SkyrimSE 9 | { 10 | public class SkyrimSEModule : GameModule 11 | { 12 | #region Constructor 13 | 14 | public SkyrimSEModule(IContainerProvider container) 15 | : base(container) { } 16 | 17 | #endregion 18 | 19 | #region GameModule Override 20 | 21 | public override string Title => "The Elder Scrolls V: Skyrim Special Edition"; 22 | public override string Executable => "SkyrimSE.exe"; 23 | public override string Module => ModuleNames.SKYRIMSE; 24 | public override BitmapImage Icon => new BitmapImage(new Uri("pack://application:,,,/ENBManager.Infrastructure;component/Resources/Icons/skyrimse.png")); 25 | public override string[] Binaries => new[] {"d3d11.dll", "d3dcompiler_46e.dll"}; 26 | public override string Url => "https://www.nexusmods.com/skyrimspecialedition"; 27 | 28 | public override void Activate() 29 | { 30 | ActivateModule(typeof(DashboardView), typeof(PresetsView), typeof(ScreenshotView)); 31 | } 32 | 33 | #endregion 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Models/Notification.cs: -------------------------------------------------------------------------------- 1 | using Prism.Commands; 2 | using System; 3 | 4 | namespace ENBManager.Modules.Shared.Models 5 | { 6 | public class Notification 7 | { 8 | #region Public Properties 9 | 10 | public Icon Icon { get; set; } 11 | public string Message { get; set; } 12 | public Action Action { get; set; } 13 | public string ActionButtonText { get; set; } 14 | public bool IsActive { get; set; } 15 | 16 | #endregion 17 | 18 | #region Commands 19 | 20 | public DelegateCommand ExecuteActionCommand { get; } 21 | public DelegateCommand HideCommand { get; } 22 | 23 | #endregion 24 | 25 | #region Constructor 26 | 27 | public Notification(Icon icon, string message, Action action, string actionButtonText) 28 | { 29 | Icon = icon; 30 | Message = message; 31 | Action = action; 32 | ActionButtonText = actionButtonText; 33 | IsActive = true; 34 | 35 | ExecuteActionCommand = action == null ? null : new DelegateCommand(action); 36 | HideCommand = new DelegateCommand(() => IsActive = false); 37 | } 38 | 39 | #endregion 40 | } 41 | 42 | public enum Icon 43 | { 44 | Success = 0, 45 | Warning = 1, 46 | Error = 2 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/Dialogs/Node.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace ENBManager.Modules.Shared.Models.Base 5 | { 6 | public abstract class Node : INotifyPropertyChanged 7 | { 8 | #region Private Members 9 | 10 | private string _name; 11 | private bool _isSelected; 12 | 13 | #endregion 14 | 15 | #region Public Properties 16 | 17 | public string Name 18 | { 19 | get { return _name; } 20 | set 21 | { 22 | _name = value; 23 | OnPropertyChanged(); 24 | } 25 | } 26 | 27 | public string Path { get; set; } 28 | 29 | public bool IsSelected 30 | { 31 | get { return _isSelected; } 32 | set 33 | { 34 | _isSelected = value; 35 | OnPropertyChanged(); 36 | } 37 | } 38 | 39 | #endregion 40 | 41 | #region INotifyPropertyChanged Implementation 42 | 43 | public event PropertyChangedEventHandler PropertyChanged; 44 | 45 | public void OnPropertyChanged([CallerMemberName] string name = null) 46 | { 47 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 48 | } 49 | 50 | #endregion 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/Base/Node.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace ENBManager.Infrastructure.BusinessEntities.Base 5 | { 6 | public abstract class Node : INotifyPropertyChanged 7 | { 8 | #region Private Members 9 | 10 | private string _name; 11 | private bool _isSelected; 12 | 13 | #endregion 14 | 15 | #region Public Properties 16 | 17 | public string Name 18 | { 19 | get { return _name; } 20 | set 21 | { 22 | _name = value; 23 | OnPropertyChanged(); 24 | } 25 | } 26 | 27 | public string Path { get; set; } 28 | 29 | public bool IsSelected 30 | { 31 | get { return _isSelected; } 32 | set 33 | { 34 | _isSelected = value; 35 | OnPropertyChanged(); 36 | } 37 | } 38 | 39 | #endregion 40 | 41 | #region INotifyPropertyChanged Implementation 42 | 43 | public event PropertyChangedEventHandler PropertyChanged; 44 | 45 | public void OnPropertyChanged([CallerMemberName] string name = null) 46 | { 47 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 48 | } 49 | 50 | #endregion 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/MainView.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 12 | 18 | 19 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Constants/DefaultKeywords.cs: -------------------------------------------------------------------------------- 1 | namespace ENBManager.Infrastructure.Constants 2 | { 3 | public static class DefaultKeywords 4 | { 5 | public static string[] FILES { get; } = { 6 | "enb", 7 | "ReShade", 8 | "dxgi", 9 | 10 | "_weatherlist.ini", 11 | "AmbientLight.fx", 12 | "Bloom.fx", 13 | "common.fxh", 14 | "Curves.fx", 15 | "d3d9.fx", 16 | "d3d9_fx.dll", 17 | "d3d9_fxaa.dll", 18 | "d3d9_SFX.dll", 19 | "d3d9_SFX_FXAA.dll", 20 | "d3d9_SFX_SMAA.dll", 21 | "d3d9_Sharpen.dll", 22 | "d3d9_smaa.dll", 23 | "d3d9_sweetfx.dll", 24 | "d3d9injFX.dll", 25 | "DefaultPreset.ini", 26 | "DPX.fx", 27 | "effect.txt", 28 | "FXAA.fxh", 29 | "HDR.fx", 30 | "injector.ini", 31 | "injFX_Settings.h", 32 | "LumaSharpen.fx", 33 | "LUT.fx", 34 | "shader.fx", 35 | "SMAA.fx", 36 | "SMAA.fh", 37 | "SMAA.h", 38 | "SweetFX_preset.txt", 39 | "SweetFX_settings.txt", 40 | "technique.fxh", 41 | "Vibrance.fx" 42 | }; 43 | 44 | public static string[] DIRECTORIES { get; } = { 45 | "Data\\Shaders", 46 | "enb", 47 | "injFX_Shaders", 48 | "ReShade", 49 | "SweetFX" 50 | }; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Models/Preset.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | using System.ComponentModel; 4 | using System.Runtime.CompilerServices; 5 | 6 | namespace ENBManager.Modules.Shared.Models 7 | { 8 | public class Preset : INotifyPropertyChanged 9 | { 10 | #region Private Members 11 | 12 | private string _name; 13 | private bool _isActive; 14 | 15 | #endregion 16 | 17 | #region Public Properties 18 | 19 | public string FullPath { get; set; } 20 | 21 | public string Name 22 | { 23 | get { return _name; } 24 | set 25 | { 26 | _name = value; 27 | OnPropertyChanged(); 28 | } 29 | } 30 | 31 | public bool IsActive 32 | { 33 | get { return _isActive; } 34 | set 35 | { 36 | _isActive = value; 37 | OnPropertyChanged(); 38 | } 39 | } 40 | 41 | public IEnumerable Files { get; set; } 42 | 43 | public ObservableCollection Screenshots { get; set; } 44 | 45 | #endregion 46 | 47 | #region INotifyPropertyChanged Implementation 48 | 49 | public event PropertyChangedEventHandler PropertyChanged; 50 | 51 | public void OnPropertyChanged([CallerMemberName] string name = null) 52 | { 53 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 54 | } 55 | 56 | #endregion 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/AppSettings.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Configuration.Models; 2 | using ENBManager.Infrastructure.Constants; 3 | using ENBManager.Logging.Enums; 4 | using System.IO; 5 | 6 | namespace ENBManager.Infrastructure.BusinessEntities 7 | { 8 | public class AppSettings : BaseSettings 9 | { 10 | #region Private Members 11 | 12 | private static readonly string PATH = Path.Combine(Paths.GetBaseDirectory(), "appsettings.json"); 13 | 14 | #endregion 15 | 16 | #region Settings 17 | 18 | public bool Initialized { get; set; } = false; 19 | public bool OpenLastActiveGame { get; set; } = true; 20 | public string LastActiveGame { get; set; } = ""; 21 | public bool DarkMode { get; set; } = true; 22 | public bool DarkModeShortcut { get; set; } = true; 23 | public string ColorScheme { get; set; } = "Flamingo"; 24 | public LogLevel LogLevel { get; set; } = LogLevel.Information; 25 | public bool DefaultPresetView { get; set; } = true; 26 | public bool ManageBinaries { get; set; } = true; 27 | public bool EnableScreenshotWithoutPreset { get; set; } = true; 28 | public bool DeleteScreenshotsWhenDeletingPreset { get; set; } = true; 29 | public bool MinimizeToTray { get; set; } = true; 30 | public bool RunGameShortcut { get; set; } = false; 31 | 32 | #endregion 33 | 34 | #region Constructor 35 | 36 | public AppSettings() 37 | : base(PATH) 38 | { 39 | } 40 | 41 | #endregion 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ENBManager.App/ENBManager.App.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WinExe 5 | netcoreapp3.1 6 | true 7 | AnyCPU;x64 8 | win-x64 9 | win-x64 10 | true 11 | true 12 | favicon.ico 13 | 1.0.0 14 | ENBManager 15 | Toll 16 | André Toll 17 | ENBManager 18 | ENBManager 19 | False 20 | false 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /ENBManager.Modules.Tests/Shared/Services/GameModuleCatalogTests.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using ENBManager.Modules.Shared.Services; 3 | using NUnit.Framework; 4 | using Prism.Ioc; 5 | using System.Windows.Media.Imaging; 6 | 7 | namespace ENBManager.Modules.Tests.Shared.Services 8 | { 9 | [TestFixture] 10 | public class GameModuleCatalogTests 11 | { 12 | [Test] 13 | public void ShouldRegisterGameModule() 14 | { 15 | // Arrange 16 | var catalog = new GameModuleCatalog(); 17 | 18 | // Act 19 | catalog.Register(null); 20 | 21 | // Assert 22 | Assert.That(catalog.GameModules, Has.Count.EqualTo(1)); 23 | } 24 | } 25 | 26 | internal class Game : GameModule 27 | { 28 | public override string Title => throw new System.NotImplementedException(); 29 | 30 | public override BitmapImage Icon => throw new System.NotImplementedException(); 31 | 32 | public override string Executable => throw new System.NotImplementedException(); 33 | 34 | public override string Module => throw new System.NotImplementedException(); 35 | 36 | public override string[] Binaries => throw new System.NotImplementedException(); 37 | 38 | public override string Url => throw new System.NotImplementedException(); 39 | 40 | public override void Activate() 41 | { 42 | throw new System.NotImplementedException(); 43 | } 44 | 45 | public Game(IContainerProvider containerProvider) 46 | : base(containerProvider) 47 | { 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ENBManager.Core/ENBManager.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | true 6 | AnyCPU;x64 7 | False 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Code 34 | 35 | 36 | 37 | 38 | 39 | Designer 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ENBManager.TestUtils/TestValues.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Windows; 5 | using System.Windows.Media; 6 | using System.Windows.Media.Imaging; 7 | 8 | namespace ENBManager.TestUtils.Utils 9 | { 10 | public static class TestValues 11 | { 12 | private static readonly Random random = new Random(); 13 | 14 | public static string GetRandomString() 15 | { 16 | const string chars = "ABCDEFGHIJKLMNOPQRSTUVXYZÅÄÖ0123456789!?&%=_-éèáà"; 17 | return new string(Enumerable.Repeat(chars, 10) 18 | .Select(s => s[random.Next(s.Length)]).ToArray()); 19 | } 20 | 21 | public static BitmapImage GetRandomImage() 22 | { 23 | const uint red = 0xFFFF0000, green = 0xFF00FF00; 24 | var bmp = new WriteableBitmap(800, 600, 96, 96, PixelFormats.Pbgra32, null); 25 | var data = Enumerable.Range(0, 800 * 600).Select(x => random.NextDouble() > 0.5 ? red : green).ToArray(); 26 | bmp.WritePixels(new Int32Rect(0, 0, 800, 600), data, bmp.BackBufferStride, 0); 27 | 28 | var image = new BitmapImage(); 29 | using (var stream = new MemoryStream()) 30 | { 31 | var encoder = new PngBitmapEncoder(); 32 | encoder.Frames.Add(BitmapFrame.Create(bmp)); 33 | encoder.Save(stream); 34 | image.BeginInit(); 35 | image.CacheOption = BitmapCacheOption.OnLoad; 36 | image.StreamSource = stream; 37 | image.EndInit(); 38 | image.Freeze(); 39 | } 40 | return image; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Services/ScreenshotWatcher.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Modules.Shared.Interfaces; 2 | using NLog; 3 | using System.Collections.ObjectModel; 4 | using System.Configuration; 5 | using System.IO; 6 | 7 | namespace ENBManager.Modules.Shared.Services 8 | { 9 | public class ScreenshotWatcher : IScreenshotWatcher 10 | { 11 | #region Private Members 12 | 13 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 14 | 15 | private readonly FileSystemWatcher _watcher; 16 | 17 | #endregion 18 | 19 | #region Constructor 20 | 21 | public ScreenshotWatcher() 22 | { 23 | _watcher = new FileSystemWatcher(); 24 | } 25 | 26 | #endregion 27 | 28 | #region Events 29 | 30 | public event FileSystemEventHandler FileCreated; 31 | 32 | #endregion 33 | 34 | #region Public Methods 35 | 36 | public void Stop() 37 | { 38 | _watcher.Created -= FileCreated; 39 | 40 | _watcher.EnableRaisingEvents = false; 41 | 42 | _logger.Info("ScreenshotWatcher stopped"); 43 | } 44 | 45 | public void Configure(string directory, params string[] filters) 46 | { 47 | _watcher.Path = directory; 48 | _watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime | NotifyFilters.LastWrite; 49 | _watcher.Filters.AddRange(filters); 50 | 51 | _logger.Info("ScreenshotWatcher configured"); 52 | } 53 | 54 | public void Start() 55 | { 56 | if (string.IsNullOrEmpty(_watcher.Path) || _watcher.Filters.Count == 0) 57 | throw new ConfigurationErrorsException("The watcher is not configured."); 58 | 59 | _watcher.Created += FileCreated; 60 | 61 | _watcher.EnableRaisingEvents = true; 62 | 63 | _logger.Info("ScreenshotWatcher started"); 64 | } 65 | 66 | #endregion 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ENBManager.Core/ViewModels/AboutViewModel.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.Constants; 2 | using ENBManager.Localization.Strings; 3 | using NLog; 4 | using Prism.Commands; 5 | using Prism.Services.Dialogs; 6 | using System; 7 | using System.Diagnostics; 8 | using System.Reflection; 9 | 10 | namespace ENBManager.Core.ViewModels 11 | { 12 | public class AboutViewModel : IDialogAware 13 | { 14 | #region Private Members 15 | 16 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 17 | 18 | #endregion 19 | 20 | #region Public Properties 21 | 22 | public string Name => ApplicationName.NAME; 23 | public string Version => Assembly.GetExecutingAssembly().GetName().Version.ToString(); 24 | 25 | #endregion 26 | 27 | #region Commands 28 | 29 | public DelegateCommand OpenSourceCodeCommand { get; } 30 | 31 | #endregion 32 | 33 | #region Constructor 34 | 35 | public AboutViewModel() 36 | { 37 | OpenSourceCodeCommand = new DelegateCommand(OnOpenSourceCodeCommand); 38 | } 39 | 40 | #endregion 41 | 42 | #region Private Methods 43 | 44 | private void OnOpenSourceCodeCommand() 45 | { 46 | _logger.Info($"Opening {Urls.SOURCE_CODE}"); 47 | 48 | var psi = new ProcessStartInfo 49 | { 50 | FileName = Urls.SOURCE_CODE, 51 | UseShellExecute = true 52 | }; 53 | 54 | Process.Start(psi); 55 | } 56 | 57 | #endregion 58 | 59 | #region IDialogAware Implementation 60 | 61 | public string Title => Strings.ABOUT; 62 | 63 | public event Action RequestClose; 64 | 65 | public bool CanCloseDialog() => true; 66 | 67 | public void OnDialogClosed() 68 | { 69 | _logger.Info("Closed"); 70 | } 71 | 72 | public void OnDialogOpened(IDialogParameters parameters) 73 | { 74 | _logger.Info("Opened"); 75 | } 76 | 77 | #endregion 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Views/ModuleShell.xaml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /ENBManager.Core.Tests/Stubs/FileServiceStub.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.Enums; 2 | using ENBManager.Infrastructure.Interfaces; 3 | using ENBManager.TestUtils.Utils; 4 | 5 | namespace ENBManager.Core.Tests.Stubs 6 | { 7 | public class GameServiceStub : IGameService 8 | { 9 | public string[] AppendBinaryVersions(string target, string[] binaries) 10 | { 11 | throw new System.NotImplementedException(); 12 | } 13 | 14 | public string BrowseGameExecutable(string fileName) 15 | { 16 | return TestValues.GetRandomString(); 17 | } 18 | 19 | public void CopyBinaries(string source, string target, string[] binaries) 20 | { 21 | throw new System.NotImplementedException(); 22 | } 23 | 24 | public void DeleteBinaries(string target, string[] binaries) 25 | { 26 | throw new System.NotImplementedException(); 27 | } 28 | 29 | public void DeleteGameDirectory(string directoryName) 30 | { 31 | throw new System.NotImplementedException(); 32 | } 33 | 34 | public string[] GetGameDirectories() 35 | { 36 | throw new System.NotImplementedException(); 37 | } 38 | 39 | public string[] VerifyBinaries(string directoryPath, string[] files) 40 | { 41 | throw new System.NotImplementedException(); 42 | } 43 | 44 | public bool VerifyBinaries(string directoryPath, string[] files, out string[] missingBinaries) 45 | { 46 | throw new System.NotImplementedException(); 47 | } 48 | 49 | public bool VerifyBinariesBackup(string directoryPath, params string[] binaries) 50 | { 51 | throw new System.NotImplementedException(); 52 | } 53 | 54 | public VersionMismatch VerifyBinariesVersion(string source, string target, string[] binaries) 55 | { 56 | throw new System.NotImplementedException(); 57 | } 58 | 59 | bool IGameService.VerifyBinaries(string directoryPath, string[] files) 60 | { 61 | throw new System.NotImplementedException(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ENBManager.Core.Tests/ViewModels/GameSettingsViewModelTests.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Core.ViewModels; 2 | using ENBManager.Infrastructure.BusinessEntities; 3 | using NUnit.Framework; 4 | using Prism.Services.Dialogs; 5 | 6 | namespace ENBManager.Core.Tests.ViewModels 7 | { 8 | [TestFixture] 9 | public class GameSettingsViewModelTests 10 | { 11 | private GameSettingsViewModel _viewModel; 12 | 13 | [SetUp] 14 | public void Setup() 15 | { 16 | _viewModel = new GameSettingsViewModel(); 17 | } 18 | 19 | [TestCase("Skyrim")] 20 | [TestCase("Fallout 4")] 21 | [TestCase("Fallout 3")] 22 | public void ShouldHaveDialogTitle(string title) 23 | { 24 | // Arrange 25 | DialogParameters dp = new DialogParameters() 26 | { 27 | { "Title", title } 28 | }; 29 | 30 | // Act 31 | _viewModel.OnDialogOpened(dp); 32 | 33 | // Assert 34 | Assert.That(string.IsNullOrEmpty(_viewModel.Title), Is.False); 35 | Assert.That(_viewModel.Title, Is.EqualTo(title)); 36 | } 37 | 38 | [TestCase(true, "C:\\Dir\\Subdir\\Subsubdir")] 39 | [TestCase(false, "C:\\Dir\\Subdir\\Subsubdir")] 40 | [TestCase(true, null)] 41 | [TestCase(false, null)] 42 | public void ShouldInitializeSettings(bool enabled, string path) 43 | { 44 | // Arrange 45 | var gameSettings = new GameSettings(); 46 | gameSettings.VirtualExecutableEnabled = enabled; 47 | gameSettings.VirtualExecutablePath = path; 48 | DialogParameters dp = new DialogParameters() 49 | { 50 | { "GameSettings", gameSettings } 51 | }; 52 | 53 | // Act 54 | _viewModel.OnDialogOpened(dp); 55 | 56 | // Assert 57 | Assert.That(_viewModel.Settings.VirtualExecutableEnabled, Is.EqualTo(enabled)); 58 | Assert.That(_viewModel.Settings.VirtualExecutablePath, Is.EqualTo(path)); 59 | Assert.That(_viewModel.VirtualExecutablePath, Is.EqualTo(path)); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Constants/Paths.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace ENBManager.Infrastructure.Constants 5 | { 6 | public static class Paths 7 | { 8 | #region Private Members 9 | 10 | private const string BASE_DIRECTORY = "ENBManager"; 11 | private const string GAMES_DIRECTORY = "Games"; 12 | private const string PRESETS_DIRECTORY = "Presets"; 13 | private const string BINARIES_BACKUP_DIRECTORY = "Binaries"; 14 | private const string SCREENSHOTS_DIRECTORY = "Screenshots"; 15 | private const string KEYWORDS_FILE = "keywords.json"; 16 | 17 | #endregion 18 | 19 | #region Public Methods 20 | 21 | public static string GetBaseDirectory() 22 | { 23 | return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), BASE_DIRECTORY); 24 | } 25 | 26 | public static string GetGamesDirectory() 27 | { 28 | return Path.Combine(GetBaseDirectory(), GAMES_DIRECTORY); 29 | } 30 | 31 | public static string GetPresetsDirectory(string module) 32 | { 33 | return Path.Combine(GetBaseDirectory(), GAMES_DIRECTORY, module, PRESETS_DIRECTORY); 34 | } 35 | 36 | public static string GetBinariesBackupDirectory(string module) 37 | { 38 | return Path.Combine(GetBaseDirectory(), GAMES_DIRECTORY, module, BINARIES_BACKUP_DIRECTORY); 39 | } 40 | 41 | public static string GetScreenshotsDirectory(string module) 42 | { 43 | return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), BASE_DIRECTORY, SCREENSHOTS_DIRECTORY, module); 44 | } 45 | 46 | public static string GetPresetScreenshotsDirectory(string module, string preset) 47 | { 48 | return Path.Combine(GetScreenshotsDirectory(module), preset); 49 | } 50 | 51 | public static string GetKeywordsFilePath() 52 | { 53 | return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), BASE_DIRECTORY, KEYWORDS_FILE); 54 | } 55 | 56 | #endregion 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Services/ScreenshotManager.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Modules.Shared.Interfaces; 2 | using NLog; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Threading; 7 | 8 | namespace ENBManager.Modules.Shared.Services 9 | { 10 | public class ScreenshotManager : IScreenshotManager 11 | { 12 | #region Private Members 13 | 14 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 15 | 16 | private const int SCREENSHOT_TIMEOUT = 3000; 17 | 18 | #endregion 19 | 20 | #region IScreenshotManager Implementation 21 | 22 | public List GetScreenshots(string directory, bool includeSubdirectories = false) 23 | { 24 | _logger.Debug("Getting screenshots"); 25 | 26 | if (!Directory.Exists(directory)) 27 | return new List(); 28 | 29 | return Directory.GetFiles(directory, "*", includeSubdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).ToList(); 30 | } 31 | 32 | public void SaveScreenshot(string directory, string path) 33 | { 34 | _logger.Debug($"Saving screenshot {path}"); 35 | 36 | if (!Directory.Exists(directory)) 37 | Directory.CreateDirectory(directory); 38 | 39 | Thread.Sleep(SCREENSHOT_TIMEOUT); 40 | File.Move(path, Path.Combine(directory, Path.GetFileName(path)), true); 41 | } 42 | 43 | public void RenameScreenshotDirectory(string directory, string newName) 44 | { 45 | _logger.Debug("Renaming screenshot directory"); 46 | 47 | string destination = Path.Combine(new DirectoryInfo(directory).Parent.FullName, newName); 48 | 49 | if (directory.Equals(destination)) 50 | return; 51 | 52 | Directory.Move(directory, destination); 53 | } 54 | 55 | public void DeleteScreenshotDirectory(string directory) 56 | { 57 | _logger.Debug("Deleting screenshot directory"); 58 | 59 | if (Directory.Exists(directory)) 60 | Directory.Delete(directory, true); 61 | } 62 | 63 | #endregion 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/Shell.xaml.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Core.ViewModels; 2 | using System; 3 | using System.Windows; 4 | 5 | namespace ENBManager.Core.Views 6 | { 7 | /// 8 | /// Interaction logic for Shell.xaml 9 | /// 10 | public partial class Shell : Window 11 | { 12 | #region Private Members 13 | 14 | private ShellViewModel _viewModel; 15 | 16 | #endregion 17 | 18 | public Shell() 19 | { 20 | InitializeComponent(); 21 | 22 | StateChanged += Shell_StateChanged; 23 | 24 | _viewModel = DataContext as ShellViewModel; 25 | _viewModel.ExitApplicationEventHandler += ViewModel_ExitApplicationEventHandler; 26 | _viewModel.RestoreApplicationEventHandler += _viewModel_RestoreApplicationEventHandler; 27 | } 28 | 29 | #region Events 30 | 31 | private void Shell_StateChanged(object sender, EventArgs e) 32 | { 33 | switch (WindowState) 34 | { 35 | case WindowState.Minimized: 36 | Minimize(); 37 | break; 38 | case WindowState.Normal: 39 | RestoreWindow(); 40 | break; 41 | } 42 | } 43 | 44 | private void ViewModel_ExitApplicationEventHandler(object sender, EventArgs e) 45 | { 46 | ExitApplication(); 47 | } 48 | 49 | private void _viewModel_RestoreApplicationEventHandler(object sender, EventArgs e) 50 | { 51 | RestoreWindow(); 52 | } 53 | 54 | #endregion 55 | 56 | #region Private Methods 57 | 58 | private void ExitApplication() 59 | { 60 | Application.Current.Shutdown(); 61 | } 62 | 63 | private void Minimize() 64 | { 65 | _viewModel.ShowNotifyIcon = true; 66 | 67 | if (_viewModel.MinimizeToTray) 68 | Hide(); 69 | } 70 | 71 | private void RestoreWindow() 72 | { 73 | _viewModel.ShowNotifyIcon = false; 74 | 75 | if (Visibility != Visibility.Visible) 76 | Show(); 77 | 78 | WindowState = WindowState.Normal; 79 | } 80 | 81 | #endregion 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/BusinessEntities/Dialogs/Base/BaseDialog.cs: -------------------------------------------------------------------------------- 1 | using MaterialDesignThemes.Wpf; 2 | using NLog; 3 | using System.ComponentModel; 4 | using System.Runtime.CompilerServices; 5 | using System.Threading.Tasks; 6 | 7 | namespace ENBManager.Infrastructure.BusinessEntities.Dialogs.Base 8 | { 9 | public abstract class BaseDialog 10 | { 11 | #region Private Members 12 | 13 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 14 | 15 | private string _hostIdentifier; 16 | 17 | #endregion 18 | 19 | #region Public Properties 20 | 21 | public string Message { get; set; } 22 | 23 | #endregion 24 | 25 | #region Constructor 26 | 27 | public BaseDialog(string message) 28 | { 29 | Message = message; 30 | } 31 | 32 | #endregion 33 | 34 | #region Public Methods 35 | 36 | /// 37 | /// Sets the target unique identifier. 38 | /// 39 | /// 40 | public void SetHost(string hostIdentifier) 41 | { 42 | _logger.Debug($"Setting host '{hostIdentifier}'"); 43 | 44 | _hostIdentifier = hostIdentifier; 45 | } 46 | 47 | public async Task OpenAsync() 48 | { 49 | _logger.Debug($"Opening {this.GetType().Name}"); 50 | 51 | await CloseAsync(); 52 | var result = await DialogHost.Show(this, _hostIdentifier); 53 | 54 | return result != null && (bool)result; 55 | } 56 | 57 | public void Close() 58 | { 59 | _logger.Debug($"Closing {this.GetType().Name}"); 60 | 61 | DialogHost.CloseDialogCommand.Execute(null, null); 62 | } 63 | 64 | public Task CloseAsync() 65 | { 66 | _logger.Debug($"Closing {this.GetType().Name}"); 67 | 68 | DialogHost.CloseDialogCommand.Execute(null, null); 69 | return Task.CompletedTask; 70 | } 71 | 72 | #endregion 73 | 74 | #region INotifyPropertyChanged Implementation 75 | 76 | public event PropertyChangedEventHandler PropertyChanged; 77 | 78 | public void OnPropertyChanged([CallerMemberName] string name = null) 79 | { 80 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 81 | } 82 | 83 | #endregion 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Interfaces/IGameService.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.Enums; 2 | 3 | namespace ENBManager.Infrastructure.Interfaces 4 | { 5 | public interface IGameService 6 | { 7 | /// 8 | /// Retrieves the managed games defined by existing folders in ProgramData. 9 | /// 10 | /// 11 | string[] GetGameDirectories(); 12 | 13 | /// 14 | /// Deletes a managed game directory from disk. 15 | /// 16 | void DeleteGameDirectory(string directoryName); 17 | 18 | /// 19 | /// Verifies the existance of the files provided. Returns any missing files. 20 | /// 21 | /// 22 | /// 23 | /// 24 | bool VerifyBinaries(string directoryPath, string[] files, out string[] missingBinaries); 25 | 26 | /// 27 | /// Verifies the existance of the files provided. 28 | /// 29 | /// 30 | /// 31 | /// 32 | bool VerifyBinaries(string directoryPath, string[] files); 33 | 34 | /// 35 | /// Verifies the version of the provided binaries compared to the binaries in the game directory. 36 | /// 37 | /// 38 | /// 39 | /// 40 | /// 41 | VersionMismatch VerifyBinariesVersion(string source, string target, string[] binaries); 42 | 43 | /// 44 | /// Creates backup files of the provided files. 45 | /// 46 | /// 47 | /// 48 | /// 49 | void CopyBinaries(string source, string target, string[] binaries); 50 | 51 | /// 52 | /// Deletes the binaries from the target directory. 53 | /// 54 | /// 55 | /// 56 | void DeleteBinaries(string target, string[] binaries); 57 | 58 | /// 59 | /// Gets the file version of the provided files. 60 | /// 61 | /// 62 | /// 63 | string[] AppendBinaryVersions(string target, string[] binaries); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/Shell.xaml: -------------------------------------------------------------------------------- 1 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Resources/TabControls.xaml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 9 | 10 | 11 | 57 | 58 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Interfaces/IPresetManager.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Modules.Shared.Models; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | 5 | namespace ENBManager.Modules.Shared.Interfaces 6 | { 7 | public interface IPresetManager 8 | { 9 | /// 10 | /// Gets the presets located in folder. 11 | /// 12 | /// 13 | IEnumerable GetPresets(string path); 14 | 15 | /// 16 | /// Gets a specific preset in folder. 17 | /// 18 | /// 19 | /// 20 | Task GetPresetAsync(string path, string preset); 21 | 22 | /// 23 | /// Renames a preset in folder and returns the new full path. 24 | /// 25 | /// 26 | /// 27 | /// 28 | string RenamePreset(Preset preset, string newName); 29 | 30 | /// 31 | /// Deletes a preset in folder. 32 | /// 33 | /// 34 | void DeletePreset(Preset preset); 35 | 36 | /// 37 | /// Activates a preset. 38 | /// 39 | /// 40 | Task ActivatePresetAsync(string targetDir, Preset preset); 41 | 42 | /// 43 | /// Deactivates a preset. 44 | /// 45 | /// 46 | Task DeactivatePresetAsync(string targetDir, Preset preset); 47 | 48 | /// 49 | /// Creates a preset based on current ENB files. 50 | /// 51 | /// 52 | /// 53 | Preset CreateExistingPreset(string targetDir); 54 | 55 | /// 56 | /// Saves the current preset to folder. 57 | /// 58 | /// 59 | /// 60 | /// 61 | Task SaveCurrentPresetAsync(string targetDir, string sourceDir, Preset preset); 62 | 63 | /// 64 | /// Saves a new preset to folder. 65 | /// 66 | /// 67 | /// 68 | /// 69 | Task SaveNewPresetAsync(string targetDir, Preset preset); 70 | 71 | /// 72 | /// Validates an active preset. 73 | /// 74 | /// 75 | /// 76 | /// 77 | Task ValidatePresetAsync(string targetDir, Preset preset); 78 | 79 | /// 80 | /// Updates the provided preset. 81 | /// 82 | /// 83 | /// 84 | Task UpdatePresetFilesAsync(string targetDir, Preset preset); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /ENBManager.Core.Tests/ViewModels/DiscoverGamesDialogViewModelTests.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Core.Tests.Stubs; 2 | using ENBManager.Core.ViewModels; 3 | using ENBManager.Modules.Fallout4; 4 | using ENBManager.Modules.Shared.Interfaces; 5 | using ENBManager.Modules.Shared.Services; 6 | using ENBManager.Modules.Skyrim; 7 | using ENBManager.Modules.SkyrimSE; 8 | using NUnit.Framework; 9 | using System.Linq; 10 | 11 | namespace ENBManager.Core.Tests.ViewModels 12 | { 13 | [TestFixture] 14 | public class DiscoverGamesDialogViewModelTests 15 | { 16 | private DiscoverGamesDialogViewModel _viewModel; 17 | 18 | [SetUp] 19 | public void Setup() 20 | { 21 | var fileService = new GameServiceStub(); 22 | var gameModuleCatalog = GetGameModuleCatalog(); 23 | _viewModel = new DiscoverGamesDialogViewModel(fileService, gameModuleCatalog); 24 | } 25 | 26 | [Test] 27 | public void ShouldHaveDialogTitle() 28 | { 29 | // Assert 30 | Assert.That(string.IsNullOrEmpty(_viewModel.Title), Is.False); 31 | } 32 | 33 | [Test] 34 | public void ShouldGetData() 35 | { 36 | // Act 37 | _viewModel.GetDataCommand.Execute(); 38 | 39 | // Assert 40 | Assert.That(_viewModel.Games, Has.Count.GreaterThan(0)); 41 | } 42 | 43 | [Test] 44 | public void ShouldInitializeGamesAsManaged() 45 | { 46 | // Act 47 | _viewModel.GetDataCommand.Execute(); 48 | 49 | // Assert 50 | Assert.That(_viewModel.Games.Where(x => x.Installed).All(x => x.ShouldManage)); 51 | } 52 | 53 | [Test] 54 | public void ShouldEnableContinueWhenManagedGamesAreFound() 55 | { 56 | // Arrange 57 | bool expectingFalse = _viewModel.ContinueCommand.CanExecute(); 58 | 59 | // Act 60 | _viewModel.GetDataCommand.Execute(); 61 | _viewModel.Games[0].InstalledLocation = "C:\\Game"; 62 | bool expectingTrue = _viewModel.ContinueCommand.CanExecute(); 63 | foreach (var game in _viewModel.Games) 64 | { 65 | game.ShouldManage = false; 66 | } 67 | bool expectingFalseAgain = _viewModel.ContinueCommand.CanExecute(); 68 | _viewModel.Games.First(x => x.Installed).ShouldManage = true; 69 | bool expectingTrueAgain = _viewModel.ContinueCommand.CanExecute(); 70 | 71 | // Assert 72 | Assert.That(expectingFalse, Is.False); 73 | Assert.That(expectingTrue, Is.True); 74 | Assert.That(expectingFalseAgain, Is.False); 75 | Assert.That(expectingTrueAgain, Is.True); 76 | } 77 | 78 | private IGameModuleCatalog GetGameModuleCatalog() 79 | { 80 | GameModuleCatalog gameModuleCatalog = new GameModuleCatalog(); 81 | 82 | gameModuleCatalog.Register(null); 83 | gameModuleCatalog.Register(null); 84 | gameModuleCatalog.Register(null); 85 | gameModuleCatalog.Register(null); 86 | gameModuleCatalog.Register(null); 87 | 88 | return gameModuleCatalog; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Helpers/DialogHelper.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Localization.Strings; 2 | using NLog; 3 | using System.IO; 4 | using System.Windows.Forms; 5 | using OpenFileDialog = Microsoft.Win32.OpenFileDialog; 6 | 7 | namespace ENBManager.Infrastructure.Helpers 8 | { 9 | /// 10 | /// A static helper class that provides functions related to and . 11 | /// 12 | public static class DialogHelper 13 | { 14 | #region Private Members 15 | 16 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 17 | 18 | #endregion 19 | 20 | public static string OpenDirectory() 21 | { 22 | _logger.Debug("Opening FolderBrowserDialog"); 23 | 24 | FolderBrowserDialog dialog = new FolderBrowserDialog(); 25 | dialog.ShowDialog(); 26 | 27 | return dialog.SelectedPath; 28 | } 29 | 30 | public static string OpenExecutable() 31 | { 32 | _logger.Debug("Opening OpenFileDialog without filename"); 33 | 34 | OpenFileDialog dialog = new OpenFileDialog() 35 | { 36 | Filter = "Exe Files (.exe)|*.exe", 37 | CheckFileExists = true 38 | }; 39 | 40 | bool? cancelled; 41 | do 42 | { 43 | cancelled = !dialog.ShowDialog(); 44 | } 45 | while (!cancelled.Value 46 | && !string.IsNullOrEmpty(dialog.FileName) 47 | && Path.GetExtension(dialog.FileName) != ".exe"); 48 | 49 | if (cancelled.Value) 50 | return null; 51 | 52 | return dialog.FileName; 53 | } 54 | 55 | public static string OpenExecutable(string fileName) 56 | { 57 | _logger.Debug("Opening OpenFileDialog with filename"); 58 | 59 | OpenFileDialog dialog = new OpenFileDialog() 60 | { 61 | Filter = $"{fileName.Split('.')[0]} ({fileName}) | {fileName}", 62 | CheckFileExists = true 63 | }; 64 | 65 | bool? cancelled; 66 | do 67 | { 68 | cancelled = !dialog.ShowDialog(); 69 | } 70 | while (!cancelled.Value 71 | && !string.IsNullOrEmpty(dialog.FileName) 72 | && Path.GetFileName(dialog.FileName.ToLower()) != fileName.ToLower()); 73 | 74 | if (cancelled.Value) 75 | return null; 76 | 77 | return dialog.FileName; 78 | } 79 | 80 | public static void SaveFile(string path, string fileName, string filter) 81 | { 82 | _logger.Debug("Opening SaveFileDialog"); 83 | 84 | SaveFileDialog saveFileDialog = new SaveFileDialog() 85 | { 86 | Title = Strings.EXPORT, 87 | InitialDirectory = @"C:\", 88 | Filter = filter, 89 | FileName = fileName 90 | }; 91 | 92 | if (saveFileDialog.ShowDialog() == DialogResult.OK) 93 | { 94 | fileName = saveFileDialog.FileName; 95 | File.Copy(path, fileName, true); 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /ENBManager.Core/ViewModels/AppSettingsViewModel.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Configuration.Interfaces; 2 | using ENBManager.Core.Helpers; 3 | using ENBManager.Infrastructure.BusinessEntities; 4 | using ENBManager.Infrastructure.Helpers; 5 | using NLog; 6 | using NLog.Targets; 7 | using Prism.Commands; 8 | using Prism.Mvvm; 9 | using Prism.Services.Dialogs; 10 | using System; 11 | using System.Collections.Generic; 12 | using System.IO; 13 | using System.Linq; 14 | 15 | namespace ENBManager.Core.ViewModels 16 | { 17 | public class AppSettingsViewModel : BindableBase, IDialogAware 18 | { 19 | #region Private Members 20 | 21 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 22 | 23 | private readonly IConfigurationManager _configurationManager; 24 | 25 | #endregion 26 | 27 | #region Public Properties 28 | 29 | public AppSettings Settings => _configurationManager.Settings; 30 | 31 | public IEnumerable ColorSchemes => ThemeHelper.GetColorSchemes().Select(x => x.Name); 32 | 33 | #endregion 34 | 35 | #region Commands 36 | 37 | public DelegateCommand SaveCommand { get; } 38 | public DelegateCommand CancelCommand { get; } 39 | public DelegateCommand ExportLogFileCommand { get; set; } 40 | 41 | #endregion 42 | 43 | #region Constructor 44 | 45 | public AppSettingsViewModel(IConfigurationManager configurationManager) 46 | { 47 | _configurationManager = configurationManager; 48 | 49 | SaveCommand = new DelegateCommand(OnSaveCommand); 50 | CancelCommand = new DelegateCommand(() => RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel))); 51 | ExportLogFileCommand = new DelegateCommand(OnExportLogFileCommand); 52 | } 53 | 54 | #endregion 55 | 56 | #region Private Methods 57 | 58 | private void OnSaveCommand() 59 | { 60 | _logger.Info("Saving app settings"); 61 | 62 | ThemeHelper.UpdateTheme(_configurationManager.Settings.DarkMode); 63 | ThemeHelper.UpdateColorScheme(_configurationManager.Settings.ColorScheme); 64 | 65 | _configurationManager.SaveSettings(); 66 | _configurationManager.LoadSettings(); 67 | 68 | RequestClose?.Invoke(new DialogResult(ButtonResult.OK)); 69 | } 70 | 71 | private void OnExportLogFileCommand() 72 | { 73 | _logger.Info("Exporting log file"); 74 | 75 | string logFilePath = (LogManager.Configuration.AllTargets[0] as FileTarget).FileName.Render(new LogEventInfo()); 76 | DialogHelper.SaveFile(logFilePath, Path.GetFileName(logFilePath), "Log files (*.log)|*.log"); 77 | } 78 | 79 | #endregion 80 | 81 | #region IDialogAware Implementation 82 | 83 | public string Title => Localization.Strings.Strings.SETTINGS; 84 | 85 | public event Action RequestClose; 86 | 87 | public bool CanCloseDialog() => true; 88 | 89 | public void OnDialogClosed() 90 | { 91 | _logger.Info("Closed"); 92 | } 93 | 94 | public void OnDialogOpened(IDialogParameters parameters) 95 | { 96 | _logger.Info("Opened"); 97 | } 98 | 99 | #endregion 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /ENBManager.Configuration/Services/ConfigurationManager.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Configuration.Interfaces; 2 | using ENBManager.Configuration.Models; 3 | using Newtonsoft.Json; 4 | using NLog; 5 | using System; 6 | using System.IO; 7 | 8 | namespace ENBManager.Configuration.Services 9 | { 10 | public class ConfigurationManager : IConfigurationManager where T : BaseSettings 11 | { 12 | #region Private Members 13 | 14 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 15 | 16 | #endregion 17 | 18 | #region Constructors 19 | 20 | /// 21 | /// Constructor. Creates a new instance of the provided type. Used to read settings directly. 22 | /// 23 | public ConfigurationManager() 24 | { 25 | Settings = (T)Activator.CreateInstance(typeof(T)); 26 | LoadSettings(); 27 | } 28 | 29 | /// 30 | /// Constructor. Sets the provided settings as the current settings. 31 | /// 32 | /// 33 | public ConfigurationManager(BaseSettings settings) 34 | { 35 | Settings = (T)settings; 36 | } 37 | 38 | #endregion 39 | 40 | #region Public Static Methods 41 | 42 | public static T LoadSettings(string fullPath) 43 | { 44 | _logger.Debug($"Loading settings from {fullPath}"); 45 | 46 | var settings = JsonConvert.DeserializeObject(File.ReadAllText(fullPath)); 47 | 48 | settings.SetFullPath(fullPath); 49 | 50 | return settings; 51 | } 52 | 53 | #endregion 54 | 55 | #region IConfigurationManager Implementation 56 | 57 | public T Settings { get; private set; } 58 | 59 | public void LoadSettings() 60 | { 61 | _logger.Debug($"Loading {Settings.GetType().Name}"); 62 | 63 | // If directory or file does not exist, create it 64 | InitializeSettings(); 65 | 66 | Settings = JsonConvert.DeserializeObject(File.ReadAllText(Settings.GetFullPath())); 67 | } 68 | 69 | public void SaveSettings() 70 | { 71 | _logger.Debug($"Saving {Settings.GetType().Name}"); 72 | 73 | // If directory does not exist, create it 74 | Directory.CreateDirectory(Path.GetDirectoryName(Settings.GetFullPath())); 75 | 76 | // If file exists, unlock it 77 | if (File.Exists(Settings.GetFullPath())) 78 | SetReadOnly(false); 79 | 80 | string json = JsonConvert.SerializeObject(Settings, Formatting.Indented); 81 | File.WriteAllText(Settings.GetFullPath(), json); 82 | 83 | SetReadOnly(true); 84 | } 85 | 86 | public void InitializeSettings() 87 | { 88 | if (!File.Exists(Settings.GetFullPath())) 89 | { 90 | _logger.Debug($"Initializing {Settings.GetType().Name}"); 91 | 92 | SaveSettings(); 93 | } 94 | } 95 | 96 | public void SetReadOnly(bool readOnly) 97 | { 98 | _logger.Debug(nameof(SetReadOnly) + " = " + readOnly); 99 | 100 | File.SetAttributes(Settings.GetFullPath(), readOnly ? FileAttributes.ReadOnly : FileAttributes.Normal); 101 | } 102 | 103 | #endregion 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /ENBManager.Core/Helpers/ThemeHelper.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using MaterialDesignColors; 3 | using MaterialDesignThemes.Wpf; 4 | using NLog; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | 8 | namespace ENBManager.Core.Helpers 9 | { 10 | /// 11 | /// A static helper class that provides functions related to themes and colors. 12 | /// 13 | public static class ThemeHelper 14 | { 15 | #region Private Members 16 | 17 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 18 | 19 | #endregion 20 | 21 | #region Public Methods 22 | 23 | /// 24 | /// Gets the available color schemes. 25 | /// 26 | /// 27 | public static IEnumerable GetColorSchemes() 28 | { 29 | _logger.Debug("Getting color schemes"); 30 | 31 | List colorSchemes = new List(); 32 | 33 | var swatches = new SwatchesProvider().Swatches; 34 | colorSchemes.Add(new ColorScheme("Fallout", "#0079c9", "#e0dd02")); 35 | colorSchemes.Add(new ColorScheme("Flamingo", "#04ae9d", "#fe4a70")); 36 | colorSchemes.Add(new ColorScheme("Volcano", "#852222", "#ffb300")); 37 | colorSchemes.Add(new ColorScheme("Joker", "#7554A3", "#96C93C")); 38 | colorSchemes.Add(new ColorScheme("Nature", "#7a411d", "#7db043")); 39 | 40 | return colorSchemes; 41 | } 42 | 43 | /// 44 | /// Updates the current theme (light/dark). 45 | /// 46 | /// 47 | public static void UpdateTheme(bool darkMode) 48 | { 49 | _logger.Debug("Updating theme"); 50 | 51 | var paletteHelper = new PaletteHelper(); 52 | 53 | IBaseTheme baseTheme; 54 | if (darkMode) 55 | baseTheme = new MaterialDesignDarkTheme(); 56 | else 57 | baseTheme = new MaterialDesignLightTheme(); 58 | 59 | ITheme theme = paletteHelper.GetTheme(); 60 | theme.SetBaseTheme(baseTheme); 61 | 62 | paletteHelper.SetTheme(theme); 63 | } 64 | 65 | /// 66 | /// Updates the current color scheme (primary/secondary). 67 | /// 68 | /// 69 | /// 70 | public static void UpdateColorScheme(string colorSchemeName) 71 | { 72 | _logger.Debug("Updating color scheme"); 73 | 74 | var colorScheme = GetColorScheme(colorSchemeName); 75 | var paletteHelper = new PaletteHelper(); 76 | ITheme theme = paletteHelper.GetTheme(); 77 | theme.SetPrimaryColor(colorScheme.Primary); 78 | theme.SetSecondaryColor(colorScheme.Secondary); 79 | 80 | paletteHelper.SetTheme(theme); 81 | } 82 | 83 | #endregion 84 | 85 | #region Private Methods 86 | 87 | private static ColorScheme GetColorScheme(string colorSchemeName) 88 | { 89 | _logger.Debug("Getting color scheme"); 90 | 91 | var colorSchemes = GetColorSchemes(); 92 | 93 | var selectedColorScheme = colorSchemes.FirstOrDefault(x => x.Name == colorSchemeName); 94 | 95 | return selectedColorScheme ?? colorSchemes.First(); 96 | } 97 | 98 | #endregion 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /ENBManager.Core/ViewModels/GameSettingsViewModel.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Configuration.Interfaces; 2 | using ENBManager.Configuration.Services; 3 | using ENBManager.Infrastructure.BusinessEntities; 4 | using ENBManager.Infrastructure.Helpers; 5 | using NLog; 6 | using Prism.Commands; 7 | using Prism.Mvvm; 8 | using Prism.Services.Dialogs; 9 | using System; 10 | 11 | namespace ENBManager.Core.ViewModels 12 | { 13 | public class GameSettingsViewModel : BindableBase, IDialogAware 14 | { 15 | #region Private Members 16 | 17 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 18 | 19 | private IConfigurationManager _configurationManager; 20 | 21 | #endregion 22 | 23 | #region Public Properties 24 | 25 | public GameSettings Settings => _configurationManager?.Settings; 26 | 27 | #endregion 28 | 29 | #region Helper Properties 30 | 31 | public string VirtualExecutablePath 32 | { 33 | get { return _configurationManager?.Settings.VirtualExecutablePath; } 34 | set 35 | { 36 | _configurationManager.Settings.VirtualExecutablePath = value; 37 | RaisePropertyChanged(); 38 | } 39 | } 40 | 41 | #endregion 42 | 43 | #region Commands 44 | 45 | public DelegateCommand SaveCommand { get; } 46 | public DelegateCommand CancelCommand { get; } 47 | public DelegateCommand BrowseCommand { get; } 48 | 49 | #endregion 50 | 51 | #region Constructor 52 | 53 | public GameSettingsViewModel() 54 | { 55 | SaveCommand = new DelegateCommand(OnSaveCommand); 56 | CancelCommand = new DelegateCommand(() => RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel))); 57 | BrowseCommand = new DelegateCommand(OnBrowseCommand); 58 | } 59 | 60 | #endregion 61 | 62 | #region Private Methods 63 | 64 | private void OnSaveCommand() 65 | { 66 | _logger.Info("Saving app settings"); 67 | 68 | _configurationManager.SaveSettings(); 69 | _configurationManager.LoadSettings(); 70 | 71 | RequestClose?.Invoke(new DialogResult(ButtonResult.OK)); 72 | } 73 | 74 | private void OnBrowseCommand() 75 | { 76 | _logger.Info("Browsing"); 77 | 78 | string fileName = DialogHelper.OpenExecutable(); 79 | 80 | if (string.IsNullOrEmpty(fileName)) 81 | return; 82 | 83 | VirtualExecutablePath = fileName; 84 | } 85 | 86 | #endregion 87 | 88 | #region IDialogAware Implementation 89 | 90 | public string Title { get; set; } 91 | 92 | public event Action RequestClose; 93 | 94 | public bool CanCloseDialog() => true; 95 | 96 | public void OnDialogClosed() 97 | { 98 | _logger.Info("Closed"); 99 | } 100 | 101 | public void OnDialogOpened(IDialogParameters parameters) 102 | { 103 | _logger.Info("Opened"); 104 | 105 | if (parameters.GetValue("Title") != null) 106 | Title = parameters.GetValue("Title"); 107 | 108 | if (parameters.GetValue("GameSettings") != null) 109 | _configurationManager = new ConfigurationManager(parameters.GetValue("GameSettings")); 110 | 111 | RaisePropertyChanged(nameof(Settings)); 112 | } 113 | 114 | #endregion 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Helpers/KeywordsHelper.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using ENBManager.Infrastructure.Constants; 3 | using ENBManager.Infrastructure.Enums; 4 | using ENBManager.Infrastructure.Exceptions; 5 | using Newtonsoft.Json; 6 | using NLog; 7 | using System.Collections.Generic; 8 | using System.IO; 9 | 10 | namespace ENBManager.Infrastructure.Helpers 11 | { 12 | public static class KeywordsHelper 13 | { 14 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 15 | 16 | public static Keywords GetKeywords() 17 | { 18 | _logger.Debug("Getting keywords"); 19 | 20 | if (!File.Exists(Paths.GetKeywordsFilePath())) 21 | { 22 | var keywords = new Keywords(); 23 | keywords.Directories = DefaultKeywords.DIRECTORIES; 24 | keywords.Files = DefaultKeywords.FILES; 25 | 26 | SaveToFile(keywords); 27 | } 28 | 29 | return JsonConvert.DeserializeObject(File.ReadAllText(Paths.GetKeywordsFilePath())); 30 | } 31 | 32 | public static void AddKeyword(KeywordType keywordType, string value) 33 | { 34 | _logger.Debug("Adding keyword"); 35 | 36 | var keywords = GetKeywords(); 37 | 38 | switch (keywordType) 39 | { 40 | case KeywordType.Folder: 41 | if (keywords.Directories.Contains(value)) 42 | throw new IdenticalNameException($"Keyword with name '{value}' already exists"); 43 | keywords.Directories.Add(value); 44 | break; 45 | case KeywordType.File: 46 | if (keywords.Files.Contains(value)) 47 | throw new IdenticalNameException($"Keyword with name '{value}' already exists"); 48 | keywords.Files.Add(value); 49 | break; 50 | } 51 | 52 | SaveToFile(keywords); 53 | } 54 | 55 | public static void RemoveKeyword(KeywordType keywordType, string value) 56 | { 57 | _logger.Debug("Removing keyword"); 58 | 59 | var keywords = GetKeywords(); 60 | 61 | switch (keywordType) 62 | { 63 | case KeywordType.Folder: 64 | keywords.Directories.Remove(value); 65 | break; 66 | case KeywordType.File: 67 | keywords.Files.Remove(value); 68 | break; 69 | } 70 | 71 | SaveToFile(keywords); 72 | } 73 | 74 | public static bool MatchesKeyword(IEnumerable keywords, string name) 75 | { 76 | _logger.Debug("Is keyword matching?"); 77 | 78 | foreach (var keyword in keywords) 79 | { 80 | if (name.ToLower().Contains(keyword.ToLower())) 81 | return true; 82 | } 83 | 84 | return false; 85 | } 86 | 87 | #region Helper Methods 88 | 89 | private static void SaveToFile(Keywords keywords) 90 | { 91 | _logger.Debug("Saving keywords to file"); 92 | 93 | if (!Directory.Exists(Path.GetDirectoryName(Paths.GetKeywordsFilePath()))) 94 | Directory.CreateDirectory(Path.GetDirectoryName(Paths.GetKeywordsFilePath())); 95 | 96 | File.WriteAllText(Paths.GetKeywordsFilePath(), JsonConvert.SerializeObject(keywords, Formatting.Indented)); 97 | } 98 | 99 | #endregion 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/NotifyIconView.xaml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 36 | 38 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 55 | 56 | 57 | 58 | 59 | 60 | 62 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /ENBManager.Configuration/ENBManager.Configuration.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B0B03203-0C05-4CC8-B133-24E11EAD6D57} 8 | Library 9 | Properties 10 | ENBManager.Configuration 11 | ENBManager.Configuration 12 | v4.6.1 13 | 512 14 | false 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | bin\x64\Debug\ 36 | DEBUG;TRACE 37 | full 38 | x64 39 | 7.3 40 | prompt 41 | MinimumRecommendedRules.ruleset 42 | 43 | 44 | bin\x64\Release\ 45 | TRACE 46 | true 47 | pdbonly 48 | x64 49 | 7.3 50 | prompt 51 | MinimumRecommendedRules.ruleset 52 | 53 | 54 | 55 | ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll 56 | 57 | 58 | ..\packages\NLog.4.7.2\lib\net45\NLog.dll 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Properties\SharedAssemblyInfo.cs 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Helpers/TreeViewHelper.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.BusinessEntities; 2 | using ENBManager.Infrastructure.BusinessEntities.Base; 3 | using NLog; 4 | using System.Collections.Generic; 5 | using System.Collections.ObjectModel; 6 | using System.ComponentModel; 7 | using System.IO; 8 | using System.Linq; 9 | 10 | namespace ENBManager.Infrastructure.Helpers 11 | { 12 | /// 13 | /// A static helper class that provides functions related to treeviews. 14 | /// 15 | public static class TreeViewHelper 16 | { 17 | #region Private Members 18 | 19 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 20 | 21 | #endregion 22 | 23 | #region Public Methods 24 | 25 | public static List GetNodes(string root, PropertyChangedEventHandler eventHandler) 26 | { 27 | _logger.Debug("Getting nodes with event handler"); 28 | 29 | var items = new List(); 30 | 31 | var dirInfo = new DirectoryInfo(root); 32 | 33 | foreach (var directory in dirInfo.GetDirectories()) 34 | { 35 | var item = new DirectoryNode 36 | { 37 | Name = directory.Name, 38 | Path = directory.FullName, 39 | Items = new ObservableCollection(GetNodes(directory.FullName, eventHandler)) 40 | }; 41 | 42 | item.PropertyChanged += eventHandler; 43 | 44 | items.Add(item); 45 | } 46 | 47 | foreach (var file in dirInfo.GetFiles()) 48 | { 49 | var item = new FileNode 50 | { 51 | Name = file.Name, 52 | Path = file.FullName 53 | }; 54 | 55 | item.PropertyChanged += eventHandler; 56 | 57 | items.Add(item); 58 | } 59 | 60 | return items; 61 | } 62 | 63 | public static List GetNodes(string root) 64 | { 65 | _logger.Debug("Getting nodes"); 66 | 67 | var items = new List(); 68 | 69 | var dirInfo = new DirectoryInfo(root); 70 | 71 | foreach (var directory in dirInfo.GetDirectories()) 72 | { 73 | var item = new DirectoryNode 74 | { 75 | Name = directory.Name, 76 | Path = directory.FullName, 77 | Items = new ObservableCollection(GetNodes(directory.FullName)) 78 | }; 79 | 80 | items.Add(item); 81 | } 82 | 83 | foreach (var file in dirInfo.GetFiles()) 84 | { 85 | var item = new FileNode 86 | { 87 | Name = file.Name, 88 | Path = file.FullName 89 | }; 90 | 91 | items.Add(item); 92 | } 93 | 94 | return items; 95 | } 96 | 97 | public static ICollection GetPaths(DirectoryNode directory) 98 | { 99 | _logger.Debug("Getting paths"); 100 | 101 | List paths = new List(); 102 | 103 | // Add empty directory 104 | if (directory.Items.Count == 0) 105 | paths.Add(directory.Path); 106 | 107 | foreach (var item in directory.Items.Where(x => x.GetType() == typeof(DirectoryNode))) 108 | { 109 | paths.AddRange(GetPaths(item as DirectoryNode)); 110 | } 111 | 112 | foreach (var file in directory.Items.Where(x => x.GetType() == typeof(FileNode))) 113 | { 114 | paths.Add(file.Path); 115 | } 116 | 117 | return paths; 118 | } 119 | 120 | public static void DeleteNode(ICollection nodes, Node nodeToDelete) 121 | { 122 | _logger.Debug($"Deleting node {nodeToDelete.Name}"); 123 | 124 | if (!nodes.Remove(nodeToDelete)) 125 | { 126 | foreach (var node in nodes.Where(x => x.GetType() == typeof(DirectoryNode))) 127 | { 128 | DeleteNode((node as DirectoryNode).Items, nodeToDelete); 129 | } 130 | } 131 | } 132 | 133 | #endregion 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /ENBManager.Logging/ENBManager.Logging.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {9CBEBCA6-2D8C-499C-9D37-7A2F79A7D142} 8 | Library 9 | Properties 10 | ENBManager.Logging 11 | ENBManager.Logging 12 | v4.6.1 13 | 512 14 | false 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | bin\x64\Debug\ 36 | DEBUG;TRACE 37 | full 38 | x64 39 | 7.3 40 | prompt 41 | MinimumRecommendedRules.ruleset 42 | 43 | 44 | bin\x64\Release\ 45 | TRACE 46 | true 47 | pdbonly 48 | x64 49 | 7.3 50 | prompt 51 | MinimumRecommendedRules.ruleset 52 | 53 | 54 | 55 | ..\packages\NLog.4.7.2\lib\net45\NLog.dll 56 | 57 | 58 | ..\packages\Prism.Core.7.2.0.1422\lib\net45\Prism.dll 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Properties\SharedAssemblyInfo.cs 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | Always 88 | 89 | 90 | Designer 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /ENBManager.Core/ViewModels/ShellViewModel.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Configuration.Interfaces; 2 | using ENBManager.Core.Views; 3 | using ENBManager.Infrastructure.BusinessEntities; 4 | using ENBManager.Infrastructure.Constants; 5 | using ENBManager.Modules.Shared.Events; 6 | using ENBManager.Modules.Shared.Views; 7 | using NLog; 8 | using Prism.Commands; 9 | using Prism.Events; 10 | using Prism.Mvvm; 11 | using Prism.Regions; 12 | using Prism.Services.Dialogs; 13 | using System; 14 | using System.Reflection; 15 | 16 | namespace ENBManager.Core.ViewModels 17 | { 18 | public class ShellViewModel : BindableBase 19 | { 20 | #region Private Members 21 | 22 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 23 | 24 | private readonly IConfigurationManager _configurationManager; 25 | private readonly IDialogService _dialogService; 26 | private readonly IEventAggregator _eventAggregator; 27 | private readonly IRegionManager _regionManager; 28 | 29 | private bool _showNotifyIcon; 30 | private bool _enableScreenshots; 31 | 32 | #endregion 33 | 34 | #region Public Properties 35 | 36 | public string Version => Assembly.GetExecutingAssembly().GetName().Version.ToString(); 37 | 38 | public bool ShowNotifyIcon 39 | { 40 | get { return _showNotifyIcon; } 41 | set 42 | { 43 | _showNotifyIcon = value; 44 | RaisePropertyChanged(); 45 | } 46 | } 47 | 48 | public bool MinimizeToTray => _configurationManager.Settings.MinimizeToTray; 49 | 50 | public bool EnableScreenshots 51 | { 52 | get { return _enableScreenshots; } 53 | set 54 | { 55 | _enableScreenshots = value; 56 | 57 | _eventAggregator.GetEvent().Publish(value); 58 | } 59 | } 60 | 61 | #endregion 62 | 63 | #region Commands 64 | 65 | public DelegateCommand RestoreApplicationCommand { get; set; } 66 | public DelegateCommand ExitApplicationCommand { get; set; } 67 | public DelegateCommand OpenSettingsCommand { get; set; } 68 | 69 | #endregion 70 | 71 | #region Constructor 72 | 73 | public ShellViewModel( 74 | IConfigurationManager configurationManager, 75 | IDialogService dialogService, 76 | IEventAggregator eventAggregator, 77 | IRegionManager regionManager) 78 | { 79 | _configurationManager = configurationManager; 80 | _dialogService = dialogService; 81 | _eventAggregator = eventAggregator; 82 | _regionManager = regionManager; 83 | 84 | eventAggregator.GetEvent().Subscribe(OnScreenshotStatusChanged); 85 | 86 | RestoreApplicationCommand = new DelegateCommand(OnRestoreApplicationCommand); 87 | ExitApplicationCommand = new DelegateCommand(OnExitApplicationCommand); 88 | OpenSettingsCommand = new DelegateCommand(OnOpenSettingsCommand); 89 | 90 | InitializeViews(); 91 | } 92 | 93 | #endregion 94 | 95 | #region Events 96 | 97 | public event EventHandler ExitApplicationEventHandler; 98 | public event EventHandler RestoreApplicationEventHandler; 99 | 100 | #endregion 101 | 102 | #region Private Methods 103 | 104 | private void OnRestoreApplicationCommand() 105 | { 106 | _logger.Debug("Restoring application"); 107 | 108 | RestoreApplicationEventHandler.Invoke(null, null); 109 | } 110 | 111 | private void OnExitApplicationCommand() 112 | { 113 | _logger.Debug("Existing application"); 114 | 115 | ExitApplicationEventHandler.Invoke(null, null); 116 | } 117 | 118 | private void OnOpenSettingsCommand() 119 | { 120 | _logger.Debug("Opening settings dialog"); 121 | 122 | _dialogService.ShowDialog(nameof(AppSettingsDialog), new DialogParameters(), null); 123 | } 124 | 125 | private void OnScreenshotStatusChanged(bool enabled) 126 | { 127 | _logger.Debug($"Screenshot enabled: {enabled}"); 128 | 129 | _enableScreenshots = enabled; 130 | RaisePropertyChanged(nameof(EnableScreenshots)); 131 | } 132 | 133 | private void InitializeViews() 134 | { 135 | _logger.Debug("Initializing views"); 136 | 137 | _regionManager.RegisterViewWithRegion(RegionNames.SideMenuRegion, typeof(SideMenuView)); 138 | _regionManager.RegisterViewWithRegion(RegionNames.MainRegion, typeof(MainView)); 139 | _regionManager.RegisterViewWithRegion(RegionNames.MainRegion, typeof(ModuleShell)); 140 | } 141 | 142 | #endregion 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /ENBManager.Modules/Shared/Models/GameModule.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.Constants; 2 | using ENBManager.Modules.Shared.Events; 3 | using ENBManager.Modules.Shared.Interfaces; 4 | using ENBManager.Modules.Shared.Models; 5 | using ENBManager.Modules.Shared.Views; 6 | using Prism.Events; 7 | using Prism.Ioc; 8 | using Prism.Regions; 9 | using System; 10 | using System.Linq; 11 | using System.ComponentModel; 12 | using System.Runtime.CompilerServices; 13 | using System.Windows.Media.Imaging; 14 | using System.Collections.ObjectModel; 15 | using NLog; 16 | using System.IO; 17 | 18 | namespace ENBManager.Infrastructure.BusinessEntities 19 | { 20 | public abstract class GameModule : INotifyPropertyChanged 21 | { 22 | #region Private Members 23 | 24 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 25 | 26 | private readonly IContainerProvider _container; 27 | 28 | private string _installedLocation; 29 | private bool _shouldManage = true; 30 | private GameSettings _settings; 31 | 32 | #endregion 33 | 34 | #region Public Properties 35 | 36 | public string InstalledLocation 37 | { 38 | get { return _installedLocation; } 39 | set 40 | { 41 | _installedLocation = value; 42 | OnPropertyChanged(); 43 | OnPropertyChanged(nameof(Installed)); 44 | } 45 | } 46 | public bool Installed => !string.IsNullOrEmpty(InstalledLocation); 47 | public bool ShouldManage 48 | { 49 | get { return _shouldManage && Installed; } 50 | set 51 | { 52 | _shouldManage = value; 53 | OnPropertyChanged(); 54 | } 55 | } 56 | public ObservableCollection Presets { get; set; } 57 | 58 | public GameSettings Settings 59 | { 60 | get { return _settings; } 61 | set 62 | { 63 | _settings = value; 64 | 65 | InstalledLocation = value.InstalledLocation; 66 | } 67 | } 68 | 69 | #endregion 70 | 71 | #region Public Abstract Properties 72 | 73 | public abstract string Title { get; } 74 | public abstract BitmapImage Icon { get; } 75 | public abstract string Executable { get; } 76 | public abstract string Module { get; } 77 | public abstract string[] Binaries { get; } 78 | public abstract string Url { get; } 79 | 80 | #endregion 81 | 82 | #region Constructor 83 | 84 | public GameModule(IContainerProvider container) 85 | { 86 | _container = container; 87 | } 88 | 89 | #endregion 90 | 91 | #region Protected Methods 92 | 93 | protected void ActivateModule(params Type[] types) 94 | { 95 | _logger.Debug($"Activating module '{this.GetType().Name}'"); 96 | 97 | var eventAggregator = _container.Resolve(); 98 | 99 | // Get presets and active preset 100 | var presetManager = _container.Resolve(); 101 | Presets = new ObservableCollection(presetManager.GetPresets(Paths.GetPresetsDirectory(Module))); 102 | if (Presets != null && Presets.Count() > 0) 103 | { 104 | var activePreset = Presets.FirstOrDefault(x => x.Name == Settings.ActivePreset); 105 | 106 | if (activePreset != null) 107 | activePreset.IsActive = true; 108 | } 109 | 110 | // Register views 111 | var regionManager = _container.Resolve(); 112 | regionManager.RequestNavigate(RegionNames.MainRegion, nameof(ModuleShell)); 113 | regionManager.Regions[RegionNames.TabRegion].RemoveAll(); 114 | foreach (var type in types) 115 | { 116 | // If installed location does not exist, skip all views except Dashboard 117 | if (!Directory.Exists(InstalledLocation) & type != typeof(DashboardView)) 118 | continue; 119 | 120 | regionManager.RegisterViewWithRegion(RegionNames.TabRegion, type); 121 | } 122 | 123 | // Start with dashboard view 124 | regionManager.RequestNavigate(RegionNames.TabRegion, types.First().FullName); 125 | 126 | // Publish events 127 | eventAggregator.GetEvent().Publish(this); 128 | } 129 | 130 | #endregion 131 | 132 | #region Public Abstract Methods 133 | 134 | public abstract void Activate(); 135 | 136 | #endregion 137 | 138 | #region INotifyPropertyChanged Implementation 139 | 140 | public event PropertyChangedEventHandler PropertyChanged; 141 | 142 | public void OnPropertyChanged([CallerMemberName] string name = null) 143 | { 144 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 145 | } 146 | 147 | #endregion 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /ENBManager.Infrastructure/Services/GameService.cs: -------------------------------------------------------------------------------- 1 | using ENBManager.Infrastructure.Constants; 2 | using ENBManager.Infrastructure.Enums; 3 | using ENBManager.Infrastructure.Interfaces; 4 | using NLog; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Diagnostics; 8 | using System.IO; 9 | 10 | namespace ENBManager.Infrastructure.Services 11 | { 12 | public class GameService : IGameService 13 | { 14 | #region Private Members 15 | 16 | private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); 17 | 18 | #endregion 19 | 20 | #region IGameService Implementation 21 | 22 | public void DeleteGameDirectory(string module) 23 | { 24 | _logger.Debug($"Deleting directory '{module}'"); 25 | 26 | Directory.Delete(Path.Combine(Paths.GetGamesDirectory(), module), true); 27 | } 28 | 29 | public string[] GetGameDirectories() 30 | { 31 | _logger.Debug("Getting game directories"); 32 | 33 | return Directory.GetDirectories(Paths.GetGamesDirectory()); 34 | } 35 | 36 | public bool VerifyBinaries(string directoryPath, string[] binaries, out string[] missingBinaries) 37 | { 38 | _logger.Debug("Verifying binaries and returns missing files"); 39 | 40 | List missingFiles = new List(); 41 | 42 | foreach (var binary in binaries) 43 | { 44 | if (!File.Exists(Path.Combine(directoryPath, binary))) 45 | { 46 | missingFiles.Add(binary); 47 | } 48 | } 49 | 50 | missingBinaries = missingFiles.ToArray(); 51 | 52 | return missingBinaries.Length == 0; 53 | } 54 | 55 | public bool VerifyBinaries(string directoryPath, string[] binaries) 56 | { 57 | _logger.Debug("Verifying binaries"); 58 | 59 | foreach (var binary in binaries) 60 | { 61 | if (!File.Exists(Path.Combine(directoryPath, binary))) 62 | { 63 | return false; 64 | } 65 | } 66 | 67 | return true; 68 | } 69 | 70 | public void CopyBinaries(string source, string target, string[] binaries) 71 | { 72 | _logger.Debug($"Copying binaries from {source} to {target}"); 73 | 74 | foreach (var binary in binaries) 75 | { 76 | if (!Directory.Exists(target)) 77 | Directory.CreateDirectory(target); 78 | 79 | File.Copy(Path.Combine(source, binary), Path.Combine(target, binary), true); 80 | } 81 | } 82 | 83 | public void DeleteBinaries(string target, string[] binaries) 84 | { 85 | _logger.Debug("Deleting binaries"); 86 | 87 | foreach (var binary in binaries) 88 | { 89 | if (File.Exists(Path.Combine(target, binary))) 90 | File.Delete(Path.Combine(target, binary)); 91 | } 92 | } 93 | 94 | public VersionMismatch VerifyBinariesVersion(string source, string target, string[] binaries) 95 | { 96 | _logger.Debug("Verifying binaries version"); 97 | 98 | foreach (var binary in binaries) 99 | { 100 | string sourcePath = Path.Combine(source, binary); 101 | string targetPath = Path.Combine(target, binary); 102 | 103 | if (File.Exists(sourcePath) && File.Exists(targetPath)) 104 | { 105 | var v1 = FileVersionInfo.GetVersionInfo(sourcePath).ProductVersion.Replace(',', '.'); 106 | var sourceVersion = new Version(v1); 107 | var v2 = FileVersionInfo.GetVersionInfo(targetPath).ProductVersion.Replace(',', '.'); 108 | var targetVersion = new Version(v2); 109 | 110 | var result = sourceVersion.CompareTo(targetVersion); 111 | 112 | switch (result) 113 | { 114 | case 0: 115 | _logger.Debug(VersionMismatch.Matching.ToString()); 116 | return VersionMismatch.Matching; 117 | case 1: 118 | _logger.Debug(VersionMismatch.Above.ToString()); 119 | return VersionMismatch.Above; 120 | case -1: 121 | _logger.Debug(VersionMismatch.Below.ToString()); 122 | return VersionMismatch.Below; 123 | } 124 | } 125 | } 126 | 127 | return VersionMismatch.Matching; 128 | } 129 | 130 | public string[] AppendBinaryVersions(string target, string[] binaries) 131 | { 132 | _logger.Debug("Getting binaries version"); 133 | 134 | for (int i = 0; i < binaries.Length; i++) 135 | { 136 | string info = FileVersionInfo.GetVersionInfo(Path.Combine(target, binaries[i])).ProductVersion.Replace(',', '.'); 137 | 138 | binaries[i] += " (" + info + ")"; 139 | } 140 | 141 | return binaries; 142 | } 143 | 144 | #endregion 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/GameSettingsDialog.xaml: -------------------------------------------------------------------------------- 1 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 56 | 57 | 58 | 29 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 60 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 80 | 91 | 92 | 93 | 94 | 95 | 96 | 98 | 101 | 102 | 103 | 104 | 105 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 117 | 119 | 122 | 125 | 126 | 127 | 128 | 129 | 130 | 133 | 136 | 137 | 138 | 139 | 140 | 141 | 144 | 145 | 146 | 148 | 149 | 150 | 151 | 152 | 155 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /ENBManager.Core/Views/AboutDialog.xaml: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 34 |