♿ 👌 导出整合包改用 Loader

This commit is contained in:
youzi-3222
2025-01-17 14:02:08 +08:00
parent 08ad8e6682
commit 74a9d18fc5
2 changed files with 68 additions and 32 deletions
@@ -1,6 +1,7 @@
Imports System.IO.Compression Imports System.IO.Compression
Imports System.Linq.Expressions Imports System.Linq.Expressions
Imports NAudio.Wave.SampleProviders Imports NAudio.Wave.SampleProviders
Imports PCL.ModLoader
Public Module ModModpack Public Module ModModpack
@@ -951,23 +952,11 @@ Retry:
End Sub End Sub
End Class End Class
''' <summary> ''' <summary>
''' 导出整合包。不阻塞。 ''' 导出整合包,返回是否成功。
''' </summary> ''' </summary>
Public Sub ModpackExport(Options As ExportOptions) Public Function ModpackExport(Task As LoaderTask(Of ExportOptions, Boolean)) As Boolean
Hint("正在导出……") If Task.Input.IncludePCL Then Return ExportCompressed(Task)
RunInNewThread( Return ExportModrinth(Task)
Sub()
If ModpackExportBlocking(Options) Then
Hint("导出成功!", HintType.Finish)
OpenExplorer($"/select,""{Options.Dest}""")
End If
End Sub, "Modpack Export")
End Sub
Private Function ModpackExportBlocking(Options As ExportOptions) As Boolean
If Options.IncludePCL Then
Return ExportCompressed(Options.Version, Options.Dest, Options.Additional, Options.Name, Options.VerID, Options.PCLSetupGlobal)
End If
Return ExportModrinth(Options.Version, Options.Dest, Options.Additional, Options.Name, Options.VerID)
End Function End Function
#Region "冗余" #Region "冗余"
@@ -1007,17 +996,22 @@ Retry:
Next Next
Return False Return False
End Function End Function
#End Region
#End Region
#Region "不同类型整合包的导出方法" #Region "不同类型整合包的导出方法"
Private Function ExportModrinth(Version As McVersion, DestPath As String, Additional As String(), Name As String, VerID As String) As Boolean Private Function ExportModrinth(Task As LoaderTask(Of ExportOptions, Boolean)) As Boolean
Try Try
Log($"[Export] 导出整合包(Modrinth):{Version.Path} -> {DestPath},额外版本文件 {If(Additional Is Nothing OrElse Not Additional.Any, "不导出", Additional.Join(", "))}") Dim Version = Task.Input.Version
Dim DestPath = Task.Input.Dest
Dim Additional = Task.Input.Additional
Dim Name = Task.Input.Name
Dim VerID = Task.Input.VerID
Log($"[Export] 导出整合包(Modrinth):{Version.Path} -> {DestPath},额外版本文件 {Additional.Count} 个")
Dim tempDir As String = $"{ExpTempDir}{GetUuid()}\" Dim tempDir As String = $"{ExpTempDir}{GetUuid()}\"
Log($"[Export] 缓存文件夹:{tempDir}") Log($"[Export] 缓存文件夹:{tempDir}")
Directory.CreateDirectory(tempDir) Directory.CreateDirectory(tempDir)
'步骤 1:从 Modrinth 获取 Mod 工程信息,得到 URL #Region "0.04-0.40:从 Modrinth 获取 Mod 工程信息,得到 URL"
Dim Mods As New Dictionary(Of String, McMod) Dim Mods As New Dictionary(Of String, McMod)
If Directory.Exists(Version.Path & "mods\") Then If Directory.Exists(Version.Path & "mods\") Then
For Each m In Directory.EnumerateFiles(Version.Path & "mods\") For Each m In Directory.EnumerateFiles(Version.Path & "mods\")
@@ -1031,24 +1025,29 @@ Retry:
Dim Failed = Mods.ToArray().ToDictionary(Function(a) a.Key, Function(a) a.Value) '获取失败的 Mod Dim Failed = Mods.ToArray().ToDictionary(Function(a) a.Key, Function(a) a.Value) '获取失败的 Mod
Dim ModrinthHashes = Mods.Select(Function(m) m.Value.ModrinthHash).ToList() Dim ModrinthHashes = Mods.Select(Function(m) m.Value.ModrinthHash).ToList()
If Mods.Count = 0 Then GoTo JumpMod If Mods.Count = 0 Then GoTo JumpMod
Dim ModrinthVersion = CType(GetJson(NetRequestRetry("https://api.modrinth.com/v2/version_files", "POST", Dim ModrinthRaw = CType(GetJson(NetRequestRetry("https://api.modrinth.com/v2/version_files", "POST",
$"{{""hashes"": [""{ModrinthHashes.Join(""",""")}""], ""algorithm"": ""sha1""}}", "application/json")), JObject) $"{{""hashes"": [""{ModrinthHashes.Join(""",""")}""], ""algorithm"": ""sha1""}}", "application/json")), JObject)
Log($"[Export] 从 Modrinth 获取到 {ModrinthVersion.Count} 个本地 Mod 的对应信息") Log($"[Export] 从 Modrinth 获取到 {ModrinthRaw.Count} 个本地 Mod 的对应信息")
Task.Progress = 0.35
For Each Entry In Mods For Each Entry In Mods
If (Not ModrinthVersion.ContainsKey(Entry.Value.ModrinthHash)) OrElse If (Not ModrinthRaw.ContainsKey(Entry.Value.ModrinthHash)) OrElse
(ModrinthVersion(Entry.Value.ModrinthHash)("files")(0)("hashes")("sha1") <> Entry.Value.ModrinthHash) Then (ModrinthRaw(Entry.Value.ModrinthHash)("files")(0)("hashes")("sha1") <> Entry.Value.ModrinthHash) Then
Continue For Continue For
End If End If
Failed.Remove(Entry.Key) Failed.Remove(Entry.Key)
ModrinthMapping.Add(Entry.Key, ModrinthVersion(Entry.Value.ModrinthHash)("files")(0)) ModrinthMapping.Add(Entry.Key, ModrinthRaw(Entry.Value.ModrinthHash)("files")(0))
Next Next
Task.Progress = 0.4
#End Region
'步骤 2:从 CurseForge 继续获取 #Region "0.40-0.80:从 CurseForge 继续获取"
Dim CurseForgeHashes = Mods.Select(Function(m) m.Value.CurseForgeHash).ToList() Dim CurseForgeHashes = Mods.Select(Function(m) m.Value.CurseForgeHash).ToList()
Dim CurseForgeRaw = CType(CType(GetJson(NetRequestRetry("https://api.curseforge.com/v1/fingerprints/432/", "POST", Dim CurseForgeRaw = CType(CType(GetJson(NetRequestRetry("https://api.curseforge.com/v1/fingerprints/432/", "POST",
$"{{""fingerprints"": [{CurseForgeHashes.Join(",")}]}}", "application/json")), JObject)("data")("exactMatches"), JContainer) $"{{""fingerprints"": [{CurseForgeHashes.Join(",")}]}}", "application/json")), JObject)("data")("exactMatches"), JContainer)
Log($"[Export] 从 CurseForge 获取到 {CurseForgeRaw.Count} 个本地 Mod 的对应信息") Log($"[Export] 从 CurseForge 获取到 {CurseForgeRaw.Count} 个本地 Mod 的对应信息")
Task.Progress = 0.7
For Each m In CurseForgeRaw For Each m In CurseForgeRaw
Dim hash As String = "" Dim hash As String = ""
For Each h In m("file")("hashes") '获取 Modrinth Hash For Each h In m("file")("hashes") '获取 Modrinth Hash
@@ -1069,9 +1068,11 @@ Retry:
End If End If
Next Next
Next Next
Task.Progress = 0.8
#End Region
JumpMod: JumpMod:
'步骤 3:合并下载链接,写入 Json 文件 #Region "0.80-0.90:合并下载链接,写入 Json 文件"
'获取作为检查目标的加载器和版本 '获取作为检查目标的加载器和版本
Dim ModLoaders = GetTargetModLoaders() Dim ModLoaders = GetTargetModLoaders()
Dim McVersion = Version.Version.McName Dim McVersion = Version.Version.McName
@@ -1085,6 +1086,8 @@ JumpMod:
BothUrls.Add(modrinth.Key, {modrinth.Value("url"), curseforge("downloadUrl")}) BothUrls.Add(modrinth.Key, {modrinth.Value("url"), curseforge("downloadUrl")})
End If End If
Next Next
Task.Progress = 0.83
Dim files As New JArray Dim files As New JArray
For Each m In ModrinthMapping For Each m In ModrinthMapping
files.Add(New JObject From { files.Add(New JObject From {
@@ -1106,6 +1109,7 @@ JumpMod:
}) })
End If End If
Next Next
Task.Progress = 0.87
Dim depend As New JObject From {{"minecraft", McVersion}} Dim depend As New JObject From {{"minecraft", McVersion}}
If Version.Version.HasForge Then depend.Add("forge", Version.Version.ForgeVersion) If Version.Version.HasForge Then depend.Add("forge", Version.Version.ForgeVersion)
@@ -1123,11 +1127,14 @@ JumpMod:
} }
File.WriteAllText(tempDir & "modrinth.index.json", json.ToString) File.WriteAllText(tempDir & "modrinth.index.json", json.ToString)
Task.Progress = 0.9
#End Region
'步骤 4:将获取不到的保存到 overrides 目录 #Region "0.90-0.99:将其余文件保存到 overrides 目录"
For Each m In Failed For Each m In Failed
CopyFile(m.Value.Path, tempDir & "overrides\mods\" & m.Value.FileName) CopyFile(m.Value.Path, tempDir & "overrides\mods\" & m.Value.FileName)
Next Next
Task.Progress = 0.92
'额外文件 '额外文件
For Each p In Additional For Each p In Additional
@@ -1138,6 +1145,8 @@ JumpMod:
CopyFile(p, $"{tempDir}overrides\{relative}") CopyFile(p, $"{tempDir}overrides\{relative}")
End If End If
Next Next
Task.Progress = 0.99
#End Region
If File.Exists(DestPath) Then File.Delete(DestPath) '选择文件的时候已经确认了要替换 If File.Exists(DestPath) Then File.Delete(DestPath) '选择文件的时候已经确认了要替换
ZipFile.CreateFromDirectory(tempDir, DestPath) ZipFile.CreateFromDirectory(tempDir, DestPath)
@@ -1148,15 +1157,24 @@ JumpMod:
Return False Return False
End Try End Try
End Function End Function
Private Function ExportCompressed(Version As McVersion, DestPath As String, Additional As String(), Name As String, VerID As String, PCLSetupGlobal As Boolean) As Boolean Private Function ExportCompressed(Task As LoaderTask(Of ExportOptions, Boolean)) As Boolean
Try Try
Dim Version = Task.Input.Version
Dim DestPath = Task.Input.Dest
Dim Additional = Task.Input.Additional
Dim Name = Task.Input.Name
Dim VerID = Task.Input.VerID
Dim PCLSetupGlobal = Task.Input.PCLSetupGlobal
Log($"[Export] 导出整合包(含启动器):{Version.Path} -> {DestPath},额外版本文件 {Additional.Count} 个,全局设置 {If(PCLSetupGlobal, "导出", "不导出")}") Log($"[Export] 导出整合包(含启动器):{Version.Path} -> {DestPath},额外版本文件 {Additional.Count} 个,全局设置 {If(PCLSetupGlobal, "导出", "不导出")}")
Dim tempDir As String = $"{ExpTempDir}{GetUuid()}\" Dim tempDir As String = $"{ExpTempDir}{GetUuid()}\"
Log($"[Export] 最终压缩包的缓存文件夹:{tempDir}") Log($"[Export] 最终压缩包的缓存文件夹:{tempDir}")
Directory.CreateDirectory(tempDir) Directory.CreateDirectory(tempDir)
Task.Progress = 0.04
Log("[Export] 开始导出 Modrinth 整合包") Log("[Export] 开始导出 Modrinth 整合包")
ExportModrinth(Version, $"{tempDir}modpack.mrpack", Additional, Name, VerID) Task.Input.Dest = $"{tempDir}modpack.mrpack"
ExportModrinth(Task)
Log($"[Export] 正在复制 PCL 本体") Log($"[Export] 正在复制 PCL 本体")
CopyFile(PathWithName, tempDir & GetFileNameFromPath(PathWithName)) CopyFile(PathWithName, tempDir & GetFileNameFromPath(PathWithName))
@@ -313,8 +313,26 @@
If String.IsNullOrEmpty(c.Tag) Then Continue For If String.IsNullOrEmpty(c.Tag) Then Continue For
If c.Checked Then contains.Add(PageVersionLeft.Version.Path & c.Tag) If c.Checked Then contains.Add(PageVersionLeft.Version.Path & c.Tag)
Next Next
ModpackExport(New ExportOptions(PageVersionLeft.Version, savePath, CheckIncludePCL.Checked, contains.Distinct.ToArray, '重复任务检查
PCLSetupGlobal:=CheckIncludeSetup.Checked, Name:=TbExportName.Text, VerID:=TbExportVersion.Text)) For Each OngoingLoader In LoaderTaskbar
If OngoingLoader.Name <> $"导出整合包 {PageVersionLeft.Version.Name}" Then Continue For
Hint("正在处理中,请稍候!", HintType.Critical)
Exit Sub
Next
'启动!
Dim Loader As New LoaderTask(Of ExportOptions, Boolean)($"导出整合包 {PageVersionLeft.Version.Name}",
Sub(Task As LoaderTask(Of ExportOptions, Boolean))
Task.Output = ModpackExport(Task)
Task.Progress = 1.0
If Task.Output Then
Hint($"{Task.Name} 成功!", HintType.Finish)
OpenExplorer($"/select,""{Task.Input.Dest}""")
End If
End Sub)
Dim Combo = New LoaderCombo(Of ExportOptions)($"导出整合包 {PageVersionLeft.Version.Name}", {Loader})
Combo.Start(New ExportOptions(PageVersionLeft.Version, savePath, CheckIncludePCL.Checked, contains.Distinct.ToArray,
PCLSetupGlobal:=CheckIncludeSetup.Checked, Name:=TbExportName.Text, VerID:=TbExportVersion.Text))
LoaderTaskbarAdd(Combo)
End Sub End Sub
#End Region #End Region