From c5ae532fd55a9c31a3a4d7b1024db4739eaabd8c 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: Wed, 16 Oct 2024 03:24:00 +0800 Subject: [PATCH] 2.8.9 --- Plain Craft Launcher 2/Application.xaml.vb | 6 +- Plain Craft Launcher 2/Controls/MyImage.vb | 212 ++- .../Controls/MyListItem.xaml.vb | 27 +- .../Controls/MyRadioBox.xaml.vb | 4 +- .../Controls/MyRadioButton.xaml.vb | 4 +- .../Controls/MyTextButton.vb | 8 +- Plain Craft Launcher 2/FormMain.xaml | 4 +- Plain Craft Launcher 2/FormMain.xaml.vb | 284 +--- .../Modules/Base/ModBase.vb | 58 +- Plain Craft Launcher 2/Modules/Base/ModNet.vb | 25 +- .../Modules/Base/ModValidate.vb | 14 +- .../Modules/Base/MyBitmap.vb | 22 +- .../Modules/Minecraft/ModCrash.vb | 31 +- .../Modules/Minecraft/ModLaunch.vb | 49 +- .../Modules/Minecraft/ModMinecraft.vb | 37 +- .../Modules/Minecraft/ModMod.vb | 1 + .../Modules/Minecraft/ModModpack.vb | 8 +- .../Modules/Minecraft/MyCompItem.xaml | 3 +- .../Modules/Minecraft/MyCompItem.xaml.vb | 77 +- .../Modules/Minecraft/MyLocalModItem.xaml | 4 +- .../Modules/Minecraft/MyLocalModItem.xaml.vb | 142 +- Plain Craft Launcher 2/Modules/ModEvent.vb | 13 +- Plain Craft Launcher 2/Modules/ModSecret.vb | 8 +- .../My Project/AssemblyInfo.vb | 4 +- .../Pages/PageDownload/ModDownloadLib.vb | 335 ++--- .../PageDownloadCompDetail.xaml.vb | 2 +- .../PageDownload/PageDownloadLeft.xaml.vb | 2 +- .../PageDownload/PageDownloadMod.xaml.vb | 12 +- .../Pages/PageLaunch/MyMsgLogin.xaml.vb | 2 +- .../Pages/PageLaunch/MySkin.xaml.vb | 4 +- .../Pages/PageLaunch/PageLaunchLeft.xaml.vb | 6 +- .../Pages/PageLaunch/PageLaunchRight.xaml.vb | 8 + .../Pages/PageLaunch/PageLoginMs.xaml.vb | 2 +- .../Pages/PageLaunch/PageLoginMsSkin.xaml.vb | 20 +- .../Pages/PageLink/PageLinkIoi.xaml.vb | 69 - .../Pages/PageLink/PageLinkLeft.xaml.vb | 2 +- .../Pages/PageOther/PageOtherLeft.xaml.vb | 8 +- .../Pages/PageSetup/ModSetup.vb | 12 +- .../Pages/PageSetup/PageSetupLeft.xaml.vb | 2 +- .../Pages/PageSetup/PageSetupSystem.xaml | 76 +- .../Pages/PageSetup/PageSetupSystem.xaml.vb | 40 +- .../Pages/PageSetup/PageSetupUI.xaml | 2 + .../Pages/PageSetup/PageSetupUI.xaml.vb | 20 +- .../Pages/PageVersion/PageVersionLeft.xaml.vb | 2 +- .../Pages/PageVersion/PageVersionMod.xaml.vb | 21 +- .../Plain Craft Launcher 2.vbproj | 7 +- Plain Craft Launcher 2/Resources/Custom.xaml | 309 ++-- Plain Craft Launcher 2/Resources/Help.zip | Bin 77143 -> 79164 bytes Plain Craft Launcher 2/Resources/ModData.txt | 1272 +++++++++++++---- 49 files changed, 1880 insertions(+), 1400 deletions(-) diff --git a/Plain Craft Launcher 2/Application.xaml.vb b/Plain Craft Launcher 2/Application.xaml.vb index 4791caf3..14f28ea7 100644 --- a/Plain Craft Launcher 2/Application.xaml.vb +++ b/Plain Craft Launcher 2/Application.xaml.vb @@ -102,7 +102,7 @@ Public Class Application Log($"[Start] 程序版本:{VersionDisplayName} ({VersionCode}{If(CommitHash = "", "", $",#{CommitHash}")})") Log($"[Start] 识别码:{UniqueAddress}{If(ThemeCheckOne(9), ",已解锁反馈主题", "")}") Log($"[Start] 程序路径:{PathWithName}") - Log($"[Start] 系统编码:{Encoding.Default} ({Encoding.Default.CodePage}, GBK={IsGBKEncoding})") + Log($"[Start] 系统编码:{Encoding.Default.HeaderName} ({Encoding.Default.CodePage}, GBK={IsGBKEncoding})") Log($"[Start] 管理员权限:{IsAdmin()}") '检测异常环境 If Path.Contains(IO.Path.GetTempPath()) OrElse Path.Contains("AppData\Local\Temp\") Then @@ -210,8 +210,8 @@ Public Class Application If AssemblyImazenWebp Is Nothing Then Log("[Start] 加载 DLL:Imazen.WebP") AssemblyImazenWebp = Assembly.Load(GetResources("Imazen_WebP")) - SetDllDirectory(GetPureAsciiDir()) - File.WriteAllBytes(GetPureAsciiDir() & "\libwebp.dll", GetResources("libwebp64")) + SetDllDirectory(PathPure.TrimEnd("\")) + WriteFile(PathPure & "libwebp.dll", GetResources("libwebp64")) End If Return AssemblyImazenWebp End SyncLock diff --git a/Plain Craft Launcher 2/Controls/MyImage.vb b/Plain Craft Launcher 2/Controls/MyImage.vb index a5a71442..29cc9162 100644 --- a/Plain Craft Launcher 2/Controls/MyImage.vb +++ b/Plain Craft Launcher 2/Controls/MyImage.vb @@ -1,7 +1,7 @@ -Public Class MyImage +Public Class MyImage Inherits Image -#Region "辅助属性注册" +#Region "公开属性" ''' ''' 网络图片的缓存有效期。 @@ -22,14 +22,6 @@ Public Class MyImage End Property Private _EnableCache As Boolean = True - '将 Source 属性映射到 XAML - Public Shared Shadows ReadOnly SourceProperty As DependencyProperty = DependencyProperty.Register( - "Source", GetType(String), GetType(MyImage), New PropertyMetadata(New PropertyChangedCallback( - Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyImage).Source = e.NewValue.ToString()))) - -#End Region - - Private _Source As String = "" ''' ''' 与 Image 的 Source 类似。 ''' 若输入以 http 开头的字符串,则会尝试下载图片然后显示,图片会保存为本地缓存。 @@ -43,74 +35,150 @@ Public Class MyImage If value = "" Then value = Nothing If _Source = value Then Exit Property _Source = value - Dim TempPath As String = $"{PathTemp}MyImage\{GetHash(value)}.png" + If Not IsInitialized Then Exit Property '属性读取顺序修正:在完成 XAML 属性读取后再触发图片加载(#4868) + Load() + End Set + End Property + Private _Source As String = "" + Public Shared Shadows ReadOnly SourceProperty As DependencyProperty = DependencyProperty.Register( + "Source", GetType(String), GetType(MyImage), New PropertyMetadata(New PropertyChangedCallback( + Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyImage).Source = e.NewValue.ToString()))) + + ''' + ''' 当 Source 首次下载失败时,会从该备用地址加载图片。 + ''' + Public Property FallbackSource As String + Get + Return _FallbackSource + End Get + Set(value As String) + _FallbackSource = value + End Set + End Property + Private _FallbackSource As String = Nothing + + ''' + ''' 正在下载网络图片时显示的本地图片。 + ''' + Public Property LoadingSource As String + Get + Return _LoadingSource + End Get + Set(value As String) + _LoadingSource = value + End Set + End Property + Private _LoadingSource As String = "pack://application:,,,/images/Icons/NoIcon.png" + +#End Region + + ''' + ''' 实际被呈现的图片地址。 + ''' + Public Property ActualSource As String + Get + Return _ActualSource + End Get + Set(value As String) + If value = "" Then value = Nothing + If _ActualSource = value Then Exit Property + _ActualSource = value Try - '空 - If value Is Nothing Then - MyBase.Source = Nothing - Exit Property - End If - '本地图片 - If Not value.StartsWithF("http") Then - MyBase.Source = New MyBitmap(value) - Exit Property - End If - '从缓存加载网络图片 - If EnableCache AndAlso File.Exists(TempPath) Then - MyBase.Source = New MyBitmap(TempPath) - If (Date.Now - File.GetCreationTime(TempPath)) < FileCacheExpiredTime Then - Exit Property '无需刷新缓存 - Else - File.Delete(TempPath) '需要刷新缓存 - End If - Else - MyBase.Source = Nothing '清空显示 - End If - '下载网络图片 - RunInNewThread( - Sub() - Dim Url As String = value '重新捕获变量,以检测在下载过程中 Source 被修改的情况 - Dim Retried As Boolean = False -RetryStart: - Dim TempDownloadingPath As String = TempPath & RandomInteger(0, 10000000) - Try - Log("[MyImage] 正在下载图片:" & Url) - NetDownload(Url, TempDownloadingPath, True) - If Url <> Source Then - '若 Source 在下载时被修改,则不显示 - File.Delete(TempDownloadingPath) - ElseIf EnableCache Then - '保存缓存并显示 - Rename(TempDownloadingPath, TempPath) - RunInUi(Sub() MyBase.Source = New MyBitmap(TempPath)) - Else - '直接显示 - RunInUiWait(Sub() MyBase.Source = New MyBitmap(TempDownloadingPath)) - File.Delete(TempDownloadingPath) - End If - Catch ex As Exception - Try - File.Delete(TempDownloadingPath) - Catch - End Try - If Not Retried Then - Log(ex, $"下载图片可重试地失败({Url})", LogLevel.Developer) - Retried = True - Thread.Sleep(1000) - GoTo RetryStart - Else - Log(ex, $"下载图片失败({Url})", LogLevel.Hint) - End If - End Try - End Sub, "MyImage PicLoader " & GetUuid() & "#", ThreadPriority.BelowNormal) + Dim Bitmap As MyBitmap = If(value Is Nothing, Nothing, New MyBitmap(value)) '在这里先触发可能的文件读取,尽量避免在 UI 线程中读取文件 + RunInUiWait(Sub() MyBase.Source = Bitmap) Catch ex As Exception - Log(ex, $"加载图片失败({value})", LogLevel.Hint) + Log(ex, $"加载图片失败({value})") Try - File.Delete(TempPath) '删除缓存,以免缓存出现问题导致一直加载失败 + If value.StartsWithF(PathTemp) AndAlso File.Exists(value) Then File.Delete(value) Catch End Try End Try End Set End Property + Private _ActualSource As String = Nothing + + Private Sub Load() _ + Handles Me.Initialized '属性读取顺序修正:在完成 XAML 属性读取后再触发图片加载(#4868) + '空 + If Source Is Nothing Then + ActualSource = Nothing + Exit Sub + End If + '本地图片 + If Not Source.StartsWithF("http") Then + ActualSource = Source + Exit Sub + End If + '从缓存加载网络图片 + Dim Url As String = Source + Dim Retried As Boolean = False + Dim TempPath As String = GetTempPath(Url) + Dim TempFile As New FileInfo(TempPath) + If EnableCache AndAlso TempFile.Exists Then + ActualSource = TempPath + If (Date.Now - TempFile.CreationTime) < FileCacheExpiredTime Then Exit Sub '无需刷新缓存 + End If + RunInNewThread( + Sub() + Dim TempDownloadingPath As String = Nothing + Try +RetryStart: + '下载 + ActualSource = LoadingSource '显示加载中图片 + TempDownloadingPath = TempPath & RandomInteger(0, 10000000) + NetDownload(Url, TempDownloadingPath, True) + If Url <> Source AndAlso Url <> FallbackSource Then + '已经更换了地址 + File.Delete(TempDownloadingPath) + ElseIf EnableCache Then + '保存缓存并显示 + If File.Exists(TempPath) Then File.Delete(TempPath) + Rename(TempDownloadingPath, TempPath) + RunInUi(Sub() ActualSource = TempPath) + Else + '直接显示 + RunInUiWait(Sub() ActualSource = TempDownloadingPath) + File.Delete(TempDownloadingPath) + End If + Catch ex As Exception + Try + If TempPath IsNot Nothing Then File.Delete(TempPath) + If TempDownloadingPath IsNot Nothing Then File.Delete(TempDownloadingPath) + Catch + End Try + If Not Retried Then + '更换备用地址 + Log(ex, $"下载图片可重试地失败({Url})", LogLevel.Developer) + Retried = True + Url = If(FallbackSource, Source) + '空 + If Url Is Nothing Then + ActualSource = Nothing + Exit Sub + End If + '本地图片 + If Not Url.StartsWithF("http") Then + ActualSource = Url + Exit Sub + End If + '从缓存加载网络图片 + TempPath = GetTempPath(Url) + TempFile = New FileInfo(TempPath) + If EnableCache AndAlso TempFile.Exists() Then + ActualSource = TempPath + If (Date.Now - TempFile.CreationTime) < FileCacheExpiredTime Then Exit Sub '无需刷新缓存 + End If + '下载 + If Source = Url Then Thread.Sleep(1000) '延迟 1s 重试 + GoTo RetryStart + Else + Log(ex, $"下载图片失败({Url})", LogLevel.Hint) + End If + End Try + End Sub, "MyImage PicLoader " & GetUuid() & "#", ThreadPriority.BelowNormal) + End Sub + Public Shared Function GetTempPath(Url As String) As String + Return $"{PathTemp}MyImage\{GetHash(Url)}.png" + End Function -End Class +End Class \ No newline at end of file diff --git a/Plain Craft Launcher 2/Controls/MyListItem.xaml.vb b/Plain Craft Launcher 2/Controls/MyListItem.xaml.vb index 60706f9f..85bb4215 100644 --- a/Plain Craft Launcher 2/Controls/MyListItem.xaml.vb +++ b/Plain Craft Launcher 2/Controls/MyListItem.xaml.vb @@ -212,33 +212,26 @@ If Not _Logo = "" Then If _Logo.StartsWithF("http", True) Then '网络图片 - PathLogo = New Image With { + PathLogo = New MyImage With { .Tag = Me, .IsHitTestVisible = LogoClickable, - .Source = New ImageSourceConverter().ConvertFromString(_Logo), + .Source = _Logo, .RenderTransformOrigin = New Point(0.5, 0.5), .RenderTransform = New ScaleTransform With {.ScaleX = LogoScale, .ScaleY = LogoScale}, .SnapsToDevicePixels = True, .UseLayoutRounding = False} RenderOptions.SetBitmapScalingMode(PathLogo, BitmapScalingMode.Linear) - ElseIf _Logo.EndsWithF(".png", True) OrElse _Logo.EndsWithF(".jpg", True) Then + ElseIf _Logo.EndsWithF(".png", True) OrElse _Logo.EndsWithF(".jpg", True) OrElse _Logo.EndsWithF(".webp", True) Then '位图 - Dim Bitmap = New MyBitmap(_Logo) PathLogo = New Canvas With { .Tag = Me, .IsHitTestVisible = LogoClickable, - .Background = Bitmap, + .Background = New MyBitmap(_Logo), .RenderTransformOrigin = New Point(0.5, 0.5), .RenderTransform = New ScaleTransform With {.ScaleX = LogoScale, .ScaleY = LogoScale}, - .SnapsToDevicePixels = True, .UseLayoutRounding = False} - 'If Bitmap.Pic.Width = 16 AndAlso Bitmap.Pic.Height = 16 Then - ' '使用最适合 16x16 物品图片显示的大小 - ' RenderOptions.SetBitmapScalingMode(PathLogo, BitmapScalingMode.NearestNeighbor) - ' PathLogo.HorizontalAlignment = HorizontalAlignment.Center : PathLogo.VerticalAlignment = VerticalAlignment.Center - ' PathLogo.Width = GetWPFSize(Math.Floor(GetPixelSize(32) / 16) * 16) : PathLogo.Height = PathLogo.Width - 'Else - PathLogo.HorizontalAlignment = HorizontalAlignment.Stretch : PathLogo.VerticalAlignment = VerticalAlignment.Stretch - RenderOptions.SetBitmapScalingMode(PathLogo, BitmapScalingMode.HighQuality) - 'End If + .SnapsToDevicePixels = True, .UseLayoutRounding = False, + .HorizontalAlignment = HorizontalAlignment.Stretch, .VerticalAlignment = VerticalAlignment.Stretch + } + RenderOptions.SetBitmapScalingMode(PathLogo, BitmapScalingMode.Linear) Else '矢量图 PathLogo = New Shapes.Path With { @@ -327,8 +320,8 @@ Private Sub OnSizeChanged() Handles Me.SizeChanged ColumnCheck.Width = New GridLength(If(_Type = CheckType.None OrElse _Type = CheckType.Clickable, If(Height < 40, 4, 2), 6)) ColumnLogo.Width = New GridLength(If(_Logo = "", 0, 34) + If(Height < 40, 0, 4)) - If Not IsNothing(PathLogo) Then - If _Logo.EndsWithF(".png", True) Then + If PathLogo IsNot Nothing Then + If _Logo.EndsWithF(".png", True) OrElse _Logo.EndsWithF(".jpg", True) OrElse _Logo.EndsWithF(".webp", True) Then PathLogo.Margin = New Thickness(4, 5, 3, 5) Else PathLogo.Margin = New Thickness(If(Height < 40, 6, 8), 8, If(Height < 40, 4, 6), 8) diff --git a/Plain Craft Launcher 2/Controls/MyRadioBox.xaml.vb b/Plain Craft Launcher 2/Controls/MyRadioBox.xaml.vb index 3cb814cf..ba5c05e1 100644 --- a/Plain Craft Launcher 2/Controls/MyRadioBox.xaml.vb +++ b/Plain Craft Launcher 2/Controls/MyRadioBox.xaml.vb @@ -157,9 +157,7 @@ End Set End Property '内容 Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyRadioBox), New PropertyMetadata(New PropertyChangedCallback( - Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs) - If Not IsNothing(sender) Then CType(sender, MyRadioBox).LabText.Text = e.NewValue - End Sub))) + Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyRadioBox).LabText.Text = e.NewValue))) '点击事件 diff --git a/Plain Craft Launcher 2/Controls/MyRadioButton.xaml.vb b/Plain Craft Launcher 2/Controls/MyRadioButton.xaml.vb index c147a2f3..8d9537be 100644 --- a/Plain Craft Launcher 2/Controls/MyRadioButton.xaml.vb +++ b/Plain Craft Launcher 2/Controls/MyRadioButton.xaml.vb @@ -117,9 +117,7 @@ End Set End Property '内容 Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyRadioButton), New PropertyMetadata(New PropertyChangedCallback( - Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs) - If Not IsNothing(sender) Then CType(sender, MyRadioButton).LabText.Text = e.NewValue - End Sub))) + Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyRadioButton).LabText.Text = e.NewValue))) Public Enum ColorState White Highlight diff --git a/Plain Craft Launcher 2/Controls/MyTextButton.vb b/Plain Craft Launcher 2/Controls/MyTextButton.vb index 3d8245f8..58fcd6ea 100644 --- a/Plain Craft Launcher 2/Controls/MyTextButton.vb +++ b/Plain Craft Launcher 2/Controls/MyTextButton.vb @@ -90,21 +90,21 @@ Get Return GetValue(EventTypeProperty) End Get - Set(value As String) SetValue(EventTypeProperty, value) End Set End Property - Public Shared ReadOnly EventTypeProperty As DependencyProperty = DependencyProperty.Register("EventType", GetType(String), GetType(MyTextButton), New PropertyMetadata(Nothing)) + Public Shared ReadOnly EventTypeProperty As DependencyProperty = DependencyProperty.Register( + "EventType", GetType(String), GetType(MyTextButton), New PropertyMetadata(Nothing)) Public Property EventData As String Get Return GetValue(EventDataProperty) End Get - Set(value As String) SetValue(EventDataProperty, value) End Set End Property - Public Shared ReadOnly EventDataProperty As DependencyProperty = DependencyProperty.Register("EventData", GetType(String), GetType(MyTextButton), New PropertyMetadata(Nothing)) + Public Shared ReadOnly EventDataProperty As DependencyProperty = DependencyProperty.Register( + "EventData", GetType(String), GetType(MyTextButton), New PropertyMetadata(Nothing)) End Class diff --git a/Plain Craft Launcher 2/FormMain.xaml b/Plain Craft Launcher 2/FormMain.xaml index edebd06e..d0a3a5e5 100644 --- a/Plain Craft Launcher 2/FormMain.xaml +++ b/Plain Craft Launcher 2/FormMain.xaml @@ -104,7 +104,7 @@ - + - + diff --git a/Plain Craft Launcher 2/FormMain.xaml.vb b/Plain Craft Launcher 2/FormMain.xaml.vb index 929d7621..c520c422 100644 --- a/Plain Craft Launcher 2/FormMain.xaml.vb +++ b/Plain Craft Launcher 2/FormMain.xaml.vb @@ -69,84 +69,19 @@ Public Class FormMain FeatureCount += 10 BugCount += 10 End If - If LastVersion < 317 Then 'Release 2.6.15 - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法安装 Forge 的 Bug")) - FeatureCount += 2 - BugCount += 2 - End If - If LastVersion < 315 Then 'Release 2.6.14 - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化 MC 下载,尝试解决各种导致 MC 下载失败的问题")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "由于 MCBBS 关站,移除其相关内容")) - FeatureCount += 17 - BugCount += 16 - End If - If LastVersion < 313 Then 'Release 2.6.13 - FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法启动 Forge 1.18.3+ 的 Bug")) - FeatureCount += 6 - BugCount += 10 - End If - If LastVersion < 311 Then 'Release 2.6.12 - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 管理页面将显示 Mod 的中文名、图标、标签等信息")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "从 Mod 管理页面查看 Mod 信息时会跳转到其下载详情页面")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重新设计 Mod 管理页面的交互与样式")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 Forge 1.18.3+ 的 Bug")) - FeatureCount += 27 - BugCount += 25 - End If - If LastVersion < 308 Then 'Release 2.6.10 - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为版本独立设置添加忽略 Java 兼容性警告选项")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复开始或结束游戏时可能报错的 Bug")) - FeatureCount += 31 - BugCount += 37 - End If - If LastVersion < 302 Then 'Release 2.6.7 - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "再次修复网络条件差时可能无法下载 MC 的 Bug")) - BugCount += 1 - End If - If LastVersion < 300 Then 'Release 2.6.6 - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持选择多种预设的主页")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod 管理中允许多选 Mod 进行批量操作")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化崩溃分析,添加多种崩溃情况的判断")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化联网获取的主页的加载与缓存")) - FeatureCount += 40 - BugCount += 34 - End If - If LastVersion < 296 Then 'Release 2.6.3 - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增内存优化功能,可以将所有程序的物理内存占用降低约 1/3")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "在选择 OptiFine 与 Fabric 后会自动选择 OptiFabric")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化崩溃分析,添加多种崩溃情况的判断")) - FeatureCount += 21 - BugCount += 30 - End If - If LastVersion < 293 Then 'Release 2.6.1 - BugCount += 1 - End If - If LastVersion < 292 Then 'Release 2.6.0 - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持在多个正版账号间切换")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "在缺少 Java 时会自动下载所需的 Java")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重新制作正版登录页面")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "彻底移除 Mojang 登录")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 CurseForge / Modrinth 来源筛选")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "Mod / 整合包下载会单独列出筛选的版本")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为下载管理和音乐播放按钮添加进度条")) - FeatureCount += 24 - BugCount += 24 - End If - If LastVersion < 286 Then 'Release 2.5.2 - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "支持搜索、安装 Modrinth 的 Mod 与整合包")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "资源搜索页面支持翻页")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "在全局启动设置中添加了 启动前执行命令 选项")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "重做资源下载的资源项界面")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "在选择下载 Fabric 时会自动选择 Fabric API")) - FeatureCount += 35 - BugCount += 36 - End If #Else '5: FEAT+ '4: IMP+ FEAT* '3:BUG+ IMP* FEAT- '2:BUG* IMP- '1:BUG- + If LastVersion < 341 Then 'Snapshot 2.8.9 + FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持下载原版服务端")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "本地 Mod 的标题支持选择显示 Mod 原始文件名")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复搜索后启用/禁用 Mod 时出错的 Bug")) + FeatureCount += 17 + BugCount += 13 + End If If LastVersion < 339 Then 'Snapshot 2.8.8 If LastVersion = 337 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复数个与新正版登录相关的严重 Bug")) FeatureCount += 3 @@ -233,117 +168,6 @@ Public Class FormMain FeatureCount += 10 BugCount += 10 End If - If LastVersion < 316 Then 'Snapshot 2.6.15 - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复无法安装 Forge 的 Bug")) - FeatureCount += 2 - BugCount += 2 - End If - If LastVersion < 314 Then 'Snapshot 2.6.14 - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化 MC 下载,尝试解决各种导致 MC 下载失败的问题")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "由于 MCBBS 关站,移除其相关内容")) - FeatureCount += 17 - BugCount += 16 - End If - If LastVersion < 312 Then 'Snapshot 2.6.13 - FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法启动 Forge 1.18.3+ 的 Bug")) - FeatureCount += 6 - BugCount += 10 - End If - If LastVersion < 310 Then 'Snapshot 2.6.12 - If LastVersion = 309 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod 管理页面添加启用、禁用单个 Mod 的快捷按钮")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复无法安装 Forge 1.18.3+ 的 Bug")) - FeatureCount += 13 - BugCount += 12 - End If - If LastVersion < 309 Then 'Snapshot 2.6.11 - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "Mod 管理页面将显示 Mod 的中文名、图标、标签等信息")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "从 Mod 管理页面查看 Mod 信息时会跳转到其下载详情页面")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重新设计 Mod 管理页面的交互与样式")) - FeatureCount += 15 - BugCount += 13 - End If - If LastVersion < 307 Then 'Snapshot 2.6.10 - FeatureCount += 2 - BugCount += 3 - End If - If LastVersion < 306 Then 'Snapshot 2.6.9 - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为版本独立设置添加忽略 Java 兼容性警告选项")) - FeatureCount += 9 - BugCount += 11 - End If - If LastVersion < 305 Then 'Snapshot 2.6.8 - FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复开始或结束游戏时可能报错的 Bug")) - FeatureCount += 20 - BugCount += 25 - End If - If LastVersion < 303 Then 'Snapshot 2.6.7 - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "再次修复网络条件差时可能无法下载 MC 的 Bug")) - BugCount += 1 - End If - If LastVersion < 301 Then 'Snapshot 2.6.6 - FeatureCount += 4 - BugCount += 2 - End If - If LastVersion < 299 Then 'Snapshot 2.6.5 - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持选择多种预设的主页")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化联网获取的主页的加载与缓存")) - FeatureCount += 18 - BugCount += 13 - End If - If LastVersion < 298 Then 'Snapshot 2.6.4 - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "Mod 管理中允许多选 Mod 进行批量操作")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化崩溃分析,添加多种崩溃情况的判断")) - FeatureCount += 18 - BugCount += 19 - End If - If LastVersion < 297 Then 'Snapshot 2.6.3 - FeatureCount += 12 - BugCount += 14 - End If - If LastVersion < 294 Then 'Snapshot 2.6.2 - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "新增内存优化功能,可以将所有程序的物理内存占用降低约 1/3")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "在选择 OptiFine 与 Fabric 后会自动选择 OptiFabric")) - FeatureCount += 9 - BugCount += 16 - End If - If LastVersion < 291 Then 'Snapshot 2.6.0 - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "支持在多个正版账号间切换")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "Mod / 整合包下载会单独列出筛选的版本")) - FeatureCount += 10 - BugCount += 2 - End If - If LastVersion < 289 Then 'Snapshot 2.5.4 - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "重新制作正版登录页面")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "彻底移除 Mojang 登录")) - FeatureCount += 6 - BugCount += 14 - End If - If LastVersion < 288 Then 'Snapshot 2.5.3 - FeatureList.Add(New KeyValuePair(Of Integer, String)(4, "在缺少 Java 时会自动下载所需的 Java")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "添加 CurseForge / Modrinth 来源筛选")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "为下载管理和音乐播放按钮添加进度条")) - FeatureCount += 8 - BugCount += 8 - End If - If LastVersion < 285 Then 'Snapshot 2.5.2 - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "重做资源下载的资源项界面")) - If LastVersion = 284 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复打开部分帮助报错的 Bug")) - FeatureCount += 8 - BugCount += 8 - End If - If LastVersion < 284 Then 'Snapshot 2.5.1 - If LastVersion >= 275 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "在全局启动设置中添加了 启动前执行命令 选项")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "在选择下载 Fabric 时会自动选择 Fabric API")) - FeatureCount += 22 - BugCount += 21 - End If - If LastVersion < 283 Then 'Snapshot 2.5.0 - FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "支持搜索、下载 Modrinth 中的 Mod 与整合包")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "资源搜索页面支持翻页")) - FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "支持安装 Modrinth 整合包")) - FeatureCount += 5 - BugCount += 5 - End If #End If '整理更新日志文本 Dim ContentList As New List(Of String) @@ -386,9 +210,6 @@ Public Class FormMain '触发降级 DowngradeSub(LastVersion) End If - ''刷新语言 - 'Lang = ReadReg("Lang", "zh_CN") - 'Application.Current.Resources.MergedDictionaries(1) = New ResourceDictionary With {.Source = New Uri("Resources\Language\" & Lang & ".xaml", UriKind.Relative)} '刷新主题 ThemeCheckAll(False) Setup.Load("UiLauncherTheme") @@ -451,12 +272,12 @@ Public Class FormMain '加载窗口 ThemeRefreshMain() Try - Height = ReadReg("WindowHeight", MinHeight + 50) - Width = ReadReg("WindowWidth", MinWidth + 50) + Height = Setup.Get("WindowHeight") + Width = Setup.Get("WindowWidth") Catch ex As Exception '修复 #2019 Log(ex, "读取窗口默认大小失败", LogLevel.Hint) - Height = MinHeight + 50 - Width = MinWidth + 50 + Height = MinHeight + 100 + Width = MinWidth + 100 End Try #If DEBUG Then MinHeight = 50 @@ -595,6 +416,16 @@ Public Class FormMain Setup.Set("UiHiddenOtherHelp", False) Log("[Start] 已解除帮助页面的隐藏") End If + '单向迁移微软登录结果(#4836) + If Not Setup.Get("CacheMsV2Migrated") Then + Setup.Set("CacheMsV2Migrated", True) + Setup.Set("CacheMsV2OAuthRefresh", Setup.Get("CacheMsOAuthRefresh")) + Setup.Set("CacheMsV2Access", Setup.Get("CacheMsAccess")) + Setup.Set("CacheMsV2ProfileJson", Setup.Get("CacheMsProfileJson")) + Setup.Set("CacheMsV2Uuid", Setup.Get("CacheMsUuid")) + Setup.Set("CacheMsV2Name", Setup.Get("CacheMsName")) + Log("[Start] 已从老版本迁移微软登录结果") + End If '输出更新日志 If LastVersionCode = 0 Then Exit Sub If LowerVersionCode >= VersionCode Then Exit Sub @@ -636,35 +467,35 @@ Public Class FormMain End If '关闭 RunInUiWait( - Sub() - IsHitTestVisible = False - If PanBack.RenderTransform Is Nothing Then - Dim TransformPos As New TranslateTransform(0, 0) - Dim TransformRotate As New RotateTransform(0) - Dim TransformScale As New ScaleTransform(1, 1) - PanBack.RenderTransform = New TransformGroup() With {.Children = New TransformCollection({TransformRotate, TransformPos, TransformScale})} - AniStart({ - AaOpacity(Me, -Opacity, 140, 40, New AniEaseOutFluent(AniEasePower.Weak)), - AaDouble( - Sub(i) - TransformScale.ScaleX += i - TransformScale.ScaleY += i - End Sub, 0.88 - TransformScale.ScaleX, 180), - AaDouble(Sub(i) TransformPos.Y += i, 20 - TransformPos.Y, 180, 0, New AniEaseOutFluent(AniEasePower.Weak)), - AaDouble(Sub(i) TransformRotate.Angle += i, 0.6 - TransformRotate.Angle, 180, 0, New AniEaseInoutFluent(AniEasePower.Weak)), - AaCode( - Sub() - IsHitTestVisible = False - Top = -10000 - ShowInTaskbar = False - End Sub, 210), - AaCode(AddressOf EndProgramForce, 230) - }, "Form Close") - Else - EndProgramForce() - End If - Log("[System] 收到关闭指令") - End Sub) + Sub() + IsHitTestVisible = False + If PanBack.RenderTransform Is Nothing Then + Dim TransformPos As New TranslateTransform(0, 0) + Dim TransformRotate As New RotateTransform(0) + Dim TransformScale As New ScaleTransform(1, 1) + PanBack.RenderTransform = New TransformGroup() With {.Children = New TransformCollection({TransformRotate, TransformPos, TransformScale})} + AniStart({ + AaOpacity(Me, -Opacity, 140, 40, New AniEaseOutFluent(AniEasePower.Weak)), + AaDouble( + Sub(i) + TransformScale.ScaleX += i + TransformScale.ScaleY += i + End Sub, 0.88 - TransformScale.ScaleX, 180), + AaDouble(Sub(i) TransformPos.Y += i, 20 - TransformPos.Y, 180, 0, New AniEaseOutFluent(AniEasePower.Weak)), + AaDouble(Sub(i) TransformRotate.Angle += i, 0.6 - TransformRotate.Angle, 180, 0, New AniEaseInoutFluent(AniEasePower.Weak)), + AaCode( + Sub() + IsHitTestVisible = False + Top = -10000 + ShowInTaskbar = False + End Sub, 210), + AaCode(AddressOf EndProgramForce, 230) + }, "Form Close") + Else + EndProgramForce() + End If + Log("[System] 收到关闭指令") + End Sub) End Sub Private Shared IsLogShown As Boolean = False Public Shared Sub EndProgramForce(Optional ReturnCode As Result = Result.Success) @@ -709,8 +540,8 @@ Public Class FormMain Public IsSizeSaveable As Boolean = False Private Sub FormMain_SizeChanged() Handles Me.SizeChanged, Me.Loaded If IsSizeSaveable Then - WriteReg("WindowHeight", Height) - WriteReg("WindowWidth", Width) + Setup.Set("WindowHeight", Height) + Setup.Set("WindowWidth", Width) End If RectForm.Rect = New Rect(0, 0, BorderForm.ActualWidth, BorderForm.ActualHeight) PanForm.Width = BorderForm.ActualWidth + 0.001 @@ -921,11 +752,12 @@ Public Class FormMain End If End If CopyFile(FilePath, Path & "PCL\Custom.xaml") - RunInUi(Sub() - Setup.Set("UiCustomType", 1) - FrmLaunchRight.ForceRefresh() - Hint("已加载主页自定义文件!", HintType.Finish) - End Sub) + RunInUi( + Sub() + Setup.Set("UiCustomType", 1) + FrmLaunchRight.ForceRefresh() + Hint("已加载主页自定义文件!", HintType.Finish) + End Sub) Exit Sub End If 'Mod 安装 diff --git a/Plain Craft Launcher 2/Modules/Base/ModBase.vb b/Plain Craft Launcher 2/Modules/Base/ModBase.vb index ca5aab48..2f13ab03 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModBase.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModBase.vb @@ -12,13 +12,13 @@ Public Module ModBase #Region "声明" '下列版本信息由更新器自动修改 - Public Const VersionBaseName As String = "2.8.8" '不含分支前缀的显示用版本名 - Public Const VersionStandardCode As String = "2.8.8." & VersionBranchCode '标准格式的四段式版本号 + Public Const VersionBaseName As String = "2.8.9" '不含分支前缀的显示用版本名 + Public Const VersionStandardCode As String = "2.8.9." & VersionBranchCode '标准格式的四段式版本号 Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换 #If BETA Then Public Const VersionCode As Integer = 340 'Release #Else - Public Const VersionCode As Integer = 339 'Snapshot + Public Const VersionCode As Integer = 341 'Snapshot #End If '自动生成的版本信息 Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName @@ -176,9 +176,9 @@ Public Module ModBase ''' Public Const IconButtonOffline As String = "M533.293176 788.841412a60.235294 60.235294 0 1 1 85.202824 85.202823l-42.616471 42.586353c-129.355294 129.385412-339.124706 129.385412-468.510117 0-129.385412-129.385412-129.385412-339.124706 0-468.510117l42.586353-42.616471a60.235294 60.235294 0 1 1 85.202823 85.202824l-42.61647 42.586352a210.823529 210.823529 0 1 0 298.164706 298.164706l42.586352-42.61647z m255.548236-255.548236l42.61647-42.586352a210.823529 210.823529 0 1 0-298.164706-298.164706l-42.586352 42.61647a60.235294 60.235294 0 1 1-85.202824-85.202823l42.616471-42.586353c129.355294-129.385412 339.124706-129.385412 468.510117 0 129.385412 129.385412 129.385412 339.124706 0 468.510117l-42.586353 42.616471a60.235294 60.235294 0 1 1-85.202823-85.202824zM192.542118 192.542118a60.235294 60.235294 0 0 1 85.202823 0l553.712941 553.712941a60.235294 60.235294 0 0 1-85.202823 85.202823L192.542118 277.744941a60.235294 60.235294 0 0 1 0-85.202823z" ''' - ''' 图标,音符,1x + ''' 图标,服务端,1x ''' - Public Const IconButtonServer As String = "M640 725.333333a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m-256 0H256a42.666667 42.666667 0 0 0 0 85.333334h128a42.666667 42.666667 0 1 0 0-85.333334z m384 0a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m-128-256a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m-256 0H256a42.666667 42.666667 0 1 0 0 85.333334h128a42.666667 42.666667 0 1 0 0-85.333334z m384-256a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m0 256a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m170.666667-256a128 128 0 0 0-128-128H213.333333a128 128 0 0 0-128 128v85.333334a128 128 0 0 0 33.28 85.333333A128 128 0 0 0 85.333333 469.333333v85.333334a128 128 0 0 0 33.28 85.333333A128 128 0 0 0 85.333333 725.333333v85.333334a128 128 0 0 0 128 128h597.333334a128 128 0 0 0 128-128v-85.333334a128 128 0 0 0-33.28-85.333333 128 128 0 0 0 33.28-85.333333v-85.333334a128 128 0 0 0-33.28-85.333333A128 128 0 0 0 938.666667 298.666667V213.333333z m-85.333334 597.333334a42.666667 42.666667 0 0 1-42.666666 42.666666H213.333333a42.666667 42.666667 0 0 1-42.666666-42.666666v-85.333334a42.666667 42.666667 0 0 1 42.666666-42.666666h597.333334a42.666667 42.666667 0 0 1 42.666666 42.666666v85.333334z m0-256a42.666667 42.666667 0 0 1-42.666666 42.666666H213.333333a42.666667 42.666667 0 0 1-42.666666-42.666666v-85.333334a42.666667 42.666667 0 0 1 42.666666-42.666666h597.333334a42.666667 42.666667 0 0 1 42.666666 42.666666v85.333334z m0-256a42.666667 42.666667 0 0 1-42.666666 42.666666H213.333333a42.666667 42.666667 0 0 1-42.666666-42.666666V213.333333a42.666667 42.666667 0 0 1 42.666666-42.666666h597.333334a42.666667 42.666667 0 0 1 42.666666 42.666666v85.333334z m-213.333333-85.333334a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334zM384 213.333333H256a42.666667 42.666667 0 1 0 0 85.333334h128a42.666667 42.666667 0 1 0 0-85.333334z" + Public Const IconButtonServer As String = "M224 160a64 64 0 0 0-64 64v576a64 64 0 0 0 64 64h576a64 64 0 0 0 64-64V224a64 64 0 0 0-64-64H224z m0 384h576v256H224v-256z m192 96v64h320v-64H416z m-128 0v64h64v-64H288zM224 224h576v256H224V224z m192 96v64h320v-64H416z m-128 0v64h64v-64H288z" ''' ''' 图标,音符,1x ''' @@ -1348,8 +1348,8 @@ RetryDir: '常见错误(记得同时修改下面的) Dim CommonReason As String = Nothing - If TypeOf InnerEx Is TypeLoadException OrElse TypeOf InnerEx Is MissingMethodException OrElse TypeOf InnerEx Is NotImplementedException OrElse TypeOf InnerEx Is TypeInitializationException Then - CommonReason = "PCL 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。" + If TypeOf InnerEx Is TypeLoadException OrElse TypeOf InnerEx Is BadImageFormatException OrElse TypeOf InnerEx Is MissingMethodException OrElse TypeOf InnerEx Is NotImplementedException OrElse TypeOf InnerEx Is TypeInitializationException Then + CommonReason = "PCL 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。若无法安装,请先卸载较新版本的 .NET Framework,然后再尝试安装。" ElseIf TypeOf InnerEx Is UnauthorizedAccessException Then CommonReason = "PCL 的权限不足。请尝试右键 PCL,选择以管理员身份运行。" ElseIf TypeOf InnerEx Is OutOfMemoryException Then @@ -1368,7 +1368,7 @@ RetryDir: If CommonReason Is Nothing Then Return Desc & Stack & TypeDesc Else - Dim Result As String = DescList.First & vbCrLf & CommonReason & vbCrLf & "————————————" & vbCrLf + Dim Result As String = CommonReason & vbCrLf & DescList.First & vbCrLf & "————————————" & vbCrLf DescList(0) = "详细错误信息:" Return Result & Join(DescList, vbCrLf & "→ ") & Stack & TypeDesc End If @@ -1396,8 +1396,8 @@ RetryDir: '常见错误(记得同时修改上面的) Dim CommonReason As String = Nothing - If TypeOf InnerEx Is TypeLoadException OrElse TypeOf InnerEx Is MissingMethodException OrElse TypeOf InnerEx Is NotImplementedException OrElse TypeOf InnerEx Is TypeInitializationException Then - CommonReason = "PCL 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。" + If TypeOf InnerEx Is TypeLoadException OrElse TypeOf InnerEx Is BadImageFormatException OrElse TypeOf InnerEx Is MissingMethodException OrElse TypeOf InnerEx Is NotImplementedException OrElse TypeOf InnerEx Is TypeInitializationException Then + CommonReason = "PCL 的运行环境存在问题。请尝试重新安装 .NET Framework 4.6.2 然后再试。若无法安装,请先卸载较新版本的 .NET Framework,然后再尝试安装。" ElseIf TypeOf InnerEx Is UnauthorizedAccessException Then CommonReason = "PCL 的权限不足。请尝试右键 PCL,选择以管理员身份运行。" ElseIf TypeOf InnerEx Is OutOfMemoryException Then @@ -1411,7 +1411,7 @@ RetryDir: '构造输出信息 If CommonReason IsNot Nothing Then - Return DescList.First & ":" & CommonReason + Return CommonReason & "详细错误:" & DescList.First Else DescList.Reverse() '让最深层错误在最左边 Return Join(DescList, " → ") @@ -1721,16 +1721,6 @@ RetryDir: Public Function RegexReplaceEach(Input As String, Replacement As MatchEvaluator, Regex As String, Optional options As RegexOptions = RegularExpressions.RegexOptions.None) As String Return RegularExpressions.Regex.Replace(Input, Regex, Replacement, options) End Function - ''' - ''' 检查传入字符串会不会引发 Issue #4505 - ''' - Public Function Ntfs83NameCheck(name As String) As Boolean - Dim regex As New Regex("(.*)~(\d*)") - Dim namePart As Byte() = Encoding.UTF8.GetBytes(regex.Match(name).Groups(1).Value) - Dim numPart As Integer = regex.Match(name).Groups(2).Value.Length - - Return namePart.Length >= 6 AndAlso numPart = 1 - End Function #End Region @@ -1822,10 +1812,10 @@ RetryDir: '进行搜索,获取相似信息 For Each Entry In Entries Entry.Similarity = SearchSimilarityWeighted(Entry.SearchSource, Query) - Entry.AbsoluteRight = False - For Each Pair In Entry.SearchSource - If Pair.Key.Replace(" ", "").ContainsF(Query.Replace(" ", ""), True) Then Entry.AbsoluteRight = True - Next + Entry.AbsoluteRight = + Query.Split(" ").All( '对于按空格分割的每一段 + Function(QueryPart) Entry.SearchSource.Any( '若与任意一个搜索源完全匹配,则标记为完全匹配项 + Function(Source) Source.Key.Replace(" ", "").ContainsF(QueryPart, True))) Next '按照相似度进行排序 Entries = Sort(Entries, @@ -1854,10 +1844,26 @@ RetryDir: #Region "系统" + ''' + ''' 可用于临时存放文件的,不含任何特殊字符的文件夹路径,以“\”结尾。 + ''' + Public PathPure As String = GetPureASCIIDir() + Private Function GetPureASCIIDir() As String + If (Path & "PCL").IsASCII() Then + Return Path & "PCL\" + ElseIf PathAppdata.IsASCII() Then + Return PathAppdata + ElseIf PathTemp.IsASCII() Then + Return PathTemp + Else + Return OsDrive & "ProgramData\PCL\" + End If + End Function + ''' ''' 指示接取到这个异常的函数进行重试。 ''' - Public Class RetryException + Public Class RestartException Inherits Exception End Class diff --git a/Plain Craft Launcher 2/Modules/Base/ModNet.vb b/Plain Craft Launcher 2/Modules/Base/ModNet.vb index ea13ad88..db4b3081 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModNet.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModNet.vb @@ -939,7 +939,6 @@ RequestFinished: Dim StartPosition As Long, StartSource As NetSource = Nothing Dim Th As Thread, ThreadInfo As NetThread SyncLock LockChain - '获取线程起点与下载源 '不分割 If IsNoSplit Then GoTo Capture @@ -1049,6 +1048,15 @@ StartThread: If ModeDebug AndAlso HttpResponse.ResponseUri.OriginalString <> Info.Source.Url Then Log($"[Download] {LocalName} {Info.Uuid}#:重定向至 {HttpResponse.ResponseUri.OriginalString}") End If + ''从响应头获取文件名 + 'If Info.IsFirstThread Then + ' Dim FileName As String = GetFileNameFromResponse(HttpResponse) + ' If ModeDebug Then Log($"[Download] {LocalName} {Info.Uuid}#:远程文件名:{If(FileName, "未提供")}") + ' If FileName IsNot Nothing AndAlso LocalName = "待定" Then + ' LocalName = FileName + ' Log($"[Download] {LocalName} {Info.Uuid}#:从响应头获取到文件名") + ' End If + 'End If '文件大小校验 ContentLength = HttpResponse.ContentLength If ContentLength = -1 Then @@ -1133,7 +1141,7 @@ NotSupportRange: If NetTaskSpeedLimitHigh > 0 Then NetTaskSpeedLimitLeft -= RealDataCount End SyncLock Dim DeltaTime = GetTimeTick() - Info.LastReceiveTime - If DeltaTime > 1000000 Then DeltaTime = 0 '时间刻反转导致出现极大值 + If DeltaTime > 1000000 Then DeltaTime = 1 '时间刻反转导致出现极大值 If RealDataCount > 0 Then '有数据 If Info.DownloadDone = 0 Then @@ -1174,7 +1182,7 @@ NotSupportRange: ResultStream.Write(HttpData, 0, RealDataCount) End If '检查速度是否过慢 - If DeltaTime > 1000 AndAlso DeltaTime > RealDataCount Then '数据包间隔大于 1s,且速度小于 1K/s + If DeltaTime > 1500 AndAlso DeltaTime > RealDataCount Then '数据包间隔大于 1.5s,且速度小于 1.5K/s Throw New TimeoutException("由于速度过慢断开链接,下载 " & RealDataCount & " B,消耗 " & DeltaTime & " ms。") End If Info.LastReceiveTime = GetTimeTick() @@ -1286,6 +1294,17 @@ Wrong: If ((FileSize >= 0 AndAlso DownloadDone >= FileSize) OrElse (FileSize = -1 AndAlso DownloadDone > 0)) AndAlso State < NetState.Merge Then Merge() End Try End Sub + ''' + ''' 从 HTTP 响应头中获取文件名。 + ''' 如果没有,返回 Nothing。 + ''' + Private Function GetFileNameFromResponse(response As HttpWebResponse) As String + Dim header As String = response.Headers("Content-Disposition") + If String.IsNullOrEmpty(header) Then Return Nothing + 'attachment; filename="filename.ext" + If Not header.Contains("filename=") Then Return Nothing + Return header.After("filename=").Trim(""""c, " "c).Before(";") + End Function '下载文件的最终收束事件 ''' diff --git a/Plain Craft Launcher 2/Modules/Base/ModValidate.vb b/Plain Craft Launcher 2/Modules/Base/ModValidate.vb index 0321004b..03940607 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModValidate.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModValidate.vb @@ -233,8 +233,8 @@ Public Class ValidateFolderName '检查特殊字符串 Dim InvalidStrCheck As String = New ValidateExceptSame({"CON", "PRN", "AUX", "CLOCK$", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"}, "文件夹名不可为 %!", True).Validate(Str) If Not InvalidStrCheck = "" Then Return InvalidStrCheck - '检查 NTFS 8.3 (issue #4505) - If Ntfs83NameCheck(Str) Then Return "文件夹名不能是一个有效的 NTFS 8.3 文件名!" + '检查 NTFS 8.3 文件名(#4505) + If RegexCheck(Str, ".{2,}~\d") Then Return "文件夹名不能包含这一特殊格式!" '检查文件夹重名 Dim Arr As New List(Of String) If PathIgnore IsNot Nothing Then @@ -288,8 +288,8 @@ Public Class ValidateFileName '检查特殊字符串 Dim InvalidStrCheck As String = New ValidateExceptSame({"CON", "PRN", "AUX", "CLOCK$", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"}, "文件名不可为 %!", True).Validate(Str) If Not InvalidStrCheck = "" Then Return InvalidStrCheck - '检查 NTFS 8.3 (issue #4505) - If Ntfs83NameCheck(Str) Then Return "文件名不能是一个有效的 NTFS 8.3 文件名!" + '检查 NTFS 8.3 文件名(#4505) + If RegexCheck(Str, ".{2,}~\d") Then Return "文件名不能包含这一特殊格式!" '检查文件重名 If ParentFolder IsNot Nothing Then Dim DirInfo As New DirectoryInfo(ParentFolder) @@ -355,9 +355,9 @@ Fin: '检查特殊字符串 Dim InvalidStrCheck As String = New ValidateExceptSame({"CON", "PRN", "AUX", "CLOCK$", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"}, "文件夹名不可为 %!").Validate(SubStr) If Not InvalidStrCheck = "" Then Return InvalidStrCheck - '检查 NTFS 8.3 (issue #4505) - If Ntfs83NameCheck(Str) Then Return "文件夹名不能是一个有效的 NTFS 8.3 文件名!" + '检查 NTFS 8.3 文件名(#4505) + If RegexCheck(Str, ".{2,}~\d") Then Return "文件夹名不能包含这一特殊格式!" Next Return "" End Function -End Class \ No newline at end of file +End Class diff --git a/Plain Craft Launcher 2/Modules/Base/MyBitmap.vb b/Plain Craft Launcher 2/Modules/Base/MyBitmap.vb index ac9fb213..e126d616 100644 --- a/Plain Craft Launcher 2/Modules/Base/MyBitmap.vb +++ b/Plain Craft Launcher 2/Modules/Base/MyBitmap.vb @@ -7,7 +7,7 @@ Public Class MyBitmap ''' ''' 位图缓存。 ''' - Public Shared BitmapCache As New Dictionary(Of String, MyBitmap) + Public Shared BitmapCache As New Concurrent.ConcurrentDictionary(Of String, MyBitmap) ''' ''' 存储的图片 @@ -61,7 +61,7 @@ Public Class MyBitmap Pic = BitmapCache(FilePathOrResourceName).Pic Else Pic = New MyBitmap(CType((New ImageSourceConverter).ConvertFromString(FilePathOrResourceName), ImageSource)) - BitmapCache.Add(FilePathOrResourceName, Pic) + BitmapCache.TryAdd(FilePathOrResourceName, Pic) End If Else '使用这种自己接管 FileStream 的方法加载才能解除文件占用 @@ -72,11 +72,9 @@ Public Class MyBitmap InputStream.Seek(0, SeekOrigin.Begin) If Header(0) = 82 AndAlso Header(1) = 73 Then '读取 WebP - If Is32BitSystem Then Throw New Exception("不支持在 32 位系统下加载 WebP 图片。") Dim FileBytes(InputStream.Length - 1) As Byte InputStream.Read(FileBytes, 0, FileBytes.Length) - Dim Decoder As New Imazen.WebP.SimpleDecoder() - Pic = Decoder.DecodeFromBytes(FileBytes, FileBytes.Length) + Pic = WebPDecoder.DecodeFromBytes(FileBytes) '将代码隔离在另外一个类中,这样只要不走进这个分支就不会加载 Imazen.WebP.dll Else Pic = New System.Drawing.Bitmap(InputStream) End If @@ -86,10 +84,9 @@ Public Class MyBitmap Pic = My.Application.TryFindResource(FilePathOrResourceName) If Pic Is Nothing Then Pic = New System.Drawing.Bitmap(1, 1) - Log(ex, $"加载位图失败({FilePathOrResourceName})") - Throw + Throw New Exception($"加载 MyBitmap 失败({FilePathOrResourceName})", ex) Else - Log(ex, $"指定类型有误的位图加载({FilePathOrResourceName})", LogLevel.Developer) + Log(ex, $"指定类型有误的 MyBitmap 加载({FilePathOrResourceName})", LogLevel.Developer) Exit Try End If End Try @@ -116,6 +113,13 @@ Public Class MyBitmap Pic = New System.Drawing.Bitmap(MS) End Using End Sub + Private Class WebPDecoder '将代码隔离在另外一个类中,这样只要不调用这个方法就不会加载 Imazen.WebP.dll + Public Shared Function DecodeFromBytes(Bytes As Byte()) As System.Drawing.Bitmap + If Is32BitSystem Then Throw New Exception("不支持在 32 位系统下加载 WebP 图片。") + Dim Decoder As New Imazen.WebP.SimpleDecoder() + Return Decoder.DecodeFromBytes(Bytes, Bytes.Length) + End Function + End Class ''' ''' 获取裁切的图片,这个方法不会导致原对象改变且会返回一个新的对象。 @@ -152,4 +156,4 @@ Public Class MyBitmap End Using End Sub -End Class \ No newline at end of file +End Class diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb index f1f070e0..c88ce9ff 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb @@ -389,7 +389,7 @@ Extracted: 版本Json中存在多个Forge Mod过多导致超出ID限制 NightConfig的Bug - ShadersMod与Optifine同时安装 + ShadersMod与OptiFine同时安装 Forge安装不完整 Mod需要Java11 Mod缺少前置或MC版本错误 @@ -516,7 +516,7 @@ Done: If LogMc.Contains("java.lang.ClassNotFoundException: org.spongepowered.asm.launch.MixinTweaker") Then AppendReason(CrashReason.MixinBootstrap缺失) If LogMc.Contains("Couldn't set pixel format") Then AppendReason(CrashReason.显卡驱动不支持导致无法设置像素格式) If LogMc.Contains("java.lang.OutOfMemoryError") OrElse LogMc.Contains("an out of memory error") Then AppendReason(CrashReason.内存不足) - If LogMc.Contains("java.lang.RuntimeException: Shaders Mod detected. Please remove it, OptiFine has built-in support for shaders.") Then AppendReason(CrashReason.ShadersMod与Optifine同时安装) + If LogMc.Contains("java.lang.RuntimeException: Shaders Mod detected. Please remove it, OptiFine has built-in support for shaders.") Then AppendReason(CrashReason.ShadersMod与OptiFine同时安装) If LogMc.Contains("java.lang.NoSuchMethodError: sun.security.util.ManifestEntryVerifier") Then AppendReason(CrashReason.低版本Forge与高版本Java不兼容) If LogMc.Contains("1282: Invalid operation") Then AppendReason(CrashReason.光影或资源包导致OpenGL1282错误) If LogMc.Contains("signer information does not match signer information of other classes in the same package") Then AppendReason(CrashReason.文件或内容校验失败, If(RegexSeek(LogMc, "(?<=class "")[^']+(?=""'s signer information)"), "").TrimEnd(vbCrLf)) @@ -525,6 +525,7 @@ Done: If LogMc.Contains("Unsupported class file major version") Then AppendReason(CrashReason.Java版本不兼容) If LogMc.Contains("com.electronwill.nightconfig.core.io.ParsingException: Not enough data available") Then AppendReason(CrashReason.NightConfig的Bug) If LogMc.Contains("Cannot find launch target fmlclient, unable to launch") Then AppendReason(CrashReason.Forge安装不完整) + If LogMc.Contains("Invalid paths argument, contained no existing paths") AndAlso LogMc.Contains("libraries\net\minecraftforge\fmlcore") Then AppendReason(CrashReason.Forge安装不完整) If LogMc.Contains("Invalid module name: '' is not a Java identifier") Then AppendReason(CrashReason.Mod名称包含特殊字符) If LogMc.Contains("has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to") Then AppendReason(CrashReason.Mod需要Java11) If LogMc.Contains("java.lang.RuntimeException: java.lang.NoSuchMethodException: no such method: sun.misc.Unsafe.defineAnonymousClass(Class,byte[],Object[])Class/invokeVirtual") Then AppendReason(CrashReason.Mod需要Java11) @@ -623,8 +624,11 @@ Done: '崩溃报告分析 If LogCrash IsNot Nothing Then If LogCrash.Contains("Suspected Mod") Then - Dim Suspects = RegexSearch(LogCrash.Between("Suspected Mod", "Stacktrace"), "(?<=\n\t[^(\t]+\()[^)\n]+") - If Suspects.Any Then AppendReason(CrashReason.怀疑Mod导致游戏崩溃, TryAnalyzeModName(Suspects)) + Dim SuspectsRaw As String = LogCrash.Between("Suspected Mod", "Stacktrace") + If Not SuspectsRaw.StartsWithF("s: None") Then 'Suspected Mods: None + Dim Suspects = RegexSearch(SuspectsRaw, "(?<=\n\t[^(\t]+\()[^)\n]+") + If Suspects.Any Then AppendReason(CrashReason.怀疑Mod导致游戏崩溃, TryAnalyzeModName(Suspects)) + End If End If End If @@ -744,7 +748,7 @@ NextStack: '[Fabric] 获取所有包含 Mod 信息的行 Dim ModNameLines As New List(Of String) For Each Line In Details.Split(vbLf) - If Line.ContainsF(".jar", True) OrElse + If (Line.ContainsF(".jar", True) AndAlso Line.Length - Line.Replace(".jar", "").Length = 4) OrElse '只有一个 .jar (IsFabricDetail AndAlso Line.StartsWithF(vbTab & vbTab) AndAlso Not RegexCheck(Line, "\t\tfabric[\w-]*: Fabric")) Then ModNameLines.Add(Line) Next Log("[Crash] 崩溃报告中找到 " & ModNameLines.Count & " 个可能的 Mod 项目行") @@ -886,6 +890,7 @@ NextStack: WriteFile(TempFolder & "Report\" & FileName, SecretFilter(ReadFile(OutputFile, FileEncoding), If(FileName = "启动脚本.bat", "F", "*")), Encoding:=FileEncoding) + Log($"[Crash] 导出文件:{FileName},编码:{FileEncoding.HeaderName}") End If Next '导出报告 @@ -942,9 +947,9 @@ NextStack: End If Case CrashReason.Mod缺少前置或MC版本错误 If Additional.Any Then - Results.Add("由于未满足 Mod 的依赖项,导致游戏退出。\n未满足的依赖项:\n - " & Join(Additional, "\n - ") & "\n\n请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。") + Results.Add("由于未安装正确的前置 Mod,导致游戏退出。\n缺失的依赖项:\n - " & Join(Additional, "\n - ") & "\n\n请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。") Else - Results.Add("由于未满足 Mod 的依赖项,导致游戏退出。\n请根据错误报告中的日志信息进行对应处理,如果看不懂英文可以使用翻译软件。\h") + Results.Add("由于未安装正确的前置 Mod,导致游戏退出。\n请根据错误报告中的日志信息进行对应处理,如果看不懂英文可以使用翻译软件。\h") End If Case CrashReason.堆栈分析发现关键字 If Additional.Count = 1 Then @@ -980,7 +985,7 @@ NextStack: If Additional.Count = 1 Then Results.Add("名为 " & Additional.First & " 的 Mod 初始化失败,导致游戏无法继续加载。\n你可以尝试禁用此 Mod,然后观察游戏是否还会崩溃。\n\e\h") Else - Results.Add("以下 Mod 初始化失败,导致游戏无法继续加载:\n - " & Join(Additional, "\n - ") & "\n\n你可以尝试依次禁用上述 Mod,然后观察游戏是否还会崩溃。\n\e\h") + Results.Add("以下 Mod 初始化失败,导致游戏出错:\n - " & Join(Additional, "\n - ") & "\n\n你可以尝试依次禁用上述 Mod,然后观察游戏是否还会崩溃。\n\e\h") End If Case CrashReason.特定方块导致崩溃 If Additional.Count = 1 Then @@ -992,7 +997,7 @@ NextStack: If Additional.Count >= 2 Then Results.Add("你重复安装了多个相同的 Mod:\n - " & Join(Additional, "\n - ") & "\n\n每个 Mod 只能出现一次,请删除重复的 Mod,然后再启动游戏。") Else - Results.Add("你可能重复安装了多个相同的 Mod,导致游戏无法继续加载。\n\n每个 Mod 只能出现一次,请删除重复的 Mod,然后再启动游戏。\e\h") + Results.Add("你可能重复安装了多个相同的 Mod,导致游戏出错。\n\n每个 Mod 只能出现一次,请删除重复的 Mod,然后再启动游戏。\e\h") End If Case CrashReason.特定实体导致崩溃 If Additional.Count = 1 Then @@ -1002,12 +1007,12 @@ NextStack: End If Case CrashReason.OptiFine与Forge不兼容 Results.Add("由于 OptiFine 与当前版本的 Forge 不兼容,导致了游戏崩溃。\n\n请前往 OptiFine 官网(https://optifine.net/downloads)查看 OptiFine 所兼容的 Forge 版本,并严格按照对应版本重新安装游戏。") - Case CrashReason.ShadersMod与Optifine同时安装 - Results.Add("无需同时安装 Optifine 和 Shaders Mod,Optifine 已经集成了 Shaders Mod 的功能。\n在删除 Shaders Mod 后,游戏即可正常运行。") + Case CrashReason.ShadersMod与OptiFine同时安装 + Results.Add("无需同时安装 Optifine 和 Shaders Mod,OptiFine 已经集成了 Shaders Mod 的功能。\n在删除 Shaders Mod 后,游戏即可正常运行。") Case CrashReason.低版本Forge与高版本Java不兼容 Results.Add("由于低版本 Forge 与当前 Java 不兼容,导致了游戏崩溃。\n\n请尝试以下解决方案:\n - 更新 Forge 到 36.2.26 或更高版本\n - 换用版本低于 1.8.0.320 的 Java") Case CrashReason.版本Json中存在多个Forge - Results.Add("可能由于使用其他启动器修改了 Forge 版本,当前版本的文件存在异常,导致了游戏崩溃。\n请尝试重新全新安装 Forge,而非使用其他启动器修改 Forge 版本。") + Results.Add("可能由于其他启动器修改了 Forge 版本,当前版本的文件存在异常,导致了游戏崩溃。\n请尝试重新全新安装 Forge,而非使用其他启动器修改 Forge 版本。") Case CrashReason.玩家手动触发调试崩溃 Results.Add("* 事实上,你的游戏没有任何问题,这是你自己触发的崩溃。\n* 你难道没有更重要的事要做吗?") Case CrashReason.Mod需要Java11 @@ -1033,7 +1038,7 @@ NextStack: Case CrashReason.文件或内容校验失败 Results.Add("部分文件或内容校验失败,导致游戏出现了问题。\n\n请尝试删除游戏(包括 Mod)并重新下载,或尝试在重新下载时使用 VPN。\h") Case CrashReason.Forge安装不完整 - Results.Add("由于 Forge 安装不完整,导致游戏无法正常运行。\n请尝试重新安装 Forge。\h") + Results.Add("由于安装的 Forge 文件丢失,导致游戏无法正常运行。\n请重新安装一次相同版本的 Forge,然后再启动游戏。\n在打包游戏时删除 libraries 文件夹可能导致此错误。\h") Case CrashReason.Fabric报错 If Additional.Count = 1 Then Results.Add("Fabric 提供了以下错误信息:\n" & Additional.First & "\n\n请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。") diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb index 123d56d8..1be022c1 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb @@ -378,7 +378,7 @@ NextInner: '根据当前登录方式优先返回 Select Case Setup.Get("LoginType") Case McLoginType.Ms - If Setup.Get("CacheMsName") <> "" Then Return Setup.Get("CacheMsName") + If Setup.Get("CacheMsV2Name") <> "" Then Return Setup.Get("CacheMsV2Name") Case McLoginType.Legacy If Setup.Get("LoginLegacyName") <> "" Then Return Setup.Get("LoginLegacyName").ToString.Before("¨") Case McLoginType.Nide @@ -387,7 +387,7 @@ NextInner: If Setup.Get("CacheAuthName") <> "" Then Return Setup.Get("CacheAuthName") End Select '查找所有可能的项 - If Setup.Get("CacheMsName") <> "" Then Return Setup.Get("CacheMsName") + If Setup.Get("CacheMsV2Name") <> "" Then Return Setup.Get("CacheMsV2Name") If Setup.Get("CacheNideName") <> "" Then Return Setup.Get("CacheNideName") If Setup.Get("CacheAuthName") <> "" Then Return Setup.Get("CacheAuthName") If Setup.Get("LoginLegacyName") <> "" Then Return Setup.Get("LoginLegacyName").ToString.Before("¨") @@ -399,7 +399,7 @@ NextInner: Public Function McLoginAble() As String Select Case Setup.Get("LoginType") Case McLoginType.Ms - If Setup.Get("CacheMsOAuthRefresh") = "" Then + If Setup.Get("CacheMsV2OAuthRefresh") = "" Then Return FrmLoginMs.IsVaild() Else Return "" @@ -450,7 +450,7 @@ NextInner: Case McLoginType.Legacy LoginData = PageLoginLegacy.GetLoginData() Case McLoginType.Ms - If Setup.Get("CacheMsOAuthRefresh") = "" Then + If Setup.Get("CacheMsV2OAuthRefresh") = "" Then LoginData = PageLoginMs.GetLoginData() Else LoginData = PageLoginMsSkin.GetLoginData() @@ -552,11 +552,11 @@ Relogin: Dim Result = MsLoginStep6(AccessToken) Data.Progress = 0.98 '输出登录结果 - Setup.Set("CacheMsOAuthRefresh", OAuthRefreshToken) - Setup.Set("CacheMsAccess", AccessToken) - Setup.Set("CacheMsUuid", Result(0)) - Setup.Set("CacheMsName", Result(1)) - Setup.Set("CacheMsProfileJson", Result(2)) + Setup.Set("CacheMsV2OAuthRefresh", OAuthRefreshToken) + Setup.Set("CacheMsV2Access", AccessToken) + Setup.Set("CacheMsV2Uuid", Result(0)) + Setup.Set("CacheMsV2Name", Result(1)) + Setup.Set("CacheMsV2ProfileJson", Result(2)) Dim MsJson As JObject = GetJson(Setup.Get("LoginMsJson")) MsJson.Remove(Input.UserName) '如果更改了玩家名…… MsJson(Result(1)) = OAuthRefreshToken @@ -850,7 +850,7 @@ Retry: While Converter.Result Is Nothing Thread.Sleep(100) End While - If TypeOf Converter.Result Is RetryException Then + If TypeOf Converter.Result Is RestartException Then If MyMsgBox($"请在登录时选择 {vbLQ}其他登录方法{vbRQ},然后选择 {vbLQ}使用我的密码{vbRQ}。{vbCrLf}如果没有该选项,请选择 {vbLQ}设置密码{vbRQ},设置完毕后再登录。", "需要使用密码登录", "重新登录", "设置密码", "取消", Button2Action:=Sub() OpenWebsite("https://account.live.com/password/Change")) = 1 Then @@ -1262,8 +1262,7 @@ Retry: ''' 释放 Java Wrapper 并返回完整文件路径。 ''' Public Function ExtractJavaWrapper() As String - Dim BaseDir As String = GetPureASCIIDir() - Dim WrapperPath As String = BaseDir & "\JavaWrapper.jar" + Dim WrapperPath As String = PathPure & "JavaWrapper.jar" Log("[Java] 选定的 Java Wrapper 路径:" & WrapperPath) SyncLock ExtractJavaWrapperLock '避免 OptiFine 和 Forge 安装时同时释放 Java Wrapper 导致冲突 Try @@ -1277,7 +1276,7 @@ Retry: WriteFile(WrapperPath, GetResources("JavaWrapper")) Catch ex2 As Exception Log(ex2, "Java Wrapper 文件重新释放失败,将尝试更换文件名重新生成", LogLevel.Developer) - WrapperPath = BaseDir & "\JavaWrapper2.jar" + WrapperPath = PathPure & "JavaWrapper2.jar" Try WriteFile(WrapperPath, GetResources("JavaWrapper")) Catch ex3 As Exception @@ -1293,22 +1292,6 @@ Retry: End Function Private ExtractJavaWrapperLock As New Object - ''' - ''' 获取一个可用于临时存放文件的,不含任何特殊字符的文件夹路径。 - ''' 返回值不以 \ 结尾。 - ''' - Public Function GetPureASCIIDir() As String - If (Path & "PCL").IsASCII() Then - Return Path & "PCL" - ElseIf PathAppdata.IsASCII() Then - Return PathAppdata.TrimEnd("\") - ElseIf PathTemp.IsASCII() Then - Return PathTemp.TrimEnd("\") - Else - Return OsDrive & "ProgramData\PCL" - End If - End Function - '主方法,合并 Jvm、Game、Replace 三部分的参数数据 Private Sub McLaunchArgumentMain(Loader As LoaderTask(Of String, List(Of McLibToken))) McLaunchLog("开始获取 Minecraft 启动参数") @@ -1408,7 +1391,7 @@ Retry: Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent)) Try Dim Response As String = NetGetCodeByRequestRetry(Server, Encoding.UTF8) - DataList.Insert(0, "-javaagent:""" & PathAppdata & "authlib-injector.jar""=" & Server & + DataList.Insert(0, "-javaagent:""" & PathPure & "authlib-injector.jar""=" & Server & " -Dauthlibinjector.side=client" & " -Dauthlibinjector.yggdrasil.prefetched=" & Convert.ToBase64String(Encoding.UTF8.GetBytes(Response))) Catch ex As Exception @@ -1418,7 +1401,7 @@ Retry: '添加 Java Wrapper 作为主 Jar If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED") - DataList.Add("-Doolloo.jlw.tmpdir=""" & GetPureASCIIDir() & """") + DataList.Add("-Doolloo.jlw.tmpdir=""" & PathPure.TrimEnd("\") & """") DataList.Add("-jar """ & ExtractJavaWrapper() & """") '添加 MainClass @@ -1475,7 +1458,7 @@ NextVersion: Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent)) Try Dim Response As String = NetGetCodeByRequestRetry(Server, Encoding.UTF8) - DataList.Insert(0, "-javaagent:""" & PathAppdata & "authlib-injector.jar""=" & Server & + DataList.Insert(0, "-javaagent:""" & PathPure & "authlib-injector.jar""=" & Server & " -Dauthlibinjector.side=client" & " -Dauthlibinjector.yggdrasil.prefetched=" & Convert.ToBase64String(Encoding.UTF8.GetBytes(Response))) Catch ex As Exception @@ -1485,7 +1468,7 @@ NextVersion: '添加 Java Wrapper 作为主 Jar If McLaunchJavaSelected.VersionCode >= 9 Then DataList.Add("--add-exports cpw.mods.bootstraplauncher/cpw.mods.bootstraplauncher=ALL-UNNAMED") - DataList.Add("-Doolloo.jlw.tmpdir=""" & GetPureASCIIDir() & """") + DataList.Add("-Doolloo.jlw.tmpdir=""" & PathPure.TrimEnd("\") & """") DataList.Add("-jar """ & ExtractJavaWrapper() & """") '将 "-XXX" 与后面 "XXX" 合并到一起 diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb index 957e2e2d..213a82c5 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb @@ -1256,9 +1256,8 @@ OnLoaded: Dim VersionList As New List(Of McVersion) #Region "循环加载每个版本的信息" - Dim Dirs As DirectoryInfo() = New DirectoryInfo(Path & "versions").GetDirectories - For Each Folder As DirectoryInfo In Dirs - If Not Folder.EnumerateFiles.Any Then + For Each Folder As DirectoryInfo In New DirectoryInfo(Path & "versions").GetDirectories + If Not Folder.Exists OrElse Not Folder.EnumerateFiles.Any Then Log("[Minecraft] 跳过空文件夹:" & Folder.FullName) Continue For End If @@ -1528,7 +1527,7 @@ OnLoaded: ''' 要求玩家选择一个皮肤文件,并进行相关校验。 ''' Public Function McSkinSelect() As McSkinInfo - Dim FileName As String = SelectFile("皮肤文件(*.png)|*.png", "选择皮肤文件") + Dim FileName As String = SelectFile("皮肤文件(*.png;*.jpg;*.webp)|*.png;*.jpg;*.webp", "选择皮肤文件") '验证有效性 If FileName = "" Then Return New McSkinInfo With {.IsVaild = False} @@ -1935,7 +1934,7 @@ OnLoaded: ''' ''' 获取版本缺失的支持库文件所对应的 NetTaskFile。 ''' - Public Function McLibFix(Version As McVersion, Optional CoreJarOnly As Boolean = False) As List(Of NetFile) + Public Function McLibFix(Version As McVersion) As List(Of NetFile) If Not Version.IsLoaded Then Version.Load() '确保例如 JumpLoader 等项被合并入 Json Dim Result As New List(Of NetFile) @@ -1948,7 +1947,6 @@ OnLoaded: Catch ex As Exception Log(ex, "版本缺失主 jar 文件所必须的信息", LogLevel.Developer) End Try - If CoreJarOnly Then Return Result 'Library 文件 Result.AddRange(McLibFixFromLibToken(McLibListGet(Version, False), JumpLoaderFolder:=Version.PathIndie & ".jumploader\")) @@ -1957,15 +1955,15 @@ OnLoaded: If Setup.Get("VersionServerLogin", Version:=Version) = 3 Then Dim TargetFile = PathAppdata & "nide8auth.jar" Dim DownloadInfo As JObject = Nothing - '获取下载信息 - Try - Log("[Minecraft] 开始获取统一通行证下载信息") - '测试链接:https://auth.mc-user.com:233/00000000000000000000000000000000/ - DownloadInfo = GetJson(NetGetCodeByDownload({ + '获取下载信息 + Try + Log("[Minecraft] 开始获取统一通行证下载信息") + '测试链接:https://auth.mc-user.com:233/00000000000000000000000000000000/ + DownloadInfo = GetJson(NetGetCodeByDownload({ "https://auth.mc-user.com:233/" & Setup.Get("VersionServerNide", Version:=Version)}, IsJson:=True)) - Catch ex As Exception - Log(ex, "获取统一通行证下载信息失败") - End Try + Catch ex As Exception + Log(ex, "获取统一通行证下载信息失败") + End Try '校验文件 If DownloadInfo IsNot Nothing Then Dim Checker As New FileChecker(Hash:=DownloadInfo("jarHash").ToString) @@ -1978,9 +1976,8 @@ OnLoaded: End If 'Authlib-Injector 文件 - If Setup.Get("VersionServerLogin", Version:=Version) = 4 OrElse - (PageLinkHiper.HiperState = LoadState.Finished AndAlso Setup.Get("LoginType") = McLoginType.Legacy) Then 'HiPer 登录转接 - Dim TargetFile = PathAppdata & "authlib-injector.jar" + If Setup.Get("VersionServerLogin", Version:=Version) = 4 Then + Dim TargetFile = PathPure & "\authlib-injector.jar" Dim DownloadInfo As JObject = Nothing '获取下载信息 Try @@ -2001,9 +1998,9 @@ OnLoaded: Replace("bmclapi2.bangbang93.com/mirrors/authlib-injector", "authlib-injector.yushi.moe") Log("[Minecraft] Authlib-Injector 需要更新:" & DownloadAddress, LogLevel.Developer) Result.Add(New NetFile({ - DownloadAddress, - DownloadAddress.Replace("authlib-injector.yushi.moe", "bmclapi2.bangbang93.com/mirrors/authlib-injector") - }, TargetFile, New FileChecker(Hash:=DownloadInfo("checksums")("sha256").ToString))) + DownloadAddress, + DownloadAddress.Replace("authlib-injector.yushi.moe", "bmclapi2.bangbang93.com/mirrors/authlib-injector") + }, TargetFile, New FileChecker(Hash:=DownloadInfo("checksums")("sha256").ToString))) End If End If End If diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb index 1eb713b2..a6662adf 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModMod.vb @@ -825,6 +825,7 @@ Finished: Finally RunInUiWait(Sub() If FrmVersionMod IsNot Nothing Then FrmVersionMod.Load.Text = "正在加载 Mod 列表") End Try + FrmVersionMod.LoaderRun(LoaderFolderRunType.UpdateOnly) End If '获取 Mod 文件夹下的可用文件列表 diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb index 4b82a949..d7285bd1 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb @@ -342,8 +342,8 @@ Retry: End If '删除原始整合包文件 For Each Target As String In {VersionFolder & "原始整合包.zip", VersionFolder & "原始整合包.mrpack"} - If Not Setup.Get("ToolDownloadKeepModpack") AndAlso File.Exists(Target) Then - Log("[ModPack] 根据设置要求删除原始整合包文件:" & Target) + If File.Exists(Target) Then + Log("[ModPack] 删除原始整合包文件:" & Target) File.Delete(Target) End If Next @@ -491,8 +491,8 @@ Retry: End If '删除原始整合包文件 For Each Target As String In {VersionFolder & "原始整合包.zip", VersionFolder & "原始整合包.mrpack"} - If Not Setup.Get("ToolDownloadKeepModpack") AndAlso File.Exists(Target) Then - Log("[ModPack] 根据设置要求删除原始整合包文件:" & Target) + If File.Exists(Target) Then + Log("[ModPack] 删除原始整合包文件:" & Target) File.Delete(Target) End If Next diff --git a/Plain Craft Launcher 2/Modules/Minecraft/MyCompItem.xaml b/Plain Craft Launcher 2/Modules/Minecraft/MyCompItem.xaml index 8fd7baec..7524a36c 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/MyCompItem.xaml +++ b/Plain Craft Launcher 2/Modules/Minecraft/MyCompItem.xaml @@ -1,6 +1,7 @@  @@ -23,7 +24,7 @@ - + $"{PathTemp}CompLogo\{GetHash(_Logo)}.png" Then Exit Sub - '在完成正常加载后才保存缓存图片 - PathLogo.Source = New MyBitmap(LocalFileAddress & DownloadEnd) - Catch ex As Exception - Log(ex, $"读取资源工程图标失败({LocalFileAddress})") - File.Delete(LocalFileAddress & DownloadEnd) - LoadError = ex - End Try - End Sub) - If LoadError IsNot Nothing Then Throw LoadError - If File.Exists(LocalFileAddress) Then - File.Delete(LocalFileAddress & DownloadEnd) - Else - FileIO.FileSystem.MoveFile(LocalFileAddress & DownloadEnd, LocalFileAddress) - End If - Catch ex As Exception - If Not Retried Then - Retried = True - GoTo RetryStart - Else - Log(ex, $"下载资源工程图标失败({_Logo})") - RunInUi(Sub() PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png")) - End If - End Try - End Sub '标题 Public Property Title As String diff --git a/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml b/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml index ce687e89..d626409b 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml +++ b/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml @@ -24,7 +24,7 @@ - + --> diff --git a/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml.vb b/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml.vb index 316d5e3f..df794e64 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/MyLocalModItem.xaml.vb @@ -6,88 +6,14 @@ Public Class MyLocalModItem Public Uuid As Integer = GetUuid() 'Logo - Private _Logo As String = "" Public Property Logo As String Get - Return _Logo + Return PathLogo.Source End Get Set(value As String) - If _Logo = value OrElse value Is Nothing Then Exit Property - _Logo = value - If ModeDebug AndAlso Not _Logo = PathImage & "Icons/NoIcon.png" Then Log($"[LocalModItem] Mod {Title} 的图标:{value}") - Dim FileAddress = PathTemp & "CompLogo\" & GetHash(_Logo) & ".png" - Try - If _Logo.StartsWithF("http", True) Then - '网络图片 - If File.Exists(FileAddress) Then - PathLogo.Source = New MyBitmap(FileAddress) - Else - PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png") - RunInNewThread(Sub() LogoLoader(FileAddress), "Comp Logo Loader " & Uuid & "#", ThreadPriority.BelowNormal) - End If - Else - '位图 - PathLogo.Source = New MyBitmap(_Logo) - End If - Catch ex As IOException - Log(ex, "加载本地 Mod 图标时读取失败(" & FileAddress & ")") - Catch ex As ArgumentException - '考虑缓存的图片本身可能有误 - Log(ex, "可视化本地 Mod 图标失败(" & FileAddress & ")") - Try - File.Delete(FileAddress) - Log("[LocalModItem] 已清理损坏的本地 Mod 图标:" & FileAddress) - Catch exx As Exception - Log(exx, "清理损坏的本地 Mod 图标缓存失败(" & FileAddress & ")", LogLevel.Hint) - End Try - Catch ex As Exception - Log(ex, "加载本地 Mod 图标失败(" & value & ")") - End Try + PathLogo.Source = value End Set End Property - '后台加载 Logo - Private Sub LogoLoader(LocalFileAddress As String) - Dim Retried As Boolean = False - Dim DownloadEnd As String = GetUuid() -RetryStart: - Try - 'CurseForge 图片使用缩略图 - Dim Url As String = _Logo - If Url.Contains("/256/256/") AndAlso GetPixelSize(1) <= 1.25 AndAlso Not Retried Then '#3075:部分 Mod 不存在 64x64 图标,所以重试时不再缩小 - Url = Url.Replace("/256/256/", "/64/64/") - End If - '下载图片 - NetDownload(Url, LocalFileAddress & DownloadEnd, True) - Dim LoadError As Exception = Nothing - RunInUiWait( - Sub() - Try - '在地址更换时取消加载 - If LocalFileAddress <> $"{PathTemp}CompLogo\{GetHash(_Logo)}.png" Then Exit Sub - '在完成正常加载后才保存缓存图片 - PathLogo.Source = New MyBitmap(LocalFileAddress & DownloadEnd) - Catch ex As Exception - Log(ex, "读取本地 Mod 图标失败(" & LocalFileAddress & ")") - File.Delete(LocalFileAddress & DownloadEnd) - LoadError = ex - End Try - End Sub) - If LoadError IsNot Nothing Then Throw LoadError - If File.Exists(LocalFileAddress) Then - File.Delete(LocalFileAddress & DownloadEnd) - Else - FileIO.FileSystem.MoveFile(LocalFileAddress & DownloadEnd, LocalFileAddress) - End If - Catch ex As Exception - If Not Retried Then - Retried = True - GoTo RetryStart - Else - Log(ex, $"下载本地 Mod 图标失败({_Logo})") - RunInUi(Sub() PathLogo.Source = New MyBitmap(PathImage & "Icons/NoIcon.png")) - End If - End Try - End Sub '标题 Private _Title As String @@ -143,9 +69,9 @@ RetryStart: For Each TagText In value Dim NewTag = GetObjectFromXML( " - + ") PanTags.Children.Add(NewTag) Next @@ -377,7 +303,7 @@ RetryStart: #End Region - Public Sub Refresh() + Public Sub Refresh() Handles Me.Loaded RunInUi( Sub() '更新 @@ -404,30 +330,45 @@ RetryStart: Else BtnUpdate.Visibility = Visibility.Collapsed End If - '标题 - If Entry.Comp Is Nothing Then - Title = Entry.Name - SubTitle = If(Entry.Version Is Nothing, "", " | " & Entry.Version) - Else - Dim Titles = Entry.Comp.GetControlTitle(False) - Title = Titles.Key - SubTitle = Titles.Value & If(Entry.Version Is Nothing, "", " | " & Entry.Version) - End If - If Checked Then - LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush2", "ColorBrush5")) - Else - LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush1", "ColorBrushGray4")) - End If - '描述 - Dim NewDescription As String + '标题与描述 + Dim DescFileName As String Select Case Entry.State Case McMod.McModState.Fine - NewDescription = GetFileNameWithoutExtentionFromPath(Entry.Path) + DescFileName = GetFileNameWithoutExtentionFromPath(Entry.Path) Case McMod.McModState.Disabled - NewDescription = GetFileNameWithoutExtentionFromPath(Entry.Path.Replace(".disabled", "").Replace(".old", "")) + DescFileName = GetFileNameWithoutExtentionFromPath(Entry.Path.Replace(".disabled", "").Replace(".old", "")) Case Else 'McMod.McModState.Unavailable - NewDescription = GetFileNameFromPath(Entry.Path) + DescFileName = GetFileNameFromPath(Entry.Path) End Select + Dim NewDescription As String + If Setup.Get("ToolModLocalNameStyle") = 1 Then + '标题显示文件名,详情显示译名 + '标题 + Title = DescFileName + SubTitle = "" + '描述 + If Entry.Comp Is Nothing Then + NewDescription = Entry.Name + Else + Dim Titles = Entry.Comp.GetControlTitle(False) + NewDescription = Titles.Key & Titles.Value + End If + NewDescription = NewDescription.Replace(" | ", " / ") + If Entry.Version IsNot Nothing Then NewDescription &= $" ({Entry.Version})" + Else + '标题显示译名,详情显示文件名 + '标题 + If Entry.Comp Is Nothing Then + Title = Entry.Name + SubTitle = If(Entry.Version Is Nothing, "", " | " & Entry.Version) + Else + Dim Titles = Entry.Comp.GetControlTitle(False) + Title = Titles.Key + SubTitle = Titles.Value & If(Entry.Version Is Nothing, "", " | " & Entry.Version) + End If + '描述 + NewDescription = DescFileName + End If If Entry.Comp IsNot Nothing Then NewDescription += ": " & Entry.Comp.Description.Replace(vbCr, "").Replace(vbLf, "") ElseIf Entry.Description IsNot Nothing Then @@ -436,6 +377,11 @@ RetryStart: NewDescription += ": " & "存在错误,无法获取信息" End If Description = NewDescription + If Checked Then + LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush2", "ColorBrush5")) + Else + LabTitle.SetResourceReference(TextBlock.ForegroundProperty, If(Entry.State = McMod.McModState.Fine, "ColorBrush1", "ColorBrushGray4")) + End If '主 Logo Logo = If(Entry.Comp Is Nothing, PathImage & "Icons/NoIcon.png", Entry.Comp.GetControlLogo()) '图标右下角的 Logo diff --git a/Plain Craft Launcher 2/Modules/ModEvent.vb b/Plain Craft Launcher 2/Modules/ModEvent.vb index e5282a97..9c29699f 100644 --- a/Plain Craft Launcher 2/Modules/ModEvent.vb +++ b/Plain Craft Launcher 2/Modules/ModEvent.vb @@ -92,7 +92,18 @@ MyMsgBox("EventData 必须为以 http:// 或 https:// 开头的网址。" & vbCrLf & "PCL 不支持其他乱七八糟的下载协议。", "事件执行失败") Exit Sub End If - PageOtherTest.StartCustomDownload(Data(0), GetFileNameFromPath(Data(0))) + Try + Select Case Data.Length + Case 1 + PageOtherTest.StartCustomDownload(Data(0), GetFileNameFromPath(Data(0))) + Case 2 + PageOtherTest.StartCustomDownload(Data(0), Data(1)) + Case Else + PageOtherTest.StartCustomDownload(Data(0), Data(1), Data(2)) + End Select + Catch + PageOtherTest.StartCustomDownload(Data(0), "未知") + End Try Case Else MyMsgBox("未知的事件类型:" & Type & vbCrLf & "请检查事件类型填写是否正确,或者 PCL 是否为最新版本。", "事件执行失败") diff --git a/Plain Craft Launcher 2/Modules/ModSecret.vb b/Plain Craft Launcher 2/Modules/ModSecret.vb index 5a2c1b97..a56256c6 100644 --- a/Plain Craft Launcher 2/Modules/ModSecret.vb +++ b/Plain Craft Launcher 2/Modules/ModSecret.vb @@ -101,8 +101,8 @@ Friend Module ModSecret ''' 设置 Headers 的 UA、Referer。 ''' Friend Sub SecretHeadersSign(Url As String, ByRef Client As WebClient, Optional UseBrowserUserAgent As Boolean = False) - If Url.Contains("modrinth.com") Then '根据 #4334,不添加 PCL 的 UA 反而能正常访问 - Client.Headers("User-Agent") = "Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36" + If Url.Contains("baidupcs.com") OrElse Url.Contains("baidu.com") Then + Client.Headers("User-Agent") = "LogStatistic" '#4951 ElseIf UseBrowserUserAgent Then Client.Headers("User-Agent") = "PCL2/" & VersionStandardCode & " Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36" Else @@ -115,8 +115,8 @@ Friend Module ModSecret ''' 设置 Headers 的 UA、Referer。 ''' Friend Sub SecretHeadersSign(Url As String, ByRef Request As HttpWebRequest, Optional UseBrowserUserAgent As Boolean = False) - If Url.Contains("modrinth.com") Then '根据 #4334,不添加 PCL 的 UA 反而能正常访问 - Request.UserAgent = "Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36" + If Url.Contains("baidupcs.com") OrElse Url.Contains("baidu.com") Then + Client.Headers("User-Agent") = "LogStatistic" '#4951 ElseIf UseBrowserUserAgent Then Request.UserAgent = "PCL2/" & VersionStandardCode & " Mozilla/5.0 AppleWebKit/537.36 Chrome/63.0.3239.132 Safari/537.36" Else diff --git a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb index 59171f6c..400835c8 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 02a4a0b8..8a62135c 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb @@ -1,4 +1,5 @@ Imports System.IO.Compression +Imports System.Net.Http Public Module ModDownloadLib @@ -59,47 +60,6 @@ Public Module ModDownloadLib Return Nothing End Try End Function - ''' - ''' 保存某个 Minecraft 版本的核心文件(仅 Json 与核心 Jar)。 - ''' - ''' 所下载的 Minecraft 的版本名。 - ''' Json 文件的 Mojang 官方地址。 - Public Sub McDownloadClientCore(Id As String, JsonUrl As String, Behaviour As NetPreDownloadBehaviour) - Try - Dim VersionFolder As String = SelectFolder() - If Not VersionFolder.Contains("\") Then Exit Sub - VersionFolder = VersionFolder & Id & "\" - - '重复任务检查 - For Each OngoingLoader In LoaderTaskbar.ToList() - If OngoingLoader.Name <> $"Minecraft {Id} 下载" Then Continue For - If Behaviour = NetPreDownloadBehaviour.ExitWhileExistsOrDownloading Then Exit Sub - Hint("该版本正在下载中!", HintType.Critical) - Exit Sub - Next - - Dim Loaders As New List(Of LoaderBase) - '下载版本 Json 文件 - Loaders.Add(New LoaderDownload("下载版本 json 文件", New List(Of NetFile) From { - New NetFile(DlSourceLauncherOrMetaGet(JsonUrl), VersionFolder & Id & ".json", New FileChecker(CanUseExistsFile:=False, IsJson:=True)) - }) With {.ProgressWeight = 2}) - '获取支持库文件地址 - Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("分析核心 jar 文件下载地址", - Sub(Task As LoaderTask(Of String, List(Of NetFile))) Task.Output = McLibFix(New McVersion(VersionFolder), True)) With {.ProgressWeight = 0.5, .Show = False}) - '下载支持库文件 - Loaders.Add(New LoaderDownload("下载核心 jar 文件", New List(Of NetFile)) With {.ProgressWeight = 5}) - - '启动 - Dim Loader As New LoaderCombo(Of String)("Minecraft " & Id & " 下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave} - Loader.Start(Id) - LoaderTaskbarAdd(Loader) - FrmMain.BtnExtraDownload.ShowRefresh() - FrmMain.BtnExtraDownload.Ribble() - - Catch ex As Exception - Log(ex, "开始 Minecraft 下载失败", LogLevel.Feedback) - End Try - End Sub ''' ''' 获取下载某个 Minecraft 版本的加载器列表。 @@ -207,19 +167,14 @@ Public Module ModDownloadLib ToolTipService.SetVerticalOffset(BtnInfo, 30) ToolTipService.SetHorizontalOffset(BtnInfo, 2) AddHandler BtnInfo.Click, AddressOf McDownloadMenuLog - Dim BtnServer As New MyIconButton With {.LogoScale = 1.05, .Logo = Logo.IconButtonServer, .ToolTip = "下载服务端"} + Dim BtnServer As New MyIconButton With {.LogoScale = 1, .Logo = Logo.IconButtonServer, .ToolTip = "下载服务端"} ToolTipService.SetPlacement(BtnServer, Primitives.PlacementMode.Center) ToolTipService.SetVerticalOffset(BtnServer, 30) ToolTipService.SetHorizontalOffset(BtnServer, 2) - AddHandler BtnServer.Click, AddressOf McDownloadMenuServer + AddHandler BtnServer.Click, AddressOf McDownloadMenuSaveServer sender.Buttons = {BtnServer, BtnInfo} End Sub Private Sub McDownloadMenuBuild(sender As Object, e As EventArgs) - Dim BtnServer As New MyIconButton With {.LogoScale = 1.05, .Logo = Logo.IconButtonServer, .ToolTip = "下载服务端"} - ToolTipService.SetPlacement(BtnServer, Primitives.PlacementMode.Center) - ToolTipService.SetVerticalOffset(BtnServer, 30) - ToolTipService.SetHorizontalOffset(BtnServer, 2) - AddHandler BtnServer.Click, AddressOf McDownloadMenuServer Dim BtnSave As New MyIconButton With {.Logo = Logo.IconButtonSave, .ToolTip = "另存为"} ToolTipService.SetPlacement(BtnSave, Primitives.PlacementMode.Center) ToolTipService.SetVerticalOffset(BtnSave, 30) @@ -230,7 +185,12 @@ Public Module ModDownloadLib ToolTipService.SetVerticalOffset(BtnInfo, 30) ToolTipService.SetHorizontalOffset(BtnInfo, 2) AddHandler BtnInfo.Click, AddressOf McDownloadMenuLog - sender.Buttons = {BtnServer, BtnSave, BtnInfo} + Dim BtnServer As New MyIconButton With {.LogoScale = 1, .Logo = Logo.IconButtonServer, .ToolTip = "下载服务端"} + ToolTipService.SetPlacement(BtnServer, Primitives.PlacementMode.Center) + ToolTipService.SetVerticalOffset(BtnServer, 30) + ToolTipService.SetHorizontalOffset(BtnServer, 2) + AddHandler BtnServer.Click, AddressOf McDownloadMenuSaveServer + sender.Buttons = {BtnSave, BtnInfo, BtnServer} End Sub Private Sub McDownloadMenuLog(sender As Object, e As RoutedEventArgs) Dim Version As JToken @@ -243,60 +203,74 @@ Public Module ModDownloadLib End If McUpdateLogShow(Version) End Sub - Private Sub McDownloadMenuServer(sender As Object, e As RoutedEventArgs) - Dim Version As JToken - If sender.Tag IsNot Nothing Then - Version = sender.Tag - ElseIf sender.Parent.Tag IsNot Nothing Then - Version = sender.Parent.Tag + Private Sub McDownloadMenuSaveServer(sender As Object, e As RoutedEventArgs) + Dim Version As MyListItem + If TypeOf sender Is MyListItem Then + Version = sender + ElseIf TypeOf sender.Parent Is MyListItem Then + Version = sender.Parent Else - Version = sender.Parent.Parent.Tag + Version = sender.Parent.Parent End If - RunInThread(Sub() - Dim Json As JObject - Try - Json = NetGetCodeByRequestRetry(Version("url"), IsJson:=True) - Catch ex As Exception - Log(ex, "未找能获取到服务端文件,文件可能不存在") - End Try - If Json?("downloads")?("server") Is Nothing Then - Hint("此版本暂未有服务端文件提供下载") - Else - RunInUi(Sub() - Try - Dim Url As String = Json("downloads")("server")("url").ToString() - Dim FileName As String = Version("id").ToString() & "-server.jar" - Dim VersionID As String = Version("id").ToString() - Dim Target As String = SelectAs("选择保存位置", FileName, "原版服务端 (*.jar)|*.jar") - If Not Target.Contains("\") Then Exit Sub - - '重复任务检查 - For Each OngoingLoader In LoaderTaskbar - If OngoingLoader.Name <> $"{VersionID} 服务端下载" Then Continue For - Hint("该服务端文件正在下载中!", HintType.Critical) - Exit Sub - Next - - '构造步骤加载器 - Dim Loaders As New List(Of LoaderBase) - '下载 - Dim Address As New List(Of String) - Address.Add(Url) - Loaders.Add(New LoaderDownload("下载服务端文件", New List(Of NetFile) From {New NetFile(Address.ToArray, Target, New FileChecker(MinSize:=1024 * 64))}) With {.ProgressWeight = 15}) - '启动 - Dim Loader As New LoaderCombo(Of JObject)($"{VersionID} 服务端下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave} - Loader.Start(Json("downloads")("server")) - LoaderTaskbarAdd(Loader) - FrmMain.BtnExtraDownload.ShowRefresh() - FrmMain.BtnExtraDownload.Ribble() - - Catch ex As Exception - Log(ex, "开始服务端文件下载失败", LogLevel.Feedback) - End Try - End Sub) - End If - End Sub - ) + Try + Dim Id = Version.Title + Dim JsonUrl = Version.Tag("url").ToString + Dim VersionFolder As String = SelectFolder() + If Not VersionFolder.Contains("\") Then Exit Sub + VersionFolder = VersionFolder & Id & "\" + + '重复任务检查 + For Each OngoingLoader In LoaderTaskbar.ToList() + If OngoingLoader.Name <> $"Minecraft {Id} 服务端下载" Then Continue For + Hint("该服务端正在下载中!", HintType.Critical) + Exit Sub + Next + + Dim Loaders As New List(Of LoaderBase) + '下载版本 JSON 文件 + Loaders.Add(New LoaderDownload("下载版本 JSON 文件", New List(Of NetFile) From { + New NetFile(DlSourceLauncherOrMetaGet(JsonUrl), VersionFolder & Id & ".json", New FileChecker(CanUseExistsFile:=False, IsJson:=True)) + }) With {.ProgressWeight = 2}) + '构建服务端 + Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("构建服务端", + Sub(Task As LoaderTask(Of String, List(Of NetFile))) + '分析服务端 JAR 文件下载地址 + Dim McVersion As New McVersion(VersionFolder) + If McVersion.JsonObject("downloads") Is Nothing OrElse McVersion.JsonObject("downloads")("server") Is Nothing OrElse McVersion.JsonObject("downloads")("server")("url") Is Nothing Then Throw New Exception($"{Id} 版本没有提供服务端文件") + Dim JarUrl As String = McVersion.JsonObject("downloads")("server")("url") + Dim Checker As New FileChecker(MinSize:=1024, ActualSize:=If(McVersion.JsonObject("downloads")("server")("size"), -1), Hash:=McVersion.JsonObject("downloads")("server")("sha1")) + Task.Output = New List(Of NetFile) From {New NetFile(DlSourceLauncherOrMetaGet(JarUrl), VersionFolder & Id & "-server.jar", Checker)} + '添加启动脚本 + Dim Bat As String = +$"@echo off +title {Id} 原版服务端 +echo 如果服务端立即停止,请右键编辑该脚本,将下一行开头的 java 替换为适合该 Minecraft 版本的完整 java.exe 的路径。 +echo 你可以在 PCL 的 [设置 → 启动选项] 中查看已安装的 java,所需的 java.exe 一般在其中的 bin 文件夹下。 +echo ------------------------------ +echo 如果提示 ""You need to agree to the EULA in order to run the server"",请打开 eula.txt,按说明阅读并同意 Minecraft EULA 后,将该文件最后一行中的 eula=false 改为 eula=true。 +echo ------------------------------ +""java"" -server -XX:+UseG1GC -Xmx4096M -Xms1024M -XX:+UseCompressedOops -jar {Id}-server.jar nogui +echo ---------------------- +echo 服务端已停止。 +pause" + WriteFile(VersionFolder & "Launch Server.bat", Bat, + Encoding:=If(Encoding.Default.Equals(Encoding.UTF8), Encoding.UTF8, Encoding.GetEncoding("GB18030"))) + '删除版本 JSON + File.Delete(VersionFolder & Id & ".json") + End Sub + ) With {.ProgressWeight = 0.5, .Show = False}) + '下载服务端文件 + Loaders.Add(New LoaderDownload("下载服务端文件", New List(Of NetFile)) With {.ProgressWeight = 5}) + + '启动 + Dim Loader As New LoaderCombo(Of String)("Minecraft " & Id & " 服务端下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave} + Loader.Start(Id) + LoaderTaskbarAdd(Loader) + FrmMain.BtnExtraDownload.ShowRefresh() + FrmMain.BtnExtraDownload.Ribble() + Catch ex As Exception + Log(ex, "开始 Minecraft 服务端下载失败", LogLevel.Feedback) + End Try End Sub Public Sub McDownloadMenuSave(sender As Object, e As RoutedEventArgs) Dim Version As MyListItem @@ -307,7 +281,41 @@ Public Module ModDownloadLib Else Version = sender.Parent.Parent End If - McDownloadClientCore(Version.Title, Version.Tag("url").ToString, NetPreDownloadBehaviour.HintWhileExists) + Try + Dim Id = Version.Title + Dim JsonUrl = Version.Tag("url").ToString + Dim VersionFolder As String = SelectFolder() + If Not VersionFolder.Contains("\") Then Exit Sub + VersionFolder = VersionFolder & Id & "\" + + '重复任务检查 + For Each OngoingLoader In LoaderTaskbar.ToList() + If OngoingLoader.Name <> $"Minecraft {Id} 下载" Then Continue For + Hint("该版本正在下载中!", HintType.Critical) + Exit Sub + Next + + Dim Loaders As New List(Of LoaderBase) + '下载版本 JSON 文件 + Loaders.Add(New LoaderDownload("下载版本 JSON 文件", New List(Of NetFile) From { + New NetFile(DlSourceLauncherOrMetaGet(JsonUrl), VersionFolder & Id & ".json", New FileChecker(CanUseExistsFile:=False, IsJson:=True)) + }) With {.ProgressWeight = 2}) + '获取支持库文件地址 + Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("分析核心 JAR 文件下载地址", + Sub(Task) Task.Output = New List(Of NetFile) From {DlClientJarGet(New McVersion(VersionFolder), False)} + ) With {.ProgressWeight = 0.5, .Show = False}) + '下载支持库文件 + Loaders.Add(New LoaderDownload("下载核心 JAR 文件", New List(Of NetFile)) With {.ProgressWeight = 5}) + + '启动 + Dim Loader As New LoaderCombo(Of String)("Minecraft " & Id & " 下载", Loaders) With {.OnStateChanged = AddressOf DownloadStateSave} + Loader.Start(Id) + LoaderTaskbarAdd(Loader) + FrmMain.BtnExtraDownload.ShowRefresh() + FrmMain.BtnExtraDownload.Ribble() + Catch ex As Exception + Log(ex, "开始 Minecraft 下载失败", LogLevel.Feedback) + End Try End Sub ''' ''' 显示某 Minecraft 版本的更新日志。 @@ -424,7 +432,7 @@ Public Module ModDownloadLib '添加 Java Wrapper 作为主 Jar Dim Arguments As String If UseJavaWrapper Then - Arguments = $"-Doolloo.jlw.tmpdir=""{GetPureASCIIDir()}"" -Duser.home=""{BaseMcFolderHome}"" -cp ""{Target}"" -jar ""{ExtractJavaWrapper()}"" optifine.Installer" + Arguments = $"-Doolloo.jlw.tmpdir=""{PathPure.TrimEnd("\")}"" -Duser.home=""{BaseMcFolderHome}"" -cp ""{Target}"" -jar ""{ExtractJavaWrapper()}"" optifine.Installer" Else Arguments = $"-Duser.home=""{BaseMcFolderHome}"" -cp ""{Target}"" optifine.Installer" End If @@ -1091,7 +1099,7 @@ Retry: '添加 Java Wrapper 作为主 Jar Dim Arguments As String If UseJavaWrapper Then - Arguments = $"-Doolloo.jlw.tmpdir=""{GetPureASCIIDir()}"" -cp ""{PathTemp}Cache\forge_installer.jar;{Target}"" -jar ""{ExtractJavaWrapper()}"" com.bangbang93.ForgeInstaller ""{McFolder}" + Arguments = $"-Doolloo.jlw.tmpdir=""{PathPure.TrimEnd("\")}"" -cp ""{PathTemp}Cache\forge_installer.jar;{Target}"" -jar ""{ExtractJavaWrapper()}"" com.bangbang93.ForgeInstaller ""{McFolder}" Else Arguments = $"-cp ""{PathTemp}Cache\forge_installer.jar;{Target}"" com.bangbang93.ForgeInstaller ""{McFolder}" End If @@ -1446,8 +1454,6 @@ Retry: '没有新增文件夹 Log("[Download] 未找到新增的版本文件夹") End If - '新建 mods 文件夹 - Directory.CreateDirectory(New McVersion(VersionFolder).GetPathIndie(True) & "mods\") Catch ex As Exception Throw New Exception($"安装新 {LoaderName} 版本失败", ex) Finally @@ -1463,57 +1469,55 @@ Retry: Else Log("[Download] 检测为非新版 Forge:" & LoaderVersion) Loaders.Add(New LoaderTask(Of List(Of NetFile), Boolean)($"安装 {LoaderName}(方式 B)", -Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) - Dim Installer As ZipArchive = Nothing - Try - '解压并获取信息 - Installer = New ZipArchive(New FileStream(InstallerAddress, FileMode.Open)) - Task.Progress = 0.2 - Dim Json As JObject = GetJson(ReadFile(Installer.GetEntry("install_profile.json").Open)) - Task.Progress = 0.4 - '新建版本文件夹 - Directory.CreateDirectory(VersionFolder) - Task.Progress = 0.5 - If Json("install") Is Nothing Then - '中版:Legacy 方式 1 - Log("[Download] 开始进行 Forge 安装,Legacy 方式 1:" & InstallerAddress) - '建立 Json 文件 - Dim JsonVersion As JObject = GetJson(ReadFile(Installer.GetEntry(Json("json").ToString.TrimStart("/")).Open)) - JsonVersion("id") = TargetVersion - WriteFile(VersionFolder & TargetVersion & ".json", JsonVersion.ToString) - Task.Progress = 0.6 - '解压支持库文件 - Installer.Dispose() - ExtractFile(InstallerAddress, InstallerAddress & "_unrar\") - CopyDirectory(InstallerAddress & "_unrar\maven\", McFolder & "libraries\") - DeleteDirectory(InstallerAddress & "_unrar\") - Else - '旧版:Legacy 方式 2 - Log("[Download] 开始进行 Forge 安装,Legacy 方式 2:" & InstallerAddress) - '解压 Jar 文件 - Dim JarAddress As String = McLibGet(Json("install")("path"), CustomMcFolder:=McFolder) - If File.Exists(JarAddress) Then File.Delete(JarAddress) - WriteFile(JarAddress, Installer.GetEntry(Json("install")("filePath")).Open) - Task.Progress = 0.9 - '建立 Json 文件 - Json("versionInfo")("id") = TargetVersion - If Json("versionInfo")("inheritsFrom") Is Nothing Then CType(Json("versionInfo"), JObject).Add("inheritsFrom", Inherit) - WriteFile(VersionFolder & TargetVersion & ".json", Json("versionInfo").ToString) - End If - '新建 mods 文件夹 - Directory.CreateDirectory(New McVersion(VersionFolder).GetPathIndie(True) & "mods\") - Catch ex As Exception - Throw New Exception("非新版方式安装 Forge 失败", ex) - Finally - Try - '清理文件 - If Installer IsNot Nothing Then Installer.Dispose() - If File.Exists(InstallerAddress) Then File.Delete(InstallerAddress) - If Directory.Exists(InstallerAddress & "_unrar\") Then DeleteDirectory(InstallerAddress & "_unrar\") - Catch ex As Exception - Log(ex, "非新版方式安装 Forge 清理文件时出错") - End Try - End Try + Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) + Dim Installer As ZipArchive = Nothing + Try + '解压并获取信息 + Installer = New ZipArchive(New FileStream(InstallerAddress, FileMode.Open)) + Task.Progress = 0.2 + Dim Json As JObject = GetJson(ReadFile(Installer.GetEntry("install_profile.json").Open)) + Task.Progress = 0.4 + '新建版本文件夹 + Directory.CreateDirectory(VersionFolder) + Task.Progress = 0.5 + If Json("install") Is Nothing Then + '中版:Legacy 方式 1 + Log("[Download] 开始进行 Forge 安装,Legacy 方式 1:" & InstallerAddress) + '建立 Json 文件 + Dim JsonVersion As JObject = GetJson(ReadFile(Installer.GetEntry(Json("json").ToString.TrimStart("/")).Open)) + JsonVersion("id") = TargetVersion + WriteFile(VersionFolder & TargetVersion & ".json", JsonVersion.ToString) + Task.Progress = 0.6 + '解压支持库文件 + Installer.Dispose() + ExtractFile(InstallerAddress, InstallerAddress & "_unrar\") + CopyDirectory(InstallerAddress & "_unrar\maven\", McFolder & "libraries\") + DeleteDirectory(InstallerAddress & "_unrar\") + Else + '旧版:Legacy 方式 2 + Log("[Download] 开始进行 Forge 安装,Legacy 方式 2:" & InstallerAddress) + '解压 Jar 文件 + Dim JarAddress As String = McLibGet(Json("install")("path"), CustomMcFolder:=McFolder) + If File.Exists(JarAddress) Then File.Delete(JarAddress) + WriteFile(JarAddress, Installer.GetEntry(Json("install")("filePath")).Open) + Task.Progress = 0.9 + '建立 Json 文件 + Json("versionInfo")("id") = TargetVersion + If Json("versionInfo")("inheritsFrom") Is Nothing Then CType(Json("versionInfo"), JObject).Add("inheritsFrom", Inherit) + WriteFile(VersionFolder & TargetVersion & ".json", Json("versionInfo").ToString) + End If + Catch ex As Exception + Throw New Exception("非新版方式安装 Forge 失败", ex) + Finally + Try + '清理文件 + If Installer IsNot Nothing Then Installer.Dispose() + If File.Exists(InstallerAddress) Then File.Delete(InstallerAddress) + If Directory.Exists(InstallerAddress & "_unrar\") Then DeleteDirectory(InstallerAddress & "_unrar\") + Catch ex As Exception + Log(ex, "非新版方式安装 Forge 清理文件时出错") + End Try + End Try End Sub) With {.ProgressWeight = 1}) End If @@ -1830,8 +1834,6 @@ Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) "https://bmclapi2.bangbang93.com/fabric-meta/v2/versions/loader/" & MinecraftName & "/" & FabricVersion & "/profile/json", "https://meta.fabricmc.net/v2/versions/loader/" & MinecraftName & "/" & FabricVersion & "/profile/json" }, VersionFolder & Id & ".json", New FileChecker(IsJson:=True))} - '新建 mods 文件夹 - Directory.CreateDirectory(New McVersion(VersionFolder).GetPathIndie(True) & "mods\") End Sub) With {.ProgressWeight = 0.5}) Loaders.Add(New LoaderDownload("下载 Fabric 主文件", New List(Of NetFile)) With {.ProgressWeight = 2.5}) @@ -2090,9 +2092,11 @@ Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) Dim OptiFineAsMod As Boolean = Request.OptiFineEntry IsNot Nothing AndAlso '1. 选择了 OptiFine (Request.FabricVersion IsNot Nothing OrElse '2. 选择了 Fabric... (Request.ForgeEntry IsNot Nothing AndAlso MinecraftCode >= 14 AndAlso MinecraftCode <= 15)) '...或者 Forge 1.14~15(#4134) + Dim ModsFolder As String = New McVersion(OutputFolder).GetPathIndie(True) & "mods\" + If OptiFineAsMod Then Log("[Download] OptiFine 将作为 Mod 进行下载") - OptiFineFolder = New McVersion(OutputFolder).GetPathIndie(True) & "mods\" + OptiFineFolder = ModsFolder End If '记录日志 @@ -2114,11 +2118,11 @@ Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) LoaderList.Add(New LoaderTask(Of Integer, Integer)("添加忽略标识", Sub() WriteFile(OutputFolder & ".pclignore", "用于临时地在 PCL 的版本列表中屏蔽此版本。")) With {.Show = False, .Block = False}) 'Fabric API If Request.FabricApi IsNot Nothing Then - LoaderList.Add(New LoaderDownload("下载 Fabric API", New List(Of NetFile) From {Request.FabricApi.ToNetFile(New McVersion(OutputFolder).GetPathIndie(True) & "mods\")}) With {.ProgressWeight = 3, .Block = False}) + LoaderList.Add(New LoaderDownload("下载 Fabric API", New List(Of NetFile) From {Request.FabricApi.ToNetFile(ModsFolder)}) With {.ProgressWeight = 3, .Block = False}) End If 'OptiFabric If Request.OptiFabric IsNot Nothing Then - LoaderList.Add(New LoaderDownload("下载 OptiFabric", New List(Of NetFile) From {Request.OptiFabric.ToNetFile(New McVersion(OutputFolder).GetPathIndie(True) & "mods\")}) With {.ProgressWeight = 3, .Block = False}) + LoaderList.Add(New LoaderDownload("下载 OptiFabric", New List(Of NetFile) From {Request.OptiFabric.ToNetFile(ModsFolder)}) With {.ProgressWeight = 3, .Block = False}) End If '原版 Dim ClientLoader = New LoaderCombo(Of String)("下载原版 " & Request.MinecraftName, McDownloadClientLoader(Request.MinecraftName, Request.MinecraftJson, Request.TargetVersionName)) With {.Show = False, .ProgressWeight = 39, .Block = Request.ForgeVersion Is Nothing AndAlso Request.OptiFineEntry Is Nothing AndAlso Request.FabricVersion Is Nothing AndAlso Request.LiteLoaderEntry Is Nothing} @@ -2153,7 +2157,12 @@ Sub(Task As LoaderTask(Of List(Of NetFile), Boolean)) InstallMerge(OutputFolder, OutputFolder, OptiFineFolder, OptiFineAsMod, ForgeFolder, Request.ForgeVersion, NeoForgeFolder, Request.NeoForgeVersion, FabricFolder, LiteLoaderFolder) Task.Progress = 0.3 If Directory.Exists(TempMcFolder & "libraries") Then CopyDirectory(TempMcFolder & "libraries", PathMcFolder & "libraries") - If Directory.Exists(TempMcFolder & "mods") Then CopyDirectory(TempMcFolder & "mods", PathMcFolder & "mods") + If Directory.Exists(TempMcFolder & "mods") Then CopyDirectory(TempMcFolder & "mods", ModsFolder) + '新建 mods 文件夹 + If Request.ForgeVersion IsNot Nothing OrElse Request.FabricVersion IsNot Nothing OrElse Request.NeoForgeEntry IsNot Nothing OrElse Request.LiteLoaderEntry IsNot Nothing Then + Directory.CreateDirectory(ModsFolder) + Log("[Download] 自动创建 mods 文件夹:" & ModsFolder) + End If End Sub) With {.ProgressWeight = 2, .Block = True}) '补全文件 If Not DontFixLibraries AndAlso diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCompDetail.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCompDetail.xaml.vb index 60f54bd9..892375de 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCompDetail.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCompDetail.xaml.vb @@ -167,7 +167,7 @@ '构造步骤加载器 Dim Loaders As New List(Of LoaderBase) Dim Target As String = $"{PathMcFolder}versions\{VersionName}\原始整合包.{If(Project.FromCurseForge, "zip", "mrpack")}" - Dim LogoFileAddress As String = PathTemp & "CompLogo\" & GetHash(CompItem.Logo) & ".png" + Dim LogoFileAddress As String = MyImage.GetTempPath(CompItem.Logo) Loaders.Add(New LoaderDownload("下载整合包文件", New List(Of NetFile) From {File.ToNetFile(Target)}) With {.ProgressWeight = 10, .Block = True}) Loaders.Add(New LoaderTask(Of Integer, Integer)("准备安装整合包", Sub() diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadLeft.xaml.vb index 2658c33e..de8faf88 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadLeft.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadLeft.xaml.vb @@ -61,7 +61,7 @@ PageChangeRun(PageGet(ID)) PageID = ID Catch ex As Exception - Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback) + Log(ex, "切换分页面失败(ID " & ID & ")", LogLevel.Feedback) Finally AniControlEnabled -= 1 End Try diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml.vb index db3f1680..ae9ee479 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadMod.xaml.vb @@ -13,12 +13,18 @@ Private Shared Function LoaderInput() As CompProjectRequest Dim Request As New CompProjectRequest(CompType.Mod, Storage, (Page + 1) * PageSize) If FrmDownloadMod IsNot Nothing Then + Dim ModLoader As CompModLoaderType = Val(FrmDownloadMod.ComboSearchLoader.SelectedItem.Tag) + Dim GameVersion As String = If(FrmDownloadMod.TextSearchVersion.Text = "全部 (也可自行输入)", Nothing, + If(FrmDownloadMod.TextSearchVersion.Text.Contains(".") OrElse FrmDownloadMod.TextSearchVersion.Text.Contains("w"), FrmDownloadMod.TextSearchVersion.Text, Nothing)) + If GameVersion IsNot Nothing AndAlso GameVersion.Contains(".") AndAlso Val(GameVersion.Split(".")(1)) < 14 AndAlso '1.14- + ModLoader = CompModLoaderType.Forge Then '选择了 Forge + ModLoader = CompModLoaderType.Any '此时,视作没有筛选 Mod Loader(因为部分老 Mod 没有设置自己支持的加载器) + End If With Request .SearchText = FrmDownloadMod.TextSearchName.Text - .GameVersion = If(FrmDownloadMod.TextSearchVersion.Text = "全部 (也可自行输入)", Nothing, - If(FrmDownloadMod.TextSearchVersion.Text.Contains(".") OrElse FrmDownloadMod.TextSearchVersion.Text.Contains("w"), FrmDownloadMod.TextSearchVersion.Text, Nothing)) + .GameVersion = GameVersion .Tag = FrmDownloadMod.ComboSearchTag.SelectedItem.Tag - .ModLoader = Val(FrmDownloadMod.ComboSearchLoader.SelectedItem.Tag) + .ModLoader = ModLoader .Source = CType(Val(FrmDownloadMod.ComboSearchSource.SelectedItem.Tag), CompSourceType) End With End If diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml.vb index 8fd9c7e6..174f4bee 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/MyMsgLogin.xaml.vb @@ -126,7 +126,7 @@ Finished(New Exception("$登录用时太长啦,重新试试吧!")) Return ElseIf ex.Message.Contains("AADSTS70000") Then '可能不能判 “invalid_grant”,见 #269 - Finished(New RetryException) + Finished(New RestartException) Return ElseIf ex.Message.Contains("authorization_pending") Then Thread.Sleep(2000) diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb index 068a40a5..bfc632e9 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb @@ -177,8 +177,8 @@ Sub() Try '更新缓存 - WriteIni(PathTemp & "Cache\Skin\IndexMs.ini", Setup.Get("CacheMsUuid"), SkinAddress) - Log(String.Format("[Skin] 已写入皮肤地址缓存 {0} -> {1}", Setup.Get("CacheMsUuid"), SkinAddress)) + WriteIni(PathTemp & "Cache\Skin\IndexMs.ini", Setup.Get("CacheMsV2Uuid"), SkinAddress) + Log(String.Format("[Skin] 已写入皮肤地址缓存 {0} -> {1}", Setup.Get("CacheMsV2Uuid"), SkinAddress)) '刷新控件 For Each SkinLoader In {PageLaunchLeft.SkinMs, PageLaunchLeft.SkinLegacy} SkinLoader.WaitForExit(IsForceRestart:=True) diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb index 9d5b534c..f3033b25 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb @@ -296,7 +296,7 @@ Case 0 '正版或离线 UnknownType: If RadioLoginType5.Checked Then - If Setup.Get("CacheMsAccess") = "" Then + If Setup.Get("CacheMsV2Access") = "" Then Type = PageType.Ms Else Type = PageType.MsSkin @@ -311,7 +311,7 @@ UnknownType: RadioLoginType5.Visibility = Visibility.Visible RadioLoginType0.Visibility = Visibility.Visible Case 1 '仅正版 - If Setup.Get("CacheMsAccess") = "" Then + If Setup.Get("CacheMsV2Access") = "" Then Type = PageType.Ms Else Type = PageType.MsSkin @@ -375,7 +375,7 @@ UnknownType: Public Shared SkinMs As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Ms", AddressOf SkinMsLoad, AddressOf SkinMsInput, ThreadPriority.AboveNormal) Private Shared Function SkinMsInput() As EqualableList(Of String) '获取名称 - Return New EqualableList(Of String) From {Setup.Get("CacheMsName"), Setup.Get("CacheMsUuid")} + Return New EqualableList(Of String) From {Setup.Get("CacheMsV2Name"), Setup.Get("CacheMsV2Uuid")} End Function Private Shared Sub SkinMsLoad(Data As LoaderTask(Of EqualableList(Of String), String)) '清空已有皮肤 diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb index 5cad11cb..1ddf391c 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchRight.xaml.vb @@ -114,6 +114,14 @@ Download: Log("[Page] 主页预设:更新日志") Url = "https://updatehomepage.pages.dev/UpdateHomepage.xaml" GoTo Download + Case 9 + Log("[Page] 主页预设:PCL 新功能说明书") + Url = "https://gitee.com/wforstbreeze/whats-new-pcl/raw/main/Custom.xaml" + GoTo Download + Case 10 + Log("[Page] 主页预设:OpenMCIM Dashboard") + Url = "https://files.mcimirror.top/PCL" + GoTo Download End Select End Select RunInUi(Sub() LoadContent(Content)) diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb index e61fa4ef..a7f98300 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMs.xaml.vb @@ -37,7 +37,7 @@ ''' 获取当前页面的登录信息。 ''' Public Shared Function GetLoginData() As McLoginMs - If FrmLoginMs Is Nothing Then Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName")} + If FrmLoginMs Is Nothing Then Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsV2OAuthRefresh"), .UserName = Setup.Get("CacheMsV2Name")} Dim Result As McLoginMs = Nothing RunInUiWait( Sub() diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb index b3f47ae0..e7ecc6c4 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginMsSkin.xaml.vb @@ -12,7 +12,7 @@ ''' 刷新页面显示的所有信息。 ''' Public Sub Reload(KeepInput As Boolean) - TextName.Text = Setup.Get("CacheMsName") + TextName.Text = Setup.Get("CacheMsV2Name") '皮肤在 Loaded 加载 End Sub ''' @@ -20,9 +20,9 @@ ''' Public Shared Function GetLoginData() As McLoginMs If McLoginMsLoader.State = LoadState.Finished Then - Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName"), .AccessToken = Setup.Get("CacheMsAccess"), .Uuid = Setup.Get("CacheMsUuid"), .ProfileJson = Setup.Get("CacheMsProfileJson")} + Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsV2OAuthRefresh"), .UserName = Setup.Get("CacheMsV2Name"), .AccessToken = Setup.Get("CacheMsV2Access"), .Uuid = Setup.Get("CacheMsV2Uuid"), .ProfileJson = Setup.Get("CacheMsV2ProfileJson")} Else - Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName")} + Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsV2OAuthRefresh"), .UserName = Setup.Get("CacheMsV2Name")} End If End Function @@ -50,11 +50,11 @@ '退出登录 Private Sub BtnExit_Click() Handles BtnExit.Click - Setup.Set("CacheMsOAuthRefresh", "") - Setup.Set("CacheMsAccess", "") - Setup.Set("CacheMsProfileJson", "") - Setup.Set("CacheMsUuid", "") - Setup.Set("CacheMsName", "") + Setup.Set("CacheMsV2OAuthRefresh", "") + Setup.Set("CacheMsV2Access", "") + Setup.Set("CacheMsV2ProfileJson", "") + Setup.Set("CacheMsV2Uuid", "") + Setup.Set("CacheMsV2Name", "") McLoginMsLoader.Abort() FrmLaunchLeft.RefreshPage(False, True) End Sub @@ -90,8 +90,8 @@ Try Retry: If McLoginMsLoader.State = LoadState.Loading Then McLoginMsLoader.WaitForExit() '等待登录结束 - Dim AccessToken As String = Setup.Get("CacheMsAccess") - Dim Uuid As String = Setup.Get("CacheMsUuid") + Dim AccessToken As String = Setup.Get("CacheMsV2Access") + Dim Uuid As String = Setup.Get("CacheMsV2Uuid") Dim Client As New Net.Http.HttpClient With {.Timeout = New TimeSpan(0, 0, 30)} Client.DefaultRequestHeaders.Authorization = New Net.Http.Headers.AuthenticationHeaderValue("Bearer", AccessToken) diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml.vb b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml.vb index f0a318f6..c1cbe612 100644 --- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml.vb @@ -419,75 +419,6 @@ Public Class PageLinkIoi '获取数据包 Public Shared Sub ReceiveJson(JsonData As JObject, Optional NewSocket As Socket = Nothing) - '获取数据 - Dim Id As String = JsonData("id"), Type As String = JsonData("type") - Select Case Type - Case "connect" - Dim DisplayName As String = JsonData("name") - Dim User As New LinkUserIoi(Id, DisplayName, NewSocket) - '如果发生了双向连接 - If UserList.ContainsKey(Id) Then - If Id > IoiId Then - Log("[IOI] 双向连接,应当抛弃当前用户(" & DisplayName & ")") - For Each Pair In UserList(User.Id).Ports.ToList - User.Ports(Pair.Key) = Pair.Value - Next - UserList(Id).Dispose() - Else - '应当保留当前用户 - Log("[IOI] 双向连接,应当保留当前用户(" & DisplayName & ")") - NewSocket.Dispose() - Exit Sub - End If - End If - '加入列表 - UserList.Add(Id, User) - '返回请求 - User.RelativeThread = RunInNewThread(Sub() - SendPortsubBack(User, JsonData("version").ToObject(Of Integer)) - End Sub, "Link Connect " & DisplayName) - '更新时间 - User.LastReceive = Date.Now - Case "update" - If Not UserList.ContainsKey(Id) Then Throw New Exception("未在列表中的用户发送了更新请求:" & Id) - Dim User = UserList(Id) - '拉满进度(该请求也作为反向连接回应出现,用于向正向连接方传达连接已完成信号) - User.Progress = 1 - '更新名称 - Dim DisplayName As String = JsonData("name") - User.DisplayName = DisplayName - '更新房间列表 - If JsonData("rooms") IsNot Nothing Then - User.Rooms = New List(Of RoomEntry) - For Each RoomObject In JsonData("rooms") - User.Rooms.Add(New RoomEntry(RoomObject("port"), RoomObject("name"), User)) - Next - End If - '更新 Ping - Dim Stage As Integer = JsonData("stage"), Unique As Long = JsonData("unique") - If Stage > 1 Then - User.PingRecord.Enqueue((Date.Now - User.PingPending(Unique)).TotalMilliseconds / 2) - If User.PingRecord.Count > 5 Then User.PingRecord.Dequeue() - User.PingPending.Remove(Unique) - End If - '返回请求 - If Stage > 0 AndAlso Stage < 3 Then RunInNewThread(Sub() - Try - SendUpdateRequest(User, Stage + 1, Unique) - Catch ex As Exception - Log(ex, "发送回程请求失败") - End Try - End Sub, "Link Update " & DisplayName) - '更新时间 - User.LastReceive = Date.Now - Case "disconnect" - '断开连接 - If Not UserList.ContainsKey(Id) Then Exit Sub - UserRemove(UserList(Id), ShowLeaveMessage:=JsonData("message") Is Nothing) - If JsonData("message") IsNot Nothing Then Hint(JsonData("message").ToString, If(JsonData("isError").ToObject(Of Boolean), HintType.Critical, HintType.Info)) - Case Else - Throw New Exception("未知的操作种类:" & Type) - End Select End Sub ''' ''' 从用户列表中移除一位用户。提示信息视作该用户主动离开。 diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml.vb index 7d62918d..38fd50ff 100644 --- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkLeft.xaml.vb @@ -63,7 +63,7 @@ PageChangeRun(PageGet(ID)) PageID = ID Catch ex As Exception - Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback) + Log(ex, "切换分页面失败(ID " & ID & ")", LogLevel.Feedback) Finally AniControlEnabled -= 1 End Try diff --git a/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml.vb index 846e453a..ffa5a72d 100644 --- a/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageOther/PageOtherLeft.xaml.vb @@ -83,7 +83,7 @@ PageChangeRun(PageGet(ID)) PageID = ID Catch ex As Exception - Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback) + Log(ex, "切换分页面失败(ID " & ID & ")", LogLevel.Feedback) Finally AniControlEnabled -= 1 End Try @@ -127,8 +127,8 @@ '打开网页 Public Shared Sub TryFeedback() Handles ItemFeedback.Click If Not CanFeedback(True) Then Exit Sub - Select Case MyMsgBox("是否要打开反馈列表网页?" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。", - "反馈提示", "提交新反馈", "查看反馈列表", "取消") + Select Case MyMsgBox("在提交新反馈前,建议先搜索反馈列表,以避免重复提交。" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。", + "反馈", "提交新反馈", "查看反馈列表", "取消") Case 1 Feedback(True, False) Case 2 @@ -137,7 +137,7 @@ End Sub Public Shared Sub TryVote() Handles ItemVote.Click If MyMsgBox("是否要打开新功能投票网页?" & vbCrLf & "如果无法打开该网页,请尝试使用加速器或 VPN。", - "提醒", "打开", "取消") = 2 Then Exit Sub + "新功能投票", "打开", "取消") = 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 diff --git a/Plain Craft Launcher 2/Pages/PageSetup/ModSetup.vb b/Plain Craft Launcher 2/Pages/PageSetup/ModSetup.vb index 468908de..8ef2a755 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/ModSetup.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/ModSetup.vb @@ -9,6 +9,8 @@ ''' Private ReadOnly SetupDict As New Dictionary(Of String, SetupEntry) From { {"Identify", New SetupEntry("", Source:=SetupSource.Registry)}, + {"WindowHeight", New SetupEntry(550)}, + {"WindowWidth", New SetupEntry(900)}, {"HintDownloadThread", New SetupEntry(False, Source:=SetupSource.Registry)}, {"HintNotice", New SetupEntry(0, Source:=SetupSource.Registry)}, {"HintDownload", New SetupEntry(0, Source:=SetupSource.Registry)}, @@ -42,6 +44,12 @@ {"CacheMsProfileJson", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)}, {"CacheMsUuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)}, {"CacheMsName", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)}, + {"CacheMsV2Migrated", New SetupEntry(False, Source:=SetupSource.Registry)}, + {"CacheMsV2OAuthRefresh", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)}, + {"CacheMsV2Access", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)}, + {"CacheMsV2ProfileJson", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)}, + {"CacheMsV2Uuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)}, + {"CacheMsV2Name", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)}, {"CacheNideAccess", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)}, {"CacheNideClient", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)}, {"CacheNideUuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)}, @@ -105,10 +113,10 @@ {"ToolDownloadSpeed", New SetupEntry(42, Source:=SetupSource.Registry)}, {"ToolDownloadVersion", New SetupEntry(0, Source:=SetupSource.Registry)}, {"ToolDownloadTranslate", New SetupEntry(0, Source:=SetupSource.Registry)}, - {"ToolDownloadKeepModpack", New SetupEntry(False, Source:=SetupSource.Registry)}, {"ToolDownloadIgnoreQuilt", New SetupEntry(True, Source:=SetupSource.Registry)}, {"ToolDownloadCert", New SetupEntry(False, Source:=SetupSource.Registry)}, {"ToolDownloadMod", New SetupEntry(1, Source:=SetupSource.Registry)}, + {"ToolModLocalNameStyle", New SetupEntry(0, Source:=SetupSource.Registry)}, {"ToolUpdateAlpha", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)}, {"ToolUpdateRelease", New SetupEntry(False, Source:=SetupSource.Registry)}, {"ToolUpdateSnapshot", New SetupEntry(False, Source:=SetupSource.Registry)}, @@ -592,7 +600,7 @@ FrmSetupUI.PanLogoChange.Visibility = Visibility.Visible End If Try - FrmMain.ImageTitleLogo.Source = New MyBitmap(Path & "PCL\Logo.png") + FrmMain.ImageTitleLogo.Source = Path & "PCL\Logo.png" Catch ex As Exception FrmMain.ImageTitleLogo.Source = Nothing Log(ex, "显示标题栏图片失败", LogLevel.Msgbox) diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLeft.xaml.vb index 17873167..9c98d0b7 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLeft.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupLeft.xaml.vb @@ -115,7 +115,7 @@ PageID = ID Catch ex As Exception - Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback) + Log(ex, "切换分页面失败(ID " & ID & ")", LogLevel.Feedback) Finally AniControlEnabled -= 1 End Try diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml index 20ac75c5..d3d32a34 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml @@ -7,66 +7,80 @@ PanScroll="{Binding ElementName=PanBack}"> - - + - - - - - - - - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - + + + + + - diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb index 105946d0..fc00a3d7 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb @@ -1,33 +1,5 @@ Class PageSetupSystem -#Region "语言" - 'Private Sub PageSetupUI_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded - ' AniControlEnabled -= 1 - - ' '读取设置 - ' Select Case Lang - ' Case "zh_CN" - ' ComboLang.SelectedIndex = 0 - ' Case "zh_HK" - ' ComboLang.SelectedIndex = 1 - ' Case "en_US" - ' ComboLang.SelectedIndex = 2 - ' End Select - ' CheckDebug.Checked = ReadReg("SystemDebugMode", "False") - - ' AniControlEnabled += 1 - 'End Sub - - 'Private Sub RefreshLang() Handles ComboLang.SelectionChanged - ' If IsLoaded Then - ' If Not ComboLang.IsLoaded Then Exit Sub - ' Lang = CType(ComboLang.SelectedItem, MyComboBoxItem).Tag - ' Application.Current.Resources.MergedDictionaries(1) = New ResourceDictionary With {.Source = New Url("Languages\" & Lang & ".xaml", UrlKind.Relative)} - ' WriteReg("Lang", Lang) - ' End If - 'End Sub -#End Region - Private Shadows IsLoaded As Boolean = False Private Sub PageSetupSystem_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded @@ -58,11 +30,13 @@ SliderDownloadThread.Value = Setup.Get("ToolDownloadThread") SliderDownloadSpeed.Value = Setup.Get("ToolDownloadSpeed") ComboDownloadVersion.SelectedIndex = Setup.Get("ToolDownloadVersion") + CheckDownloadCert.Checked = Setup.Get("ToolDownloadCert") + + 'Mod 与整合包 ComboDownloadTranslate.SelectedIndex = Setup.Get("ToolDownloadTranslate") ComboDownloadMod.SelectedIndex = Setup.Get("ToolDownloadMod") - CheckDownloadKeepModpack.Checked = Setup.Get("ToolDownloadKeepModpack") + ComboModLocalNameStyle.SelectedIndex = Setup.Get("ToolModLocalNameStyle") CheckDownloadIgnoreQuilt.Checked = Setup.Get("ToolDownloadIgnoreQuilt") - CheckDownloadCert.Checked = Setup.Get("ToolDownloadCert") 'Minecraft 更新提示 CheckUpdateRelease.Checked = Setup.Get("ToolUpdateRelease") @@ -91,10 +65,10 @@ Setup.Reset("ToolDownloadSpeed") Setup.Reset("ToolDownloadVersion") Setup.Reset("ToolDownloadTranslate") - Setup.Reset("ToolDownloadKeepModpack") Setup.Reset("ToolDownloadIgnoreQuilt") Setup.Reset("ToolDownloadCert") Setup.Reset("ToolDownloadMod") + Setup.Reset("ToolModLocalNameStyle") Setup.Reset("ToolUpdateRelease") Setup.Reset("ToolUpdateSnapshot") Setup.Reset("ToolHelpChinese") @@ -116,13 +90,13 @@ 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 + Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckDebugMode.Change, CheckDebugDelay.Change, CheckDebugSkipCopy.Change, CheckUpdateRelease.Change, CheckUpdateSnapshot.Change, CheckHelpChinese.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 If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Value) End Sub - Private Shared Sub ComboChange(sender As MyComboBox, e As Object) Handles ComboDownloadVersion.SelectionChanged, ComboDownloadTranslate.SelectionChanged, ComboSystemUpdate.SelectionChanged, ComboSystemActivity.SelectionChanged, ComboDownloadMod.SelectionChanged + Private Shared Sub ComboChange(sender As MyComboBox, e As Object) Handles ComboDownloadVersion.SelectionChanged, ComboModLocalNameStyle.SelectionChanged, ComboDownloadTranslate.SelectionChanged, ComboSystemUpdate.SelectionChanged, ComboSystemActivity.SelectionChanged, ComboDownloadMod.SelectionChanged If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.SelectedIndex) End Sub Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextSystemCache.ValidatedTextChanged diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml index aeb3ae4e..e9b7edc8 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml @@ -245,6 +245,8 @@ + + diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.vb index 45c03a7f..f058d565 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.vb @@ -25,14 +25,15 @@ Next End If + AniControlEnabled += 1 + Reload() '#4826,在每次进入页面时都刷新一下 + AniControlEnabled -= 1 + '非重复加载部分 If IsLoaded Then Exit Sub IsLoaded = True - AniControlEnabled += 1 SliderLoad() - Reload() - AniControlEnabled -= 1 #If BETA Then PanLauncherHide.Visibility = Visibility.Visible @@ -269,17 +270,16 @@ End Try End Sub - '顶部栏 Private Sub BtnLogoChange_Click(sender As Object, e As EventArgs) Handles BtnLogoChange.Click - Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif", "选择图片") + Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif;*.webp)|*.png;*.jpg;*.gif;*.webp", "选择图片") If FileName = "" Then Exit Sub Try '拷贝文件 File.Delete(Path & "PCL\Logo.png") CopyFile(FileName, Path & "PCL\Logo.png") '设置当前显示 - FrmMain.ImageTitleLogo.Source = New MyBitmap(Path & "PCL\Logo.png") + FrmMain.ImageTitleLogo.Source = Path & "PCL\Logo.png" Catch ex As Exception If ex.Message.Contains("参数无效") Then Log("改变标题栏图片失败,该图片文件可能并非标准格式。" & vbCrLf & @@ -296,7 +296,7 @@ Refresh: '已有图片则不再选择 If File.Exists(Path & "PCL\Logo.png") Then Try - FrmMain.ImageTitleLogo.Source = New MyBitmap(Path & "PCL\Logo.png") + FrmMain.ImageTitleLogo.Source = Path & "PCL\Logo.png" Catch ex As Exception If ex.Message.Contains("参数无效") Then Log("调整标题栏图片失败,该图片文件可能并非标准格式。" & vbCrLf & @@ -315,7 +315,7 @@ Refresh: Exit Sub End If '没有图片则要求选择 - Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif", "选择图片") + Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif;*.webp)|*.png;*.jpg;*.gif;*.webp", "选择图片") If FileName = "" Then FrmMain.ImageTitleLogo.Source = Nothing e.Handled = True @@ -428,8 +428,8 @@ Refresh: RadioLauncherTheme5Gray.Opacity -= 0.23 RadioLauncherTheme5.Opacity += 0.23 AniStart({ - AaOpacity(RadioLauncherTheme5Gray, 1, 1000), - AaOpacity(RadioLauncherTheme5, -1, 1000) + AaOpacity(RadioLauncherTheme5Gray, 1, 1000 * AniSpeed), + AaOpacity(RadioLauncherTheme5, -1, 1000 * AniSpeed) }, "ThemeUnlock") If RadioLauncherTheme5Gray.Opacity < 0.08 Then ThemeUnlock(5, UnlockHint:="隐藏主题 玄素黑 已解锁!") diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb index 99e211fa..a12b5f7a 100644 --- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionLeft.xaml.vb @@ -61,7 +61,7 @@ PageChangeRun(PageGet(ID)) PageID = ID Catch ex As Exception - Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback) + Log(ex, "切换分页面失败(ID " & ID & ")", LogLevel.Feedback) Finally AniControlEnabled -= 1 End Try diff --git a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml.vb b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml.vb index 372b6a7a..f0643461 100644 --- a/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageVersion/PageVersionMod.xaml.vb @@ -30,7 +30,7 @@ ''' 刷新 Mod 列表。 ''' Public Sub ReloadModList(Optional ForceReload As Boolean = False) - If LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", If(ForceReload, LoaderFolderRunType.ForceRun, LoaderFolderRunType.RunOnUpdated)) Then + If LoaderRun(If(ForceReload, LoaderFolderRunType.ForceRun, LoaderFolderRunType.RunOnUpdated)) Then Log("[System] 已刷新 Mod 列表") Filter = FilterType.All PanBack.ScrollToHome() @@ -43,9 +43,12 @@ End Sub Private Sub Load_Click(sender As Object, e As MouseButtonEventArgs) Handles Load.Click If McModLoader.State = LoadState.Failed Then - LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.ForceRun) + LoaderRun(LoaderFolderRunType.ForceRun) End If End Sub + Public Function LoaderRun(Type As LoaderFolderRunType) As Boolean + Return LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", Type) + End Function #End Region @@ -329,7 +332,7 @@ Private Sub ChangeAllSelected(Value As Boolean) AniControlEnabled += 1 SelectedMods.Clear() - For Each Item As MyLocalModItem In GetShowingMods(True).Select(Function(m) ModItems(m.RawFileName)) + For Each Item As MyLocalModItem In GetShowingMods(True).Where(Function(m) ModItems.ContainsKey(m.RawFileName)).Select(Function(m) ModItems(m.RawFileName)) Item.Checked = Value If Value Then SelectedMods.Add(Item.Entry.RawFileName) Next @@ -467,10 +470,12 @@ '更改 Loader 中的列表 Dim NewModEntity As New McMod(NewPath) NewModEntity.FromJson(ModEntity.ToJson) - Dim IndexOfLoader As Integer = McModLoader.Output.IndexOf(ModEntity) - McModLoader.Output.RemoveAt(IndexOfLoader) - McModLoader.Output.Insert(IndexOfLoader, NewModEntity) - If SearchResult IsNot Nothing Then + If McModLoader.Output.Contains(ModEntity) Then + Dim IndexOfLoader As Integer = McModLoader.Output.IndexOf(ModEntity) + McModLoader.Output.RemoveAt(IndexOfLoader) + McModLoader.Output.Insert(IndexOfLoader, NewModEntity) + End If + If SearchResult IsNot Nothing AndAlso SearchResult.Contains(ModEntity) Then '#4862 Dim IndexOfResult As Integer = SearchResult.IndexOf(ModEntity) SearchResult.Remove(ModEntity) SearchResult.Insert(IndexOfResult, NewModEntity) @@ -489,6 +494,7 @@ Hint("由于文件被占用,Mod 的状态切换失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical) ReloadModList(True) End If + LoaderRun(LoaderFolderRunType.UpdateOnly) End Sub '更新 @@ -696,6 +702,7 @@ Log(ex, "删除 Mod 出现未知错误", LogLevel.Feedback) ReloadModList(True) End Try + LoaderRun(LoaderFolderRunType.UpdateOnly) End Sub '取消选择 diff --git a/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj b/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj index 85d3bd72..990f7a66 100644 --- a/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj +++ b/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj @@ -186,12 +186,15 @@ + MyIconTextButton.xaml - + + + @@ -476,6 +479,7 @@ FormMain.xaml Code + MSBuild:Compile Designer @@ -910,6 +914,7 @@ + diff --git a/Plain Craft Launcher 2/Resources/Custom.xaml b/Plain Craft Launcher 2/Resources/Custom.xaml index df177e3a..21ca4593 100644 --- a/Plain Craft Launcher 2/Resources/Custom.xaml +++ b/Plain Craft Launcher 2/Resources/Custom.xaml @@ -4,311 +4,309 @@ 你也可以使用 Ctrl + F 快速查找。例如,若需要改变文本颜色,则搜索 “颜色” 即可。 --> - + - + - - - + + - + - + - - + Text="local:MyImage 代表图片,你需要在它的 Source 属性中填写一个网址或文件路径,它会从该处获取图片并显示。通常需要使用 Height 限制它的高度。" /> + + - + - - - - + - + - - - - + - + - - - - - + - + - - - - - - + - - + - - - - - - - + - - - - + - - + - - + - - - + + - - - - - - + + + - - - - + + - + - + - + EventType="打开帮助" EventData="帮助/自定义帮助.json" Type="Clickable" /> - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - + - + - - + + - - + - + - - + - - + - - + - - + - - - - - - - - - - - + + + + + + + - - - - + + - - - + + - - - - - - - - + - - - + + - - +