From 5fb5a3b96333d2c180b0613faf931309ca70d7a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=99=E8=85=BE=E7=8C=AB=E8=B7=83?= <1043137532@qq.com> Date: Sat, 26 Nov 2022 22:39:08 +0800 Subject: [PATCH] 2.4.3 --- Plain Craft Launcher 2/Application.xaml.vb | 1 - Plain Craft Launcher 2/Controls/MyCard.vb | 14 +- Plain Craft Launcher 2/FormMain.xaml.vb | 14 +- .../Modules/Base/ModBase.vb | 10 +- .../Modules/Minecraft/ModDownload.vb | 74 ++++---- .../Modules/Minecraft/ModLaunch.vb | 52 ++++-- .../Modules/Minecraft/ModMinecraft.vb | 18 +- .../Modules/Minecraft/ModModpack.vb | 6 +- .../My Project/AssemblyInfo.vb | 4 +- .../Pages/PageDownload/ModDownloadLib.vb | 96 +++++----- .../PageDownload/PageDownloadCfDetail.xaml.vb | 165 ++++++++++++------ .../Pages/PageDownload/PageDownloadMod.xaml | 16 +- .../PageDownload/PageDownloadMod.xaml.vb | 1 + .../Pages/PageDownload/PageDownloadPack.xaml | 23 +-- .../PageDownload/PageDownloadPack.xaml.vb | 1 + .../Pages/PageLaunch/MySkin.xaml.vb | 26 +-- .../Pages/PageOther/PageOtherLeft.xaml | 1 - .../Pages/PageOther/PageOtherLeft.xaml.vb | 12 +- .../Plain Craft Launcher 2.vbproj | 9 + Plain Craft Launcher 2/Resources/Help.zip | Bin 69242 -> 69043 bytes .../Resources/java-wrapper.jar | Bin 16757 -> 16818 bytes 21 files changed, 332 insertions(+), 211 deletions(-) diff --git a/Plain Craft Launcher 2/Application.xaml.vb b/Plain Craft Launcher 2/Application.xaml.vb index 43d16987..9b2d9bd8 100644 --- a/Plain Craft Launcher 2/Application.xaml.vb +++ b/Plain Craft Launcher 2/Application.xaml.vb @@ -15,7 +15,6 @@ Public Class Application Log(ex, "开发者模式测试出错", LogLevel.Feedback) End Try End Sub - #End If '开始 diff --git a/Plain Craft Launcher 2/Controls/MyCard.vb b/Plain Craft Launcher 2/Controls/MyCard.vb index 1cc059be..3192fcec 100644 --- a/Plain Craft Launcher 2/Controls/MyCard.vb +++ b/Plain Craft Launcher 2/Controls/MyCard.vb @@ -287,9 +287,9 @@ End Class Partial Public Module ModAnimation Public Sub AniDispose(Control As MyCard, RemoveFromChildren As Boolean, Optional CallBack As ParameterizedThreadStart = Nothing) - If Not Control.IsHitTestVisible Then Exit Sub - Control.IsHitTestVisible = False - AniStart({ + If Control.IsHitTestVisible Then + Control.IsHitTestVisible = False + AniStart({ AaScaleTransform(Control, -0.08, 200,, New AniEaseInFluent), AaOpacity(Control, -1, 200,, New AniEaseOutFluent), AaHeight(Control, -Control.ActualHeight, 150, 100, New AniEaseOutFluent), @@ -302,5 +302,13 @@ Partial Public Module ModAnimation If CallBack IsNot Nothing Then CallBack(Control) End Sub,, True) }, "MyCard Dispose " & Control.Uuid) + Else + If RemoveFromChildren Then + CType(Control.Parent, Object).Children.Remove(Control) + Else + Control.Visibility = Visibility.Collapsed + End If + If CallBack IsNot Nothing Then CallBack(Control) + End If End Sub End Module \ No newline at end of file diff --git a/Plain Craft Launcher 2/FormMain.xaml.vb b/Plain Craft Launcher 2/FormMain.xaml.vb index 22838424..fc235851 100644 --- a/Plain Craft Launcher 2/FormMain.xaml.vb +++ b/Plain Craft Launcher 2/FormMain.xaml.vb @@ -10,6 +10,12 @@ Public Class FormMain Dim FeatureList As New List(Of KeyValuePair(Of Integer, String)) '统计更新日志条目 #If BETA Then + If LastVersion < 270 Then 'Release 2.4.3 + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化 Mod、整合包下载的版本检查与显示")) + If LastVersion <= 267 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 LiteLoader 的 Bug")) + FeatureCount += 6 + BugCount += 15 + End If If LastVersion < 268 Then 'Release 2.4.2 FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "暂时关闭了联机功能")) FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "游戏崩溃的弹窗添加了直接查看日志的选项")) @@ -100,6 +106,12 @@ Public Class FormMain '3:BUG+ IMP* FEAT- '2:BUG* IMP- '1:BUG- + If LastVersion < 271 Then 'Snapshot 2.4.3 + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化 Mod、整合包下载的版本检查与显示")) + If LastVersion <= 267 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 LiteLoader 的 Bug")) + FeatureCount += 6 + BugCount += 15 + End If If LastVersion < 269 Then 'Snapshot 2.4.2 If LastVersion = 267 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法下载 CurseForge 整合包的 Bug")) FeatureCount += 2 @@ -1136,7 +1148,7 @@ Install: If MyMsgBox("由于联机提供商要求新联机强制付费,且高度商业化,PCL 将暂时关闭联机功能,不再使用该联机模块。" & vbCrLf & "PCL、HMCL、BakaXL 将合作开发新的跨启动器联机功能,在开发结束后将同步开放,请各位多多理解。", "联机功能已暂时关闭", "查看详情", "确定") = 1 Then - OpenWebsite("https://www.bilibili.com/read/cv19553725") + OpenWebsite("https://www.bilibili.com/read/cv19845645") End If e.Handled = True End Sub diff --git a/Plain Craft Launcher 2/Modules/Base/ModBase.vb b/Plain Craft Launcher 2/Modules/Base/ModBase.vb index f4bcd613..82cab7d0 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModBase.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModBase.vb @@ -10,12 +10,12 @@ Public Module ModBase #Region "声明" '下列版本信息由更新器自动修改 - Public Const VersionBaseName As String = "2.4.2" '不含分支前缀的显示用版本名 - Public Const VersionStandardCode As String = "2.4.2." & VersionBranchCode '标准格式的四段式版本号 + Public Const VersionBaseName As String = "2.4.3" '不含分支前缀的显示用版本名 + Public Const VersionStandardCode As String = "2.4.3." & VersionBranchCode '标准格式的四段式版本号 #If BETA Then - Public Const VersionCode As Integer = 268 'Release + Public Const VersionCode As Integer = 270 'Release #Else - Public Const VersionCode As Integer = 269 'Snapshot + Public Const VersionCode As Integer = 271 'Snapshot #End If '自动生成的版本信息 Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName @@ -771,6 +771,8 @@ Public Module ModBase '还原文件路径 If Not FromPath.Contains(":\") Then FromPath = Path & FromPath If Not ToPath.Contains(":\") Then ToPath = Path & ToPath + '如果复制同一个文件则跳过 + If FromPath = ToPath Then Exit Sub '读取文件内容 Dim FileBytes As Byte() Using ReadStream As New FileStream(FromPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) '支持读取使用中的文件 diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb index 6e811587..9668a04f 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb @@ -221,6 +221,7 @@ McDownloadClientUpdateHint(Version, Json) IsNewClientVersionHinted = True End If + McVersionHighest = Version.Split(".")(1) Setup.Set("ToolUpdateReleaseLast", Version) '解析更新提示(Snapshot) Version = Json("latest")("snapshot") @@ -772,7 +773,7 @@ ''' Public IsLegacy As Boolean ''' - ''' 发布时间,格式为“yyyy/mm/dd HH:mm:ss”。 + ''' 发布时间,格式为“yyyy/mm/dd HH:mm”。 ''' Public ReleaseTime As String ''' @@ -1090,33 +1091,27 @@ DateUpdate = Data("dateModified") DownloadCount = Data("downloadCount") IsModPack = Not Website.Contains("/mc-mods/") - '获取常见文件 + '获取 Mod Loader 列表 + ModLoaders = New List(Of String) For Each File In If(Data("latestFiles"), {}) Dim NewFile As New DlCfFile(File, IsModPack) If Not NewFile.IsAvailable Then Continue For + ModLoaders.AddRange(NewFile.ModLoaders) Next - '获取游戏版本、Mod Loader + ModLoaders = ModLoaders.Distinct.ToList + '用一个偷懒的方式让 Forge 排在 Fabric 的前面 + ModLoaders = ModLoaders.Select(Function(s) s.Replace("Forge", "Aorge")).ToList() + ModLoaders.Sort() + ModLoaders = ModLoaders.Select(Function(s) s.Replace("Aorge", "Forge")).ToList() + '获取游戏版本 Dim GameVersions As New List(Of Integer) - ModLoaders = New List(Of String) For Each File In If(Data("latestFilesIndexes"), {}) Dim Version As String = File("gameVersion") If Not Version.Contains("1.") Then Continue For GameVersions.Add(Version.Split(".")(1).Split("-").First) - Select Case If(File("modLoader"), "0").ToString - Case 1 - ModLoaders.Add("Forge") - Case 2 - ModLoaders.Add("Cauldron") - Case 3 - ModLoaders.Add("LiteLoader") - Case 4 - ModLoaders.Add("Fabric") - End Select FileIndexes.Add(File("fileId")) Next GameVersions = Sort(GameVersions.Distinct.ToList, AddressOf VersionSortBoolean) - ModLoaders = ModLoaders.Distinct.ToList - ModLoaders.Sort() If GameVersions.Count = 0 Then GameVersionDesc = "" Else @@ -1133,8 +1128,15 @@ Next If StartVersion = EndVersion Then SpaVersions.Add("1." & StartVersion) + ElseIf StartVersion >= McVersionHighest Then + SpaVersions.Add("1." & EndVersion & "+") + ElseIf EndVersion <= 7 Then + SpaVersions.Add("1." & StartVersion & "-") + Exit For + ElseIf StartVersion - EndVersion = 1 Then + SpaVersions.Add("1." & StartVersion & ", 1." & EndVersion) Else - SpaVersions.Add("1." & StartVersion & "-1." & EndVersion) + SpaVersions.Add("1." & StartVersion & "~1." & EndVersion) End If Next GameVersionDesc = "[" & Join(SpaVersions, ", ") & "] " @@ -1211,12 +1213,11 @@ Dim NewItem As New MyCfItem With {.Tag = Me} NewItem.LabTitle.Text = ChineseName NewItem.LabInfo.Text = Description.Replace(vbCr, "").Replace(vbLf, "") - NewItem.LabLeft.Text = If(ModLoaders.Count > 0 AndAlso ShowLoaderDesc, "[" & Join(ModLoaders, " & ") & "] ", "") & - If(ShowVersionDesc, GameVersionDesc, "") & + NewItem.LabLeft.Text = (If(ModLoaders.Count > 0 AndAlso ShowLoaderDesc, "[" & Join(ModLoaders, "/") & "] ", "") & + If(ShowVersionDesc, GameVersionDesc, "")).Replace("] [", " ") & Join(CategoryDesc, ",") & " (" & - GetTimeSpanString(DateUpdate - Date.Now) & "更新" & - If(DownloadCount > 0, - "," & If(DownloadCount > 100000, Math.Round(DownloadCount / 10000) & " 万次下载", DownloadCount & " 次下载"), "") & ")" + GetTimeSpanString(DateUpdate - Date.Now) & "更新," & + If(DownloadCount > 100000, Math.Round(DownloadCount / 10000) & " 万次下载", DownloadCount & " 次下载") & ")" If Thumb Is Nothing Then NewItem.Logo = "pack://application:,,,/images/Icons/NoIcon.png" Else @@ -1279,7 +1280,7 @@ Dim SearchResult As String = "" For i = 0 To SearchResults.Count - 1 If Not SearchResults(i).AbsoluteRight AndAlso i >= Math.Min(2, SearchResults.Count - 1) Then Exit For '把 3 个结果拼合以提高准确度 - SearchResult += SearchResults(i).Item.Replace(" (", "|").Split("|").Last.TrimEnd(")") & " " + SearchResult += SearchResults(i).Item.Replace(" - ", "§").Split("§").First.Replace(" (", "|").Split("|").Last.TrimEnd(")") & " " Next Log("[Download] CurseForge 工程列表中文搜索原始关键词:" & SearchResult, LogLevel.Developer) '去除常见连接词 @@ -1432,6 +1433,7 @@ Public DisplayName As String Public [Date] As Date Public GameVersion As String() + Public ModLoaders As New List(Of String) Public ReleaseType As Integer Public FileName As String Public DownloadCount As Integer @@ -1481,11 +1483,13 @@ End If Next End If - '获取游戏版本 + '获取游戏版本与 Mod 加载器列表 Dim Versions As New List(Of String) - For Each Version In Data("gameVersions") - If Version.ToString.StartsWith("1.") OrElse Version.ToString.Contains("w") Then - Versions.Add(Version.ToString.Trim.ToLower) + For Each Version In Data("gameVersions").Select(Function(t) t.ToString.Trim.ToLower) + If Version.StartsWith("1.") OrElse Version.Contains("w") Then + Versions.Add(Version) + ElseIf Version = "forge" OrElse Version = "fabric" OrElse Version = "quilt" OrElse Version = "rift" Then + ModLoaders.Add(Version.First.ToString.ToUpper & Version.Substring(1)) End If Next If Versions.Count > 1 Then @@ -1493,11 +1497,13 @@ If IsModPack Then GameVersion = {GameVersion(0)} ElseIf Versions.Count = 1 Then GameVersion = Versions.ToArray - 'ElseIf Data("gameVersion").Count = 1 AndAlso Not Data("gameVersion")(0).ToString.Contains("1.") Then - ' GameVersion = {"1.16.4"} Else GameVersion = {"未知版本"} End If + '用一个偷懒的方式让 Forge 排在 Fabric 的前面 + ModLoaders = ModLoaders.Select(Function(s) s.Replace("Forge", "Aorge")).ToList() + ModLoaders.Sort() + ModLoaders = ModLoaders.Select(Function(s) s.Replace("Aorge", "Forge")).ToList() End Sub ''' @@ -1513,10 +1519,14 @@ '获取描述信息 Dim Info As String = "" If Not IsModPack Then - Info += "适用于 " & Join(GameVersion, "、").Replace("-snapshot", " 快照") & - If(ModeDebug AndAlso Dependencies.Count > 0, "," & Dependencies.Count & " 个前置,", ",") + Info += If(ModLoaders.Count > 0, Join(ModLoaders, "/"), "") & + If(GameVersion.Count > 1, If(ModLoaders.Count > 0, " ", "") & Join(GameVersion, "、").Replace("-snapshot", " 快照"), "") + If Info <> "" Then Info = "适用于 " & Info & "," + Info += If(ModeDebug AndAlso Dependencies.Count > 0, Dependencies.Count & " 个前置 Mod,", "") End If - Info += If(DownloadCount > 0, If(DownloadCount > 100000, Math.Round(DownloadCount / 10000) & " 万次下载,", DownloadCount & " 次下载,"), "") + 'If DownloadCount > 0 Then 'DownloadCount 目前的返回内容完全不正确,经常是 0,干脆不显示了 + ' Info += If(DownloadCount > 100000, Math.Round(DownloadCount / 10000) & " 万次下载,", DownloadCount & " 次下载,") + 'End If Info += GetTimeSpanString([Date] - Date.Now) & "更新" Info += If(ReleaseType <> 1, "," & ReleaseTypeString, "") diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb index dffc6c87..b2fb5be3 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb @@ -1078,19 +1078,30 @@ SystemBrowser: MaxVer = New Version(1, 12, 999, 999) End If + 'OptiFine 检测 + If McVersionCurrent.Version.HasOptiFine Then + If McVersionCurrent.Version.McCodeMain <= 7 AndAlso McVersionCurrent.Version.McCodeMain > 0 Then + '<1.7:至多 Java 8(Java 9 - 10 未测试) + MaxVer = New Version(1, 8, 999, 999) + ElseIf McVersionCurrent.Version.McCodeMain >= 8 AndAlso McVersionCurrent.Version.McCodeMain <= 11 Then + '1.8 - 1.11:必须恰好 Java 8(Java 9 - 10 未测试) + MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 8, 999, 999) + End If + End If + 'Forge 检测 If McVersionCurrent.Version.HasForge Then If McVersionCurrent.Version.McName = "1.7.2" Then '1.7.2:必须 Java 7 MinVer = New Version(1, 7, 0, 0) : MaxVer = New Version(1, 7, 999, 999) ElseIf McVersionCurrent.Version.McCodeMain <= 12 AndAlso McVersionCurrent.Version.McCodeMain > 0 AndAlso VersionSortBoolean("14.23.5.2855", McVersionCurrent.Version.ForgeVersion) Then - '1.12,Forge 14.23.5.2855 及更低:Java 8 + '<1.12,Forge 14.23.5.2855 及更低:Java 8 MaxVer = New Version(1, 8, 999, 999) ElseIf McVersionCurrent.Version.McCodeMain <= 14 AndAlso McVersionCurrent.Version.McCodeMain > 0 AndAlso VersionSortBoolean("28.2.23", McVersionCurrent.Version.ForgeVersion) Then '1.13 - 1.14,Forge 28.2.23 及更低:Java 8 - 10 MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 10, 999, 999) - ElseIf McVersionCurrent.Version.McCodeMain <= 16 AndAlso McVersionCurrent.Version.McCodeMain > 0 Then - '1.15 - 1.16:Java 8 - 15 + ElseIf McVersionCurrent.Version.McCodeMain <= 15 AndAlso McVersionCurrent.Version.McCodeMain > 0 Then + '1.15:Java 8 - 15 MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 15, 999, 999) ElseIf McVersionCurrent.Version.McCodeMain >= 18 AndAlso McVersionCurrent.Version.McCodeMain < 99 AndAlso McVersionCurrent.Version.HasOptiFine Then '#305 '1.18+:若安装了 OptiFine,最高 Java 18 @@ -1101,8 +1112,8 @@ SystemBrowser: 'Fabric 检测 If McVersionCurrent.Version.HasFabric Then If McVersionCurrent.Version.McCodeMain >= 15 AndAlso McVersionCurrent.Version.McCodeMain <= 16 AndAlso McVersionCurrent.Version.McCodeMain <> -1 Then - '1.15 - 1.16:Java 8 - 15 - MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 15, 999, 999) + '1.15 - 1.16:Java 8 - 18 + MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 18, 999, 999) ElseIf McVersionCurrent.Version.McCodeMain >= 18 AndAlso McVersionCurrent.Version.McCodeMain < 99 Then '1.18+:Java 17 - 18 MinVer = New Version(1, 17, 0, 0) : MaxVer = New Version(1, 18, 999, 999) @@ -1150,22 +1161,29 @@ SystemBrowser: Private McLaunchArgument As String ''' - ''' 释放 Java Wrapper 并返回文件路径。 + ''' 释放 Java Wrapper 并返回完整文件路径。 ''' Public Function ExtractJavaWrapper() As String - Dim WrapperPath As String = PathAppdata & "JavaWrapper.jar" + Dim WrapperPath As String = GetJavaWrapperDir() & "\JavaWrapper.jar" + If Not File.Exists(WrapperPath) OrElse New FileInfo(WrapperPath).Length <> 16818 Then + WriteFile(WrapperPath, GetResources("JavaWrapper")) + Log("[Java] 已自动释放 Java Wrapper:" & WrapperPath) + End If + Return WrapperPath + End Function + ''' + ''' 获取 Java Wrapper 所在的文件夹,不以 \ 结尾。 + ''' + Public Function GetJavaWrapperDir() As String + Dim WrapperPath As String = PathAppdata.TrimEnd("\") If Encoding.UTF8.GetByteCount(WrapperPath) <> WrapperPath.Length Then Log("[Java] AppData 路径中包含非 ASCII 字符,换用 Temp 目录") - WrapperPath = PathTemp & "JavaWrapper.jar" + WrapperPath = PathTemp.TrimEnd("\") If Encoding.UTF8.GetByteCount(PathTemp) <> PathTemp.Length Then Log("[Java] Temp 路径中包含非 ASCII 字符,换用 C 盘根目录") - WrapperPath = "C:\PCL\JavaWrapper.jar" + WrapperPath = "C:\PCL" End If End If - If Not File.Exists(WrapperPath) OrElse New FileInfo(WrapperPath).Length > 20 * 1024 Then - WriteFile(WrapperPath, GetResources("JavaWrapper")) - Log("[Java] 已自动释放 Java Wrapper:" & WrapperPath) - End If Return WrapperPath End Function @@ -1185,7 +1203,7 @@ SystemBrowser: McLaunchLog("旧版 JVM 参数获取成功:") McLaunchLog(Arguments) End If - If McVersionCurrent.JsonObject("minecraftArguments") IsNot Nothing Then + If Not String.IsNullOrEmpty(McVersionCurrent.JsonObject("minecraftArguments")) Then '有的版本是空字符串 McLaunchLog("获取旧版 Game 参数") Arguments += " " & McLaunchArgumentsGameOld(McVersionCurrent) McLaunchLog("旧版 Game 参数获取成功") @@ -1270,6 +1288,7 @@ SystemBrowser: '添加 Java Wrapper 作为主 Jar If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED") + DataList.Insert(0, "-Doolloo.jlw.tmpdir=""" & GetJavaWrapperDir() & """") DataList.Add("-jar """ & ExtractJavaWrapper() & """") '添加 MainClass @@ -1336,6 +1355,7 @@ NextVersion: '添加 Java Wrapper 作为主 Jar If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED") + DataList.Insert(0, "-Doolloo.jlw.tmpdir=""" & GetJavaWrapperDir() & """") DataList.Add("-jar """ & ExtractJavaWrapper() & """") '将 "-XXX" 与后面 "XXX" 合并到一起 @@ -1502,9 +1522,7 @@ NextVersion: GameArguments.Add("${assets_index_name}", McAssetsGetIndexName(Version)) '支持库参数 - 'Dim LibList As List(Of McLibToken) = McLibListGet(Version, - ' Not (Version.Version.HasForge AndAlso Version.Version.McCodeMain >= 17)) '包含版本 Jar 的条件是不为 1.17+ 的 Forge - Dim LibList As List(Of McLibToken) = McLibListGet(Version, True) '如果在 1.19.x Forge 不包含版本 Jar 会导致 #188 + Dim LibList As List(Of McLibToken) = McLibListGet(Version, True) Loader.Output = LibList Dim CpStrings As New List(Of String) Dim OptiFineCp As String = Nothing diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb index 9f5f63a7..85f1221f 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb @@ -2327,13 +2327,16 @@ NextVersion: Dim RealVersion As McVersion Dim RequiredJar As String = Version.JsonObject("jar")?.ToString If Version.IsHmclFormatJson OrElse RequiredJar Is Nothing Then + 'HMCL 项直接使用自身的 Jar '根据 Inherit 获取最深层版本 - '此外,HMCL 项直接使用自身的 Jar Dim OriginalVersion As McVersion = Version - Do Until OriginalVersion.InheritVersion = "" - If OriginalVersion.InheritVersion = OriginalVersion.Name Then Exit Do - OriginalVersion = New McVersion(PathMcFolder & "versions\" & OriginalVersion.InheritVersion & "\") - Loop + '1.17+ 的 Forge 不寻找 Inherit + If Not (Version.Version.HasForge AndAlso Version.Version.McCodeMain >= 17) Then + Do Until OriginalVersion.InheritVersion = "" + If OriginalVersion.InheritVersion = OriginalVersion.Name Then Exit Do + OriginalVersion = New McVersion(PathMcFolder & "versions\" & OriginalVersion.InheritVersion & "\") + Loop + End If '需要新建对象,否则后面的 Check 会导致 McVersionCurrent 的 State 变回 Original '复现:启动一个 Snapshot 版本 RealVersion = New McVersion(OriginalVersion.Path) @@ -2380,6 +2383,11 @@ NextVersion: '转换为 LibToken For Each Library As JObject In AllLibs.Children + '清理 null 项(BakaXL 会把没有的项序列化为 null,但会被 Newtonsoft 转换为 JValue,导致 Is Nothing = false;这导致了 #409) + For i = Library.Properties.Count - 1 To 0 Step -1 + If Library.Properties(i).Value.Type = JTokenType.Null Then Library.Remove(Library.Properties(i).Name) + Next + '检查是否需要(Rules) If Not McJsonRuleCheck(Library("rules")) Then Continue For diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb index a383530c..ad36237f 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb @@ -241,8 +241,12 @@ Retry: For Each ModJson In Task.Input '跳过重复的 Mod(疑似 CurseForge Bug) If FileList.ContainsKey(ModJson("id").ToObject(Of Integer)) Then Continue For + '根据 modules 判断是资源包还是 Mod + Dim ModuleNames = CType(ModJson("modules"), JArray).Select(Function(l) l("name").ToString).ToList + Dim IsResourcePack As Boolean = Not ModuleNames.Contains("META-INF") AndAlso ModuleNames.Contains("pack.mcmeta") '实际的添加 - FileList.Add(ModJson("id"), New DlCfFile(ModJson, False).GetDownloadFile(PathMcFolder & "versions\" & VersionName & "\mods\", False)) + FileList.Add(ModJson("id"), New DlCfFile(ModJson, False).GetDownloadFile( + PathMcFolder & "versions\" & VersionName & "\" & If(IsResourcePack, "resourcepacks", "mods") & "\", False)) Task.Progress += 1 / (1 + ModFileList.Count) Next Task.Output = FileList.Values.ToList diff --git a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb index af43c2ae..f63cd505 100644 --- a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb +++ b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb @@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices ' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 ' 方法是按如下所示使用“*” - - + + diff --git a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb index 2e059094..1373db68 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb @@ -1,8 +1,15 @@ Imports System.IO.Compression Public Module ModDownloadLib - '如果 OptiFine 与 Forge 同时开始安装,就会导致 Forge 安装失败 + + ''' + ''' 如果 OptiFine 与 Forge 同时开始安装,就会导致 Forge 安装失败,所以在这里添加一个锁。 + ''' Private InstallSyncLock As New Object + ''' + ''' 最高的 Minecraft 大版本号,-1 代表尚未获取。 + ''' + Public McVersionHighest As Integer = -1 #Region "Minecraft 下载" @@ -114,7 +121,7 @@ Public Module ModDownloadLib Task.Output = New List(Of NetFile) From {New NetFile(DlSourceLauncherOrMetaGet(JsonAddress), VersionFolder & VersionName & ".json")} End Sub) With {.ProgressWeight = 2, .Show = False}) End If - Loaders.Add(New LoaderDownload("下载原版 Json 文件", New List(Of NetFile) From { + Loaders.Add(New LoaderDownload(McDownloadClientJsonName, New List(Of NetFile) From { New NetFile(DlSourceLauncherOrMetaGet(If(JsonUrl, "")), VersionFolder & VersionName & ".json", New FileChecker(CanUseExistsFile:=False, IsJson:=True)) }) With {.ProgressWeight = 3}) @@ -159,6 +166,7 @@ Public Module ModDownloadLib End Function Private Const McDownloadClientLibName As String = "下载原版支持库文件" + Private Const McDownloadClientJsonName As String = "下载原版 Json 文件" #End Region @@ -378,7 +386,7 @@ Public Module ModDownloadLib Throw New Exception("未找到用于安装 OptiFine 的 Java") End If '添加 Java Wrapper 作为主 Jar - Dim Arguments = "-Duser.home=""" & BaseMcFolderHome & """ -cp """ & Target & """ -jar """ & ExtractJavaWrapper() & """ optifine.Installer" + Dim Arguments = "-Doolloo.jlw.tmpdir=""" & GetJavaWrapperDir() & """ -Duser.home=""" & BaseMcFolderHome & """ -cp """ & Target & """ -jar """ & ExtractJavaWrapper() & """ optifine.Installer" If Java.VersionCode >= 9 Then Arguments = "--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED " & Arguments '开始启动 SyncLock InstallSyncLock @@ -518,27 +526,28 @@ Public Module ModDownloadLib Loaders.Add(New LoaderDownload("下载 OptiFine 主文件", New List(Of NetFile)) With {.ProgressWeight = 8}) Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)("等待原版下载", Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) - '是否已经存在原版文件 - If ClientDownloadLoader Is Nothing Then Exit Sub '等待原版文件下载完成 - For Each Loader In ClientDownloadLoader.GetLoaderList - If Loader.Name <> McDownloadClientLibName Then Continue For - If Loader.State = LoadState.Loading Then - Log("[Download] OptiFine 安装正在等待原版文件下载完成") - Loader.WaitForExit() - End If - Exit For - Next + If ClientDownloadLoader Is Nothing Then Exit Sub + Dim TargetLoaders As List(Of LoaderBase) = + ClientDownloadLoader.GetLoaderList.Where(Function(l) l.Name = McDownloadClientLibName OrElse l.Name = McDownloadClientJsonName). + Where(Function(l) l.State <> LoadState.Finished).ToList + If TargetLoaders.Count > 0 Then Log("[Download] OptiFine 安装正在等待原版文件下载完成") + Do While TargetLoaders.Count > 0 AndAlso Not Task.IsAborted + TargetLoaders = TargetLoaders.Where(Function(l) l.State <> LoadState.Finished).ToList + Thread.Sleep(50) + Loop + If Task.IsAborted Then Exit Sub '拷贝原版文件 - If IsCustomFolder Then - Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name - Directory.CreateDirectory(McFolder & "versions\" & DownloadInfo.Inherit) - If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json") Then - CopyFile(ClientDownloadLoader.Input & ClientName & ".json", McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json") - End If - If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar") Then - CopyFile(ClientDownloadLoader.Input & ClientName & ".jar", McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar") - End If + If Not IsCustomFolder Then Exit Sub + Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name + Directory.CreateDirectory(McFolder & "versions\" & DownloadInfo.Inherit) + If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json") Then + CopyFile(ClientDownloadLoader.Input & ClientName & ".json", + McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".json") + End If + If Not File.Exists(McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar") Then + CopyFile(ClientDownloadLoader.Input & ClientName & ".jar", + McFolder & "versions\" & DownloadInfo.Inherit & "\" & DownloadInfo.Inherit & ".jar") End If End Sub) With {.ProgressWeight = 0.1, .Show = False}) @@ -876,8 +885,8 @@ Public Module ModDownloadLib '构造版本 Json Dim VersionJson As New JObject VersionJson.Add("id", VersionName) - VersionJson.Add("time", DateTime.ParseExact(DownloadInfo.ReleaseTime, "yyyy/MM/dd HH:mm:ss", Globalization.CultureInfo.CurrentCulture)) - VersionJson.Add("releaseTime", DateTime.ParseExact(DownloadInfo.ReleaseTime, "yyyy/MM/dd HH:mm:ss", Globalization.CultureInfo.CurrentCulture)) + VersionJson.Add("time", Date.ParseExact(DownloadInfo.ReleaseTime, "yyyy/MM/dd HH:mm", Globalization.CultureInfo.CurrentCulture)) + VersionJson.Add("releaseTime", Date.ParseExact(DownloadInfo.ReleaseTime, "yyyy/MM/dd HH:mm", Globalization.CultureInfo.CurrentCulture)) VersionJson.Add("type", "release") VersionJson.Add("arguments", GetJson("{""game"":[""--tweakClass"",""" & DownloadInfo.JsonToken("tweakClass").ToString & """]}")) VersionJson.Add("libraries", DownloadInfo.JsonToken("libraries")) @@ -1094,7 +1103,7 @@ Public Module ModDownloadLib Throw New Exception("未找到用于安装 Forge 的 Java") End If '添加 Java Wrapper 作为主 Jar - Dim Arguments = "-cp """ & PathTemp & "Cache\forge_installer.jar;" & Target & """ -jar """ & ExtractJavaWrapper() & """ com.bangbang93.ForgeInstaller """ & McFolder + Dim Arguments = "-Doolloo.jlw.tmpdir=""" & GetJavaWrapperDir() & """ -cp """ & PathTemp & "Cache\forge_installer.jar;" & Target & """ -jar """ & ExtractJavaWrapper() & """ com.bangbang93.ForgeInstaller """ & McFolder If Java.VersionCode >= 9 Then Arguments = "--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED " & Arguments '开始启动 SyncLock InstallSyncLock @@ -1329,27 +1338,26 @@ Public Module ModDownloadLib End If #End Region #Region "原版文件" - '是否已经存在原版文件 - If ClientDownloadLoader Is Nothing Then Exit Sub '等待原版文件下载完成 - For Each Loader In ClientDownloadLoader.GetLoaderList - If Loader.Name <> McDownloadClientLibName Then Continue For - If Loader.State = LoadState.Loading Then - Log("[Download] Forge 安装正在等待原版文件下载完成") - Loader.WaitForExit() - End If - Exit For - Next + If ClientDownloadLoader Is Nothing Then Exit Sub + Dim TargetLoaders As List(Of LoaderBase) = + ClientDownloadLoader.GetLoaderList.Where(Function(l) l.Name = McDownloadClientLibName OrElse l.Name = McDownloadClientJsonName). + Where(Function(l) l.State <> LoadState.Finished).ToList + If TargetLoaders.Count > 0 Then Log("[Download] Forge 安装正在等待原版文件下载完成") + Do While TargetLoaders.Count > 0 AndAlso Not Task.IsAborted + TargetLoaders = TargetLoaders.Where(Function(l) l.State <> LoadState.Finished).ToList + Thread.Sleep(50) + Loop + If Task.IsAborted Then Exit Sub '拷贝原版文件 - If IsCustomFolder Then - Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name - Directory.CreateDirectory(McFolder & "versions\" & Inherit) - If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".json") Then - CopyFile(ClientDownloadLoader.Input & ClientName & ".json", McFolder & "versions\" & Inherit & "\" & Inherit & ".json") - End If - If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".jar") Then - CopyFile(ClientDownloadLoader.Input & ClientName & ".jar", McFolder & "versions\" & Inherit & "\" & Inherit & ".jar") - End If + If Not IsCustomFolder Then Exit Sub + Dim ClientName As String = New DirectoryInfo(ClientDownloadLoader.Input).Name + Directory.CreateDirectory(McFolder & "versions\" & Inherit) + If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".json") Then + CopyFile(ClientDownloadLoader.Input & ClientName & ".json", McFolder & "versions\" & Inherit & "\" & Inherit & ".json") + End If + If Not File.Exists(McFolder & "versions\" & Inherit & "\" & Inherit & ".jar") Then + CopyFile(ClientDownloadLoader.Input & ClientName & ".jar", McFolder & "versions\" & Inherit & "\" & Inherit & ".jar") End If #End Region End Sub) With {.ProgressWeight = 0.1, .Show = False}) diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb index ea650e28..8a13bb06 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb @@ -192,63 +192,124 @@ End Try End Sub 'Mod 下载;整合包另存为 - Public Shared DownloadFolder = Nothing '仅在本次缓存的下载文件夹 + Public Shared CachedFolder As String = Nothing '仅在本次缓存的下载文件夹 Public Sub Save_Click(sender As Object, e As EventArgs) - Try - Dim Desc As String = If(Project.IsModPack, "整合包", "Mod ") - - '确认默认保存位置 - Dim DefaultFolder As String = Nothing - If Not Project.IsModPack Then - DefaultFolder = DownloadFolder - If McVersionCurrent IsNot Nothing Then - If Not McVersionCurrent.IsLoaded Then McVersionCurrent.Load() - If McVersionCurrent.Modable Then + Dim File As DlCfFile = If(TypeOf sender Is MyListItem, sender, sender.Parent).Tag + RunInNewThread( + Sub() + Try + Dim Desc As String = If(Project.IsModPack, "整合包", "Mod ") + '确认默认保存位置 + Dim DefaultFolder As String = Nothing + If Not Project.IsModPack Then + '获取 Mod 所需的加载器种类 + Dim AllowForge As Boolean? = Nothing, AllowFabric As Boolean? = Nothing 'FUTURE: Quilt 支持 + If File.ModLoaders.Count > 0 Then '从文件中获取 + AllowForge = False : AllowFabric = False + For Each LoaderType In File.ModLoaders + If LoaderType = "Forge" Then AllowForge = True + If LoaderType = "Fabric" Then AllowFabric = True + Next + ElseIf Project.ModLoaders.Count > 0 Then '从工程中获取 + AllowForge = False : AllowFabric = False + For Each LoaderType In Project.ModLoaders + If LoaderType = "Forge" Then AllowForge = True + If LoaderType = "Fabric" Then AllowFabric = True + Next + End If + If AllowForge IsNot Nothing AndAlso Not AllowForge AndAlso + AllowFabric IsNot Nothing AndAlso Not AllowFabric Then + AllowForge = Nothing : AllowFabric = Nothing + End If + Log("[Download] 允许 Forge:" & If(AllowForge, "未知") & ",允许 Fabric:" & If(AllowFabric, "未知")) + '判断某个版本是否符合要求 + Dim IsVersionSuitable As Func(Of McVersion, Boolean) = + Function(Version) + If Not Version.IsLoaded Then Version.Load() + If Not Version.Modable Then Return False + If File.GameVersion.Any(Function(v) v.Contains(".")) AndAlso + Not File.GameVersion.Any(Function(v) v.Contains(".") AndAlso v.Split(".")(1) = Version.Version.McCodeMain) Then Return False + If AllowForge Is Nothing OrElse AllowFabric Is Nothing Then Return True + If AllowForge AndAlso Version.Version.HasForge Then Return True + If AllowFabric AndAlso Version.Version.HasFabric Then Return True + Return False + End Function + '获取 Mod 默认下载位置 + If CachedFolder IsNot Nothing Then + DefaultFolder = CachedFolder + Log("[Download] 使用上次下载时的文件夹作为默认下载位置") + ElseIf McVersionCurrent IsNot Nothing AndAlso IsVersionSuitable(McVersionCurrent) Then DefaultFolder = McVersionCurrent.PathIndie & "mods\" Directory.CreateDirectory(DefaultFolder) + Log("[Download] 使用当前版本的 mods 文件夹作为默认下载位置(" & McVersionCurrent.Name & ")") + Else + Dim NeedLoad As Boolean = McVersionListLoader.State <> LoadState.Finished + If NeedLoad Then + Hint("正在查找适合的游戏版本……") + LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\", WaitForExit:=True) + End If + Dim SuitableVersions As New List(Of McVersion) + For Each Version As McVersion In McVersionList.Values.SelectMany(Function(l) l) + If IsVersionSuitable(Version) Then SuitableVersions.Add(Version) + Next + If SuitableVersions.Count = 0 Then + DefaultFolder = PathMcFolder + If NeedLoad Then + Hint("当前 MC 文件夹中未找到适合这个 Mod 的游戏版本") + Else + Log("[Download] 由于当前版本不兼容,使用当前的 MC 文件夹作为默认下载位置") + End If + Else '选择 Mod 数量最多的版本 + Dim SelectedVersion = SuitableVersions.OrderBy(Function(v) + Dim Info As New DirectoryInfo(v.PathIndie & "mods\") + Return If(Info.Exists, Info.GetFiles().Length, -1) + End Function).LastOrDefault() + DefaultFolder = SelectedVersion.PathIndie & "mods\" + Directory.CreateDirectory(DefaultFolder) + Log("[Download] 使用适合的游戏版本作为默认下载位置(" & SelectedVersion.Name & ")") + End If End If End If - If String.IsNullOrEmpty(DefaultFolder) Then DefaultFolder = Nothing - End If - - '获取基本信息 - Dim File As DlCfFile = If(TypeOf sender Is MyListItem, sender, sender.Parent).Tag - Dim ChineseName As String = If(Project.ChineseName = Project.Name, "", - Project.ChineseName.Replace(" (", "Å").Split("Å").First.Replace("\", "\").Replace("/", "/").Replace("|", "|").Replace(":", ":").Replace("<", "<").Replace(">", ">").Replace("*", "*").Replace("?", "?").Replace("""", "").Replace(": ", ":")) - Dim FileName As String - Select Case Setup.Get("ToolDownloadTranslate") - Case 0 - FileName = If(ChineseName = "", "", "[" & ChineseName & "] ") & File.FileName - Case 1 - FileName = If(ChineseName = "", "", ChineseName & "-") & File.FileName - Case 2 - FileName = File.FileName & If(ChineseName = "", "", "-" & ChineseName) - Case Else - FileName = File.FileName - End Select - Dim Target As String - If File.FileName.EndsWith(".litemod") Then - Target = SelectAs("选择保存位置", FileName, Desc & "文件|" & If(Project.IsModPack, "*.zip", "*.litemod"), DefaultFolder) - Else - Target = SelectAs("选择保存位置", FileName, Desc & "文件|" & If(Project.IsModPack, "*.zip", "*.jar"), DefaultFolder) - End If - If Not Target.Contains("\") Then Exit Sub - Dim LoaderName As String = Desc & "下载:" & File.DisplayName & " " - If Target <> DefaultFolder AndAlso Not Project.IsModPack Then DownloadFolder = GetPathFromFullPath(Target) - - '构造步骤加载器 - Dim Loaders As New List(Of LoaderBase) - Loaders.Add(New LoaderDownload("下载文件", New List(Of NetFile) From {File.GetDownloadFile(Target, True)}) With {.ProgressWeight = 6, .Block = True}) - - '启动 - Dim Loader As New LoaderCombo(Of Integer)(LoaderName, Loaders) With {.OnStateChanged = AddressOf DownloadStateSave} - Loader.Start(1) - LoaderTaskbarAdd(Loader) - FrmMain.BtnExtraDownload.ShowRefresh() - FrmMain.BtnExtraDownload.Ribble() - Catch ex As Exception - Log(ex, "保存 CurseForge 文件失败", LogLevel.Feedback) - End Try + '获取基本信息 + Dim ChineseName As String = If(Project.ChineseName = Project.Name, "", + Project.ChineseName.Replace(" (", "Å").Split("Å").First.Replace("\", "\").Replace("/", "/").Replace("|", "|").Replace(":", ":").Replace("<", "<").Replace(">", ">").Replace("*", "*").Replace("?", "?").Replace("""", "").Replace(": ", ":")) + Dim FileName As String + Select Case Setup.Get("ToolDownloadTranslate") + Case 0 + FileName = If(ChineseName = "", "", "[" & ChineseName & "] ") & File.FileName + Case 1 + FileName = If(ChineseName = "", "", ChineseName & "-") & File.FileName + Case 2 + FileName = File.FileName & If(ChineseName = "", "", "-" & ChineseName) + Case Else + FileName = File.FileName + End Select + RunInUi( + Sub() + '弹窗要求选择保存位置 + Dim Target As String + If File.FileName.EndsWith(".litemod") Then + Target = SelectAs("选择保存位置", FileName, Desc & "文件|" & If(Project.IsModPack, "*.zip", "*.litemod"), DefaultFolder) + Else + Target = SelectAs("选择保存位置", FileName, Desc & "文件|" & If(Project.IsModPack, "*.zip", "*.jar"), DefaultFolder) + End If + If Not Target.Contains("\") Then Exit Sub + '构造步骤加载器 + Dim LoaderName As String = Desc & "下载:" & File.DisplayName & " " + If Target <> DefaultFolder AndAlso Not Project.IsModPack Then CachedFolder = GetPathFromFullPath(Target) + Dim Loaders As New List(Of LoaderBase) + Loaders.Add(New LoaderDownload("下载文件", New List(Of NetFile) From {File.GetDownloadFile(Target, True)}) With {.ProgressWeight = 6, .Block = True}) + '启动 + Dim Loader As New LoaderCombo(Of Integer)(LoaderName, Loaders) With {.OnStateChanged = AddressOf DownloadStateSave} + Loader.Start(1) + LoaderTaskbarAdd(Loader) + FrmMain.BtnExtraDownload.ShowRefresh() + FrmMain.BtnExtraDownload.Ribble() + End Sub) + Catch ex As Exception + Log(ex, "保存 CurseForge 文件失败", LogLevel.Feedback) + End Try + End Sub, "Download CFDetail Save") End Sub Private Sub BtnIntroCf_Click(sender As Object, e As EventArgs) Handles BtnIntroCf.Click diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml index 438b94e5..bc31c158 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml @@ -51,28 +51,17 @@ + - - - - - - - - - - - - @@ -83,9 +72,10 @@ - + + diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml.vb index 194172b7..d163ffb7 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml.vb @@ -3,6 +3,7 @@ '初始化加载器信息 Private Sub PageDownloadMod_Inited(sender As Object, e As EventArgs) Handles Me.Initialized PageLoaderInit(Load, PanLoad, CardProjects, PanAlways, Loader, AddressOf Load_OnFinish, AddressOf LoaderInput) + McVersionHighest = Math.Max(McVersionHighest, Integer.Parse(CType(TextSearchVersion.Items(1), MyComboBoxItem).Content.ToString.Split(".")(1))) End Sub Public Shared Loader As New LoaderTask(Of DlCfProjectRequest, DlCfProjectResult)("DlCfProject Mod", AddressOf DlCfProjectSub, AddressOf LoaderInput) With {.ReloadTimeout = 60 * 1000} Private Shared Function LoaderInput() As DlCfProjectRequest diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml index 2e73cf5a..bf3ea09c 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml @@ -47,42 +47,21 @@ + - - - - - - - - - - - - - - - - - - - - - - diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml.vb index fe50914b..4df28c42 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadPack.xaml.vb @@ -3,6 +3,7 @@ '初始化加载器信息 Private Sub PageDownloadMod_Inited(sender As Object, e As EventArgs) Handles Me.Initialized PageLoaderInit(Load, PanLoad, CardProjects, PanAlways, Loader, AddressOf Load_OnFinish, AddressOf LoaderInput) + McVersionHighest = Math.Max(McVersionHighest, Integer.Parse(CType(TextSearchVersion.Items(1), MyComboBoxItem).Content.ToString.Split(".")(1))) End Sub Public Shared Loader As New LoaderTask(Of DlCfProjectRequest, DlCfProjectResult)("DlCfProject ModPack", AddressOf DlCfProjectSub, AddressOf LoaderInput) With {.ReloadTimeout = 60 * 1000} Private Shared Function LoaderInput() As DlCfProjectRequest diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb index efd17e6a..4b6b4c4b 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb @@ -83,12 +83,21 @@ '加载 Dim Image As New MyBitmap(Address) ImgBack.Tag = Address + '大小检查 + Dim Scale As Integer = Image.Pic.Width / 64 + If Image.Pic.Width < 32 OrElse Image.Pic.Height < 32 Then + ImgFore.Source = Nothing : ImgBack.Source = Nothing + Throw New Exception("图片大小不足,长为 " & Image.Pic.Height & ",宽为 " & Image.Pic.Width) + End If '头发层(附加层) If Image.Pic.Width >= 64 AndAlso Image.Pic.Height >= 32 Then - '如果图片中有透明像素,或是头部颜色和透明区均不一样,则加载附加层 - If (Image.Pic.GetPixel(1, 1).A = 0 OrElse Image.Pic.GetPixel(Image.Pic.Width - 1, Image.Pic.Height - 1).A = 0 OrElse Image.Pic.GetPixel(Image.Pic.Width - 2, 2).A = 0) OrElse - (Image.Pic.GetPixel(1, 1) <> Image.Pic.GetPixel(41, 9) AndAlso Image.Pic.GetPixel(Image.Pic.Width - 1, Image.Pic.Height - 1) <> Image.Pic.GetPixel(41, 9) AndAlso Image.Pic.GetPixel(Image.Pic.Width - 2, 2) <> Image.Pic.GetPixel(41, 9)) Then - ImgFore.Source = New CroppedBitmap(Image, New Int32Rect(40, 8, 8, 8)) + If (Image.Pic.GetPixel(1, 1).A = 0 OrElse '如果图片中有任何透明像素(避免纯色白底) + Image.Pic.GetPixel(Image.Pic.Width - 1, Image.Pic.Height - 1).A = 0 OrElse + Image.Pic.GetPixel(Image.Pic.Width - 2, Image.Pic.Height / 2 - 2).A = 0) OrElse + (Image.Pic.GetPixel(1, 1) <> Image.Pic.GetPixel(Scale * 41, Scale * 9) AndAlso '或是头部颜色和透明区均不一样 + Image.Pic.GetPixel(Image.Pic.Width - 1, Image.Pic.Height - 1) <> Image.Pic.GetPixel(Scale * 41, Scale * 9) AndAlso + Image.Pic.GetPixel(Image.Pic.Width - 2, Image.Pic.Height / 2 - 2) <> Image.Pic.GetPixel(Scale * 41, Scale * 9)) Then + ImgFore.Source = New CroppedBitmap(Image, New Int32Rect(Scale * 40, Scale * 8, Scale * 8, Scale * 8)) Else ImgFore.Source = Nothing End If @@ -96,13 +105,8 @@ ImgFore.Source = Nothing End If '脸层 - If Image.Pic.Width >= 32 AndAlso Image.Pic.Height >= 32 Then - ImgBack.Source = New CroppedBitmap(Image, New Int32Rect(8, 8, 8, 8)) - Log("[Skin] 载入头像成功:" & Loader.Name) - Else - ImgBack.Source = Nothing - Throw New Exception("图片大小不足,长为 " & Image.Pic.Height & ",宽为 " & Image.Pic.Width) - End If + ImgBack.Source = New CroppedBitmap(Image, New Int32Rect(Scale * 8, Scale * 8, Scale * 8, Scale * 8)) + Log("[Skin] 载入头像成功:" & Loader.Name) Catch ex As Exception Log(ex, "载入头像失败(" & If(Address, "null") & "," & Loader.Name & ")", LogLevel.Hint) End Try diff --git a/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml b/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml index c6cf1afa..3656845e 100644 --- a/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml +++ b/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml @@ -18,7 +18,6 @@ diff --git a/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml.vb index 9ada0d9e..919298cc 100644 --- a/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml.vb @@ -122,9 +122,17 @@ FrmOtherHelp.SearchBox.Text = "" End Sub - '打开反馈 + '打开网页 Public Shared Sub TryFeedback() Handles ItemFeedback.Click - If CanFeedback(True) Then Feedback(True, False) + If Not CanFeedback(True) Then Exit Sub + If MyMsgBox("是否要打开反馈列表网页?" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。", + "提醒", "打开", "取消") = 2 Then Exit Sub + Feedback(True, False) + End Sub + Public Shared Sub TryVote() Handles ItemVote.Click + If MyMsgBox("是否要打开新功能投票网页?" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。", + "提醒", "打开", "取消") = 2 Then Exit Sub + OpenWebsite("https://github.com/Hex-Dragon/PCL2/discussions/categories/%E5%8A%9F%E8%83%BD%E6%8A%95%E7%A5%A8?discussions_q=category%3A%E5%8A%9F%E8%83%BD%E6%8A%95%E7%A5%A8+sort%3Adate_created") End Sub End Class diff --git a/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj b/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj index 6560948a..78dca232 100644 --- a/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj +++ b/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj @@ -899,5 +899,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/Plain Craft Launcher 2/Resources/Help.zip b/Plain Craft Launcher 2/Resources/Help.zip index 43e6c367c6139af92ed11ca1e642448b9819aae9..4b7dfacdb9520c57e4cd9f3132778aaa0981866f 100644 GIT binary patch delta 9073 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 delta 9151 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 diff --git a/Plain Craft Launcher 2/Resources/java-wrapper.jar b/Plain Craft Launcher 2/Resources/java-wrapper.jar index 498ace799ca4c0c2dd927b46d2f6355ff015e281..166445a360b39763eeb62b03e4072aadc3552c2c 100644 GIT binary patch delta 2285 zcmY+GdpHw(8^`Btmf4KwbtsZUnX`!;M~)?j5Srr{Qo}>ZoHh?CG=~|HW6L3%gcU;$ z?O`+Yh(#xnc*Vp+PI-u4xvuwmulM)Q{r%q8{k!i!zn{%iK6)CTxT~XppcnukDhe=> zh$V@u2|gxndytIo3iv*jCb3imbilEsrBj51a%tljQ~$mQ03az20LTFVfT$=eHY!Tz zDmG5XDkkhg6dDr}qaBPzU%wvf>GQk%xa__s!*A$Xzh_V|t39tzg&ypvs^|Rs1-S_o z7PEQsOm?%=IWI1Is)=h-UwDjh%l|AWf}-AKNw(yFX6uSNpTbcWKHKhp8WHlSNPQ)#*|PKXhmf7kJn;YAz2}3$mI(f z#lVLOVelrQr&d!II*|d8UY)GWI~cR0Hqy>_nMIf+;|w{yx<9@8mX)G+X?f*^-!gD` zC%dAi{SKnNv{~)6{E1qnIGH&&f!yNs z!SurO;XF(a>5Xdoj!XD!)XOn0tQp;J$c62yY#St=P)0A~+6P*kPz1HAi5zqdB2Hdb zD{}E1a2(e0+Gi2xSKVF~`(VgHei#p&a#)YHTWrbq@K?qP)2VHdiZHOPzvo#*?zL7W zwk@S#dfZVXj2npG+`AW2a!=YcWVo+mITP>bxM-M$d!*^?n0zE`kp~QOOFaoIg7_C+ zba|r-GTiU04t+gHKnw%?ede$ES($&8QJb9jfbAhgr_)HaE%H4E{qLzPv(h2in+>;v zk>!`fO;IyU;3YSJzk9vffk!x&JFQ3foU zu4>&`Ws~x(+7>A%rCD2P^y-L7j2FL2LV0qeI)Ans5EK zEPgm6P(BfMDXoTgyZKVJ!?a~m4~!*LSN^QxJ7EV z)dBU}*)O&jocir!_#Xag=C-=|=Yj-(?L}K^Jr2ul4Hc7bD5!i-ta5M8&%VNG%}7CL zprbIGPkgl0C#VJKg*OeXv0ZF8ovtNV?+)*Ah4aF0N&iP@wzE6WJBZz&db7^q>4GwW z&&sxBIoi59E;euOOVt@qE1M`({!VNS6vSz3#`MGOGHlpGbp@nz@BD?+>5fk{9&xn0 zwCMDrg10F5RMG$8STY;ELEY#8|?H%f@^;*Wh;J4u3G!gTZc?A?a zXUt=&#~J3Wt-;#hZ!-GWJLbqX~;S4!;17mm^hB4V?r%e&*p zTwN!4-){=a8Fi+3^>(xERj6IoPsjn$X*23ZE)P<@G#Y*GzG~=Hn2SX=k~&_*d$f!X z#HZWEj7+R~CjuqX_mVCb*-vtUrjPE}6sz41Z+xF1OWTe4d0n(6(+EAhYK-++lYRp7 zO<5XZ_DfwC)pq_Uqb*1!puk+ot;A1O$qJ0lJGbja1ELWtb9-p)7r(hWIW*okLS>kN z)du4kDhG?Q;ZginbpnQcLOnY=j6&t1)#T0p$iG<$jIiA(? z8MbZOBZlmY`~ixaMsBpeXkB2HyGd`IlOLF$B;pH**`M{nGX%&h<(NAzpA`n*K1LEOa<*JOMHO~$h~$E64P2EIf2E962|bo1MUbI%+BZL023Tm#zlb2qCf z?2+5o-f?D1dI`1odpR)*XuW2{vv@EAoZgz=`lWf<0lX;`?tU?$G%vqwdHtQ<2g5rK zk5*z00$!B7`F_zj_czbJ;jb+goeej3e0ulIQ1+($6+?BvT@L1$M!QzrY-K~dO>ehZ zkTG^?jqRW#Si*dFNGu| zXRiWFTuyNQT#fNbx)*3jk(8Jg>=*87LW*Qdz1QqM6Am76fdEz1mB&~yqRlopP!2EI z@C07ph2YU4hS} zKME`-Wd%fBaa4%Y{QIfVh-Pa}KTBhpCioGD$Bha6*a{8`N?82)zwkdu`=|AyB|^XQ z{;304TUg)#2cE`D=}R4oC#OJshoVz`3U(;U%_R;yeoT=EER_%4%7I%VgRG7oI=GcQ|6k_h$L2ER04s>_q{XiV{{gs8 BC5r$6 delta 2203 zcmY+Fc{me}AICT6%oQ`|M4^zQ%`JwB$$hTeAtA>oSFVMyN^Bv7!;jM6viwKOVPF>2>%tBIWOD%kq5#sm9t`&g;~Wh6E^>gWbN#%W zm-;X%UYf?@cvVa0jYVqlFpuhK+L>W^jRorapr>+qwP#ILh%$%8khF!_TY|s{D#I;b zJbTq~CzrA`;0TpQ3j+`%sF9c-?}ZBImu zvsXYQShRA$wm9%0xLgvU`T7ITQ@$VIfCR`a0n%1}rT5-L6~ufZIYCa)oj`AwywUy? z?9SgN0*`U*D9oT&Z|k1(%C0!LpWq`9qlWjPtBLftU?Q^4rOTI6GQ{WbLFg zYHt+L459vM-Hf2?o;qmGDG;J;B9uBJgS5`T`y5D3(IkeYV@L3K4dV0IFLPsy{6%b8}s};wYyGHp~S#A-{7z;=j}elPQ-IGzQgaCd`hTsv)(eQ zx6E-A?n)(aDN7O1NlS%o(;rr?FjQThMw)j)7wPKy`du2kegaFIt`+dnw6n6hpu(^7 zLylugP2`^iF3Qyzt8QQQ*E%Gw$(k@rG4PVsr}K;B-{#pLmP^?`RDC_RU3M$KFLNW{ zoX_w(!L;|G7`18Ndv+<+ss5jBuNrkmW|m6hPSqcpqx$MiZh34(8s>U+BNDz}@&-kH zEcFP3oi{J&)uEY=WYUHn=eJ#H%;N92nzPLB4-BEkMM)y4CM|}zNUbNqXY_vtqw!Pu zlxZ7U`nCNWZ}}OHIyPl9>nO-|;^ZX$5e3qC-s|~i2KBBU^!;#~ZP)xDyvMSenvsip z)^1zQYL_6d>PdNd#mQ_y0P%(#$@&)Y?2RS#?bKQMlPo^yO0*Ggc-gjUqkW8^-lK{G zC9bkl;*C?IKg`Fl7xI*l6%=Nnv$EuP);tT#@x7W)bU^1)_yvOyj{Qmn|4pzDCJ|W_7AlXadI76dWSZ_a8-_YY$K$@4cBzZY zc$A9woTww;uE_?v?eP5xwX{0R7z>01*?A6;Llr7#1VM6X)%UVaoaiq3v8Zm$_KnSP zQR==I^djTA%*%-iZBL-AM%M2u?I2>uHIYXMM3zZ{u=XywuuDL4bsuN#=qI37rhooN zUnlq@@~O|*h0$!qkgph8>?qE4_d(Za*@fNUs6&y&8f&2j74qonOH-45VrLw%8rQ21 zJBgatJ}Cq~xa;RF=jS9I(O~K#p=MrSG z|E{-GTCUQK-`kEF>)dMLJvHEJf8q%kyyGq-1>gA*0cOtv8@&u=_TqtvhIJ_65g)w}R~(UK!^|T+G97V!n8Z zeJf6suo?4hMXpi@QVmv-$vrtwdN_6FwBlBqQZX*i+n4uYxW;5zBsF}WD7!BL--q%} zVy|sVA$F{)wy{y~+Mlnq8`?s{&GI@%k;Zx`+L>V1*k22yNk2URymrmphpln2J5+Pz z^xiB$Yn3)Z2T|yQ8_Jq^^yAwwoM%wV}!>u$`YnqAEr~yywPqyCV z4uEk5f&+VJ3Jp2QykqYa8m;iP3j;wGRZ;nj$*7!WGfe>b1 z7a4^R;ozL3KmYlnxX#Q$lxyRs{tuPu=wE1Vk8%Aw&Y*zICp6z73zHe8tA>#YlA^*! z;Pe?)MRAm-Syiv?e_-Cqw&7|0`JWbCMAPY~zdXq(3u&z_6p$o%q8s+!Ux6Nv<3Q&JCt;SB1~q{DN0 zx^m`yMp7H^YbNciO{G#RWu>9(O(X>HzdEFR*G~9W_n}#fqO0mJ@$zgksn%T z^@sO=oIV1xL!BTc+LaYRSqEjX{zWt;iARZz`H0|@S^u~?Sn1RjeWxpBy`7}4cD zPDsCzs>hfoN$Vm1a-QU^hxmJil&h!C^Z%qLjq7P2SH$$ifQ2LtefV+F|Hxe+rRbmi zdze&tBtq6*bJnOoq~ZF@GZ&2048zNbWo9r=KBc%0AhgvfZ);o@07$7 ONQnk=Y)_DXlYaq;%mZKm