public static bool Handle(string[] args)
        {
            var logFilename = args.FirstOrDefault(x => x.StartsWith(@"--log="))?.Substring(6);
            var outFilename = args.FirstOrDefault(x => x.StartsWith(@"--out="))?.Substring(6);

            if (logFilename != null)
            {
                Logging.Initialize(logFilename, false);
            }
            if (SteamStarter.Initialize(MainExecutingFile.Directory, true))
            {
                var data = args.Contains(@"--stats")
                        ? JsonConvert.SerializeObject(SteamStarter.GetAchievementStats(), Formatting.Indented)
                        : JsonConvert.SerializeObject(SteamStarter.GetAchievements(), Formatting.Indented);
                if (outFilename != null)
                {
                    File.WriteAllText(outFilename, data);
                }
                else
                {
                    MessageBox.Show(data);
                }
            }
            return(true);
        }
Example #2
0
        private App()
        {
            if (AppArguments.GetBool(AppFlag.IgnoreHttps))
            {
                ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
            }

            AppArguments.Set(AppFlag.SyncNavigation, ref ModernFrame.OptionUseSyncNavigation);
            AppArguments.Set(AppFlag.DisableTransitionAnimation, ref ModernFrame.OptionDisableTransitionAnimation);
            AppArguments.Set(AppFlag.RecentlyClosedQueueSize, ref LinkGroupFilterable.OptionRecentlyClosedQueueSize);

            AppArguments.Set(AppFlag.NoProxy, ref KunosApiProvider.OptionNoProxy);

            var proxy = AppArguments.Get(AppFlag.Proxy);

            if (!string.IsNullOrWhiteSpace(proxy))
            {
                try {
                    var s = proxy.Split(':');
                    WebRequest.DefaultWebProxy = new WebProxy(s[0], FlexibleParser.ParseInt(s.ArrayElementAtOrDefault(1), 1080));
                } catch (Exception e) {
                    Logging.Error(e);
                }
            }

            // TODO: AppArguments.Set(AppFlag.ScanPingTimeout, ref RecentManagerOld.OptionScanPingTimeout);
            AppArguments.Set(AppFlag.LanSocketTimeout, ref KunosApiProvider.OptionLanSocketTimeout);
            AppArguments.Set(AppFlag.LanPollTimeout, ref KunosApiProvider.OptionLanPollTimeout);
            AppArguments.Set(AppFlag.WebRequestTimeout, ref KunosApiProvider.OptionWebRequestTimeout);
            AppArguments.Set(AppFlag.DirectRequestTimeout, ref KunosApiProvider.OptionDirectRequestTimeout);
            AppArguments.Set(AppFlag.CommandTimeout, ref GameCommandExecutorBase.OptionCommandTimeout);

            AppArguments.Set(AppFlag.DisableAcRootChecking, ref AcPaths.OptionEaseAcRootCheck);
            AppArguments.Set(AppFlag.AcObjectsLoadingConcurrency, ref BaseAcManagerNew.OptionAcObjectsLoadingConcurrency);
            AppArguments.Set(AppFlag.SkinsLoadingConcurrency, ref CarObject.OptionSkinsLoadingConcurrency);
            AppArguments.Set(AppFlag.KunosCareerIgnoreSkippedEvents, ref KunosCareerEventsManager.OptionIgnoreSkippedEvents);
            AppArguments.Set(AppFlag.IgnoreMissingSkinsInKunosEvents, ref KunosEventObjectBase.OptionIgnoreMissingSkins);

            AppArguments.Set(AppFlag.CanPack, ref AcCommonObject.OptionCanBePackedFilter);
            AppArguments.Set(AppFlag.CanPackCars, ref CarObject.OptionCanBePackedFilter);

            AppArguments.Set(AppFlag.ForceToastFallbackMode, ref Toast.OptionFallbackMode);

            AppArguments.Set(AppFlag.SmartPresetsChangedHandling, ref UserPresetsControl.OptionSmartChangedHandling);
            AppArguments.Set(AppFlag.EnableRaceIniRestoration, ref Game.OptionEnableRaceIniRestoration);
            AppArguments.Set(AppFlag.EnableRaceIniTestMode, ref Game.OptionRaceIniTestMode);
            AppArguments.Set(AppFlag.RaceOutDebug, ref Game.OptionDebugMode);

            AppArguments.Set(AppFlag.NfsPorscheTribute, ref RaceGridViewModel.OptionNfsPorscheNames);
            AppArguments.Set(AppFlag.KeepIniComments, ref IniFile.OptionKeepComments);
            AppArguments.Set(AppFlag.AutoConnectPeriod, ref OnlineServer.OptionAutoConnectPeriod);
            AppArguments.Set(AppFlag.GenericModsLogging, ref GenericModsEnabler.OptionLoggingEnabled);
            AppArguments.Set(AppFlag.SidekickOptimalRangeThreshold, ref SidekickHelper.OptionRangeThreshold);
            AppArguments.Set(AppFlag.GoogleDriveLoaderDebugMode, ref GoogleDriveLoader.OptionDebugMode);
            AppArguments.Set(AppFlag.GoogleDriveLoaderManualRedirect, ref GoogleDriveLoader.OptionManualRedirect);
            AppArguments.Set(AppFlag.DebugPing, ref ServerEntry.OptionDebugPing);
            AppArguments.Set(AppFlag.DebugContentId, ref AcObjectNew.OptionDebugLoading);
            AppArguments.Set(AppFlag.JpegQuality, ref ImageUtilsOptions.JpegQuality);
            AppArguments.Set(AppFlag.FbxMultiMaterial, ref Kn5.OptionJoinToMultiMaterial);

            Acd.Factory       = new AcdFactory();
            Lazier.SyncAction = ActionExtension.InvokeInMainThreadAsync;
            KeyboardListenerFactory.Register <KeyboardListener>();

            LimitedSpace.Initialize();
            DataProvider.Initialize();
            SteamIdHelper.Initialize(AppArguments.Get(AppFlag.ForceSteamId));
            TestKey();

            AppDomain.CurrentDomain.ProcessExit += OnProcessExit;

            if (!AppArguments.GetBool(AppFlag.PreventDisableWebBrowserEmulationMode) && (
                    ValuesStorage.Get <int>(WebBrowserEmulationModeDisabledKey) < WebBrowserHelper.EmulationModeDisablingVersion ||
                    AppArguments.GetBool(AppFlag.ForceDisableWebBrowserEmulationMode)))
            {
                try {
                    WebBrowserHelper.DisableBrowserEmulationMode();
                    ValuesStorage.Set(WebBrowserEmulationModeDisabledKey, WebBrowserHelper.EmulationModeDisablingVersion);
                } catch (Exception e) {
                    Logging.Warning("Can’t disable emulation mode: " + e);
                }
            }

            JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
                Formatting           = Formatting.None,
                NullValueHandling    = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Include,
                Culture = CultureInfo.InvariantCulture
            };

            AcToolsLogging.Logger = (s, m, p, l) => Logging.Write($"{s} (AcTools)", m, p, l);
            AcToolsLogging.NonFatalErrorHandler = (s, c, e, b) => {
                if (b)
                {
                    NonfatalError.NotifyBackground(s, c, e);
                }
                else
                {
                    NonfatalError.Notify(s, c, e);
                }
            };

            AppArguments.Set(AppFlag.ControlsDebugMode, ref ControlsSettings.OptionDebugControlles);
            AppArguments.Set(AppFlag.ControlsRescanPeriod, ref DirectInputScanner.OptionMinRescanPeriod);
            var ignoreControls = AppArguments.Get(AppFlag.IgnoreControls);

            if (!string.IsNullOrWhiteSpace(ignoreControls))
            {
                ControlsSettings.OptionIgnoreControlsFilter = Filter.Create(new StringTester(), ignoreControls);
            }

            var sseStart = AppArguments.Get(AppFlag.SseName);

            if (!string.IsNullOrWhiteSpace(sseStart))
            {
                SseStarter.OptionStartName = sseStart;
            }
            AppArguments.Set(AppFlag.SseLogging, ref SseStarter.OptionLogging);

            FancyBackgroundManager.Initialize();
            if (AppArguments.Has(AppFlag.UiScale))
            {
                AppearanceManager.Instance.AppScale = AppArguments.GetDouble(AppFlag.UiScale, 1d);
            }
            if (AppArguments.Has(AppFlag.WindowsLocationManagement))
            {
                AppearanceManager.Instance.ManageWindowsLocation = AppArguments.GetBool(AppFlag.WindowsLocationManagement, true);
            }

            if (!InternalUtils.IsAllRight)
            {
                AppAppearanceManager.OptionCustomThemes = false;
            }
            else
            {
                AppArguments.Set(AppFlag.CustomThemes, ref AppAppearanceManager.OptionCustomThemes);
            }

            AppArguments.Set(AppFlag.FancyHintsDebugMode, ref FancyHint.OptionDebugMode);
            AppArguments.Set(AppFlag.FancyHintsMinimumDelay, ref FancyHint.OptionMinimumDelay);
            AppArguments.Set(AppFlag.WindowsVerbose, ref DpiAwareWindow.OptionVerboseMode);
            AppArguments.Set(AppFlag.ShowroomUiVerbose, ref LiteShowroomFormWrapperWithTools.OptionAttachedToolsVerboseMode);
            AppArguments.Set(AppFlag.BenchmarkReplays, ref GameDialog.OptionBenchmarkReplays);

            // Shared memory, now as an app flag
            SettingsHolder.Drive.WatchForSharedMemory = !AppArguments.GetBool(AppFlag.DisableSharedMemory);

            /*AppAppearanceManager.OptionIdealFormattingModeDefaultValue = AppArguments.GetBool(AppFlag.IdealFormattingMode,
             *      !Equals(DpiAwareWindow.OptionScale, 1d));*/
            NonfatalErrorSolution.IconsDictionary = new Uri("/AcManager.Controls;component/Assets/IconData.xaml", UriKind.Relative);
            AppearanceManager.DefaultValuesSource = new Uri("/AcManager.Controls;component/Assets/ModernUI.Default.xaml", UriKind.Relative);
            AppAppearanceManager.Initialize(Pages.Windows.MainWindow.GetTitleLinksEntries());
            VisualExtension.RegisterInput <WebBlock>();

            ContentUtils.Register("AppStrings", AppStrings.ResourceManager);
            ContentUtils.Register("ControlsStrings", ControlsStrings.ResourceManager);
            ContentUtils.Register("ToolsStrings", ToolsStrings.ResourceManager);
            ContentUtils.Register("UiStrings", UiStrings.ResourceManager);

            AcObjectsUriManager.Register(new UriProvider());

            {
                var uiFactory = new GameWrapperUiFactory();
                GameWrapper.RegisterFactory(uiFactory);
                ServerEntry.RegisterFactory(uiFactory);
            }

            GameWrapper.RegisterFactory(new DefaultAssistsFactory());
            LapTimesManager.Instance.SetListener();
            RaceResultsStorage.Instance.SetListener();

            AcError.RegisterFixer(new AcErrorFixer());
            AcError.RegisterSolutionsFactory(new SolutionsFactory());

            InitializePresets();

            SharingHelper.Initialize();
            SharingUiHelper.Initialize(AppArguments.GetBool(AppFlag.ModernSharing) ? new Win10SharingUiHelper() : null);

            {
                var addonsDir  = FilesStorage.Instance.GetFilename("Addons");
                var pluginsDir = FilesStorage.Instance.GetFilename("Plugins");
                if (Directory.Exists(addonsDir) && !Directory.Exists(pluginsDir))
                {
                    Directory.Move(addonsDir, pluginsDir);
                }
                else
                {
                    pluginsDir = FilesStorage.Instance.GetDirectory("Plugins");
                }

                PluginsManager.Initialize(pluginsDir);
                PluginsWrappers.Initialize(
                    new AssemblyResolvingWrapper(KnownPlugins.Fmod, FmodResolverService.Resolver),
                    new AssemblyResolvingWrapper(KnownPlugins.Fann, FannResolverService.Resolver),
                    new AssemblyResolvingWrapper(KnownPlugins.Magick, ImageUtils.MagickResolver),
                    new AssemblyResolvingWrapper(KnownPlugins.CefSharp, CefSharpResolverService.Resolver));
            }

            {
                var onlineMainListFile   = FilesStorage.Instance.GetFilename("Online Servers", "Main List.txt");
                var onlineFavouritesFile = FilesStorage.Instance.GetFilename("Online Servers", "Favourites.txt");
                if (File.Exists(onlineMainListFile) && !File.Exists(onlineFavouritesFile))
                {
                    Directory.Move(onlineMainListFile, onlineFavouritesFile);
                }
            }

            CupClient.Initialize();
            Superintendent.Initialize();
            ModsWebBrowser.Initialize();

            AppArguments.Set(AppFlag.OfflineMode, ref AppKeyDialog.OptionOfflineMode);

            WebBlock.DefaultDownloadListener  = new WebDownloadListener();
            FlexibleLoader.CmRequestHandler   = new CmRequestHandler();
            ContextMenus.ContextMenusProvider = new ContextMenusProvider();
            PrepareUi();

            AppShortcut.Initialize("Content Manager", "Content Manager");

            // If shortcut exists, make sure it has a proper app ID set for notifications
            if (File.Exists(AppShortcut.ShortcutLocation))
            {
                AppShortcut.CreateShortcut();
            }

            AppIconService.Initialize(new AppIconProvider());

            Toast.SetDefaultAction(() => (Current.Windows.OfType <ModernWindow>().FirstOrDefault(x => x.IsActive) ??
                                          Current.MainWindow as ModernWindow)?.BringToFront());
            BbCodeBlock.ImageClicked             += OnBbImageClick;
            BbCodeBlock.OptionEmojiProvider       = new EmojiProvider();
            BbCodeBlock.OptionImageCacheDirectory = FilesStorage.Instance.GetTemporaryFilename("Images");
            BbCodeBlock.OptionEmojiCacheDirectory = FilesStorage.Instance.GetTemporaryFilename("Emoji");

            BbCodeBlock.AddLinkCommand(new Uri("cmd://findMissing/car"),
                                       new DelegateCommand <string>(
                                           id => {
                WindowsHelper.ViewInBrowser(SettingsHolder.Content.MissingContentSearch.GetUri(id, SettingsHolder.MissingContentType.Car));
            }));

            BbCodeBlock.AddLinkCommand(new Uri("cmd://findMissing/track"),
                                       new DelegateCommand <string>(
                                           id => {
                WindowsHelper.ViewInBrowser(SettingsHolder.Content.MissingContentSearch.GetUri(id, SettingsHolder.MissingContentType.Track));
            }));

            BbCodeBlock.AddLinkCommand(new Uri("cmd://downloadMissing/car"), new DelegateCommand <string>(id => {
                var s = id.Split('|');
                IndexDirectDownloader.DownloadCarAsync(s[0], s.ArrayElementAtOrDefault(1)).Forget();
            }));

            BbCodeBlock.AddLinkCommand(new Uri("cmd://downloadMissing/track"), new DelegateCommand <string>(id => {
                var s = id.Split('|');
                IndexDirectDownloader.DownloadTrackAsync(s[0], s.ArrayElementAtOrDefault(1)).Forget();
            }));

            BbCodeBlock.AddLinkCommand(new Uri("cmd://createNeutralLut"),
                                       new DelegateCommand <string>(id => NeutralColorGradingLut.CreateNeutralLut(id.As(16))));

            BbCodeBlock.DefaultLinkNavigator.PreviewNavigate += (sender, args) => {
                if (args.Uri.IsAbsoluteUri && args.Uri.Scheme == "acmanager")
                {
                    ArgumentsHandler.ProcessArguments(new[] { args.Uri.ToString() }, true).Forget();
                    args.Cancel = true;
                }
            };

            AppArguments.SetSize(AppFlag.ImagesCacheLimit, ref BetterImage.OptionCacheTotalSize);
            AppArguments.Set(AppFlag.ImagesMarkCached, ref BetterImage.OptionMarkCached);
            BetterImage.RemoteUserAgent      = CmApiProvider.UserAgent;
            BetterImage.RemoteCacheDirectory = BbCodeBlock.OptionImageCacheDirectory;
            GameWrapper.Started += (sender, args) => {
                BetterImage.CleanUpCache();
                GCHelper.CleanUp();
            };

            AppArguments.Set(AppFlag.UseVlcForAnimatedBackground, ref DynamicBackground.OptionUseVlc);
            Filter.OptionSimpleMatching = true;

            GameResultExtension.RegisterNameProvider(new GameSessionNameProvider());
            CarBlock.CustomShowroomWrapper   = new CustomShowroomWrapper();
            CarBlock.CarSetupsView           = new CarSetupsView();
            SettingsHolder.Content.OldLayout = AppArguments.GetBool(AppFlag.CarsOldLayout);

            var acRootIsFine = Superintendent.Instance.IsReady && !AcRootDirectorySelector.IsReviewNeeded();

            if (acRootIsFine && SteamStarter.Initialize(AcRootDirectory.Instance.Value))
            {
                if (SettingsHolder.Drive.SelectedStarterType != SettingsHolder.DriveSettings.SteamStarterType)
                {
                    SettingsHolder.Drive.SelectedStarterType = SettingsHolder.DriveSettings.SteamStarterType;
                    Toast.Show("Starter changed to replacement", "Enjoy Steam being included into CM");
                }
            }
            else if (SettingsHolder.Drive.SelectedStarterType == SettingsHolder.DriveSettings.SteamStarterType)
            {
                SettingsHolder.Drive.SelectedStarterType = SettingsHolder.DriveSettings.DefaultStarterType;
                Toast.Show($"Starter changed to {SettingsHolder.Drive.SelectedStarterType.DisplayName}", "Steam Starter is unavailable", () => {
                    ModernDialog.ShowMessage(
                        "To use Steam Starter, please make sure CM is taken place of the official launcher and AC root directory is valid.",
                        "Steam Starter is unavailable", MessageBoxButton.OK);
                });
            }

            InitializeUpdatableStuff();
            BackgroundInitialization();
            ExtraProgressRings.Initialize();

            FatalErrorMessage.Register(new AppRestartHelper());
            ImageUtils.SafeMagickWrapper = fn => {
                try {
                    return(fn());
                } catch (OutOfMemoryException e) {
                    NonfatalError.Notify(ToolsStrings.MagickNet_CannotLoad, ToolsStrings.MagickNet_CannotLoad_Commentary, e);
                } catch (Exception e) {
                    NonfatalError.Notify(ToolsStrings.MagickNet_CannotLoad, e);
                }
                return(null);
            };

            DataFileBase.ErrorsCatcher = new DataSyntaxErrorCatcher();
            AppArguments.Set(AppFlag.SharedMemoryLiveReadingInterval, ref AcSharedMemory.OptionLiveReadingInterval);
            AcSharedMemory.Initialize();

            AppArguments.Set(AppFlag.RunRaceInformationWebserver, ref PlayerStatsManager.OptionRunStatsWebserver);
            AppArguments.Set(AppFlag.RaceInformationWebserverFile, ref PlayerStatsManager.OptionWebserverFilename);

            PlayerStatsManager.Instance.SetListener();
            RhmService.Instance.SetListener();

            WheelOptionsBase.SetStorage(new WheelAnglesStorage());

            _hibernator = new AppHibernator();
            _hibernator.SetListener();

            VisualCppTool.Initialize(FilesStorage.Instance.GetDirectory("Plugins", "NativeLibs"));

            try {
                SetRenderersOptions();
            } catch (Exception e) {
                VisualCppTool.OnException(e, null);
            }

            CommonFixes.Initialize();

            CmPreviewsTools.MissingShowroomHelper = new CarUpdatePreviewsDialog.MissingShowroomHelper();

            // Paint shop+livery generator?
            LiteShowroomTools.LiveryGenerator = new LiveryGenerator();

            // Discord
            if (AppArguments.Has(AppFlag.DiscordCmd))
            {
                // Do not show main window and wait for futher instructions?
            }

            if (SettingsHolder.Integrated.DiscordIntegration)
            {
                AppArguments.Set(AppFlag.DiscordVerbose, ref DiscordConnector.OptionVerboseMode);
                DiscordConnector.Initialize(AppArguments.Get(AppFlag.DiscordClientId) ?? InternalUtils.GetDiscordClientId(), new DiscordHandler());
                DiscordImage.OptionDefaultImage = @"track_ks_brands_hatch";
                GameWrapper.Started            += (sender, args) => args.StartProperties.SetAdditional(new GameDiscordPresence(args.StartProperties, args.Mode));
            }

            // Reshade?
            var loadReShade = AppArguments.GetBool(AppFlag.ForceReshade);

            if (!loadReShade && string.Equals(AppArguments.Get(AppFlag.ForceReshade), "kn5only", StringComparison.OrdinalIgnoreCase))
            {
                loadReShade = AppArguments.Values.Any(x => x.EndsWith(".kn5", StringComparison.OrdinalIgnoreCase));
            }

            if (loadReShade)
            {
                var reshade = Path.Combine(MainExecutingFile.Directory, "dxgi.dll");
                if (File.Exists(reshade))
                {
                    Kernel32.LoadLibrary(reshade);
                }
            }

            // Auto-show that thing
            InstallAdditionalContentDialog.Initialize();

            // Let’s roll
            ShutdownMode = ShutdownMode.OnExplicitShutdown;
            new AppUi(this).Run();
        }
Example #3
0
 public Task UpdateProgressViaSteamStarter(IProgress <string> progress, CancellationToken cancellation)
 {
     return(UpdateProgressViaSteamStatisticsReader(c => Task.Run(() => SteamStarter.GetAchievements()), progress, cancellation));
 }
Example #4
0
        private App()
        {
            if (AppArguments.GetBool(AppFlag.IgnoreHttps))
            {
                ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
            }

            AppArguments.Set(AppFlag.SyncNavigation, ref ModernFrame.OptionUseSyncNavigation);
            AppArguments.Set(AppFlag.DisableTransitionAnimation, ref ModernFrame.OptionDisableTransitionAnimation);
            AppArguments.Set(AppFlag.RecentlyClosedQueueSize, ref LinkGroupFilterable.OptionRecentlyClosedQueueSize);

            AppArguments.Set(AppFlag.NoProxy, ref KunosApiProvider.OptionNoProxy);

            var proxy = AppArguments.Get(AppFlag.Proxy);

            if (!string.IsNullOrWhiteSpace(proxy))
            {
                try {
                    var s = proxy.Split(':');
                    WebRequest.DefaultWebProxy = new WebProxy(s[0], FlexibleParser.ParseInt(s.ElementAtOrDefault(1), 1080));
                } catch (Exception e) {
                    Logging.Error(e);
                }
            }

            // TODO: AppArguments.Set(AppFlag.ScanPingTimeout, ref RecentManagerOld.OptionScanPingTimeout);
            AppArguments.Set(AppFlag.LanSocketTimeout, ref KunosApiProvider.OptionLanSocketTimeout);
            AppArguments.Set(AppFlag.LanPollTimeout, ref KunosApiProvider.OptionLanPollTimeout);
            AppArguments.Set(AppFlag.WebRequestTimeout, ref KunosApiProvider.OptionWebRequestTimeout);
            AppArguments.Set(AppFlag.DirectRequestTimeout, ref KunosApiProvider.OptionDirectRequestTimeout);
            AppArguments.Set(AppFlag.CommandTimeout, ref GameCommandExecutorBase.OptionCommandTimeout);

            AppArguments.Set(AppFlag.DisableAcRootChecking, ref AcRootDirectory.OptionDisableChecking);
            AppArguments.Set(AppFlag.AcObjectsLoadingConcurrency, ref BaseAcManagerNew.OptionAcObjectsLoadingConcurrency);
            AppArguments.Set(AppFlag.SkinsLoadingConcurrency, ref CarObject.OptionSkinsLoadingConcurrency);
            AppArguments.Set(AppFlag.KunosCareerIgnoreSkippedEvents, ref KunosCareerEventsManager.OptionIgnoreSkippedEvents);
            AppArguments.Set(AppFlag.IgnoreMissingSkinsInKunosEvents, ref KunosEventObjectBase.OptionIgnoreMissingSkins);

            AppArguments.Set(AppFlag.CanPack, ref AcCommonObject.OptionCanBePackedFilter);
            AppArguments.Set(AppFlag.CanPackCars, ref CarObject.OptionCanBePackedFilter);

            AppArguments.Set(AppFlag.ForceToastFallbackMode, ref Toast.OptionFallbackMode);

            AppArguments.Set(AppFlag.SmartPresetsChangedHandling, ref UserPresetsControl.OptionSmartChangedHandling);
            AppArguments.Set(AppFlag.EnableRaceIniRestoration, ref Game.OptionEnableRaceIniRestoration);
            AppArguments.Set(AppFlag.EnableRaceIniTestMode, ref Game.OptionRaceIniTestMode);
            AppArguments.Set(AppFlag.RaceOutDebug, ref Game.OptionDebugMode);

            AppArguments.Set(AppFlag.NfsPorscheTribute, ref RaceGridViewModel.OptionNfsPorscheNames);
            AppArguments.Set(AppFlag.KeepIniComments, ref IniFile.OptionKeepComments);
            AppArguments.Set(AppFlag.AutoConnectPeriod, ref OnlineServer.OptionAutoConnectPeriod);

            LimitedSpace.Initialize();
            LimitedStorage.Initialize();

            DataProvider.Initialize();
            CountryIdToImageConverter.Initialize(
                FilesStorage.Instance.GetDirectory(FilesStorage.DataDirName, ContentCategory.CountryFlags),
                FilesStorage.Instance.GetDirectory(FilesStorage.DataUserDirName, ContentCategory.CountryFlags));
            FilesStorage.Instance.Watcher(ContentCategory.CountryFlags).Update += (sender, args) => {
                CountryIdToImageConverter.ResetCache();
            };

            TestKey();

            AppDomain.CurrentDomain.ProcessExit += OnProcessExit;

            if (!AppArguments.GetBool(AppFlag.PreventDisableWebBrowserEmulationMode) && (
                    ValuesStorage.GetInt(WebBrowserEmulationModeDisabledKey) < WebBrowserHelper.EmulationModeDisablingVersion ||
                    AppArguments.GetBool(AppFlag.ForceDisableWebBrowserEmulationMode)))
            {
                try {
                    WebBrowserHelper.DisableBrowserEmulationMode();
                    ValuesStorage.Set(WebBrowserEmulationModeDisabledKey, WebBrowserHelper.EmulationModeDisablingVersion);
                } catch (Exception e) {
                    Logging.Warning("Can’t disable emulation mode: " + e);
                }
            }

            JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
                Formatting           = Formatting.None,
                NullValueHandling    = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Include,
                Culture = CultureInfo.InvariantCulture
            };

            AcToolsLogging.Logger = (s, m, p, l) => Logging.Write($"{s} (AcTools)", m, p, l);
            AcToolsLogging.NonFatalErrorHandler = (s, c, e) => NonfatalError.Notify(s, c, e);

            var ignoreControls = AppArguments.Get(AppFlag.IgnoreControls);

            if (!string.IsNullOrWhiteSpace(ignoreControls))
            {
                ControlsSettings.OptionIgnoreControlsFilter = Filter.Create(new StringTester(), ignoreControls);
            }

            var sseStart = AppArguments.Get(AppFlag.SseName);

            if (!string.IsNullOrWhiteSpace(sseStart))
            {
                SseStarter.OptionStartName = sseStart;
            }
            AppArguments.Set(AppFlag.SseLogging, ref SseStarter.OptionLogging);

            FancyBackgroundManager.Initialize();
            if (AppArguments.Has(AppFlag.UiScale))
            {
                DpiAwareWindow.OptionScale = AppArguments.GetDouble(AppFlag.UiScale, 1d);
            }

            if (!AppKeyHolder.IsAllRight)
            {
                AppAppearanceManager.OptionCustomThemes = false;
            }
            else
            {
                AppArguments.Set(AppFlag.CustomThemes, ref AppAppearanceManager.OptionCustomThemes);
            }

            AppArguments.Set(AppFlag.FancyHintsDebugMode, ref FancyHint.OptionDebugMode);
            AppArguments.Set(AppFlag.FancyHintsMinimumDelay, ref FancyHint.OptionMinimumDelay);

            /*AppAppearanceManager.OptionIdealFormattingModeDefaultValue = AppArguments.GetBool(AppFlag.IdealFormattingMode,
             *      !Equals(DpiAwareWindow.OptionScale, 1d));*/
            AppAppearanceManager.Initialize();

            AcObjectsUriManager.Register(new UriProvider());

            {
                var uiFactory = new GameWrapperUiFactory();
                GameWrapper.RegisterFactory(uiFactory);
                ServerEntry.RegisterFactory(uiFactory);
            }

            GameWrapper.RegisterFactory(new DefaultAssistsFactory());
            LapTimesManager.Instance.SetListener();

            AcError.RegisterFixer(new AcErrorFixer());
            AcError.RegisterSolutionsFactory(new SolutionsFactory());

            InitializePresets();

            SharingHelper.Initialize();
            SharingUiHelper.Initialize();

            {
                var addonsDir  = FilesStorage.Instance.GetFilename("Addons");
                var pluginsDir = FilesStorage.Instance.GetFilename("Plugins");
                if (Directory.Exists(addonsDir) && !Directory.Exists(pluginsDir))
                {
                    Directory.Move(addonsDir, pluginsDir);
                }
                else
                {
                    pluginsDir = FilesStorage.Instance.GetDirectory("Plugins");
                }

                PluginsManager.Initialize(pluginsDir);
                PluginsWrappers.Initialize(
                    new FmodPluginWrapper(),
                    new MagickPluginWrapper(),
                    new AwesomiumPluginWrapper(),
                    new CefSharpPluginWrapper(),
                    new StarterPlus());
            }

            {
                var onlineMainListFile   = FilesStorage.Instance.GetFilename("Online Servers", "Main List.txt");
                var onlineFavouritesFile = FilesStorage.Instance.GetFilename("Online Servers", "Favourites.txt");
                if (File.Exists(onlineMainListFile) && !File.Exists(onlineFavouritesFile))
                {
                    Directory.Move(onlineMainListFile, onlineFavouritesFile);
                }
            }

            SteamIdHelper.Initialize(AppArguments.Get(AppFlag.ForceSteamId));
            Superintendent.Initialize();

            AppArguments.Set(AppFlag.OfflineMode, ref AppKeyDialog.OptionOfflineMode);

            PrepareUi();

            AppShortcut.Initialize("AcClub.ContentManager", "Content Manager");
            AppIconService.Initialize(this);

            Toast.SetDefaultAction(() => (Current.Windows.OfType <ModernWindow>().FirstOrDefault(x => x.IsActive) ??
                                          Current.MainWindow as ModernWindow)?.BringToFront());
            BbCodeBlock.ImageClicked             += OnBbImageClick;
            BbCodeBlock.OptionEmojiProvider       = InternalUtils.GetEmojiProvider();
            BbCodeBlock.OptionImageCacheDirectory = FilesStorage.Instance.GetTemporaryFilename("Images");
            BbCodeBlock.OptionEmojiCacheDirectory = FilesStorage.Instance.GetTemporaryFilename("Emoji");

            BbCodeBlock.AddLinkCommand(new Uri("cmd://findmissing/car"), new DelegateCommand <string>(id => {
                WindowsHelper.ViewInBrowser(SettingsHolder.Content.MissingContentSearch.GetUri(id, SettingsHolder.MissingContentType.Car));
            }));

            BbCodeBlock.AddLinkCommand(new Uri("cmd://findmissing/track"), new DelegateCommand <string>(id => {
                WindowsHelper.ViewInBrowser(SettingsHolder.Content.MissingContentSearch.GetUri(id, SettingsHolder.MissingContentType.Track));
            }));

            BbCodeBlock.AddLinkCommand(new Uri("cmd://downloadmissing/car"), new DelegateCommand <string>(id => {
                var s = id.Split('|');
                IndexDirectDownloader.DownloadCarAsync(s[0], s.ElementAtOrDefault(1)).Forget();
            }));

            BbCodeBlock.AddLinkCommand(new Uri("cmd://downloadmissing/track"), new DelegateCommand <string>(id => {
                var s = id.Split('|');
                IndexDirectDownloader.DownloadTrackAsync(s[0], s.ElementAtOrDefault(1)).Forget();
            }));

            BbCodeBlock.AddLinkCommand(new Uri("cmd://createneutrallut"), new DelegateCommand <string>(id => {
                NeutralColorGradingLut.CreateNeutralLut(id.AsInt(16));
            }));

            BbCodeBlock.DefaultLinkNavigator.PreviewNavigate += (sender, args) => {
                if (args.Uri.IsAbsoluteUri && args.Uri.Scheme == "acmanager")
                {
                    ArgumentsHandler.ProcessArguments(new[] { args.Uri.ToString() }).Forget();
                    args.Cancel = true;
                }
            };

            AppArguments.SetSize(AppFlag.ImagesCacheLimit, ref BetterImage.OptionCacheTotalSize);
            AppArguments.Set(AppFlag.ImagesMarkCached, ref BetterImage.OptionMarkCached);
            BetterImage.RemoteUserAgent      = CmApiProvider.UserAgent;
            BetterImage.RemoteCacheDirectory = BbCodeBlock.OptionImageCacheDirectory;

            AppArguments.Set(AppFlag.UseVlcForAnimatedBackground, ref DynamicBackground.OptionUseVlc);
            Filter.OptionSimpleMatching = SettingsHolder.Content.SimpleFiltering;

            CarBlock.CustomShowroomWrapper = new CustomShowroomWrapper();
            CarBlock.CarSetupsView         = new CarSetupsView();

            var acRootIsFine = Superintendent.Instance.IsReady && !AcRootDirectorySelector.IsReviewNeeded();

            if (acRootIsFine && SteamStarter.Initialize(AcRootDirectory.Instance.Value))
            {
                if (SettingsHolder.Drive.SelectedStarterType != SettingsHolder.DriveSettings.SteamStarterType)
                {
                    SettingsHolder.Drive.SelectedStarterType = SettingsHolder.DriveSettings.SteamStarterType;
                    Toast.Show("Starter Changed to Replacement", "Enjoy Steam being included into CM");
                }
            }
            else if (SettingsHolder.Drive.SelectedStarterType == SettingsHolder.DriveSettings.SteamStarterType)
            {
                SettingsHolder.Drive.SelectedStarterType = SettingsHolder.DriveSettings.OfficialStarterType;
                Toast.Show("Starter Changed to Official", "Steam Starter is unavailable", () => {
                    ModernDialog.ShowMessage("To use Steam Starter, please make sure CM is taken place of the official launcher and AC root directory is valid.",
                                             "Steam Starter is unavailable", MessageBoxButton.OK);
                });
            }

            InitializeUpdatableStuff();
            BackgroundInitialization();

            FatalErrorMessage.Register(this);
            ImageUtils.SafeMagickWrapper = fn => {
                try {
                    return(fn());
                } catch (OutOfMemoryException e) {
                    NonfatalError.Notify(ToolsStrings.MagickNet_CannotLoad, ToolsStrings.MagickNet_CannotLoad_Commentary, e);
                } catch (Exception e) {
                    NonfatalError.Notify(ToolsStrings.MagickNet_CannotLoad, e);
                }
                return(null);
            };

            AbstractDataFile.ErrorsCatcher = new DataSyntaxErrorCatcher();
            AppArguments.Set(AppFlag.SharedMemoryLiveReadingInterval, ref AcSharedMemory.OptionLiveReadingInterval);
            AcSharedMemory.Initialize();

            AppArguments.Set(AppFlag.RunRaceInformationWebserver, ref PlayerStatsManager.OptionRunStatsWebserver);
            AppArguments.Set(AppFlag.RaceInformationWebserverFile, ref PlayerStatsManager.OptionWebserverFilename);
            PlayerStatsManager.Instance.SetListener();

            // AppArguments.Set(AppFlag.RhmKeepAlive, ref RhmService.OptionKeepRunning);
            RhmService.Instance.SetListener();

            _hibernator = new AppHibernator();
            _hibernator.SetListener();

            AppArguments.Set(AppFlag.TrackMapGeneratorMaxSize, ref TrackMapRenderer.OptionMaxSize);
            CommonFixes.Initialize();

            // TODO: rearrange code!
            CmPreviewsSettings.SelectCarDialog    = SelectCarDialog.Show;
            CmPreviewsTools.MissingShowroomHelper = new CarUpdatePreviewsDialog.MissingShowroomHelper();

            // paint shop+livery generator?
            LiteShowroomTools.LiveryGenerator = new LiveryGenerator();

            // auto-show that thing
            InstallAdditionalContentDialog.Initialize();

            ShutdownMode = ShutdownMode.OnExplicitShutdown;
            new AppUi(this).Run();
        }