Пример #1
0
        public async void Launch()
        {
            IsLaunching        = true;
            GreetingVM.IsShown = false;
            LaunchProcessStarted?.Invoke();

            // Check JRE
            if (_config.JreDir == null)
            {
                _windowManager.ShowMessageBox("${JreNotFound}\n${PleaseInstallJre}", "${IntegrityCheck}",
                                              MessageBoxButton.OK, MessageBoxImage.Error);

                _statusVM.Status = LaunchStatus.Failed;
                return;
            }

            _statusVM.GameOutputLog = null;
            this.ActivateItem(_statusVM);

            _statusVM.Status = LaunchStatus.LoggingIn;

            // No account found, the user must create one
            var account = _accountService.GetSelected();

            if (account == null)
            {
                _accountEditVM.Setup(AccountEditType.AddAccount);

                if (_windowManager.ShowDialog(_accountEditVM) != true)
                {
                    _statusVM.Status = LaunchStatus.Failed;
                    return;
                }

                account = _accountService.GetSelected();
            }
            else
            {
                // Previous login token is invalid, need re-authentication
                var authResult = await _authService.LoginAsync(account);

                if (!authResult.IsSuccessful)
                {
                    _accountEditVM.Setup(AccountEditType.ReAuth, account);

                    if (_windowManager.ShowDialog(_accountEditVM) != true)
                    {
                        _statusVM.Status = LaunchStatus.Failed;
                        return;
                    }
                }
                else if (authResult.SelectedProfile == null)
                {
                    var selectedProfile = authResult.AvailableProfiles.FirstOrDefault();

                    _profileSelectVM.Setup(authResult.AvailableProfiles, account.ProfileServer);
                    if (_windowManager.ShowDialog(_profileSelectVM) ?? false)
                    {
                        selectedProfile = _profileSelectVM.SelectedProfile;
                    }

                    account.Username = selectedProfile.Name;
                    account.UUID     = selectedProfile.Id;

                    await _accountService.LoadSkinAsync(account);

                    GreetingVM.NotifyAccountChanged();
                }
            }

            // Check authlib-injector if selected account is using external authentication
            if (account.AuthMode == AuthMode.AuthLibInjector)
            {
                if (!_authlibInjectorService.CheckIntegrity(account.AuthlibInjectorSHA256))
                {
                    // Authlib-Injector is missing or damaged
                    var latest = await _authlibInjectorService.GetLatest();

                    if (latest == null)
                    {
                        _statusVM.Status = LaunchStatus.Failed;
                        return;
                    }

                    var download = _authlibInjectorService.GetDownload(latest);
                    if (!await StartDownloadAsync(DownloadType.AuthlibInjector, download))
                    {
                        _statusVM.Status = LaunchStatus.Failed;
                        return;
                    }

                    account.AuthlibInjectorSHA256 = latest.SHA256;
                }

                account.PrefetchedAuthServerInfo =
                    await _authService.PrefetchAuthServerInfo(account.AuthServerBase);

                if (account.PrefetchedAuthServerInfo == null)
                {
                    _statusVM.Status = LaunchStatus.Failed;
                    return;
                }
            }

            _statusVM.Status = LaunchStatus.ProcessingDependencies;
            var launchVersion = _versionService.GetByID(_config.SelectedVersion);

            // Check main jar and fix possible damage
            if (!_versionService.CheckIntegrity(launchVersion))
            {
                var download = _versionService.GetDownload(launchVersion);
                if (!await StartDownloadAsync(DownloadType.MainJar, download))
                {
                    _statusVM.Status = LaunchStatus.Failed;
                    return;
                }
            }

            // Check dependent libraries and fix possible damage
            var damagedLibs = await _libraryService.CheckIntegrityAsync(launchVersion.Libraries);

            if (damagedLibs.Any())
            {
                // For 1.13.2+ forge versions, there is no way to fix damaged forge jar unless reinstall
                if (launchVersion.Type == VersionType.NewForge && damagedLibs.Any(
                        lib => lib.Type == LibraryType.ForgeMain
                        ))
                {
                    _windowManager.ShowMessageBox("${MainJarDamaged}\n${PleaseReinstallForge}", "${IntegrityCheck}",
                                                  MessageBoxButton.OK, MessageBoxImage.Error);
                    // Delete the damaged forge version (but retain the libraries)
                    // force user to reinstall it
                    await _versionService.DeleteFromDiskAsync(launchVersion.ID, false);

                    _statusVM.Status = LaunchStatus.Failed;
                    return;
                }

                var downloads = _libraryService.GetDownloads(damagedLibs);
                if (!await StartDownloadAsync(DownloadType.Libraries, downloads))
                {
                    _statusVM.Status = LaunchStatus.Failed;
                    return;
                }
            }

            // Extract native libraries
            _libraryService.ExtractNatives(launchVersion.Libraries.Where(lib => lib.Type == LibraryType.Native));

            // Try loading assets
            if (!_assetService.LoadAllObjects(launchVersion.AssetsInfo))
            {
                if (await _assetService.DownloadIndexJsonAsync(launchVersion.AssetsInfo))
                {
                    // Successfully downloaded the missing index json, load assets
                    _assetService.LoadAllObjects(launchVersion.AssetsInfo);
                }

                // if index json download failed (what are the odds!), not gonna retry
                // Prepare for enjoying a silent game XD
            }

            // Check assets and fix possible damage on user's discretion
            var damagedAssets = await _assetService.CheckIntegrityAsync(launchVersion.AssetsInfo);

            if ((damagedAssets?.Any() ?? false) &&
                _windowManager.ShowMessageBox("${AssetsDamaged}\n${WhetherFixNow}", "${IntegrityCheck}",
                                              MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                var downloads = _assetService.GetDownloads(damagedAssets);
                await StartDownloadAsync(DownloadType.Assets, downloads);
            }

            // For legacy versions (1.7.2 or earlier), copy hashed asset objects to virtual files
            if (launchVersion.AssetsInfo.IsLegacy)
            {
                await _assetService.CopyToVirtualAsync(launchVersion.AssetsInfo);
            }

            // All good to go, now build launch profile
            var profile = new LaunchProfile
            {
                IsDebugMode   = _config.JavaDebugMode,
                JvmArgs       = _config.JvmArgs,
                MaxMemory     = _config.JavaMaxMem,
                Account       = account,
                VersionType   = AssemblyUtil.Title,
                WinWidth      = _config.WindowWidth,
                WinHeight     = _config.WindowHeight,
                IsFullScreen  = _config.FullScreen,
                ServerAddress = _config.ServerAddress,
                ExtraArgs     = _config.ExtraMinecraftArgs,
            };

            _statusVM.Status = LaunchStatus.StartingProcess;

            void UpdateLogDisplay(string logMessage) => _statusVM.GameOutputLog = logMessage;

            _launchService.LogReceived += UpdateLogDisplay;

            if (!await _launchService.LaunchGameAsync(profile, launchVersion))
            {
                _statusVM.Status            = LaunchStatus.Failed;
                _launchService.LogReceived -= UpdateLogDisplay;
                return;
            }

            _statusVM.Status = LaunchStatus.Running;

            _launchService.LogReceived -= UpdateLogDisplay;
            _statusVM.GameOutputLog     = XD;
        }