diff --git a/BedrockLauncher.Core.StartUp/Program.cs b/BedrockLauncher.Core.StartUp/Program.cs deleted file mode 100644 index ba3a4d9..0000000 --- a/BedrockLauncher.Core.StartUp/Program.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System.Net; -using System.Net.Http.Json; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; -using System.Text.Json; -using System.Text.Json.Serialization; -using Windows.Management.Deployment; -using BedrockLauncher.Core.CoreOption; -using BedrockLauncher.Core.DependsComplete; -using BedrockLauncher.Core.GdkDecode; -using BedrockLauncher.Core.SoureGenerate; -using BedrockLauncher.Core.Utils; -using BedrockLauncher.Core.VersionJsons; - -namespace BedrockLauncher.Core.StartUp -{ - internal class Program - { - static void PrintDownloadProgress(DownloadProgress progress) - { - Console.WriteLine("下载进度信息:"); - Console.WriteLine($"进度: {progress.Progress:F1}%"); - Console.WriteLine($"已完成: {FormatBytes(progress.FinishedBytes)} / {FormatBytes(progress.TotalBytes)}"); - Console.WriteLine($"速度: {progress.Speed:F1} KB/s"); - Console.WriteLine($"阶段: {GetStageDescription(progress.Phase)}"); - - // 绘制进度条(仅在下载阶段显示) - if (progress.Phase == DownloadStage.Downloading) - { - DrawProgressBar(progress.Progress); - } - } - - static string FormatBytes(long bytes) - { - string[] suffixes = { "B", "KB", "MB", "GB", "TB" }; - int counter = 0; - double number = bytes; - - while (number >= 1024 && counter < suffixes.Length - 1) - { - number /= 1024; - counter++; - } - - return $"{number:F1} {suffixes[counter]}"; - } - - static string GetStageDescription(DownloadStage stage) - { - return stage switch - { - DownloadStage.Downloading => "下载中", - DownloadStage.Merging => "合并中", - DownloadStage.Merged => "已完成", - _ => "未知" - }; - } - - static void DrawProgressBar(double progress) - { - const int totalBlocks = 20; - int filledBlocks = (int)(progress / 100 * totalBlocks); - - Console.Write("进度条: ["); - Console.Write(new string('█', filledBlocks)); - Console.Write(new string('░', totalBlocks - filledBlocks)); - Console.WriteLine($"] {progress:F1}%"); - } - static void Main(string[] args) - { - - //var buildDatabaseAsync = VersionsHelper.GetBuildDatabaseAsync("https://data.mcappx.com/v2/bedrock.json").Result; - var bedrockCore = new BedrockCore(); - var options = new LocalGamePackageOptions() - { - FileFullPath = Path.GetFullPath(@"C:\Users\Administrator\AppData\Roaming\RoundStudio\BedrockBoot\Bedrock_Data\Appx\1.21.12020.appx"), - Type = MinecraftBuildTypeVersion.UWP, - GameTypeVersion = MinecraftGameTypeVersion.Preview, - ExtractionProgress = (new Progress((progress => - { - double percentage = progress.TotalCount > 0 - ? (double)progress.CurrentCount / progress.TotalCount * 100 - : 0; - - // 创建进度条 - int barWidth = 50; - int progressBars = progress.TotalCount > 0 - ? (int)((double)progress.CurrentCount / progress.TotalCount * barWidth) - : 0; - - string progressBar = new string('█', progressBars) + - new string('░', barWidth - progressBars); - - // 打印进度信息 - Console.Write($"\r[{progressBar}] {percentage:F1}% | " + - $"{progress.CurrentCount:N0}/{progress.TotalCount:N0} | " + - $"{progress.FileName}"); - - // 如果完成,换行 - if (progress.CurrentCount >= progress.TotalCount) - { - Console.WriteLine(); - } - }))), - InstallDstFolder = Path.GetFullPath("./rr4") - }; - options.DeployProgress = new Progress((progress => - { - Console.WriteLine(progress.percentage + progress.state.ToString()); - })); - var installResult = bedrockCore.InstallPackageAsync(options).Result; - Console.WriteLine(installResult.DeploymentResult?.IsRegistered); - Console.WriteLine(installResult.DeploymentResult?.ErrorText); - } - static void PrintBuildInfo(BuildDatabase buildData) - { - Console.WriteLine($"数据库创建时间: {buildData.CreationTime:yyyy-MM-dd HH:mm:ss}"); - Console.WriteLine($"包含 {buildData.Builds.Count} 个版本"); - Console.WriteLine(); - - foreach (var (version, buildInfo) in buildData.Builds) - { - Console.WriteLine($"版本: {version}"); - Console.WriteLine($" 类型: {buildInfo.Type}"); - Console.WriteLine($" 构建类型: {buildInfo.BuildType}"); - Console.WriteLine($" 内部ID: {buildInfo.ID}"); - Console.WriteLine($" 发布日期: {buildInfo.Date}"); - Console.WriteLine($" 变体数量: {buildInfo.Variations.Count}"); - - foreach (var variation in buildInfo.Variations) - { - Console.WriteLine($" 架构: {variation.Arch}"); - Console.WriteLine($" 归档状态: {variation.ArchivalStatus}"); - Console.WriteLine($" 系统要求: {variation.OSBuild}"); - Console.WriteLine($" MD5: {variation.MD5}"); - Console.WriteLine($" 元数据: {string.Join(", ", variation.MetaData)}"); - } - Console.WriteLine(); - } - - } - } -} diff --git a/BedrockLauncher.Core.StartUp/Properties/launchSettings.json b/BedrockLauncher.Core.StartUp/Properties/launchSettings.json deleted file mode 100644 index e526e5e..0000000 --- a/BedrockLauncher.Core.StartUp/Properties/launchSettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "profiles": { - "BedrockLauncher.Core.StartUp": { - "commandName": "Project", - "nativeDebugging": true - } - } -} \ No newline at end of file diff --git a/BedrockLauncher.Core.slnx b/BedrockLauncher.Core.slnx index 702d1d6..b4a7a98 100644 --- a/BedrockLauncher.Core.slnx +++ b/BedrockLauncher.Core.slnx @@ -1,4 +1,4 @@ - + diff --git a/BedrockLauncher.Core/BedrockCore.cs b/BedrockLauncher.Core/BedrockCore.cs index 078aabf..374aa9c 100644 --- a/BedrockLauncher.Core/BedrockCore.cs +++ b/BedrockLauncher.Core/BedrockCore.cs @@ -1,9 +1,14 @@ #pragma warning disable CS8524 +using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; using System.Net; using System.Runtime.InteropServices; using System.Text; +using System.Threading; +using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; using BedrockLauncher.Core.CoreOption; @@ -12,6 +17,7 @@ using BedrockLauncher.Core.Utils; using BedrockLauncher.Core.UwpRegister; using Microsoft.Win32; +using Windows.Foundation.Collections; using Windows.Management.Deployment; using Windows.System; @@ -19,7 +25,6 @@ namespace BedrockLauncher.Core; public class BedrockCore { - public Lazy MultiThreadDownloader = new(); public BedrockCore() { @@ -247,7 +252,7 @@ public async Task StartGameAsync(LaunchOptions options) var info = new ProcessStartInfo(); info.FileName = Path.Combine(options.GameFolder, "Minecraft.Windows.exe"); info.Arguments = options.LaunchArgs; - info.UseShellExecute = true; + info.UseShellExecute = false; info.CreateNoWindow = true; process.StartInfo = info; process.Start(); @@ -257,6 +262,18 @@ public async Task StartGameAsync(LaunchOptions options) if (options.MinecraftBuildType == MinecraftBuildTypeVersion.UWP) { string manifest = Path.Combine(options.GameFolder, "AppxManifest.xml"); + string packageFamily = options.GameType switch + { + MinecraftGameTypeVersion.Release => "Microsoft.MinecraftUWP_8wekyb3d8bbwe", + MinecraftGameTypeVersion.Preview => "Microsoft.MinecraftWindowsBeta_8wekyb3d8bbwe", + MinecraftGameTypeVersion.Beta => "Microsoft.MinecraftWindowsBeta_8wekyb3d8bbwe" + }; + string packageName = options.GameType switch + { + MinecraftGameTypeVersion.Beta => "Microsoft.MinecraftWindowsBeta", + MinecraftGameTypeVersion.Release => "Microsoft.MinecraftUWP", + MinecraftGameTypeVersion.Preview => "Microsoft.MinecraftWindowsBeta" + }; if (!File.Exists(manifest)) { throw new IOException("File doesn't exist"); @@ -265,12 +282,7 @@ public async Task StartGameAsync(LaunchOptions options) bool twice_launch = false; foreach (var package in packageManager.FindPackages()) { - if (package.Id.Name.Equals(options.GameType switch - { - MinecraftGameTypeVersion.Beta => "Microsoft.MinecraftWindowsBeta", - MinecraftGameTypeVersion.Release => "Microsoft.MinecraftUWP", - MinecraftGameTypeVersion.Preview => "Microsoft.MinecraftWindowsBeta" - }, StringComparison.OrdinalIgnoreCase)) + if (package.Id.Name.Equals(packageName, StringComparison.OrdinalIgnoreCase)) { if (Path.GetFullPath(package.InstalledPath) == Path.GetFullPath(options.GameFolder)) { @@ -278,12 +290,7 @@ public async Task StartGameAsync(LaunchOptions options) } } } - bool is_installed = UwpRegister.UwpRegister.IsPackageInstalled(options.GameType switch - { - MinecraftGameTypeVersion.Beta => "Microsoft.MinecraftWindowsBeta", - MinecraftGameTypeVersion.Release => "Microsoft.MinecraftUWP", - MinecraftGameTypeVersion.Preview => "Microsoft.MinecraftWindowsBeta" - }); + bool is_installed = UwpRegister.UwpRegister.IsPackageInstalled(packageName); var config = new DeploymentOptionsConfig(); options.Progress?.Report(LaunchState.Registering); config.CancellationToken = options.CancellationToken.GetValueOrDefault(); @@ -302,64 +309,41 @@ public async Task StartGameAsync(LaunchOptions options) } } - var appDiagnosticInfos = AppDiagnosticInfo.RequestInfoForPackageAsync(options.GameType switch + if (options.Old_VersionLaunching) { - MinecraftGameTypeVersion.Release => "Microsoft.MinecraftUWP_8wekyb3d8bbwe", - MinecraftGameTypeVersion.Preview => "Microsoft.MinecraftWindowsBeta_8wekyb3d8bbwe", - MinecraftGameTypeVersion.Beta => "Microsoft.MinecraftWindowsBeta_8wekyb3d8bbwe" - }).AsTask().Result; - if (appDiagnosticInfos.Count != 0) - { - await appDiagnosticInfos[0].LaunchAsync(); - - Process[] processes = Process.GetProcessesByName("Minecraft.Windows"); - processes.OrderBy(p => p.StartTime); - process = processes.Last(); + var appDiagnosticInfos = AppDiagnosticInfo.RequestInfoForPackageAsync(packageFamily).AsTask().Result; + if (appDiagnosticInfos.Count != 0) + { + await appDiagnosticInfos[0].LaunchAsync(); + } } - } - return process; - } - /// - /// Downloads and validates a game package based on the provided online package options - /// - /// The online package options containing build info, architecture, and download settings - /// The build type version of the downloaded game package - /// Thrown when the specified architecture version is not found - /// Thrown when no available download URI is found - /// Thrown when the downloaded file fails MD5 validation - public async Task GetGamePackage(GameOnlinePackageOptions gamePackage) - { - Architecture devicesArch = gamePackage.Architecture.HasValue ? gamePackage.Architecture.Value : RuntimeInformation.OSArchitecture; - - var find = gamePackage.BuildInfo.Variations.Find((variation => variation.Arch == devicesArch)); - if (find == null) - throw new BedrockCoreException($"Unable to find {devicesArch} Version"); - if (find.MetaData.Count == 0) - throw new BedrockCoreNoAvailbaleVersionUri("There is no available Uri to download"); - await MultiThreadDownloader.Value.DownloadFileAsync( - await GetPackageUri(find.MetaData.Last()), - gamePackage.SaveFilePath, - gamePackage.DownloadThread.HasValue ? gamePackage.DownloadThread.Value : 4, - gamePackage.DownloadProgress ?? new Progress(), - gamePackage.CancellationToken.HasValue ? gamePackage.CancellationToken.Value : default(CancellationToken), - gamePackage.MaxRetryTimes.HasValue ? gamePackage.MaxRetryTimes.Value : 3 - ); - if (Options.IsCheckMD5) - { - var fileMd5 = await ComputeFileMD5.ComputeFileMD5Async(gamePackage.SaveFilePath); - if (fileMd5 != find.MD5) + else { - throw new WebException("Download file failed because of md5 mismatch"); + var options_st = new LauncherOptions + { + TargetApplicationPackageFamilyName = packageFamily + }; + if (options.LaunchArgs != null) + { + await Launcher.LaunchUriAsync(new Uri(options.LaunchArgs), options_st); + } + else + { + await Launcher.LaunchUriAsync(new Uri("minecraft://launch"), options_st); + } + } + Process[] processes = Process.GetProcessesByName("Minecraft.Windows"); + process = processes.OrderBy(p => p.StartTime).Last(); } - return gamePackage.BuildInfo.BuildType; + return process; } /// /// Remove Uwp Minecraft Game /// /// /// - public async Task RemoveUWPGameAsync(MinecraftGameTypeVersion type) + public async Task RemoveUWPGameAsync(MinecraftGameTypeVersion type) { var packageManager = new PackageManager(); @@ -383,13 +367,8 @@ await GetPackageUri(find.MetaData.Last()), return null; } - /// - /// Retrieves the download URI for a package based on its metadata - /// - /// The metadata string which may be a direct URI or an identifier to resolve - /// The resolved download URI as a string - /// Thrown when no available URI is found for the metadata - private static async Task GetPackageUri([NotNull] string metadata) + + private async Task GetPackageUriInside([NotNull] string metadata) { if (metadata.StartsWith("http")) return metadata; @@ -406,4 +385,18 @@ private static async Task GetPackageUri([NotNull] string metadata) throw; } } + /// + /// Retrieves the download URI for a package based on its metadata + /// + /// The resolved download URI as a string + /// Thrown when no available URI is found for the metadata + public async Task GetPackageUri(BuildInfo buildInfo,Architecture devicesArch) + { + var find = buildInfo.Variations.Find((variation => variation.Arch == devicesArch)); + if (find == null) + throw new BedrockCoreException($"Unable to find {devicesArch} Version"); + if (find.MetaData.Count == 0) + throw new BedrockCoreNoAvailbaleVersionUri("There is no available Uri to download"); + return await GetPackageUriInside(find.MetaData.Last()); + } } \ No newline at end of file diff --git a/BedrockLauncher.Core/BedrockCoreException.cs b/BedrockLauncher.Core/BedrockCoreException.cs index 5956c16..30086c5 100644 --- a/BedrockLauncher.Core/BedrockCoreException.cs +++ b/BedrockLauncher.Core/BedrockCoreException.cs @@ -1,4 +1,6 @@ -namespace BedrockLauncher.Core; +using System; + +namespace BedrockLauncher.Core; public class BedrockCoreException : Exception { diff --git a/BedrockLauncher.Core/BedrockLauncher.Core.csproj b/BedrockLauncher.Core/BedrockLauncher.Core.csproj index 6ab6776..3c839a7 100644 --- a/BedrockLauncher.Core/BedrockLauncher.Core.csproj +++ b/BedrockLauncher.Core/BedrockLauncher.Core.csproj @@ -20,11 +20,11 @@ true - 2.0.0-rc.1 + 2.0.0-rc.2-dev - 2.0.0-rc.1 + 2.0.0-rc.2 diff --git a/BedrockLauncher.Core/CoreOption/GameOnlinePackageOptions.cs b/BedrockLauncher.Core/CoreOption/GameOnlinePackageOptions.cs deleted file mode 100644 index 0588c36..0000000 --- a/BedrockLauncher.Core/CoreOption/GameOnlinePackageOptions.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; - -namespace BedrockLauncher.Core.CoreOption -{ - /// - /// Represents the set of options used to configure an online game package operation, including file paths, build - /// information, architecture, download settings, and cancellation support. - /// - /// Use this class to specify parameters when initiating an online game package process, such as where to - /// save files, which architecture to target, and how to handle download progress and cancellation. All required - /// properties must be set before use. - public class GameOnlinePackageOptions - { - /// - /// Gets or sets the file path where data is saved. - /// - public required string SaveFilePath; - /// - /// Specifies the processor architecture, or null if the architecture is unspecified. - /// - public Architecture? Architecture; - /// - /// Gets or sets the build information for the application. - /// - public required BuildInfo BuildInfo; - /// - /// Gets or sets the identifier of the download thread, if available. - /// - public int? DownloadThread; - /// - /// Gets or sets the progress reporter for download operations. - /// - /// Use this property to receive progress updates during a download. The progress reporter receives - /// updates as values, which typically indicate the number of bytes downloaded and the - /// total size, if known. If this property is , no progress updates are reported. - public Progress? DownloadProgress; - /// - /// Gets or sets the optional cancellation token that can be used to cancel the associated operation. - /// - /// If a value is provided, the operation will observe cancellation requests signaled through this - /// token. If null, the operation cannot be cancelled via a token. - public CancellationToken? CancellationToken; - /// - /// Max RetryTimes - /// - public int? MaxRetryTimes; - } -} diff --git a/BedrockLauncher.Core/CoreOption/LaunchOptions.cs b/BedrockLauncher.Core/CoreOption/LaunchOptions.cs index 3736fc8..6242777 100644 --- a/BedrockLauncher.Core/CoreOption/LaunchOptions.cs +++ b/BedrockLauncher.Core/CoreOption/LaunchOptions.cs @@ -44,7 +44,10 @@ public class LaunchOptions /// Gets or sets the progress reporter for package registration operations /// public IProgress? RegisterProgress; - //public bool OpenConsole; + /// + /// Launching for old version + /// + public bool Old_VersionLaunching = false; } /// diff --git a/BedrockLauncher.Core/Downloader/MultiThreadDownloader.cs b/BedrockLauncher.Core/Downloader/MultiThreadDownloader.cs deleted file mode 100644 index 208f2f3..0000000 --- a/BedrockLauncher.Core/Downloader/MultiThreadDownloader.cs +++ /dev/null @@ -1,250 +0,0 @@ -using System; -using System.IO; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using System.Collections.Generic; - -public enum DownloadStage -{ - Downloading, - Merging, - Merged -} - -public class DownloadProgress -{ - public double Progress { get; set; } - public long FinishedBytes { get; set; } - public long TotalBytes { get; set; } - public double Speed { get; set; } - public DownloadStage Phase { get; set; } -} - -public class MultiThreadDownloader -{ - private readonly HttpClient _client = new HttpClient(); - - /// - /// Multithreaded downloader with progress, speed, retry and cleanup temp files. - /// - public async Task DownloadFileAsync( - string url, - string outputPath, - int threadCount = 4, - IProgress? progress = null, - CancellationToken cancellationToken = default, - int maxRetry = 3, - int retryDelayMs = 2000) - { - var tempFiles = new List(); - try - { - var headResponse = await _client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url), cancellationToken); - headResponse.EnsureSuccessStatusCode(); - long totalBytes = headResponse.Content.Headers.ContentLength ?? throw new Exception("Content-Length header not found"); - if (headResponse.Headers.AcceptRanges == null || !headResponse.Headers.AcceptRanges.Contains("bytes")) - throw new NotSupportedException("Server does not support range downloads."); - - long chunkSize = totalBytes / threadCount; - long totalRead = 0; - long mergedRead = 0; - object progressLock = new object(); - - DownloadStage phase = DownloadStage.Downloading; - long lastTotal = 0; - DateTime lastTick = DateTime.UtcNow; - double lastSpeed = 0; - - var downloadTasks = new List(); - var sliceTotals = new long[threadCount]; - - var reportTask = Task.Run(async () => - { - while (true) - { - await Task.Delay(500, cancellationToken); - - long currentFinished, currentTotal; - DownloadStage currPhase; - lock (progressLock) - { - if (phase == DownloadStage.Downloading) - { - currentFinished = 0; - for (int j = 0; j < threadCount; j++) currentFinished += sliceTotals[j]; - } - else - { - currentFinished = Math.Min(totalRead + mergedRead, totalBytes); - } - currentTotal = totalBytes; - currPhase = phase; - } - double speed = 0; - var now = DateTime.UtcNow; - if ((now - lastTick).TotalSeconds > 0.1) - { - speed = (currentFinished - lastTotal) / (now - lastTick).TotalSeconds; - lastTick = now; - lastTotal = currentFinished; - lastSpeed = speed; - } - else - { - speed = lastSpeed; - } - double prog = Math.Min((double)currentFinished / Math.Max(1, currentTotal), 1.0); - - progress?.Report(new DownloadProgress - { - Progress = prog, - FinishedBytes = currentFinished, - TotalBytes = currentTotal, - Speed = speed, - Phase = currPhase - }); - - if (currPhase == DownloadStage.Merged) - break; - } - }, cancellationToken); - - for (int i = 0; i < threadCount; i++) - { - int partIdx = i; - long from = chunkSize * partIdx; - long to = (partIdx == threadCount - 1) ? totalBytes - 1 : (chunkSize * (partIdx + 1)) - 1; - string tempFile = Path.GetTempFileName(); - tempFiles.Add(tempFile); - - downloadTasks.Add(Task.Run(async () => - { - await DownloadRangeToFileWithRetryAsync( - url, from, to, tempFile, cancellationToken, - onRead: bytesRead => - { - lock (progressLock) - { - sliceTotals[partIdx] += bytesRead; - } - }, - maxRetry: maxRetry, - retryDelayMs: retryDelayMs - ); - }, cancellationToken)); - } - - await Task.WhenAll(downloadTasks); - - lock (progressLock) - { - totalRead = 0; - for (int i = 0; i < threadCount; i++) totalRead += sliceTotals[i]; - phase = DownloadStage.Merging; - lastTick = DateTime.UtcNow; - lastTotal = 0; - mergedRead = 0; - lastSpeed = 0; - } - - using (var output = new FileStream(outputPath, FileMode.Create, FileAccess.Write, FileShare.None)) - { - foreach (var tempFile in tempFiles) - { - using (var input = new FileStream(tempFile, FileMode.Open, FileAccess.Read)) - { - byte[] buffer = new byte[81920]; - int read; - while ((read = await input.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0) - { - await output.WriteAsync(buffer, 0, read, cancellationToken); - lock (progressLock) { mergedRead += read; } - } - } - File.Delete(tempFile); - } - } - - lock (progressLock) - { - phase = DownloadStage.Merged; - } - progress?.Report(new DownloadProgress - { - Progress = 1.0, - FinishedBytes = totalBytes, - TotalBytes = totalBytes, - Speed = 0, - Phase = phase - }); - - await reportTask; - } - catch (OperationCanceledException) - { - foreach (var file in tempFiles) - { - try { if (File.Exists(file)) File.Delete(file); } catch { } - } - throw; - } - catch - { - foreach (var file in tempFiles) - { - try { if (File.Exists(file)) File.Delete(file); } catch { } - } - throw; - } - } - - private async Task DownloadRangeToFileWithRetryAsync( - string url, long from, long to, string tempFile, CancellationToken cancellationToken, - Action? onRead = null, int maxRetry = 3, int retryDelayMs = 2000) - { - int attempt = 0; - Exception? lastException = null; - - while (attempt < maxRetry) - { - try - { - if (attempt > 0 && File.Exists(tempFile)) - File.Delete(tempFile); - - await DownloadRangeToFileAsync(url, from, to, tempFile, cancellationToken, onRead); - return; - } - catch (OperationCanceledException) { throw; } - catch (Exception ex) when (ex is IOException || ex is HttpRequestException) - { - lastException = ex; - attempt++; - if (attempt < maxRetry) - await Task.Delay(retryDelayMs, cancellationToken); - } - } - throw new Exception($"Part download failed (from:{from} to:{to}), retried {maxRetry} times.", lastException); - } - - private async Task DownloadRangeToFileAsync( - string url, long from, long to, string tempFile, CancellationToken cancellationToken, Action? onRead = null) - { - var request = new HttpRequestMessage(HttpMethod.Get, url); - request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(from, to); - var response = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); - response.EnsureSuccessStatusCode(); - - using var src = await response.Content.ReadAsStreamAsync(cancellationToken); - using var fs = new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None); - - byte[] buffer = new byte[81920]; - int read; - while ((read = await src.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0) - { - await fs.WriteAsync(buffer, 0, read, cancellationToken); - onRead?.Invoke(read); - } - } -} \ No newline at end of file diff --git a/BedrockLauncher.Core/MinecraftVersion.cs b/BedrockLauncher.Core/MinecraftVersion.cs index 60088ec..5fae9f4 100644 --- a/BedrockLauncher.Core/MinecraftVersion.cs +++ b/BedrockLauncher.Core/MinecraftVersion.cs @@ -1,4 +1,5 @@ #pragma warning disable CS8509 +using System; using System.Runtime.InteropServices; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/BedrockLauncher.Core/VersionJsons/VersionsHelper.cs b/BedrockLauncher.Core/VersionJsons/VersionsHelper.cs index d307399..eb5d137 100644 --- a/BedrockLauncher.Core/VersionJsons/VersionsHelper.cs +++ b/BedrockLauncher.Core/VersionJsons/VersionsHelper.cs @@ -1,4 +1,7 @@ -using System.Text.Json; +using System.Net.Http; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; using BedrockLauncher.Core.SoureGenerate; namespace BedrockLauncher.Core.VersionJsons; diff --git a/BedrockLauncher.Core.StartUp/BedrockLauncher.Core.StartUp.csproj b/CoreTest/CoreTest.csproj similarity index 60% rename from BedrockLauncher.Core.StartUp/BedrockLauncher.Core.StartUp.csproj rename to CoreTest/CoreTest.csproj index d878cec..49ed5c8 100644 --- a/BedrockLauncher.Core.StartUp/BedrockLauncher.Core.StartUp.csproj +++ b/CoreTest/CoreTest.csproj @@ -1,16 +1,22 @@  - Exe net10.0-windows10.0.19041.0 + latest enable enable - true - true + + + + + + + + diff --git a/CoreTest/InstallTest.cs b/CoreTest/InstallTest.cs new file mode 100644 index 0000000..95ed0f9 --- /dev/null +++ b/CoreTest/InstallTest.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Windows.Management.Deployment; +using BedrockLauncher.Core; +using BedrockLauncher.Core.CoreOption; +using BedrockLauncher.Core.VersionJsons; + +namespace CoreTest +{ + [TestClass] + public sealed class InstallTest + { + [TestMethod] + public void Test() + { + var bedrockCore = new BedrockCore(); + bedrockCore.InitAsync().Wait(); + var localGamePackageOptions = new LocalGamePackageOptions() + { + DeployProgress = (new Progress((progress => + { + Console.WriteLine(progress.percentage); + }))), + Type = MinecraftBuildTypeVersion.UWP, + GameTypeVersion = MinecraftGameTypeVersion.Release, + InstallDstFolder = Path.GetFullPath("./Test5"), + GameName = "8899", + FileFullPath = @"D:\Windows11\Download\Microsoft.MinecraftUWP_1.19.8301.0_x64__8wekyb3d8bbwe.Appx" + }; + bedrockCore.InstallPackageAsync(localGamePackageOptions).Wait(); + } + } +} diff --git a/CoreTest/LaunchTest.cs b/CoreTest/LaunchTest.cs new file mode 100644 index 0000000..0c427be --- /dev/null +++ b/CoreTest/LaunchTest.cs @@ -0,0 +1,23 @@ +using BedrockLauncher.Core; +using BedrockLauncher.Core.CoreOption; + +namespace CoreTest; + +[TestClass] +public class LaunchTest +{ + [TestMethod] + public void Test() + { + var bedrockCore = new BedrockCore(); + bedrockCore.InitAsync().Wait(); + var launchOptions = new LaunchOptions() + { + GameFolder = Path.GetFullPath("C:\\Users\\Administrator\\AppData\\Roaming\\RoundStudio\\BedrockBoot\\Bedrock_Data\\bedrock_versions\\1.21.120202"), + MinecraftBuildType = MinecraftBuildTypeVersion.UWP, + GameType = MinecraftGameTypeVersion.Preview, + LaunchArgs = "minecraft://creator/?Editor=true" + }; + bedrockCore.StartGameAsync(launchOptions).Wait(); + } +} diff --git a/CoreTest/MSTestSettings.cs b/CoreTest/MSTestSettings.cs new file mode 100644 index 0000000..aaf278c --- /dev/null +++ b/CoreTest/MSTestSettings.cs @@ -0,0 +1 @@ +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] diff --git a/CoreTest/UriGetTest.cs b/CoreTest/UriGetTest.cs new file mode 100644 index 0000000..00208cc --- /dev/null +++ b/CoreTest/UriGetTest.cs @@ -0,0 +1,19 @@ +using System.Runtime.InteropServices; +using BedrockLauncher.Core; +using BedrockLauncher.Core.VersionJsons; + +namespace CoreTest; + +[TestClass] +public class UriGetTest +{ + [TestMethod] + public void Test() + { + var bedrockCore = new BedrockCore(); + bedrockCore.InitAsync().Wait(); + var buildDatabaseAsync = VersionsHelper.GetBuildDatabaseAsync("https://data.mcappx.com/v2/bedrock.json").Result; + var result = bedrockCore.GetPackageUri(buildDatabaseAsync.Builds["1.21.114"],Architecture.X64).Result; + Console.WriteLine(result); + } +}