From 6c8a7a33b710f765e83807e8c65ebcf5f1307a79 Mon Sep 17 00:00:00 2001 From: youzi-2333 Date: Sun, 28 Jul 2024 22:30:59 +0800 Subject: [PATCH] =?UTF-8?q?:ok=5Fhand:=20:boom:=20=E6=9B=B4=E6=96=B0=20LTC?= =?UTF-8?q?att=20=E7=9A=84=E5=AE=A1=E6=A0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plain Craft Launcher 2/Modules/Base/ModNet.vb | 42 ---------- .../Modules/Minecraft/ModComp.vb | 24 +++--- .../Modules/Minecraft/ModDownload.vb | 76 +++++++++++++++++-- .../Modules/Minecraft/ModMod.vb | 10 +-- .../Pages/PageSetup/PageSetupSystem.xaml | 8 +- .../Pages/PageSetup/PageSetupSystem.xaml.vb | 17 +---- 6 files changed, 89 insertions(+), 88 deletions(-) diff --git a/Plain Craft Launcher 2/Modules/Base/ModNet.vb b/Plain Craft Launcher 2/Modules/Base/ModNet.vb index b3febfe..eaf57a2 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModNet.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModNet.vb @@ -2,45 +2,6 @@ Public Module ModNet -#Region "Mod" - Public Function ModMirrorUrl(Url As String) As String - Select Case Setup.Get("ToolDownloadMod") - Case 0 - Return Url - Case 1 - Return Url.Replace("api.modrinth.com/v2", "mod.mcmirror.top/modrinth"). - Replace("staging-api.modrinth.com/v2", "mod.mcmirror.top/modrinth"). - Replace("cdn.modrinth.com", "mod.mcimirror.top"). - Replace("api.curseforge.com", "mod.mcimirror.top/curseforge"). - Replace("edge.forgecdn.net", "mod.mcimirror.top"). - Replace("mediafilez.forgecdn.net", "mod.mcimirror.top"). - Replace("media.forgecdn.net", "mod.mcimirror.top") - Case Else - Return Url - End Select - End Function - Public Function AllowModMirror(IsModFile As Boolean) - Return Setup.Get("ToolDownloadMod") <> 0 AndAlso (Setup.Get("ToolDownloadModMirror") OrElse Not IsModFile) - End Function - ''' - ''' 请求 CurseForge 或者 Modrinth。会抛出异常。 - ''' - Public Function NetRequestMod(Url As String, Method As String, Data As Object, ContentType As String, - Optional Headers As Dictionary(Of String, String) = Nothing, - Optional IsModFile As Boolean = False) As String - Try - If AllowModMirror(IsModFile) Then - Return NetRequestOnce(Url, Method, Data, ContentType, Timeout:=5000, Headers:=Headers) - Else - Return NetRequestRetry(Url, Method, Data, ContentType, Headers:=Headers) - End If - Catch ex1 As Exception - If Not AllowModMirror(IsModFile) Then Throw ex1 '没机会了,45s 都没有加载完 - Dim retry As Integer = 0 - Return NetRequestOnce(ModMirrorUrl(Url), Method, Data, ContentType, Timeout:=30000, Headers:=Headers) - End Try - End Function -#End Region Public Const NetDownloadEnd As String = ".PCLDownloading" @@ -143,9 +104,6 @@ Retry: Dim RetryCount As Integer = 0 Dim RetryException As Exception = Nothing Dim StartTime As Long = GetTimeTick() - If BackupUrl Is Nothing Then - If ModMirrorUrl(Url) <> Url Then BackupUrl = ModMirrorUrl(Url) - End If Try Retry: Select Case RetryCount diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb index 3f88eb5..12c0bd0 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModComp.vb @@ -947,7 +947,7 @@ Retry: Try '获取工程列表 Log("[Comp] 开始从 CurseForge 获取工程列表:" & CurseForgeUrl) - Dim RequestResult As JObject = NetGetCodeByRequestRetry(CurseForgeUrl, IsJson:=True, Encode:=Encoding.UTF8, BackupUrl:=ModMirrorUrl(CurseForgeUrl)) + Dim RequestResult As JObject = DlModRequest(CurseForgeUrl, IsJson:=True) Task.Progress += 0.2 Dim ProjectList As New List(Of CompProject) For Each JsonEntry As JObject In RequestResult("data") @@ -977,7 +977,7 @@ Retry: Sub() Try Log("[Comp] 开始从 Modrinth 获取工程列表:" & ModrinthUrl) - Dim RequestResult As JObject = NetGetCodeByRequestRetry(ModrinthUrl, IsJson:=True, Encode:=Encoding.UTF8, BackupUrl:=ModMirrorUrl(ModrinthUrl)) + Dim RequestResult As JObject = DlModRequest(ModrinthUrl, IsJson:=True) Task.Progress += 0.2 Dim ProjectList As New List(Of CompProject) For Each JsonEntry As JObject In RequestResult("hits") @@ -1212,7 +1212,7 @@ Retry: ''' 目标本地文件夹,或完整的文件路径。会自动判断类型。 Public Function ToNetFile(LocalAddress As String) As NetFile Dim urls As List(Of String) = DownloadUrls - If AllowModMirror(True) Then urls.AddRange(MirrorUrls) + urls.AddRange(MirrorUrls) Return New NetFile(urls, LocalAddress & If(LocalAddress.EndsWithF("\"), FileName, ""), New FileChecker(Hash:=Hash), UseBrowserUserAgent:=True) End Function @@ -1334,7 +1334,7 @@ Retry: '末尾添加备用镜像 URL MirrorUrls = New List(Of String) For Each u In DownloadUrls - MirrorUrls.Add(ModMirrorUrl(u)) + MirrorUrls.Add(DlSourceModGet(u)) Next End If End Sub @@ -1442,11 +1442,11 @@ Retry: Retry: Dim comp As Object If FromCurseForge Then 'CurseForge - comp = NetGetCodeByRequestRetry("https://api.curseforge.com/v1/mods/" & ProjectId, IsJson:=True, Encode:=Encoding.UTF8) - TargetProject = New CompProject(NetGetCodeByRequestRetry("https://api.curseforge.com/v1/mods/" & ProjectId, IsJson:=True, Encode:=Encoding.UTF8)("data")) + comp = DlModRequest("https://api.curseforge.com/v1/mods/" & ProjectId, IsJson:=True) + TargetProject = New CompProject(DlModRequest("https://api.curseforge.com/v1/mods/" & ProjectId, IsJson:=True)("data")) Else 'Modrinth - comp = NetGetCodeByRequestRetry("https://api.modrinth.com/v2/project/" & ProjectId, IsJson:=True, Encode:=Encoding.UTF8) - TargetProject = New CompProject(NetGetCodeByRequestRetry("https://api.modrinth.com/v2/project/" & ProjectId, IsJson:=True, Encode:=Encoding.UTF8)) + comp = DlModRequest("https://api.modrinth.com/v2/project/" & ProjectId, IsJson:=True) + TargetProject = New CompProject(DlModRequest("https://api.modrinth.com/v2/project/" & ProjectId, IsJson:=True)) End If If comp Is Nothing Then '获取 ("data") 时会报值不能为 null If retryCount > 2 Then Throw New Exception("工程对象获取失败,请等待一段时间后刷新再试!") @@ -1462,13 +1462,13 @@ Retry: If FromCurseForge Then 'CurseForge If TargetProject.Type = CompType.Mod Then 'Mod 使用每个版本最新的文件 - ResultJsonArray = GetJson(NetRequestMod("https://api.curseforge.com/v1/mods/files", "POST", "{""fileIds"": [" & Join(TargetProject.CurseForgeFileIds, ",") & "]}", "application/json"))("data") + ResultJsonArray = GetJson(DlModRequest("https://api.curseforge.com/v1/mods/files", "POST", "{""fileIds"": [" & Join(TargetProject.CurseForgeFileIds, ",") & "]}", "application/json"))("data") Else '否则使用全部文件 - ResultJsonArray = NetGetCodeByRequestRetry($"https://api.curseforge.com/v1/mods/{ProjectId}/files?pageSize=999", Accept:="application/json", IsJson:=True)("data") + ResultJsonArray = NetGetCodeByRequestRetry($"https://api.curseforge.com/v1/mods/{ProjectId}/files?pageSize=999", Accept:="application/json", IsJson:=True, BackupUrl:=DlSourceModGet($"https://api.curseforge.com/v1/mods/{ProjectId}/files?pageSize=999"))("data") End If Else 'Modrinth - ResultJsonArray = NetGetCodeByRequestRetry($"https://api.modrinth.com/v2/project/{ProjectId}/version", Accept:="application/json", IsJson:=True) + ResultJsonArray = NetGetCodeByRequestRetry($"https://api.modrinth.com/v2/project/{ProjectId}/version", Accept:="application/json", IsJson:=True, BackupUrl:=DlSourceModGet($"https://api.modrinth.com/v2/project/{ProjectId}/version")) End If CompFilesCache(ProjectId) = ResultJsonArray.Select(Function(a) New CompFile(a, TargetProject.Type)). Where(Function(a) a.Available).ToList.Distinct(Function(a, b) a.Id = b.Id) 'CurseForge 可能会重复返回相同项(#1330) @@ -1482,7 +1482,7 @@ Retry: Log($"[Comp] {ProjectId} 文件列表中还需要获取信息的前置 Mod:{Join(UndoneDeps, ",")}") Dim Projects As JArray If TargetProject.FromCurseForge Then - Projects = GetJson(NetRequestMod("https://api.curseforge.com/v1/mods", + Projects = GetJson(DlModRequest("https://api.curseforge.com/v1/mods", "POST", "{""modIds"": [" & Join(UndoneDeps, ",") & "]}", "application/json"))("data") Else Projects = NetGetCodeByRequestRetry($"https://api.modrinth.com/v2/projects?ids=[""{Join(UndoneDeps, """,""")}""]", diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb index 08a0400..506ef75 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb @@ -1,4 +1,4 @@ -Imports System.Security.Policy +Imports Newtonsoft Public Module ModDownload @@ -1077,6 +1077,69 @@ Public Module ModDownload #End Region +#Region "DlMod* | Mod 列表 / 信息 / 下载" + Public Function DlModRequest(Url As String, Optional IsJson As Boolean = False) As String + Dim McimUrl As String = DlSourceModGet(Url) + Dim Urls As New List(Of KeyValuePair(Of String, Integer)) + If McimUrl <> Url Then + Select Case Setup.Get("ToolDownloadVersion") + Case 0 + Urls.Add(New KeyValuePair(Of String, Integer)(McimUrl, 30)) + Urls.Add(New KeyValuePair(Of String, Integer)(Url, 60)) + Case 1 + Urls.Add(New KeyValuePair(Of String, Integer)(Url, 5)) + Urls.Add(New KeyValuePair(Of String, Integer)(McimUrl, 35)) + Case Else + Urls.Add(New KeyValuePair(Of String, Integer)(Url, 60)) + Urls.Add(New KeyValuePair(Of String, Integer)(McimUrl, 60)) + End Select + End If + Return DlModRequest(Urls, IsJson:=IsJson) + End Function + Public Function DlModRequest(Url As String, Method As String, Data As String, ContentType As String, + Optional Headers As Dictionary(Of String, String) = Nothing) As String + Dim McimUrl As String = DlSourceModGet(Url) + Dim Urls As New List(Of KeyValuePair(Of String, Integer)) + If McimUrl <> Url Then + Select Case Setup.Get("ToolDownloadVersion") + Case 0 + Urls.Add(New KeyValuePair(Of String, Integer)(McimUrl, 30)) + Urls.Add(New KeyValuePair(Of String, Integer)(Url, 60)) + Case 1 + Urls.Add(New KeyValuePair(Of String, Integer)(Url, 5)) + Urls.Add(New KeyValuePair(Of String, Integer)(McimUrl, 35)) + Case Else + Urls.Add(New KeyValuePair(Of String, Integer)(Url, 60)) + Urls.Add(New KeyValuePair(Of String, Integer)(McimUrl, 60)) + End Select + End If + Return DlModRequest(Urls, Method, Data, ContentType, Headers:=Headers) + End Function + Private Function DlModRequest(Urls As List(Of KeyValuePair(Of String, Integer)), Optional IsJson As Boolean = False) As String + Dim exMessage As String = "" + For Each url In Urls + Try + Return NetGetCodeByDownload(url.Key, Timeout:=url.Value, IsJson:=IsJson) + Catch ex As Exception + exMessage += ex.Message + vbCrLf + End Try + Next + Throw New Exception(exMessage) + End Function + Private Function DlModRequest(Urls As List(Of KeyValuePair(Of String, Integer)), Method As String, Data As String, + ContentType As String, Optional Headers As Dictionary(Of String, String) = Nothing) As String + Dim exMessage As String = "" + For Each url In Urls + Try + Return NetRequestOnce(url.Key, Method, Data, ContentType, Timeout:=url.Value, Headers:=Headers) + Catch ex As Exception + exMessage += ex.Message + vbCrLf + End Try + Next + Throw New Exception(exMessage) + End Function +#End Region + #Region "DlSource | 镜像下载源" Public Function DlSourceResourceGet(MojangBase As String) As String() @@ -1094,18 +1157,15 @@ Public Module ModDownload MojangBase } End Function - Public Function DlSourceCfOrMrGet(CfMrBase As String) As String() - If CfMrBase Is Nothing Then Throw New Exception("无对应的 Mod 下载地址") - Return { - CfMrBase.Replace("api.modrinth.com/v2", "mod.mcmirror.top/modrinth") _ + Public Function DlSourceModGet(CfMrBase As String) As String + 'If CfMrBase Is Nothing Then Throw New Exception("无对应的 Mod 下载地址") + Return CfMrBase.Replace("api.modrinth.com/v2", "mod.mcmirror.top/modrinth") _ .Replace("staging-api.modrinth.com/v2", "mod.mcmirror.top/modrinth") _ .Replace("cdn.modrinth.com", "mod.mcimirror.top") _ .Replace("api.curseforge.com", "mod.mcimirror.top/curseforge") _ .Replace("edge.forgecdn.net", "mod.mcimirror.top") _ .Replace("mediafilez.forgecdn.net", "mod.mcimirror.top") _ - .Replace("media.forgecdn.net", "mod.mcimirror.top"), - CfMrBase - } + .Replace("media.forgecdn.net", "mod.mcimirror.top") End Function Public Function DlSourceLauncherOrMetaGet(MojangBase As String) As String() diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb index 0acd2f3..ddb4bf3 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb @@ -952,7 +952,7 @@ Finished: Try '步骤 1:获取 Hash 与对应的工程 ID Dim ModrinthHashes = Mods.Select(Function(m) m.ModrinthHash).ToList() - Dim ModrinthVersion = CType(GetJson(NetRequestMod("https://api.modrinth.com/v2/version_files", "POST", + Dim ModrinthVersion = CType(GetJson(DlModRequest("https://api.modrinth.com/v2/version_files", "POST", $"{{""hashes"": [""{ModrinthHashes.Join(""",""")}""], ""algorithm"": ""sha1""}}", "application/json")), JObject) Log($"[Mod] 从 Modrinth 获取到 {ModrinthVersion.Count} 个本地 Mod 的对应信息") '步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系 @@ -985,7 +985,7 @@ Finished: Next Log($"[Mod] 已从 Modrinth 获取本地 Mod 信息,继续获取更新信息") '步骤 4:获取更新信息 - Dim ModrinthUpdate = CType(GetJson(NetRequestMod("https://api.modrinth.com/v2/version_files/update", "POST", + Dim ModrinthUpdate = CType(GetJson(DlModRequest("https://api.modrinth.com/v2/version_files/update", "POST", $"{{""hashes"": [""{ModrinthMapping.SelectMany(Function(l) l.Value.Select(Function(m) m.ModrinthHash)).Join(""",""")}""], ""algorithm"": ""sha1"", ""loaders"": [""{ModLoaders.Join(""",""").ToLower}""],""game_versions"": [""{McVersion}""]}}", "application/json")), JObject) For Each Entry In Mods @@ -1022,7 +1022,7 @@ Finished: CurseForgeHashes.Add(Entry.CurseForgeHash) If Loader.IsAbortedWithThread(MainThread) Then Exit Sub Next - Dim CurseForgeRaw = CType(CType(GetJson(NetRequestMod("https://api.curseforge.com/v1/fingerprints/432/", "POST", + Dim CurseForgeRaw = CType(CType(GetJson(DlModRequest("https://api.curseforge.com/v1/fingerprints/432/", "POST", $"{{""fingerprints"": [{CurseForgeHashes.Join(",")}]}}", "application/json")), JObject)("data")("exactMatches"), JContainer) Log($"[Mod] 从 CurseForge 获取到 {CurseForgeRaw.Count} 个本地 Mod 的对应信息") '步骤 2:尝试读取工程信息缓存,构建其他 Mod 的对应关系 @@ -1045,7 +1045,7 @@ Finished: Log($"[Mod] 需要从 CurseForge 获取 {CurseForgeMapping.Count} 个本地 Mod 的工程信息") '步骤 3:获取工程信息 If Not CurseForgeMapping.Any() Then Exit Sub - Dim CurseForgeProject = CType(GetJson(NetRequestMod("https://api.curseforge.com/v1/mods", "POST", + Dim CurseForgeProject = CType(GetJson(DlModRequest("https://api.curseforge.com/v1/mods", "POST", $"{{""modIds"": [{CurseForgeMapping.Keys.Join(",")}]}}", "application/json")), JObject)("data") Dim UpdateFileIds As New Dictionary(Of Integer, List(Of McMod)) 'FileId -> 本地 Mod 文件列表 Dim FileIdToProjectSlug As New Dictionary(Of Integer, String) @@ -1087,7 +1087,7 @@ Finished: Log($"[Mod] 已从 CurseForge 获取本地 Mod 信息,需要获取 {UpdateFileIds.Count} 个用于检查更新的文件信息") '步骤 4:获取更新文件信息 If Not UpdateFileIds.Any() Then Exit Sub - Dim CurseForgeFiles = CType(GetJson(NetRequestMod("https://api.curseforge.com/v1/mods/files", "POST", + Dim CurseForgeFiles = CType(GetJson(DlModRequest("https://api.curseforge.com/v1/mods/files", "POST", $"{{""fileIds"": [{UpdateFileIds.Keys.Join(",")}]}}", "application/json")), JObject)("data") Dim UpdateFiles As New Dictionary(Of McMod, CompFile) For Each FileJson In CurseForgeFiles diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml index 2e287f1..d3eef4d 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml @@ -47,12 +47,10 @@ - - + + + - diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb index 17aef34..066894e 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb @@ -57,12 +57,6 @@ ComboDownloadVersion.SelectedIndex = Setup.Get("ToolDownloadVersion") ComboDownloadTranslate.SelectedIndex = Setup.Get("ToolDownloadTranslate") ComboDownloadMod.SelectedIndex = Setup.Get("ToolDownloadMod") - CheckDownloadModMirror.Checked = Setup.Get("ToolDownloadModMirror") - If ComboDownloadMod.SelectedItem Is ComboItemDefault Then - CheckDownloadModMirror.IsEnabled = False - Else - CheckDownloadModMirror.IsEnabled = True - End If CheckDownloadKeepModpack.Checked = Setup.Get("ToolDownloadKeepModpack") CheckDownloadIgnoreQuilt.Checked = Setup.Get("ToolDownloadIgnoreQuilt") CheckDownloadCert.Checked = Setup.Get("ToolDownloadCert") @@ -98,7 +92,6 @@ Setup.Reset("ToolDownloadIgnoreQuilt") Setup.Reset("ToolDownloadCert") Setup.Reset("ToolDownloadMod") - Setup.Reset("ToolDownloadModMirror") Setup.Reset("ToolUpdateRelease") Setup.Reset("ToolUpdateSnapshot") Setup.Reset("ToolHelpChinese") @@ -120,7 +113,7 @@ End Sub '将控件改变路由到设置改变 - Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckDebugMode.Change, CheckDebugDelay.Change, CheckDebugSkipCopy.Change, CheckUpdateRelease.Change, CheckUpdateSnapshot.Change, CheckHelpChinese.Change, CheckDownloadKeepModpack.Change, CheckDownloadIgnoreQuilt.Change, CheckDownloadCert.Change, CheckDownloadModMirror.Change + Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckDebugMode.Change, CheckDebugDelay.Change, CheckDebugSkipCopy.Change, CheckUpdateRelease.Change, CheckUpdateSnapshot.Change, CheckHelpChinese.Change, CheckDownloadKeepModpack.Change, CheckDownloadIgnoreQuilt.Change, CheckDownloadCert.Change If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked) End Sub Private Shared Sub SliderChange(sender As MySlider, e As Object) Handles SliderDebugAnim.Change, SliderDownloadThread.Change, SliderDownloadSpeed.Change @@ -132,14 +125,6 @@ Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextSystemCache.ValidatedTextChanged If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Text) End Sub - Private Sub ComboDownloadMod_SelectionChanged(sender As MyComboBox, e As Object) Handles ComboDownloadMod.SelectionChanged - If CheckDownloadModMirror Is Nothing Then Exit Sub - If sender.SelectedItem Is ComboItemDefault Then - CheckDownloadModMirror.IsEnabled = False - Else - CheckDownloadModMirror.IsEnabled = True - End If - End Sub '滑动条 Private Sub SliderLoad()