diff --git a/MinecraftLaunch.BanchTest/MinecraftLaunch.BanchTest.csproj b/MinecraftLaunch.BanchTest/MinecraftLaunch.BanchTest.csproj
index 3f035a6..9adfd8e 100644
--- a/MinecraftLaunch.BanchTest/MinecraftLaunch.BanchTest.csproj
+++ b/MinecraftLaunch.BanchTest/MinecraftLaunch.BanchTest.csproj
@@ -3,7 +3,6 @@
enable
Exe
- true
enable
net8.0
true
diff --git a/MinecraftLaunch.BanchTest/Program.cs b/MinecraftLaunch.BanchTest/Program.cs
index 31df623..9d5fa52 100644
--- a/MinecraftLaunch.BanchTest/Program.cs
+++ b/MinecraftLaunch.BanchTest/Program.cs
@@ -2,25 +2,92 @@
using BenchmarkDotNet.Attributes;
using MinecraftLaunch.Components.Checker;
using MinecraftLaunch.Components.Resolver;
+using MinecraftLaunch.Extensions;
+using MinecraftLaunch.Classes.Interfaces;
+using System.Threading.Tasks.Dataflow;
+using MinecraftLaunch.Utilities;
+using System.Diagnostics;
-var summary = BenchmarkRunner.Run();
+//var summary = BenchmarkRunner.Run();
+
+await new BenchmarkClass().RunTaskParallel();
+Console.ReadKey();
[MemoryDiagnoser]
public class BenchmarkClass {
private readonly ResourceChecker _checker;
- private readonly GameResolver _gameResolver = new("D:\\GamePackages\\.minecraft");
+ private readonly GameResolver _gameResolver = new("C:\\Users\\w\\Desktop\\temp\\.minecraft");
public BenchmarkClass() {
- _checker = new(_gameResolver.GetGameEntity("Life in the village"));
+ _checker = new(_gameResolver.GetGameEntity("1.16.5"));
+ _ = _checker.CheckAsync();
}
- //[Benchmark]
- //public Task RunTask() {
- // return _checker.CheckAsync1();
- //}
+ [Benchmark]
+ public ValueTask RunTaskParallel() {
+ return _checker.MissingResources.DownloadResourceParallel();
+ }
[Benchmark]
- public ValueTask RunValueTask() {
- return _checker.CheckAsync();
+ public ValueTask RunParallel() {
+ return _checker.MissingResources.DownloadResourceEntrysAsync();
+ }
+}
+
+public static class Downloader {
+ public static async ValueTask DownloadResourceParallel(this IEnumerable entries) {
+ int completedCount = 0;
+ int totalCount = entries.Count();
+
+ TransformBlock transformBlock = new(x => {
+ return x;
+ }, new ExecutionDataflowBlockOptions {
+ BoundedCapacity = DownloadUitl.DefaultDownloadRequest.MultiThreadsCount,
+ MaxDegreeOfParallelism = DownloadUitl.DefaultDownloadRequest.MultiThreadsCount,
+ });
+
+ ActionBlock actionBlock = new(async x => {
+ await Task.Run(async () => {
+ if (string.IsNullOrEmpty(x.Url)) {
+ return;
+ }
+
+ await DownloadUitl.DownloadAsync(x).AsTask().ContinueWith(task => {
+ if (task.IsFaulted) {
+ if (!x.Verify()) {
+ Debug.WriteLine(task.Exception.Message);
+ return;
+ }
+
+ return;
+ }
+
+ var downloadResult = task.Result;
+ });
+
+ Interlocked.Increment(ref completedCount);
+ });
+ }, new ExecutionDataflowBlockOptions {
+ BoundedCapacity = DownloadUitl.DefaultDownloadRequest.MultiThreadsCount,
+ MaxDegreeOfParallelism = DownloadUitl.DefaultDownloadRequest.MultiThreadsCount,
+ });
+
+ var transformManyBlock = new TransformManyBlock, IDownloadEntry>(chunk => chunk,
+ new ExecutionDataflowBlockOptions());
+
+ var linkOptions = new DataflowLinkOptions {
+ PropagateCompletion = true
+ };
+
+ transformManyBlock.LinkTo(transformBlock, linkOptions);
+ transformBlock.LinkTo(actionBlock, linkOptions);
+
+ if (entries != null) {
+ transformManyBlock.Post(entries);
+ }
+
+ transformManyBlock.Complete();
+ await actionBlock.Completion.WaitAsync(new CancellationToken());
+ return true;
}
}
\ No newline at end of file
diff --git a/MinecraftLaunch.Test/MinecraftLaunch.Simple.csproj b/MinecraftLaunch.Test/MinecraftLaunch.Simple.csproj
index d251f97..c1a7f5c 100644
--- a/MinecraftLaunch.Test/MinecraftLaunch.Simple.csproj
+++ b/MinecraftLaunch.Test/MinecraftLaunch.Simple.csproj
@@ -8,7 +8,6 @@
-
diff --git a/MinecraftLaunch.Test/Program.cs b/MinecraftLaunch.Test/Program.cs
index 1d1845f..9f10490 100644
--- a/MinecraftLaunch.Test/Program.cs
+++ b/MinecraftLaunch.Test/Program.cs
@@ -1,133 +1,199 @@
using MinecraftLaunch;
+using MinecraftLaunch.Extensions;
+using MinecraftLaunch.Classes.Models.Auth;
+using MinecraftLaunch.Classes.Models.Launch;
using MinecraftLaunch.Components.Resolver;
using MinecraftLaunch.Components.Analyzer;
+using MinecraftLaunch.Components.Launcher;
using MinecraftLaunch.Components.Installer;
using MinecraftLaunch.Components.Authenticator;
-using MinecraftLaunch.Extensions;
-using MinecraftLaunch.Classes.Models.Auth;
-MirrorDownloadManager.IsUseMirrorDownloadSource = true;
+MirrorDownloadManager.IsUseMirrorDownloadSource = false;
+
+try {
+ #region ServerPing
+
+ //ServerPingWatcher serverPingWatcher = new(25565, "mc.163mc.cn", 47);
+
+ //serverPingWatcher.ServerConnectionProgressChanged += OnServerConnectionProgressChanged;
+
+ //serverPingWatcher.ServerLatencyChanged += (_, args) => {
+ // Console.WriteLine($"{args.Latency}ms");
+ //};
+
+ //await serverPingWatcher.StartAsync();
+
+ //void OnServerConnectionProgressChanged(object? sender, ProgressChangedEventArgs args) {
+ // Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
+ // if (args.Status == TaskStatus.Canceled) {
+ // serverPingWatcher.ServerConnectionProgressChanged -= OnServerConnectionProgressChanged;
+ // }
+ //}
+
+ #endregion
+
+ #region Forge Install
+
+ //GameResolver gameResolver = new("C:\\Users\\w\\Downloads\\.minecraft");
+
+ //VanlliaInstaller vanlliaInstaller = new(gameResolver, "1.12.2");
+ //vanlliaInstaller.ProgressChanged += (_, args) => {
+ // Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
+ //};
+
+ //await vanlliaInstaller.InstallAsync();
+
+ //Console.WriteLine();
+
+ //ForgeInstaller forgeInstaller = new(gameResolver.GetGameEntity("1.12.2"),
+ // (await ForgeInstaller.EnumerableFromVersionAsync("1.12.2")).First(),
+ // "C:\\Program Files\\Java\\jdk1.8.0_301\\bin\\javaw.exe",
+ // "1.12.2-forge-114514");
+
+ //forgeInstaller.ProgressChanged += (_, args) => {
+ // Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
+ //};
+
+ //await forgeInstaller.InstallAsync();
+
+ #endregion
+
+ #region Fabric Install
+
+ //GameResolver gameResolver = new("C:\\Users\\w\\Downloads\\.minecraft");
+ //VanlliaInstaller vanlliaInstaller = new(gameResolver, "1.16.5");
+ //vanlliaInstaller.ProgressChanged += (_, args) => {
+ // Console.WriteLine($"{args.Progress * 100:0.00}% - {args.Status} - {args.ProgressStatus}");
+ //};
+
+ //await vanlliaInstaller.InstallAsync();
-#region ServerPing
+ //FabricInstaller fabricInstaller = new(gameResolver.GetGameEntity("1.16.5"),
+ // (await FabricInstaller.EnumerableFromVersionAsync("1.16.5")).First(),
+ // "1.16.5-fabric-114514");
-//ServerPingWatcher serverPingWatcher = new(25565, "mc.163mc.cn", 47);
+ //fabricInstaller.ProgressChanged += (_, args) => {
+ // Console.WriteLine($"{args.Progress * 100:0.00}% - {args.Status} - {args.ProgressStatus}");
+ //};
-//serverPingWatcher.ServerConnectionProgressChanged += OnServerConnectionProgressChanged;
+ //await fabricInstaller.InstallAsync();
-//serverPingWatcher.ServerLatencyChanged += (_, args) => {
-// Console.WriteLine($"{args.Latency}ms");
-//};
+ //foreach (var item in gameResolver.GetGameEntitys()){
+ // Console.WriteLine(item.Id);
+ //};
-//await serverPingWatcher.StartAsync();
+ #endregion
-//void OnServerConnectionProgressChanged(object? sender, ProgressChangedEventArgs args) {
-// Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
-// if (args.Status == TaskStatus.Canceled) {
-// serverPingWatcher.ServerConnectionProgressChanged -= OnServerConnectionProgressChanged;
-// }
-//}
+ #region Optifine Install
-#endregion
+ //GameResolver gameResolver = new("C:\\Users\\w\\Downloads\\.minecraft");
-#region Forge Install
+ //VanlliaInstaller vanlliaInstaller = new(gameResolver, "1.12.2", MirrorDownloadManager.Bmcl);
+ //vanlliaInstaller.ProgressChanged += (_, args) => {
+ // Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
+ //};
-//GameResolver gameResolver = new("C:\\Users\\w\\Downloads\\.minecraft");
+ //await vanlliaInstaller.InstallAsync();
-//VanlliaInstaller vanlliaInstaller = new(gameResolver, "1.12.2");
-//vanlliaInstaller.ProgressChanged += (_, args) => {
-// Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
-//};
+ //Console.WriteLine();
-//await vanlliaInstaller.InstallAsync();
+ //OptifineInstaller optifineInstaller = new(gameResolver.GetGameEntity("1.12.2"),
+ // (await OptifineInstaller.EnumerableFromVersionAsync("1.12.2")).First(),
+ // "C:\\Program Files\\Java\\jdk1.8.0_301\\bin\\javaw.exe",
+ // "1.12.2-optifine-114514");
-//Console.WriteLine();
+ //optifineInstaller.ProgressChanged += (_, args) => {
+ // Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
+ //};
-//ForgeInstaller forgeInstaller = new(gameResolver.GetGameEntity("1.12.2"),
-// (await ForgeInstaller.EnumerableFromVersionAsync("1.12.2")).First(),
-// "C:\\Program Files\\Java\\jdk1.8.0_301\\bin\\javaw.exe",
-// "1.12.2-forge-114514");
+ //await optifineInstaller.InstallAsync();
-//forgeInstaller.ProgressChanged += (_, args) => {
-// Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
-//};
+ #endregion
-//await forgeInstaller.InstallAsync();
+ #region Composition Install
-#endregion
+ GameResolver gameResolver = new("C:\\Users\\wxysd\\Desktop\\temp\\.minecraft");
-#region Fabric Install
+ VanlliaInstaller vanlliaInstaller = new(gameResolver, "1.18.2", MirrorDownloadManager.Bmcl);
+ vanlliaInstaller.ProgressChanged += (_, args) => {
+ Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
+ };
-//GameResolver gameResolver = new("C:\\Users\\w\\Downloads\\.minecraft");
-//VanlliaInstaller vanlliaInstaller = new(gameResolver, "1.16.5");
-//vanlliaInstaller.ProgressChanged += (_, args) => {
-// Console.WriteLine($"{args.Progress * 100:0.00}% - {args.Status} - {args.ProgressStatus}");
-//};
+ await vanlliaInstaller.InstallAsync();
-//await vanlliaInstaller.InstallAsync();
+ Console.WriteLine();
-//FabricInstaller fabricInstaller = new(gameResolver.GetGameEntity("1.16.5"),
-// (await FabricInstaller.EnumerableFromVersionAsync("1.16.5")).First(),
-// "1.16.5-fabric-114514");
+ ForgeInstaller forgeInstaller = new(gameResolver.GetGameEntity("1.18.2"),
+ (await ForgeInstaller.EnumerableFromVersionAsync("1.18.2")).First(),
+ "C:\\Users\\wxysd\\AppData\\Roaming\\.minecraft\\runtime\\java-runtime-gamma\\bin\\javaw.exe",
+ "1.18.2-Composition-114514",
+ MirrorDownloadManager.Bmcl);
-//fabricInstaller.ProgressChanged += (_, args) => {
-// Console.WriteLine($"{args.Progress * 100:0.00}% - {args.Status} - {args.ProgressStatus}");
-//};
+ CompositionInstaller compositionInstaller = new(forgeInstaller,
+ "1.18.2-Composition-114514",
+ (await OptifineInstaller.EnumerableFromVersionAsync("1.18.2")).First());
-//await fabricInstaller.InstallAsync();
+ compositionInstaller.ProgressChanged += (_, args) => {
+ Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
+ };
-//foreach (var item in gameResolver.GetGameEntitys()){
-// Console.WriteLine(item.Id);
-//};
+ await compositionInstaller.InstallAsync();
-#endregion
+ #endregion
-#region Optifine Install
+ #region MicrosoftAuthenticator
-//GameResolver gameResolver = new("C:\\Users\\w\\Downloads\\.minecraft");
+ //MicrosoftAuthenticator microsoftAuthenticator = new("Your Client ID");
+ //await microsoftAuthenticator.DeviceFlowAuthAsync(x => {
+ // Console.WriteLine(x.UserCode);
+ // Console.WriteLine(x.VerificationUrl);
+ //});
-//VanlliaInstaller vanlliaInstaller = new(gameResolver, "1.12.2", MirrorDownloadManager.Bmcl);
-//vanlliaInstaller.ProgressChanged += (_, args) => {
-// Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
-//};
+ //var account = await microsoftAuthenticator.AuthenticateAsync();
-//await vanlliaInstaller.InstallAsync();
+ #endregion
-//Console.WriteLine();
+ #region Launch
-//OptifineInstaller optifineInstaller = new(gameResolver.GetGameEntity("1.12.2"),
-// (await OptifineInstaller.EnumerableFromVersionAsync("1.12.2")).First(),
-// "C:\\Program Files\\Java\\jdk1.8.0_301\\bin\\javaw.exe",
-// "1.12.2-optifine-114514");
+ var account = new OfflineAuthenticator("Yang114").Authenticate();
+ var resolver = new GameResolver("C:\\Users\\wxysd\\Desktop\\temp\\.minecraft");
-//optifineInstaller.ProgressChanged += (_, args) => {
-// Console.WriteLine($"{args.Progress * 100:0.00} - {args.Status} - {args.ProgressStatus}");
-//};
+ var config = new LaunchConfig {
+ Account = account,
+ IsEnableIndependencyCore = true,
+ JvmConfig = new(@"C:\Users\wxysd\AppData\Roaming\.minecraft\runtime\java-runtime-gamma\bin\\javaw.exe") {
+ MaxMemory = 1024,
+ }
+ };
-//await optifineInstaller.InstallAsync();
+ Launcher launcher = new(resolver, config);
+ var gameProcessWatcher = await launcher.LaunchAsync("1.18.2-Composition-114514");
-#endregion
+ //获取输出日志
+ gameProcessWatcher.OutputLogReceived += (sender, args) => {
+ Console.WriteLine(args.Original);
+ };
-#region MicrosoftAuthenticator
+ //检测游戏退出
+ gameProcessWatcher.Exited += (sender, args) => {
+ Console.WriteLine("exit");
+ };
-//MicrosoftAuthenticator microsoftAuthenticator = new("Your Client ID");
-//await microsoftAuthenticator.DeviceFlowAuthAsync(x => {
-// Console.WriteLine(x.UserCode);
-// Console.WriteLine(x.VerificationUrl);
-//});
+ #endregion
-//var account = await microsoftAuthenticator.AuthenticateAsync();
+ #region Crash Analysis
-#endregion
+ //GameResolver gameResolver = new("C:\\Users\\w\\Desktop\\总整包\\MC\\mc启动器\\BakaXL\\.minecraft");
-#region Crash Analysis
-//GameResolver gameResolver = new("C:\\Users\\w\\Desktop\\总整包\\MC\\mc启动器\\BakaXL\\.minecraft");
+ var crashAnalyzer = new GameCrashAnalyzer(gameResolver.GetGameEntity("1.18.2-Composition-114514"), true);
+ var reports = crashAnalyzer.AnalysisLogs();
-//var crashAnalyzer = new GameCrashAnalyzer(gameResolver.GetGameEntity("1.20.1"), true);
-//var reports = crashAnalyzer.AnalysisLogs();
+ foreach (var report in reports) {
+ Console.WriteLine(report);
+ }
-//foreach (var report in reports) {
-// Console.WriteLine(report);
-//}
-#endregion
+ #endregion
+} catch (Exception) {
+}
Console.ReadKey();
\ No newline at end of file
diff --git a/MinecraftLaunch/Components/Installer/CompositionInstaller.cs b/MinecraftLaunch/Components/Installer/CompositionInstaller.cs
new file mode 100644
index 0000000..ff8329b
--- /dev/null
+++ b/MinecraftLaunch/Components/Installer/CompositionInstaller.cs
@@ -0,0 +1,78 @@
+
+using MinecraftLaunch.Classes.Models.Event;
+using MinecraftLaunch.Classes.Models.Game;
+using MinecraftLaunch.Classes.Models.Install;
+using MinecraftLaunch.Extensions;
+
+namespace MinecraftLaunch.Components.Installer;
+
+///
+/// 复合安装器
+///
+public sealed class CompositionInstaller : InstallerBase {
+ private readonly string _customId;
+ private readonly InstallerBase _installerBase;
+ private readonly OptiFineInstallEntity _entity;
+
+ ///
+ /// 自定义下载进度计算表达式
+ ///
+ public override Func CalculateExpression { get; set; } = x => x.ToPercentage(0.0d, 0.8d);
+
+ public override GameEntry InheritedFrom { get; }
+
+ public CompositionInstaller(InstallerBase installerBase, string customId, OptiFineInstallEntity entity = default) {
+ if (installerBase is NeoForgeInstaller or QuiltInstaller) {
+ throw new ArgumentException("选择的安装器类型不支持复合安装");
+ }
+
+ _entity = entity;
+ _customId = customId;
+ _installerBase = installerBase;
+
+ InheritedFrom = _installerBase.InheritedFrom;
+ }
+
+ public override async ValueTask InstallAsync() {
+ _installerBase.ProgressChanged += OnProgressChanged;
+ await _installerBase.InstallAsync();
+
+ if (_entity is null) {
+ CalculateExpression = null;
+ ReportProgress(1.0d, "Installation is complete", TaskStatus.RanToCompletion);
+ ReportCompleted();
+ return true;
+ }
+
+ ReportProgress(0.8d, "Start installing the sub loader", TaskStatus.WaitingToRun);
+
+ string downloadUrl = $"https://bmclapi2.bangbang93.com/optifine/{_entity.McVersion}/{_entity.Type}/{_entity.Patch}";
+ string packagePath = Path.Combine(Path.Combine(InheritedFrom.GameFolderPath, "versions", _customId, "mods"), _entity.FileName);
+ var request = downloadUrl.ToDownloadRequest(packagePath.ToFileInfo());
+ CalculateExpression = x => x.ToPercentage(0.8d, 1.0d);
+
+ var result = await request.DownloadAsync(x => {
+ ReportProgress(x,
+ "Downloading Optifine installation package",
+ TaskStatus.Running);
+ });
+
+ ReportCompleted();
+
+ if (result) {
+ ReportProgress(1.0d, "Installation is complete", TaskStatus.RanToCompletion);
+ return true;
+ }
+
+ ReportProgress(1.0d, "Installation is complete", TaskStatus.Faulted);
+ return false;
+ }
+
+ private void OnCompleted(object sender, EventArgs e) {
+ ReportCompleted();
+ }
+
+ private void OnProgressChanged(object sender, ProgressChangedEventArgs e) {
+ ReportProgress(e.Progress, e.ProgressStatus, e.Status);
+ }
+}
\ No newline at end of file
diff --git a/MinecraftLaunch/Components/Installer/FabricInstaller.cs b/MinecraftLaunch/Components/Installer/FabricInstaller.cs
index ad157e0..2186982 100644
--- a/MinecraftLaunch/Components/Installer/FabricInstaller.cs
+++ b/MinecraftLaunch/Components/Installer/FabricInstaller.cs
@@ -8,9 +8,10 @@
namespace MinecraftLaunch.Components.Installer;
public sealed class FabricInstaller(GameEntry inheritedFrom, FabricBuildEntry entry, string customId = default, MirrorDownloadSource source = default) : InstallerBase {
- private readonly string _customId = customId;
+ private readonly string _customId = customId;
private readonly FabricBuildEntry _fabricBuildEntry = entry;
- private readonly GameEntry _inheritedFrom = inheritedFrom;
+
+ public override GameEntry InheritedFrom => inheritedFrom;
public override async ValueTask InstallAsync() {
/*
@@ -23,7 +24,7 @@ public override async ValueTask InstallAsync() {
var libraries = LibrariesResolver.GetLibrariesFromJsonArray(versionInfoNode
.GetEnumerable("libraries"),
- _inheritedFrom.GameFolderPath);
+ InheritedFrom.GameFolderPath);
/*
* Download dependent resources
@@ -43,7 +44,7 @@ await libraries.DownloadResourceEntrysAsync(source, x => {
}
var id = versionInfoNode.GetString("id");
- var jsonFile = new FileInfo(Path.Combine(_inheritedFrom.GameFolderPath,
+ var jsonFile = new FileInfo(Path.Combine(InheritedFrom.GameFolderPath,
"versions", id, $"{id}.json"));
if (!jsonFile.Directory.Exists) {
diff --git a/MinecraftLaunch/Components/Installer/ForgeInstaller.cs b/MinecraftLaunch/Components/Installer/ForgeInstaller.cs
index 6285b05..f6e251d 100644
--- a/MinecraftLaunch/Components/Installer/ForgeInstaller.cs
+++ b/MinecraftLaunch/Components/Installer/ForgeInstaller.cs
@@ -13,13 +13,15 @@ namespace MinecraftLaunch.Components.Installer;
public sealed class ForgeInstaller(GameEntry inheritedFrom, ForgeInstallEntry installEntry, string javaPath, string customId = default, MirrorDownloadSource mirror = default) : InstallerBase {
private readonly string _customId = customId;
private readonly string _javaPath = javaPath;
- private readonly GameEntry _inheritedFrom = inheritedFrom;
private readonly ForgeInstallEntry _installEntry = installEntry;
private readonly MirrorDownloadSource _mirrorDownloadSource = mirror;
+ public override GameEntry InheritedFrom => inheritedFrom;
+
public override async ValueTask InstallAsync() {
List highVersionForgeProcessors = default;
+
/*
* Download Forge installation package
*/
@@ -60,7 +62,7 @@ await request.DownloadAsync(x => {
var libraries = LibrariesResolver.GetLibrariesFromJsonArray(versionInfoJson
.GetEnumerable("libraries"),
- _inheritedFrom.GameFolderPath).ToList();
+ InheritedFrom.GameFolderPath).ToList();
if (MirrorDownloadManager.IsUseMirrorDownloadSource) {
foreach (var lib in libraries) {
@@ -70,8 +72,8 @@ await request.DownloadAsync(x => {
if (!isLegacyForgeVersion) {
libraries.AddRange(LibrariesResolver.GetLibrariesFromJsonArray(installProfile
- .GetEnumerable("libraries"),
- _inheritedFrom.GameFolderPath));
+ .GetEnumerable("libraries"),
+ InheritedFrom.GameFolderPath));
var highVersionForgeDataDictionary = installProfile
.Select("data")
@@ -87,11 +89,11 @@ await request.DownloadAsync(x => {
var replaceValues = new Dictionary {
{ "{SIDE}", "client" },
- { "{MINECRAFT_JAR}", _inheritedFrom.JarPath.ToPath() },
+ { "{MINECRAFT_JAR}", InheritedFrom.JarPath.ToPath() },
{ "{MINECRAFT_VERSION}", installProfile.GetString("minecraft") },
- { "{ROOT}", _inheritedFrom.GameFolderPath.ToPath() },
+ { "{ROOT}", InheritedFrom.GameFolderPath.ToPath() },
{ "{INSTALLER}", packagePath.ToPath() },
- { "{LIBRARY_DIR}", Path.Combine(_inheritedFrom.GameFolderPath, "libraries").ToPath() }
+ { "{LIBRARY_DIR}", Path.Combine(InheritedFrom.GameFolderPath, "libraries").ToPath() }
};
var replaceProcessorArgs = highVersionForgeDataDictionary.ToDictionary(
@@ -100,7 +102,7 @@ await request.DownloadAsync(x => {
if (!value.StartsWith('[')) {
return value;
}
- return Path.Combine(_inheritedFrom.GameFolderPath,
+ return Path.Combine(InheritedFrom.GameFolderPath,
"libraries",
LibrariesResolver.FormatLibraryNameToRelativePath(value.TrimStart('[').TrimEnd(']')))
.ToPath();
@@ -116,7 +118,7 @@ await request.DownloadAsync(x => {
processor.Args = processor.Args.Select(x => {
if (x.StartsWith("["))
return Path.Combine(
- _inheritedFrom.GameFolderPath,
+ InheritedFrom.GameFolderPath,
"libraries",
LibrariesResolver.FormatLibraryNameToRelativePath(x.TrimStart('[').TrimEnd(']')))
.ToPath();
@@ -144,7 +146,7 @@ await libraries.DownloadResourceEntrysAsync(_mirrorDownloadSource, x => {
* Write information to version json
*/
ReportProgress(0.85d, "Write information to version json", TaskStatus.WaitingToRun);
- string forgeLibsFolder = Path.Combine(_inheritedFrom.GameFolderPath,
+ string forgeLibsFolder = Path.Combine(InheritedFrom.GameFolderPath,
"libraries\\net\\minecraftforge\\forge",
forgeVersion);
@@ -168,7 +170,7 @@ await libraries.DownloadResourceEntrysAsync(_mirrorDownloadSource, x => {
}
var jsonFile = new FileInfo(Path.Combine(
- _inheritedFrom.GameFolderPath,
+ InheritedFrom.GameFolderPath,
"versions",
versionInfoJson.GetString("id"),
$"{versionInfoJson.GetString("id")}.json"));
@@ -194,7 +196,7 @@ await libraries.DownloadResourceEntrysAsync(_mirrorDownloadSource, x => {
foreach (var processor in highVersionForgeProcessors) {
var fileName = Path.Combine(
- _inheritedFrom.GameFolderPath,
+ InheritedFrom.GameFolderPath,
"libraries",
LibrariesResolver.FormatLibraryNameToRelativePath(processor.Jar));
@@ -207,7 +209,7 @@ await libraries.DownloadResourceEntrysAsync(_mirrorDownloadSource, x => {
string classPath = string.Join(Path.PathSeparator.ToString(), new List() { fileName }
.Concat(processor.Classpath.Select(x => Path.Combine(
- _inheritedFrom.GameFolderPath,
+ InheritedFrom.GameFolderPath,
"libraries",
LibrariesResolver.FormatLibraryNameToRelativePath(x)))));
@@ -220,11 +222,11 @@ await libraries.DownloadResourceEntrysAsync(_mirrorDownloadSource, x => {
args.AddRange(processor.Args);
using var process = Process.Start(new ProcessStartInfo(_javaPath) {
- Arguments = string.Join(" ", args),
UseShellExecute = false,
- WorkingDirectory = _inheritedFrom.GameFolderPath,
RedirectStandardError = true,
- RedirectStandardOutput = true
+ RedirectStandardOutput = true,
+ Arguments = string.Join(" ", args),
+ WorkingDirectory = InheritedFrom.GameFolderPath
});
var outputs = new List();
diff --git a/MinecraftLaunch/Components/Installer/InstallerBase.cs b/MinecraftLaunch/Components/Installer/InstallerBase.cs
index 7e68789..6c77d01 100644
--- a/MinecraftLaunch/Components/Installer/InstallerBase.cs
+++ b/MinecraftLaunch/Components/Installer/InstallerBase.cs
@@ -1,13 +1,16 @@
using MinecraftLaunch.Classes.Interfaces;
using MinecraftLaunch.Classes.Models.Event;
+using MinecraftLaunch.Classes.Models.Game;
namespace MinecraftLaunch.Components.Installer;
public abstract class InstallerBase : IInstaller {
public event EventHandler Completed;
-
public event EventHandler ProgressChanged;
+ public abstract GameEntry InheritedFrom { get; }
+ public virtual Func CalculateExpression { get; set; }
+
public abstract ValueTask InstallAsync();
public void ReportCompleted() {
@@ -15,6 +18,6 @@ public void ReportCompleted() {
}
internal virtual void ReportProgress(double progress, string progressStatus, TaskStatus status) {
- ProgressChanged?.Invoke(this, new(status, progress, progressStatus));
+ ProgressChanged?.Invoke(this, new(status, CalculateExpression is null ? progress : CalculateExpression.Invoke(progress), progressStatus));
}
-}
\ No newline at end of file
+}
diff --git a/MinecraftLaunch/Components/Installer/NeoForgeInstaller.cs b/MinecraftLaunch/Components/Installer/NeoForgeInstaller.cs
index a813923..17b15b5 100644
--- a/MinecraftLaunch/Components/Installer/NeoForgeInstaller.cs
+++ b/MinecraftLaunch/Components/Installer/NeoForgeInstaller.cs
@@ -1,7 +1,11 @@
+using MinecraftLaunch.Classes.Models.Game;
+
namespace MinecraftLaunch.Components.Installer;
public sealed class NeoForgeInstaller : InstallerBase {
+ public override GameEntry InheritedFrom => throw new NotImplementedException();
+
public override ValueTask InstallAsync() {
throw new NotImplementedException();
}
diff --git a/MinecraftLaunch/Components/Installer/OptifineInstaller.cs b/MinecraftLaunch/Components/Installer/OptifineInstaller.cs
index cbb6534..40b3044 100644
--- a/MinecraftLaunch/Components/Installer/OptifineInstaller.cs
+++ b/MinecraftLaunch/Components/Installer/OptifineInstaller.cs
@@ -1,28 +1,28 @@
using Flurl.Http;
using System.Text.Json;
-using MinecraftLaunch.Classes.Models.Game;
-using MinecraftLaunch.Classes.Models.Install;
-using MinecraftLaunch.Classes.Models.Download;
-using System;
-using MinecraftLaunch.Extensions;
+using System.Diagnostics;
using System.IO.Compression;
using System.Text.Json.Serialization;
+using MinecraftLaunch.Extensions;
using MinecraftLaunch.Components.Resolver;
-using System.Diagnostics;
+using MinecraftLaunch.Classes.Models.Game;
+using MinecraftLaunch.Classes.Models.Install;
+using MinecraftLaunch.Classes.Models.Download;
namespace MinecraftLaunch.Components.Installer;
-public sealed class OptifineInstaller(GameEntry inheritedFrom,
+public sealed class OptifineInstaller(
+ GameEntry inheritedFrom,
OptiFineInstallEntity installEntry,
string javaPath, string customId = default,
MirrorDownloadSource mirror = default) : InstallerBase {
-
private readonly string _customId = customId;
private readonly string _javaPath = javaPath;
- private readonly GameEntry _inheritedFrom = inheritedFrom;
private readonly OptiFineInstallEntity _installEntry = installEntry;
private readonly MirrorDownloadSource _mirrorDownloadSource = mirror;
+ public override GameEntry InheritedFrom => inheritedFrom;
+
public override async ValueTask InstallAsync() {
/*
* Download Optifine installation package
@@ -74,15 +74,15 @@ await request.DownloadAsync(x => {
minecraftArguments = " --tweakClass optifine.OptiFineTweaker"
};
- var jarFilePath = Path.Combine(_inheritedFrom.GameFolderPath, "versions", jsonEntity.id, $"{jsonEntity.id}.jar");
- var jsonFilePath = Path.Combine(_inheritedFrom.GameFolderPath, "versions", jsonEntity.id, $"{jsonEntity.id}.json");
+ var jarFilePath = Path.Combine(InheritedFrom.GameFolderPath, "versions", jsonEntity.id, $"{jsonEntity.id}.jar");
+ var jsonFilePath = Path.Combine(InheritedFrom.GameFolderPath, "versions", jsonEntity.id, $"{jsonEntity.id}.json");
var launchwrapperFile = Path.Combine(
- _inheritedFrom.GameFolderPath,
+ InheritedFrom.GameFolderPath,
"libraries",
LibrariesResolver.FormatLibraryNameToRelativePath(jsonEntity.libraries[1].Name));
var optifineLibraryPath = Path.Combine(
- _inheritedFrom.GameFolderPath,
+ InheritedFrom.GameFolderPath,
"libraries",
LibrariesResolver.FormatLibraryNameToRelativePath(jsonEntity.libraries[0].Name));
@@ -98,21 +98,21 @@ await request.DownloadAsync(x => {
}));
packageArchive.GetEntry($"launchwrapper-of-{launchwrapper}.jar").ExtractToFile(launchwrapperFile, true);
- File.Copy(_inheritedFrom.JarPath, jarFilePath, true);
+ File.Copy(InheritedFrom.JarPath, jarFilePath, true);
/*
* Running install processor
*/
using var process = Process.Start(new ProcessStartInfo(_javaPath) {
UseShellExecute = false,
- WorkingDirectory = _inheritedFrom.GameFolderPath,
+ WorkingDirectory = InheritedFrom.GameFolderPath,
RedirectStandardError = true,
RedirectStandardOutput = true,
Arguments = string.Join(" ", [
"-cp",
packagePath.ToPath(),
"optifine.Patcher",
- _inheritedFrom.JarPath.ToPath(),
+ InheritedFrom.JarPath.ToPath(),
packagePath.ToPath(),
optifineLibraryPath.ToPath()
])
diff --git a/MinecraftLaunch/Components/Installer/QuiltInstaller.cs b/MinecraftLaunch/Components/Installer/QuiltInstaller.cs
index b94ca76..3ced728 100644
--- a/MinecraftLaunch/Components/Installer/QuiltInstaller.cs
+++ b/MinecraftLaunch/Components/Installer/QuiltInstaller.cs
@@ -11,7 +11,8 @@ namespace MinecraftLaunch.Components.Installer;
public sealed class QuiltInstaller(GameEntry inheritedFrom, QuiltBuildEntry entry, string customId = default, MirrorDownloadSource source = default) : InstallerBase {
private readonly string _customId = customId;
private readonly QuiltBuildEntry _quiltBuildEntry = entry;
- private readonly GameEntry _inheritedFrom = inheritedFrom;
+
+ public override GameEntry InheritedFrom => inheritedFrom;
public override async ValueTask InstallAsync() {
/*
@@ -24,7 +25,7 @@ public override async ValueTask InstallAsync() {
var libraries = LibrariesResolver.GetLibrariesFromJsonArray(versionInfoNode
.GetEnumerable("libraries"),
- _inheritedFrom.GameFolderPath);
+ InheritedFrom.GameFolderPath);
/*
@@ -49,7 +50,7 @@ await libraries.DownloadResourceEntrysAsync(source, x => {
}
var id = versionInfoNode.GetString("id");
- var jsonFile = new FileInfo(Path.Combine(_inheritedFrom.GameFolderPath,
+ var jsonFile = new FileInfo(Path.Combine(InheritedFrom.GameFolderPath,
"versions", id, $"{id}.json"));
if (!jsonFile.Directory.Exists) {
diff --git a/MinecraftLaunch/Components/Installer/VanlliaInstaller.cs b/MinecraftLaunch/Components/Installer/VanlliaInstaller.cs
index ffac1ec..900e6a1 100644
--- a/MinecraftLaunch/Components/Installer/VanlliaInstaller.cs
+++ b/MinecraftLaunch/Components/Installer/VanlliaInstaller.cs
@@ -5,6 +5,7 @@
using MinecraftLaunch.Components.Checker;
using MinecraftLaunch.Classes.Models.Install;
using MinecraftLaunch.Classes.Models.Download;
+using MinecraftLaunch.Classes.Models.Game;
namespace MinecraftLaunch.Components.Installer;
@@ -16,6 +17,8 @@ public sealed class VanlliaInstaller(IGameResolver gameFoloder, string gameId, M
private readonly MirrorDownloadSource _source = source;
private readonly IGameResolver _gameResolver = gameFoloder;
+ public override GameEntry InheritedFrom => throw new NotSupportedException();
+
public override async ValueTask InstallAsync() {
/*
* Check if the specified id exists
diff --git a/MinecraftLaunch/Utilities/DownloadUitl.cs b/MinecraftLaunch/Utilities/DownloadUitl.cs
index bdc34e3..f46efcd 100644
--- a/MinecraftLaunch/Utilities/DownloadUitl.cs
+++ b/MinecraftLaunch/Utilities/DownloadUitl.cs
@@ -17,7 +17,7 @@ public static class DownloadUitl {
public static DownloadRequest DefaultDownloadRequest { get; set; } = new() {
IsPartialContentSupported = true,
FileSizeThreshold = 1024 * 1024 * 3,
- MultiThreadsCount = 64,
+ MultiThreadsCount = 256,
MultiPartsCount = 8
};