Example #1
0
        public static int Main(string[] args)
        {
            CultureInfo.DefaultThreadCurrentCulture   = CultureInfo.InvariantCulture;
            CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");

            try {
                var options = new Options();
                if (!Parser.Default.ParseArguments(args, options))
                {
                    return(1);
                }

                FilesStorage.Initialize(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "AcTools Console Wrapper"));
                ValuesStorage.Initialize(null, null);
                CacheStorage.Initialize(null);
                LimitedSpace.Initialize();
                LimitedStorage.Initialize();
                DataProvider.Initialize();

                AcRootDirectory.Initialize(options.AcRoot);
                if (!AcRootDirectory.Instance.IsReady)
                {
                    Console.Error.WriteLine("Invalid AC root directory");
                    return(3);
                }

                Superintendent.Initialize();

                AsyncContext.Run(() => MainAsync(options));
                return(0);
            } catch (InformativeException e) {
                Console.Error.WriteLine(e.Message);
                return(2);
            } catch (Exception e) {
                Console.Error.WriteLine(e.ToString());
                return(2);
            }
        }
Example #2
0
        public App()
        {
            FilesStorage.Initialize(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "AcTools Arcade Corsa"));
            ValuesStorage.Initialize(FilesStorage.Instance.GetFilename("Values.data"), null);
            CacheStorage.Initialize(FilesStorage.Instance.GetFilename("Cache.data"));
            NonfatalError.Initialize();
            LimitedSpace.Initialize();
            LimitedStorage.Initialize();
            DataProvider.Initialize();
            DpiAwareWindow.OptionScale = 2d;

            Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline), new FrameworkPropertyMetadata {
                DefaultValue = 20
            });

            AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;

            Resources.MergedDictionaries.Add(new SharedResourceDictionary {
                Source = new Uri("/FirstFloor.ModernUI;component/Assets/ModernUI.xaml", UriKind.Relative)
            });

            Resources.MergedDictionaries.Add(new SharedResourceDictionary {
                Source = new Uri("/Arcade Corsa;component/Assets/Theme.xaml", UriKind.Relative)
            });

            if (MainExecutingFile.Name.IndexOf("fancy", StringComparison.OrdinalIgnoreCase) != -1)
            {
                Resources["EffectsEnabled"] = true;
                Resources["ShadowEffect"]   = new DropShadowEffect {
                    RenderingBias = RenderingBias.Performance,
                    BlurRadius    = 30,
                    Direction     = -90,
                    Color         = Colors.Black,
                    ShadowDepth   = 4,
                    Opacity       = 0.6
                };
            }
            else
            {
                Resources["EffectsEnabled"] = false;
                Resources["ShadowEffect"]   = null;
            }

            var    config = Path.Combine(MainExecutingFile.Directory, "Config.json");
            string acRoot;

            if (File.Exists(config))
            {
                var options = JsonConvert.DeserializeObject <Options>(File.ReadAllText(config));
                if (options.AcRoot == null)
                {
                    options.AcRoot = AcRootDirectory.TryToFind();
                    File.WriteAllText(config, JsonConvert.SerializeObject(options));
                }

                acRoot = options.AcRoot;
            }
            else
            {
                acRoot = AcRootDirectory.TryToFind();
            }

            AcRootDirectory.Initialize(acRoot);
            if (!AcRootDirectory.Instance.IsReady)
            {
                ModernDialog.ShowMessage("Can’t find AC root directory. Please, specify it using Config.json file.");
                return;
            }

            Superintendent.Initialize();

            StartupUri = new Uri("MainWindow.xaml", UriKind.Relative);
        }
Example #3
0
        private App()
        {
            AppArguments.Set(AppFlag.SyncNavigation, ref ModernFrame.OptionUseSyncNavigation);
            AppArguments.Set(AppFlag.DisableTransitionAnimation, ref ModernFrame.OptionDisableTransitionAnimation);
            AppArguments.Set(AppFlag.RecentlyClosedQueueSize, ref LinkGroupFilterable.OptionRecentlyClosedQueueSize);

            AppArguments.Set(AppFlag.ForceSteamId, ref SteamIdHelper.OptionForceValue);

            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.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.LiteStartupModeSupported, ref Pages.Windows.MainWindow.OptionLiteModeSupported);
            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 += CurrentDomain_ProcessExit;

            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);

            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;
            }

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

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

            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 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();
            AppIconService.Initialize(this);
            Toast.SetDefaultAction(() => (Current.Windows.OfType <ModernWindow>().FirstOrDefault(x => x.IsActive) ??
                                          Current.MainWindow as ModernWindow)?.BringToFront());
            BbCodeBlock.ImageClicked             += BbCodeBlock_ImageClicked;
            BbCodeBlock.OptionEmojiProvider       = InternalUtils.GetEmojiProvider();
            BbCodeBlock.OptionImageCacheDirectory = FilesStorage.Instance.GetTemporaryFilename("Images");
            BbCodeBlock.OptionEmojiCacheDirectory = FilesStorage.Instance.GetTemporaryFilename("Emoji");

            AppArguments.SetSize(AppFlag.ImagesCacheLimit, ref BetterImage.OptionCacheTotalSize);
            AppArguments.Set(AppFlag.ImagesMarkCached, ref BetterImage.OptionMarkCached);
            AppArguments.Set(AppFlag.UseVlcForAnimatedBackground, ref DynamicBackground.OptionUseVlc);
            Filter.OptionSimpleMatching = SettingsHolder.Content.SimpleFiltering;

            StartupUri = new Uri(!Superintendent.Instance.IsReady || AcRootDirectorySelector.IsReviewNeeded() ?
                                 @"Pages/Dialogs/AcRootDirectorySelector.xaml" : @"Pages/Windows/MainWindow.xaml", UriKind.Relative);

            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();
        }
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();
        }