public async ValueTask Run() { var downloader = new FileDownloader(); var libDownloadList = await Game.EnsureLibraryAsync(LibDir); foreach (var lib in libDownloadList) { downloader.Enqueue(lib.Url, Path.Combine(LibDir, lib.Path), lib.Sha); } await foreach (var asset in Asset.EnsureAssets(AssetDir)) { downloader.Enqueue(asset.DownloadUrl, asset.SaveLocation, asset.Hash); } await downloader.Execute(); var nativePath = Path.Combine(StartupDir, "natives"); var name = Assembly.GetExecutingAssembly().GetName(); Options["version_name"] = Game.Id; Options["game_directory"] = StartupDir; Options["assets_root"] = AssetDir; Options["assets_index_name"] = Game.AssetIndex; Options["launcher_name"] = name.Name ?? "TheLauncher"; Options["version_type"] = name.Name ?? "TheLauncher"; Options["launcher_version"] = name.Version?.ToString() ?? "Unknown"; await Game.ExtractNativeAsync(nativePath, LibDir); Options["natives_directory"] = $"{nativePath}"; Options["classpath"] = Game.ProcessClassPath(LibDir); foreach (var(key, value) in await Authenticator.Authenticate()) { Options[key] = value; } Game.ApplyArgs(Options); ArgBuilder.Append(Game); var info = new ProcessStartInfo(JavaPath) { WorkingDirectory = StartupDir }; foreach (var s in ArgBuilder.Build()) { info.ArgumentList.Add(s); } using var minecraft = Process.Start(info); if (minecraft != null) { await minecraft.WaitForExitAsync(); } }